summaryrefslogtreecommitdiff
path: root/support/dbtex/dbtex.awk
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dbtex/dbtex.awk
Initial commit
Diffstat (limited to 'support/dbtex/dbtex.awk')
-rw-r--r--support/dbtex/dbtex.awk246
1 files changed, 246 insertions, 0 deletions
diff --git a/support/dbtex/dbtex.awk b/support/dbtex/dbtex.awk
new file mode 100644
index 0000000000..9f6666cc7f
--- /dev/null
+++ b/support/dbtex/dbtex.awk
@@ -0,0 +1,246 @@
+# dbTeX.awk - a simple preprocessor for generating TeX output from
+# database files
+# Version 1.1.beta (1991-02-12) dr. w. kraml, KPMG Alpen-Treuhand Wien
+# see dbTeX.tex for documentation!
+
+
+BEGIN { console_msg("This is dbTeX Version 1.1.beta (1991-02-12)")
+ printf("%% dbTeX (1.1.beta) Output generated " ctime() "\n")
+ # ^ PolyAwk specific!
+ printf("%% dbTeX Input file: %s\n", ARGV[1])
+# a number of initialisations and defs follow here:
+ FieldS = FS
+ RecordS = RS
+ NRincluded = 0
+ example_flag = 0
+ buffer = ""
+ STANDARD = 0
+ STRING = 1
+ TEMPLATE = 2
+ ID = 3
+ USER = 1
+ }
+
+
+# main loop - do this for each line in script
+
+{ if ($0 ~ /^%!/) { # embedded dbTeX-command
+ in_template = 0
+ buffer = substr($0,3)
+ print $0 # output for reference
+ dbTeX_command()
+ }
+ else if ($0 ~ /^%_/) { # template contin. line
+ print $0
+ if (in_template) { # start cont. with newlines
+ nl = length(template[t_name]) ? "\n" : ""
+ template[t_name] = template[t_name] nl substr($0,3)
+ }
+ else error_msg("INVALID CONTINUATION")
+ }
+ else if (example_flag) { # embedded examples
+ in_template = 0
+ print "%" $0
+ }
+ else {
+ in_template = 0
+ print $0 # original TeX line
+ }
+}
+
+END { s = NR " line(s) input, " NRincluded " record(s) included, "
+ s = s (errors+0) " error(s)"
+ info_msg(s)
+ }
+
+
+
+# functions performing helpful tasks with various messages
+
+function console_msg(s) { # output to console
+ print s > "/dev/tty"
+ }
+
+function error_msg(msg, s) { # print error on console
+ s = "% (dbTeX) Error: " msg "!" # and in output file
+ ++errors
+ print s
+ console_msg(s " -> line " NR ":")
+ console_msg($0)
+}
+
+function info_msg(msg, s) { # print info on console
+ s = "% (dbTeX) Info: " msg "." # and in output file
+ print s
+ console_msg(s)
+}
+
+
+# dbTeX functions
+
+function dbTeX_command() { # the dbTeX main function
+ advance(ID)
+ example_flag = 0
+ if (tok == "examples") example_flag = 1 # %! examples
+ else if (tok == "record") { # %! record <id> <FS> [<RS>]
+ if (advance(ID)) {
+ if (tok ~ /^%[0-9]+%$/) { # data-named template
+ templ_typ = 1
+ templ_field = substr(tok,2,length(tok)-2)
+ }
+ else { # script-named template
+ templ_typ = 0
+ templ_name = tok
+ }
+ }
+ FieldS = advance(STRING) ? tok : FS
+ RecordS = advance(STRING) ? tok : RS
+ }
+ else if (tok=="template") { # %! template <id> <template>
+ in_template = 1
+ if (advance(ID)) # get name
+ t_name = tok
+ if (advance(TEMPLATE))
+ template[t_name] = tok
+ }
+ else if (tok=="break") { # %! break %f% <id>
+ if (advance(ID)) {
+ if (tok ~ /^%[0-9]+%$/)
+ breakfield = substr(tok,2,length(tok)-2)
+ else
+ breakfield = tok
+ }
+ if (advance(ID))
+ breaktemplate[breakfield] = tok
+ if (advance(ID))
+ breakmode[breakfield] = 1
+ else breakmode[breakfield] = 0
+ }
+ else if (tok=="clearbreaks") { # %! clearbreaks
+ for (i in oldvalue)
+ delete oldvalue[i]
+ for (i in breaktemplate)
+ delete breaktemplate[i]
+ for (i in breakmode)
+ delete breakmode[i]
+ }
+ else if (tok=="translate") { # %! translate <id>
+ if (advance(ID))
+ set_translation(tok)
+ }
+ else if (tok=="change") { # %! change <s1> <s2>
+ add_trtbl(USER)
+ }
+ else if (tok=="include") { # %! include <filename>
+ if (advance(ID))
+ do_include(tok)
+ }
+ else error_msg("UNKNOWN COMMAND")
+}
+
+
+function advance(type, sep,pos) { # get next token of type
+ sub(/^[ \t]+/, "", buffer) # remove white space
+ if (type == ID) {
+ match(buffer, /^[^ \t]+/) # all up to white space
+ tok = tolower(substr(buffer, 1, RLENGTH)) # tolower(): PolyAwk & GNU only!
+ buffer = substr(buffer, RLENGTH+1)
+ return RLENGTH
+ }
+ else if (type == TEMPLATE) { # rest of line
+ tok = buffer
+ buffer = ""
+ return length(tok)
+ }
+ else if (type == STRING) { # string delimited by
+ sep = substr(buffer,1,1) # unique character
+ buffer = substr(buffer,2)
+ pos = index(buffer, sep)
+ if (pos) {
+ tok = substr(buffer,1,pos-1)
+ buffer = substr(buffer, pos+1)
+ return pos
+ }
+ else {
+ tok = ""
+ return 0
+ }
+ }
+ else return 0
+}
+
+
+function add_trtbl(tbl) { # add an entry to tr table
+ if (advance(STRING)) {
+ tmp = tok
+ if (advance(STRING))
+ tbl==USER ? (usr_tbl[tmp] = tok) : (std_tbl[tmp] = tok)
+ else
+ tbl==USER ? (usr_tbl[tmp] = "") : (std_tbl[tmp] = "")
+ }
+}
+
+
+function set_translation(id) { # install translation table
+ if (toupper(id) == "OFF") {
+ for (i in std_tbl)
+ delete std_tbl[i]
+ for (i in usr_tbl)
+ delete usr_tbl[i]
+ }
+ else { # read translation table
+ while ((status = getline line < id) > 0) {
+ buffer = line
+ if (buffer !~ /^#/)
+ add_trtbl(STANDARD)
+ }
+ if (status == -1)
+ error_msg("TRANSLATION TABLE " id " NOT FOUND")
+ }
+}
+
+
+function do_include(file) { # include records of <file>
+ old_FS = FS; old_RS = RS
+ FS = FieldS; RS = RecordS
+ inc = 0
+ while (getline < file > 0) {
+ for (i in breaktemplate) # check for breaks
+ if (oldvalue[i] != $i) {
+ oldvalue[i] = $i
+ if (inc || breakmode[i]) # no break before 1st rec.,
+ incl_(template[breaktemplate[i]])
+ } # if not explicitly wanted!
+
+ if (templ_typ)
+ incl_(template[$templ_field])
+ else incl_(template[templ_name])
+ ++NRincluded; ++inc
+ }
+ FS = old_FS; RS = old_RS
+ close(file)
+ if (!inc) error_msg("FILE " file " NOT FOUND OR NOT ACCESSIBLE!")
+ info_msg(inc " record(s) included from " file)
+}
+
+
+function incl_(t) { # include record with template t
+ s = ""
+ while (match(t, /%[0-9]+%/)) {
+ l = RSTART-1
+ s = s substr(t,1,l) txlate($(substr(t,RSTART+1,RLENGTH-2)))
+ # translated data field
+ t = substr(t,l+RLENGTH+1)
+ }
+ print s t
+}
+
+
+function txlate(s) { # perform translations on string s
+ for (target in std_tbl)
+ gsub(target, std_tbl[target], s)
+ for (target in usr_tbl)
+ gsub(target, usr_tbl[target], s)
+ return s
+}
+