summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/scripts/context/ruby/base/texutil.rb
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/scripts/context/ruby/base/texutil.rb')
-rw-r--r--Master/texmf-dist/scripts/context/ruby/base/texutil.rb308
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