summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2006-07-13 22:26:00 +0200
committerHans Hagen <pragma@wxs.nl>2006-07-13 22:26:00 +0200
commitcb58eea8a8460f4288c8ba9279bcd1a4d9333f74 (patch)
treea935db5f4be07adc3ab7ff0a6838505030a72fc4 /scripts
parentf9420a5dde4d6646f2e117813bd85e0bfc701d7d (diff)
downloadcontext-cb58eea8a8460f4288c8ba9279bcd1a4d9333f74.tar.gz
stable 2006.07.13 22:26
Diffstat (limited to 'scripts')
-rw-r--r--scripts/context/perl/texexec.pl12
-rw-r--r--scripts/context/ruby/base/mp.rb2
-rw-r--r--scripts/context/ruby/base/system.rb7
-rw-r--r--scripts/context/ruby/base/tex.rb210
-rw-r--r--scripts/context/ruby/base/texutil.rb12
-rw-r--r--scripts/context/ruby/ctxtools.rb14
-rw-r--r--scripts/context/ruby/fcd_start.rb32
-rw-r--r--scripts/context/ruby/pdftools.rb816
-rw-r--r--scripts/context/ruby/texexec.rb65
-rw-r--r--scripts/context/ruby/texmfstart.rb6
-rw-r--r--scripts/context/ruby/xmltools.rb117
11 files changed, 1221 insertions, 72 deletions
diff --git a/scripts/context/perl/texexec.pl b/scripts/context/perl/texexec.pl
index 21595aa7b..fb564bbd5 100644
--- a/scripts/context/perl/texexec.pl
+++ b/scripts/context/perl/texexec.pl
@@ -937,7 +937,7 @@ SetInterfaces( "en", "english", "english" );
SetInterfaces( "de", "german", "german" );
SetInterfaces( "fr", "french", "french" );
SetInterfaces( "cz", "czech", "czech" );
-SetInterfaces( "uk", "brittish", "english" );
+SetInterfaces( "uk", "british", "english" );
SetInterfaces( "it", "italian", "italian" );
SetInterfaces( "no", "norwegian", "norwegian" );
SetInterfaces( "ro", "romanian", "romanian" );
@@ -3151,7 +3151,7 @@ interface user interface
=de German
=fr French
=cz Czech
-=uk Brittish
+=uk British
=it Italian
-----------
language main hyphenation language
@@ -3178,7 +3178,7 @@ module typeset tex/pl/mp module
-----------
mptex run an MetaPost plus btex-etex cycle
-----------
-mpxtex generatet an MetaPostmpx file
+mpxtex generate an MetaPost mpx file
-----------
noarrange process but ignore arrange
-----------
@@ -3191,8 +3191,8 @@ automprun MetaPost at runtime when needed
once run TeX only once (no TeXUtil either)
-----------
output specials to use
-=pdftex Han The Than's pdf backend
-=dvips Thomas Rokicky's dvi to ps converter
+=pdftex Han The Thanh's pdf backend
+=dvips Tomas Rokicky's dvi to ps converter
=dvipsone YandY's dvi to ps converter
=dviwindo YandY's windows previewer
=dvipdfm Mark Wicks' dvi to pdf converter
@@ -3285,7 +3285,7 @@ verbose shows some additional info
-----------
help show this or more, e.g. '--help interface'
-----------
-alone bypass utilities (e.g. fmtutil for non-standard fmt's)
+alone bypass utilities (e.g. fmtutil for non-standard fmts)
-----------
texutil force TeXUtil run
-----------
diff --git a/scripts/context/ruby/base/mp.rb b/scripts/context/ruby/base/mp.rb
index 17e9eca76..d26882456 100644
--- a/scripts/context/ruby/base/mp.rb
+++ b/scripts/context/ruby/base/mp.rb
@@ -87,7 +87,7 @@ EOT
f.puts("")
f.puts(@@start[method])
end
- data.gsub!(/%.*?$/mo) do
+ data.gsub!(/[^\\]%.*?$/mo) do
''
end
data.scan(/(verbatim|b)tex\s*(.*?)\s*etex/mo) do
diff --git a/scripts/context/ruby/base/system.rb b/scripts/context/ruby/base/system.rb
index 4a8cba652..267a22cb9 100644
--- a/scripts/context/ruby/base/system.rb
+++ b/scripts/context/ruby/base/system.rb
@@ -33,6 +33,13 @@ module System
if @@mswindows then 'nul' else '/dev/null/' end
end
+ def System.unix?
+ not @@mswindows
+ end
+ def System.mswin?
+ @@mswindows
+ end
+
def System.binnames(str)
if @@binnames.key?(str) then
@@binnames[str]
diff --git a/scripts/context/ruby/base/tex.rb b/scripts/context/ruby/base/tex.rb
index c09327725..29e0de44f 100644
--- a/scripts/context/ruby/base/tex.rb
+++ b/scripts/context/ruby/base/tex.rb
@@ -83,7 +83,27 @@ class TEX
@@texmethods = Hash.new
@@mpsmethods = Hash.new
- ['tex','pdftex','pdfetex','standard'] .each do |e| @@texengines[e] = 'pdfetex' end
+ @@pdftex = 'pdftex' # new default, pdfetex is gone
+
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |p|
+ if System.unix? then
+ pp, pe = "#{p}/pdftex" , "#{p}/pdfetex"
+ else
+ pp, pe = "#{p}/pdftex.exe", "#{p}/pdfetex.exe"
+ end
+ if FileTest.file?(pe) then
+ # we assume no update
+ @@pdftex = 'pdfetex'
+ break
+ elsif FileTest.file?(pp) then
+ # we assume an update
+ @@pdftex = 'pdftex'
+ break
+ end
+ end
+
+ ['etex','pdfetex','standard'] .each do |e| @@texengines[e] = @@pdftex end
+ ['tex','pdftex'] .each do |e| @@texengines[e] = 'pdftex' end
['aleph','omega'] .each do |e| @@texengines[e] = 'aleph' end
['xetex'] .each do |e| @@texengines[e] = 'xetex' end
['luatex'] .each do |e| @@texengines[e] = 'luatex' end
@@ -122,7 +142,8 @@ class TEX
['plain','mpost'] .each do |f| @@mpsformats[f] = 'plain' end
['metafun','context','standard'] .each do |f| @@mpsformats[f] = 'metafun' end
- ['pdfetex','aleph','omega','xetex','luatex'] .each do |p| @@prognames[p] = 'context' end
+ ['pdftex','pdfetex','aleph','omega',
+ 'xetex','luatex'] .each do |p| @@prognames[p] = 'context' end
['mpost'] .each do |p| @@prognames[p] = 'metafun' end
['plain','default','standard','mptopdf'] .each do |f| @@texmethods[f] = 'plain' end
@@ -140,15 +161,16 @@ class TEX
'cont-fr','cont-cz','cont-ro','cont-uk'] .each do |f| @@texprocstr[f] = "\\emergencyend" end
# @@runoptions['xetex'] = ['--output-driver \\\"-d 4 -V 5\\\"'] # we need the pos pass
- @@runoptions['xetex'] = ['--8bit --no-pdf'] # from now on we assume (x)dvipdfmx to be used
- @@runoptions['pdfetex'] = ['--8bit']
- @@runoptions['luatex'] = ['--8bit']
- @@runoptions['aleph'] = ['--8bit']
+ @@runoptions['xetex'] = ['--8bit -no-pdf'] # from now on we assume (x)dvipdfmx to be used
+ @@runoptions['pdfetex'] = ['--8bit ']
+ @@runoptions['pdftex'] = ['--8bit '] # pdftex is now pdfetex
+ @@runoptions['luatex'] = ['--8bit ']
+ @@runoptions['aleph'] = ['--8bit ']
@@booleanvars = [
'batchmode', 'nonstopmode', 'fast', 'fastdisabled', 'silentmode', 'final',
'paranoid', 'notparanoid', 'nobanner', 'once', 'allpatterns',
- 'nompmode', 'nomprun', 'automprun',
+ 'nompmode', 'nomprun', 'automprun', 'combine',
'nomapfiles', 'local',
'arrange', 'noarrange',
'forcexml', 'foxet',
@@ -244,6 +266,11 @@ class TEX
setvariable('texengine', 'standard')
setvariable('mpsengine', 'standard')
setvariable('backend', 'standard')
+ setvariable('error', '')
+ end
+
+ def error?
+ not getvariable('error').empty?
end
def runtime
@@ -344,11 +371,12 @@ class TEX
end
def prefixed(format,engine)
+ # format
case engine
- when /etex|eetex|pdfetex|pdfeetex|pdfxtex|xpdfetex|eomega|aleph|xetex|luatex/io then
- "*#{format}"
- else
- format
+ when /etex|pdftex|pdfetex|aleph|xetex|luatex/io then
+ "*#{format}"
+ else
+ format
end
end
@@ -608,7 +636,7 @@ class TEX
f.close
if FileTest.file?(tempfilename('tex')) then
format = File.basename(name)
- engine = if name =~ /(pdfetex|aleph|xetex)[\/\\]#{format}/ then $1 else '' end
+ engine = if name =~ /(pdftex|pdfetex|aleph|xetex|luatex)[\/\\]#{format}/ then $1 else '' end
if engine.empty? then
engineflag = ""
else
@@ -843,7 +871,7 @@ class TEX
if tmp = openedfile(File.suffixed(rawbase,'run')) then
tmp << "\\starttext\n"
if forcexml then
- tmp << checkxmlfile(rawname)
+ # tmp << checkxmlfile(rawname)
tmp << "\\processXMLfilegrouped{#{rawname}}\n"
else
tmp << "\\processfile{#{rawname}}\n"
@@ -856,8 +884,48 @@ class TEX
end
end
+ # def checkxmlfile(rawname)
+ # tmp = ''
+ # if FileTest.file?(rawname) && (xml = File.open(rawname)) then
+ # xml.each do |line|
+ # case line
+ # when /<\?context\-directive\s+(\S+)\s+(\S+)\s+(\S+)\s*(.*?)\s*\?>/o then
+ # category, key, value, rest = $1, $2, $3, $4
+ # case category
+ # when 'job' then
+ # case key
+ # when 'control' then
+ # setvariable(value,if rest.empty? then true else rest end)
+ # when 'mode', 'modes' then
+ # tmp << "\\enablemode[#{value}]\n"
+ # when 'stylefile', 'environment' then
+ # tmp << "\\environment #{value}\n"
+ # when 'module' then
+ # tmp << "\\usemodule[#{value}]\n"
+ # when 'interface' then
+ # contextinterface = value
+ # when 'ctxfile' then
+ # setvariable('ctxfile', value)
+ # report("using source driven ctxfile #{value}")
+ # end
+ # end
+ # when /<[a-z]+/io then # beware of order, first pi test
+ # break
+ # end
+ # end
+ # xml.close
+ # end
+ # return tmp
+ # end
+
+ def extendvariable(name,value)
+ set = getvariable(name).split(',')
+ set << value
+ str = set.uniq.join(',')
+ setvariable(name,str)
+ end
+
def checkxmlfile(rawname)
- tmp = ''
if FileTest.file?(rawname) && (xml = File.open(rawname)) then
xml.each do |line|
case line
@@ -868,12 +936,14 @@ class TEX
case key
when 'control' then
setvariable(value,if rest.empty? then true else rest end)
- when 'mode', 'modes' then
- tmp << "\\enablemode[#{value}]\n"
- when 'stylefile', 'environment' then
- tmp << "\\environment #{value}\n"
- when 'module' then
- tmp << "\\usemodule[#{value}]\n"
+ when /^(mode)(s|)$/ then
+ extendvariable('modes',value)
+ when /^(stylefile|environment)(s|)$/ then
+ extendvariable('environments',value)
+ when /^(use|)(module)(s|)$/ then
+ extendvariable('usemodules',value)
+ when /^(filter)(s|)$/ then
+ extendvariable('filters',value)
when 'interface' then
contextinterface = value
when 'ctxfile' then
@@ -887,7 +957,6 @@ class TEX
end
xml.close
end
- return tmp
end
end
@@ -935,6 +1004,87 @@ class TEX
reportruntime
end
+ def processmpgraphic
+ getarrayvariable('files').each do |filename|
+ setvariable('filename',filename)
+ report("processing graphic '#{filename}'")
+ runtexmp(filename)
+ begin
+ data = IO.read(File.suffixed(filename,'log'))
+ basename = filename.sub(/\.mp$/, '')
+ if data =~ /output files* written\:\s*(.*)$/mois then
+ files, number, range, list = $1.split(/\s+/), 0, false, []
+ files.each do |fname|
+ if fname =~ /^.*\.(\d+)$/ then
+ if range then
+ (number+1 .. $1.to_i).each do |i|
+ list << i
+ end
+ range = false
+ else
+ number = $1.to_i
+ list << number
+ end
+ elsif fname =~ /\.\./ then
+ range = true
+ else
+ range = false
+ next
+ end
+ end
+ begin
+ if getvariable('combine') then
+ fullname = "#{basename}.#{number}"
+ File.open("texexec.tex",'w') do |f|
+ f << "\\setupoutput[pdftex]\n"
+ f << "\\setupcolors[state=start]\n"
+ f << "\\starttext\n"
+ list.each do |number|
+ f << "\\startTEXpage\n"
+ f << "\\convertMPtoPDF{#{fullname}}{1}{1}"
+ f << "\\stopTEXpage\n"
+ end
+ f << "\\stoptext\n"
+ end
+ report("converting graphic '#{fullname}'")
+ runtex("texexec.tex")
+ pdffile = File.suffixed(basename,'pdf')
+ File.silentrename("texexec.pdf",pdffile)
+ report ("#{basename}.* converted to #{pdffile}")
+ else
+ list.each do |number|
+ begin
+ fullname = "#{basename}.#{number}"
+ File.open("texexec.tex",'w') do |f|
+ f << "\\setupoutput[pdftex]\n"
+ f << "\\setupcolors[state=start]\n"
+ f << "\\starttext \\startTEXpage\n"
+ f << "\\convertMPtoPDF{#{fullname}}{1}{1}"
+ f << "\\stopTEXpage \\stoptext\n"
+ end
+ report("converting graphic '#{fullname}'")
+ runtex("texexec.tex")
+ if files.length>1 then
+ pdffile = File.suffixed(basename,number.to_s,'pdf')
+ else
+ pdffile = File.suffixed(basename,'pdf')
+ end
+ File.silentrename("texexec.pdf",pdffile)
+ report ("#{fullname} converted to #{pdffile}")
+ end
+ end
+ end
+ rescue
+ report ("error when converting #{fullname} (#{$!})")
+ end
+ end
+ rescue
+ report("error in converting #{filename}")
+ end
+ end
+ reportruntime
+ end
+
def processmpxtex
getarrayvariable('files').each do |filename|
setvariable('filename',filename)
@@ -1019,7 +1169,7 @@ class TEX
opt << "\\setuppapersize[#{$1.upcase}][#{$2.upcase}]\n"
else # ...*...
pf = str.upcase.split(/[x\*]/o)
- pf << pf[0] if pd.size == 1
+ pf << pf[0] if pf.size == 1
opt << "\\setuppapersize[#{pf[0]}][#{pf[1]}]\n"
end
end
@@ -1102,7 +1252,7 @@ class TEX
report("unable to write option file #{topname}")
end
rescue
- report("fatal error in writing option file #{topname}")
+ report("fatal error in writing option file #{topname} (#{$!})")
end
end
@@ -1182,7 +1332,7 @@ class TEX
if texengine && texformat && progname then
fixbackendvars(@@mappaths[texengine])
runcommand([quoted(texengine),prognameflag(progname),formatflag(texengine,texformat),tcxflag,runoptions(texengine),filename,texprocextras(texformat)])
- true
+ # true
else
false
end
@@ -1260,7 +1410,7 @@ class TEX
end
end
- # 1=tex 2=mptex 3=mpxtex
+ # 1=tex 2=mptex 3=mpxtex 4=mpgraphic
def runtexexec(filename=[], options=[], mode=nil)
begin
@@ -1278,6 +1428,7 @@ class TEX
when 1 then job.processtex
when 2 then job.processmptex
when 3 then job.processmpxtex
+ when 4 then job.processmpgraphic
end
job.inspect && Kpse.inspect if getvariable('verbose')
return true
@@ -1402,7 +1553,11 @@ class TEX
end
end
- jobsuffix = makestubfile(rawname,rawbase,forcexml) if dummyfile || forcexml
+ if dummyfile || forcexml then
+ jobsuffix = makestubfile(rawname,rawbase,forcexml)
+ checkxmlfile(rawname)
+ end
+
# preprocess files
@@ -1505,6 +1660,9 @@ class TEX
stoprunning = state.stable?
end
end
+ if not ok then
+ setvariable('error','error in tex file')
+ end
ok = runtexutil(rawbase) if (nofruns == 1) && getvariable('texutil')
if ok && finalrun && (nofruns > 1) then
makeoptionfile(rawbase,jobname,orisuffix,true,finalrun,4,texruns) unless getvariable('nooptionfile')
diff --git a/scripts/context/ruby/base/texutil.rb b/scripts/context/ruby/base/texutil.rb
index 3d25c3e97..b81604c17 100644
--- a/scripts/context/ruby/base/texutil.rb
+++ b/scripts/context/ruby/base/texutil.rb
@@ -468,7 +468,7 @@ class TeXUtil
def build(sorter)
@sortkey = sorter.normalize(sorter.tokenize(@sortkey))
- @sortkey = sorter.remap(sorter.simplify(@key.downcase))
+ @sortkey = sorter.remap(sorter.simplify(@key.downcase)) # ??
if @sortkey.empty? then
@sortkey = sorter.remap(@command.downcase)
end
@@ -550,6 +550,9 @@ class TeXUtil
class Register
+@@specialsymbol = "\000"
+@@specialbanner = "" # \\relax"
+
@@debug = false
@@debug = true
@@ -593,7 +596,12 @@ 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 special then
+ @sortkey = "#{@@specialsymbol}#{@sortkey}"
+end
@sortkey = [
@sortkey.downcase,
@sortkey,
@@ -667,6 +675,8 @@ end
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}"
diff --git a/scripts/context/ruby/ctxtools.rb b/scripts/context/ruby/ctxtools.rb
index b1e880682..420145db0 100644
--- a/scripts/context/ruby/ctxtools.rb
+++ b/scripts/context/ruby/ctxtools.rb
@@ -46,6 +46,8 @@
banner = ['CtxTools', 'version 1.3.3', '2004/2006', 'PRAGMA ADE/POD']
+# todo dirname
+
unless defined? ownpath
ownpath = $0.sub(/[\\\/][a-z0-9\-]*?\.rb/i,'')
$: << ownpath
@@ -448,7 +450,7 @@ class Commands
globbed = if recurse then "**/#{pat}.*" else "#{pat}.*" end
files.push(Dir.glob(globbed))
end
- report("purging#{if all then ' all' end} temporary files : #{pattern.join(' ')}")
+ report("purging#{if purgeall then ' all' end} temporary files : #{pattern.join(' ')}")
end
files.flatten!
files.sort!
@@ -528,7 +530,8 @@ class Commands
$forsuresuffixes = [
"tui", "tup", "ted", "tes", "top",
"log", "tmp", "run", "bck", "rlg",
- "mpt", "mpx", "mpd", "mpo", "ctl",
+ "mpt", "mpx", "mpd", "mpo", "mpb",
+ "ctl",
"tmp.md5", "tmp.out"
]
$texonlysuffixes = [
@@ -2316,6 +2319,13 @@ class Commands
report("fatal error, make sure that you have 'unzip' in your path")
return false
else
+ if System.unix? then
+ begin
+ system("chmod +x scripts/context/unix/stubs/*")
+ rescue
+ report("change x-permissions of 'scripts/context/unix/stubs/*' manually")
+ end
+ end
return true
end
else
diff --git a/scripts/context/ruby/fcd_start.rb b/scripts/context/ruby/fcd_start.rb
index 8ac48f79e..348ac75ba 100644
--- a/scripts/context/ruby/fcd_start.rb
+++ b/scripts/context/ruby/fcd_start.rb
@@ -256,6 +256,8 @@ class FastCD
@result = @list.grep(/\/#{@pattern}[^\/]*$/i)
end
end
+ else
+ puts(Dir.pwd.gsub(/\\/o, '/'))
end
rescue
end
@@ -403,31 +405,37 @@ class FastCD
end
+$stdout.sync = true
+
verbose, action, args = false, :find, Array.new
-usage = "fcd [--make|add|show|find] [--verbose] [pattern]"
+usage = "fcd [--add|clear|find|list|make|show|stub] [--verbose] [pattern]"
+version = "1.0.2"
+
+def quit(message)
+ puts(message)
+ exit
+end
ARGV.each do |a|
case a
- when '-v', '--verbose' then verbose = true
- when '-m', '--make' then action = :make
- when '-c', '--clear' then action = :clear
when '-a', '--add' then action = :add
- when '-s', '--show' then action = :show
- when '-l', '--list' then action = :show
+ when '-c', '--clear' then action = :clear
when '-f', '--find' then action = :find
+ when '-l', '--list' then action = :show
+ when '-m', '--make' then action = :make
+ when '-s', '--show' then action = :show
when '--stub' then action = :stub
- when '-h', '--help' then puts "usage: #{usage}" ; exit
- when /^\-\-.*/ then puts "unknown switch: #{a}" + "\n" + "usage: #{usage}" ; exit
+ when '-v', '--verbose' then verbose = true
+ when '--version' then quit("version: #{version}")
+ when '-h', '--help' then quit("usage: #{usage}")
+ when /^\-\-.*/ then quit("error: unknown switch #{a}, try --help")
else args << a
end
end
-$stdout.sync = true
-
fcd = FastCD.new(verbose)
-
-fcd.report("Fast Change Dir / version 1.0")
+fcd.report("Fast Change Dir / version #{version}")
case action
when :make then
diff --git a/scripts/context/ruby/pdftools.rb b/scripts/context/ruby/pdftools.rb
new file mode 100644
index 000000000..8a62a0487
--- /dev/null
+++ b/scripts/context/ruby/pdftools.rb
@@ -0,0 +1,816 @@
+#!/usr/bin/env ruby
+
+# program : pdftools
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2003-2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+# This script will harbor some handy manipulations on tex
+# related files.
+
+banner = ['PDFTools', 'version 1.2.1', '2003/2005', 'PRAGMA ADE/POD']
+
+unless defined? ownpath
+ ownpath = $0.sub(/[\\\/][a-z0-9\-]*?\.rb/i,'')
+ $: << ownpath
+end
+
+require 'base/switch'
+require 'base/logger'
+
+require 'ftools'
+
+class File
+
+ def File.deletefiles(*filenames)
+ filenames.flatten.each do |filename|
+ begin
+ delete(filename) if FileTest.file?(filename)
+ rescue
+ end
+ end
+ end
+
+ def File.needsupdate(oldname,newname)
+ begin
+ return File.stat(oldname).mtime != File.stat(newname).mtime
+ rescue
+ return true
+ end
+ end
+
+ def File.syncmtimes(oldname,newname)
+ begin
+ t = Time.now # i'm not sure if the time is frozen, so we do it here
+ File.utime(0,t,oldname,newname)
+ rescue
+ end
+ end
+
+ def File.replacesuffix(oldname,subpath='')
+ newname = File.expand_path(oldname.sub(/\.\w+?$/,'.pdf'))
+ File.join(File.dirname(newname),subpath,File.basename(newname))
+ end
+
+end
+
+class ImageMagick
+
+ def initialize
+
+ begin
+ version = `convert -version`
+ rescue
+ @binary = nil
+ ensure
+ if (version) && (! version.empty?) && (version =~ /ImageMagick/mo) && (version =~ /version/mio) then
+ @binary = 'convert'
+ else
+ @binary = 'imagemagick'
+ end
+ end
+
+ end
+
+ def process(arguments)
+ begin
+ @binary && system("#{@binary} #{arguments}")
+ rescue
+ false
+ end
+ end
+
+end
+
+class TexExec
+
+ def initialize
+ @binary = 'texmfstart texexec.pl --pdf --batch --silent --purge'
+ end
+
+ def process(arguments,once=true)
+ begin
+ if once then
+ @binary && system("#{@binary} --once #{arguments}")
+ else
+ @binary && system("#{@binary} #{arguments}")
+ end
+ rescue
+ false
+ end
+ end
+
+end
+
+class PdfImages
+
+ def initialize
+ @binary = "pdfimages"
+ end
+
+ def process(arguments)
+ begin
+ @binary && system("#{@binary} #{arguments}")
+ rescue
+ false
+ end
+ end
+
+end
+
+class ConvertImage
+
+ def initialize(command=nil)
+ @command = command
+ end
+
+ def convertimage(filename)
+
+ return if filename =~ /\.(pdf)$/io
+
+ retain = @command.option('retain')
+ subpath = @command.option('subpath')
+
+ if filename =~ /\s/ then
+ @command.report("skipping strange filename '#{filename}'")
+ else
+ newname = File.replacesuffix(filename,subpath)
+ # newname.gsub!(s/[^a-zA-Z0-9\_-\.]/o, '-')
+ begin
+ File.makedirs(File.dirname(newname))
+ rescue
+ end
+ if ! retain || File.needsupdate(filename,newname) then
+ imagemagick = ImageMagick.new
+ if imagemagick then
+ ok = imagemagick.process("-compress zip -quality 99 #{filename} #{newname}")
+ File.syncmtimes(oldname,newname) if retain
+ end
+ end
+ end
+ end
+
+end
+
+class DownsampleImage
+
+ def initialize(command=nil)
+ @command = command
+ end
+
+ def convertimage(filename)
+
+ return if filename =~ /\.(pdf)$/io
+
+ retain = @command.option('retain')
+ subpath = @command.option('subpath')
+
+ if @command.option('lowres') then
+ method = '4'
+ elsif @command.option('medres') || @command.option('normal') then
+ method = '5'
+ else
+ method = '4'
+ end
+
+ if filename =~ /\s/ then
+ @command.report("skipping strange filename '#{filename}'")
+ else
+ newname = File.replacesuffix(filename,subpath)
+ begin
+ File.makedirs(File.dirname(newname))
+ rescue
+ end
+ if ! retain || File.needsupdate(filename,newname) then
+ ok = system("texmfstart pstopdf.rb --method=#{method} #{filename} #{newname}")
+ File.syncmtimes(oldname,newname) if retain
+ end
+ end
+ end
+
+end
+
+class ColorImage
+
+ def initialize(command=nil,tmpname='pdftools')
+ @command = command
+ @tmpname = tmpname
+ @colorname = nil
+ @colorspec = nil
+ @colorspace = nil
+ end
+
+ def registercolor(spec='.5',name='c')
+ name = name || 'c'
+ spec = spec.split(',')
+ case spec.length
+ when 4
+ @colorname, @colorspec, @colorspace = name, spec.join('/'), 'cmyk'
+ when 3
+ @colorname, @colorspec, @colorspace = name, spec.join('/'), 'rgb'
+ when 1
+ @colorname, @colorspec, @colorspace = name, spec.join('/'), 'gray'
+ else
+ @colorname, @colorspec, @colorspace = nil, nil, nil
+ end
+ end
+
+ def convertimage(filename)
+
+ invert = @command.option('invert')
+ retain = @command.option('retain')
+ subpath = @command.option('subpath')
+
+ subpath += '/' unless subpath.empty?
+
+ if @colorname && ! @colorname.empty? && @colorspec && ! @colorspec.empty? then
+ basename = filename.sub(/\.\w+?$/,'')
+ oldname = filename
+ ppmname = @tmpname + '-000.ppm'
+ jpgname = @tmpname + '-000.jpg'
+ newname = File.expand_path(oldname)
+ newname = File.dirname(newname) + '/' + subpath + @colorname + '-' + File.basename(newname)
+ newname.sub!(/\.\w+?$/, '.pdf')
+ begin
+ File.makedirs(File.dirname(newname))
+ rescue
+ end
+ if ! retain || File.needsupdate(filename,newname) then
+ pdfimages = PdfImages.new
+ imagemagick = ImageMagick.new
+ if pdfimages && imagemagick then
+ File.deletefiles(ppmname,jpgname,newname)
+ if filename =~ /\.(pdf)$/io then
+ ok = pdfimages.process("-j -f 1 -l 1 #{filename} #{@tmpname}")
+ if ok then
+ if FileTest.file?(ppmname) then
+ inpname = ppmname
+ elsif FileTest.file?(jpgname) then
+ inpname = jpgname
+ else
+ ok = false
+ end
+ if ok then
+ switch = if ! invert then '-negate' else '' end
+ # make sure that we keep the format
+ tmpname = File.basename(inpname)
+ tmpname = tmpname.sub(/(.*)\..*?$/,@tmpname) # somehow sub! fails here
+ ok = imagemagick.process("-colorspace gray #{switch} #{inpname} #{tmpname}")
+ if ! ok || ! FileTest.file?(tmpname) then
+ # problems
+ else
+ ok = imagemagick.process("-colorspace #{switch} #{@colorspace} -colorize #{@colorspec} -compress zip #{tmpname} #{newname}")
+ if ! ok || ! FileTest.file?(newname) then
+ # unable to colorize image
+ else
+ # conversion done
+ end
+ end
+ end
+ end
+ else
+ # make sure that we keep the format
+ tmpname = File.basename(basename)
+ tmpname = tmpname.sub(/(.*)\..*?$/,@tmpname) # somehow sub! fails here
+ ok = imagemagick.process("-colorspace gray #{oldname} #{tmpname}")
+ if ! ok || ! FileTest.file?(tmpname) then
+ # unable to convert color to gray
+ else
+ ok = imagemagick.process("-colorspace #{@colorspace} -colorize #{@colorspec} -compress zip #{tmpname} #{newname}")
+ if ! ok || ! FileTest.file?(newname) then
+ # unable to colorize image
+ else
+ # conversion done
+ end
+ end
+ end
+ File.deletefiles(ppmname,jpgname,tmpname)
+ File.syncmtimes(filename,newname) if retain
+ end
+ end
+ end
+ end
+
+end
+
+class SpotColorImage
+
+ def initialize(command=nil, tmpname='pdftools')
+ @command = command
+ @tmpname = tmpname
+ @colorname = nil
+ @colorspec = nil
+ @colorspace = nil
+ @colorfile = nil
+ end
+
+ def registercolor(spec='.5',name='unknown')
+ name = name || 'unknown'
+ if spec =~ /^[\d\.\,]+$/ then
+ spec = spec.split(',')
+ case spec.length
+ when 4
+ @colorname, @colorspec, @colorspace = name, ["c=#{spec[0]}","m=#{spec[1]}","y=#{spec[2]}","k=#{spec[3]}"].join(','), 'cmyk'
+ when 3
+ @colorname, @colorspec, @colorspace = name, ["r=#{spec[0]}","g=#{spec[1]}","b=#{spec[2]}"].join(','), 'rgb'
+ when 1
+ @colorname, @colorspec, @colorspace = name, ["s=#{spec[0]}"].join(','), 'gray'
+ else
+ @colorname, @colorspec, @colorspace = nil, nil, nil
+ end
+ else
+ @colorname, @colorfile = name, spec
+ end
+ end
+
+ def convertgrayimage(filename)
+
+ invert = @command.option('invert')
+ retain = @command.option('retain')
+ subpath = @command.option('subpath')
+
+ subpath += '/' unless subpath.empty?
+
+ if @colorname && ! @colorname.empty? && ((@colorspec && ! @colorspec.empty?) || (@colorfile && ! @colorfile.empty?)) then
+ basename = filename.sub(/\.\w+?$/,'')
+ oldname = filename # png jpg pdf
+ newname = File.expand_path(oldname)
+ ppmname = @tmpname + '-000.ppm'
+ jpgname = @tmpname + '-000.jpg'
+ outname = @tmpname + '-000.pdf'
+ texname = @tmpname + '-temp.tex'
+ pdfname = @tmpname + '-temp.pdf'
+ newname = File.dirname(newname) + '/' + subpath + @colorname + '-' + File.basename(newname)
+ newname.sub!(/\.\w+?$/, '.pdf')
+ begin
+ File.makedirs(File.dirname(newname))
+ rescue
+ end
+ if ! retain || File.needsupdate(filename,newname) then
+ pdfimages = PdfImages.new
+ imagemagick = ImageMagick.new
+ texexec = TexExec.new
+ if pdfimages && imagemagick && texexec then
+ if filename =~ /\.(jpg|png|pdf)$/io then
+ @command.report("processing #{basename}")
+ File.deletefiles(ppmname,jpgname,newname)
+ switch = if ! invert then '-negate' else '' end
+ if filename =~ /\.(pdf)$/io then
+ ok = pdfimages.process("-j -f 1 -l 1 #{oldname} #{@tmpname}")
+ if ok then
+ if FileTest.file?(ppmname) then
+ inpname = ppmname
+ elsif FileTest.file?(jpgname) then
+ inpname = jpgname
+ else
+ ok = false
+ end
+ if ok then
+ ok = imagemagick.process("-colorspace gray #{switch} -compress zip #{inpname} #{outname}")
+ end
+ end
+ else
+ ok = imagemagick.process("-colorspace gray #{switch} -compress zip #{oldname} #{outname}")
+ end
+ if ok then
+ ok = false unless FileTest.file?(outname)
+ end
+ if ok then
+ if f = File.open(texname, 'w') then
+ f.puts(conversionfile(filename,outname,newname))
+ f.close
+ ok = texexec.process(texname)
+ else
+ ok = false
+ end
+ @command.report("error in processing #{newname}") unless ok
+ if FileTest.file?(pdfname) then
+ if f = File.open(pdfname,'r') then
+ f.binmode
+ begin
+ if g = File.open(newname,'w') then
+ g.binmode
+ data = f.read
+ # pdftex (direct) & imagemagick (indirect)
+ if data =~ /(\d+)\s+0\s+obj\s+\[\/Separation\s+\/#{@colorname}/mos then
+ @command.report("replacing separation color")
+ object = $1
+ data.gsub!(/(\/Type\s+\/XObject.*?)(\/ColorSpace\s*(\/DeviceGray|\/DeviceCMYK|\/DeviceRGB|\d+\s+\d+\s+R))/mois) do
+ $1 + "/ColorSpace #{object} 0 R".ljust($2.length)
+ end
+ elsif data =~ /(\d+)\s+0\s+obj\s+\[\/Indexed\s*\[/mos then
+ @command.report("replacing indexed color")
+ # todo: more precise check on color
+ object = $1
+ data.gsub!(/(\/Type\s+\/XObject.*?)(\/ColorSpace\s*(\/DeviceGray|\/DeviceCMYK|\/DeviceRGB|\d+\s+\d+\s+R))/mois) do
+ $1 + "/ColorSpace #{object} 0 R".ljust($2.length)
+ end
+ elsif data =~ /(\d+)\s+0\s+obj\s+\[\/Separation/mos then
+ @command.report("replacing separation color")
+ object = $1
+ data.gsub!(/(\/Type\s+\/XObject.*?)(\/ColorSpace\s*(\/DeviceGray|\/DeviceCMYK|\/DeviceRGB|\d+\s+\d+\s+R))/mois) do
+ $1 + "/ColorSpace #{object} 0 R".ljust($2.length)
+ end
+ end
+ g.write(data)
+ g.close
+ end
+ rescue
+ @command.report("error in converting #{newname}")
+ else
+ @command.report("#{newname} is converted")
+ end
+ f.close
+ end
+ else
+ @command.report("error in writing #{newname}")
+ end
+ else
+ @command.report("error in producing #{newname}")
+ end
+ File.deletefiles(ppmname,jpgname,outname)
+ # File.deletefiles(texname,pdfname)
+ File.syncmtimes(filename,newname) if retain
+ end
+ else
+ @command.report("error in locating binaries")
+ end
+ else
+ @command.report("#{newname} is not changed")
+ end
+ end
+ end
+
+ private
+
+ # % example colorfile:
+ #
+ # \definecolor [darkblue] [c=1,m=.38,y=0,k=.64] % pantone pms 2965 uncoated m
+ # \definecolor [darkyellow] [c=0,m=.28,y=1,k=.06] % pantone pms 124 uncoated m
+ #
+ # % \definecolor [darkblue-100] [darkblue] [p=1]
+ # % \definecolor [darkyellow-100] [darkyellow] [p=1]
+ #
+ # \definecolorcombination [pdftoolscolor] [darkblue=.12,darkyellow=.28] [c=.1,m=.1,y=.3,k=.1]
+
+ def conversionfile(originalname,filename,finalname)
+ tex = "\\setupcolors[state=start]\n"
+ if @colorfile then
+ tex += "\\readfile{#{@colorfile}}{}{}\n"
+ tex += "\\starttext\n"
+ # tex += "\\predefineindexcolor[pdftoolscolor]\n"
+ tex += "\\startTEXpage\n"
+ tex += "\\pdfimage{#{filename}}\n"
+ tex += "\\stopTEXpage\n"
+ tex += "\\stoptext\n"
+ else
+ tex += "\\definecolor[#{@colorname}][#{@colorspec}]\n"
+ tex += "\\definecolor[pdftoolscolor][#{@colorname}][p=1]\n"
+ tex += "\\starttext\n"
+ tex += "\\startTEXpage\n"
+ tex += "\\hbox{\\color[pdftoolscolor]{\\pdfimage{#{filename}}}}\n"
+ tex += "\\stopTEXpage\n"
+ tex += "\\stoptext\n"
+ end
+ tex += "\n"
+ tex += "% old: #{originalname}\n"
+ tex += "% new: #{finalname}\n"
+ return tex
+ end
+
+end
+
+module XML
+
+ def XML::version
+ "<?xml version='1.0'?>"
+ end
+
+ def XML::start(element, attributes='')
+ if attributes.empty? then
+ "<#{element}>"
+ else
+ "<#{element} #{attributes}>"
+ end
+ end
+
+ def XML::end(element)
+ "</#{element}>"
+ end
+
+ def XML::empty(element, attributes='')
+ if attributes && attributes.empty? then
+ "<#{element}/>"
+ else
+ "<#{element} #{attributes}/>"
+ end
+ end
+
+ def XML::element(element, attributes='', content='')
+ if content && ! content.empty? then
+ XML::start(element,attributes) + content + XML::end(element)
+ else
+ XML::empty(element,attributes)
+ end
+ end
+
+ def XML::box(tag, rect, type=1)
+ case type
+ when 1
+ if rect && ! rect.empty? then
+ rect = rect.split(' ')
+ XML::element("#{tag}box", '',
+ XML::element("llx", '', rect[0]) +
+ XML::element("lly", '', rect[1]) +
+ XML::element("ulx", '', rect[2]) +
+ XML::element("uly", '', rect[3]) )
+ else
+ XML::empty("#{tag}box")
+ end
+ when 2
+ if rect && ! rect.empty? then
+ rect = rect.split(' ')
+ XML::element("box", "type='#{tag}'",
+ XML::element("llx", '', rect[0]) +
+ XML::element("lly", '', rect[1]) +
+ XML::element("ulx", '', rect[2]) +
+ XML::element("uly", '', rect[3]) )
+ else
+ XML::empty("box", "type='#{tag}'")
+ end
+ when 3
+ if rect && ! rect.empty? then
+ rect = rect.split(' ')
+ XML::element("box", "type='#{tag}' llx='#{rect[0]}' lly='#{rect[1]}' ulx='#{rect[2]}' uly='#{rect[3]}'")
+ else
+ XML::empty("box", "type='#{tag}'")
+ end
+ else
+ ''
+ end
+ end
+
+ def XML::crlf
+ "\n"
+ end
+
+ def XML::skip(n=1)
+ ' '*n
+ end
+
+end
+
+class Commands
+
+ include CommandBase
+
+ # alias savedhelp :help
+
+ # def help
+ # savedhelp
+ # report("under construction (still separate tools)")
+ # end
+
+ # filename.pdf --spotimage --colorname=darkblue --colorspec=1,0.38,0,0.64
+
+ def spotimage
+
+ if ! @commandline.argument('first').empty? && files = findfiles() then
+ colorname = @commandline.option('colorname')
+ colorspec = @commandline.option('colorspec')
+ if colorname && ! colorname.empty? && colorspec && ! colorspec.empty? then
+ files.each do |filename|
+ s = SpotColorImage.new(self)
+ s.registercolor(colorspec,colorname)
+ s.convertgrayimage(filename)
+ end
+ else
+ report("provide --colorname=somename --colorspec=c,m,y,k")
+ end
+ else
+ report("provide filename (png, jpg, pdf)")
+ end
+
+ end
+
+ def colorimage
+
+ if ! @commandline.argument('first').empty? && files = findfiles() then
+ colorname = @commandline.option('colorname')
+ colorspec = @commandline.option('colorspec')
+ if colorspec && ! colorspec.empty? then
+ files.each do |filename|
+ s = ColorImage.new(self)
+ s.registercolor(colorspec,colorname) # name optional
+ s.convertimage(filename)
+ end
+ else
+ report("provide --colorspec=c,m,y,k")
+ end
+ else
+ report("provide filename")
+ end
+
+ end
+
+ def convertimage
+
+ if ! @commandline.argument('first').empty? && files = findfiles() then
+ files.each do |filename|
+ s = ConvertImage.new(self)
+ s.convertimage(filename)
+ end
+ else
+ report("provide filename")
+ end
+
+ end
+
+ def downsampleimage
+
+ if ! @commandline.argument('first').empty? && files = findfiles() then
+ files.each do |filename|
+ s = DownsampleImage.new(self)
+ s.convertimage(filename)
+ end
+ else
+ report("provide filename")
+ end
+
+ end
+
+ def info
+
+ if files = findfiles() then
+
+ print(XML.version + XML.crlf)
+ print(XML.start('pdfinfo', "xmlns='http://www.pragma-ade.com/schemas/pdfinfo.rng'") + XML.crlf)
+
+ files.each do |filename|
+
+ if filename =~ /\.pdf$/io then
+
+ begin
+ data = `pdfinfo -box #{filename}`.chomp.split("\n")
+ rescue
+ data = nil
+ end
+
+ if data then
+
+ pairs = Hash.new
+
+ data.each do |d|
+ if (d =~ /^\s*(.*?)\s*\:\s*(.*?)\s*$/mois) then
+ key, val = $1, $2
+ pairs[key.downcase.sub(/ /,'')] = val
+ end
+ end
+
+ print(XML.skip(1) + XML.start('pdffile', "filename='#{filename}'") + XML.crlf)
+
+ print(XML.skip(2) + XML.element('path', '', File.expand_path(filename)) + XML.crlf)
+
+ if pairs.key?('error') then
+
+ print(XML.skip(2) + XML.element('comment', '', pairs['error']) + XML.crlf)
+
+ else
+
+ print(XML.skip(2) + XML.element('version', '', pairs['pdfversion']) + XML.crlf)
+ print(XML.skip(2) + XML.element('pages', '', pairs['pages' ]) + XML.crlf)
+ print(XML.skip(2) + XML.element('title', '', pairs['title' ]) + XML.crlf)
+ print(XML.skip(2) + XML.element('subject', '', pairs['subject' ]) + XML.crlf)
+ print(XML.skip(2) + XML.element('author', '', pairs['author' ]) + XML.crlf)
+ print(XML.skip(2) + XML.element('producer', '', pairs['producer' ]) + XML.crlf)
+
+ if pairs.key?('creationdate') then
+ pairs['creationdate'].sub!(/(\d\d)\/(\d\d)\/(\d\d)/) do
+ '20' + $3 + '-' + $1 + '-' +$2
+ end
+ pairs['creationdate'].sub!(/(\d\d)\/(\d\d)\/(\d\d\d\d)/) do
+ $3 + '-' + $1 + '-' + $2
+ end
+ print(XML.skip(2) + XML.element('creationdate', '', pairs['creationdate']) + XML.crlf)
+ end
+
+ if pairs.key?('moddate') then
+ if pairs['moddate'] =~ /(\d\d\d\d)(\d\d)(\d\d)/ then
+ pairs['moddate'] = "#{$1}-#{$2}-#{$3}"
+ end
+ print(XML.skip(2) + XML.element('modificationdate', '', pairs['moddate']) + XML.crlf)
+ end
+
+ print(XML.skip(2) + XML.element('tagged', '', pairs['tagged' ]) + XML.crlf)
+ print(XML.skip(2) + XML.element('encrypted', '', pairs['encrypted']) + XML.crlf)
+ print(XML.skip(2) + XML.element('optimized', '', pairs['optimized']) + XML.crlf)
+
+ if pairs.key?('PageSize') then
+ print(XML.skip(2) + XML.element('width', '', pairs['pagesize'].sub(/\s*(.*?)\s+(.*?)\s+.*/, $1)) + XML.crlf)
+ print(XML.skip(2) + XML.element('height', '', pairs['pagesize'].sub(/\s*(.*?)\s+(.*?)\s+.*/, $2)) + XML.crlf)
+ end
+
+ if pairs.key?('FileSize') then
+ print(XML.skip(2) + XML.element('size', '', pairs['filesize'].sub(/\s*(.*?)\s+.*/, $1)) + XML.crlf)
+ end
+
+ print(XML.skip(2) + XML.box('media', pairs['mediabox']) + XML.crlf)
+ print(XML.skip(2) + XML.box('crop' , pairs['cropbox' ]) + XML.crlf)
+ print(XML.skip(2) + XML.box('bleed', pairs['bleedbox']) + XML.crlf)
+ print(XML.skip(2) + XML.box('trim' , pairs['trimBox' ]) + XML.crlf)
+ print(XML.skip(2) + XML.box('art' , pairs['artbox' ]) + XML.crlf)
+
+ end
+
+ print(XML.skip(1) + XML.end('pdffile') + XML.crlf)
+
+ end
+
+ end
+
+ end
+
+ print(XML.end('pdfinfo') + XML.crlf)
+
+ end
+
+ end
+
+ def countpages
+ filenames, n = findfiles('pdf'), 0
+ filenames.each do |filename|
+ if `pdfinfo #{filename}`.chomp =~ /^pages\s*\:\s*(\d+)/mois then
+ report("#{$1.rjust(4)} pages found in #{filename}")
+ n += $1.to_i
+ end
+ end
+ report("#{n.to_s.rjust(4)} pages in total")
+ end
+
+ def analyzefile
+ # needs an update
+ filenames = @commandline.arguments
+ filenames.each do |filename|
+ if filename && FileTest.file?(filename) && filename =~ /\.pdf/io then
+ filesize = FileTest.size(filename)
+ report("analyzing file : #{filename}")
+ report("file size : #{filesize}")
+ if pdf = File.open(filename) then
+ pdf.binmode
+ nofobject, nofxform, nofannot, noflink, nofwidget, nofnamed, nofscript, nofcross = 0, 0, 0, 0, 0, 0, 0, 0
+ while data = pdf.gets do
+ data.scan(/\d+\s+\d+\s+obj/o) do nofobject += 1 end
+ data.scan(/\/Type\s*\/XObject/o) do nofxform += 1 end
+ data.scan(/\/Type\s*\/Annot/o) do nofannot += 1 end
+ data.scan(/\/GoToR\s*\/F/o) do nofcross += 1 end
+ data.scan(/\/Subtype\s*\/Link/o) do noflink += 1 end
+ data.scan(/\/Subtype\s*\/Widget/o) do nofwidget += 1 end
+ data.scan(/\/S\s*\/Named/o) do nofnamed += 1 end
+ data.scan(/\/S\s*\/JavaScript/o) do nofscript += 1 end
+ end
+ pdf.close
+ report("objects : #{nofobject}")
+ report("xforms : #{nofxform}")
+ report("annotations : #{nofannot}")
+ report("links : #{noflink} (#{nofnamed} named / #{nofscript} scripts / #{nofcross} files)")
+ report("widgets : #{nofwidget}")
+ end
+ end
+ end
+ end
+
+end
+
+logger = Logger.new(banner.shift)
+commandline = CommandLine.new
+
+commandline.registeraction('spotimage' , 'filename --colorspec= --colorname= [--retain --invert --subpath=]')
+commandline.registeraction('colorimage', 'filename --colorspec= [--retain --invert --colorname= ]')
+commandline.registeraction('convertimage', 'filename [--retain --subpath]')
+commandline.registeraction('downsampleimage', 'filename [--retain --subpath --lowres --normal]')
+commandline.registeraction('info', 'filename')
+commandline.registeraction('countpages', 'pattern')
+
+commandline.registeraction('analyzefile' , 'filename')
+
+commandline.registeraction('help')
+commandline.registeraction('version')
+
+commandline.registervalue('colorname')
+commandline.registervalue('colorspec')
+commandline.registervalue('subpath')
+
+commandline.registerflag('lowres')
+commandline.registerflag('medres')
+commandline.registerflag('normal')
+commandline.registerflag('invert')
+commandline.registerflag('retain')
+
+commandline.expand
+
+Commands.new(commandline,logger,banner).send(commandline.action || 'help')
diff --git a/scripts/context/ruby/texexec.rb b/scripts/context/ruby/texexec.rb
index a7b870376..14bc15662 100644
--- a/scripts/context/ruby/texexec.rb
+++ b/scripts/context/ruby/texexec.rb
@@ -63,6 +63,7 @@ class Commands
prepare(job)
job.processtex
job.inspect && Kpse.inspect if @commandline.option('verbose')
+ exit 1 if job.error?
end
end
@@ -72,6 +73,7 @@ class Commands
prepare(job)
job.processmptex
job.inspect && Kpse.inspect if @commandline.option('verbose')
+ exit 1 if job.error?
end
end
@@ -81,6 +83,17 @@ class Commands
prepare(job)
job.processmpxtex
job.inspect && Kpse.inspect if @commandline.option('verbose')
+ exit 1 if job.error?
+ end
+ end
+
+ def mpgraphic
+ if job = TEX.new(logger) then
+ job.setvariable('files',@commandline.arguments)
+ prepare(job)
+ job.processmpgraphic
+ job.inspect && Kpse.inspect if @commandline.option('verbose')
+ exit 1 if job.error?
end
end
@@ -137,8 +150,8 @@ class Commands
files = @commandline.arguments.sort
if files.length > 0 then
if f = File.open(job.tempfilename('tex'),'w') then
- # will be replaced
- Kpse.runscript('texutil',files.join(' '),'--figures')
+ # will be replaced, does not work any more
+ Kpse.runscript('texutil.pl',files.join(' '),'--figures')
figures = @commandline.checkedoption('method', 'a').downcase
paperoffset = @commandline.checkedoption('paperoffset', '0pt')
backspace = @commandline.checkedoption('backspace', '1.5cm')
@@ -410,6 +423,8 @@ class Commands
end
end
+ # todo: make this styles
+
def combineoutput
if job = TEX.new(logger) then
prepare(job)
@@ -419,20 +434,24 @@ class Commands
if f = File.open(job.tempfilename('tex'),'w') then
paperoffset = @commandline.checkedoption('paperoffset', '0cm')
combination = @commandline.checkedoption('combination','2*2').split(/[\*x]/o)
- paperformat = @commandline.checkedoption('paperoffset', 'A4*A4').split(/[\*x]/o)
+ paperformat = @commandline.checkedoption('paperformat', 'A4*A4').split(/[\*x]/o)
+ bannerheight = @commandline.checkedoption('bannerheight', '')
nx, ny = combination[0] || '2', combination[1] || combination[0] || '2'
from, to = paperformat[0] || 'A4', paperformat[1] || paperformat[0] || 'A4'
f << "\\setuppapersize[#{from}][#{to}]\n"
f << "\\setuplayout\n"
- f << " [topspace=#{paperoffset},\n"
- f << " backspace=#{paperoffset},\n"
- f << " header=0pt,\n"
- f << " footer=1cm,\n"
- f << " width=middle,\n"
- f << " height=middle]\n"
+ f << " [topspace=#{paperoffset},backspace=#{paperoffset},\n"
+ f << " header=0pt,footer=0pt,\n"
+ f << " width=middle,height=middle]\n"
+ if bannerheight.empty? then
+ f << "\\setuplayout[footer=1cm]\n"
+ else
+ f << "\\definelayer[page][width=\\paperwidth,height=\\paperheight]\n"
+ f << "\\setupbackgrounds[page][background=page]\n"
+ end
if @commandline.option('nobanner') then
- f << "\\setuplayout\n"
- f << " [footer=0cm]\n"
+ f << "\\setuplayout[footer=0cm]\n"
+ f << "\\setupbackgrounds[page][background=]\n"
end
f << "\\setupexternalfigures\n"
f << " [directory=]\n"
@@ -442,8 +461,15 @@ class Commands
if (filename !~ /^texexec/io) && (filename !~ /^#{result}/) then
report("combination file: #{filename}")
cleanname = cleantexfilename(filename).downcase
- f << "\\setupfootertexts\n"
- f << " [\\tttf #{cleanname}\\quad\\quad\\currentdate\\quad\\quad\\pagenumber]\n"
+ bannerstring = "\\tttf #{cleanname}\\quad\\quad\\currentdate\\quad\\quad\\pagenumber"
+ if bannerheight.empty? then
+ f << "\\setupfootertexts\n"
+ f << " [#{bannerstring}]\n"
+ else
+ # for the moment we lack a better hook
+ f << "\\setuptexttexts\n"
+ f << " [{\\setlayerframed[page][preset=middlebottom][frame=off,height=#{bannerheight}]{#{bannerstring}}}]\n"
+ end
f << "\\combinepages[#{filename}][nx=#{nx},ny=#{ny}]\n"
f << "\\page\n"
end
@@ -545,11 +571,12 @@ end
logger = Logger.new(banner.shift)
commandline = CommandLine.new
-commandline.registeraction('make', 'make formats')
-commandline.registeraction('check', 'check versions')
-commandline.registeraction('process', 'process file')
-commandline.registeraction('mptex', 'process mp file')
-commandline.registeraction('mpxtex', 'process mpx file')
+commandline.registeraction('make', 'make formats')
+commandline.registeraction('check', 'check versions')
+commandline.registeraction('process', 'process file')
+commandline.registeraction('mptex', 'process mp file')
+commandline.registeraction('mpxtex', 'process mpx file')
+commandline.registeraction('mpgraphic', 'process mp file to stand-alone graphics')
commandline.registeraction('listing', 'list of file content')
commandline.registeraction('figures', 'generate overview of figures')
@@ -577,7 +604,7 @@ end
# so far for compatibility
@@extrastringvars = [
- 'pages', 'background', 'backspace', 'topspace', 'boxtype', 'tempdir',
+ 'pages', 'background', 'backspace', 'topspace', 'boxtype', 'tempdir','bannerheight',
'printformat', 'paperformat', 'method', 'scale', 'selection',
'combination', 'paperoffset', 'textwidth', 'addempty', 'logfile',
'startline', 'endline', 'startcolumn', 'endcolumn', 'scale'
diff --git a/scripts/context/ruby/texmfstart.rb b/scripts/context/ruby/texmfstart.rb
index 22c9e36d1..1f76d703f 100644
--- a/scripts/context/ruby/texmfstart.rb
+++ b/scripts/context/ruby/texmfstart.rb
@@ -2263,9 +2263,11 @@ def process(&block)
oldchecksum = "old"
end
end
- if oldchecksum != newchecksum then
+ if $verbose then
report("old checksum #{filename}: #{oldchecksum}")
report("new checksum #{filename}: #{newchecksum}")
+ end
+ if oldchecksum != newchecksum then
report("file is changed, processing started")
begin
File.open(checkname,'w') do |f|
@@ -2535,3 +2537,5 @@ def execute(arguments)
end
execute(ARGV)
+
+exit (if ($?.to_i rescue 0) > 0 then 1 else 0 end)
diff --git a/scripts/context/ruby/xmltools.rb b/scripts/context/ruby/xmltools.rb
index 97b572e19..8974fff23 100644
--- a/scripts/context/ruby/xmltools.rb
+++ b/scripts/context/ruby/xmltools.rb
@@ -229,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
@@ -359,8 +359,16 @@ class Commands
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"
+ 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
@@ -375,7 +383,7 @@ class Commands
f.puts "</document>\n"
f.close
if process then
- system("texmfstart texexec --purgeall --pdf --use=xml-analyze #{result}")
+ system("texmfstart texexec --purge --pdf --use=xml-analyze #{result}")
end
else
report("unable to open file '#{result}'")
@@ -391,6 +399,105 @@ class Commands
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
+ rescue
+ 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 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)
@@ -399,6 +506,7 @@ commandline = CommandLine.new
commandline.registeraction('dir', 'generate directory listing')
commandline.registeraction('mmlpages','generate graphic from mathml')
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=]')
@@ -424,6 +532,7 @@ commandline.registerflag('utf')
commandline.registerflag('process')
commandline.registervalue('style')
commandline.registervalue('modes')
+commandline.registervalue('verbose')
commandline.expand