summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/scripts/context/ruby/xmltools.rb
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/scripts/context/ruby/xmltools.rb')
-rw-r--r--Master/texmf-dist/scripts/context/ruby/xmltools.rb303
1 files changed, 245 insertions, 58 deletions
diff --git a/Master/texmf-dist/scripts/context/ruby/xmltools.rb b/Master/texmf-dist/scripts/context/ruby/xmltools.rb
index a57f7445020..a10d34314aa 100644
--- a/Master/texmf-dist/scripts/context/ruby/xmltools.rb
+++ b/Master/texmf-dist/scripts/context/ruby/xmltools.rb
@@ -10,13 +10,16 @@
# info : j.hagen@xs4all.nl
# www : www.pragma-ade.com
+# todo : use kpse lib
+
# This script will harbor some handy manipulations on tex
# related files.
-banner = ['XMLTools', 'version 1.1.1', '2002/2005', 'PRAGMA ADE/POD']
+banner = ['XMLTools', 'version 1.2.0', '2002/2006', 'PRAGMA ADE/POD']
unless defined? ownpath
ownpath = $0.sub(/[\\\/][a-z0-9\-]*?\.rb/i,'')
+ # ownpath = File.dirname($0)
$: << ownpath
end
@@ -170,7 +173,7 @@ class Commands
if FileTest.file?(file+'.xml') then
style = "--arg=\"style=#{style}\"" unless style.empty?
modes = "--mode=#{modes}" unless modes.empty?
- if system("texmfstart texexec.pl --batch --pdf --once --result=#{long} --use=mmlpag #{style} #{modes} #{file}.xml") then
+ if system("texmfstart texexec --batch --pdf --once --result=#{long} --use=mmlpag #{style} #{modes} #{file}.xml") then
if eps then
if f = open("#{file}-mmlpages.txt") then
while line = f.gets do
@@ -226,7 +229,7 @@ class Commands
else
report("error in processing file #{file}")
end
- system("texmfstart texutil --purge")
+ system("texmfstart ctxtools --purge")
else
report("error in processing file #{file}")
end
@@ -235,77 +238,188 @@ class Commands
def analyze
- file = @commandline.argument('first')
- result = @commandline.option('output')
+ file = @commandline.argument('first')
+ result = @commandline.option('output')
+ utf = @commandline.option('utf')
+ process = @commandline.option('process')
if FileTest.file?(file) then
if data = IO.read(file) then
- report("xml file #{file} loaded")
- elements = Hash.new
- attributes = Hash.new
- entities = Hash.new
- data.scan(/<([^>\s\/\!\?]+)([^>]*?)>/o) do
- element, attributelist = $1, $2
- if elements.key?(element) then
- elements[element] += 1
- else
- elements[element] = 1
- end
- attributelist.scan(/\s*([^\=]+)\=([\"\'])(.*?)(\2)/) do
- key, value = $1, $3
- attributes[element] = Hash.new unless attributes.key?(element)
- attributes[element][key] = Hash.new unless attributes[element].key?(key)
- if attributes[element][key].key?(value) then
- attributes[element][key][value] += 1
+ if data =~ /<?xml.*?version\=/ then
+ report("xml file #{file} loaded")
+ elements = Hash.new
+ attributes = Hash.new
+ entities = Hash.new
+ chars = Hash.new
+ unicodes = Hash.new
+ names = Hash.new
+ data.scan(/<([^>\s\/\!\?]+)([^>]*?)>/o) do
+ element, attributelist = $1, $2
+ if elements.key?(element) then
+ elements[element] += 1
else
- attributes[element][key][value] = 1
+ elements[element] = 1
+ end
+ attributelist.scan(/\s*([^\=]+)\=([\"\'])(.*?)(\2)/) do
+ key, value = $1, $3
+ attributes[element] = Hash.new unless attributes.key?(element)
+ attributes[element][key] = Hash.new unless attributes[element].key?(key)
+ if attributes[element][key].key?(value) then
+ attributes[element][key][value] += 1
+ else
+ attributes[element][key][value] = 1
+ end
end
end
- end
- data.scan(/\&([^\;]+)\;/o) do
- entity = $1
- if entities.key?(entity) then
- entities[entity] += 1
- else
- entities[entity] = 1
+ data.scan(/\&([^\;]+)\;/o) do
+ entity = $1
+ if entities.key?(entity) then
+ entities[entity] += 1
+ else
+ entities[entity] = 1
+ end
end
- end
- result = file.gsub(/\..*?$/, '') + '.xlg' if result.empty?
- if f = File.open(result,'w') then
- report("saving report in #{result}")
- f.puts "<?xml version='1.0'?>\n"
- f.puts "<document>\n"
- if entities.length>0 then
- f.puts " <entities>\n"
- entities.keys.asort.each do |entity|
- f.puts " <entity name=#{entity.xstring} n=#{entities[entity].to_s.xstring}/>\n"
+ if utf then
+ data.scan(/(\w)/u) do
+ chars[$1] = (chars[$1] || 0) + 1
+ end
+ if chars.size > 0 then
+ begin
+ # todo : use kpse lib
+ filename, ownpath, foundpath = 'contextnames.txt', File.dirname($0), ''
+ begin
+ foundpath = File.dirname(`kpsewhich -progname=context -format=\"other text files\" #{filename}`.chomp)
+ rescue
+ foundpath = '.'
+ else
+ foundpath = '.' if foundpath.empty?
+ end
+ [foundpath,ownpath,File.join(ownpath,'../../../context/data')].each do |path|
+ fullname = File.join(path,filename)
+ if FileTest.file?(fullname) then
+ report("loading '#{fullname}'")
+ # rough scan, we assume no valid lines after comments
+ IO.read(fullname).scan(/^([0-9A-F][0-9A-F][0-9A-F][0-9A-F])\s*\;\s*(.*?)\s*\;\s*(.*?)\s*\;\s*(.*?)\s*$/) do
+ names[$1.hex.to_i.to_s] = [$2,$3,$4]
+ end
+ break
+ end
+ end
+ rescue
+ end
end
- f.puts " </entities>\n"
end
- if elements.length>0 then
- f.puts " <elements>\n"
- elements.keys.sort.each do |element|
- if attributes.key?(element) then
- f.puts " <element name=#{element.xstring} n=#{elements[element].to_s.xstring}>\n"
+ result = file.gsub(/\..*?$/, '') + '.xlg' if result.empty?
+ if f = File.open(result,'w') then
+ report("saving report in #{result}")
+ f.puts "<?xml version='1.0'?>\n"
+ f.puts "<document>\n"
+ if entities.length>0 then
+ total = 0
+ entities.each do |k,v|
+ total += v
+ end
+ f.puts " <entities n=#{total.to_s.xstring}>\n"
+ entities.keys.asort.each do |entity|
+ f.puts " <entity name=#{entity.xstring} n=#{entities[entity].to_s.xstring}/>\n"
+ end
+ f.puts " </entities>\n"
+ end
+ if utf && (chars.size > 0) then
+ total = 0
+ chars.each do |k,v|
+ total += v
+ end
+ f.puts " <characters n=#{total.to_s.xstring}>\n"
+ chars.each do |k,v|
+ if k.length > 1 then
+ begin
+ u = k.unpack('U')
+ unicodes[u] = (unicodes[u] || 0) + v
+ rescue
+ report("invalid utf codes")
+ end
+ end
+ end
+ unicodes.keys.sort.each do |u|
+ ustr = u.to_s
+ if names[ustr] then
+ f.puts " <character number=#{ustr.xstring} pname=#{names[ustr][0].xstring} cname=#{names[ustr][1].xstring} uname=#{names[ustr][2].xstring} n=#{unicodes[u].to_s.xstring}/>\n"
+ else
+ f.puts " <character number=#{ustr.xstring} n=#{unicodes[u].to_s.xstring}/>\n"
+ end
+ end
+ f.puts " </characters>\n"
+ end
+ if elements.length>0 then
+ f.puts " <elements>\n"
+ elements.keys.sort.each do |element|
if attributes.key?(element) then
- attributes[element].keys.asort.each do |attribute|
- f.puts " <attribute name=#{attribute.xstring}>\n"
- attributes[element][attribute].keys.asort.each do |value|
- f.puts " <instance value=#{value.xstring} n=#{attributes[element][attribute][value].to_s.xstring}/>\n"
+ f.puts " <element name=#{element.xstring} n=#{elements[element].to_s.xstring}>\n"
+ if attributes.key?(element) then
+ attributes[element].keys.asort.each do |attribute|
+ f.puts " <attribute name=#{attribute.xstring}>\n"
+ if attribute =~ /id$/o then
+ nn = 0
+ attributes[element][attribute].keys.asort.each do |value|
+ nn += attributes[element][attribute][value].to_i
+ end
+ f.puts " <instance value=#{"*".xstring} n=#{nn.to_s.xstring}/>\n"
+ else
+ attributes[element][attribute].keys.asort.each do |value|
+ f.puts " <instance value=#{value.xstring} n=#{attributes[element][attribute][value].to_s.xstring}/>\n"
+ end
+ end
+ f.puts " </attribute>\n"
end
- f.puts " </attribute>\n"
end
+ f.puts " </element>\n"
+ else
+ f.puts " <element name=#{element.xstring} n=#{elements[element].to_s.xstring}/>\n"
end
- f.puts " </element>\n"
- else
- f.puts " <element name=#{element.xstring} n=#{elements[element].to_s.xstring}/>\n"
end
+ f.puts " </elements>\n"
+ end
+ f.puts "</document>\n"
+ f.close
+ if process then
+ system("texmfstart texexec --purge --pdf --use=xml-analyze #{result}")
+ end
+ else
+ report("unable to open file '#{result}'")
+ end
+ else
+ report("invalid xml file '#{file}'")
+ end
+ else
+ report("unable to load file '#{file}'")
+ end
+ else
+ report("unknown file '#{file}'")
+ end
+ end
+
+ def cleanup # todo, share loading/saving with previous
+
+ file = @commandline.argument('first')
+ force = @commandline.option('force')
+ verbose = @commandline.option('verbose')
+
+ if FileTest.file?(file) then
+ if data = IO.read(file) then
+ if data =~ /<?xml.*?version\=/ then
+ data = doxmlcleanup(data,verbose)
+ result = if force then file else file.gsub(/\..*?$/, '') + '.xlg' end
+ begin
+ if f = File.open(result,'w') then
+ f << data
+ f.close
end
- f.puts " </elements>\n"
+ rescue
+ report("unable to open file '#{result}'")
end
- f.puts "</document>\n"
else
- report("unable to open file '#{result}'")
+ report("invalid xml file '#{file}'")
end
else
report("unable to load file '#{file}'")
@@ -313,8 +427,77 @@ class Commands
else
report("unknown file '#{file}'")
end
+
end
+ def doxmlreport(str,verbose=false)
+ if verbose then
+ result = str
+ report(result)
+ return result
+ else
+ return str
+ end
+ end
+
+ def doxmlcleanup(data="",verbose=false)
+
+ # remove funny spaces (looks cleaner)
+ #
+ # data = "<whatever ></whatever ><whatever />"
+
+ data.gsub!(/\<(\/*\w+)\s*(\/*)>/o) do
+ "<#{$1}#{$2}>"
+ end
+
+ # remove funny ampersands
+ #
+ # data = "<x> B&W </x>"
+
+ data.gsub!(/\&([^\<\>\&]*?)\;/mo) do
+ "<entity name='#{$1}'/>"
+ end
+ data.gsub!(/\&/o) do
+ doxmlreport("&amp;",verbose)
+ end
+ data.gsub!(/\<entity name=\'(.*?)\'\/\>/o) do
+ doxmlreport("&#{$1};",verbose)
+ end
+
+ # remove funny < >
+ #
+ # data = "<x> < 5% </x>"
+
+ data.gsub!(/<([^>].*?)>/o) do
+ tag = $1
+ case tag
+ when /^\//o then
+ "<#{tag}>" # funny tag but ok
+ when /\/$/o then
+ "<#{tag}>" # funny tag but ok
+ when /</o then
+ doxmlreport("&lt;#{tag}>",verbose)
+ else
+ "<#{tag}>"
+ end
+ end
+
+ # remove funny < >
+ #
+ # data = "<x> > 5% </x>"
+
+ data.gsub!(/<([^>].*?)>([^\>\<]*?)>/o) do
+ doxmlreport("<#{$1}>#{$2}&gt;",verbose)
+ end
+
+ return data
+ end
+
+ # puts doxmlcleanup("<whatever ></whatever ><whatever />")
+ # puts doxmlcleanup("<x> B&W </x>")
+ # puts doxmlcleanup("<x> < 5% </x>")
+ # puts doxmlcleanup("<x> > 5% </x>")
+
end
logger = Logger.new(banner.shift)
@@ -322,7 +505,8 @@ commandline = CommandLine.new
commandline.registeraction('dir', 'generate directory listing')
commandline.registeraction('mmlpages','generate graphic from mathml')
-commandline.registeraction('analyze', 'report entities and elements')
+commandline.registeraction('analyze', 'report entities and elements [--utf --process]')
+commandline.registeraction('cleanup', 'cleanup xml file [--force]')
# commandline.registeraction('dir', 'filename --pattern= --output= [--recurse --stripname --longname --url --root]')
# commandline.registeraction('mmlpages','filename [--eps --jpg --png --style= --mode=]')
@@ -344,8 +528,11 @@ commandline.registervalue('root')
commandline.registerflag('eps')
commandline.registerflag('png')
commandline.registerflag('jpg')
+commandline.registerflag('utf')
+commandline.registerflag('process')
commandline.registervalue('style')
commandline.registervalue('modes')
+commandline.registervalue('verbose')
commandline.expand