summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/context/perl/texexec.pl129
-rw-r--r--scripts/context/ruby/base/file.rb6
-rw-r--r--scripts/context/ruby/base/kpse.rb6
-rw-r--r--scripts/context/ruby/base/tex.rb513
-rw-r--r--scripts/context/ruby/base/texutil.rb790
-rw-r--r--scripts/context/ruby/base/variables.rb8
-rw-r--r--scripts/context/ruby/ctxtools.rb82
-rw-r--r--scripts/context/ruby/newtexexec.rb35
-rw-r--r--scripts/context/ruby/newtexutil.rb601
-rw-r--r--scripts/context/ruby/texmfstart.rb2
10 files changed, 1289 insertions, 883 deletions
diff --git a/scripts/context/perl/texexec.pl b/scripts/context/perl/texexec.pl
index 263388a4c..9a8f2bff0 100644
--- a/scripts/context/perl/texexec.pl
+++ b/scripts/context/perl/texexec.pl
@@ -155,6 +155,7 @@ my $ProducePdfT = 0;
my $ProducePdfM = 0;
my $ProducePdfX = 0;
my $ProducePdfXTX = 0;
+my $ProducePs = 0;
my $Input = "";
my $Result = '';
my $Suffix = '';
@@ -263,6 +264,7 @@ my $MakeMpy = '';
"pdx" => \$ProducePdfX,
"dpx" => \$ProducePdfX,
"xtx" => \$ProducePdfXTX,
+ "ps" => \$ProducePs,
"pdfarrange" => \$PdfArrange,
"pdfselect" => \$PdfSelect,
"pdfcombine" => \$PdfCombine,
@@ -380,6 +382,7 @@ if ( $DoMPTeX || $DoMPXTeX ) {
$ProducePdfX = 0;
$ProducePdfM = 0;
$ProducePdfXTX = 0;
+ $ProducePs = 0;
}
if ( $PdfArrange || $PdfSelect || $PdfCopy || $PdfTrim || $PdfCombine ) {
@@ -391,6 +394,7 @@ if ($ProducePdfT) { $OutputFormat = "pdftex" }
elsif ($ProducePdfM) { $OutputFormat = "dvipdfm" }
elsif ($ProducePdfX) { $OutputFormat = "dvipdfmx" }
elsif ($ProducePdfXTX) { $OutputFormat = "xetex" }
+elsif ($ProducePs) { $OutputFormat = "dvips" }
if ( $ProducePdfXTX ) {
$TeXProgram = 'xetex' ; # ignore the default pdfetex engine
@@ -884,6 +888,7 @@ $OutputFormats{pdftex} = "pdftex"; $OutputFormats{pdf} = "pdftex";
$OutputFormats{dvipdfm} = "dvipdfm"; $OutputFormats{dpm} = "dvipdfm";
$OutputFormats{dvipdfmx} = "dvipdfmx"; $OutputFormats{dpx} = "dvipdfmx";
$OutputFormats{xetex} = "xetex"; $OutputFormats{xtx} = "xetex";
+$OutputFormats{dvips} = "dvips"; $OutputFormats{ps} = "dvips";
# kind of obsolete now that yandy is gone
@@ -1405,6 +1410,7 @@ sub ScanTeXPreamble {
$ProducePdfM = ($OutputFormat eq "dvipdfm") ;
$ProducePdfX = ($OutputFormat eq "dvipdfmx") ;
$ProducePdfXTX = ($OutputFormat eq "xetex") ;
+ $ProducePs = ($OutputFormat eq "dvips") ;
}
sub ScanContent {
@@ -1480,14 +1486,17 @@ sub PrepRunTeX {
return $cmd;
}
+my $emergencyend = "" ;
+#~ my $emergencyend = "\\emergencyend" ;
+
sub RunTeX {
my ( $JobName, $JobSuffix ) = @_;
my $StartTime = time;
my $cmd = PrepRunTeX($JobName, $JobSuffix, '');
if ($EnterBatchMode) {
- $Problems = System("$cmd");
+ $Problems = System("$cmd $emergencyend");
} else {
- $Problems = System("$cmd");
+ $Problems = System("$cmd $emergencyend");
}
my $StopTime = time - $StartTime;
print "\n return code : $Problems";
@@ -1729,7 +1738,7 @@ sub RunConTeXtFile {
} elsif (/\<\?context\-directive\s+(.+?)\s+(.+?)\s+(.+?)\s*\?\>/o) {
my ($class, $key, $value) = ($1, $2, $3) ;
if ($class eq 'job') {
- if ($key eq 'stylefile') {
+ if (($key eq 'stylefile') || ($key eq 'environment')) {
print TMP "\\environment $value\n" ;
} elsif ($key eq 'module') {
print TMP "\\usemodule[$value]\n" ;
@@ -1838,7 +1847,7 @@ sub RunConTeXtFile {
$tubchecksumafter = CheckTubChanges($JobName) ;
if ($AutoMPRun) { $mpchecksumafter = CheckMPChanges($JobName) }
if ( ( !$Problems ) && ( $NOfRuns > 1 ) ) {
- if ( !$NoMPMode ) {
+ unless ( $NoMPMode ) {
$MPrundone = RunTeXMP( $JobName, "mpgraph" );
$MPrundone = RunTeXMP( $JobName, "mprun" );
}
@@ -1879,6 +1888,21 @@ sub RunConTeXtFile {
$ENV{'backend'} = $ENV{'progname'} = 'xetex' ;
$ENV{'TEXFONTMAPS'} = '.;$TEXMF/fonts/map/{xetex,pdftex,dvips,}//' ;
System("xdv2pdf $JobName.xdv") ;
+ } elsif ($ProducePs) {
+ $ENV{'backend'} = $ENV{'progname'} = 'dvips' ;
+ $ENV{'TEXFONTMAPS'} = '.;$TEXMF/fonts/map/{dvips,pdftex,}//' ;
+ # temp hack, some day there will be map file loading in specials
+ my $mapfiles = '' ;
+ if (-f "$JobName.tui") {
+ open(TUI,"$JobName.tui") ;
+ while (<TUI>) {
+ if (/c \\usedmapfile\{.\}\{(.*?)\}/o) {
+ $mapfiles .= "-u +$1 " ;
+ }
+ }
+ close(TUI) ;
+ }
+ System("dvips $mapfiles $JobName.dvi") ;
}
PopResult($JobName);
}
@@ -1938,6 +1962,50 @@ sub RunModule {
# the next one can be more efficient: directly process ted
# file a la --use=abr-01,mod-01
+sub checktexformatpath {
+ # engine support is either broken of not implemented in some
+ # distributions, so we need to take care of it ourselves
+ my $texformats ;
+ if (defined($ENV{'TEXFORMATS'})) {
+ $texformats = $ENV{'TEXFORMATS'} ;
+ } else {
+ $texformats = '' ;
+ }
+ if ($texformats eq '') {
+ if ($UseEnginePath) {
+ if ($dosish) {
+ $texformats = `kpsewhich --engine=$TeXExecutable --expand-var=\$TEXFORMATS` ;
+ } else {
+ $texformats = `kpsewhich --engine=$TeXExecutable --expand-var=\\\$TEXFORMATS` ;
+ }
+ } else {
+ if ($dosish) {
+ $texformats = `kpsewhich --expand-var=\$TEXFORMATS` ;
+ } else {
+ $texformats = `kpsewhich --expand-var=\\\$TEXFORMATS` ;
+ }
+ }
+ chomp($texformats) ;
+ }
+ if (($texformats !~ /web2c\/.*$TeXExecutable/) && ($texformats !~ /web2c[\/\\].*\$engine/i)) {
+ $texformats =~ s/(web2c\/\{)(\,\})/$1\$engine$2/ ; # needed for empty engine flags
+ if ($texformats !~ /web2c[\/\\].*\$ENGINE/) {
+ $texformats =~ s/web2c/web2c\/{\$engine,}/ ; # needed for me
+ }
+ $ENV{'TEXFORMATS'} = $texformats ;
+ print " fixing texformat path : $ENV{'TEXFORMATS'}\n";
+ } else {
+ print " using texformat path : $ENV{'TEXFORMATS'}\n" if ($Verbose) ;
+ }
+ if (! defined($ENV{'ENGINE'})) {
+ if ($MpEngineSupport) {
+ $ENV{'ENGINE'} .= $MpExecutable ;
+ } ;
+ $ENV{'ENGINE'} = $TeXExecutable ;
+ print "fixing engine variable : $ENV{'ENGINE'}\n";
+ }
+}
+
sub DoRunModule {
my ( $FileName, $FileSuffix ) = @_;
RunPerlScript( $TeXUtil, "--documents $FileName.$FileSuffix" );
@@ -1959,8 +2027,8 @@ sub DoRunModule {
print MOD "\\readlocfile{$FileName.ted}{}{}\n";
print MOD "\\stoptext\n";
close(MOD);
+ checktexformatpath ;
RunConTeXtFile( $ModuleFile, "tex" );
-
if ( $FileName ne $ModuleFile ) {
foreach my $FileSuffix ( "dvi", "pdf", "tui", "tuo", "log" ) {
unlink("$FileName.$FileSuffix");
@@ -1998,6 +2066,7 @@ sub RunFigures {
print FIG "\\stoptext\n";
close(FIG);
$ConTeXtInterface = "en";
+ checktexformatpath ;
RunConTeXtFile( $FiguresFile, "tex" );
unlink('texutil.tuf') if ( -f 'texutil.tuf' );
}
@@ -2038,6 +2107,7 @@ sub RunListing {
print LIS "\\stoptext\n";
close(LIS);
$ConTeXtInterface = "en";
+ checktexformatpath ;
RunConTeXtFile( $ListingFile, "tex" );
}
@@ -2083,6 +2153,7 @@ sub RunArrange {
print ARR "\\stoptext\n";
close(ARR);
$ConTeXtInterface = "en";
+ checktexformatpath ;
RunConTeXtFile( $ModuleFile, "tex" );
}
@@ -2131,6 +2202,7 @@ sub RunSelect {
print SEL "\\stoptext\n";
close(SEL);
$ConTeXtInterface = "en";
+ checktexformatpath ;
RunConTeXtFile( $SelectFile, "tex" );
}
@@ -2181,6 +2253,7 @@ sub RunCopy {
print COP "\\stoptext\n";
close(COP);
$ConTeXtInterface = "en";
+ checktexformatpath ;
RunConTeXtFile( $CopyFile, "tex" );
}
@@ -2231,6 +2304,7 @@ sub RunCombine {
print COM "\\stoptext\n";
close(COM);
$ConTeXtInterface = "en";
+ checktexformatpath ;
RunConTeXtFile( $CombineFile, "tex" );
}
@@ -2432,50 +2506,6 @@ sub RunMpFormat {
my $dir = File::Temp::tempdir(CLEANUP=>1) ;
my ($fh, $filename) = File::Temp::tempfile(DIR=>$dir, UNLINK=>1);
-sub checktexformatpath {
- # engine support is either broken of not implemented in some
- # distributions, so we need to take care of it ourselves
- my $texformats ;
- if (defined($ENV{'TEXFORMATS'})) {
- $texformats = $ENV{'TEXFORMATS'} ;
- } else {
- $texformats = '' ;
- }
- if ($texformats eq '') {
- if ($UseEnginePath) {
- if ($dosish) {
- $texformats = `kpsewhich --engine=$TeXExecutable --expand-var=\$TEXFORMATS` ;
- } else {
- $texformats = `kpsewhich --engine=$TeXExecutable --expand-var=\\\$TEXFORMATS` ;
- }
- } else {
- if ($dosish) {
- $texformats = `kpsewhich --expand-var=\$TEXFORMATS` ;
- } else {
- $texformats = `kpsewhich --expand-var=\\\$TEXFORMATS` ;
- }
- }
- chomp($texformats) ;
- }
- if (($texformats !~ /web2c\/.*$TeXExecutable/) && ($texformats !~ /web2c[\/\\].*\$engine/i)) {
- $texformats =~ s/(web2c\/\{)(\,\})/$1\$engine$2/ ; # needed for empty engine flags
- if ($texformats !~ /web2c[\/\\].*\$ENGINE/) {
- $texformats =~ s/web2c/web2c\/{\$engine,}/ ; # needed for me
- }
- $ENV{'TEXFORMATS'} = $texformats ;
- print " fixing texformat path : $ENV{'TEXFORMATS'}\n";
- } else {
- print " using texformat path : $ENV{'TEXFORMATS'}\n" if ($Verbose) ;
- }
- if (! defined($ENV{'ENGINE'})) {
- if ($MpEngineSupport) {
- $ENV{'ENGINE'} .= $MpExecutable ;
- } ;
- $ENV{'ENGINE'} = $TeXExecutable ;
- print "fixing engine variable : $ENV{'ENGINE'}\n";
- }
-}
-
sub RunFiles {
my $currentpath = cwd() ;
my $oldrunpath = $RunPath ;
@@ -2819,6 +2849,7 @@ sub RunMPX {
open( TMP, ">>$MpTex" );
print TMP "\\end\n"; # to be sure
close(TMP);
+ checktexformatpath ;
if ( ( $Format eq '' ) || ( $Format =~ /^cont.*/io ) ) {
RunConTeXtFile( $MpTmp, "tex" );
} else {
diff --git a/scripts/context/ruby/base/file.rb b/scripts/context/ruby/base/file.rb
index b7170d555..f6189043c 100644
--- a/scripts/context/ruby/base/file.rb
+++ b/scripts/context/ruby/base/file.rb
@@ -4,7 +4,11 @@ class File
def File.suffixed(name,sufa,sufb=nil)
if sufb then
- unsuffixed(name) + "-#{sufa}.#{sufb}"
+ if sufa.empty? then
+ unsuffixed(name) + ".#{sufb}"
+ else
+ unsuffixed(name) + "-#{sufa}.#{sufb}"
+ end
else
unsuffixed(name) + ".#{sufa}"
end
diff --git a/scripts/context/ruby/base/kpse.rb b/scripts/context/ruby/base/kpse.rb
index 7073ad017..a5e2ecac2 100644
--- a/scripts/context/ruby/base/kpse.rb
+++ b/scripts/context/ruby/base/kpse.rb
@@ -284,12 +284,14 @@ module Kpse
def Kpse.runscript(name,filename=[],options=[])
setscript(name,`texmfstart --locate #{name}`) unless @@scripts.key?(name)
- system("#{@@scripts[name]} #{[options].flatten.join(' ')} #{[filename].flatten.join(' ')}")
+ cmd = "#{@@scripts[name]} #{[options].flatten.join(' ')} #{[filename].flatten.join(' ')}"
+ system(cmd)
end
def Kpse.pipescript(name,filename=[],options=[])
setscript(name,`texmfstart --locate #{name}`) unless @@scripts.key?(name)
- `#{@@scripts[name]} #{[options].flatten.join(' ')} #{[filename].flatten.join(' ')}`
+ cmd = "#{@@scripts[name]} #{[options].flatten.join(' ')} #{[filename].flatten.join(' ')}"
+ `#{cmd}`
end
private
diff --git a/scripts/context/ruby/base/tex.rb b/scripts/context/ruby/base/tex.rb
index cea6662ae..2be0548d3 100644
--- a/scripts/context/ruby/base/tex.rb
+++ b/scripts/context/ruby/base/tex.rb
@@ -11,6 +11,8 @@
# todo: write systemcall for mpost to file so that it can be run
# faster
+# report ?
+
require 'base/variables'
require 'base/kpse'
require 'base/system'
@@ -18,6 +20,30 @@ require 'base/state'
require 'base/pdf'
require 'base/file'
+class String
+
+ def standard?
+ begin
+ self == 'standard'
+ rescue
+ false
+ end
+ end
+
+end
+
+class Array
+
+ def standard?
+ begin
+ self.include?('standard')
+ rescue
+ false
+ end
+ end
+
+end
+
class TEX
# The make-part of this class was made on a rainy day while listening
@@ -33,42 +59,65 @@ class TEX
@@texformats = Hash.new
@@mpsformats = Hash.new
@@prognames = Hash.new
+ @@texmakestr = Hash.new
+ @@texprocstr = Hash.new
+ @@mpsmakestr = Hash.new
+ @@mpsprocstr = Hash.new
- ['tex','pdftex','pdfetex','standard'] .each do |e| @@texengines[e] = 'pdfetex' end
- ['aleph','omega'] .each do |e| @@texengines[e] = 'aleph' end
- ['xetex'] .each do |e| @@texengines[e] = 'xetex' end
+ @@texmethods = Hash.new
+ @@mpsmethods = Hash.new
- ['metapost','mpost','standard'] .each do |e| @@mpsengines[e] = 'mpost' end
+ ['tex','pdftex','pdfetex','standard'] .each do |e| @@texengines[e] = 'pdfetex' end
+ ['aleph','omega'] .each do |e| @@texengines[e] = 'aleph' end
+ ['xetex'] .each do |e| @@texengines[e] = 'xetex' end
- ['pdfetex','pdftex','pdf','pdftex','standard'] .each do |b| @@backends[b] = 'pdftex' end
- ['dvipdfmx','dvipdfm','dpx','dpm'] .each do |b| @@backends[b] = 'dvipdfmx' end
- ['xetex','xtx'] .each do |b| @@backends[b] = 'xetex' end
- ['dvips','ps'] .each do |b| @@backends[b] = 'dvips' end
- ['dvipsone'] .each do |b| @@backends[b] = 'dvipsone' end
- ['acrobat','adobe','distiller'] .each do |b| @@backends[b] = 'acrobat' end
+ ['metapost','mpost','standard'] .each do |e| @@mpsengines[e] = 'mpost' end
+
+ ['pdfetex','pdftex','pdf','pdftex','standard'] .each do |b| @@backends[b] = 'pdftex' end
+ ['dvipdfmx','dvipdfm','dpx','dpm'] .each do |b| @@backends[b] = 'dvipdfmx' end
+ ['xetex','xtx'] .each do |b| @@backends[b] = 'xetex' end
+ ['dvips','ps'] .each do |b| @@backends[b] = 'dvips' end
+ ['dvipsone'] .each do |b| @@backends[b] = 'dvipsone' end
+ ['acrobat','adobe','distiller'] .each do |b| @@backends[b] = 'acrobat' end
# todo norwegian (no)
- ['plain'] .each do |f| @@texformats[f] = 'plain' end
- ['cont-en','en','english','context','standard'].each do |f| @@texformats[f] = 'cont-en' end
- ['cont-nl','nl','dutch'] .each do |f| @@texformats[f] = 'cont-nl' end
- ['cont-de','de','german'] .each do |f| @@texformats[f] = 'cont-de' end
- ['cont-it','it','italian'] .each do |f| @@texformats[f] = 'cont-it' end
- ['cont-cz','cz','czech'] .each do |f| @@texformats[f] = 'cont-cz' end
- ['cont-ro','ro','romanian'] .each do |f| @@texformats[f] = 'cont-ro' end
- ['cont-uk','uk','brittish'] .each do |f| @@texformats[f] = 'cont-uk' end
- ['mptopdf'] .each do |f| @@texformats[f] = 'mptopdf' end
+ ['plain'] .each do |f| @@texformats[f] = 'plain' end
+ ['cont-en','en','english','context','standard'].each do |f| @@texformats[f] = 'cont-en' end
+ ['cont-nl','nl','dutch'] .each do |f| @@texformats[f] = 'cont-nl' end
+ ['cont-de','de','german'] .each do |f| @@texformats[f] = 'cont-de' end
+ ['cont-it','it','italian'] .each do |f| @@texformats[f] = 'cont-it' end
+ ['cont-cz','cz','czech'] .each do |f| @@texformats[f] = 'cont-cz' end
+ ['cont-ro','ro','romanian'] .each do |f| @@texformats[f] = 'cont-ro' end
+ ['cont-uk','uk','brittish'] .each do |f| @@texformats[f] = 'cont-uk' end
+ ['mptopdf'] .each do |f| @@texformats[f] = 'mptopdf' end
+
+ ['latex'] .each do |f| @@texformats[f] = 'latex.ltx' end
- ['plain','mpost'] .each do |f| @@mpsformats[f] = 'plain' end
- ['metafun','context','standard'] .each do |f| @@mpsformats[f] = 'metafun' end
+ ['plain','mpost'] .each do |f| @@mpsformats[f] = 'plain' end
+ ['metafun','context','standard'] .each do |f| @@mpsformats[f] = 'metafun' end
- ['pdfetex','aleph','omega'] .each do |p| @@prognames[p] = 'context' end
- ['mpost'] .each do |p| @@prognames[p] = 'metafun' end
+ ['pdfetex','aleph','omega'] .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
+ ['cont-en','cont-nl','cont-de','cont-it',
+ 'cont-cz','cont-ro','cont-uk'] .each do |f| @@texmethods[f] = 'context' end
+ ['latex'] .each do |f| @@texmethods[f] = 'latex' end
+
+ ['plain','default','standard'] .each do |f| @@mpsmethods[f] = 'plain' end
+ ['metafun'] .each do |f| @@mpsmethods[f] = 'metafun' end
+
+ @@texmakestr['plain'] = "\\dump"
+ @@mpsmakestr['plain'] = "\\dump"
+
+ ['cont-en','cont-nl','cont-de','cont-it',
+ 'cont-cz','cont-ro','cont-uk'] .each do |f| @@texprocstr[f] = "\\emergencyend" end
@@runoptions['xetex'] = ['--no-pdf']
@@booleanvars = [
- 'batchmode', 'nonstopmode', 'fastmode', 'fastdisabled', 'silentmode', 'final',
+ 'batchmode', 'nonstopmode', 'fast', 'fastdisabled', 'silentmode', 'final',
'paranoid', 'notparanoid', 'nobanner', 'once', 'allpatterrns',
'nompmode', 'nomprun', 'automprun',
'nomapfiles', 'local',
@@ -77,7 +126,7 @@ class TEX
'mpyforce', 'forcempy',
'forcetexutil', 'texutil',
'globalfile', 'autopath',
- 'purge', 'pdfopen', 'simplerun',
+ 'purge', 'pdfopen', 'simplerun', 'verbose',
]
@@stringvars = [
'modefile', 'result', 'suffix', 'response', 'path',
@@ -120,7 +169,15 @@ class TEX
@@temptexfile = 'texexec.tex'
def initialize(logger)
- @logger = logger
+ if @logger = logger then
+ def report(str='')
+ @logger.report(str)
+ end
+ else
+ def report(str='')
+ puts(str)
+ end
+ end
@cleanups = Array.new
@variables = Hash.new
@startuptime = Time.now
@@ -139,12 +196,16 @@ class TEX
setvariable('mpsformats', defaultmpsformats)
setvariable('progname', 'context')
setvariable('interface', 'standard')
- setvariable('engine', 'standard')
+ setvariable('engine', 'standard') # replaced by tex/mpsengine
setvariable('backend', 'pdftex')
setvariable('runs', '8')
- setvariable('randomseed', rand(1440))
+ setvariable('randomseed', rand(1440).to_s)
# files
- setvariable('files', [])
+ setvariable('files', [])
+ # defaults
+ setvariable('texengine', 'standard')
+ setvariable('mpsengine', 'standard')
+ setvariable('backend', 'standard')
end
def runtime
@@ -193,33 +254,23 @@ class TEX
end
end
- def texengines
- @@texengines.keys.sort
- end
+ def backends() @@backends.keys.sort end
- def mpsengines
- @@mpsengines.keys.sort
- end
+ def texengines() @@texengines.keys.sort end
+ def mpsengines() @@mpsengines.keys.sort end
+ def texformats() @@texformats.keys.sort end
+ def mpsformats() @@mpsformats.keys.sort end
- def backends
- @@backends.keys.sort
- end
+ def defaulttexformats() ['en','nl','mptopdf'] end
+ def defaultmpsformats() ['metafun'] end
- def texformats
- @@texformats.keys.sort
- end
+ def texmakeextras(format) @@texmakestr[format] || '' end
+ def mpsmakeextras(format) @@mpsmakestr[format] || '' end
+ def texprocextras(format) @@texprocstr[format] || '' end
+ def mpsprocextras(format) @@mpsprocstr[format] || '' end
- def mpsformats
- @@mpsformats.keys.sort
- end
-
- def defaulttexformats
- ['en','nl','mptopdf']
- end
-
- def defaultmpsformats
- ['metafun']
- end
+ def texmethod(format) @@texmethods[str] || @@texmethods['standard'] end
+ def mpsmethod(format) @@mpsmethods[str] || @@mpsmethods['standard'] end
def runoptions(engine)
if @@runoptions.key?(engine) then @@runoptions[engine].join(' ') else '' end
@@ -265,18 +316,14 @@ class TEX
if str.class == String then str.split(',') else str.flatten end
end
- def validtexformat(str)
- validsomething(str,@@texformats)
- end
- def validmpsformat(str)
- validsomething(str,@@mpsformats)
- end
- def validtexengine(str)
- validsomething(str,@@texengines)
- end
- def validmpsengine(str)
- validsomething(str,@@mpsengines)
- end
+ def validtexformat(str) validsomething(str,@@texformats) end
+ def validmpsformat(str) validsomething(str,@@mpsformats) end
+ def validtexengine(str) validsomething(str,@@texengines) end
+ def validmpsengine(str) validsomething(str,@@mpsengines) end
+
+ def validtexmethod(str) [validsomething(str,@@texmethods)].flatten.first end
+ def validmpsmethod(str) [validsomething(str,@@mpsmethods)].flatten.first end
+
def validsomething(str,something)
if str then
list = [str].flatten.collect do |s|
@@ -320,11 +367,11 @@ class TEX
else return ""
end
if format then
- if engine then
- "#{prefix}=#{engine}/#{format}"
- else
+ # if engine then
+ # "#{prefix}=#{engine}/#{format}"
+ # else
"#{prefix}=#{format}"
- end
+ # end
else
prefix
end
@@ -362,12 +409,8 @@ class TEX
end
end
- def iniflag
- "--ini"
- end
- def tcxflag
- "--translate-file=natural.tcx"
- end
+ def iniflag() "--ini" end
+ def tcxflag() "--translate-file=natural.tcx" end
def filestate(file)
File.mtime(file).strftime("%d/%m/%Y %H:%M:%S")
@@ -388,6 +431,12 @@ class TEX
end
def makeformats
+ if getvariable('fast') then
+ report('using existing database')
+ else
+ report('updating file database')
+ Kpse.update
+ end
# goody
if getvariable('texformats') == 'standard' then
setvariable('texformats',[getvariable('interface')]) unless getvariable('interface').empty?
@@ -413,14 +462,11 @@ class TEX
makeuserfile
makeresponsefile
end
- texformats.each do |format|
- if texformat = validtexformat(format) then
- report("generating tex format #{texformat}")
- # report("some texmf environment variables are fixed") if Kpse.fixtexmfvars(texengine)
- command = [quoted(texengine),prognameflag(progname),iniflag,tcxflag,prefixed(texformat,texengine)].join(' ')
- report(command) if getvariable('verbose')
- system(command)
- end
+ texformats.each do |texformat|
+ report("generating tex format #{texformat}")
+ command = [quoted(texengine),prognameflag(progname),iniflag,tcxflag,prefixed(texformat,texengine),texmakeextras(texformat)].join(' ')
+ report(command) if getvariable('verbose')
+ system(command)
end
else
texformatpath = ''
@@ -434,14 +480,11 @@ class TEX
Dir.chdir(mpsformatpath)
rescue
end
- mpsformats.each do |format|
- if mpsformat = validmpsformat(format) then
- report("generating mps format #{mpsformat}")
- # report("some texmf environment variables are fixed") if Kpse.fixtexmfvars(mpsengine)
- command = [quoted(mpsengine),prognameflag(progname),iniflag,tcxflag,mpsformat].join(' ')
- report(command) if getvariable('verbose')
- system(command)
- end
+ mpsformats.each do |mpsformat|
+ report("generating mps format #{mpsformat}")
+ command = [quoted(mpsengine),prognameflag(progname),iniflag,tcxflag,mpsformat,mpsmakeextras(mpsformat)].join(' ')
+ report(command) if getvariable('verbose')
+ system(command)
end
else
mpsformatpath = ''
@@ -482,11 +525,12 @@ class TEX
globpattern = "**/{#{formatpaths.join(',')}}/*/*.{fmt,efmt,ofmt,xfmt,mem}"
report("format path: #{formatpaths.join(' ')}")
# utilities
- report
+ report('start of analysis')
+ results = Array.new
['texexec','texutil','ctxtools'].each do |program|
result = `texmfstart #{program} --help`
result.sub!(/.*?(#{program}[^\n]+)\n.*/mi) do $1 end
- report("#{result}")
+ results.push("#{result}")
end
# formats
cleanuptemprunfiles
@@ -511,24 +555,23 @@ class TEX
case format
when /cont\-([a-z]+)/ then
interface = $1.sub(/cont\-/,'')
- report
- report("testing interface #{interface}")
+ results.push('')
+ results.push("testing interface #{interface}")
flags = ['--process','--batch','--once',"--interface=#{interface}",engineflag]
-# to be adapted !
-result = Kpse.pipescript('newtexexec',tempfilename,flags)
-# to just texexec
+ # result = Kpse.pipescript('newtexexec',tempfilename,flags)
+ result = runtexexec([tempfilename], flags, 1)
if FileTest.file?("#{@@temprunfile}.log") then
logdata = IO.read("#{@@temprunfile}.log")
if logdata =~ /^\s*This is (.*?)[\s\,]+(.*?)$/mois then
if validtexengine($1.downcase) then
- report("#{$1} #{$2.gsub(/\(format.*$/,'')}".strip)
+ results.push("#{$1} #{$2.gsub(/\(format.*$/,'')}".strip)
end
end
if logdata =~ /^\s*(ConTeXt)\s+(.*int:\s+[a-z]+.*?)\s*$/mois then
- report("#{$1} #{$2}".gsub(/\s+/,' ').strip)
+ results.push("#{$1} #{$2}".gsub(/\s+/,' ').strip)
end
else
- report("format #{format} does not work")
+ results.push("format #{format} does not work")
end
when /metafun/ then
# todo
@@ -536,12 +579,17 @@ result = Kpse.pipescript('newtexexec',tempfilename,flags)
# todo
end
else
- report("error in creating #{tempfilename('tex')}")
+ results.push("error in creating #{tempfilename('tex')}")
end
end
cleanuptemprunfiles
end
end
+ report('end of analysis')
+ report
+ results.each do |line|
+ report(line)
+ end
cleanuptemprunfiles
end
@@ -628,8 +676,8 @@ result = Kpse.pipescript('newtexexec',tempfilename,flags)
def scantexcontent(filename)
if tex = File.open(filename) then
- while str = tex.gets.chomp do
- case str
+ while str = tex.gets do
+ case str.chomp
when /^\%/o then
# next
when /\\(starttekst|stoptekst|startonderdeel|startdocument|startoverzicht)/o then
@@ -709,13 +757,16 @@ result = Kpse.pipescript('newtexexec',tempfilename,flags)
break
elsif line =~ /<\?context\-directive\s+(.+?)\s+(.+?)\s+(.+?)\s*\?>/o then
category, key, value = $1, $2, $3
- if category == 'job' then
- if key == 'stylefile' then
- tmp << "\\environment $value\n"
- elsif key == 'module' then
- tmp << "\\usemodule[$value]\n"
- elsif key == 'interface' then
- contextinterface = value
+ case category
+ when 'job' then
+ case key
+ when 'stylefile', 'environment' then
+ tmp << "\\environment $value\n"
+ when 'module' then
+ tmp << "\\usemodule[$value]\n"
+ when 'interface' then
+ contextinterface = value
+ end
end
end
end
@@ -742,7 +793,7 @@ class TEX
getarrayvariable('files').each do |filename|
setvariable('filename',filename)
report("processing document '#{filename}'")
- processcontextfile
+ processfile
end
reportruntime
end
@@ -804,7 +855,7 @@ class TEX
if getvariable('nompmode') || getvariable('nomprun') || getvariable('automprun') then
opt << "\\runMPgraphicsfalse\n"
end
- if getvariable('fastmode') && ! getvariable('fastdisabled') then
+ if getvariable('fast') && ! getvariable('fastdisabled') then
opt << "\\fastmode\n"
end
if getvariable('silent') then
@@ -942,7 +993,7 @@ class TEX
report("tex format: #{texformat}")
report("progname: #{progname}")
if texengine && texformat && progname then
- command = [quoted(texengine),prognameflag(progname),formatflag(texengine,texformat),runoptions(texengine),filename].join(' ')
+ command = [quoted(texengine),prognameflag(progname),formatflag(texengine,texformat),runoptions(texengine),filename,texprocextras(texformat)].join(' ')
report(command) if getvariable('verbose')
system(command)
else
@@ -955,7 +1006,7 @@ class TEX
mpsformat = validmpsformat(getarrayvariable('mpsformats').first)
progname = validprogname(getvariable('progname'))
if mpsengine && mpsformat && progname then
- command = [quoted(mpsengine),prognameflag(progname),formatflag(mpsengine,mpsformat),runoptions(mpsengine),filename].join(' ')
+ command = [quoted(mpsengine),prognameflag(progname),formatflag(mpsengine,mpsformat),runoptions(mpsengine),filename,mpsprocextras(mpsformat)].join(' ')
report(command) if getvariable('verbose')
system(command)
else
@@ -982,8 +1033,8 @@ class TEX
mpfile = File.suffixed(filename,filetype,'mp')
if File.atleast?(mpfile,25) && (data = File.silentread(mpfile)) then
textranslation = if data =~ /^\%\s+translate.*?\=([\w\d\-]+)/io then $1 else '' end
- mpjobname = if data =~ /collected graphics of job \"(.+)\"/io then $1 else '' end
- if File.unsuffixed(filename) =~ /#{mpjobname}/ then # don't optimize
+ mpjobname = if data =~ /collected graphics of job \"(.+?)\"/io then $1 else '' end
+ if ! mpjobname.empty? and File.unsuffixed(filename) =~ /#{mpjobname}/ then # don't optimize
options = Array.new
options.push("--mptex")
options.push("--nomp")
@@ -991,18 +1042,52 @@ class TEX
options.push("--translate=#{textranslation}") unless textranslation.empty?
options.push("--batch") if getvariable('batchmode')
options.push("--nonstop") if getvariable('nonstopmode')
- return runtexexec(mpfile,options)
+ options.push("--output=ps")
+ return runtexexec(mpfile,options,2)
end
end
return false
end
def runtexutil(filename=[], options=['--ref','--ij','--high'])
- Kpse.runscript('texutil',filename,options)
+ begin
+ filename.each do |fname|
+ logger = Logger.new('TeXUtil')
+ if tu = TeXUtil::Converter.new(logger) and tu.loaded(fname) then
+ tu.saved if tu.processed
+ end
+ end
+ rescue
+ Kpse.runscript('texutil',filename,options)
+ end
end
- def runtexexec(filename=[], options=[])
- Kpse.runscript('texexec',filename,options)
+ # 1=tex 2=mptex 3=mpxtex
+
+ def runtexexec(filename=[], options=[], mode=nil)
+ begin
+ if mode and job = TEX.new(@logger) then
+ options.each do |option|
+ if option=~ /^\-*(.*?)\=(.*)$/o then
+ job.setvariable($1,$2)
+ else
+ job.setvariable(option,true)
+ end
+ end
+ job.setvariable("files",filename)
+ case mode
+ when 1 then job.processtex
+ when 2 then job.processmptex
+ when 3 then job.processmpxtex
+ end
+ job.inspect && Kpse.inspect if getvariable('verbose')
+ return true
+ else
+ Kpse.runscript('texexec',filename,options)
+ end
+ rescue
+ Kpse.runscript('texexec',filename,options)
+ end
end
def fixbackendvars(backend)
@@ -1011,15 +1096,44 @@ class TEX
ENV['TEXFONTMAPS'] = ".;\$TEXMF/fonts/map/{#{backend},pdftex,dvips,}//"
end
- def processcontextfile
+ def runbackend(jobname)
+ case validbackend(getvariable('backend'))
+ when 'dvipdfmx' then
+ fixbackendvars('dvipdfm')
+ system("dvipdfmx -d 4 #{File.unsuffixed(jobname)}")
+ when 'xetex' then
+ fixbackendvars('xetex')
+ system("xdv2pdf #{File.suffixed(jobname,'xdv')}")
+ when 'dvips' then
+ fixbackendvars('dvips')
+ mapfiles = ''
+ begin
+ if tuifile = File.suffixed(jobname,'tui') and FileTest.file?(tuifile) then
+ IO.read(tuifile).scan(/^c \\usedmapfile\{.\}\{(.*?)\}\s*$/o) do
+ mapfiles += "-u +#{$1} " ;
+ end
+ end
+ rescue
+ mapfiles = ''
+ end
+ system("dvips #{mapfiles} #{File.unsuffixed(jobname)}")
+ when 'pdftex' then
+ # no need for postprocessing
+ else
+ report("no postprocessing needed")
+ end
+ end
+
+ def processfile
takeprecautions
jobname = getvariable('filename')
- suffix = getvariable('suffix')
- result = getvariable('result')
+ suffix = getvariable('suffix')
+ result = getvariable('result')
- final = getvariable('final')
+ runonce = getvariable('once')
+ finalrun = getvariable('final') || (getvariable('arrange') && ! getvariable('noarrange'))
if getvariable('autopath') then
jobname = File.basename(jobname)
@@ -1036,9 +1150,12 @@ class TEX
orisuffix = jobsuffix # still needed ?
+ setvariable('nomprun',true) if orisuffix == 'mpx' # else cylic run
+
PDFview.closeall if getvariable('pdfopen')
forcexml = jobsuffix === /(xml|fo|fox|rlg|exa|)/io # === returns true|false, =~ returns position
+
dummyfile = false
# fuzzy code snippet: (we kunnen kpse: prefix gebruiken)
@@ -1055,81 +1172,89 @@ class TEX
unless dummyfile # we don't need this for xml
scantexpreamble(File.suffixed(jobname,jobsuffix))
- scantexcontent(File.suffixed(jobname,jobsuffix)) if getvariable('texformat').standard?
+ scantexcontent(File.suffixed(jobname,jobsuffix)) if getvariable('texformats').standard?
end
result = File.suffixed(jobname,suffix) unless suffix.empty?
pushresult(jobname,result)
- if getvariable('simplerun') then
- makeoptionfile(jobname,orisuffix,true,true,3)
- problems = runtex(File.suffixed(jobname,jobsuffix))
- if problems then
- ok = runtexutil(jobname) if getvariable('texutil') || getvariable('forcetexutil')
- popresult(jobname,result)
- end
- File.silentrename(File.suffixed(jobname,'top'),File.suffixed(jobname,'tmp'))
- else
- mprundone, ok, stoprunning = false, true, false
- texruns, nofruns = 0, getvariable('runs').to_i
- state = FileState.new
- ['tub','tuo'].each do |s|
- state.register(File.suffixed(jobname,s))
- end
- ['mprun','mpgraph'].each do |s|
- state.register(File.suffixed(jobname,s,'mp'),'randomseed')
- # state.register(File.suffixed(jobname,s,'mpo'))
- end
- while ! stoprunning && (texruns < nofruns) && ok do
- texruns += 1
- report("TeX run #{texruns}")
- if texruns == 1 then
- makeoptionfile(jobname,orisuffix,false,false,1)
+ method = validtexmethod(validtexformat(getvariable('texformats')))
+
+ report("tex processing method: #{method}")
+
+ case method
+
+ when 'context' then
+
+ if getvariable('simplerun') || runonce then
+ makeoptionfile(jobname,orisuffix,true,true,3)
+ problems = runtex(File.suffixed(jobname,jobsuffix))
+ unless problems then
+ ok = runtexutil(jobname) if getvariable('texutil') || getvariable('forcetexutil')
+ runbackend(jobname)
+ popresult(jobname,result)
+ end
+ File.silentrename(File.suffixed(jobname,'top'),File.suffixed(jobname,'tmp'))
else
- makeoptionfile(jobname,orisuffix,false,false,2)
- end
- ok = runtex(File.suffixed(jobname,jobsuffix))
- if ok && (nofruns > 1) then
- unless getvariable('nomprun') then
- mprundone = runtexmpjob(jobname, "mpgraph")
- mprundone = runtexmpjob(jobname, "mprun")
+ mprundone, ok, stoprunning = false, true, false
+ texruns, nofruns = 0, getvariable('runs').to_i
+ state = FileState.new
+ ['tub','tuo'].each do |s|
+ state.register(File.suffixed(jobname,s))
+ end
+ if getvariable('automprun') then # check this
+ ['mprun','mpgraph'].each do |s|
+ state.register(File.suffixed(jobname,s,'mp'),'randomseed')
+ # state.register(File.suffixed(jobname,s,'mpo'))
+ end
+ end
+ while ! stoprunning && (texruns < nofruns) && ok do
+ texruns += 1
+ report("TeX run #{texruns}")
+ if texruns == 1 then
+ makeoptionfile(jobname,orisuffix,false,false,1)
+ else
+ makeoptionfile(jobname,orisuffix,false,false,2)
+ end
+ ok = runtex(File.suffixed(jobname,jobsuffix))
+ if ok && (nofruns > 1) then
+ unless getvariable('nompmode') then
+ mprundone = runtexmpjob(jobname, "mpgraph")
+ mprundone = runtexmpjob(jobname, "mprun")
+ end
+ ok = runtexutil(jobname)
+ state.update
+ stoprunning = state.stable?
+ end
+ end
+ ok = runtexutil(jobname) if (nofruns == 1) && getvariable('texutil')
+ if ! problems && finalrun && (nofruns > 1) then
+ makeoptionfile(jobname,orisuffix,true,finalrun,4)
+ report("final TeX run #{texruns}")
+ problems = runtex(File.suffixed(jobname,jobsuffix))
+ end
+ File.silentcopy(File.suffixed(jobname,'top'),File.suffixed(jobname,'tmp'))
+ ['tup','top'].each do |s| # previous tuo file / runtime option file
+ File.silentdelete(File.suffixed(jobname,s))
+ end
+ unless problems then
+ runbackend(jobname)
+ popresult(jobname,result)
end
- ok = runtexutil(jobname)
- state.update
- stoprunning = state.stable?
end
- end
- ok = runtexutil(jobname) if (nofruns == 1) && getvariable('texutil')
- finalrun = getvariable('arrange') && ! getvariable('noarrange')
- if ! problems && finalrun && (nofruns > 1) then
- makeoptionfile(jobname,orisuffix,true,finalrun,4)
- report("final TeX run #{texruns}")
+
+ Kpse.runscript('ctxtools',jobname,'--purge') if getvariable('purge')
+
+ when 'latex' then
+
problems = runtex(File.suffixed(jobname,jobsuffix))
- end
- File.silentcopy(File.suffixed(jobname,'top'),File.suffixed(jobname,'tmp'))
- ['tup','top'].each do |s| # previous tuo file / runtime option file
- File.silentdelete(File.suffixed(jobname,s))
- end
- case validbackend(getvariable('backend'))
- when 'dvipdfmx' then
- fixbackendvars('dvipdfm')
- system("dvipdfmx -d 4 #{File.unsuffixed(jobname)}")
- when 'xetex' then
- fixbackendvars('xetex')
- system("xdv2pdf #{File.suffixed(jobname,'xdv')}")
- when 'dvips' then
- fixbackendvars('dvips')
- system("dvips #{File.unsuffixed(jobname)}")
- when 'pdftex' then
- # no need for postprocessing
- else
- report("no postprocessing needed")
- end
- popresult(jobname,result)
- end
- Kpse.runscript('ctxtools',jobname,'--purge') if getvariable('purge')
+ else
+
+ problems = runtex(File.suffixed(jobname,jobsuffix))
+
+ end
begin
File.delete(File.suffixed(jobname,jobsuffix)) if dummyfile || forcexml
@@ -1290,15 +1415,3 @@ class TEX
end
end
-
-class String
-
- def standard?
- begin
- self == 'standard'
- rescue
- false
- end
- end
-
-end
diff --git a/scripts/context/ruby/base/texutil.rb b/scripts/context/ruby/base/texutil.rb
new file mode 100644
index 000000000..2e5fbaaad
--- /dev/null
+++ b/scripts/context/ruby/base/texutil.rb
@@ -0,0 +1,790 @@
+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 = Hash.new, Hash.new, Hash.new
+ @max = max
+ @rexa, @rexb = nil, nil
+ end
+
+ def replacer(from,to='') # and expand
+ @rep[from.escaped] = to || ''
+ end
+
+ # sorter.reducer('ch', 'c')
+ # sorter.reducer('ij', 'y')
+
+ def reducer(from,to='')
+ @map[from] = to || ''
+ end
+
+ # sorter.expander('aeligature', 'ae')
+ # sorter.expander('ijligature', 'y')
+
+ def expander(from,to=nil)
+ @exp[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
+ @rexa = /(#{@rep.keys.join('|')})/o
+ 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)
+ str.gsub(@rexa) do
+ @rep[$1.escaped]
+ end.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
+
+ def preset(shortcuts=[],expansions=[],reductions=[])
+ 'a'.upto('z') do |c|
+ expander(c)
+ end
+ 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
+ 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
+
+ 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]})\n"
+ end
+ end
+
+ def MyExtras::processor(logger)
+ @@programs.each do |p|
+ cmd = "texmfstart #{@@programs[p]}"
+ logger.report("running #{cmd}")
+ system(cmd)
+ end
+ end
+
+ end
+
+ end
+
+ class Plugin
+
+ module MySynonyms
+
+ class Synonym
+
+ @@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)
+ 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 = 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)
+ #
+ # 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[0,1]}] [#{entry.sortkey.gsub(/#{@@split}/o,'] [')}]\n"
+ end
+ end
+ list.each do |entry|
+ testalpha = entry.sortkey[0,1].downcase
+ if testalpha != alpha.downcase or alphaclass != entry.class then
+ alpha = testalpha
+ alphaclass = entry.class
+ if alpha != ' ' then
+ flushsavedline(handle)
+ character = alpha.sub(/([^a-zA-Z])/o) do "\\" + $1 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"
+ elsif @@collapse then
+ if savedentry != nextentry then
+ savedFrom = savedline
+ else
+ savedTo, savedentry = savedline, nextentry
+ end
+ else
+ handle << "\\registerpage#{savedline}\n"
+ end
+ @nofpages += 1
+ lastpage, lastrealpage = entry.page, entry.realpage
+ end
+ end
+ Register.flushsavedline(handle)
+ end
+ end
+
+ end
+
+ @@registers = Hash.new
+
+ def MyRegisters::reset(logger)
+ @@registers = Hash.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)
+ # report("register #{@@registers[s].class}: #{@@registers[s].@nofentries} entries and #{@@registers[s].@nofpages} pages")
+ end
+ end
+ end
+
+ def MyRegisters::processor(logger)
+ sorter = Sorter.new
+ sorter.preset(eval("MyKeys").shortcuts,eval("MyKeys").expansions,eval("MyKeys").reductions)
+ 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
+
+ def MyKeys::shortcuts
+ @@shortcuts
+ end
+ def MyKeys::expansions
+ @@expansions
+ end
+ def MyKeys::reductions
+ @@reductions
+ 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)
+ 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)
+ 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}")
+ File.open(File.suffixed(filename,'tui')).each do |line|
+ case line.chomp
+ when /^f (.*)$/o then @plugins.reader('MyFiles', $1.splitdata)
+ when /^c (.*)$/o then @plugins.reader('MyCommands', $1.splitdata)
+ 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
+ rescue
+ report("fatal error in parsing file (#{$!})")
+ @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
diff --git a/scripts/context/ruby/base/variables.rb b/scripts/context/ruby/base/variables.rb
index 0c495d22d..5cbc5ba53 100644
--- a/scripts/context/ruby/base/variables.rb
+++ b/scripts/context/ruby/base/variables.rb
@@ -26,6 +26,14 @@ module Variables
if @variables.key?(key) then @variables[key] else default end
end
+ def checkedvariable(str,default='')
+ if @variables.key?(key) then
+ if @variables[key].empty? then default else @variables[key] end
+ else
+ default
+ end
+ end
+
def report(*str)
@logger.report(*str)
end
diff --git a/scripts/context/ruby/ctxtools.rb b/scripts/context/ruby/ctxtools.rb
index c90299b0a..c89b1a30b 100644
--- a/scripts/context/ruby/ctxtools.rb
+++ b/scripts/context/ruby/ctxtools.rb
@@ -31,6 +31,7 @@ require 'base/system'
require 'rexml/document'
require 'ftools'
+require 'kconv'
exit if defined?(REQUIRE2LIB)
@@ -746,12 +747,15 @@ class Language
@language = language
@filenames = filenames
@remapping = Array.new
+ @unicode = Hash.new
@encoding = encoding
@data = ''
@read = ''
preload_accents()
+ preload_unicode() if @commandline.option('utf8')
case @encoding.downcase
when 't1', 'ec', 'cork' then preload_vector('ec')
+ when 'y', 'texnansi' then preload_vector('texnansi')
end
end
@@ -773,15 +777,13 @@ class Language
@filenames.each do |fileset|
[fileset].flatten.each do |filename|
begin
- if filename = located(filename) then
- data = IO.read(filename)
+ if fname = located(filename) then
+ data = IO.read(fname)
@data += data.gsub(/\%.*$/, '')
data.gsub!(/(\\patterns|\\hyphenation)\s*\{.*/mo) do '' end
- @read += "\n% preamble of file #{filename}\n\n#{data}\n"
- report("file #{filename} is loaded")
+ @read += "\n% preamble of file #{fname}\n\n#{data}\n"
+ report("file #{fname} is loaded")
break # next fileset
- else
- report("file #{filename} is not found")
end
rescue
report("file #{filename} is not readable")
@@ -808,9 +810,17 @@ class Language
end
end
report("#{n} changes in patterns and exceptions")
- return n
+ if @commandline.option('utf8') then
+ n = 0
+ @data.gsub!(/\[(.*?)\]/o) do
+ n += 1
+ @unicode[$1] || $1
+ end
+ report("#{n} unicode utf8 entries")
+ end
+ return true
else
- return 0
+ return false
end
end
@@ -850,6 +860,22 @@ class Language
end
end
+ def triggerunicode
+ if @commandline.option('utf8') then
+ "% xetex needs utf8 encoded patterns and for patterns\n" +
+ "% coded as such we need to enable this regime when\n" +
+ "% not in xetex; this code will be moved into context\n" +
+ "% as soon as we've spread the generic patterns\n" +
+ "\n" +
+ "\\ifx\\XeTeXversion\\undefined \\else\n" +
+ " \\ifx\\enableregime\\undefined \\else\n" +
+ " \\enableregime[utf]\n" +
+ " \\fi\n" +
+ "\\fi\n" +
+ "\n"
+ end
+ end
+
def save
xml = @commandline.option("xml")
@@ -938,11 +964,13 @@ class Language
data += $1 + "\n"
end
data.gsub!(/(\s*\n\s*)+/mo, "\n")
+
f << banner
f << comment("context pattern file, see #{commentfile} for original comment")
f << comment("source of data: #{@filenames.join(' ')}")
f << description
f << comment("begin pattern data")
+ f << triggerunicode
f << content('patterns', data)
f << comment("end pattern data")
f.close
@@ -964,11 +992,12 @@ class Language
data.gsub!(/(\s*\n\s*)+/mo, "\n")
f << banner
f << comment("context hyphenation file, see #{commentfile} for original comment")
- f.<< comment("source of data: #{@filenames.join(' ')}")
+ f << comment("source of data: #{@filenames.join(' ')}")
f << description
- f.<< comment("begin hyphenation data")
+ f << comment("begin hyphenation data")
+ f << triggerunicode
f << content('hyphenation', data)
- f.<< comment("end hyphenation data")
+ f << comment("end hyphenation data")
f.close
report("exceptions saved in file #{hypname}")
else
@@ -1005,10 +1034,10 @@ class Language
def located(filename)
begin
- filename = `kpsewhich -progname=context #{filename}`.chomp
- if FileTest.file?(filename) then
- report("using file #{filename}")
- return filename
+ fname = `kpsewhich -progname=context #{filename}`.chomp
+ if FileTest.file?(fname) then
+ report("using file #{fname}")
+ return fname
else
report("file #{filename} is not present")
return nil
@@ -1041,6 +1070,26 @@ class Language
end
+ def preload_unicode
+
+ # \definecharacter Agrave {\uchar0{192}}
+
+ begin
+ if filename = located("enco-uc.tex") then
+ if data = IO.read(filename) then
+ report("preloading unicode conversions")
+ data.scan(/\\definecharacter\s*(.+?)\s*\{\\uchar\{*(\d+)\}*\s*\{(\d+)\}/o) do
+ one, two, three = $1, $2.to_i, $3.to_i
+ @unicode[one] = [(two*256 + three)].pack("U")
+ end
+ end
+ end
+ rescue
+ report("error in loading unicode mapping (#{$!})")
+ end
+
+ end
+
def preload_vector(encoding='')
# funny polish
@@ -1279,7 +1328,7 @@ commandline.registeraction('documentation', 'generate documentation [--type=] [f
commandline.registeraction('filterpages') # no help, hidden temporary feature
commandline.registeraction('purgeallfiles') # no help, compatibility feature
-commandline.registeraction('patternfiles', 'generate pattern files [--all] [languagecode]')
+commandline.registeraction('patternfiles', 'generate pattern files [--all --xml --utf8] [languagecode]')
commandline.registeraction('dpxmapfiles', 'convert pdftex mapfiles to dvipdfmx [--force] [texmfroot]')
@@ -1291,6 +1340,7 @@ commandline.registerflag('pipe')
commandline.registerflag('all')
commandline.registerflag('xml')
commandline.registerflag('log')
+commandline.registerflag('utf8')
# general
diff --git a/scripts/context/ruby/newtexexec.rb b/scripts/context/ruby/newtexexec.rb
index 758a42d89..0d9602312 100644
--- a/scripts/context/ruby/newtexexec.rb
+++ b/scripts/context/ruby/newtexexec.rb
@@ -1,4 +1,4 @@
-banner = ['TeXExec', 'version 6.0.1', '1997-2005', 'PRAGMA ADE/POD']
+banner = ['TeXExec', 'version 6.1.0', '1997-2005', 'PRAGMA ADE/POD']
unless defined? ownpath
ownpath = $0.sub(/[\\\/][a-z0-9\-]*?\.rb/i,'')
@@ -11,6 +11,7 @@ require 'base/variables'
require 'base/system'
require 'base/tex'
+require 'base/texutil'
require 'ftools' # needed ?
@@ -25,13 +26,6 @@ class Commands
def make
if job = TEX.new(logger) then
- # prepare, move to TEX ?
- if @commandline.option('fast') then
- report('using existing database')
- else
- report('updating file database')
- Kpse.update
- end
prepare(job)
# bonus, overloads language switch !
job.setvariable('language','all') if @commandline.option('all')
@@ -56,6 +50,14 @@ class Commands
end
end
+ def main
+ if @commandline.arguments.length>0 then
+ process
+ else
+ help
+ end
+ end
+
def process
if job = TEX.new(logger) then
job.setvariable('files',@commandline.arguments)
@@ -65,14 +67,6 @@ class Commands
end
end
- def main
- if @commandline.arguments.length>0 then
- process
- else
- help
- end
- end
-
def mptex
if job = TEX.new(logger) then
job.setvariable('files',@commandline.arguments)
@@ -181,11 +175,11 @@ class Commands
end
def modules
- msuffixes = ['tex','mp','pl','pm','rb']
if job = TEX.new(logger) then
prepare(job)
job.cleanuptemprunfiles
files = @commandline.arguments.sort
+ msuffixes = ['tex','mp','pl','pm','rb']
if files.length > 0 then
files.each do |fname|
fnames = Array.new
@@ -491,6 +485,8 @@ class Commands
job.setvariable('backend','xetex')
elsif @commandline.oneof('aleph') then
job.setvariable('backend','dvipdfmx')
+ elsif @commandline.oneof('dvips','ps') then
+ job.setvariable('backend','dvips')
else
job.setvariable('backend','standard')
end
@@ -512,8 +508,6 @@ end
logger = Logger.new(banner.shift)
commandline = CommandLine.new
-# actions
-
commandline.registeraction('make', 'make formats')
commandline.registeraction('check', 'check versions')
commandline.registeraction('process', 'process file')
@@ -572,6 +566,9 @@ commandline.registerflag('dvipdfm')
commandline.registerflag('dpx')
commandline.registerflag('dpm')
+commandline.registerflag('dvips')
+commandline.registerflag('ps')
+
commandline.registerflag('xetex')
commandline.registerflag('xtx')
diff --git a/scripts/context/ruby/newtexutil.rb b/scripts/context/ruby/newtexutil.rb
index 001bdde68..b8cc99ccf 100644
--- a/scripts/context/ruby/newtexutil.rb
+++ b/scripts/context/ruby/newtexutil.rb
@@ -1,557 +1,14 @@
-#D Plugins
-#D
-#D test.pm:
-#D
-#D \starttypen
-#D see plugtest.pm
-#D \stoptypen
-#D
-#D utility format:
-#D
-#D \starttypen
-#D p u {name} {data} {data} ...
-#D \stoptypen
+require 'base/logger'
+require 'base/texutil'
-# my $pm_path ;
+logger = Logger.new('TeXUtil')
-# BEGIN
- # { $pm_path = "$FindBin::Bin/" ;
- # if ($pm_path eq "") { $pm_path = "./" } }
+filename = ARGV[0] || 'tuitest'
-# use lib $pm_path ;
-
-# my %UserPlugIns ;
-
-# sub HandlePlugIn
- # { if ($RestOfLine =~ /\s*u\s*\{(.*?)\}\s*(.*)\s*/io)
- # { my $tag = $1 ;
- # my $arg = $2 ;
- # if (! defined($UserPlugIns{$tag}))
- # { $UserPlugIns{$tag} = 1 ;
- # eval("use $tag") ;
- # my $result = $tag->identify ;
- # if ($result ne "")
- # { Report ("PlugInInit", "$tag -> $result") }
- # else
- # { Report ("PlugInInit", $tag ) }
- # $tag->initialize() }
- # if (defined($UserPlugIns{$tag}))
- # { $arg =~ s/\{(.*)\}/$1/o ;
- # my @args = split(/\}\s*\{/o, $arg) ;
- # $tag->handle(@args) } } }
-
-# sub FlushPlugIns
- # { foreach my $tag (keys %UserPlugIns)
- # { my @report = $tag->report ;
- # foreach $rep (@report)
- # { my ($key,$val) = split (/\s*\:\s*/,$rep) ;
- # if ($val ne "")
- # { Report ("PlugInReport", "$tag -> $key -> $val") }
- # else
- # { Report ("PlugInReport", "$tag -> $key") } }
- # $tag->process ;
- # print TUO "%\n" . "% $Program / " . $tag->identify . "\n" . "%\n" ;
- # foreach my $str ($tag->results)
- # { print TUO "\\plugincommand\{$str\}\n" } } }
-
-require "base/file"
-
-def report(str)
- puts(str)
+if tu = TeXUtil::Converter.new(logger) and tu.loaded(filename) then
+ tu.saved if tu.processed
end
-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
-
-end
-
-class Sorter
-
- def initialize(max=12)
- @rep, @map, @exp = Hash.new, Hash.new, Hash.new
- @max = max
- @rexa, @rexb = nil, nil
- end
-
- def replace(from,to='') # and expand
- @rep[from.escaped] = to || ''
- end
-
- # sorter.reduce('ch', 'c')
- # sorter.reduce('ij', 'y')
-
- def reduce(from,to='')
- @map[from] = to || ''
- end
-
- # sorter.expand('aeligature', 'ae')
- # sorter.expand('ijligature', 'y')
-
- def expand(from,to=nil)
- @exp[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)
- replace(from,to)
- expand(to)
- end
-
- def prepare
- @rexa = /(#{@rep.keys.join('|')})/o
- 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)
- str.gsub(@rexa) do
- @rep[$1.escaped]
- end.gsub(@rexb) do
- token = $1.sub(/\\/o, '')
- if @map.key?(token) then
- @map[token].ljust(@max,' ')
- elsif @exp.key?(token) then
- @exp[token].split('').collect do |t|
- t.ljust(@max,' ')
- end.join('')
- else
- ''
- end
- end
- end
-
- def remap(str)
- str.gsub(@rexa) do
- @rep[$1.escaped]
- end.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
-
- def preset(language='')
- 'a'.upto('z') do |c|
- expand(c)
- end
- shortcut("\\\'\\i", 'iacute')
- shortcut("\\\'i", 'iacute')
- shortcut("\\\"e", 'ediaeresis')
- shortcut("\\\'o", 'oacute')
- expand('aeligature', 'ae')
- expand('ijligature', 'y')
- expand('eacute')
- expand('egrave')
- expand('ediaeresis')
- # reduce('ch', 'c')
- # reduce('ij', 'y')
- # expand('aeligature', 'ae')
- # expand('ijligature', 'y')
- # expand('tex')
- 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
-
-end
-
-class Synonym
-
- @@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
-
-class Register
-
- @@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
- 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)
- #
- # 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[0,1]}] [#{entry.sortkey.gsub(/#{@@split}/o,'] [')}]\n"
- end
- end
- list.each do |entry|
- testalpha = entry.sortkey[0,1].downcase
- if testalpha != alpha.downcase or alphaclass != entry.class then
- alpha = testalpha
- alphaclass = entry.class
- if alpha != ' ' then
- flushsavedline(handle)
- character = alpha.sub(/([^a-zA-Z])/o) do "\\" + $1 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"
- elsif @@collapse then
- if savedentry != nextentry then
- savedFrom = savedline
- else
- savedTo, savedentry = savedline, nextentry
- end
- else
- handle << "\\registerpage#{savedline}\n"
- end
- nofpages += 1
- lastpage, lastrealpage = entry.page, entry.realpage
- end
- end
- Register.flushsavedline(handle)
- report("register #{list[0].class}: #{nofentries} entries and #{nofpages} pages")
- end
- end
-
-end
-
-class TeXUtil
-
- # how to deal with encoding:
- #
- # load context enco-* file
-
- def initialize
- @commands = []
- @programs = []
- @synonyms = Hash.new
- @registers = Hash.new
- @files = Hash.new
- @filename = 'texutil'
- @fatalerror = false
- end
-
- def loaded(filename)
- # begin
- File.open(File.suffixed(filename,'tui')).each do |line|
- case line.chomp
- # f b|e {filename}
- when /^f (b|e) \{(.*)\}$/o then
- if @files.key?($2) then @files[$2] += 1 else @files[$2] = 1 end
- # c commmand
- when /^c (.*)$/o then
- @commands.push($1)
- # e p {program data}
- when /^e p \{(.*)\}$/o then
- @programs.push($1)
- # s e {type}{command}{key}{associated data}
- when /^s e \{(.*)\}\s*\{(.*)\}\s*\{(.*)\}\s*\{(.*)\}\s*$/o then
- @synonyms[$1] = Array.new unless @synonyms.key?($1)
- @synonyms[$1].push(Synonym.new($1,$2,$3,$4))
- # from: r f
- when /^r f \{(.*)\}\s*\{(.*)\}\s*\{(.*)\}\s*\{(.*)\}\s*\{(.*)\}\s*\{(.*)\}\s*/o then
- @registers[$1] = Array.new unless @registers.key?($1)
- @registers[$1].push(Register.new(1,$1,$2,$3,$4,nil,$5,$6))
- # entry: r e {type}{location}{key}{entry}{page}{realpage}
- when /^r e \{(.*)\}\s*\{(.*)\}\s*\{(.*)\}\s*\{(.*)\}\s*\{(.*)\}\s*\{(.*)\}\s*/o then
- @registers[$1] = Array.new unless @registers.key?($1)
- @registers[$1].push(Register.new(2,$1,$2,$3,$4,nil,$5,$6))
- # from: r t
- when /^r t \{(.*)\}\s*\{(.*)\}\s*\{(.*)\}\s*\{(.*)\}\s*\{(.*)\}\s*\{(.*)\}\s*/o then
- @registers[$1] = Array.new unless @registers.key?($1)
- @registers[$1].push(Register.new(3,$1,$2,$3,$4,nil,$5,$6))
- # see: r s {type}{location}{key}{entry}{seetoo}{page}
- when /^r s \{(.*)\}\s*\{(.*)\}\s*\{(.*)\}\s*\{(.*)\}\s*\{(.*)\}\s*\{(.*)\}\s*/o then
- @registers[$1] = Array.new unless @registers.key?($1)
- @registers[$1].push(Register.new(4,$1,$2,$3,$4,$5,$6,nil))
- when /^k /o then
- # key
- when /^p /o then
- # plugin
- when /^q/o then
- break
- else
- report("unknown entry #{line}")
- end
- end
- # rescue
- # report("error in parsing file (#{$!})")
- # @filename = 'texutil'
- # else
- @filename = filename
- # end
- end
-
- def sorted
- sorter = Sorter.new
- sorter.preset
- sorter.prepare
- [@synonyms,@registers].each do |target|
- target.keys.each do |s|
- target[s].each_index do |i|
- target[s][i].build(sorter)
- end
- target[s] = target[s].sort
- end
- end
- end
-
- def banner(str)
- report(str)
- return "%\n% #{str}\n%\n"
- 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
- if @files.size > 0 then
- f << banner("loaded files: #{@files.size}")
- @files.keys.sort.each do |k|
- unless (@files[k] % 2) == 0 then
- report("check loading of file #{k}, begin/end problem")
- end
- f << "% > #{k} #{@files[k]/2}\n"
- end
- end
- if @commands.size > 0 then
- f << banner("commands: #{@commands.size}")
- @commands.each do |c|
- f << "#{c}\n"
- end
- end
- if @synonyms.size > 0 then
- @synonyms.keys.sort.each do |s|
- f << banner("synonyms: #{s} #{@synonyms[s].size}")
- Synonym.flush(@synonyms[s],f)
- end
- end
- if @registers.size > 0 then
- @registers.keys.sort.each do |s|
- f << banner("registers: #{s} #{@registers[s].size}")
- Register.flush(@registers[s],f)
- end
- end
- if @programs.size > 0 then
- f << banner("programs: #{@programs.size}")
- @programs.each do |p|
- f << "% #{p} (#{@programs[p]})\n"
- end
- end
- f.close
- @programs.each do |p|
- cmd = "texmfstart #{@programs[p]}"
- report("running #{cmd}")
- system(cmd)
- end
- end
- # rescue
- # report("fatal error when saving file (#{$!})")
- # end
- end
- end
-
-end
-
-if tu = TeXUtil.new and tu.loaded('tuitest') then
- tu.sorted
- tu.saved
-end
-
- # ShowBanner ;
-
# if ($UnknownOptions ) { ShowHelpInfo } # not yet done
# elsif ($ProcessReferences) { HandleReferences }
# elsif ($ProcessFigures ) { HandleFigures }
@@ -563,49 +20,3 @@ end
# elsif ($FilterPages ) { my $args = @ARGV.join(' ') ; system("texmfstart ctxtools --filter $args") }
# elsif ($ProcessHelp ) { ShowHelpInfo } # redundant
# else { ShowHelpInfo }
-
-#D So far.
-
-
-# # # # keep
-
-# sorter = Sorter.new
-# sorter.reduce('ch', 'c')
-# sorter.reduce('ij', 'y')
-
-# sorter.expand('aeligature', 'ae')
-# sorter.expand('ijligature', 'y')
-
-# str = Array.new
-
-# str.push 'aex c abc'
-# str.push 'aex h abc'
-# str.push 'aex ch abc'
-# str.push 'aex a abc'
-# str.push 'aex b abc'
-# str.push 'aex c def'
-# str.push 'aex h def'
-# str.push 'aex ch def'
-# str.push 'aex a def'
-# str.push 'aex b def'
-# str.push 'a\eacute x'
-# str.push 'a\egrave x'
-# str.push 'a\ediaeresis x'
-# str.push 'a\ediaeresis'
-# str.push '\aeligature xx'
-# str.push '+abc'
-# str.push 'ijs'
-# str.push 'ijverig'
-# str.push '\ijligature verig'
-# str.push 'ypsilon'
-
-# old = str.dup
-
-# str.collect! do |s|
- # sorter.remap(s)
-# end
-
-# str.sort.each do |i|
- # puts i
-# end
-
diff --git a/scripts/context/ruby/texmfstart.rb b/scripts/context/ruby/texmfstart.rb
index c082b623d..d791ee1a4 100644
--- a/scripts/context/ruby/texmfstart.rb
+++ b/scripts/context/ruby/texmfstart.rb
@@ -361,7 +361,7 @@ def output(str)
end
def usage
- print "version : #{$version} - 2003/2004 - www.pragma-ade.com\n"
+ print "version : #{$version} - 2003/2005 - www.pragma-ade.com\n"
print("\n")
print("usage : texmfstart [switches] filename [optional arguments]\n")
print("\n")