# -*- srcfile:/adv/deplate/mod/a2e.rb; mode: ruby; coding: utf-8; -*- # Time-stamp: <2010-04-14 18:17:40 phm> # =Macros of the a2e.rb packages # # ==Multilinguisation # # Some usage examples: # # {vok:{ml:From the above results it has been recognised that the %1 strand is propagated in %(2|mammal-originating strandified cells), and it is believed that these are equivalent to the %4 strands found in the commercially available %3.}|B1(G)|pe:{ml:Vero, MDBK and BHK21}|{ml:NB vaccine}|B1(K)} # # Two macros are enough for a very powerful mechanism of separation of minimal translatable text from meta-structures that don't interst translators: # # [ml] multilingual expression: its text argument is the translatable string that may contain enumerated placeholders, %1 %2 %3 etc for variables, and %(1:...|...|...) for functions. Apart from the text argument the ml expression can have an id (identifier) attribute. If an id is supplied. # [vok] invokes a multilingual expression and stuffs it with arguments which are supplied to it. The first character after the first expression (that can be an ml macro or a previously defined (by ID attribute) expression, or a builtin command) is the argument separation chacter, in this case '|'. Whether the supplied arguments taken are interpreted as functions or variables depends on the ml expression. In the above example, 'tpe' is a function that places its first argument as an explaining parenthesis after the expression, encircled by the %(2|....) bracket, which it expands. # # By applying the abstractions to the above sentence, it becomes easier to reuse once-translated sentence templates, and these templates themselves are often easier to oversee than the completely expanded structures. # # ==Advanced usage of ml and vok (not all implemented) # # ===Enumerations, with special meaning of %9 as last argument # # {ml id=etlist ja="%1と%2と%9":%1, %2 and %9} # {vok:etlist|{ml ja=兎:rabbit}|{ml ja=馬:horse}|{ml ja=牛:cow}|{ml ja=狐:fox}} ==> rabbit, horse, cow and fox # # ===Definitions of derived placeholders that are made available to translators # # {ml id=heisei Y=%(add,1988,%1) M=%(numpad,2,%2) MN=%(month_name,%3 D=numpad,2,%3) ja="平成%1年%2月%3日":%MN %D, %Y} # # ===Function and variable Placeholders, another example # # {vok:{ml id=firmnorm ja="%1の%(2:%3規格)":%(2:%3 standard) of %1}|{vok:tp|{vok:{ml id=landfirm ja="%1%2":%2 of %1}|{ml ja="メキシコ":Mexico}|{vok:{ml id=firm ja="%1社":%1 Inc}|ALPES}}|{vok:firm|{ml id=chariver ja="チャールスリバー":Charles River}}}|link:http://www.alpes.com/standards/spf|SPF} # # ==Dynamic Linking # # Instead of pointing to a URL literally, we point to the identifier of a document (dok). # The URL is looked up and substituted by the software. The following two might lead # to the same result # # When using {ah url="http://a2e.de/adv/deplate":Deplate}, we ... # # When using {ah dok=deplate:Deplate}, we ... # # ==Various record structures # # We use the deplate macro language as a serialisation format for data-records, similar to YAML, and provide commands that, when certain conditions are true, write these data records to the database. The conditions are: (1) the 'dbput' variable is set true and the chosen formatter is of type plain text. We initiate the entry into the database by calling 'make dbput' in the directory, using a phony Make target. It is assured that data are not written by the ordinary Makefile process, which usually generate XHtml and LaTeX/PDF, not plain text. # # At the moment these commands are specially tailored to local needs, not very generic. But the advantages of serialising data this way may be of general value. The looseness of the Deplate macro language (as compared to XML or YAML) helps us move quickly from first prototypes to operational data. # # =Working Environment # # This packages is loaded into Deplate as a module, with the -m a2e option on the # commandline, provided that it has been copied into the Deplate modules directory. # require 'rubygems' require 'postgres' # for debugging # require 'breakpoint' # needed only when calling from outside of deplate require 'deplate' class Deplate::Macro @@dbnom = nil @@dbnom0 = File.exists?('@dbnom') ? File.new('@dbnom').readline.chomp.intern : :a2e @@conn = {} @@dokvars = {} @@tokens ||= Hash.new @@tokens['et'] = 'and' @@tokens['vel'] = 'or' @@abbrevs ||= Hash.new @@cjk_opening_chars = [40, 65288, 123]; @@cjk_closing_chars = [41, 65289, 125]; @@cjk_opening_closers = { 40 => 41, 65288 => 65289, 123 => 125, 12300=>12301 } @@cjk_closing_openers = { 41 => 40, 65289 => 65288, 125 => 123, 12301=>12300 } @@ascii_quote_chars = [34, 39]; @@id_chars = (45..57).collect.concat((65..90).collect).concat((97..122).collect).concat([95]) @@dbtabs = {} def db_connect_a2e return if @@conn[:a2e].is_a?(PGconn) # print "db_connect_a2e\n" db_pass_file = File.new("/home/#{@@dokvars[:whoami]}/.dbpass_a2e") (db_pass, db_user) = db_pass_file.collect { |line| line.chomp } db_user ||= @@dokvars[:whoami] db_pass_file.close # print "db_connect_a2e with db_user #{db_user} and db_pass #{db_pass}\n" if @@dokvars[:hostname] == 'bartu' @@conn[:a2e] = PGconn.connect('', 5432, '', '', 'a2e', @@dokvars[:whoami]) else if ENV['DBHOST'] == 'localhost' or ENV['DABA_LOKAL'] == '1' print "choosing local database with user #{@@dokvars[:whoami]}\n" @@conn[:a2e] = PGconn.connect('', 5432, '', '', 'a2e', @@dokvars[:whoami]) else # print "try connect to a2e.de with user #{db_user} and pass #{db_pass}\n" begin @@conn[:a2e] = PGconn.connect('a2e.de', 5432, '', '', 'a2e', db_user, db_pass) rescue PGError print "resorting to local database with user #{@@dokvars[:whoami]}\n" @@conn[:a2e] = PGconn.connect('', 5432, '', '', 'a2e', @@dokvars[:whoami]) end end end # print "db_connect_a2e at end with user #{@@conn[:a2e].user}\n" return 1 end def db_connect_ffii return if @@conn[:ffii].is_a?(PGconn) db_pass_file = File.new("/home/#{@@dokvars[:whoami]}/.dbpass_ffii") (db_pass, db_user) = db_pass_file.collect { |line| line.chomp } db_user ||= @@dokvars[:whoami] db_pass_file.close if @@dokvars[:hostname] == 'vic' @@conn[:ffii] = PGconn.connect('', 5432, '', '', 'ffii', @@dokvars[:whoami]) else if ENV['DBHOST'] == 'localhost' or ENV['DABA_LOKAL'] @@conn[:ffii] = PGconn.connect('', 5432, '', '', 'ffii', @@dokvars[:whoami]) else begin @@conn[:ffii] = PGconn.connect('ffii.org', 5432, '', '', 'ffii', db_user, db_pass) rescue PGError @@conn[:ffii] = PGconn.connect('', 5432, '', '', 'ffii', @@dokvars[:whoami]) end end end end def db_connect dbnom = @deplate.variables['dbnom']; dbnom = dbnom ? dbnom.intern : @@dbnom0 print "setting database to #{dbnom}\n" if not @@dbnom == dbnom @@dbnom = dbnom return if @@conn.include?(@@dbnom) and @@conn[@@dbnom].is_a?(PGconn) and @@conn[@@dbnom].client_encoding == "UTF8" if @@dbnom == :ffii db_connect_ffii else db_connect_a2e end @@conn[@@dbnom].set_client_encoding "UTF8" # probably not needed return true end def set_dokvars @@dokvars[:whoami] ||= `whoami`.chomp # print "dokvars of whoami is #{@@dokvars[:whoami]}\n" @@dokvars[:hostname] ||= `hostname`.chomp # print "dokvars of hostname is #{@@dokvars[:hostname]}\n" db_connect return if defined?(@@alidok) res = @@conn[@@dbnom].exec "select dok, varval from doktexts where varnom = 'alias' and valsymp" tups = res.result @@alidok = Hash.new tups.each { |tup| @@alidok[tup[0].intern] = tup[1].intern } @@domain = 'a2e.de' @@domrxp = /^https?:\/\/([^\/]+)(\/.*)$/ # url_clip = @deplate.get_clip('url') # url = url_clip ? url_clip.format_clip(self, Deplate::Particle) : File.new('@url').readline.chomp dok = @deplate.variables['dok'] url = @deplate.variables['url'] || (f = "@url.#{dok}.txt";File.exists?(f) && File.new(f).readline.chomp) || (f = '@url';File.new(f).readline.chomp) print "dok #{dok}, url #{url}\n" if url match = @@domrxp.match(url) if match; @@domain = match[1] @@lokurl = match[2] # print "found domain #{@@domain} and lokurl #{@@lokurl}\n" end end @@urlrxp = /^https?:\/\/#{@@domain}(.*)$/ end def get_dok_anchor_text(text, dok, url, url_lang, ref) if url and /^(\w+)$/.match(url) and not File.readable?(url) dok = url end rest = String.new('') if dok; match = /^(\w+)(\/.*)$/.match(dok) if match; dok = match[1];rest = match[2];end doks = [ dok ] while dok = @@alidok[dok] and doks.grep(dok).length == 0 doks = doks.unshift(dok) end dok = doks[0] set_dokvars res = @@conn[@@dbnom].exec("select dokurl from mlhtdok where dok = '#{dok}'") if res[0] url = res[0][0] match = @@urlrxp.match(url) if match; url = match[1] + rest;end end end if text && text.length > 0 text = @deplate.parse_and_format(@container, text) elsif dok && dok.length > 0 label = dok lang = @deplate.variables['lang'] res = lang && lang.length == 2 && @@conn[@@dbnom].exec("select mltxt from langtxts where dok = '#{dok}' and lang = '#{lang}' and mlid = 'label'") if res && res[0] label = res[0][0] else res = @@conn[@@dbnom].exec("select mltxt from langtxts where dok = '#{dok}' and lang is null and mlid = 'label'") if res[0] label = res[0][0] else res = @@conn[@@dbnom].exec("select mltxt from langtxts where dok = '#{dok}' and mlid = 'label'") if res[0] label = res[0][0] end end end text = @deplate.parse_and_format(@container, label) elsif url && url.length > 0 text = @deplate.parse_and_format(@container, url) end if url_lang url = if url;then url;else ".";end url = url + "/index." + url_lang.to_s + ".html" end if url @text = format_particle(:format_url, self, text, url, nil) elsif dok @text = if text.length > 0 then text else "#{dok}" end else @text = text end @text = if text.length > 0 then text else 'NULL TEXT ERROR' end end def dbput_ok? () @deplate.variables['dbput'].to_i > 0 and @deplate.formatter.matches?("plain") end def dbput (table, keycols, valcols) # table = :spez # keycols = { :spez => :japaK7 } # valcols = { :spezrem => "wird noch in kalenderwoche 32 bezahlt", :spezde => :TbkKM, :spezal => :a2e, :spezktg => :trden, :speznom => nil } return unless table and table.is_a?(Symbol) return unless keycols and keycols.is_a?(Hash) return unless valcols and valcols.is_a?(Hash) return unless dbput_ok? valcols.delete_if {|key, val| not val} set_dokvars sqlset = valcols.collect {|key, val| "#{key}" + ' = ' + PGconn.quote("#{val}")}.join(', ') sqlwhere = keycols.collect { |key, val| "#{key}" + ' = ' + PGconn.quote("#{val}")}.join(' and ') unless sqlwhere and sqlwhere.length > 0 warn "attempted update without where condition. stop" return end sqlstr = "update #{table} set #{sqlset} where #{sqlwhere}" print sqlstr, "\n" res = @@conn[@@dbnom].exec sqlstr print "UPDATE #{res.cmdtuples}\n" return res.cmdtuples if res.cmdtuples > 0 sqlcols = keycols.keys.concat(valcols.keys).collect{|x| "#{x}"}.join(', ') sqlcolvals = keycols.values.concat(valcols.values).collect{|x| PGconn.quote("#{x}")}.join(', ') sqlstr = "insert into #{table} (#{sqlcols}) values (#{sqlcolvals})" print sqlstr, "\n" res = @@conn[@@dbnom].exec(sqlstr) print "INSERT #{res.cmdtuples}\n" return res.cmdtuples end def read_to_end_brace (str, p) p0 = p bracelevel = 1 len = str.length while true p += 1 break unless p < len # print "not less than len #{len}\n" if str[p] == 123; bracelevel += 1 # print "bracelevel up\n" next end if str[p] == 125 bracelevel -= 1 # print "bracelevel down\n" end if bracelevel <= 0 # print "all braces closed\n" break end end return p + 1, str[p0..p] end def vok_split (str) p = 0 len = str.length # { 123 | 124 } 125 texts = Array.new if str[p] == 123 p, elem = read_to_end_brace str, p texts.push elem else p0 = p while p < len; break unless (65..90).include?(str[p]) or (97..122).include?(str[p]) or (49..57).include?(str[p]) or str[p] == 95 p += 1 end texts.push str[p0..p-1] end sepchar = str[p] while p < len bracelevel = 0 p += 1 p0 = p while p < len break if str[p] == sepchar and bracelevel <= 0 bracelevel += 1 if str[p] == 123 bracelevel -= 1 if str[p] == 125 p += 1 end elem = str[p0..p-1] texts.push elem end return texts end def read_fun_args0 (text) p = 0 enc_ch = 0 if text[p] == 40 end_ch = 41 p += 1 end args = Array.new if text[p] == 123 p, sd = read_to_end_brace text, p args.push sd else p0 = p p +=1 while (@@id_chars.grep text[p])[0] args.push text[p0..p-1] end sep = text[p] p0 = p + 1 len = text.length closers = Array.new while begin p += 1;p < len;end ch = text[p] if (@@cjk_opening_chars.grep text[p])[0] closers.unshift @@cjk_opening_closers[text[p]] elsif (@@cjk_closing_chars.grep ch)[0] if closers[0] == text[p] closers.shift elsif text[p] == end_ch p -= 1 break else print "ignoring bracket mismatch at #{p} in #{text}" end end next if closers[0] if ch == sep args.push text[p0..p-1] if p > p0 p0 = p + 1 end end args.push text[p0..p] if p >= p0 return args end def read_fun_args1 (text) closers = Array.new if (@@cjk_opening_chars.grep text[0])[0] closers.unshift @@cjk_opening_closers[text[0]] else return end len = text.length p = 1 # get fun p0 = p p += 1 while ((49..57).collect.grep text[p])[0] fun = text[p0..p-1].to_i sep = text[p] args = Array.new p0 = p + 1 while begin p += 1;p < len;end ch = text[p] if (@@cjk_closing_chars.grep ch)[0] if closers[0] == text[p] closers.shift break unless closers[0] else print "ignoring mismatch at #{p}" end elsif (@@cjk_opening_chars.grep ch)[0] closers.unshift @@cjk_opening_closers[text[p]] end next if closers[1] if ch == sep args.push text[p0..p-1] if p > p0 p0 = p + 1 end end args.push text[p0..p-1] if p > p0 return p, fun, *args end def vok_fill (texts) # args.each { |a| puts a } p = 0 p0 = 0 len = texts[0].length s = String.new n = 0 # print "start vok_fill\n" # texts.each { |t| n += 1;print "#{n}. #{t}\n" } while p < len ch = texts[0][p] if ch == 37 p1 = p-1 # kludgy: remove any backslash escapes that may have been added by LaTeX # we should really do our own simple parsing with these arguments before we allow formatter expansion p1 -= 1 while texts[0][p1] == 92 and p1 > 0 s += texts[0][p0..p1] if p1 >= p0 p +=1 p0 = p ch = texts[0][p] if ch == 40 pd, i_fun, *args1 = read_fun_args1 texts[0][p..len] if i_fun > 0 and texts[i_fun] p += pd fun, *args0 = read_fun_args0 texts[i_fun] vok_args = [fun].concat(args0).concat(args1) vok_args_str = "{vok:" + vok_args.collect { |x| "#{x}" }.join('|') + "}" s += vok_args_str p0 = p + 1 else puts "skipping invalid function argument opener at #{p}" p += 1 end elsif begin i = ch.chr.to_i;i > 0 and texts[i];end s += texts[i] p += 1 p0 = p end end p += 1 end s += texts[0][p0..p] if p >= p0 return s end end class Deplate::Macro::DokVars < Deplate::Macro register_as 'dok_vars' def setup(text) text = text.length > 0 ? text : 'dok_vars' @elt = @deplate.parse(@container, "#{text}; domain: #{@@domain}; lokurl: #{@@lokurl}; urlrxp: #{@@urlrxp}") end end class Deplate::Macro::DokInit < Deplate::Macro register_as 'dok_init' def setup(text) set_dokvars end end class Deplate::Macro::Dok < Deplate::Macro register_as 'dok' def setup(dok) set_dokvars res = @@conn[@@dbnom].exec("select dokurl from mlhtdok where dok = '#{dok}'") if res[0] url = res[0][0] match = @@urlrxp.match(url) href = match ? match[1] : url else href = dok end @elt = @deplate.parse(@container, href) end end class Deplate::Macro::Inklud < Deplate::Macro register_as 'inklud' def setup(text) file = File.new(text) lines = file.collect { |line| line.chomp } file.close sep = @args['sep'] @text = lines.join(sep) end end class Deplate::Macro::DokAnchor < Deplate::Macro register_as 'ah' def setup(text) if !@args; log(['unknown variable args'], :error);return; end set_dokvars dok = String.new(@args['dok'] || '') url = String.new(@args['url'] || '') url_lang = @args['lang'] # if url and /^(\w+)$/.match(url) and not File.readable?(url) # dok = url # end rest = String.new('') if dok; match = /^(\w+)(\/.*)$/.match(dok) if match; dok = match[1];rest = match[2];end doks = [ dok ] while dok = @@alidok[dok] and doks.grep(dok).length == 0 doks = doks.unshift(dok) end dok = doks[0] res = @@conn[@@dbnom].exec("select dokurl from mlhtdok where dok = '#{dok}'") if res[0] url = res[0][0] match = @@urlrxp.match(url) if match; url = match[1];end end end url = url + rest if text && text.length > 0 text = @deplate.parse_and_format(@container, text) elsif dok && dok.length > 0 label = dok lang = @deplate.variables['lang'] res = lang && lang.length == 2 && @@conn[@@dbnom].exec("select mltxt from langtxts where dok = '#{dok}' and lang = '#{lang}' and mlid = 'label'") if res && res[0] label = res[0][0] else res = @@conn[@@dbnom].exec("select mltxt from langtxts where dok = '#{dok}' and lang is null and mlid = 'label'") if res[0] label = res[0][0] else res = @@conn[@@dbnom].exec("select mltxt from langtxts where dok = '#{dok}' and mlid = 'label'") if res[0] label = res[0][0] end end end text = @deplate.parse_and_format(@container, label) elsif url && url.length > 0 text = @deplate.parse_and_format(@container, url) end if url_lang url = if url;then url;else ".";end url = url + "/index." + url_lang + ".html" end if url @text = format_particle(:format_url, self, text, url, nil) elsif dok @text = text || "#{dok}" else @text = text end @text = 'NULL TEXT ERROR' unless @text.length > 0 end end class Deplate::Macro::Ag < Deplate::Macro register_as 'ag' def setup(text) if !@args; log(['unknown variable args'], :error);return; end set_dokvars dok = @args['dok'] url = @args['url'] lang = @args['lang'] ref = @args['ref'] de = @args['de'] al = @args['al'] rkod = @args['rkod'] ust = @args['ust'] mon = @args['mon'] fdat = @args['fdat'] idat = @args['idat'] odat = @args['odat'] rem = @args['rem'] status = @args['status'] vals = @args.dup.delete_if {|key, val| ['dok', '@id'].rindex(key) or not key.is_a?(String) or not val.is_a?(String) }.collect {|key, val| [key, val].join(': ') }.join('; ') text = @deplate.parse_and_format(@container, "#{vals}: #{text}") if dok or url doktext = dok or url text = [get_dok_anchor_text(doktext, dok, url, lang, ref), text].join(': ') end @text = text || 'NULL TEXT ERROR' dbput :spez, { :spez => dok }, { :spezde => de, :spezal => al, :spzrkod => rkod, :ustvat => ust, :spezmon => mon, :spzfdat => fdat, :spzidat => idat, :spzodat => odat, :speznom => @args['nom'], :spezdes => @args['des'], :spezode => @args['ode'], :prespz => @args['pre'] } end end class Deplate::Macro::Sql < Deplate::Macro register_as 'sql' def setup(text) return unless text set_dokvars print text, "\n"; res = @@conn[@@dbnom].exec text return res.cmdtuples end end class Deplate::Macro::Dbtab < Deplate::Macro register_as 'dbtab' def setup(text) if !@args; log(['unknown variable args'], :error);return; end # @args = { 'keys' => "mail uid ref", 'vals' =>"user host rem", 'user' => 'mailuser', 'host' => 'mailhost', 'ref' => 'mailref', 'rem' => 'mailrem', 'text' => 'rem' } # text = "address of {arg:mail_uid} is {arg:mail_mailuser}@{arg:mail_mailhost}" argvals = @args.collect { |key, val| val.is_a?(String) && [key, val].join(': ') }.delete_if { |key| not key }.join(', ') # print "dbtab argvals: " + argvals + "\n" keys = @args['keys'].split.collect { |key| key.intern } tab = keys.shift vals = @args['vals'].split.collect { |key| key.intern } brev_arr = [keys, vals, ['text',tab]].flatten.collect { |key| ks = key.to_s;@args[ks] && [ ks, @args[ks] ] }.compact.flatten.collect { |key| key.intern } brev = Hash[*brev_arr] @@dbtabs[tab] = [ keys, vals, brev, text ] keys_str = keys.collect { |key| key.to_s }.join(', ') vals_str = vals.collect { |val| val.to_s }.join(', ') brev_str = brev.collect { |key, val| [key.to_s, val.to_s ].join(": ") }.join(', ') @text = "dbtab " + tab.to_s + "; keys " + keys_str + "; vals " + vals_str + "; brev " + brev_str @text ||= 'NULL TEXT ERROR' end end class Deplate::Macro::Db < Deplate::Macro register_as 'db' def setup(text) if !@args; log(['unknown variable args'], :error);return; end set_dokvars # @args = { 'rek' => 'mail phm norm', 'user'=>'phm', 'host'=>'a2e.de' } # text = "abcdef" argvals = @args.collect { |key, val| val.is_a?(String) && [key, val].join(': ') }.delete_if { |key| not key }.join(', ') # print "db argvals: " + argvals + "\n" rek = @args['rek'] if !rek; log(['no rek found'], :error);return;end dok = @args['dok'] url = @args['url'] keyvals = rek.split.collect { |key| key.intern } valtups = @args.dup.delete_if {|key, val| key == 'rek' or not key.is_a?(String) or not val.is_a?(String) }; valtext = valtups.collect {|key, val| [key, val].join(': ') }.join('; ') # print "valtups: " + valtext + "\n" valtups = valtups.collect { |key, val| [key.intern, val] } valtext = valtups.collect {|key, val| [key.to_s, val].join(': ') }.join('; ') # print "valtups: " + valtext + "\n" textval = text @text = text tab = keyvals.shift # print "tab #{tab}\n" begin raise "@@dbtabs not found" unless @@dbtabs raise "@@dbtabs is not an array" unless @@dbtabs.is_a?(Hash) rescue Exception => e puts e.message puts e.backtrace.inspect end tabdef = @@dbtabs[tab] # print "tabdef was #{tabdef}" + "\n"; begin raise "tabdef not found for #{tab}" unless tabdef raise "tabdef of #{tab} is not an array" unless tabdef.is_a?(Array) rescue Exception => e puts e.message puts e.backtrace.inspect end tabdef = tabdef.dup tabkeykeys = tabdef.shift begin raise "not array in tabkeykeys" unless tabkeykeys.is_a?(Array) rescue Exception => e puts e.message puts e.backtrace.inspect end tabvalkeys = tabdef.shift begin raise "not array in tabvalkeys" unless tabvalkeys.is_a?(Array) rescue Exception => e puts e.message puts e.backtrace.inspect end tabbrevs = tabdef.shift begin raise "not hash in tabbrevs" unless tabbrevs.is_a?(Hash) rescue Exception => e puts e.message puts e.backtrace.inspect end textkey = tabbrevs[:text] if textkey; textkey = tabbrevs[textkey] || textkey end tab_str = tab.to_s tab = tabbrevs[tab] || tab keys_arr = tabkeykeys.zip(keyvals).collect { |key, val| var = [tab_str,key.to_s].join('_'); # print "deplate variables of #{var} is #{val}\n"; @deplate.variables[var] = val.to_s next unless tabkeykeys.include?(key) key = tabbrevs[key] || key; [key, val] }.compact.flatten keytups = Hash[*keys_arr] # print "keytups: " + keytups.collect { |key, val| [key.to_s, val.to_s].join(": ") }.join(', ') + "\n" vals_arr = valtups.collect { |key, val| var = [tab_str,key.to_s].join('_'); # print "deplate variables of #{var} is #{val}\n"; @deplate.variables[var] = val.to_s next unless tabvalkeys.include?(key) key = tabbrevs[key] || key; [key, val] }.compact.flatten valtups = Hash[*vals_arr] begin raise "not hash in valtups" unless valtups.is_a?(Hash) rescue Exception => e puts e.message puts e.backtrace.inspect end valtext = valtups.collect {|key, val| [key.to_s, val].join(': ') }.join('; ') # print "valtups before textkey #{textkey} insertion: " + valtext + "\n" if textkey; valtups[textkey] ||= textval; if valtups[textkey].length > 0; # print "valtups of textkey #{textkey} is now " + valtups[textkey] + "\n" else valtups.delete(textkey) end end valtups = valtups.delete_if { |key, val| not key }; valtext = valtups.collect {|key, val| [key.to_s, val].join(': ') }.join('; ') # print "valtups: " + valtext + "\n" dbput tab, keytups, valtups tabtmpl = tabdef.shift begin raise "not string tabtmpl" unless tabtmpl.is_a?(String) rescue Exception => e puts e.message puts e.backtrace.inspect end # print "tabtmpl: #{tabtmpl}\n" text = @deplate.parse_and_format(@container, tabtmpl) # print "text: #{text}\n" if dok or url doktext = dok or url lang = @args['lang'] || @deplate.variables['lang'] ref = @args['ref'] text = [get_dok_anchor_text(doktext, dok, url, lang, ref), text].join(': ') end @text = text end end class Deplate::Macro::TaDok < Deplate::Macro register_as 'td' def setup(text) if !@args; log(['unknown variable args'], :error);return; end set_dokvars ta = @args['ta'] dok = @args['dok'] ktg = @args['ktg'] ref = @args['ref'] url = @args['url'] rem = text vals = @args.dup.delete_if {|key, val| ['dok', '@id'].rindex(key) or not key.is_a?(String) or not val.is_a?(String) }.collect {|key, val| [key, val].join(': ') }.join('; ') text = @deplate.parse_and_format(@container, "#{vals}: #{rem}") text = @deplate.parse_and_format(@container, text) lang = @deplate.variables['lang'] if dok text = [get_dok_anchor_text("#{dok}", dok, url, lang, ref), text].join(': ') end @text = text dbput :tadok, { :ta => ta, :dok =>dok }, { :tarem => rem, :taktg => ktg } end end class Deplate::Macro::TaKtg < Deplate::Macro register_as 'taktg' def setup(text) if !@args; log(['unknown variable args'], :error);return; end set_dokvars ta = @args['ta'] sup = @args['sup'] rem = text vals = @args.dup.delete_if {|key, val| ['dok', '@id'].rindex(key) or not key.is_a?(String) or not val.is_a?(String) }.collect {|key, val| [key, val].join(': ') }.join('; ') text = @deplate.parse_and_format(@container, "#{vals}: #{rem}") @text = @deplate.parse_and_format(@container, text) lang = @deplate.variables['lang'] dbput :taktg, { :taktg => ta }, { :taktgrem => rem, :supktg => sup } end end class Deplate::Macro::Ev < Deplate::Macro register_as 'ev' def setup(text) if !@args; log(['unknown variable args'], :error);return; end set_dokvars id = @args['id'] || @args['ev'] dok = @args['dok'] || @deplate.variables['dok'] url = @args['url'] lang = @args['lang'] ref = @args['ref'] dat = @args['dat'] typ = @args['typ'] rem = @args['rem'] prs = @args['prs'] ta = @args['ta'] delta = @args['dlt'] cert = @args['cert'] vals = @args.dup.delete_if {|key, val| ['dok', 'id', '@id', 'cert', 'typ'].rindex(key) or not key.is_a?(String) or not val.is_a?(String) }.collect {|key, val| [key, val].join(': ') }.join('; ') text = @deplate.parse_and_format(@container, "#{vals}: #{text}"); @text = text @text = 'NULL TEXT ERROR' unless @text.length > 0 return unless dok and dbput_ok? if dok or url doktext = id or dok or url text = [get_dok_anchor_text(doktext, dok, url, lang, ref), text].join(': ') end if cert and cert.length > 0;then n = 1 - cert.to_i if n > 0 sfx = "?" * n text = sfx + text + sfx end end @text = text @text = 'NULL TEXT ERROR' unless @text.length > 0 end end class Deplate::Macro::Person < Deplate::Macro register_as 'person' def setup(text) if !@args; log(['unknown variable args'], :error);return; end set_dokvars vals = @args.dup.delete_if {|key, val| ['dok', 'id', '@id', 'person'].rindex(key) or not key.is_a?(String) or not val.is_a?(String) }.collect {|key, val| [key, val].join(': ') }.join('; ') text = @deplate.parse_and_format(@container, "#{vals}: #{text}"); @text = text return unless dbput_ok? person = @args['id'] or @args['person'] if person text = [get_dok_anchor_text(person, person, @args['url'], @args['lang'], @args['ref']), text].join(': ') end return unless person typ = @args['typ'] dbput :person, { :person => person }, { :persnom => @args['nom'], :persdes => @args['des'], :perstyp => typ, :rol => @args['rol'], :lok => @args['lok'], :mail => @args['mail'] } land = @args['land'] case typ when 'hom' genus = @args['genus'] or @args['mf'] dbput :hom, { :person => person }, { :genus => genus } if genus when 'frm' supfrm = @args['supfrm'] dbput :frm, { :person => person }, { :supfrm => supfrm, :land => land } if land end plz = @args['plz'] or @args['zip'] if plz or @args['str'] or @args['dom'] dbput :adr, { :person => person }, { :postkod => plz, :urb => @args['urb'], :urber => @args['urb2'], :strad => @args['str'], :strader => @args['str2'], :dom => @args['dom'], :domer => @args['dom2'] } end end end class Deplate::Macro::Ml < Deplate::Macro register_as 'ml' def setup(text) id = @args['id'] if id;@@tokens[id] = text;end text = @deplate.parse_and_format(@container,text) brev = @args['brev']; if brev @@abbrevs[brev] = text @text = brev else @text = text end end end class Deplate::Macro::Vok < Deplate::Macro register_as 'vok' def setup(text) # print "vok starts with argument text #{text}\n" texts = vok_split text # print "splitted into the following texts:\n"; 0.upto(texts.length-1) { |n| print "\t" + n.to_s + ". " + texts[n] + "\n" } # print "Now the formatted arguments\n"; 1.upto(texts.length-1) { |n| texts[n] = @deplate.parse_and_format(@container, texts[n]) # print "\t" + n.to_s + ". " + texts[n] + "\n" } case texts[0] when 'tp' text = "#{texts[1]} (#{texts[2]})"; when 'pe' text = "#{texts[2]} (#{texts[1]})"; when 'un' text = "#{texts[2]} #{texts[1]}"; when 'comma_list' text = texts[1..texts.length-1].join(', ') when 'koniug' text = texts[2..texts.length-2].join(', ') + ' ' + @@tokens[texts[1]] + ' ' + texts[texts.length-1]; when 'join' text = texts[2..texts.length-1].join(texts[1]) when 'land' res = @@conn[@@dbnom].exec("select landdes from isoland where land = '#{texts[1]}'") text = res[0][0] else if @@tokens[texts[0]] texts[0] = @@tokens[texts[0]] # print "predicate was among registered tokens, is now #{texts[0]}\n"; end texts[0] = @deplate.parse_and_format(@container,texts[0]) # print "here is the formatted predicate: #{texts[0]}\n" text = vok_fill texts # print "this is the result after vok_fill expansion: #{text}\n" text = @deplate.parse_and_format(@container,text) # print "and this is the result after deplate parsing: #{text}\n" end id = @args['id'] if id # print "vok registering token #{id} as #{text}\n" @@tokens[id] = text end brev = @args['brev']; if brev; @@abbrevs[brev] = text @text = brev else @text = text end # print "from vok return #{@text}\n" end end class Deplate::Macro::Abbrevs < Deplate::Macro register_as 'abbrevs' def setup(text) sep = @args['sep'] || '; ' @text = @@abbrevs.sort.collect { |k, v| "#{k}: #{v}" }.join(sep) @@abbrevs = {}; end end class Deplate::Macro::Css < Deplate::Macro register_as 'css' def setup(text) dok = @args['dok'] set_dokvars @text = "" # print "from css return #{@text}\n" end end