summaryrefslogtreecommitdiff
path: root/support/ratexdb/ratexdb.rb
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/ratexdb/ratexdb.rb
Initial commit
Diffstat (limited to 'support/ratexdb/ratexdb.rb')
-rw-r--r--support/ratexdb/ratexdb.rb471
1 files changed, 471 insertions, 0 deletions
diff --git a/support/ratexdb/ratexdb.rb b/support/ratexdb/ratexdb.rb
new file mode 100644
index 0000000000..b1af7d236e
--- /dev/null
+++ b/support/ratexdb/ratexdb.rb
@@ -0,0 +1,471 @@
+#!/usr/bin/env ruby
+
+# ratexdb Version 0.14
+# Database Access in LaTeX
+# Copyright (C) 2007-2010 Robin Höns, Integranova GmbH
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#
+# For more information see the web pages
+#
+# Robin Höns: http://www.hoens.net/robin
+# Integranova and the Programming Machine:
+# http://www.programmiermaschine.de
+# http://www.care-t.com
+
+require 'dbi'
+require 'FileUtils'
+
+
+$filedebug = nil
+
+# primitive debug output routine
+def debugoutput line
+ if $filedebug
+ $filedebug.puts "#{line}"
+ end
+end
+
+
+
+def replace_latex dbtext
+# Replace Latex special characters in DB result
+#Unterstrich _ \_
+#Rückstrich\Backslash \ \setminus
+#Dollarzeichen $ \$
+#Kaufmanns-Und & \&
+#Raute # \#
+#Geschweifte Klammern { } \{ \}
+#Prozentzeichen % \%
+ debugoutput "replatex rein: " + dbtext
+
+ specialhash = {
+ ?\\ => "\\\\ensuremath{\\\\backslash}",
+ ?_ => "\\\\_",
+ ?$ => "\\\\$",
+ ?& => "\\\\&",
+ ?# => "\\\\#",
+ ?{ => "\\\\{",
+ ?} => "\\\\}",
+ ?~ => "\\\\~{}",
+ ?% => "\\\\%"
+ }
+
+ result = ""
+
+ for i in (0..dbtext.length)
+ maski = specialhash[dbtext[i]]
+ if maski
+ result << maski
+ else
+ result << dbtext[i,1]
+ end
+ end
+
+ debugoutput "replatex raus: " + result
+
+ return result
+end
+
+def replace_sql dbtext
+# Replace SQL special characters in DB result
+# (important against SQL injection!)
+ return dbtext.gsub("'", "''")
+end
+
+def check_number dbtext
+# This text must contain a single numeric value
+# (important against SQL injection!)
+ unless dbtext =~ /\A(\+|-)?[\da-fA-F]+\Z/
+ raise "Numeric variable contains non-numeric value: #{dbtext}"
+ end
+ return dbtext
+end
+
+
+def execute_if texblock
+ debugoutput "Pruefe if #{$select_to_handle}"
+ debugoutput texblock
+
+ selectkram = $select_hash[$select_to_handle]
+ $select_to_handle = nil
+ $modus_collect = false
+
+ selectbefehl = selectkram[0]
+ debugoutput "Select: #{selectbefehl}"
+ row = $dbconn.select_one( selectbefehl )
+
+ if row
+ # Ja, es gibt Daten zu diesem Select
+ for nowline in texblock.split("\n")
+ debugoutput "nowline " + nowline
+ handle_line(nowline)
+ end
+ end
+end
+
+
+def execute_for_loop texblock
+
+ debugoutput "Mache #{$select_to_handle} mit:"
+ debugoutput texblock
+
+ selectkram = $select_hash[$select_to_handle]
+ $select_to_handle = nil
+ $modus_collect = false
+
+ selectbefehl = selectkram[0]
+ variablen = selectkram[1]
+
+ debugoutput "Select: #{selectbefehl}"
+ for myvar in variablen
+ debugoutput "Var: #{myvar}"
+ end
+
+ rows = $dbconn.select_all( selectbefehl )
+
+ for row in rows
+ ergebnis = texblock
+ vari = 0
+ while vari < variablen.length
+ variable_regexs = variablen[vari].split("/")
+ varname = variable_regexs[0]
+
+ debugoutput "ok: " + varname
+ if varname[0,2] != "##"
+ raise "Variable #{varname} does not begin with ##"
+ end
+ varnamesql = "$$" + varname[2..-1]
+ varnamenum = "&&" + varname[2..-1]
+
+ original_db_result = row[vari].to_s
+ current_db_result_latex = replace_latex(original_db_result)
+ current_db_result_sql = replace_sql(original_db_result)
+ if ergebnis.index(varnamenum)
+ current_db_result_num = check_number(original_db_result)
+ else
+ current_db_result_num = original_db_result
+ end
+
+ debugoutput "latex: #{current_db_result_latex}"
+ debugoutput "sql: #{current_db_result_sql}"
+ debugoutput "num: #{current_db_result_num}"
+
+ # Perform all Regexp replaces
+ rei = 2
+ while rei < variable_regexs.length
+ debugoutput variable_regexs[rei-1]
+ rei_regex = Regexp.new( variable_regexs[rei-1] )
+ debugoutput rei_regex
+ rei_replace = variable_regexs[rei]
+ debugoutput rei_replace
+ current_db_result_latex = current_db_result_latex.gsub(rei_regex, rei_replace)
+ current_db_result_sql = current_db_result_sql.gsub(rei_regex, rei_replace)
+ current_db_result_num = current_db_result_num.gsub(rei_regex, rei_replace)
+
+ debugoutput "latex: #{current_db_result_latex}"
+ debugoutput "sql: #{current_db_result_sql}"
+ debugoutput "num: #{current_db_result_num}"
+
+ rei += 2
+ end
+
+# Handle the three variable flavours
+ ergebnis = ergebnis.gsub(varname, current_db_result_latex)
+ ergebnis = ergebnis.gsub(varnamesql, current_db_result_sql)
+ if ergebnis.index(varnamenum)
+ ergebnis = ergebnis.gsub(varnamenum, current_db_result_num)
+ end
+
+ vari += 1
+ end
+ debugoutput "Ergebnis: #{ergebnis}"
+ for nowline in ergebnis.split("\n")
+ handle_line(nowline)
+ end
+ end
+end
+
+def execute_defselect texblock
+ debugoutput "defselect #{$select_to_define}"
+ debugoutput texblock
+
+ $defining_select_statement = texblock
+
+end
+
+
+def execute_defvariablen texblock
+ debugoutput "defvariablen #{$select_to_define}"
+ debugoutput texblock
+
+ # remove all white space from variable list
+
+ varliste = Array.new
+
+ for var in texblock.split(",")
+ varliste << var.strip
+ end
+
+ varliste.each {|var| debugoutput "Got Var: " + var}
+
+ $select_hash[$select_to_define] = [$defining_select_statement, varliste]
+
+ $select_to_define = nil
+ $modus_collect = false
+end
+
+
+def handle_line_unless_empty(line)
+ debugoutput "handle unless empty"
+ unless line == nil
+ unless line.length == 0
+ debugoutput "Handle: " + line
+ handle_line line
+ else
+# debugoutput "line is empty"
+ end
+ else
+# debugoutput "line is nil"
+ end
+end
+
+def handle_line(line)
+# debugoutput "Handle: " + line
+
+## matchDef=/\A([^%]*)\\texdbdef\{##([^\}]*)\}\{(.*)\}\{(.*)\}(.*)/
+ matchDef=/\A([^%]*)\\texdbdef\{##([^\}]*)\}\{(.*)/
+## matchFor=/\A(.*)\\texdbfor\{##([^\}]*)\}\{(.*)\}(.*)/
+ matchFor=/\A([^%]*)\\texdbfor\{##([^\}]*)\}\{(.*)/
+ matchIf=/\A([^%]*)\\texdbif\{##([^\}]*)\}\{(.*)/
+ matchDbDef=/\A([^%]*)\\texdbconnection\{([^\}]*)\}(.*)/
+ matchDbCmd=/\A([^%]*)\\texdbcommand\{([^\}]*)\}(.*)/
+
+ if $modus_collect == false
+ if line =~ matchDef
+ debugoutput "Found Def!"
+ handle_line_unless_empty($1)
+ $select_to_define = $2
+ $bracedepth = 1
+ $modus_collect = 1
+ $collected_text = ""
+ $kommando="defselect"
+ handle_line_unless_empty($3)
+ elsif line =~ matchFor
+ debugoutput "Found For!"
+ handle_line_unless_empty($1)
+ $select_to_handle = $2
+ $bracedepth = 1
+ $modus_collect = 1
+ $collected_text = ""
+ $kommando="for"
+ handle_line_unless_empty($3)
+ elsif line =~ matchIf
+ debugoutput "Found If!"
+ handle_line_unless_empty($1)
+ $select_to_handle = $2
+ $bracedepth = 1
+ $modus_collect = 1
+ $collected_text = ""
+ $kommando="if"
+ handle_line_unless_empty($3)
+ elsif line =~ matchDbDef
+ debugoutput "Found DbDef!"
+ handle_line_unless_empty($1)
+ debugoutput "Datenbank: #{$2}"
+ dbpar = $2.split(",")
+ $dbconn = DBI.connect(dbpar[0], dbpar[1], dbpar[2], dbpar[3])
+ handle_line_unless_empty($3)
+ elsif line =~ matchDbCmd
+ debugoutput "Found DbCmd!"
+ handle_line_unless_empty($1)
+ debugoutput "Command: #{$2}"
+ unless $dbconn
+ raise "Please put texdbconnection before texdbcommand!"
+ end
+ sth = $dbconn.execute($2)
+ sth.finish
+ handle_line_unless_empty($3)
+ else
+ $fileout.puts "#{line}"
+ end
+ else
+ # wir sammeln Zeilen
+
+ if line == nil
+ linelength = 0
+ else
+ linelength = line.length
+ end
+# debugoutput linelength
+ i = 0
+ backslashgelesen = 0
+ while i < linelength && $bracedepth > 0
+ currchar = line[i]
+# debugoutput "curr #{currchar} backsl #{backslashgelesen}"
+ if currchar == ?\\
+ if backslashgelesen == 0
+ backslashgelesen = 1
+ else
+ backslashgelesen = 0
+ end
+ elsif currchar == ?{
+ if backslashgelesen == 0
+ $bracedepth += 1
+ debugoutput "Tiefe: #{$bracedepth}"
+ else
+ debugoutput "kein ++, Backslash!"
+ end
+ backslashgelesen = 0
+ elsif currchar == ?}
+ if backslashgelesen == 0
+ $bracedepth -= 1
+ debugoutput "Tiefe: #{$bracedepth}"
+ else
+ debugoutput "kein --, Backslash!"
+ end
+ backslashgelesen = 0
+ else
+ backslashgelesen = 0
+ end
+ i += 1
+ end # while
+ debugoutput "Zeile Tiefe: #{$bracedepth}"
+ $collected_text << line[0, i]
+ i -= 1
+
+ if $bracedepth == 0
+ # chop, um } wegzuschmeißen
+ if $kommando == "for"
+ execute_for_loop $collected_text.chop
+ $modus_collect = false
+ elsif $kommando == "if"
+ execute_if $collected_text.chop
+ $modus_collect = false
+ elsif $kommando == "defselect"
+ execute_defselect $collected_text.chop
+ i += 1
+ if i >= linelength || line[i] != ?{
+ raise "In texdbdef of #{$select_to_define} there is nothing allowed between the select and variable block, but I did not find the \}\{."
+ end
+ $modus_collect = 1
+ $kommando = "defvariablen"
+ $bracedepth = 1
+ $collected_text = ""
+ elsif $kommando == "defvariablen"
+ execute_defvariablen $collected_text.chop
+ $modus_collect = false
+ end
+
+ handle_line_unless_empty line[i+1 .. -1]
+ end
+
+ $collected_text << "\n"
+
+ end
+end
+
+def output_help
+
+ puts "Ratexdb 0.14 Copyright (C) 2007-2010 Robin Hoens, Integranova GmbH"
+ puts "This program comes with ABSOLUTELY NO WARRANTY."
+ puts "This is free software, and you are welcome to redistribute it"
+ puts "under certain conditions."
+ puts "See file COPYING for details."
+ puts ""
+ puts "Usage:"
+ puts "#{$0} [-p|-l] <texfile.tex> [Parameters...]"
+ puts "-p = pdflatex"
+ puts "-l = latex"
+ puts "none of the two: just produce texfile1.tex"
+ exit
+end
+
+
+if ARGV.length == 0
+ output_help
+end
+
+arg_index = 0
+
+before_texfile = 1
+
+while before_texfile
+ if ARGV[arg_index] == "-p"
+ texbefehl = "pdflatex"
+ resultextension = ".pdf"
+ elsif ARGV[arg_index] == "-l"
+ texbefehl = "latex"
+ resultextension = ".dvi"
+ elsif ARGV[arg_index] == "-d"
+ $filedebug = File.new("ratexdb.txt", "w")
+ else
+ before_texfile = false
+ end
+ arg_index += 1
+ if ARGV.length < arg_index
+ output_help
+ end
+end
+
+arg_index -= 1
+
+datei_rein = ARGV[arg_index]
+datei_raus = datei_rein.sub(/\.tex\Z/, "1.tex")
+
+if datei_raus == datei_rein
+ raise "Sorry: File name must end on .tex. I got #{datei_rein}"
+end
+
+debugoutput datei_rein
+debugoutput datei_raus
+
+$select_to_handle = nil
+$select_hash = {}
+$variable_hash = {}
+$modus_collect = false
+
+cmdlinehash = {}
+i=1
+while arg_index + i < ARGV.length
+ cmdlinehash[i.to_s] = ARGV[arg_index + i]
+ i+=1
+end
+
+filein = File.new(datei_rein, "r")
+$fileout = File.new(datei_raus, "w")
+while (line = filein.gets)
+ cmdlinehash.each {|key, value|
+ line = line.gsub("##" + key, replace_latex(value))
+ line = line.gsub("$$" + key, replace_sql(value))
+ if line.index("&&" + key)
+ line = line.gsub("&&" + key, check_number(value))
+ end
+ }
+ handle_line line.chomp
+end
+filein.close
+$fileout.close
+
+$dbconn.disconnect if $dbconn
+
+if texbefehl
+ system(texbefehl, datei_raus)
+
+ rauspdf = datei_raus.sub(/\.tex\Z/, resultextension)
+ ergebnispdf = datei_rein.sub(/\.tex\Z/, resultextension)
+
+ File.mv(rauspdf, ergebnispdf)
+end