summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/scripts/context/ruby/base/texutil.rb
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2006-01-09 01:54:09 +0000
committerKarl Berry <karl@freefriends.org>2006-01-09 01:54:09 +0000
commit50b347972956e0bfbe7029305e0f459e5ce3ac0c (patch)
treed1b824bbc33a30bf7fcf54b866a1cff949d2e0bf /Master/texmf-dist/scripts/context/ruby/base/texutil.rb
parent52f01b2f769ac290674a469d46f149985042ee2e (diff)
trunk/Master/texmf-dist/scripts
git-svn-id: svn://tug.org/texlive/trunk@92 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/scripts/context/ruby/base/texutil.rb')
-rw-r--r--Master/texmf-dist/scripts/context/ruby/base/texutil.rb872
1 files changed, 872 insertions, 0 deletions
diff --git a/Master/texmf-dist/scripts/context/ruby/base/texutil.rb b/Master/texmf-dist/scripts/context/ruby/base/texutil.rb
new file mode 100644
index 00000000000..c279bcc97a6
--- /dev/null
+++ b/Master/texmf-dist/scripts/context/ruby/base/texutil.rb
@@ -0,0 +1,872 @@
+require "base/file"
+require "base/logger"
+
+class String
+
+ # real dirty, but inspect does a pretty good escaping but
+ # unfortunately puts quotes around the string so we need
+ # to strip these
+
+ # def escaped
+ # self.inspect[1,self.inspect.size-2]
+ # end
+
+ def escaped
+ str = self.inspect ; str[1,str.size-2]
+ end
+
+ def splitdata
+ if self =~ /^\s*(.*?)\s*\{(.*)\}\s*$/o then
+ first, second = $1, $2
+ if first.empty? then
+ [second.split(/\} \{/o)].flatten
+ else
+ [first.split(/\s+/o)] + [second.split(/\} \{/o)]
+ end
+ else
+ []
+ end
+ end
+
+end
+
+class Logger
+ def banner(str)
+ report(str)
+ return "%\n% #{str}\n%\n"
+ end
+end
+
+class TeXUtil
+
+ class Plugin
+
+ # we need to reset module data for each run; persistent data is
+ # possible, just don't reinitialize the data structures that need
+ # to be persistent; we reset afterwards becausethen we know what
+ # plugins are defined
+
+ def initialize(logger)
+ @plugins = Array.new
+ @logger = logger
+ end
+
+ def reset(name)
+ if @plugins.include?(name) then
+ begin
+ eval("#{name}").reset(@logger)
+ rescue Exception
+ @logger.report("fatal error in resetting plugin")
+ end
+ else
+ @logger.report("no plugin #{name}")
+ end
+ end
+
+ def resets
+ @plugins.each do |p|
+ reset(p)
+ end
+ end
+
+ def register(name, file=nil) # maybe also priority
+ if file then
+ begin
+ require("#{file.downcase.sub(/\.rb$/,'')}.rb")
+ rescue Exception
+ @logger.report("no plugin file #{file} for #{name}")
+ else
+ @plugins.push(name)
+ end
+ else
+ @plugins.push(name)
+ end
+ return self
+ end
+
+ def reader(name, data=[])
+ if @plugins.include?(name) then
+ begin
+ eval("#{name}").reader(@logger,data.flatten)
+ rescue Exception
+ @logger.report("fatal error in plugin reader #{name} (#{$!})")
+ end
+ else
+ @logger.report("no plugin #{name}")
+ end
+ end
+
+ def readers(data=[])
+ @plugins.each do |p|
+ reader(p,data.flatten)
+ end
+ end
+
+ def writers(handle)
+ @plugins.each do |p|
+ begin
+ eval("#{p}").writer(@logger,handle)
+ rescue Exception
+ @logger.report("fatal error in plugin writer #{p} (#{$!})")
+ end
+ end
+ end
+
+ def processors
+ @plugins.each do |p|
+ begin
+ eval("#{p}").processor(@logger)
+ rescue Exception
+ @logger.report("fatal error in plugin processor #{p} (#{$!})")
+ end
+ end
+ end
+
+ end
+
+ class Sorter
+
+ def initialize(max=12)
+ @rep, @map, @exp, @div = Hash.new, Hash.new, Hash.new, Hash.new
+ @max = max
+ @rexa, @rexb = nil, nil
+ end
+
+ def replacer(from,to='') # and expand
+ @max = [@max,to.length+1].max if to
+ @rep[from.escaped] = to || ''
+ end
+
+ # sorter.reducer('ch', 'c')
+ # sorter.reducer('ij', 'y')
+
+ def reducer(from,to='')
+ @max = [@max,to.length+1].max if to
+ @map[from] = to || ''
+ end
+
+ # sorter.expander('aeligature', 'ae')
+ # sorter.expander('ijligature', 'y')
+
+ def expander(from,to=nil)
+ from, to = converted(from), converted(to)
+ @max = [@max,to.length+1].max if to
+ @exp[from] = to || from || ''
+ end
+
+ def division(from,to=nil)
+ from, to = converted(from), converted(to)
+ @max = [@max,to.length+1].max if to
+ @div[from] = to || from || ''
+ end
+
+ # shortcut("\\ab\\cd\\e\\f", 'iacute')
+ # shortcut("\\\'\\i", 'iacute')
+ # shortcut("\\\'i", 'iacute')
+ # shortcut("\\\"e", 'ediaeresis')
+ # shortcut("\\\'o", 'oacute')
+
+ def shortcut(from,to)
+ replacer(from,to)
+ expander(to)
+ end
+
+ def prepare
+ if @rep.size > 0 then
+ @rexa = /(#{@rep.keys.join('|')})/ # o
+ else
+ @rexa = nil
+ end
+ if @map.size > 0 then
+ # watch out, order of match matters
+ @rexb = /(\\[a-zA-Z]+|#{@map.keys.join('|')}|.)\s*/ # o
+ else
+ @rexb = /(\\[a-zA-Z]+|.)\s*/o
+ end
+ end
+
+ def remap(str)
+ s = str.dup
+ s.gsub!(/(\d+)/o) do
+ $1.rjust(10,'a') # rest is b .. k
+ end
+ if @rexa then
+ s.gsub!(@rexa) do
+ @rep[$1.escaped]
+ end
+ end
+ if @rexb then
+ s.gsub!(@rexb) do
+ token = $1.sub(/\\/o, '')
+ if @exp.key?(token) then
+ @exp[token].ljust(@max,' ')
+ elsif @map.key?(token) then
+ @map[token].ljust(@max,' ')
+ else
+ ''
+ end
+ end
+ end
+ s
+ end
+
+ def preset(shortcuts=[],expansions=[],reductions=[],divisions=[])
+ # maybe we should move this to sort-def.tex
+ '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
+ end
+
+ def simplify(str)
+ s = str.dup
+ # ^^
+ # s.gsub!(/\^\^([a-f0-9][a-f0-9])/o, $1.hex.chr)
+ # \- ||
+ s.gsub!(/(\\\-|\|\|)/o) do '-' end
+ # {}
+ s.gsub!(/\{\}/o) do '' end
+ # <*..> (internal xml entity)
+ s.gsub!(/<\*(.*?)>/o) do $1 end
+ # entities
+ s.gsub!(/\\getXMLentity\s*\{(.*?)\}/o) do $1 end
+ # elements
+ s.gsub!(/\<.*?>/o) do '' end
+ # what to do with xml and utf-8
+ # \"e etc
+ # unknown \cs
+ s.gsub!(/\\[a-z][a-z]+\s*\{(.*?)\}/o) do $1 end
+ return s
+ end
+
+ def getdivision(str)
+ @div[str] || str
+ end
+
+ def division?(str)
+ @div.key?(str)
+ end
+
+ private
+
+ def converted(str)
+ if str then
+ str.gsub(/([\+\-]*\d+)/o) do
+ n = $1.to_i
+ if n > 0 then
+ 'z'*n
+ elsif n < 0 then
+ '-'*(-n) # '-' precedes 'a'
+ else
+ ''
+ end
+ end
+ else
+ nil
+ end
+ end
+
+ end
+
+ class Plugin
+
+ module MyFiles
+
+ @@files = Hash.new
+
+ def MyFiles::reset(logger)
+ @@files = 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
+ end
+ end
+
+ def MyFiles::writer(logger,handle)
+ handle << logger.banner("loaded files: #{@@files.size}")
+ @@files.keys.sort.each do |k|
+ handle << "% > #{k} #{@@files[k]/2}\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")
+ end
+ end
+ end
+
+ end
+
+ end
+
+ class Plugin
+
+ module MyCommands
+
+ @@commands = []
+
+ def MyCommands::reset(logger)
+ @@commands = []
+ end
+
+ def MyCommands::reader(logger,data)
+ @@commands.push(data.shift+data.collect do |d| "\{#{d}\}" end.join)
+ end
+
+ def MyCommands::writer(logger,handle)
+ handle << logger.banner("commands: #{@@commands.size}")
+ @@commands.each do |c|
+ handle << "#{c}\n"
+ end
+ end
+
+ def MyCommands::processor(logger)
+ end
+
+ end
+
+ end
+
+ class Plugin
+
+ module MyExtras
+
+ @@programs = []
+
+ def MyExtras::reset(logger)
+ @@programs = []
+ end
+
+ def MyExtras::reader(logger,data)
+ case data[0]
+ when 'p' then
+ @@programs.push(data[1]) if data[0]
+ end
+ end
+
+ def MyExtras::writer(logger,handle)
+ handle << logger.banner("programs: #{@@programs.size}")
+ @@programs.each do |p|
+ handle << "% #{p} (#{@@programs[p.to_i]})\n"
+ end
+ end
+
+ def MyExtras::processor(logger)
+ @@programs.each do |p|
+ cmd = "texmfstart #{@@programs[p.to_i]}"
+ logger.report("running #{cmd}")
+ system(cmd)
+ end
+ end
+
+ end
+
+ end
+
+ class Plugin
+
+ module MySynonyms
+
+ class Synonym
+
+ @@debug = false
+ @@debug = true
+
+ def initialize(t, c, k, d)
+ @type, @command, @key, @sortkey, @data = t, c, k, k, d
+ end
+
+ attr_reader :type, :command, :key, :data
+ attr_reader :sortkey
+ attr_writer :sortkey
+
+ def build(sorter)
+ @sortkey = sorter.remap(sorter.simplify(@key.downcase))
+ if @sortkey.empty? then
+ @sortkey = sorter.remap(@command.downcase)
+ end
+ end
+
+ def <=> (other)
+ @sortkey <=> other.sortkey
+ end
+
+ def Synonym.flush(list,handle)
+ if @@debug then
+ list.each do |entry|
+ handle << "% [#{entry.sortkey}]\n"
+ end
+ end
+ list.each do |entry|
+ handle << "\\synonymentry{#{entry.type}}{#{entry.command}}{#{entry.key}}{#{entry.data}}\n"
+ end
+ end
+
+ end
+
+ @@synonyms = Hash.new
+
+ def MySynonyms::reset(logger)
+ @@synonyms = 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]))
+ end
+ end
+
+ def MySynonyms::writer(logger,handle)
+ if @@synonyms.size > 0 then
+ @@synonyms.keys.sort.each do |s|
+ handle << logger.banner("synonyms: #{s} #{@@synonyms[s].size}")
+ Synonym.flush(@@synonyms[s],handle)
+ end
+ end
+ 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|
+ @@synonyms[s].each_index do |i|
+ @@synonyms[s][i].build(sorter)
+ end
+ @@synonyms[s] = @@synonyms[s].sort
+ end
+ end
+
+ end
+
+ end
+
+ class Plugin
+
+ module MyRegisters
+
+ class Register
+
+ @@debug = false
+ @@debug = true
+
+ @@howto = /^(.*?)\:\:(.*)$/o
+ @@split = ' && '
+
+ def initialize(state, t, l, k, e, s, p, r)
+ @state, @type, @location, @key, @entry, @seetoo, @page, @realpage = state, t, l, k, e, s, p, r
+ if @key =~ @@howto then @pagehowto, @key = $1, $2 else @pagehowto = '' end
+ if @entry =~ @@howto then @texthowto, @entry = $1, $2 else @texthowto = '' end
+ @key = @entry.dup if @key.empty?
+ @sortkey = @key.dup
+ @nofentries, @nofpages = 0, 0
+ end
+
+ attr_reader :state, :type, :location, :key, :entry, :seetoo, :page, :realpage, :texthowto, :pagehowto
+ attr_reader :sortkey
+ 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
+ end
+ # {a}{b}{c}
+ # if target =~ /^\{(.*)\}$/o then
+ # $1.split(/\} \{/o).join(@@split) # space between } { is mandate
+ # else
+ target
+ # end
+ end
+ @sortkey = sorter.simplify(@key)
+ @sortkey = @sortkey.split(@@split).collect do |c| sorter.remap(c) end.join(@@split)
+ # if ($Key eq "") { $Key = SanitizedString($Entry) }
+ # if ($ProcessHigh){ $Key = HighConverted($Key) }
+ @sortkey = [
+ @sortkey.downcase,
+ @sortkey,
+ @texthowto.ljust(10,' '),
+ @state,
+ @realpage.rjust(6,' '),
+ @pagehowto
+ ].join(@@split)
+ end
+
+ def <=> (other)
+ @sortkey <=> other.sortkey
+ end
+
+ # more module like
+
+ @@savedhowto, @@savedfrom, @@savedto, @@savedentry = '', '', '', '', ''
+ @@collapse = false
+
+ def Register.flushsavedline(handle)
+ if @@collapse && ! @@savedfrom.empty? then
+ if ! @@savedto.empty? then
+ handle << "\\registerfrom#{@@savedfrom}"
+ handle << "\\registerto#{@@savedto}"
+ else
+ handle << "\\registerpage#{@@savedfrom}"
+ end
+ end
+ @@savedhowto, @@savedfrom, @@savedto, @@savedentry = '', '', '', ''
+ end
+
+ def Register.flush(list,handle,sorter)
+ # a bit messy, quite old mechanism, maybe some day ...
+ # alphaclass can go, now flushed per class
+ if list.size > 0 then
+ @nofentries, @nofpages = 0, 0
+ current, previous, howto = Array.new, Array.new, Array.new
+ lastpage, lastrealpage = '', ''
+ alphaclass, alpha = '', ''
+ @@savedhowto, @@savedfrom, @@savedto, @@savedentry = '', '', '', ''
+ if @@debug then
+ list.each do |entry|
+ handle << "% [#{entry.sortkey.gsub(/#{@@split}/o,'] [')}]\n"
+ end
+ end
+ list.each do |entry|
+ if entry.sortkey =~ /^(\S+)/o then
+ if sorter.division?($1) then
+ testalpha = sorter.getdivision($1)
+ else
+ testalpha = entry.sortkey[0,1].downcase
+ end
+ else
+ testalpha = entry.sortkey[0,1].downcase
+ end
+ if testalpha != alpha.downcase or 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.length > 1 then
+ # character = "\\getvalue\{#{alpha}\}"
+ character = "\\#{alpha}"
+ else
+ character = "\\#{alpha}"
+ end
+ handle << "\\registerentry{#{entry.type}}{#{character}}\n"
+ end
+ end
+ current = [entry.entry.split(@@split),'','',''].flatten
+ howto = current.collect do |e|
+ e + '::' + entry.texthowto
+ end
+ if howto[0] == previous[0] then
+ current[0] = ''
+ else
+ previous[0] = howto[0].dup
+ previous[1] = ''
+ previous[2] = ''
+ end
+ if howto[1] == previous[1] then
+ current[1] = ''
+ else
+ previous[1] = howto[1].dup
+ previous[2] = ''
+ end
+ if howto[2] == previous[2] then
+ current[2] = ''
+ else
+ previous[2] = howto[2].dup
+ end
+ copied = false
+ unless current[0].empty? then
+ Register.flushsavedline(handle)
+ handle << "\\registerentrya{#{entry.type}}{#{current[0]}}\n"
+ copied = true
+ end
+ unless current[1].empty? then
+ Register.flushsavedline(handle)
+ handle << "\\registerentryb{#{entry.type}}{#{current[1]}}\n"
+ copied = true
+ end
+ unless current[2].empty? then
+ Register.flushsavedline(handle)
+ handle << "\\registerentryc{#{entry.type}}{#{current[2]}}\n"
+ copied = true
+ end
+ @nofentries += 1 if copied
+ if entry.realpage.to_i == 0 then
+ Register.flushsavedline(handle)
+ handle << "\\registersee{#{entry.type}}{#{entry.pagehowto},#{entry.texthowto}}{#{entry.seetoo}}{#{entry.page}}\n" ;
+ lastpage, lastrealpage = entry.page, entry.realpage
+ elsif @@savedhowto != entry.pagehowto and ! entry.pagehowto.empty? then
+ @@savedhowto = entry.pagehowto
+ end
+ if copied || ! ((lastpage == entry.page) && (lastrealpage == entry.realpage)) then
+ nextentry = "{#{entry.type}}{#{previous[0]}}{#{previous[1]}}{#{previous[2]}}{#{entry.pagehowto},#{entry.texthowto}}"
+ savedline = "{#{entry.type}}{#{@@savedhowto},#{entry.texthowto}}{#{entry.location}}{#{entry.page}}{#{entry.realpage}}"
+ if entry.state == 1 then # from
+ Register.flushsavedline(handle)
+ handle << "\\registerfrom#{savedline}\n"
+ elsif entry.state == 3 then # to
+ Register.flushsavedline(handle)
+ handle << "\\registerto#{savedline}\n"
+ @@savedhowto = '' # test
+ elsif @@collapse then
+ if savedentry != nextentry then
+ savedFrom = savedline
+ else
+ savedTo, savedentry = savedline, nextentry
+ end
+ else
+ handle << "\\registerpage#{savedline}\n"
+ @@savedhowto = '' # test
+ end
+ @nofpages += 1
+ lastpage, lastrealpage = entry.page, entry.realpage
+ end
+ end
+ Register.flushsavedline(handle)
+ end
+ end
+
+ end
+
+ @@registers = Hash.new
+ @@sorter = Sorter.new
+
+ def MyRegisters::reset(logger)
+ @@registers = Hash.new
+ @@sorter = Sorter.new
+ end
+
+ def MyRegisters::reader(logger,data)
+ case data[0]
+ when 'f' then
+ @@registers[data[1]] = Array.new unless @@registers.key?(data[1])
+ @@registers[data[1]].push(Register.new(1,data[1],data[2],data[3],data[4],nil,data[5],data[6]))
+ when 'e' then
+ @@registers[data[1]] = Array.new unless @@registers.key?(data[1])
+ @@registers[data[1]].push(Register.new(2,data[1],data[2],data[3],data[4],nil,data[5],data[6]))
+ when 't' then
+ @@registers[data[1]] = Array.new unless @@registers.key?(data[1])
+ @@registers[data[1]].push(Register.new(3,data[1],data[2],data[3],data[4],nil,data[5],data[6]))
+ 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))
+ end
+ end
+
+ def MyRegisters::writer(logger,handle)
+ 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)
+ # 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|
+ @@registers[s].each_index do |i|
+ @@registers[s][i].build(@@sorter)
+ end
+ @@registers[s] = @@registers[s].sort
+ end
+ end
+
+ end
+
+ end
+
+ class Plugin
+
+ module MyPlugins
+
+ @@plugins = nil
+
+ def MyPlugins::reset(logger)
+ @@plugins = nil
+ end
+
+ def MyPlugins::reader(logger,data)
+ @@plugins = Plugin.new(logger) unless @@plugins
+ case data[0]
+ when 'r' then
+ logger.report("registering plugin #{data[1]}")
+ @@plugins.register(data[1],data[2])
+ when 'd' then
+ begin
+ @@plugins.reader(data[1],data[2,data.length-1])
+ rescue
+ @@plugins.reader(data[1],['error'])
+ end
+ end
+ end
+
+ def MyPlugins::writer(logger,handle)
+ @@plugins.writers(handle) if @@plugins
+ end
+
+ def MyPlugins::processor(logger)
+ @@plugins.processors if @@plugins
+ end
+
+ end
+
+ end
+
+ class Plugin
+
+ module MyKeys
+
+ @@shortcuts = Array.new
+ @@expansions = Array.new
+ @@reductions = Array.new
+ @@divisions = Array.new
+
+ def MyKeys::shortcuts
+ @@shortcuts
+ end
+ def MyKeys::expansions
+ @@expansions
+ end
+ def MyKeys::reductions
+ @@reductions
+ end
+ def MyKeys::divisions
+ @@divisions
+ end
+
+ def MyKeys::reset(logger)
+ @@shortcuts = Array.new
+ @@expansions = Array.new
+ @@reductions = Array.new
+ end
+
+ def MyKeys::reader(logger,data)
+ key = data.shift
+ grp = data.shift # language code, todo
+ case key
+ when 's' then @@shortcuts.push(data)
+ when 'e' then @@expansions.push(data)
+ when 'r' then @@reductions.push(data)
+ when 'd' then @@divisions.push(data)
+ end
+ end
+
+ def MyKeys::writer(logger,handle)
+ end
+
+ def MyKeys::processor(logger)
+ logger.report("shortcuts : #{@@shortcuts.size}") # logger.report(@@shortcuts.inspect)
+ logger.report("expansions: #{@@expansions.size}") # logger.report(@@expansions.inspect)
+ logger.report("reductions: #{@@reductions.size}") # logger.report(@@reductions.inspect)
+ logger.report("divisions : #{@@divisions.size}") # logger.report(@@divisions.inspect)
+ end
+
+ end
+
+ end
+
+ class Converter
+
+ def initialize(logger=nil)
+ if @logger = logger then
+ def report(str)
+ @logger.report(str)
+ end
+ def banner(str)
+ @logger.banner(str)
+ end
+ else
+ @logger = self
+ def report(str)
+ puts(str)
+ end
+ def banner(str)
+ puts(str)
+ end
+ end
+ @filename = 'texutil'
+ @fatalerror = false
+ @plugins = Plugin.new(@logger)
+ ['MyFiles', 'MyCommands', 'MySynonyms', 'MyRegisters', 'MyExtras', 'MyPlugins', 'MyKeys'].each do |p|
+ @plugins.register(p)
+ end
+ end
+
+ 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}")
+ end
+ end
+ f.close
+ end
+ rescue
+ report("fatal error in parsing #{filename}")
+ @filename = 'texutil'
+ else
+ @filename = filename
+ end
+ end
+
+ def processed
+ @plugins.processors
+ return true # for the moment
+ end
+
+ def saved(filename=@filename)
+ if @fatalerror then
+ report("fatal error, no tuo file saved")
+ else
+ begin
+ if f = File.open(File.suffixed(filename,'tuo'),'w') then
+ @plugins.writers(f)
+ f.close
+ end
+ rescue
+ report("fatal error when saving file (#{$!})")
+ else
+ report("tuo file saved")
+ end
+ end
+ @plugins.resets
+ end
+
+ def reset
+ @plugins.resets
+ end
+
+ end
+
+end