diff options
Diffstat (limited to 'Master/texmf-dist/scripts/context/ruby/base/texutil.rb')
-rw-r--r-- | Master/texmf-dist/scripts/context/ruby/base/texutil.rb | 308 |
1 files changed, 232 insertions, 76 deletions
diff --git a/Master/texmf-dist/scripts/context/ruby/base/texutil.rb b/Master/texmf-dist/scripts/context/ruby/base/texutil.rb index c279bcc97a6..2bca831675e 100644 --- a/Master/texmf-dist/scripts/context/ruby/base/texutil.rb +++ b/Master/texmf-dist/scripts/context/ruby/base/texutil.rb @@ -51,12 +51,21 @@ class TeXUtil @logger = logger end + def report(str) + @logger.report("fatal error in plugin (#{str}): #{$!}") + puts("\n") + $@.each do |line| + puts(" #{line}") + end + puts("\n") + end + def reset(name) if @plugins.include?(name) then begin eval("#{name}").reset(@logger) rescue Exception - @logger.report("fatal error in resetting plugin") + report("resetting") end else @logger.report("no plugin #{name}") @@ -89,7 +98,7 @@ class TeXUtil begin eval("#{name}").reader(@logger,data.flatten) rescue Exception - @logger.report("fatal error in plugin reader #{name} (#{$!})") + report("reading") end else @logger.report("no plugin #{name}") @@ -107,7 +116,7 @@ class TeXUtil begin eval("#{p}").writer(@logger,handle) rescue Exception - @logger.report("fatal error in plugin writer #{p} (#{$!})") + report("writing") end end end @@ -117,7 +126,17 @@ class TeXUtil begin eval("#{p}").processor(@logger) rescue Exception - @logger.report("fatal error in plugin processor #{p} (#{$!})") + report("processing") + end + end + end + + def finalizers + @plugins.each do |p| + begin + eval("#{p}").finalizer(@logger) + rescue Exception + report("finalizing") end end end @@ -126,6 +145,8 @@ class TeXUtil class Sorter + @@downcase = true + def initialize(max=12) @rep, @map, @exp, @div = Hash.new, Hash.new, Hash.new, Hash.new @max = max @@ -149,7 +170,7 @@ class TeXUtil # sorter.expander('ijligature', 'y') def expander(from,to=nil) - from, to = converted(from), converted(to) + to = converted(to) # not from !!! @max = [@max,to.length+1].max if to @exp[from] = to || from || '' end @@ -179,16 +200,50 @@ class TeXUtil end if @map.size > 0 then # watch out, order of match matters - @rexb = /(\\[a-zA-Z]+|#{@map.keys.join('|')}|.)\s*/ # o + if @@downcase then + @rexb = /(\\[a-zA-Z]+|#{@map.keys.join('|')}|.)\s*/i # o + else + @rexb = /(\\[a-zA-Z]+|#{@map.keys.join('|')}|.)\s*/ # o + end else - @rexb = /(\\[a-zA-Z]+|.)\s*/o + if @@downcase then + @rexb = /(\\[a-zA-Z]+|.)\s*/io + else + @rexb = /(\\[a-zA-Z]+|.)\s*/o + end + end + if false then + @exp.keys.each do |e| + @exp[e].downcase! + end end end + def replace(str) + if @rexa then + str.gsub(@rexa) do + @rep[$1.escaped] + end + else + str + end + end + + def normalize(str) + # replace(str).gsub(/ +/,' ') + replace(str).gsub(/\s\s+/," \\space") + end + + def tokenize(str) + str.gsub(/\\strchr\{(.*?)\}/o) do "\\#{$1}" end + end + def remap(str) s = str.dup - s.gsub!(/(\d+)/o) do - $1.rjust(10,'a') # rest is b .. k + if true then # numbers are treated special + s.gsub!(/(\d+)/o) do + $1.rjust(10,'a') # rest is b .. k + end end if @rexa then s.gsub!(@rexa) do @@ -198,6 +253,9 @@ class TeXUtil if @rexb then s.gsub!(@rexb) do token = $1.sub(/\\/o, '') + if @@downcase then + token.downcase! + end if @exp.key?(token) then @exp[token].ljust(@max,' ') elsif @map.key?(token) then @@ -210,17 +268,16 @@ class TeXUtil s end - def preset(shortcuts=[],expansions=[],reductions=[],divisions=[]) - # maybe we should move this to sort-def.tex + def preset(shortcuts=[],expansions=[],reductions=[],divisions=[],language='') 'a'.upto('z') do |c| expander(c) ; division(c) end + 'A'.upto('Z') do |c| expander(c) ; division(c) end expander('1','b') ; expander('2','c') ; expander('3','e') ; expander('4','f') expander('5','g') ; expander('6','h') ; expander('7','i') ; expander('8','i') expander('9','j') ; expander('0','a') ; expander('-','-') ; - # end potential move - shortcuts.each do |s| shortcut(s[0],s[1]) end - expansions.each do |e| expander(e[0],e[1]) end - reductions.each do |r| reducer(r[0],r[1]) end - divisions.each do |d| division(d[0],d[1]) end + shortcuts.each do |s| shortcut(s[1],s[2]) if s[0] == '' || s[0] == language end + expansions.each do |e| expander(e[1],e[2]) if e[0] == '' || e[0] == language end + reductions.each do |r| reducer(r[1],r[2]) if r[0] == '' || r[0] == language end + divisions.each do |d| division(d[1],d[2]) if d[0] == '' || d[0] == language end end def simplify(str) @@ -240,7 +297,7 @@ class TeXUtil # what to do with xml and utf-8 # \"e etc # unknown \cs - s.gsub!(/\\[a-z][a-z]+\s*\{(.*?)\}/o) do $1 end + s.gsub!(/\\[a-zA-Z][a-zA-Z]+\s*\{(.*?)\}/o) do $1 end return s end @@ -256,6 +313,7 @@ class TeXUtil def converted(str) if str then + # puts str str.gsub(/([\+\-]*\d+)/o) do n = $1.to_i if n > 0 then @@ -277,20 +335,18 @@ class TeXUtil module MyFiles - @@files = Hash.new + @@files, @@temps = Hash.new, Hash.new def MyFiles::reset(logger) - @@files = Hash.new + @@files, @@temps = Hash.new, Hash.new end def MyFiles::reader(logger,data) case data[0] when 'b', 'e' then - if @@files.key?(data[1]) then - @@files[data[1]] += 1 - else - @@files[data[1]] = 1 - end + @@files[data[1]] = (@@files[data[1]] ||0) + 1 + when 't' then # temporary file + @@temps[data[1]] = (@@temps[data[1]] ||0) + 1 end end @@ -299,14 +355,24 @@ class TeXUtil @@files.keys.sort.each do |k| handle << "% > #{k} #{@@files[k]/2}\n" end + handle << logger.banner("temporary files: #{@@temps.size}") + @@temps.keys.sort.each do |k| + handle << "% > #{k} #{@@temps[k]}\n" + end end def MyFiles::processor(logger) @@files.keys.sort.each do |k| unless (@@files[k] % 2) == 0 then - logger.report("check loading of file #{k}, begin/end problem") + logger.report("check loading of file '#{k}', begin/end problem") end end + @@temps.keys.sort.each do |k| + # logger.report("temporary file '#{k}' can be deleted") + end + end + + def MyFiles::finalizer(logger) end end @@ -337,6 +403,9 @@ class TeXUtil def MyCommands::processor(logger) end + def MyCommands::finalizer(logger) + end + end end @@ -367,7 +436,15 @@ class TeXUtil def MyExtras::processor(logger) @@programs.each do |p| - cmd = "texmfstart #{@@programs[p.to_i]}" + # cmd = @@programs[p.to_i] + # logger.report("running #{cmd}") + # system(cmd) + end + end + + def MyExtras::finalizer(logger) + @@programs.each do |p| + cmd = @@programs[p.to_i] logger.report("running #{cmd}") system(cmd) end @@ -395,7 +472,8 @@ class TeXUtil attr_writer :sortkey def build(sorter) - @sortkey = sorter.remap(sorter.simplify(@key.downcase)) + @sortkey = sorter.normalize(sorter.tokenize(@sortkey)) + @sortkey = sorter.remap(sorter.simplify(@key.downcase)) # ?? if @sortkey.empty? then @sortkey = sorter.remap(@command.downcase) end @@ -418,16 +496,23 @@ class TeXUtil end - @@synonyms = Hash.new + @@synonyms = Hash.new + @@sorter = Hash.new + @@languages = Hash.new def MySynonyms::reset(logger) - @@synonyms = Hash.new + @@synonyms = Hash.new + @@sorter = Hash.new + @@languages = Hash.new end def MySynonyms::reader(logger,data) - if data[0] == 'e' then - @@synonyms[data[1]] = Array.new unless @@synonyms.key?(data[1]) - @@synonyms[data[1]].push(Synonym.new(data[1],data[2],data[3],data[4])) + case data[0] + when 'e' then + @@synonyms[data[1]] = Array.new unless @@synonyms.key?(data[1]) + @@synonyms[data[1]].push(Synonym.new(data[1],data[2],data[3],data[4])) + when 'l' then + @@languages[data[1]] = data[2] || '' end end @@ -441,17 +526,25 @@ class TeXUtil end def MySynonyms::processor(logger) - sorter = Sorter.new - sorter.preset(eval("MyKeys").shortcuts,eval("MyKeys").expansions,eval("MyKeys").reductions,eval("MyKeys").divisions) - sorter.prepare @@synonyms.keys.each do |s| + @@sorter[s] = Sorter.new + @@sorter[s].preset( + eval("MyKeys").shortcuts, + eval("MyKeys").expansions, + eval("MyKeys").reductions, + eval("MyKeys").divisions, + @@languages[s] || '') + @@sorter[s].prepare @@synonyms[s].each_index do |i| - @@synonyms[s][i].build(sorter) + @@synonyms[s][i].build(@@sorter[s]) end @@synonyms[s] = @@synonyms[s].sort end end + def MySynonyms::finalizer(logger) + end + end end @@ -462,6 +555,9 @@ class TeXUtil class Register + @@specialsymbol = "\000" + @@specialbanner = "" # \\relax" + @@debug = false @@debug = true @@ -475,6 +571,7 @@ class TeXUtil @key = @entry.dup if @key.empty? @sortkey = @key.dup @nofentries, @nofpages = 0, 0 + @normalizeentry = false end attr_reader :state, :type, :location, :key, :entry, :seetoo, :page, :realpage, :texthowto, :pagehowto @@ -482,34 +579,55 @@ class TeXUtil attr_writer :sortkey def build(sorter) - @entry, @key = [@entry, @key].collect do |target| - # +a+b+c &a&b&c a+b+c a&b&c - case target[0,1] - when '&' then target = target.sub(/^./o,'').gsub(/([^\\])\&/o) do "#{$1}#{@@split}" end - when '+' then target = target.sub(/^./o,'').gsub(/([^\\])\+/o) do "#{$1}#{@@split}" end - else target = target .gsub(/([^\\])[\&\+]/o) do "#{$1}#{@@split}" end + # @entry, @key = sorter.normalize(@entry), sorter.normalize(sorter.tokenize(@key)) + @entry = sorter.normalize(sorter.tokenize(@entry)) if @normalizeentry + @key = sorter.normalize(sorter.tokenize(@key)) + if false then + @entry, @key = [@entry, @key].collect do |target| + # +a+b+c &a&b&c a+b+c a&b&c + case target[0,1] + when '&' then target = target.sub(/^./o,'').gsub(/([^\\])\&/o) do "#{$1}#{@@split}" end + when '+' then target = target.sub(/^./o,'').gsub(/([^\\])\+/o) do "#{$1}#{@@split}" end + else target = target .gsub(/([^\\])[\&\+]/o) do "#{$1}#{@@split}" end + end + # {a}{b}{c} + # if target =~ /^\{(.*)\}$/o then + # $1.split(/\} \{/o).join(@@split) # space between } { is mandate + # else + target + # end end - # {a}{b}{c} - # if target =~ /^\{(.*)\}$/o then - # $1.split(/\} \{/o).join(@@split) # space between } { is mandate - # else - target - # end + else + @entry, @key = cleanupsplit(@entry), cleanupsplit(@key) end @sortkey = sorter.simplify(@key) + # special = @sortkey =~ /^([^a-zA-Z\\])/o + special = @sortkey =~ /^([\`\~\!\@\#\$\%\^\&\*\(\)\_\-\+\=\{\}\[\]\:\;\"\'\|\<\,\>\.\?\/\d])/o @sortkey = @sortkey.split(@@split).collect do |c| sorter.remap(c) end.join(@@split) - # if ($Key eq "") { $Key = SanitizedString($Entry) } - # if ($ProcessHigh){ $Key = HighConverted($Key) } + if special then + @sortkey = "#{@@specialsymbol}#{@sortkey}" + end @sortkey = [ @sortkey.downcase, @sortkey, + @entry, @texthowto.ljust(10,' '), - @state, - @realpage.rjust(6,' '), + # @state, # no, messes up things + (@realpage ||'').rjust(6,' ').gsub(/0/,' '), + # (@realpage ||'').rjust(6,' '), @pagehowto ].join(@@split) end + def cleanupsplit(target) + # +a+b+c &a&b&c a+b+c a&b&c + case target[0,1] + when '&' then target.sub(/^./o,'').gsub(/([^\\])\&/o) do "#{$1}#{@@split}" end + when '+' then target.sub(/^./o,'').gsub(/([^\\])\+/o) do "#{$1}#{@@split}" end + else target .gsub(/([^\\])[\&\+]/o) do "#{$1}#{@@split}" end + end + end + def <=> (other) @sortkey <=> other.sortkey end @@ -555,18 +673,20 @@ class TeXUtil else testalpha = entry.sortkey[0,1].downcase end - if testalpha != alpha.downcase or alphaclass != entry.class then + if (testalpha != alpha.downcase) || (alphaclass != entry.class) then alpha = testalpha alphaclass = entry.class if alpha != ' ' then flushsavedline(handle) if alpha =~ /^[a-zA-Z]$/o then character = alpha.dup + elsif alpha == @@specialsymbol then + character = @@specialbanner elsif alpha.length > 1 then # character = "\\getvalue\{#{alpha}\}" character = "\\#{alpha}" else - character = "\\#{alpha}" + character = "\\unknown" end handle << "\\registerentry{#{entry.type}}{#{character}}\n" end @@ -614,6 +734,7 @@ class TeXUtil Register.flushsavedline(handle) handle << "\\registersee{#{entry.type}}{#{entry.pagehowto},#{entry.texthowto}}{#{entry.seetoo}}{#{entry.page}}\n" ; lastpage, lastrealpage = entry.page, entry.realpage + copied = false # no page ! elsif @@savedhowto != entry.pagehowto and ! entry.pagehowto.empty? then @@savedhowto = entry.pagehowto end @@ -648,11 +769,13 @@ class TeXUtil end @@registers = Hash.new - @@sorter = Sorter.new + @@sorter = Hash.new + @@languages = Hash.new def MyRegisters::reset(logger) @@registers = Hash.new - @@sorter = Sorter.new + @@sorter = Hash.new + @@languages = Hash.new end def MyRegisters::reader(logger,data) @@ -669,6 +792,8 @@ class TeXUtil when 's' then @@registers[data[1]] = Array.new unless @@registers.key?(data[1]) @@registers[data[1]].push(Register.new(4,data[1],data[2],data[3],data[4],data[5],data[6],nil)) + when 'l' then + @@languages[data[1]] = data[2] || '' end end @@ -676,23 +801,32 @@ class TeXUtil if @@registers.size > 0 then @@registers.keys.sort.each do |s| handle << logger.banner("registers: #{s} #{@@registers[s].size}") - Register.flush(@@registers[s],handle,@@sorter) + Register.flush(@@registers[s],handle,@@sorter[s]) # report("register #{@@registers[s].class}: #{@@registers[s].@nofentries} entries and #{@@registers[s].@nofpages} pages") end end end def MyRegisters::processor(logger) - @@sorter.preset(eval("MyKeys").shortcuts,eval("MyKeys").expansions,eval("MyKeys").reductions,eval("MyKeys").divisions) - @@sorter.prepare @@registers.keys.each do |s| + @@sorter[s] = Sorter.new + @@sorter[s].preset( + eval("MyKeys").shortcuts, + eval("MyKeys").expansions, + eval("MyKeys").reductions, + eval("MyKeys").divisions, + @@languages[s] || '') + @@sorter[s].prepare @@registers[s].each_index do |i| - @@registers[s][i].build(@@sorter) + @@registers[s][i].build(@@sorter[s]) end @@registers[s] = @@registers[s].sort end end + def MyRegisters::finalizer(logger) + end + end end @@ -730,6 +864,10 @@ class TeXUtil @@plugins.processors if @@plugins end + def MyPlugins::finalizer(logger) + @@plugins.finalizers if @@plugins + end + end end @@ -764,7 +902,7 @@ class TeXUtil def MyKeys::reader(logger,data) key = data.shift - grp = data.shift # language code, todo + # grp = data.shift # language code, todo case key when 's' then @@shortcuts.push(data) when 'e' then @@expansions.push(data) @@ -783,6 +921,9 @@ class TeXUtil logger.report("divisions : #{@@divisions.size}") # logger.report(@@divisions.inspect) end + def MyKeys::finalizer(logger) + end + end end @@ -816,24 +957,31 @@ class TeXUtil def loaded(filename) begin - report("parsing file #{filename}") - if f = open(File.suffixed(filename,'tui')) then - f.each do |line| - case line.chomp - when /^f (.*)$/o then @plugins.reader('MyFiles', $1.splitdata) - when /^c (.*)$/o then @plugins.reader('MyCommands', [$1]) - when /^e (.*)$/o then @plugins.reader('MyExtras', $1.splitdata) - when /^s (.*)$/o then @plugins.reader('MySynonyms', $1.splitdata) - when /^r (.*)$/o then @plugins.reader('MyRegisters',$1.splitdata) - when /^p (.*)$/o then @plugins.reader('MyPlugins', $1.splitdata) - when /^x (.*)$/o then @plugins.reader('MyKeys', $1.splitdata) - else report("unknown entry #{line[0,1]} in line #{line.chomp}") + tuifile = File.suffixed(filename,'tui') + if FileTest.file?(tuifile) then + report("parsing file #{tuifile}") + if f = open(tuifile) then + f.each do |line| + case line.chomp + when /^f (.*)$/o then @plugins.reader('MyFiles', $1.splitdata) + when /^c (.*)$/o then @plugins.reader('MyCommands', [$1]) + when /^e (.*)$/o then @plugins.reader('MyExtras', $1.splitdata) + when /^s (.*)$/o then @plugins.reader('MySynonyms', $1.splitdata) + when /^r (.*)$/o then @plugins.reader('MyRegisters',$1.splitdata) + when /^p (.*)$/o then @plugins.reader('MyPlugins', $1.splitdata) + when /^x (.*)$/o then @plugins.reader('MyKeys', $1.splitdata) + when /^r (.*)$/o then # nothing, not handled here + else + # report("unknown entry #{line[0,1]} in line #{line.chomp}") + end end + f.close end - f.close + else + report("unable to locate #{tuifile}") end rescue - report("fatal error in parsing #{filename}") + report("fatal error in parsing #{tuifile}") @filename = 'texutil' else @filename = filename @@ -848,19 +996,27 @@ class TeXUtil def saved(filename=@filename) if @fatalerror then report("fatal error, no tuo file saved") + return false else - begin + begin if f = File.open(File.suffixed(filename,'tuo'),'w') then @plugins.writers(f) f.close end rescue report("fatal error when saving file (#{$!})") + return false else report("tuo file saved") + return true end end + end + + def finalized + @plugins.finalizers @plugins.resets + return true # for the moment end def reset |