summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/context/perl/makempy.pl4
-rw-r--r--scripts/context/perl/texexec.pl280
-rw-r--r--scripts/context/perl/texexec.rme2
-rw-r--r--scripts/context/perl/texfont.pl15
-rw-r--r--scripts/context/perl/texutil.pl49
-rw-r--r--scripts/context/ruby/base/file.rb133
-rw-r--r--scripts/context/ruby/base/kpse.rb270
-rw-r--r--scripts/context/ruby/base/logger.rb104
-rw-r--r--scripts/context/ruby/base/pdf.rb53
-rw-r--r--scripts/context/ruby/base/state.rb75
-rw-r--r--scripts/context/ruby/base/switch.rb (renamed from scripts/context/ruby/xmpl/switch.rb)164
-rw-r--r--scripts/context/ruby/base/system.rb102
-rw-r--r--scripts/context/ruby/base/tex.rb1281
-rw-r--r--scripts/context/ruby/base/tool.rb305
-rw-r--r--scripts/context/ruby/base/variables.rb37
-rw-r--r--scripts/context/ruby/ctxtools.rb97
-rw-r--r--scripts/context/ruby/exa/logger.rb108
-rw-r--r--scripts/context/ruby/graphics/gs.rb631
-rw-r--r--scripts/context/ruby/graphics/inkscape.rb103
-rw-r--r--scripts/context/ruby/graphics/magick.rb161
-rw-r--r--scripts/context/ruby/newimgtopdf.rb86
-rw-r--r--scripts/context/ruby/newpstopdf.rb527
-rw-r--r--scripts/context/ruby/newtexexec.rb588
-rw-r--r--scripts/context/ruby/rlxtools.rb261
-rw-r--r--scripts/context/ruby/texmfstart.rb428
-rw-r--r--scripts/context/ruby/texsync.rb19
-rw-r--r--scripts/context/ruby/textools.rb16
-rw-r--r--scripts/context/ruby/xmltools.rb15
28 files changed, 5468 insertions, 446 deletions
diff --git a/scripts/context/perl/makempy.pl b/scripts/context/perl/makempy.pl
index 49298f318..5b52ee0bb 100644
--- a/scripts/context/perl/makempy.pl
+++ b/scripts/context/perl/makempy.pl
@@ -18,8 +18,8 @@ eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' && eval 'exec perl -S $0 $
# of binaries on UNIX as well as did some usefull suggestions
# to improve the functionality.
-# This script uses GhostScript and PStoEdit as well as
-# pdfTeX, and if requested TeXEdit and ConTeXt.
+# This script uses GhostScript and PStoEdit as well as
+# pdfTeX, and if requested TeXEdit and ConTeXt.
# todo: we can nowadays do without the intermediate step, because GS
# can now handle PDF quite good
diff --git a/scripts/context/perl/texexec.pl b/scripts/context/perl/texexec.pl
index fe6c8421f..0e6e5d098 100644
--- a/scripts/context/perl/texexec.pl
+++ b/scripts/context/perl/texexec.pl
@@ -34,6 +34,8 @@ eval '(exit $?0)' && eval 'exec perl -w -S $0 ${1+"$@"}' && eval 'exec perl -w -
use strict ;
+my $OriginalArgs = join(' ',@ARGV) ;
+
#~ use warnings ; # strange warnings, todo
# todo: second run of checksum of mp file with --nomprun changes
@@ -48,6 +50,9 @@ use Getopt::Long;
use Class::Struct; # needed for help subsystem
use FindBin;
use File::Compare;
+use File::Temp;
+
+use IO::Handle; autoflush STDOUT 1;
my %ConTeXtInterfaces; # otherwise problems with strict
my %ResponseInterface; # since i dunno how to allocate else
@@ -195,11 +200,15 @@ my $Paranoid = 0 ;
my $NotParanoid = 0 ;
my $BoxType = '' ;
+my $TempDir = '' ;
+
my $StartLine = 0 ;
my $StartColumn = 0 ;
my $EndLine = 0 ;
my $EndColumn = 0 ;
+my $MpEngineSupport = 0 ; # not now, we also need to patch executemp in context itself
+
# makempy :
my $MakeMpy = '';
@@ -303,6 +312,8 @@ my $MakeMpy = '';
"paranoid" => \$Paranoid,
"notparanoid" => \$NotParanoid,
"boxtype=s" => \$BoxType, # media art crop bleed trim
+ #### unix is unsafe (symlink viruses)
+ "tempdir=s" => \$TempDir,
#### experiment
"startline=s" => \$StartLine,
"startcolumn=s" => \$StartColumn,
@@ -409,7 +420,7 @@ if ( ( $LogFile ne '' ) && ( $LogFile =~ /\w+\.log$/io ) ) {
*STDERR = *LOGFILE;
}
-my $Program = " TeXExec 5.2.5 - ConTeXt / PRAGMA ADE 1997-2005";
+my $Program = " TeXExec 5.3.2 - ConTeXt / PRAGMA ADE 1997-2005";
print "\n$Program\n\n";
@@ -742,7 +753,9 @@ my $MpVirginFlag = IniValue( 'MpVirginFlag', '-ini' );
my $MpPassString = IniValue( 'MpPassString', '' );
my $MpFormat = IniValue( 'MpFormat', $MetaFun );
my $MpFormatPath = IniValue( 'MpFormatPath', $TeXFormatPath );
-my $UseEnginePath = IniValue( 'UseEnginePath', $TheEnginePath);
+my $UseEnginePath = IniValue( 'UseEnginePath', '');
+
+if ($TheEnginePath) { $UseEnginePath = 1 }
my $FmtLanguage = IniValue( 'FmtLanguage', '' );
my $FmtBodyFont = IniValue( 'FmtBodyFont', '' );
@@ -787,18 +800,20 @@ if ( $MpFormatFlag eq "" ) {
$MpFormatFlag = "-mem=" ;
}
-if ($UseEnginePath && (! $MakeFormats)) {
- $MpFormatFlag .= $MpExecutable . '/' ;
- $TeXFormatFlag .= $TeXExecutable . '/' ;
-}
+#~ if ($UseEnginePath && (! $MakeFormats)) {
+ #~ if ($MpEngineSupport) {
+ #~ $MpFormatFlag .= $MpExecutable . '/' ;
+ #~ } ;
+ #~ $TeXFormatFlag .= $TeXExecutable . '/' ;
+#~ }
#~ if ( $TeXFormatFlag eq "" ) { $TeXFormatFlag = "&" }
#~ if ( $MpFormatFlag eq "" ) { $MpFormatFlag = "&" }
-unless ( $dosish && !$escapeshell ) {
- if ( $TeXFormatFlag eq "&" ) { $TeXFormatFlag = "\\&" }
- if ( $MpFormatFlag eq "&" ) { $MpFormatFlag = "\\&" }
-}
+#~ unless ( $dosish && !$escapeshell ) {
+ #~ if ( $TeXFormatFlag eq "&" ) { $TeXFormatFlag = "\\&" }
+ #~ if ( $MpFormatFlag eq "&" ) { $MpFormatFlag = "\\&" }
+#~ }
if ($TeXProgram) { $TeXExecutable = $TeXProgram }
@@ -1490,6 +1505,10 @@ sub PrepRunTeX {
if ( $TeXTranslation ne '' ) { $cmd .= "-translate-file=$TeXTranslation " }
$cmd .= "$TeXFormatFlag$TeXFormatPath$Format $JobName.$JobSuffix $PipeString";
if ($Verbose) { print "\n$cmd\n\n" }
+unless ( $dosish && ! $escapeshell ) {
+ #~ $cmd =~ s/[^\\]\&/\\\&/io ;
+ $cmd =~ s/([^\\])\&/$1\\\&/io ;
+}
return $cmd;
}
@@ -1497,6 +1516,7 @@ sub RunTeX {
my ( $JobName, $JobSuffix ) = @_;
my $StartTime = time;
my $cmd = PrepRunTeX($JobName, $JobSuffix, '');
+ print $cmd if ($Verbose) ;
if ($EnterBatchMode) {
$Problems = system("$cmd");
} else {
@@ -1667,7 +1687,7 @@ sub CopyFile { # agressive copy, works for open files like in gs
close(OUT);
}
-sub CheckChanges { # also tub
+sub CheckMPChanges {
my $JobName = shift;
my $checksum = 0;
my $MPJobName = MPJobName( $JobName, "mpgraph" );
@@ -1691,6 +1711,18 @@ sub CheckChanges { # also tub
return $checksum;
}
+sub CheckTubChanges {
+ my $JobName = shift;
+ my $checksum = 0;
+ if ( open( TUB, "$JobName.tub" ) ) {
+ while (<TUB>) {
+ $checksum += do { unpack( "%32C*", <TUB> ) % 65535 }
+ }
+ close(TUB);
+ }
+ return $checksum;
+}
+
my $DummyFile = 0;
sub isXMLfile {
@@ -1854,9 +1886,12 @@ if ($JobSuffix =~ /\_fo$/i) {
}
print " TeX run : $TeXRuns\n\n";
my ( $mpchecksumbefore, $mpchecksumafter ) = ( 0, 0 );
- if ($AutoMPRun) { $mpchecksumbefore = CheckChanges($JobName) }
+ my ( $tubchecksumbefore, $tubchecksumafter ) = ( 0, 0 );
+ if ($AutoMPRun) { $mpchecksumbefore = CheckMPChanges($JobName) }
+ $tubchecksumbefore = CheckTubChanges($JobName) ;
$Problems = RunTeX( $JobName, $JobSuffix );
- if ($AutoMPRun) { $mpchecksumafter = CheckChanges($JobName) }
+ $tubchecksumafter = CheckTubChanges($JobName) ;
+ if ($AutoMPRun) { $mpchecksumafter = CheckMPChanges($JobName) }
if ( ( !$Problems ) && ( $NOfRuns > 1 ) ) {
if ( !$NoMPMode ) {
$MPrundone = RunTeXMP( $JobName, "mpgraph" );
@@ -1868,6 +1903,9 @@ if ($JobSuffix =~ /\_fo$/i) {
( $StopRunning
&& ( $mpchecksumafter == $mpchecksumbefore ) );
}
+ $StopRunning =
+ ( $StopRunning
+ && ( $tubchecksumafter == $tubchecksumbefore ) );
}
}
if ( ( $NOfRuns == 1 ) && $ForceTeXutil ) {
@@ -2043,7 +2081,7 @@ sub RunListing {
foreach $FileName (@FileNames) {
$CleanFileName = lc CleanTeXFileName($FileName);
print LIS "\\page\n";
- print LIS "\\setupfootertexts[\\tttf $CleanFileName][\\tttf \pagenumber]\n";
+ print LIS "\\setupfootertexts[\\tttf $CleanFileName][\\tttf \\pagenumber]\n";
print LIS "\\typefile\{$FileName\}\n";
}
print LIS "\\stoptext\n";
@@ -2248,33 +2286,76 @@ sub RunCombine {
sub LocatedFormatPath {
my $FormatPath = shift;
my $EnginePath = shift;
+ my $EngineDone = shift;
if ( ( $FormatPath eq '' ) && ( $kpsewhich ne '' ) ) {
- $FormatPath = `$kpsewhich --expand-var=\$TEXFORMATS` ;
- chomp $FormatPath;
+ unless ($EngineDone) {
+ my $str = $ENV{"TEXFORMATS"} ;
+ $str =~ s/\$ENGINE//io ;
+ $ENV{"TEXFORMATS"} = $str ;
+ }
+ # expanded paths
+ print " assuming engine : $EnginePath\n";
+ if (($UseEnginePath)&&($EngineDone)) {
+ $FormatPath = `$kpsewhich --engine=$EnginePath --show-path=fmt` ;
+ } else {
+ $FormatPath = `$kpsewhich --show-path=fmt` ;
+ }
+ chomp $FormatPath ;
+ if ( ( $FormatPath ne '' ) && $Verbose ) {
+ print "located formatpath (1) : $FormatPath\n";
+ }
+ # fall back
if ($FormatPath eq '') {
- $FormatPath = `$kpsewhich --show-path=fmt`;
- chomp $FormatPath;
+ if (($UseEnginePath)&&($EngineDone)) {
+ if ($dosish) {
+ $FormatPath = `$kpsewhich --engine=$EnginePath --expand-var=\$TEXFORMATS` ;
+ } else {
+ $FormatPath = `$kpsewhich --engine=$EnginePath --expand-var=\\\$TEXFORMATS` ;
+ }
+ } else {
+ if ($dosish) {
+ $FormatPath = `$kpsewhich --expand-var=\$TEXFORMATS` ;
+ } else {
+ $FormatPath = `$kpsewhich --expand-var=\\\$TEXFORMATS` ;
+ }
+ }
+ }
+ chomp $FormatPath ;
+ if ( ( $FormatPath ne '' ) && $Verbose ) {
+ print "located formatpath (2) : $FormatPath\n";
}
- $FormatPath =~ s/\.+\;//o; # should be a sub
- $FormatPath =~ s/\;.*//o;
- $FormatPath =~ s/\!//go;
+ #
+ if ( ( $FormatPath ne '' ) && ($FormatPath =~ /unsetengine/) ) {
+ $FormatPath =~ s/unsetengine/$EnginePath/;
+ if ( ( $FormatPath ne '' ) && $Verbose ) {
+ print "located formatpath (!) : $FormatPath (unbugged)\n";
+ }
+ }
+ # take first one
+ if ($dosish) {
+ $FormatPath =~ s/\;.*//o;
+ } else {
+ $FormatPath =~ s/\:.*//o;
+ }
+ # remove clever things
+ $FormatPath =~ s/[\!\{\}\,]//go;
$FormatPath =~ s/\\/\//go;
$FormatPath =~ s/\/\//\//go;
$FormatPath =~ s/[\/\\]$//;
if ( ( $FormatPath ne '' ) && $Verbose ) {
- print " located formatpath : $FormatPath\n";
+ print "located formatpath (3) : $FormatPath\n";
}
$FormatPath .= '/';
}
- if ($UseEnginePath && ($FormatPath ne '' && ($FormatPath !~ /$EnginePath\/$/))) {
+ if ($UseEnginePath && $EngineDone && ($FormatPath ne '') && ($FormatPath !~ /$EnginePath\/$/)) {
$FormatPath .= $EnginePath ;
unless (-d $FormatPath) {
mkdir $FormatPath ;
}
$FormatPath .= '/' ;
}
-
+ print " using formatpath : $FormatPath\n" if $Verbose ;
return $FormatPath;
}
@@ -2300,7 +2381,7 @@ sub RunOneFormat {
$TeXPrefix = "*";
}
my $CurrentPath = cwd();
- my $TheTeXFormatPath = LocatedFormatPath($TeXFormatPath, $TeXExecutable);
+ my $TheTeXFormatPath = LocatedFormatPath($TeXFormatPath, $TeXExecutable,1);
if ( $TheTeXFormatPath ne '' ) { chdir $TheTeXFormatPath }
MakeUserFile;
MakeResponseFile;
@@ -2314,6 +2395,12 @@ sub RunOneFormat {
RestoreUserFile;
if ( ( $TheTeXFormatPath ne '' ) && ( $CurrentPath ne '' ) ) {
+ print "\n";
+ if ($UseEnginePath) {
+ print " used engineformatpath : $TheTeXFormatPath\n";
+ } else {
+ print " used formatpath : $TheTeXFormatPath\n";
+ }
chdir $CurrentPath;
}
}
@@ -2355,31 +2442,110 @@ sub RunFormats {
}
sub RunMpFormat {
+ # engine is not supported by MP
my $MpFormat = shift;
return if ( $MpFormat eq '' );
my $CurrentPath = cwd();
- my $TheMpFormatPath = LocatedFormatPath($MpFormatPath, $MpExecutable);
+ my $TheMpFormatPath = LocatedFormatPath($MpFormatPath,$MpExecutable,$MpEngineSupport);
if ( $TheMpFormatPath ne '' ) { chdir $TheMpFormatPath }
$own_quote = ($MpExecutable =~ m/^[^\"].* / ? "\"" : "") ;
my $cmd =
"$own_quote$MpExecutable$own_quote $MpVirginFlag $MpPassString $MpFormat";
+
+unless ( $dosish && !$escapeshell ) {
+ $cmd =~ s/[^\\]\&/\\\&/io ;
+}
+
if ($Verbose) { print "\n$cmd\n\n" }
system($cmd ) ;
if ( ( $TheMpFormatPath ne '' ) && ( $CurrentPath ne '' ) ) {
+ print "\n";
+ #~ if ($UseEnginePath) {
+ #~ print " used engineformatpath : $TheMpFormatPath\n";
+ #~ } else {
+ print " used formatpath : $TheMpFormatPath\n";
+ #~ }
chdir $CurrentPath;
}
}
+
+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 ($dosish) {
+ $texformats = `kpsewhich --expand-var=\$TEXFORMATS`.chomp ;
+ } else {
+ $texformats = `kpsewhich --expand-var=\\\$TEXFORMATS`.chomp ;
+ }
+ }
+ if ($texformats !~ /web2c[\/\\].*\$ENGINE/) {
+ $texformats =~ s/web2c/web2c\/{\$ENGINE,}/ ;
+ $ENV{'TEXFORMATS'} = $texformats ;
+ print " fixing texformat path : $ENV{'TEXFORMATS'}\n";
+ }
+ if (! defined($ENV{'ENGINE'})) {
+ if ($MpEngineSupport) {
+ $ENV{'ENGINE'} .= $MpExecutable ;
+ } ;
+ $ENV{'ENGINE'} = $TeXExecutable ;
+ }
+}
+
sub RunFiles {
my $currentpath = cwd() ;
+ my $oldrunpath = $RunPath ;
+ # new
+ checktexformatpath ;
# test if current path is writable
if (! -w "$currentpath") {
print " current path readonly : $currentpath\n";
- if ($ENV{"TEMP"} && -e $ENV{"TEMP"}) {
- $RunPath = $ENV{"TEMP"} ;
- } elsif ($ENV{"TMP"} && -e $ENV{"TMP"}) {
- $RunPath = $ENV{"TMP"} ;
+ #
+ # we cannot use the following because then the result will
+ # also be removed and users will not know where to look
+ #
+ # $RunPath = File::Temp::tempdir(CLEANUP=>1) ;
+ # if ($RunPath) {
+ # print " using temp path : $RunPath\n";
+ # } else {
+ # print " problematic temp path : $currentpath\n";
+ # exit ;
+ # }
+ #
+ foreach my $d ($ENV{"TMPDIR"},$ENV{"TEMP"},$ENV{"TMP"},"/tmp") {
+ if ($d && -e $d) { $RunPath = $d ; last ; }
+ }
+ if ($TempDir eq '') {
+ print " provide temp path for : $RunPath\n";
+ exit ;
+ } elsif ($RunPath ne $oldrunpath) {
+ chdir ($RunPath) ;
+ unless (-e $TempDir) {
+ print " creating texexec path : $TempDir\n";
+ mkdir ("$TempDir", 077)
+ }
+ if (-e $TempDir) {
+ $RunPath += $TempDir ;
+ } else {
+ # we abort this run because on unix an invalid tmp
+ # path can be an indication of a infected system
+ print " problematic temp path : $RunPath\n";
+ exit ;
+ }
+ } else {
+ print " no writable temp path : $RunPath\n";
+ exit ;
}
}
# test if we need to change paths
@@ -2640,6 +2806,7 @@ sub doRunMP { ###########
}
# prevent nameclash, experimental
my $MpMpName = "$MpName";
+ print "$cmd $MpMpName" if ($Verbose) ;
$Problems = system("$cmd $MpMpName");
open( MPL, "$MpName.log" );
while (<MPL>) # can be one big line unix under win
@@ -2732,45 +2899,6 @@ sub load_set_file {
if ( $SetFile ne "" ) { load_set_file( $SetFile, $Verbose ) }
-# todo : more consistent argv handling
-#
-# sub ifargs
-# { $problems = (@ARGV==0) ;
-# if ($problems)
-# { print " warning : nothing to do\n" }
-# return $problems }
-
-# sub check_texmf_root
-# { return if ($TeXRoot eq "") ;
-# my $root = $TeXRoot ;
-# $root =~ s/\\/\//goi ;
-# if (-d $root)
-# { print " using tex root : $root \n" ;
-# $ENV{TEXROOT} = $root ;
-# $ENV{TEXMFCNF} = "$root/texmf-local/web2c" ;
-# $ENV{TEXMFFONTS} = "$root/texmf-fonts" ;
-# $ENV{TEXMFLOCAL} = "$root/texmf-local" ;
-# $ENV{TEXMFMAIN} = "$root/texmf" }
-# else
-# { print " invalid tex root : $root \n" } }
-#
-# sub check_texmf_tree
-# { return if ($TeXTree eq "") ;
-# my $tree = $TeXTree ;
-# unless (-d $tree)
-# { $tree = $ENV{TEXMFLOCAL} ;
-# $tree =~ s/texmf.*//io ;
-# $tree .= $TeXTree }
-# if (-d $tree)
-# { print " using texmf tree : $tree \n" ;
-# $ENV{TEXMFPROJECT} = $tree ;
-# if ((-f "$tree/web2c/cont-en.efmt")||
-# (-f "$tree/web2c/cont-nl.efmt"))
-# { $ENV{TEXFORMATS} = "$tree/web2c" }
-# $ENV{TEXMF} = '{$TEXMFPROJECT,$TEXMFFONTS,$TEXMFLOCAL,!!$TEXMFMAIN}' }
-# else
-# { print " invalid texmf tree : $tree \n" } }
-
sub check_texmf_root { }
sub check_texmf_tree { }
@@ -2834,6 +2962,7 @@ if ($HelpAsked) {
show_help_info
} elsif ($Version) {
show_version_info
+ #~ system("texmfstart ctxtools --check $OriginalArgs") ;
} elsif ($TypesetListing) {
check_texmf_root;
check_texmf_tree;
@@ -2859,23 +2988,12 @@ if ($HelpAsked) {
else {
RunFormats ;
}
+ #~ system("texmfstart ctxtools $OriginalArgs") ;
} elsif (@ARGV) {
check_texmf_root;
check_texmf_tree;
@ARGV = <@ARGV>;
RunFiles;
-#~ } else {
- #~ if ($Modules ne "") { # kind of fall back: texexec --use=set-02 --pdf
- #~ my @tmp = split(',', $Modules) ;
- #~ @ARGV[0] = @tmp[0] ;
- #~ }
- #~ if (@ARGV) {
- #~ check_texmf_root;
- #~ check_texmf_tree;
- #~ RunFiles;
- #~ } elsif ( !$HelpAsked ) {
- #~ show_help_options;
-#~ } }
} elsif ( !$HelpAsked ) {
show_help_options;
}
diff --git a/scripts/context/perl/texexec.rme b/scripts/context/perl/texexec.rme
index 419d1faec..f38b4be7f 100644
--- a/scripts/context/perl/texexec.rme
+++ b/scripts/context/perl/texexec.rme
@@ -51,7 +51,7 @@ set TeXShell to tetex
%
% Here are some general defaults. They can be overruled later.
-set UseEnginePath to false
+set UseEnginePath to true
set UsedInterfaces to en nl metafun mptopdf
set UserInterface to en
diff --git a/scripts/context/perl/texfont.pl b/scripts/context/perl/texfont.pl
index 71433cb56..732fb0f3e 100644
--- a/scripts/context/perl/texfont.pl
+++ b/scripts/context/perl/texfont.pl
@@ -144,7 +144,7 @@ my $remove = 0 ;
my $expert = 0 ;
my $trace = 0 ;
my $afmpl = 0 ;
-my $trees = 'TEXMFFONTS,TEXMFLOCAL,TEXMFEXTRA,TEXMFMAIN' ;
+my $trees = 'TEXMFFONTS,TEXMFLOCAL,TEXMFEXTRA,TEXMFMAIN,TEXMFDIST' ;
my $pattern = '' ;
my $fontsuffix = "" ;
@@ -649,12 +649,13 @@ sub UnLink
sub globafmfiles
{ my ($runpath, $pattern) = @_ ;
my @files = validglob("$runpath/$pattern.afm") ;
+ report("locating afm files : using pattern $runpath/$pattern.afm");
if ($preproc && !$lcdf)
{ @files = validglob("$runpath/$pattern.*tf") ;
- report("locating otf files : using pattern $pattern");
+ report("locating otf files : using pattern $runpath/$pattern.*tf");
unless (@files)
{ @files = validglob("$sourcepath/$pattern.ttf") ;
- report("locating ttf files : using pattern $pattern") }
+ report("locating ttf files : using pattern $sourcepath/$pattern.ttf") }
}
if (@files) # also elsewhere
{ report("locating afm files : using pattern $pattern") }
@@ -758,13 +759,9 @@ unless ($tex) { report "warning : can't open $texfile" }
if ($map)
{ print MAP "% This file is generated by the TeXFont Perl script.\n" ;
print MAP "%\n" ;
- print MAP "% You need to add the following line to pdftex.cfg:\n" ;
+ print MAP "% You need to add the following line to your file:\n" ;
print MAP "%\n" ;
- print MAP "% map +$mapfile\n" ;
- print MAP "%\n" ;
- print MAP "% Alternatively in your TeX source you can say:\n" ;
- print MAP "%\n" ;
- print MAP "% \\pdf \{+$mapfile\}\n" ;
+ print MAP "% \\pdfmapfile{+$mapfile}\n" ;
print MAP "%\n" ;
print MAP "% In ConTeXt you can best use:\n" ;
print MAP "%\n" ;
diff --git a/scripts/context/perl/texutil.pl b/scripts/context/perl/texutil.pl
index 025fe8946..d5e6ef9ea 100644
--- a/scripts/context/perl/texutil.pl
+++ b/scripts/context/perl/texutil.pl
@@ -134,11 +134,38 @@ my $dosish = ($Config{'osname'} =~ /^(ms)?dos|^os\/2|^(ms|cyg)win/i) ;
"verbose" => \$ProcessVerbose,
"interface=s" => \$UserInterface) ;
+# A bit old, this code, could be an array. Anyhow, we will
+# replace texutil soon.
+
+$InputFile = "@ARGV" ; # niet waterdicht
+
#D We need some hacks to suppress terminal output. This
#D piece of code is based on page~193 of "Programming Perl".
$ProgramLog = "texutil.log" ;
+# Well, it seems that unix' symlinks are sensitive for being
+# hijacked. The assumption is that a known file can be a problem.
+# Of course when one knows that certains files are processed,
+# the names are always known and hijacking can always take
+# place. But let's use a slightly less predictable name here:
+#
+# if ((@ARGV[0]) && (@ARGV[0] ne "")) {
+# $ProgramLog = "@ARGV[0]-$ProgramLog" ;
+# } else {
+# # no need to be silent
+# $ProcessSilent = 0 ;
+# }
+#
+# or better, let's drop this feature, since i'm not in the mood
+# now to test hacks like this (i'll just wait till the age of
+# computer anarchy has ended).
+
+$ProgramLog = "/dev/null" ;
+
+# Maybe we should just write to the nul device. (In the rewritten
+# version I can treat unix more strick.)
+
sub RedirectTerminal
{ open SAVEDSTDOUT, ">&STDOUT" ;
open STDOUT, ">$ProgramLog" ;
@@ -166,8 +193,6 @@ sub CloseTerminal
#D subroutine below is therefore only needed when no file or
#D pattern is given.
-$InputFile = "@ARGV" ; # niet waterdicht
-
sub CompFileName
{ my ($a,$b) = @_ ;
my ($fa,$sa) = split(/\./,$a) ;
@@ -1360,6 +1385,7 @@ sub FlushSavedLine
print TUO "\\registerto$SavedTo" }
else
{ print TUO "\\registerpage$SavedFrom" } }
+ $SavedHow = "" ;
$SavedFrom = "" ;
$SavedTo = "" ;
$SavedEntry = "" }
@@ -1383,6 +1409,7 @@ sub FlushRegisters
$SavedFrom = "" ;
$SavedTo = "" ;
$SavedEntry = "" ;
+ $SavedHow = "" ;
for ($n=1 ; $n<=$NOfEntries ; ++$n)
{ ($Class, $LCKey, $Key, $Entry, $TextHow, $RegisterState,
@@ -1393,7 +1420,6 @@ sub FlushRegisters
#
if ($SortN)
{ $AlfKey = $Key ;
-# $AlfKey =~ s/(.).*\x00(.).*/$1$2/o ;
$AlfKey =~ s/(.).*\x00(.).*/$2/o ;
if (defined($ALF{$AlfKey}))
{ $TestAlfa = $ALF{$AlfKey} } }
@@ -1445,11 +1471,16 @@ sub FlushRegisters
print TUO "\\registersee{$Class}{$PageHow,$TextHow}{$SeeToo}{$Page}\n" ;
$LastPage = $Page ;
$LastRealPage = $RealPage }
- elsif (($Copied) ||
- ! (($LastPage eq $Page) and ($LastRealPage eq $RealPage)))
+ else {
+if (($SavedHow ne $PageHow) && ($PageHow ne "")) {
+ # last valid page attribute counts
+ $SavedHow = $PageHow ;
+}
+ if (($Copied) || ! (($LastPage eq $Page) && ($LastRealPage eq $RealPage)))
{ # print "$LastPage / $Page // $LastRealPage / $RealPage\n" ;
$NextEntry = "{$Class}{$PreviousA}{$PreviousB}{$PreviousC}{$PageHow,$TextHow}" ;
- $SavedLine = "{$Class}{$PageHow,$TextHow}{$Location}{$Page}{$RealPage}\n" ;
+ #~ $SavedLine = "{$Class}{$PageHow,$TextHow}{$Location}{$Page}{$RealPage}\n" ;
+ $SavedLine = "{$Class}{$SavedHow,$TextHow}{$Location}{$Page}{$RealPage}\n" ;
if ($RegisterState eq $RegStat{"f"})
{ FlushSavedLine ;
print TUO "\\registerfrom$SavedLine" }
@@ -1468,7 +1499,7 @@ sub FlushRegisters
}
++$NOfSanePages ;
$LastPage = $Page ;
- $LastRealPage = $RealPage } }
+ $LastRealPage = $RealPage } } }
FlushSavedLine ;
@@ -2205,10 +2236,10 @@ sub HandlePdfFigure
{ if (($MediaBoxFound < 2) && ($SomeLine =~ /\/ArtBox\s*\[/io))
{ $MediaBoxFound = 3 ;
$MediaBox = $SomeLine }
- elsif (($MediaBoxFound < 2) && ($SomeLine =~ /\/CropBox\s*\[ /io))
+ elsif (($MediaBoxFound < 2) && ($SomeLine =~ /\/CropBox\s*\[/io))
{ $MediaBoxFound = 2 ;
$MediaBox = $SomeLine }
- elsif (($MediaBoxFound == 0) && ($SomeLine =~ /\/MediaBox\s*\[ /io))
+ elsif (($MediaBoxFound == 0) && ($SomeLine =~ /\/MediaBox\s*\[/io))
{ $MediaBoxFound = 1 ;
$MediaBox = $SomeLine } } }
close ( PDF ) ;
diff --git a/scripts/context/ruby/base/file.rb b/scripts/context/ruby/base/file.rb
new file mode 100644
index 000000000..b7170d555
--- /dev/null
+++ b/scripts/context/ruby/base/file.rb
@@ -0,0 +1,133 @@
+require 'ftools'
+
+class File
+
+ def File.suffixed(name,sufa,sufb=nil)
+ if sufb then
+ unsuffixed(name) + "-#{sufa}.#{sufb}"
+ else
+ unsuffixed(name) + ".#{sufa}"
+ end
+ end
+
+ def File.unsuffixed(name)
+ name.sub(/\.[^\.]*?$/o, '')
+ end
+
+ def File.suffix(name,default='')
+ if name =~ /\.([^\.]*?)$/o then
+ $1
+ else
+ default
+ end
+ end
+
+ def File.splitname(name,suffix='')
+ if name =~ /(.*)\.([^\.]*?)$/o then
+ [$1, $2]
+ else
+ [name, suffix]
+ end
+ end
+
+end
+
+class File
+
+ def File.silentopen(name,method='r')
+ begin
+ f = File.open(name,method)
+ rescue
+ return nil
+ else
+ return f
+ end
+ end
+
+ def File.silentread(name)
+ begin
+ data = IO.read(name)
+ rescue
+ return nil
+ else
+ return data
+ end
+ end
+
+ def File.atleast?(name,n=0)
+ begin
+ size = FileTest.size(name)
+ rescue
+ return false
+ else
+ return size > n
+ end
+ end
+
+ def File.appended(name,str='')
+ if FileTest.file?(name) then
+ begin
+ if f = File.open(name,'a') then
+ f << str
+ f.close
+ return true
+ end
+ rescue
+ end
+ end
+ return false
+ end
+
+ def File.written(name,str='')
+ begin
+ if f = File.open(name,'w') then
+ f << str
+ f.close
+ return true
+ end
+ rescue
+ end
+ return false
+ end
+
+ def File.silentdelete(filename)
+ begin File.delete(filename) ; rescue ; end
+ end
+
+ def File.silentcopy(oldname,newname)
+ return if File.expand_path(oldname) == File.expand_path(newname)
+ begin File.copy(oldname,newname) ; rescue ; end
+ end
+
+ def File.silentrename(oldname,newname)
+ # in case of troubles, we just copy the file; we
+ # maybe working over multiple file systems or
+ # apps may have mildly locked files (like gs does)
+ return if File.expand_path(oldname) == File.expand_path(newname)
+ begin File.delete(newname) ; rescue ; end
+ begin
+ File.rename(oldname,newname)
+ rescue
+ begin File.copy(oldname,newname) ; rescue ; end
+ end
+ end
+
+end
+
+class File
+
+ # handles "c:\tmp\test.tex" as well as "/${TEMP}/test.tex")
+
+ def File.unixfied(filename)
+ begin
+ str = filename.gsub(/\$\{*([a-z0-9\_]+)\}*/oi) do
+ if ENV.key?($1) then ENV[$1] else $1 end
+ end
+ str.gsub(/[\/\\]+/o, '/')
+ rescue
+ filename
+ end
+ end
+
+end
+
diff --git a/scripts/context/ruby/base/kpse.rb b/scripts/context/ruby/base/kpse.rb
new file mode 100644
index 000000000..6dbd6e6cf
--- /dev/null
+++ b/scripts/context/ruby/base/kpse.rb
@@ -0,0 +1,270 @@
+# module : base/kpse
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2002-2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+# rename this one to environment
+
+module Kpse
+
+ @@located = Hash.new
+ @@paths = Hash.new
+ @@scripts = Hash.new
+ @@formats = ['tex','texmfscripts','other text files']
+ @@progname = 'context'
+ @@ownpath = $0.sub(/[\\\/][a-z0-9\-]*?\.rb/i,'')
+ @@problems = false
+ @@tracing = false
+ @@distribution = 'web2c'
+ @@crossover = true
+ @@mswindows = Config::CONFIG['host_os'] =~ /mswin/
+
+ # check first in bin path
+
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
+ @@distribution = 'miktex' if path =~ /miktex/o
+ end
+
+ # if @@crossover then
+ # ENV.keys.each do |k|
+ # case k
+ # when /\_CTX\_KPSE\_V\_(.*?)\_/io then @@located[$1] = ENV[k].dup
+ # when /\_CTX\_KPSE\_P\_(.*?)\_/io then @@paths [$1] = ENV[k].dup.split(';')
+ # when /\_CTX\_KPSE\_S\_(.*?)\_/io then @@scripts[$1] = ENV[k].dup
+ # end
+ # end
+ # end
+
+ if @@crossover then
+ ENV.keys.each do |k|
+ case k
+ when /\_CTX\_KPSE\_V\_(.*?)\_/io then @@located[$1] = ENV[k].dup
+ when /\_CTX\_KPSE\_P\_(.*?)\_/io then @@paths [$1] = ENV[k].dup.split(';')
+ when /\_CTX\_KPSE\_S\_(.*?)\_/io then @@scripts[$1] = ENV[k].dup
+ end
+ end
+ end
+
+ def Kpse.inspect
+ @@located.keys.sort.each do |k| puts("located : #{k} -> #{@@located[k]}\n") end
+ @@paths .keys.sort.each do |k| puts("paths : #{k} -> #{@@paths [k]}\n") end
+ @@scripts.keys.sort.each do |k| puts("scripts : #{k} -> #{@@scripts[k]}\n") end
+ end
+
+ def Kpse.distribution
+ @@distribution
+ end
+
+ def Kpse.found(filename, progname=nil, format=nil)
+ begin
+ tag = Kpse.key(filename) # all
+ if @@located.key?(tag) then
+ return @@located[tag]
+ elsif FileTest.file?(filename) then
+ setvariable(tag,filename)
+ return filename
+ elsif FileTest.file?(File.join(@@ownpath,filename)) then
+ setvariable(tag,File.join(@@ownpath,filename))
+ return @@located[tag]
+ else
+ [progname,@@progname].flatten.compact.uniq.each do |prg|
+ [format,@@formats].flatten.compact.uniq.each do |fmt|
+ begin
+ tag = Kpse.key(filename,prg,fmt)
+ if @@located.key?(tag) then
+ return @@located[tag]
+ elsif p = Kpse.kpsewhich(filename,prg,fmt) then
+ setvariable(tag,p.chomp)
+ return @@located[tag]
+ end
+ rescue
+ end
+ end
+ end
+ setvariable(tag,filename)
+ return filename
+ end
+ rescue
+ filename
+ end
+ end
+
+ def Kpse.kpsewhich(filename,progname,format)
+ Kpse.run("-progname=#{progname} -format=\"#{format}\" #{filename}")
+ end
+
+ def Kpse.which
+ Kpse.Kpsewhich
+ end
+
+ def Kpse.run(arguments)
+ puts arguments if @@tracing
+ begin
+ if @@problems then
+ results = ''
+ else
+ results = `kpsewhich #{arguments}`.chomp
+ end
+ rescue
+ puts "unable to run kpsewhich" if @@tracing
+ @@problems, results = true, ''
+ end
+ puts results if @@tracing
+ return results
+ end
+
+ def Kpse.formatpaths
+ unless @@paths.key?('formatpaths') then
+ begin
+ setpath('formatpaths',run("--show-path=fmt").gsub(/\\/,'/').split(File::PATH_SEPARATOR))
+ rescue
+ setpath('formatpaths',[])
+ end
+ end
+ return @@paths['formatpaths']
+ end
+
+ def Kpse.key(filename='',progname='all',format='all')
+ [progname,format,filename].join('-')
+ end
+
+ def Kpse.formatpath(engine='pdfetex',enginepath=true)
+
+ unless @@paths.key?(engine) then
+ # overcome a bug/error in web2c/distributions/kpse
+ if ENV['TEXFORMATS'] then
+ ENV['TEXFORMATS'] = ENV['TEXFORMATS'].sub(/\$ENGINE/io,'')
+ end
+ # use modern method
+ if enginepath then
+ formatpath = run("--engine=#{engine} --show-path=fmt")
+ else
+ formatpath = run("--show-path=fmt")
+ end
+ # use ancient method
+ if formatpath.empty? then
+ if enginepath then
+ if @@mswindows then
+ formatpath = run("--engine=#{engine} --expand-var=\$TEXFORMATS")
+ else
+ formatpath = run("--engine=#{engine} --expand-var=\\\$TEXFORMATS")
+ end
+ else
+ if enginepath then
+ formatpath = run("--expand-var=\$TEXFORMATS")
+ else
+ formatpath = run("--expand-var=\\\$TEXFORMATS")
+ end
+ end
+ end
+ # overcome a bug/error in web2c/distributions/kpse
+ formatpath.sub!(/unsetengine/, engine)
+ # take first one
+ if ! formatpath.empty? then
+ formatpath = formatpath.split(File::PATH_SEPARATOR).first
+ # remove clever things
+ formatpath.gsub!(/[\!\{\}\,]/, '')
+ unless formatpath.empty? then
+ if enginepath then
+ newformatpath = File.join(formatpath,engine).gsub(/[\/\\]+/, '/')
+ if FileTest.directory?(newformatpath) then
+ formatpath = newformatpath
+ else
+ begin
+ File.makedirs(newformatpath)
+ rescue
+ else
+ formatpath = newformatpath if FileTest.directory?(newformatpath)
+ end
+ end
+ else
+ formatpath = formatpath.gsub(/[\/\\]+/, '/').gsub(/\/$/, '')
+ end
+ end
+ end
+ setpath(engine,formatpath)
+ end
+ return @@paths[engine]
+ end
+
+ def Kpse.update
+ case @@distribution
+ when 'miktex' then
+ system('initexmf --update-fndb')
+ else
+ # always mktexlsr anyway
+
+ end
+ system('mktexlsr')
+ end
+
+ def Kpse.distribution
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
+ if path =~ /miktex/ then
+ return 'miktex'
+ end
+ end
+ return 'web2c'
+ end
+
+ def Kpse.miktex?
+ distribution == 'miktex'
+ end
+
+ def Kpse.web2c?
+ distribution == 'web2c'
+ end
+
+ # engine support is either broken of not implemented in some
+ # distributions, so we need to take care of it ourselves
+
+ def Kpse.fixtexmfvars(engine=nil)
+ ENV['ENGINE'] = engine if engine
+ texformats = if ENV['TEXFORMATS'] then ENV['TEXFORMATS'].dup else '' end
+ if @@mswindows then
+ texformats = `kpsewhich --expand-var=\$TEXFORMATS`.chomp if texformats.empty?
+ else
+ texformats = `kpsewhich --expand-var=\\\$TEXFORMATS`.chomp if texformats.empty?
+ end
+ if texformats !~ /web2c[\/\\].*\$ENGINE/ then
+ ENV['TEXFORMATS'] = texformats.gsub(/web2c/, "web2c/{\$ENGINE,}")
+ return true
+ else
+ return false
+ end
+
+ end
+
+ def Kpse.runscript(name,filename=[],options=[])
+ setscript(name,`texmfstart --locate #{name}`) unless @@scripts.key?(name)
+ system("#{@@scripts[name]} #{[options].flatten.join(' ')} #{[filename].flatten.join(' ')}")
+ end
+
+ def Kpse.pipescript(name,filename=[],options=[])
+ setscript(name,`texmfstart --locate #{name}`) unless @@scripts.key?(name)
+ `#{@@scripts[name]} #{[options].flatten.join(' ')} #{[filename].flatten.join(' ')}`
+ end
+
+ private
+
+ def Kpse.setvariable(key,value)
+ @@located[key] = value
+ ENV["_CTX_K_V_#{key}_"] = @@located[key] if @@crossover
+ end
+
+ def Kpse.setscript(key,value)
+ @@scripts[key] = value
+ ENV["_CTX_K_S_#{key}_"] = @@scripts[key] if @@crossover
+ end
+
+ def Kpse.setpath(key,value)
+ @@paths[key] = [value].flatten.uniq
+ ENV["_CTX_K_P_#{key}_"] = @@paths[key].join(';') if @@crossover
+ end
+
+end
diff --git a/scripts/context/ruby/base/logger.rb b/scripts/context/ruby/base/logger.rb
new file mode 100644
index 000000000..2526cdb0e
--- /dev/null
+++ b/scripts/context/ruby/base/logger.rb
@@ -0,0 +1,104 @@
+# module : base/logger
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2002-2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+require 'thread'
+
+# The next calls are valid:
+
+# @log.report('a','b','c', 'd')
+# @log.report('a','b',"c #{d}")
+# @log.report("a b c #{d}")
+
+# Keep in mind that "whatever #{something}" is two times faster than
+# 'whatever ' + something or ['whatever',something].join and that
+# when verbosity is not needed the following is much faster too:
+
+# @log.report('a','b','c', 'd') if @log.verbose?
+# @log.report('a','b',"c #{d}") if @log.verbose?
+# @log.report("a b c #{d}") if @log.verbose?
+
+# The last three cases are equally fast when verbosity is turned off.
+
+# Under consideration: verbose per instance
+
+class Logger
+
+ @@length = 0
+ @@verbose = false
+
+ def initialize(tag=nil,length=0,verbose=false)
+ @tag = tag || ''
+ @@verbose = @@verbose || verbose
+ @@length = @tag.length if @tag.length > @@length
+ @@length = length if length > @@length
+ end
+
+ def report(*str)
+ begin
+ case str.length
+ when 0
+ print("\n")
+ return true
+ when 1
+ message = str.first
+ else
+ message = [str].flatten.collect{|s| s.to_s}.join(' ').chomp
+ end
+ if @tag.empty? then
+ print("#{message}\n")
+ else
+ # try to avoid too many adjustments
+ @tag = @tag.ljust(@@length) unless @tag.length == @@length
+ print("#{@tag} | #{message}\n")
+ end
+ rescue
+ end
+ return true
+ end
+
+ def reportlines(*str)
+ unless @tag.empty? then
+ @tag = @tag.ljust(@@length) unless @tag.length == @@length
+ end
+ report([str].flatten.collect{|s| s.gsub(/\n/,"\n#{@tag} | ")}.join(' '))
+ end
+
+ def debug(*str)
+ report(str) if @@verbose
+ end
+
+ def error(*str)
+ if ! $! || $!.to_s.empty? then
+ report(str)
+ else
+ report(str,$!)
+ end
+ end
+
+ def verbose
+ @@verbose = true
+ end
+
+ def silent
+ @@verbose = false
+ end
+
+ def verbose?
+ @@verbose
+ end
+
+ # attr_reader :tag
+
+ # alias fatal error
+ # alias info debug
+ # alias warn debug
+ # alias debug? :verbose?
+
+end
diff --git a/scripts/context/ruby/base/pdf.rb b/scripts/context/ruby/base/pdf.rb
new file mode 100644
index 000000000..49d177b5d
--- /dev/null
+++ b/scripts/context/ruby/base/pdf.rb
@@ -0,0 +1,53 @@
+module PDFview
+
+ @files = Hash.new
+
+ def PDFview.open(*list)
+ begin
+ [*list].flatten.each do |file|
+ filename = fullname(file)
+ if FileTest.file?(filename) then
+ result = `pdfopen --file #{filename} 2>&1`
+ @files[filename] = true
+ end
+ end
+ rescue
+ end
+ end
+
+ def PDFview.close(*list)
+ [*list].flatten.each do |file|
+ filename = fullname(file)
+ begin
+ if @files.key?(filename) then
+ result = `pdfclose --file #{filename} 2>&1`
+ else
+ closeall
+ return
+ end
+ rescue
+ end
+ @files.delete(filename)
+ end
+ end
+
+ def PDFview.closeall
+ begin
+ result = `pdfclose --all 2>&1`
+ rescue
+ end
+ @files.clear
+ end
+
+ def PDFview.fullname(name)
+ name + if name =~ /\.pdf$/ then '' else '.pdf' end
+ end
+
+end
+
+puts ('' || false)
+
+# PDFview.open("t:/document/show-exa.pdf")
+# PDFview.open("t:/document/show-gra.pdf")
+# PDFview.close("t:/document/show-exa.pdf")
+# PDFview.close("t:/document/show-gra.pdf")
diff --git a/scripts/context/ruby/base/state.rb b/scripts/context/ruby/base/state.rb
new file mode 100644
index 000000000..f57231592
--- /dev/null
+++ b/scripts/context/ruby/base/state.rb
@@ -0,0 +1,75 @@
+require "md5"
+
+# todo: register omissions per file
+
+class FileState
+
+ def initialize
+ @states = Hash.new
+ @omiter = Hash.new
+ end
+
+ def reset
+ @states.clear
+ @omiter.clear
+ end
+
+ def register(filename,omit=nil)
+ unless @states.key?(filename) then
+ @states[filename] = Array.new
+ @omiter[filename] = omit
+ end
+ @states[filename] << checksum(filename,@omiter[filename])
+ end
+
+ def update(filename=nil)
+ [filename,@states.keys].flatten.compact.uniq.each do |fn|
+ register(fn)
+ end
+ end
+
+ def inspect(filename=nil)
+ result = ''
+ [filename,@states.keys].flatten.compact.uniq.sort.each do |fn|
+ if @states.key?(fn) then
+ result += "#{fn}: #{@states[fn].inspect}\n"
+ end
+ end
+ result
+ end
+
+ def changed?(filename)
+ if @states.key?(filename) then
+ n = @states[filename].length
+ if n>1 then
+ changed = @states[filename][n-1] != @states[filename][n-2]
+ else
+ changed = true
+ end
+ else
+ changed = true
+ end
+ return changed
+ end
+
+ def checksum(filename,omit=nil)
+ sum = ''
+ begin
+ if FileTest.file?(filename) && (data = IO.read(filename)) then
+ data.gsub!(/\n.*?(#{[omit].flatten.join('|')}).*?\n/ms,"\n") if omit
+ sum = MD5.new(data).hexdigest.upcase
+ end
+ rescue
+ sum = ''
+ end
+ return sum
+ end
+
+ def stable?
+ @states.keys.each do |s|
+ return false if changed?(s)
+ end
+ return true
+ end
+
+end
diff --git a/scripts/context/ruby/xmpl/switch.rb b/scripts/context/ruby/base/switch.rb
index de747bbd5..d011a78ae 100644
--- a/scripts/context/ruby/xmpl/switch.rb
+++ b/scripts/context/ruby/base/switch.rb
@@ -1,21 +1,26 @@
-# module : xmpl/switch
-# copyright : PRAGMA Publishing On Demand
-# version : 1.00 - 2002
+# module : base/switch
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2002-2005
# author : Hans Hagen
#
-# project : eXaMpLe
+# project : ConTeXt / eXaMpLe
# concept : Hans Hagen
# info : j.hagen@xs4all.nl
-# www : www.pragma-pod.com / www.pragma-ade.com
+# www : www.pragma-ade.com
# we cannot use getoptlong because we want to be more
-# tolerant; also we want to be case insensitive.
+# tolerant; also we want to be case insensitive (2002).
# we could make each option a class itself, but this is
# simpler; also we can put more in the array
# beware: regexps/o in methods are optimized globally
+require "rbconfig"
+
+$mswindows = Config::CONFIG['host_os'] =~ /mswin/
+$separator = File::PATH_SEPARATOR
+
class String
def has_suffix?(suffix)
@@ -24,6 +29,48 @@ class String
end
+# may move to another module
+
+class File
+
+ def File.needsupdate(oldname,newname)
+ begin
+ if $mswindows then
+ return File.stat(oldname).mtime > File.stat(newname).mtime
+ else
+ return File.stat(oldname).mtime != File.stat(newname).mtime
+ end
+ rescue
+ return true
+ end
+ end
+
+ def File.syncmtimes(oldname,newname)
+ begin
+ if $mswindows then
+ # does not work (yet)
+ t = File.mtime(oldname) # i'm not sure if the time is frozen, so we do it here
+ File.utime(0,t,oldname,newname)
+ else
+ t = File.mtime(oldname) # i'm not sure if the time is frozen, so we do it here
+ File.utime(0,t,oldname,newname)
+ end
+ rescue
+ end
+ end
+
+ def File.timestamp(name)
+ begin
+ "#{File.stat(name).mtime}"
+ rescue
+ return 'unknown'
+ end
+ end
+
+end
+
+# main thing
+
module CommandBase
# this module can be used as a mixin in a command handler
@@ -43,28 +90,43 @@ module CommandBase
# only works in 1.8
#
# def report(*str)
- # @logger.report(str)
+ # @logger.report(str)
# end
#
# def version # just a bit of playing with defs
- # report(@banner.join(' - '))
- # def report(*str)
- # @logger.report
- # @logger.report(str)
- # def report(*str)
- # @logger.report(str)
- # end
- # end
- # def version
- # end
+ # report(@banner.join(' - '))
+ # def report(*str)
+ # @logger.report
+ # @logger.report(str)
+ # def report(*str)
+ # @logger.report(str)
+ # end
+ # end
+ # def version
+ # end
# end
def report(*str)
+ initlogger ; @logger.report(str)
+ end
+
+ def debug(*str)
+ initlogger ; @logger.debug(str)
+ end
+
+ def error(*str)
+ initlogger ; @logger.error(str)
+ end
+
+ def initlogger
if @forcenewline then
@logger.report
@forcenewline = false
end
- @logger.report(str)
+ end
+
+ def logger
+ @logger
end
def version # just a bit of playing with defs
@@ -89,6 +151,18 @@ module CommandBase
def option(key)
@commandline.option(key)
end
+ def oneof(*key)
+ @commandline.oneof(*key)
+ end
+
+ def globfiles(pattern='*',suffix=nil)
+ @commandline.setarguments([pattern].flatten)
+ if files = findfiles(suffix) then
+ @commandline.setarguments(files)
+ else
+ @commandline.setarguments
+ end
+ end
private
@@ -190,7 +264,11 @@ class CommandLine
end
- def register (option,shortcut,kind,default=false,action=false,helptext='')
+ def setarguments(args=[])
+ @arguments = if args then args else [] end
+ end
+
+ def register(option,shortcut,kind,default=false,action=false,helptext='')
if kind == FLAG then
@options[option] = default
elsif not default then
@@ -316,8 +394,45 @@ class CommandLine
end
end
- def option(str)
- @options[str] # @options.fetch(str,'')
+ def option(str,default=nil)
+ if @options.key?(str) then
+ @options[str]
+ elsif default then
+ default
+ else
+ @options[str]
+ end
+ end
+
+ def checkedoption(str,default='')
+ if @options.key?(str) then
+ if @options[str].empty? then default else @options[str] end
+ else
+ default
+ end
+ end
+
+ def foundoption(str,default='')
+ str = str.split(',') if str.class == String
+ str.each do |s|
+ return str if @options.key?(str)
+ end
+ return default
+ end
+
+ def oneof(*key)
+ [*key].flatten.compact.each do |k|
+ return true if @options.key?(k) && @options[k]
+ end
+ return false
+ end
+
+ def setoption(str,value)
+ @options[str] = value
+ end
+
+ def getoption(str,value='') # value ?
+ @options[str]
end
def argument(n=0)
@@ -336,7 +451,7 @@ class CommandLine
end
end
- # a few local methods, cannot be defined nested (yet)
+ # a few local methods, cannot be defined nested (yet)
private
@@ -387,11 +502,6 @@ class CommandLine
end
if foundkey then
@provided[foundkey] = true
- # if value.class == FalseClass then
- # @options[foundkey] = true
- # else
- # @options[foundkey] = if foundkind == VALUE then cleanvalue(value) else true end
- # end
if foundkind == VALUE then
@options[foundkey] = cleanvalue(value)
else
diff --git a/scripts/context/ruby/base/system.rb b/scripts/context/ruby/base/system.rb
new file mode 100644
index 000000000..ed8c2756e
--- /dev/null
+++ b/scripts/context/ruby/base/system.rb
@@ -0,0 +1,102 @@
+# module : base/system
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2002-2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+require "rbconfig"
+
+module System
+
+ @@mswindows = Config::CONFIG['host_os'] =~ /mswin/
+ @@binpaths = ENV['PATH'].split(File::PATH_SEPARATOR)
+ @@binsuffixes = if $mswindows then ['.exe','.com','.bat'] else ['','.sh','.csh'] end
+ @@located = Hash.new
+ @@binnames = Hash.new
+
+ if @@mswindows then
+ @@binnames['ghostscript'] = ['gswin32c.exe','gs.cmd','gs.bat']
+ @@binnames['imagemagick'] = ['imagemagick.exe','convert.exe']
+ @@binnames['inkscape'] = ['inkscape.exe']
+ else
+ @@binnames['ghostscript'] = ['gs']
+ @@binnames['imagemagick'] = ['convert']
+ @@binnames['inkscape'] = ['inkscape']
+ end
+
+
+ def System.null
+ if @@mswindows then 'nul' else '/dev/null/' end
+ end
+
+ def System.binnames(str)
+ if @@binnames.key?(str) then
+ @@binnames[str]
+ else
+ [str]
+ end
+ end
+
+ def System.locatedprogram(program)
+ if @@located.key?(program) then
+ return @@located[program]
+ else
+ System.binnames(program).each do |binname|
+ if binname =~ /\..*$/io then
+ @@binpaths.each do |path|
+ if FileTest.file?(str = File.join(path,binname)) then
+ return @@located[program] = str
+ end
+ end
+ end
+ binname.gsub!(/\..*$/io, '')
+ @@binpaths.each do |path|
+ @@binsuffixes.each do |suffix|
+ if FileTest.file?(str = File.join(path,"#{binname}#{suffix}")) then
+ return @@located[program] = str
+ end
+ end
+ end
+ end
+ end
+ return @@located[program] = "texmfstart #{program}"
+ end
+
+ def System.command(program,arguments='')
+ if program =~ /^(.*?) (.*)$/ then
+ program = System.locatedprogram($1) + ' ' + $2
+ else
+ program = System.locatedprogram(program)
+ end
+ program = program + ' ' + arguments if ! arguments.empty?
+ program.gsub!(/\s+/io, ' ')
+ program.gsub!(/(\.\/)+/io, '')
+ program.gsub!(/\\/io, '/')
+ return program
+ end
+
+ def System.run(program,arguments='',pipe=false,collect=false)
+ if pipe then
+ if collect then
+ `#{System.command(program,arguments)} 2>&1`
+ else
+ `#{System.command(program,arguments)}`
+ end
+ else
+ system(System.command(program,arguments))
+ end
+ end
+
+ def System.pipe(program,arguments='',collect=false)
+ System.run(program,arguments,true)
+ end
+
+ def System.safepath(path)
+ if path.match(/ /o) then "\"#{path}\"" else path end
+ end
+
+end
diff --git a/scripts/context/ruby/base/tex.rb b/scripts/context/ruby/base/tex.rb
new file mode 100644
index 000000000..e9f66ea8d
--- /dev/null
+++ b/scripts/context/ruby/base/tex.rb
@@ -0,0 +1,1281 @@
+# module : base/tex
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+# todo: write systemcall for mpost to file so that it can be run
+# faster
+
+require 'base/variables'
+require 'base/kpse'
+require 'base/system'
+require 'base/state'
+require 'base/pdf'
+require 'base/file'
+
+class TEX
+
+ # The make-part of this class was made on a rainy day while listening
+ # to "10.000 clowns on a rainy day" by Jan Akkerman. Unfortunately the
+ # make method is not as swinging as this live cd.
+
+ include Variables
+
+ @@texengines = Hash.new
+ @@mpsengines = Hash.new
+ @@backends = Hash.new
+ @@runoptions = Hash.new
+ @@texformats = Hash.new
+ @@mpsformats = Hash.new
+ @@prognames = 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
+
+ ['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','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
+
+ @@runoptions['xetex'] = ['--no-pdf']
+
+ @@booleanvars = [
+ 'batchmode', 'nonstopmode', 'fastmode', 'fastdisabled', 'silentmode', 'final',
+ 'paranoid', 'notparanoid', 'nobanner', 'once', 'allpatterrns',
+ 'nompmode', 'nomprun', 'automprun',
+ 'nomapfiles',
+ 'arrange', 'noarrange',
+ 'forcexml', 'foxet',
+ 'mpyforce', 'forcempy',
+ 'forcetexutil', 'texutil',
+ 'globalfile', 'autopath',
+ 'purge', 'pdfopen', 'simplerun',
+ ]
+ @@stringvars = [
+ 'modefile', 'result', 'suffix', 'response', 'path',
+ 'filters', 'usemodules', 'environments', 'separation', 'setuppath',
+ 'arguments', 'input', 'output', 'randomseed', 'modes', 'filename',
+ 'modefile',
+ ]
+ @@standardvars = [
+ 'mainlanguage', 'bodyfont', 'language'
+ ]
+ @@knownvars = [
+ 'engine', 'distribution', 'texformats', 'mpsformats', 'progname', 'interface',
+ 'runs', 'backend'
+ ]
+
+ @@extrabooleanvars = []
+ @@extrastringvars = []
+
+ def booleanvars
+ [@@booleanvars,@@extrabooleanvars].flatten
+ end
+ def stringvars
+ [@@stringvars,@@extrastringvars].flatten
+ end
+ def standardvars
+ @@standardvars
+ end
+ def knownvars
+ @@knownvars
+ end
+
+ def setextrastringvars(vars)
+ @@extrastringvars << vars
+ end
+ def setextrabooleanvars(vars)
+ @@extrabooleanvars << vars
+ end
+
+ @@temprunfile = 'texexec'
+ @@temptexfile = 'texexec.tex'
+
+ def initialize(logger)
+ @logger = logger
+ @cleanups = Array.new
+ @variables = Hash.new
+ @startuptime = Time.now
+ # options
+ booleanvars.each do |k|
+ setvariable(k,false)
+ end
+ stringvars.each do |k|
+ setvariable(k,'')
+ end
+ standardvars.each do |k|
+ setvariable(k,'standard')
+ end
+ setvariable('distribution', Kpse.distribution)
+ setvariable('texformats', defaulttexformats)
+ setvariable('mpsformats', defaultmpsformats)
+ setvariable('progname', 'context')
+ setvariable('interface', 'standard')
+ setvariable('engine', 'standard')
+ setvariable('backend', 'pdftex')
+ setvariable('runs', '8')
+ setvariable('randomseed', rand(1440))
+ # files
+ setvariable('files', [])
+ end
+
+ def runtime
+ Time.now - @startuptime
+ end
+
+ def reportruntime
+ report("runtime: #{runtime}")
+ end
+
+ def inspect(name=nil)
+ if ! name || name.empty? then
+ name = [booleanvars,stringvars,standardvars,knownvars]
+ end
+ [name].flatten.each do |n|
+ if str = getvariable(n) then
+ unless (str.class == String) && str.empty? then
+ report("option '#{n}' is set to '#{str}'")
+ end
+ end
+ end
+ end
+
+ def tempfilename(suffix='')
+ @@temprunfile + if suffix.empty? then '' else ".#{suffix}" end
+ end
+
+ def cleanup
+ @cleanups.each do |name|
+ begin
+ File.delete(name) if FileTest.file?(name)
+ rescue
+ report("unable to delete #{name}")
+ end
+ end
+ end
+
+ def cleanuptemprunfiles
+ begin
+ Dir.glob("#{@@temprunfile}*").each do |name|
+ if File.file?(name) && (File.splitname(name)[1] !~ /(pdf|dvi)/o) then
+ begin File.delete(name) ; rescue ; end
+ end
+ end
+ rescue
+ end
+ end
+
+ def texengines
+ @@texengines.keys.sort
+ end
+
+ def mpsengines
+ @@mpsengines.keys.sort
+ end
+
+ def backends
+ @@backends.keys.sort
+ end
+
+ def texformats
+ @@texformats.keys.sort
+ end
+
+ def mpsformats
+ @@mpsformats.keys.sort
+ end
+
+ def defaulttexformats
+ ['en','nl','mptopdf']
+ end
+
+ def defaultmpsformats
+ ['metafun']
+ end
+
+ def runoptions(engine)
+ if @@runoptions.key?(engine) then @@runoptions[engine].join(' ') else '' end
+ end
+
+ # private
+
+ def cleanuplater(name)
+ begin
+ @cleanups.push(File.expand_path(name))
+ rescue
+ @cleanups.push(name)
+ end
+ end
+
+ def openedfile(name)
+ cleanuplater(name) if f = File.open(name, 'w')
+ return f
+ end
+
+ def prefixed(format,engine)
+ case engine
+ when /etex|eetex|pdfetex|pdfeetex|pdfxtex|xpdfetex|eomega|aleph|xetex/io then
+ "*#{format}"
+ else
+ format
+ end
+ end
+
+ def quoted(str)
+ if str =~ /^[^\"].* / then "\"#{str}\"" else str end
+ end
+
+ def getarrayvariable(str='')
+ str = getvariable(str)
+ 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 validsomething(str,something)
+ if str then
+ list = [str].flatten.collect do |s|
+ something[s]
+ end .compact.uniq
+ if list.length>0 then
+ if str.class == String then list.first else list end
+ else
+ false
+ end
+ else
+ false
+ end
+ end
+
+ def validbackend(str)
+ if str && @@backends.key?(str) then
+ @@backends[str]
+ else
+ @@backends['standard']
+ end
+ end
+
+ def validprogname(str,engine='standard')
+ if str && @@prognames.key?(str) then
+ @@prognames[str]
+ elsif (engine != 'standard') && @@prognames.key?(engine) then
+ @@prognames[engine]
+ else
+ str
+ end
+ end
+
+ # we no longer support the & syntax
+
+ def formatflag(engine=nil,format=nil)
+ case getvariable('distribution')
+ when 'standard' then prefix = "--fmt"
+ when /web2c/io then prefix = web2cformatflag(engine)
+ when /miktex/io then prefix = "--undump"
+ else return ""
+ end
+ if format then
+ if engine then
+ "#{prefix}=#{engine}/#{format}"
+ else
+ "#{prefix}=#{format}"
+ end
+ else
+ prefix
+ end
+ end
+
+ def web2cformatflag(engine=nil)
+ # funny that we've standardized on the fmt suffix (at the cost of
+ # upward compatibility problems) but stuck to the bas/mem/fmt flags
+ if engine then
+ case validmpsengine(engine)
+ when /mpost/ then "--mem"
+ when /mfont/ then "--bas"
+ else "--fmt"
+ end
+ else
+ "--fmt"
+ end
+ end
+
+ def prognameflag(progname=nil)
+ case getvariable('distribution')
+ when 'standard' then prefix = "--progname"
+ when /web2c/io then prefix = "--progname"
+ when /miktex/io then prefix = "--alias"
+ else return ""
+ end
+ if progname then
+ if progname = validprogname(progname) then
+ "#{prefix}=#{progname}"
+ else
+ ""
+ end
+ else
+ prefix
+ end
+ 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")
+ end
+
+ # will go to context/process context/listing etc
+
+ def contextversion # ook elders gebruiken
+ filename = Kpse.found('context.tex')
+ version = 'unknown'
+ begin
+ if FileTest.file?(filename) && IO.read(filename).match(/\\contextversion\{(\d+\.\d+\.\d+)\}/) then
+ version = $1
+ end
+ rescue
+ end
+ return version
+ end
+
+ def makeformats
+ # goody
+ if getvariable('texformats') == 'standard' then
+ setvariable('texformats',[getvariable('interface')]) unless getvariable('interface').empty?
+ end
+ # prepare
+ texformats = validtexformat(getarrayvariable('texformats'))
+ mpsformats = validmpsformat(getarrayvariable('mpsformats'))
+ texengine = validtexengine(getvariable('texengine'))
+ mpsengine = validmpsengine(getvariable('mpsengine'))
+ # save current path
+ savedpath = Dir.getwd
+ # generate tex formats
+ if texformats && texengine && (progname = validprogname(getvariable('progname'),texengine)) then
+ report("using tex engine #{texengine}")
+ texformatpath = Kpse.formatpath(texengine,true)
+ # can be empty, to do
+ report("using tex format path #{texformatpath}")
+ begin
+ Dir.chdir(texformatpath)
+ rescue
+ end
+ if texformats.length > 0 then
+ 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
+ end
+ else
+ texformatpath = ''
+ end
+ # generate mps formats
+ if mpsformats && mpsengine && (progname = validprogname(getvariable('progname'),mpsengine)) then
+ report("using mp engine #{mpsengine}")
+ mpsformatpath = Kpse.formatpath(mpsengine,false)
+ report("using mps format path #{mpsformatpath}")
+ begin
+ 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
+ end
+ else
+ mpsformatpath = ''
+ end
+ # check for problems
+ report("tex engine path: #{texformatpath}") unless texformatpath.empty?
+ report("mps engine path: #{mpsformatpath}") unless mpsformatpath.empty?
+ [['fmt','tex'],['mem','mps']].each do |f|
+ [[texformatpath,'global'],[mpsformatpath,'global'],[savedpath,'current']].each do |p|
+ begin
+ Dir.chdir(p[0])
+ rescue
+ else
+ Dir.glob("*.#{f[0]}").each do |file|
+ report("#{f[1]}format: #{filestate(file)} > #{File.expand_path(file)}")
+ end
+ end
+ end
+ end
+ # to be sure, go back to current path
+ begin
+ Dir.chdir(savedpath)
+ rescue
+ end
+ # finalize
+ cleanup
+ reportruntime
+ end
+
+ def checkcontext
+
+ # todo : report texmf.cnf en problems
+
+ # basics
+ report("current distribution: #{Kpse.distribution}")
+ report("context source date: #{contextversion}")
+ formatpaths = Kpse.formatpaths
+ globpattern = "**/{#{formatpaths.join(',')}}/*/*.{fmt,efmt,ofmt,xfmt,mem}"
+ report("format path: #{formatpaths.join(' ')}")
+ # utilities
+ report
+ ['texexec','texutil','ctxtools'].each do |program|
+ result = `texmfstart #{program} --help`
+ result.sub!(/.*?(#{program}[^\n]+)\n.*/mi) do $1 end
+ report("#{result}")
+ end
+ # formats
+ cleanuptemprunfiles
+ if formats = Dir.glob(globpattern) then
+ formats.sort.each do |name|
+ cleanuptemprunfiles
+ if f = open(tempfilename('tex'),'w') then
+ # kind of aleph-run-out-of-par safe
+ f << "\\starttext\n"
+ f << " \\relax test \\relax\n"
+ f << "\\stoptext\n"
+ f << "\\endinput\n"
+ f.close
+ if FileTest.file?(tempfilename('tex')) then
+ format = File.basename(name)
+ engine = if name =~ /(pdfetex|aleph|xetex)[\/\\]#{format}/ then $1 else '' end
+ if engine.empty? then
+ engineflag = ""
+ else
+ engineflag = "--engine=#{$1}"
+ end
+ case format
+ when /cont\-([a-z]+)/ then
+ interface = $1.sub(/cont\-/,'')
+ report
+ report("testing interface #{interface}")
+ flags = ['--process','--batch','--once',"--interface=#{interface}",engineflag]
+# to be adapted !
+result = Kpse.pipescript('newtexexec',tempfilename,flags)
+# to just texexec
+ 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)
+ end
+ end
+ if logdata =~ /^\s*(ConTeXt)\s+(.*int:\s+[a-z]+.*?)\s*$/mois then
+ report("#{$1} #{$2}".gsub(/\s+/,' ').strip)
+ end
+ else
+ report("format #{format} does not work")
+ end
+ when /metafun/ then
+ # todo
+ when /mptopdf/ then
+ # todo
+ end
+ else
+ report("error in creating #{tempfilename('tex')}")
+ end
+ end
+ cleanuptemprunfiles
+ end
+ end
+ cleanuptemprunfiles
+
+ end
+
+ private
+
+ def makeuserfile
+ language = getvariable('language')
+ mainlanguage = getvariable('mainlanguage')
+ bodyfont = getvariable('bodyfont')
+ if f = openedfile("cont-fmt.tex") then
+ f << "\\unprotect"
+ case language
+ when 'all' then
+ f << "\\preloadallpatterns\n"
+ when '' then
+ f << "% no language presets\n"
+ when 'standard'
+ f << "% using defaults\n"
+ else
+ languages = language.split(',')
+ languages.each do |l|
+ f << "\\installlanguage[\\s!#{l}][\\c!state=\\v!start]\n"
+ end
+ mainlanguage = languages.first
+ end
+ unless mainlanguage == 'standard' then
+ f << "\\setupcurrentlanguage[\\s!#{mainlanguage}]\n";
+ end
+ unless bodyfont == 'standard' then
+ # ~ will become obsolete when lmr is used
+ f << "\\definetypescriptsynonym[cmr][#{bodyfont}]"
+ # ~ is already obsolete for some years now
+ f << "\\definefilesynonym[font-cmr][font-#{bodyfont}]\n"
+ end
+ f << "\\protect\n"
+ f << "\\endinput\n"
+ f.close
+ end
+ end
+
+ def makeresponsefile
+ interface = getvariable('interface')
+ if f = openedfile("mult-def.tex") then
+ case interface
+ when 'standard' then
+ f << "% using default response interface"
+ else
+ f << "\\def\\currentresponses\{#{interface}\}\n"
+ end
+ f << "\\endinput\n"
+ f.close
+ end
+ end
+
+ private # will become baee/context
+
+ @@preamblekeys = [
+ ['tex','texengine'],['program','texengine'],
+ ['ctx','ctxfilter'],['translate','ctxfilter'],
+ ['output','backend'],['modes','modes'],['version','contextversion'],
+ ['format','texformat'],['interface','texformat']
+ ]
+
+ def scantexpreamble(filename)
+ if tex = File.open(filename) then
+ while str = tex.gets.chomp do
+ if str =~ /^\%\s*(.*)/o then
+ vars = Hash.new
+ $1.split(/\s+/o).each do |s|
+ k, v = s.split('=')
+ vars[k] = v
+ end
+ @@preamblekeys.each do |v|
+ setvariable(v[1],vars[v[0]]) if vars.key?(v[0])
+ end
+ else
+ break
+ end
+ end
+ tex.close
+ end
+ end
+
+ def scantexcontent(filename)
+ if tex = File.open(filename) then
+ while str = tex.gets.chomp do
+ case str
+ when /^\%/o then
+ # next
+ when /\\(starttekst|stoptekst|startonderdeel|startdocument|startoverzicht)/o then
+ setvariable('texformat','nl') ; break
+ when /\\(stelle|verwende|umgebung|benutze)/o then
+ setvariable('texformat','de') ; break
+ when /\\(stel|gebruik|omgeving)/o then
+ setvariable('texformat','nl') ; break
+ when /\\(use|setup|environment)/o then
+ setvariable('texformat','en') ; break
+ when /\\(usa|imposta|ambiente)/o then
+ setvariable('texformat','it') ; break
+ when /(height|width|style)=/o then
+ setvariable('texformat','en') ; break
+ when /(hoehe|breite|schrift)=/o then
+ setvariable('texformat','de') ; break
+ when /(hoogte|breedte|letter)=/o then
+ setvariable('texformat','nl') ; break
+ when /(altezza|ampiezza|stile)=/o then
+ setvariable('texformat','it') ; break
+ when /externfiguur/o then
+ setvariable('texformat','nl') ; break
+ when /externalfigure/o then
+ setvariable('texformat','en') ; break
+ when /externeabbildung/o then
+ setvariable('texformat','de') ; break
+ when /figuraesterna/o then
+ setvariable('texformat','it') ; break
+ end
+ end
+ tex.close
+ end
+
+ end
+
+ private # will become base/context
+
+ def pushresult(filename,resultname)
+ fname = File.unsuffixed(filename)
+ rname = File.unsuffixed(resultname)
+ if ! rname.empty? && (rname != fname) then
+ report("outputfile #{result}")
+ ['tuo','log','dvi','pdf'].each do |s|
+ File.silentrename(File.suffixed(fname,s),File.suffixed('texexec',s))
+ end
+ ['tuo'].each do |s|
+ File.silentrename(File.suffixed(rname,s),File.suffixed(fname,s)) if FileTest(suffixed(rname,s))
+ end
+ end
+ end
+
+ def popresult(filename,resultname)
+ fname = File.unsuffixed(filename)
+ rname = File.unsuffixed(resultname)
+ if ! rname.empty? && (rname != fname) then
+ report("renaming #{fname} to #{rname}")
+ ['tuo','log','dvi','pdf'].each do |s|
+ File.silentrename(File.suffixed(fname,s),File.suffixed(rname,s))
+ end
+ report("restoring #{fname}")
+ unless $fname == 'texexec' then
+ ['tuo','log','dvi','pdf'].each do |s|
+ File.silentrename(File.suffixed('texexec',s),File.suffixed(fname,s))
+ end
+ end
+ end
+ end
+
+ def makestubfile(jobname,jobsuffix,forcexml=false)
+ if tmp = File.open(File.suffixed(jobname,'run'),'w') then
+ fullname = File.suffixed(jobname,jobsuffix)
+ tmp << "\\starttext\n"
+ if forcexml then
+ if FileTest.file?(fullname) && (xml = File.open(fullname)) then
+ xml.each do |line|
+ if line =~ /<[a-z]+/io then
+ 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
+ end
+ end
+ end
+ end
+ xml.close
+ end
+ tmp << "\\processXMLfilegrouped{#{fullname}}\n"
+ else
+ tmp << "\\processfile{#{fullname}}\n"
+ end
+ tmp << "\\stoptext\n"
+ tmp.close
+ jobsuffix = "run"
+ end
+ return jobsuffix
+ end
+
+end
+
+class TEX
+
+ def processtex # much to do: mp, xml, runs etc
+ setvariable('texformats',[getvariable('interface')]) unless getvariable('interface').empty?
+ getarrayvariable('files').each do |filename|
+ setvariable('filename',filename)
+ report("processing document '#{filename}'")
+ processcontextfile
+ end
+ reportruntime
+ end
+
+ def processmptex
+ getarrayvariable('files').each do |filename|
+ setvariable('filename',filename)
+ report("processing graphic '#{filename}'")
+ runtexmp(filename)
+ end
+ reportruntime
+ end
+
+ def processmpxtex
+ getarrayvariable('files').each do |filename|
+ setvariable('filename',filename)
+ report("processing text of graphic '#{filename}'")
+ processmpx(filename,true)
+ end
+ reportruntime
+ end
+
+ def makeoptionfile(jobname, jobsuffix, finalrun, fastdisabled, kindofrun)
+ if opt = File.open(File.suffixed(jobname,'top'),'w') then
+ # local handies
+ opt << "\% $JobName.top\n"
+ opt << "\\unprotect\n"
+ opt << "\\setupsystem[\\c!n=#{kindofrun}]\n"
+ opt << "\\def\\MPOSTformatswitch\{#{prognameflag('metafun')} #{formatflag('mpost')}=\}"
+ if getvariable('batchmode') then
+ opt << "\\batchmode\n"
+ end
+ if getvariable('nonstopmode') then
+ opt << "\\nonstopmode\n"
+ end
+ if getvariable('paranoid') then
+ opt << "\\def\\maxreadlevel{1}\n"
+ end
+ if (str = File.unixfied(getvariable('modefile'))) && ! str.empty? then
+ opt << "\\readlocfile{#{str}}{}{}\n"
+ end
+ if (str = File.unixfied(getvariable('result'))) && ! str.empty? then
+ opt << "\\setupsystem[file=#{str}]\n"
+ elsif (str = getvariable('suffix')) && ! str.empty? then
+ opt << "\\setupsystem[file=#{File.suffixed(jobname,str,nil)}]\n"
+ end
+ if (str = File.unixfied(getvariable('path'))) && ! str.empty? then
+ opt << "\\usepath[#{str}]\n" unless str.empty?
+ end
+ if (str = getvariable('mainlanguage').downcase) && ! str.empty? && ! str.standard? then
+ opt << "\\setuplanguage[#{str}]\n"
+ end
+ if str = validbackend(getvariable('backend')) then
+ opt << "\\setupoutput[#{str}]\n"
+ end
+ if getvariable('color') then
+ opt << "\\setupcolors[\\c!state=\\v!start]\n"
+ end
+ if getvariable('nompmode') || getvariable('nomprun') || getvariable('automprun') then
+ opt << "\\runMPgraphicsfalse\n"
+ end
+ if getvariable('fastmode') && ! getvariable('fastdisabled') then
+ opt << "\\fastmode\n"
+ end
+ if getvariable('silent') then
+ opt << "\\silentmode\n"
+ end
+ if (str = getvariable('separation')) && ! str.empty? then
+ opt << "\\setupcolors[\\c!split=#{str}]\n"
+ end
+ if (str = getvariable('setuppath')) && ! str.empty? then
+ opt << "\\setupsystem[\\c!directory=\{#{str}\}]\n"
+ end
+ if (str = getvariable('paperformat')) && ! str.empty? && ! str.standard? then
+ if str =~ /^([a-z]+\d+)([a-z]+\d+)$/io then # A5A4 A4A3 A2A1 ...
+ opt << "\\setuppapersize[#{$1.upcase}][#{$2.upcase}]\n"
+ else # ...*...
+ pf = str.upcase.split(/[x\*]/o)
+ pf << pf[0] if pd.size == 1
+ opt << "\\setuppapersize[#{pf[0]}][#{pf[1]}]\n"
+ end
+ end
+ if (str = getvariable('background')) && ! str.empty? then
+ opt << "\\defineoverlay[whatever][{\\externalfigure[#{str}][\\c!factor=\\v!max]}]\n"
+ opt << "\\setupbackgrounds[\\v!page][\\c!background=whatever]\n"
+ end
+ if getvariable('centerpage') then
+ opt << "\\setuplayout[\\c!location=\\v!middle,\\c!marking=\\v!on]\n"
+ end
+ if getvariable('nomapfiles') then
+ opt << "\\disablemapfiles\n"
+ end
+ if getvariable('noarrange') then
+ opt << "\\setuparranging[\\v!disable]\n"
+ elsif getvariable('arrange') then
+ arrangement = Array.new
+ if finalrun then
+ arrangement << "\\v!doublesided" unless getvariable('noduplex')
+ case printformat
+ when '' then arrangement << "\\v!normal"
+ when /.*up/oi then arrangement << "\\v!rotated"
+ when /.*down/oi then arrangement << ["2DOWN","\\v!rotated"]
+ when /.*side/oi then arrangement << ["2SIDE","\\v!rotated"]
+ end
+ else
+ arrangement << "\\v!disable"
+ end
+ opt << "\\setuparranging[#{arrangement.flatten.join(',')}]\n" if arrangement.size > 0
+ end
+ if (str = getvariable('modes')) && ! str.empty? then
+ opt << "\\enablemode[#{modes}]\n"
+ end
+ if (str = getvariable('arguments')) && ! str.empty? then
+ opt << "\\setupenv[#{str}]\n"
+ end
+ if (str = getvariable('randomseed')) && ! str.empty? then
+ opt << "\\setupsystem[\\c!random=#{str}]\n"
+ end
+ if (str = getvariable('input')) && ! str.empty? then
+ opt << "\\setupsystem[inputfile=#{str}]\n"
+ else
+ opt << "\\setupsystem[inputfile=#{File.suffixed(jobname,jobsuffix)}]\n"
+ end
+ if (str = getvariable('pages')) && ! str.empty? then
+ if str.downcase == 'odd' then
+ opt << "\\chardef\\whichpagetoshipout=1\n"
+ elsif str.downcase == 'even' then
+ opt << "\\chardef\\whichpagetoshipout=2\n"
+ else
+ pagelist = Array.new
+ str.split(/\,/).each do |page|
+ pagerange = page.split(/(\:|\.\.)/o )
+ if pagerange.size > 1 then
+ pagerange.first.to_i.upto(pagerange.last.to_i) do |p|
+ pagelist << p.to_s
+ end
+ else
+ pagelist << page
+ end
+ end
+ opt << "\\def\\pagestoshipout\{pagelist.join(',')\}\n";
+ end
+ end
+ opt << "\\protect\n";
+ begin
+ getvariable('filters').split(',').each do |f| opt << "\\useXMLfilter[#{f}]\n" end
+ rescue
+ end
+ begin
+ getvariable('usemodules').split(',').each do |m| opt << "\\usemodule[#{m}]\n" end
+ rescue
+ end
+ begin
+ getvariable('environments').split(',').each do |e| opt << "\\usemodule[#{e}]\n" end
+ rescue
+ end
+ opt << "\\endinput\n"
+ opt.close
+ end
+ end
+
+ def takeprecautions
+ ENV['MPXCOMAND'] = '0' # else loop
+ if getvariable('paranoid') then
+ ENV['SHELL_ESCAPE'] = ENV['SHELL_ESCAPE'] || 'f'
+ ENV['OPENOUT_ANY'] = ENV['OPENOUT_ANY'] || 'p'
+ ENV['OPENIN_ANY'] = ENV['OPENIN_ANY'] || 'p'
+ else
+ ENV['SHELL_ESCAPE'] = ENV['SHELL_ESCAPE'] || 't'
+ ENV['OPENOUT_ANY'] = ENV['OPENOUT_ANY'] || 'p'
+ ENV['OPENIN_ANY'] = ENV['OPENIN_ANY'] || 'a'
+ end
+ if (ENV['OPENIN_ANY'] == 'p') || (ENV['OPENOUT_ANY'] == 'p') then
+ setvariable('paranoid', true)
+ end
+ if ENV.key?('SHELL_ESCAPE') && (ENV['SHELL_ESCAPE'] == 'f') then
+ setvariable('automprun',true)
+ end
+ ['TXRESOURCES','MPRESOURCES','MFRESOURCES'].each do |res|
+ [getvariable('runpath'),getvariable('path')].each do |pat|
+ unless pat.empty? then
+ if ENV.key?(res) then
+ ENV[res] = if ENV[res].empty? then pat else pat + ":" + ENV[res] end
+ else
+ ENV[res] = pat
+ end
+ end
+ end
+ end
+ end
+
+ def runtex(filename)
+ texengine = validtexengine(getvariable('texengine'))
+ texformat = validtexformat(getarrayvariable('texformats').first)
+ progname = validprogname(getvariable('progname'))
+ report("tex engine: #{texengine}")
+ report("tex format: #{texformat}")
+ report("progname: #{progname}")
+ if texengine && texformat && progname then
+ command = [quoted(texengine),prognameflag(progname),formatflag(texengine,texformat),runoptions(texengine),filename].join(' ')
+ report(command) if getvariable('verbose')
+ system(command)
+ else
+ false
+ end
+ end
+
+ def runmp(filename)
+ mpsengine = validmpsengine(getvariable('mpsengine'))
+ 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(' ')
+ report(command) if getvariable('verbose')
+ system(command)
+ else
+ false
+ end
+ end
+
+ def runtexmp(filename,filetype='')
+ mpfile = File.suffixed(filename,filetype,'mp')
+ if File.atleast?(mpfile,25) then
+ # first run needed
+ File.silentdelete(File.suffixed(mpfile,'mpt'))
+ doruntexmp(mpfile,false)
+ mpgraphics = checkmpgraphics(mpfile)
+ mplabels = checkmplabels(mpfile)
+ if mpgraphics || mplabels then
+ # second run needed
+ doruntexmp(mpfile,mplabels)
+ end
+ end
+ end
+
+ def runtexmpjob(filename,filetype='')
+ 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
+ options = Array.new
+ options.push("--mptex")
+ options.push("--nomp")
+ options.push("--mpyforce") if getvariable('forcempy') || getvariable('mpyforce')
+ options.push("--translate=#{textranslation}") unless textranslation.empty?
+ options.push("--batch") if getvariable('batchmode')
+ options.push("--nonstop") if getvariable('nonstopmode')
+ return runtexexec(mpfile,options)
+ end
+ end
+ return false
+ end
+
+ def runtexutil(filename=[], options=['--ref','--ij','--high'])
+ Kpse.runscript('texutil',filename,options)
+ end
+
+ def runtexexec(filename=[], options=[])
+ Kpse.runscript('texexec',filename,options)
+ end
+
+ def processcontextfile
+
+ takeprecautions
+
+ jobname = getvariable('filename')
+ suffix = getvariable('suffix')
+ result = getvariable('result')
+
+ final = getvariable('final')
+
+ if getvariable('autopath') then
+ jobname = File.basename(jobname)
+ inppath = File.dirname(jobname)
+ else
+ inppath = ''
+ end
+
+ jobname, jobsuffix = File.splitname(jobname,'tex')
+
+ jobname = File.unixfied(jobname)
+ inppath = File.unixfied(inppath)
+ result = File.unixfied(result)
+
+ orisuffix = jobsuffix # still needed ?
+
+ 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)
+
+ unless FileTest.file?(File.suffixed(jobname,jobsuffix)) then
+ inppath.split(',').each do |ip|
+ break if dummyfile = FileTest.file?(File.join(ip,File.suffixed(jobname,jobsuffix)))
+ end
+ end
+
+ jobsuffix = makestubfile(jobname,jobsuffix,forcexml) if dummyfile || forcexml
+
+ if getvariable('globalfile') || FileTest.file?(File.suffixed(jobname,jobsuffix)) then
+
+ unless dummyfile # we don't need this for xml
+ scantexpreamble(File.suffixed(jobname,jobsuffix))
+ scantexcontent(File.suffixed(jobname,jobsuffix)) if getvariable('texformat').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)
+ 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")
+ 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}")
+ 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('driver'))
+ when 'dvipdfmx' then system("dvipdfmx -f dvipdfmx.map -d 4 #{File.unsuffixed(jobname)}")
+ when 'xetex' then system("xdv2pdf #{File.suffixed(jobname,'xdv')}")
+ when 'dvips' then system("dvips #{File.unsuffixed(jobname)}")
+ end
+ popresult(jobname,result)
+ end
+
+ Kpse.runscript('ctxtools',jobname,'--purge') if getvariable('purge')
+
+ begin
+ File.delete(File.suffixed(jobname,jobsuffix)) if dummyfile || forcexml
+ rescue
+ report("unable to delete stub file")
+ end
+
+ if ! problems && getvariable('pdfopen') then
+ PDFview.open(if resultname.empty? then jobname else resultname end)
+ end
+
+ end
+
+ end
+
+ # mp specific
+
+ def doruntexmp(mpname,mergebe=true,context=true)
+ texfound = false
+ mpbetex = Hash.new
+ mpfile = File.suffixed(mpname,'mp')
+ mpcopy = File.suffixed(mpname,'copy','mp')
+ setvariable('mp.file',mpfile)
+ setvariable('mp.line','')
+ setvariable('mp.error','')
+ if mpdata = File.silentread(mpfile) then
+ mpdata.gsub!(/^\#.*\n/o,'')
+ File.silentrename(mpfile,mpcopy)
+ texfound = mergebe || mpdata =~ /btex .*? etex/o
+ if mp = File.silentopen(mpfile,'w') then
+ mpdata.gsub!(/(btex.*?)\;(.*?etex)/o) do "#{$1}@@@#{$2}" end
+ mpdata.gsub!(/(\".*?)\;(.*?\")/o) do "#{$1}@@@#{$2}" end
+ mpdata.gsub!(/\;/o, "\;\n")
+ mpdata.gsub!(/\n+/o, "\n")
+ mpdata.gsub!(/(btex.*?)@@@(.*?etex)/o) do "#{$1}\;#{$2}" end
+ mpdata.gsub!(/(\".*?)@@@(.*?\")/o) do "#{$1};#{$2}" end
+ if mergebe then
+ mpdata.gsub!(/beginfig\s*\((\d+)\)\s*\;(.*?)endfig\s*\;/o) do
+ n, str = $1, $2
+ if str =~ /(.*?)(verbatimtex.*?etex)\s*\;(.*)/o then
+ "beginfig(#{n})\;\n$1$2\;\n#{mpbetex(n)}\n$3\;endfig\;\n"
+ else
+ "beginfig(#{n})\;\n#{mpbetex(n)}\n#{str}\;endfig\;\n"
+ end
+ end
+ end
+ unless mpdata =~ /beginfig\s*\(\s*0\s*\)/o then
+ mp << mpbetex[0] if mpbetex.key?(0)
+ end
+ mp << mpdata # ??
+ mp << "\n"
+ mp << "end"
+ mp << "\n"
+ mp.close
+ end
+ processmpx(mpname) if texfound
+ if getvariable('batchmode') then
+ options = ' --interaction=batch'
+ elsif getvariable('nonstopmode') then
+ options = ' --interaction=nonstop'
+ else
+ options = ''
+ end
+ # todo plain|mpost|metafun
+ ok = runmp(mpname)
+ if f = File.silentopen(File.suffixed(mpfile,'log')) then
+ while str = f.gets do
+ if str =~ /^l\.(\d+)\s(.*?)\n/o then
+ setvariable('mp.line',$1)
+ setvariable('mp.error',$2)
+ break
+ end
+ end
+ f.close
+ end
+ File.silentrename(mpfile,"mptrace.tmp")
+ File.silentrename(mpcopy, mpfile)
+ end
+ end
+
+ def processmpx(mpname,context=true)
+ mpname = File.suffixed(mpname,'mp')
+ if File.atleast?(mpname,10) && (data = File.silentread(mpname)) then
+ begin
+ if data =~ /(btex|etex|verbatimtex)/o then
+ mptex = File.suffixed(mpname,'temp','tex')
+ mpdvi = File.suffixed(mpname,'temp','dvi')
+ mplog = File.suffixed(mpname,'temp','log')
+ mpmpx = File.suffixed(mpname,'temp','mpx')
+ ok = system("mpto #{mpname} > #{mptex}")
+ if ok && File.appended(mptex, "\\end\n") then
+ if context then
+ ok = RunConTeXtFile(mptex)
+ else
+ ok = RunSomeTeXFile(mptex)
+ end
+ ok = ok && FileTest.file?(mpdvi) && system("dvitomp #{mpdvi} #{mpmpx}")
+ [mptex,mpdvi,mplog].each do |mpfil|
+ File.silentdelete(mpfil)
+ end
+ end
+ end
+ rescue
+ # error in processing mpx file
+ end
+ end
+ end
+
+ def checkmpgraphics(mpname)
+ mpoptions = ''
+ if getvariable('makempy') then
+ mpoptions += " --makempy "
+ end
+ if getvariable('mpyforce') || getvariable('forcempy') then
+ mpoptions += " --force "
+ else
+ mponame = File.suffixed(mpname,'mpo')
+ mpyname = File.suffixed(mpname,'mpy')
+ return false unless File.atleast?(mponame,32)
+ mpochecksum = State.new.checksum(mponame)
+ return false if mpochecksum.empty?
+ # where does the checksum get into the file?
+ # maybe let texexec do it?
+ # solution: add one if not present or update when different
+ if f = File.open(mpyname) then
+ str = f.gets.chomp
+ f.close
+ if str =~ /^\%\s*mpochecksum\s*\:\s*(\d+)/o then
+ return false if mpochecksum == $1
+ end
+ end
+ end
+ return Kpse.runscript('makempy',mpname)
+ end
+
+ def checkmplabels(mpname)
+ mpname = File.suffixed(mpname,'mpt')
+ if File.atleast?(mpname,10) && (mp = File.open(mpname)) then
+ labels = Hash.new
+ while str = mp.gets do
+ if str =~ /%\s*setup\s*:\s*(.*)/o then
+ t = $1
+ else
+ t = ''
+ end
+ if str =~ /%\s*figure\s*(\d+)\s*:\s*(.*)/o then
+ unless t.empty? then
+ labels[$1] += "#{t}\n"
+ t = ''
+ end
+ labels[$1] += "$2\n"
+ end
+ end
+ mp.close
+ return labels if labels.size>0
+ end
+ return nil
+ end
+
+end
+
+class String
+
+ def standard?
+ begin
+ self == 'standard'
+ rescue
+ false
+ end
+ end
+
+end
diff --git a/scripts/context/ruby/base/tool.rb b/scripts/context/ruby/base/tool.rb
new file mode 100644
index 000000000..c9e6a1890
--- /dev/null
+++ b/scripts/context/ruby/base/tool.rb
@@ -0,0 +1,305 @@
+# module : base/tool
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2002-2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+require 'timeout'
+require 'socket'
+require 'rbconfig'
+
+module Tool
+
+ $constructedtempdir = ''
+
+ def Tool.constructtempdir(create,mainpath='',fallback='')
+ begin
+ mainpath += '/' unless mainpath.empty?
+ timeout(5) do
+ begin
+ t = Time.now
+ u = t.usec.to_s % [1..2] [0..3]
+ pth = t.strftime("#{mainpath}%Y%m%d-%H%M%S-#{u}-#{Process.pid}")
+ if pth == $constructedtempdir
+ # sleep(0.01)
+ retry
+ end
+ Dir.mkdir(pth) if create
+ $constructedtempdir = pth
+ return pth
+ rescue
+ # sleep(0.01)
+ retry
+ end
+ end
+ rescue TimeoutError
+ # ok
+ rescue
+ # ok
+ end
+ unless fallback.empty?
+ begin
+ pth = "#{mainpath}#{fallback}"
+ mkdir(pth) if create
+ $constructedtempdir = path
+ return pth
+ rescue
+ return '.'
+ end
+ else
+ return '.'
+ end
+
+ end
+
+ def Tool.findtempdir(*vars)
+ constructtempdir(false,*vars)
+ end
+
+ def Tool.maketempdir(*vars)
+ constructtempdir(true,*vars)
+ end
+
+ # print maketempdir + "\n"
+ # print maketempdir + "\n"
+ # print maketempdir + "\n"
+ # print maketempdir + "\n"
+ # print maketempdir + "\n"
+
+
+ def Tool.ruby_platform
+ case RUBY_PLATFORM
+ when /(mswin|bccwin|mingw|cygwin)/i then 'mswin'
+ when /(linux)/i then 'linux'
+ when /(netbsd|unix)/i then 'unix'
+ when /(darwin|rhapsody|nextstep)/i then 'macosx'
+ else 'unix'
+ end
+ end
+
+ $defaultlineseparator = $/ # $RS in require 'English'
+
+ def Tool.file_platform(filename)
+
+ begin
+ if f = open(filename,'rb') then
+ str = f.read(4000)
+ f.close
+ nn = str.count("\n")
+ nr = str.count("\r")
+ if nn>nr then
+ return 2
+ elsif nn<nr then
+ return 3
+ else
+ return 1
+ end
+ else
+ return 0
+ end
+ rescue
+ return 0
+ end
+
+ end
+
+ def Tool.path_separator
+ return File::PATH_SEPARATOR
+ end
+
+ def Tool.line_separator(filename)
+
+ case file_platform(filename)
+ when 1 then return $defaultlineseparator
+ when 2 then return "\n"
+ when 3 then return "\r"
+ else return $defaultlineseparator
+ end
+
+ end
+
+ def Tool.default_line_separator
+ $defaultlineseparator
+ end
+
+ def Tool.simplefilename(old)
+
+ return old unless test(?f,old)
+
+ new = old.downcase
+ new.gsub!(/[^A-Za-z0-9\-\.\\\/]/o) do # funny chars
+ '-'
+ end
+ if old =~ /[a-zA-Z]\:/o
+ # seems like we have a dos/windows drive prefix, so roll back
+ new.sub!(/^(.)\-/) do
+ $1 + ':'
+ end
+ end
+ new.gsub!(/(.+?)\.(.+?)(\..+)$/o) do # duplicate .
+ $1 + '-' + $2 + $3
+ end
+ new.gsub!(/\-+/o) do # duplicate -
+ '-'
+ end
+ new
+
+ end
+
+ if Config::CONFIG['host_os'] =~ /mswin/ then
+
+ require 'Win32API'
+
+ GetShortPathName = Win32API.new('kernel32', 'GetShortPathName', ['P','P','N'], 'N')
+ GetLongPathName = Win32API.new('kernel32', 'GetLongPathName', ['P','P','N'], 'N')
+
+ def Tool.dowith_pathname (filename,filemethod)
+ filename.gsub!(/\\/o,'/')
+ case filename
+ when /\;/o then
+ # could be a path spec
+ return filename
+ when /\s+/o then
+ # danger lurking
+ buffer = ' ' * 260
+ length = filemethod.call(filename,buffer,buffer.size)
+ if length>0 then
+ return buffer.slice(0..length-1)
+ else
+ # when the path or file does not exist, nothing is returned
+ # so we try to handle the path separately from the basename
+ basename = File.basename(filename)
+ pathname = File.dirname(filename)
+ length = filemethod.call(pathname,buffer,260)
+ if length>0 then
+ return buffer.slice(0..length-1) + '/' + basename
+ else
+ return filename
+ end
+ end
+ else
+ # no danger
+ return filename
+ end
+ end
+
+ def Tool.shortpathname(filename)
+ dowith_pathname(filename,GetShortPathName)
+ end
+
+ def Tool.longpathname(filename)
+ dowith_pathname(filename,GetLongPathName)
+ end
+
+ else
+
+ def Tool.shortpathname(filename)
+ filename
+ end
+
+ def Tool.longpathname(filename)
+ filename
+ end
+
+ end
+
+ # print shortpathname("C:/Program Files/ABBYY FineReader 6.0/matrix.str")+ "!\n"
+ # print shortpathname("C:/Program Files/ABBYY FineReader 6.0/matrix.strx")+ "!\n"
+
+ def Tool.checksuffix(old)
+
+ return old unless test(?f,old)
+
+ new = old
+
+ unless new =~ /\./io # no suffix
+ f = open(filename,'rb')
+ if str = f.gets
+ case str
+ when /^\%\!PS/io
+ # logging.report(filename, 'analyzed as EPS')
+ new = new + '.eps'
+ when /^\%PDF/io
+ # logging.report(filename, 'analyzed as PDF')
+ new = new + '.pdf'
+ else
+ # logging.report(filename, 'fallback as TIF')
+ new = new + '.tif'
+ end
+ end
+ f.close
+ end
+
+ new.sub!(/\.jpeg$/io) do
+ '.jpg'
+ end
+ new.sub!(/\.tiff$/io) do
+ '.tif'
+ end
+ new.sub!(/\.ai$/io) do
+ '.eps'
+ end
+ new.sub!(/\.ai(.*?)$/io) do
+ '-' + $1 + '.eps'
+ end
+ new
+
+ end
+
+ def Tool.cleanfilename(old,logging=nil)
+
+ return old unless test(?f,old)
+
+ new = checksuffix(simplefilename(old))
+ unless new == old
+ begin
+ File.rename(old,new)
+ logging.report("renaming fuzzy name #{old} to #{new}") unless logging
+ return old
+ rescue
+ logging.report("unable to rename fuzzy name #{old} to #{new}") unless logging
+ end
+ end
+ return new
+
+ end
+
+ def Tool.preventduplicates(old,logging=nil)
+
+ return false unless test(?f,old)
+
+ if old =~ /\.(tif|jpg|png|tiff)$/io
+ suffix = $1
+ new = old
+ newn, news = new.split('.')
+ if test(?e,'newn.eps')
+ new = newn + '-' + suffix + '.' + suffix
+ begin
+ File.rename(old,new)
+ logging.report("renaming duplicate #{old} to #{new}") unless logging
+ return true
+ rescue
+ logging.report("unable to rename duplicate #{old} to #{new}") unless logging
+ end
+ end
+ end
+ return false
+
+ end
+
+ def Tool.servername
+ host = Socket::gethostname
+ begin
+ Socket::gethostbyname(host)[0]
+ rescue
+ host
+ end
+ end
+
+ # print file_platform(ARGV[0])
+
+end
diff --git a/scripts/context/ruby/base/variables.rb b/scripts/context/ruby/base/variables.rb
new file mode 100644
index 000000000..0c495d22d
--- /dev/null
+++ b/scripts/context/ruby/base/variables.rb
@@ -0,0 +1,37 @@
+# module : base/variables
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2002-2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+# ['base/tool','tool'].each do |r| begin require r ; rescue Exception ; else break ; end ; end
+
+require 'base/tool'
+
+module Variables
+
+ def setvariable(key,value='')
+ @variables[key] = value
+ end
+
+ def replacevariable(key,value='')
+ @variables[key] = value if @variables.key?(key)
+ end
+
+ def getvariable(key,default='')
+ if @variables.key?(key) then @variables[key] else default end
+ end
+
+ def report(*str)
+ @logger.report(*str)
+ end
+
+ def debug(*str)
+ @logger.debug(str)
+ end
+
+end
diff --git a/scripts/context/ruby/ctxtools.rb b/scripts/context/ruby/ctxtools.rb
index 9953087d8..1a87e298e 100644
--- a/scripts/context/ruby/ctxtools.rb
+++ b/scripts/context/ruby/ctxtools.rb
@@ -2,24 +2,37 @@
# program : ctxtools
# copyright : PRAGMA Advanced Document Engineering
+# version : 2004-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 context
# related files.
# todo: move scite here
+#
+# todo: move kpse call to kpse class/module
+
-banner = ['CtxTools', 'version 1.2.1', '2004/2005', 'PRAGMA ADE/POD']
+banner = ['CtxTools', 'version 1.2.2', '2004/2005', 'PRAGMA ADE/POD']
unless defined? ownpath
ownpath = $0.sub(/[\\\/][a-z0-9\-]*?\.rb/i,'')
$: << ownpath
end
-require 'ftools'
-require 'xmpl/switch'
-require 'exa/logger'
+require 'base/switch'
+require 'base/logger'
+require 'base/system'
+
require 'rexml/document'
+require 'ftools'
+
+exit if defined?(REQUIRE2LIB)
class String
@@ -362,18 +375,19 @@ class Commands
public
- def purgefiles
+ def purgefiles(all=false)
pattern = @commandline.arguments
- purgeall = @commandline.option("all")
+ purgeall = @commandline.option("all") || all
$dontaskprefixes.push(Dir.glob("mpx-*"))
$dontaskprefixes.flatten!
$dontaskprefixes.sort!
if purgeall then
- forsuresuffixes.push(texnonesuffixes)
- texnonesuffixes = []
+ $forsuresuffixes.push($texnonesuffixes)
+ $texnonesuffixes = []
+ $forsuresuffixes.flatten!
end
if ! pattern || pattern.empty? then
@@ -442,6 +456,10 @@ class Commands
end
+ def purgeall
+ purgefiles(true) # for old times sake
+ end
+
private
$removedfiles = 0
@@ -680,25 +698,29 @@ class Commands
pdffile = "#{filename}.pdf"
tuofile = "#{filename}.tuo"
if FileTest.file?(pdffile) then
- prevline, n = '', 0
- if (pdf = File.open(pdffile)) && (tuo = File.open(tuofile,'a')) then
- report('filtering page object numbers')
- pdf.binmode
- while line = pdf.gets do
- line.chomp
- # typical pdftex search
- if (line =~ /\/Type \/Page/o) && (prevline =~ /^(\d+)\s+0\s+obj/o) then
- p = $1
- n += 1
- tuo.puts("\\objectreference{PDFP}{#{n}}{#{p}}{#{n}}\n")
- else
- prevline = line
+ begin
+ prevline, n = '', 0
+ if (pdf = File.open(pdffile)) && (tuo = File.open(tuofile,'a')) then
+ report('filtering page object numbers')
+ pdf.binmode
+ while line = pdf.gets do
+ line.chomp
+ # typical pdftex search
+ if (line =~ /\/Type \/Page/o) && (prevline =~ /^(\d+)\s+0\s+obj/o) then
+ p = $1
+ n += 1
+ tuo.puts("\\objectreference{PDFP}{#{n}}{#{p}}{#{n}}\n")
+ else
+ prevline = line
+ end
end
end
+ pdf.close
+ tuo.close
+ report("number of pages : #{n}")
+ rescue
+ report("fatal error in filtering pages")
end
- pdf.close
- tuo.close
- report("number of pages : #{n}")
end
end
@@ -836,15 +858,18 @@ class Language
rmename = "lang-#{@language}.rme"
logname = "lang-#{@language}.log"
+ desname = "lang-all.xml"
+
@data.gsub!(/\\[nc]\{(.+?)\}/) do $1 end
@data.gsub!(/\{\}/) do '' end
@data.gsub!(/\n+/mo) do "\n" end
@read.gsub!(/\n+/mo) do "\n" end
description = ''
+ commentfile = rmename.dup
begin
- desfile = `kpsewhich -progname=context lang-all.xml`.chomp
+ desfile = `kpsewhich -progname=context #{desname}`.chomp
if f = File.new(desfile) then
if doc = REXML::Document.new(f) then
if e = REXML::XPath.first(doc.root,"/descriptions/description[@language='#{@language}']") then
@@ -856,6 +881,7 @@ class Language
description = ''
else
unless description.empty? then
+ commentfile = desname.dup
str = "<!-- copied from lang-all.xml\n\n"
str << "<?xml version='1.0' standalone='yes'?>\n\n"
str << description.chomp
@@ -913,7 +939,7 @@ class Language
end
data.gsub!(/(\s*\n\s*)+/mo, "\n")
f << banner
- f << comment("context pattern file, see #{rmename} for original comment")
+ f << comment("context pattern file, see #{commentfile} for original comment")
f << comment("source of data: #{@filenames.join(' ')}")
f << description
f << comment("begin pattern data")
@@ -937,7 +963,7 @@ class Language
end
data.gsub!(/(\s*\n\s*)+/mo, "\n")
f << banner
- f << comment("context hyphenation file, see #{rmename} for original comment")
+ f << comment("context hyphenation file, see #{commentfile} for original comment")
f.<< comment("source of data: #{@filenames.join(' ')}")
f << description
f.<< comment("begin hyphenation data")
@@ -1142,7 +1168,7 @@ class Commands
end
-logger = EXA::ExaLogger.new(banner.shift)
+logger = Logger.new(banner.shift)
commandline = CommandLine.new
commandline.registeraction('touchcontextfile', 'update context version')
@@ -1158,22 +1184,25 @@ commandline.registeraction('purgefiles', 'remove temporary files [--all] [basena
commandline.registeraction('documentation', 'generate documentation file [--type=] [filename]')
-commandline.registeraction('filterpages') # no help, hidden temporary feature
+commandline.registeraction('filterpages') # no help, hidden temporary feature
+commandline.registeraction('purgeallfiles') # no help, compatibility feature
commandline.registeraction('patternfiles', 'generate pattern files [languagecode|all]')
-commandline.registeraction('help')
-commandline.registeraction('version')
-
commandline.registervalue('type','')
-# commandline.registerflag('recurse')
-# commandline.registerflag('force')
+commandline.registerflag('recurse')
+commandline.registerflag('force')
commandline.registerflag('pipe')
commandline.registerflag('all')
commandline.registerflag('xml')
commandline.registerflag('log')
+# general
+
+commandline.registeraction('help')
+commandline.registeraction('version')
+
commandline.expand
Commands.new(commandline,logger,banner).send(commandline.action || 'help')
diff --git a/scripts/context/ruby/exa/logger.rb b/scripts/context/ruby/exa/logger.rb
deleted file mode 100644
index 0bbd67f24..000000000
--- a/scripts/context/ruby/exa/logger.rb
+++ /dev/null
@@ -1,108 +0,0 @@
-# module : exa/logger
-# copyright : PRAGMA Publishing On Demand
-# version : 1.01 - 2002/2003
-# author : Hans Hagen
-#
-# project : eXaMpLe
-# concept : Hans Hagen
-# info : j.hagen@xs4all.nl
-# www : www.pragma-pod.com / www.pragma-ade.com
-
-require 'thread'
-
-module EXA
-
- # The next calls are valid:
- #
- # @log.report('a','b','c', 'd')
- # @log.report('a','b',"c #{d}")
- # @log.report("a b c #{d}")
- #
- # Keep in mind that "whatever #{something}" is two times faster than
- # 'whatever ' + something or ['whatever',something].join and that
- # when verbosity is not needed the following is much faster too:
- #
- # @log.report('a','b','c', 'd') if @log.verbose?
- # @log.report('a','b',"c #{d}") if @log.verbose?
- # @log.report("a b c #{d}") if @log.verbose?
- #
- # The last three cases are equally fast when verbosity is turned off.
-
- # Under consideration: verbose per instance
-
- class ExaLogger
-
- @@length = 0
- @@verbose = false
-
- def initialize(tag=nil,length=0,verbose=false)
- @tag = tag || ''
- @@verbose = @@verbose || verbose
- @@length = @tag.length if @tag.length > @@length
- @@length = length if length > @@length
- end
-
- def report(*str)
- begin
- case str.length
- when 0
- print("\n")
- return true
- when 1
- message = str.first
- else
- message = [str].flatten.collect{|s| s.to_s}.join(' ').chomp
- end
- if @tag.empty? then
- print("#{message}\n")
- else
- # try to avoid too many adjustments
- @tag = @tag.ljust(@@length) unless @tag.length == @@length
- print("#{@tag} | #{message}\n")
- end
- rescue
- end
- return true
- end
-
- def reportlines(*str)
- unless @tag.empty? then
- @tag = @tag.ljust(@@length) unless @tag.length == @@length
- end
- report([str].flatten.collect{|s| s.gsub(/\n/,"\n#{@tag} | ")}.join(' '))
- end
-
- def debug(*str)
- report(str) if @@verbose
- end
-
- def error(*str)
- if ! $! || $!.to_s.empty? then
- report(str)
- else
- report(str,$!)
- end
- end
-
- def verbose
- @@verbose = true
- end
-
- def silent
- @@verbose = false
- end
-
- def verbose?
- @@verbose
- end
-
- # attr_reader :tag
-
- # alias fatal error
- # alias info debug
- # alias warn debug
- # alias debug? :verbose?
-
- end
-
-end
diff --git a/scripts/context/ruby/graphics/gs.rb b/scripts/context/ruby/graphics/gs.rb
new file mode 100644
index 000000000..e9ad2a07f
--- /dev/null
+++ b/scripts/context/ruby/graphics/gs.rb
@@ -0,0 +1,631 @@
+# module : graphics/gs
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2002-2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+# ['base/variables','../variables','variables'].each do |r| begin require r ; rescue Exception ; else break ; end ; end
+# ['base/system', '../system', 'system' ].each do |r| begin require r ; rescue Exception ; else break ; end ; end
+
+require 'base/variables'
+require 'base/system'
+
+class GhostScript
+
+ include Variables
+
+ @@pstopdfoptions = [
+ 'AntiAliasColorImages',
+ 'AntiAliasGrayImages',
+ 'AntiAliasMonoImages',
+ 'ASCII85EncodePages',
+ 'AutoFilterColorImages',
+ 'AutoFilterGrayImages',
+ 'AutoPositionEPSFiles',
+ 'AutoRotatePages',
+ 'Binding',
+ 'ColorConversionStrategy',
+ 'ColorImageDepth',
+ 'ColorImageDownsampleThreshold',
+ 'ColorImageDownsampleType',
+ 'ColorImageFilter',
+ 'ColorImageResolution',
+ 'CompatibilityLevel',
+ 'CompressPages',
+ #'ConvertCMYKImagesToRGB', # buggy
+ #'ConvertImagesToIndexed', # buggy
+ 'CreateJobTicket',
+ 'DetectBlends',
+ 'DoThumbnails',
+ 'DownsampleColorImages',
+ 'DownsampleGrayImages',
+ 'DownsampleMonoImages',
+ 'EmbedAllFonts',
+ 'EncodeColorImages',
+ 'EncodeGrayImages',
+ 'EncodeMonoImages',
+ 'EndPage',
+ 'FirstPage',
+ 'GrayImageDepth',
+ 'GrayImageDownsampleThreshold',
+ 'GrayImageDownsampleType',
+ 'GrayImageFilter',
+ 'GrayImageResolution',
+ 'MaxSubsetPct',
+ 'MonoImageDepth',
+ 'MonoImageDownsampleThreshold',
+ 'MonoImageDownsampleType',
+ 'MonoImageFilter',
+ 'MonoImageResolution',
+ 'Optimize',
+ 'ParseDCSComments',
+ 'ParseDCSCommentsForDocInfo',
+ 'PreserveCopyPage',
+ 'PreserveEPSInfo',
+ 'PreserveHalftoneInfo',
+ 'PreserveOPIComments',
+ 'PreserveOverprintSettings',
+ 'SubsetFonts',
+ 'UseFlateCompression'
+ ]
+
+ @@methods = Hash.new
+
+ @@methods['raw'] = '1'
+ @@methods['bound'] = '2'
+ @@methods['bounded'] = '2'
+ @@methods['crop'] = '3'
+ @@methods['cropped'] = '3'
+ @@methods['down'] = '4'
+ @@methods['downsample'] = '4'
+ @@methods['downsampled'] = '4'
+ @@methods['simplify'] = '5'
+ @@methods['simplified'] = '5'
+
+ @@tempfile = 'gstemp'
+ @@pstempfile = @@tempfile + '.ps'
+ @@pdftempfile = @@tempfile + '.pdf'
+
+ @@bboxspec = '\s*([\-\d\.]+)' + '\s+([\-\d\.]+)'*3
+
+ def initialize(logger=nil)
+
+ unless logger then
+ puts('gs class needs a logger')
+ exit
+ end
+
+ @variables = Hash.new
+ @psoptions = Hash.new
+ @logger = logger
+
+ setvariable('profile', 'gsprofile.ini')
+ setvariable('pipe', true)
+ setvariable('method', 2)
+ setvariable('force', false)
+ setvariable('colormodel', 'cmyk')
+ setvariable('inputfile', '')
+ setvariable('outputfile', '')
+
+ @@pstopdfoptions.each do |key|
+ @psoptions[key] = ''
+ end
+
+ reset
+
+ end
+
+ def reset
+ @llx = @lly = @ulx = @uly = 0
+ @oldbbox = [@llx,@lly,@urx,@ury]
+ @width = @height = @xoffset = @yoffset = @offset = 0
+ @rs = Tool.default_line_separator
+ end
+
+ def supported?(filename)
+ psfile?(filename) || pdffile?(filename)
+ end
+
+ def psfile?(filename)
+ filename =~ /\.(eps|epsf|ps|ai\d*)$/io
+ end
+
+ def pdffile?(filename)
+ filename =~ /\.(pdf)$/io
+ end
+
+ def setpsoption(key,value)
+ @psoptions[key] = value unless value.empty?
+ end
+
+ def setdimensions (llx,lly,urx,ury)
+ @oldbbox = [llx,lly,urx,ury]
+ @llx, @lly = llx.to_f-@offset, lly.to_f-@offset
+ @urx, @ury = urx.to_f+@offset, ury.to_f+@offset
+ @width, @height = @urx - @llx, @ury - @lly
+ @xoffset, @yoffset = 0 - @llx, 0 - @lly
+ end
+
+ def setoffset (offset=0)
+ @offset = offset.to_f
+ setdimensions(@llx,@lly,@urx,@ury) if dimensions?
+ end
+
+ def resetdimensions
+ setdimensions(0,0,0,0)
+ end
+
+ def dimensions?
+ (@width>0) && (@height>0)
+ end
+
+ def convert
+
+ inpfile = getvariable('inputfile')
+
+ if inpfile.empty? then
+ report('no inputfile specified')
+ return false
+ end
+
+ unless FileTest.file?(inpfile) then
+ report("unknown input file #{inpfile}")
+ return false
+ end
+
+ outfile = getvariable('outputfile')
+
+ if outfile.empty? then
+ outfile = inpfile
+ outfile = outfile.sub(/^.*[\\\/]/,'')
+ end
+
+ outfile = outfile.sub(/\.(pdf|eps|ps|ai)/i, "")
+ resultfile = outfile + '.pdf'
+ setvariable('outputfile', resultfile)
+
+ # flags
+
+ saveprofile(getvariable('profile'))
+
+ begin
+ gsmethod = method(getvariable('method')).to_i
+ report("conversion method #{gsmethod}")
+ rescue
+ gsmethod = 1
+ report("fallback conversion method #{gsmethod}")
+ end
+
+ debug('piping data') if getvariable('pipe')
+
+ ok = false
+ begin
+ case gsmethod
+ when 0, 1 then ok = convertasis(inpfile,resultfile)
+ when 2 then ok = convertbounded(inpfile,resultfile)
+ when 3 then ok = convertcropped(inpfile,resultfile)
+ when 4 then ok = downsample(inpfile,resultfile,'screen')
+ when 5 then ok = downsample(inpfile,resultfile,'prepress')
+ else report("invalid conversion method #{gsmethod}")
+ end
+ rescue
+ report('job aborted due to some error')
+ begin
+ File.delete(resultfile) if test(?e,resultfile)
+ rescue
+ report("unable to delete faulty #{resultfile}")
+ end
+ ok = false
+ ensure
+ deleteprofile(getvariable('profile'))
+ File.delete(@@pstempfile) if test(?e,@@pstempfile)
+ File.delete(@@pdftempfile) if test(?e,@@pdftempfile)
+ end
+ return ok
+ end
+
+ # private
+
+ def method (str)
+ if @@methods.key?(str) then
+ @@methods[str]
+ else
+ str
+ end
+ end
+
+ def pdfmethod? (str)
+ case method(str).to_i
+ when 4, 5 then return true
+ end
+ return false
+ end
+
+ def pdfprefix (str)
+ case method(str).to_i
+ when 4 then return 'lowres-'
+ when 5 then return 'normal-'
+ end
+ return ''
+ end
+
+ def psmethod? (str)
+ ! pdfmethod?(str)
+ end
+
+ def insertprofile (flags)
+ for key in flags.keys do
+ replacevariable("flag.#{key}", flags[key])
+ end
+ end
+
+ def deleteprofile (filename)
+ begin
+ File.delete(filename) if FileTest.file?(filename)
+ rescue
+ end
+ end
+
+ def saveprofile (filename)
+ return if filename.empty? || ! (ini = open(filename,"w"))
+ @@pstopdfoptions.each do |k|
+ str = @psoptions[k]
+ # beware, booleans are translated, but so are yes/no which is dangerous
+ if str.class == String then
+ if ! str.empty? && (str != 'empty') then
+ str.sub!(/(.+)\-/io, '')
+ str = "/" + str unless str =~ /^(true|false|none|[\d\.\-\+]+)$/
+ ini.puts("-d#{k}=#{str}\n")
+ end
+ end
+ end
+ ini.close
+ debug("gs profile #{filename} saved")
+ end
+
+ def gsstream # private
+ if getvariable('pipe') then '-' else @@pstempfile end
+ end
+
+ def gscolorswitch
+ case getvariable('colormodel')
+ when 'cmyk' then '-dProcessColorModel=/DeviceCMYK '
+ when 'rgb' then '-dProcessColorModel=/DeviceRGB '
+ when 'gray' then '-dProcessColorModel=/DeviceGRAY '
+ else
+ ''
+ end
+ end
+
+ def gsdefaults
+ defaults = ''
+ begin
+ defaults << '-dAutoRotatePages=/None ' if @psoptions['AutoRotatePages'].empty?
+ rescue
+ defaults << '-dAutoRotatePages=/None '
+ end
+ return defaults
+ end
+
+ def convertasis (inpfile, outfile)
+
+ report("converting #{inpfile} as-is")
+
+ @rs = Tool.line_separator(inpfile)
+ debug("platform mac") if @rs == "\r"
+
+ arguments = ''
+ arguments << "\@gsprofile.ini "
+ arguments << "-q -sDEVICE=pdfwrite -dNOPAUSE -dNOCACHE -dBATCH "
+arguments << "#{gsdefaults} "
+ arguments << "#{gscolorswitch} "
+ arguments << "-sOutputFile=#{outfile} #{inpfile} -c quit "
+
+ debug("ghostscript: #{arguments}")
+ unless ok = System.run('ghostscript',arguments) then
+ begin
+ report("removing file #{outfile}")
+ File.delete(outfile) if FileTest.file?(outfile)
+ rescue
+ debug("file #{outfile} may be invalid")
+ end
+ end
+ return ok
+
+ end
+
+ def convertbounded (inpfile, outfile)
+
+ report("converting #{inpfile} bounded")
+
+ begin
+ return false if FileTest.file?(outfile) && (! File.delete(outfile))
+ rescue
+ return false
+ end
+
+ arguments = ''
+ arguments << "\@gsprofile.ini "
+ arguments << "-q -sDEVICE=pdfwrite -dNOPAUSE -dNOCACHE -dBATCH -dSAFER"
+ arguments << "#{gscolorswitch} "
+arguments << "#{gsdefaults} "
+ arguments << "-sOutputFile=#{outfile} #{gsstream} -c quit "
+
+ debug("ghostscript: #{arguments}")
+ debug('opening input file')
+
+ @rs = Tool.line_separator(inpfile)
+ debug("platform #{mac}") if @rs == "\r"
+
+ return false unless tmp = open(inpfile, 'rb')
+
+ debug('opening pipe/file')
+
+ if getvariable('pipe') then
+
+ return false unless eps = IO.popen(System.command('ghostscript',arguments),'wb')
+ debug('piping data')
+ unless pipebounded(tmp,eps) then
+ debug('something went wrong in the pipe')
+ File.delete(outfile) if test(?e,outfile)
+ end
+ debug('closing pipe')
+ eps.close_write
+
+ else
+
+ return false unless eps = File.open(@@pstempfile, 'wb')
+
+ debug('copying data')
+
+ if pipebounded(tmp,eps) then
+ eps.close
+ debug('processing temp file')
+ begin
+ ok = System.run('ghostscript',arguments)
+ rescue
+ ok = false
+ # debug("fatal error: #{$!}")
+ ensure
+ end
+ else
+ eps.close
+ ok = false
+ end
+
+ unless ok then
+ begin
+ report('no output file due to error')
+ File.delete(outfile) if test(?e,outfile)
+ rescue
+ debug('file',outfile,'may be invalid')
+ end
+ end
+
+ debug('deleting temp file')
+ begin
+ File.delete(@@pstempfile) if test(?e,@@pstempfile)
+ rescue
+ end
+
+ end
+
+ tmp.close
+ return FileTest.file?(outfile)
+
+ end
+
+ # hm, strange, no execute here, todo ! ! !
+
+ def getdimensions (inpfile)
+
+ # -dEPSFitPage and -dEPSCrop behave weird (don't work)
+
+ arguments = "-sDEVICE=bbox -dSAFER -dNOPAUSE -dBATCH #{inpfile}"
+
+ debug("ghostscript: #{arguments}")
+
+ begin
+ bbox = System.run('ghostscript',arguments,true,true)
+ rescue
+ bbox = ''
+ end
+
+ resetdimensions
+
+ debug('bbox spec', bbox)
+
+ if bbox =~ /(Exact|HiRes)BoundingBox:#{@@bboxspec}/mois then
+ debug("high res bbox #{$2} #{$3} #{$4} #{$5}")
+ setdimensions($2,$3,$4,$5)
+ elsif bbox =~ /BoundingBox:#{@@bboxspec}/mois
+ debug("low res bbox #{$1} #{$2} #{$3} #{$4}")
+ setdimensions($1,$2,$3,$4)
+ end
+
+ return dimensions?
+
+ end
+
+ def convertcropped (inpfile, outfile)
+
+ report("converting #{inpfile} cropped")
+
+ convertbounded(inpfile, @@pdftempfile)
+
+ return unless test(?e,@@pdftempfile)
+
+ arguments = " --offset=#{@offset} #{@@pdftempfile} #{outfile}"
+
+ unless ok = System.run('cropcrap',arguments) then
+ report('cropping failed')
+ begin
+ File.delete(outfile)
+ rescue
+ end
+ begin
+ File.move(@@pdftempfile,outfile)
+ rescue
+ File.copy(@@pdftempfile,outfile)
+ File.delete(@@pdftempfile)
+ end
+ end
+
+ return ok
+
+ end
+
+ def pipebounded (eps, out)
+
+ epsbbox, skip, buffer = false, false, ''
+
+ debug('stripping preamble crap')
+
+ while str = eps.gets(rs=@rs) do
+ if str =~ /%!PS/mois
+ str = str.sub(/(.*)%!PS/mois, "%!PS")
+ out.puts(str)
+ break
+ elsif str =~ /%PDF\-\d+\.\d+/mois
+ debug("looks like a pdf file, so let\'s quit")
+ return false
+ end
+ end
+
+ debug('locating boundingbox')
+
+ # why no BeginData check
+
+ while str = eps.gets(rs=@rs)
+ case str
+ when /^%%Page:/io then
+ break
+ when /^%%(Crop|HiResBounding|ExactBounding)Box:#{@@bboxspec}/mois then
+ debug('high res boundingbox found')
+ setdimensions($2,$3,$4,$5)
+ break
+ when /^%%BoundingBox:#{@@bboxspec}/mois then
+ debug('low res boundingbox found')
+ setdimensions($1,$2,$3,$4)
+ end
+ end
+
+ eps.rewind
+
+ while str = eps.gets(rs=@rs) do
+ if skip then
+ skip = false if str =~ /^%+(EndData|EndPhotoshop|BeginProlog).*$/o
+ out.puts(str) if $1 == "BeginProlog"
+ elsif str =~ /^%(BeginPhotoshop)\:\s*\d+.*$/o then
+ skip = true
+ elsif str =~ /^%%/mos then
+ if ! epsbbox && str =~ /^%%(Page:|EndProlog)/io then
+ out.puts(str) if $1 == "EndProlog"
+ debug('faking papersize')
+ out.puts("<< /PageSize [#{@width} #{@height}] >> setpagedevice\n")
+ out.puts("gsave #{@xoffset} #{@yoffset} translate\n")
+ epsbbox = true
+ elsif str =~ /^%%BeginBinary\:\s*\d+\s*$/o then
+ debug('copying binary data')
+ out.puts(str)
+ while str = eps.gets(rs=@rs)
+ if str =~ /^%%EndBinary\s*$/o then
+ out.puts(str)
+ else
+ out.write(str)
+ end
+ end
+ elsif str =~ /^%AI9\_PrivateDataBegin/o then
+ debug('ignore private ai crap')
+ break
+ elsif str =~ /^%%EOF/o then
+ debug('ignore post eof crap')
+ break
+ # elsif str =~ /^%%PageTrailer/o then
+ # debug('ignoring post page trailer crap')
+ # break
+ elsif str =~ /^%%Trailer/o then
+ debug('ignoring post trailer crap')
+ break
+ elsif str =~ /^%%Creator.*Illustrator.*$/io then
+ debug('getting rid of problematic creator spec')
+ str = "% Creator: Adobe Illustrator ..."
+ out.puts(str)
+ elsif str =~ /^%%AI.*(PaperRect|Margin)/io then
+ debug('removing AI paper crap')
+ elsif str =~ /^%%AI.*Version.*$/io then
+ debug('removing dangerous version info')
+ elsif str =~ /^(%+AI.*Thumbnail.*)$/o then
+ debug('skipping AI thumbnail')
+ skip = true
+ else
+ out.puts(str)
+ end
+ else
+ out.puts(str)
+ end
+ end
+
+ debug('done, sending EOF')
+
+ out.puts "grestore\n%%EOF\n"
+
+ # ok = $? == 0
+ # report('process aborted, broken pipe, fatal error') unless ok
+ # return ok
+
+ return true
+
+ end
+
+ def downsample (inpfile, outfile, method='screen')
+
+ # gs <= 8.50
+
+ report("downsampling #{inpfile}")
+
+ doit = true
+ unless getvariable('force') then
+ begin
+ if f = File.open(inpfile) then
+ f.binmode
+ while doit && (data = f.gets) do
+ if data =~ /\/ArtBox\s*\[\s*[\d\.]+\s+[\d\.]+\s+[\d\.]+\s+[\d\.]+\s*\]/io then
+ doit = false
+ end
+ end
+ f.close
+ end
+ rescue
+ end
+ end
+
+ if doit then
+ arguments = ''
+ arguments << "-dPDFSETTINGS=/#{method} -dEmbedAllFonts=true "
+ arguments << "#{gscolorswitch} "
+arguments << "#{gsdefaults} "
+ arguments << "-q -sDEVICE=pdfwrite -dNOPAUSE -dNOCACHE -dBATCH -dSAFER "
+ arguments << "-sOutputFile=#{outfile} #{inpfile} -c quit "
+ unless ok = System.run('ghostscript',arguments) then
+ begin
+ File.delete(outfile) if FileTest.file?(outfile)
+ report("removing file #{outfile}")
+ rescue
+ debug("file #{outfile} may be invalid")
+ end
+ end
+ return ok
+ else
+ report("crop problem, straight copying #{inpfile}")
+ File.copy(inpfile,outfile)
+ return false
+ end
+
+ end
+
+end
diff --git a/scripts/context/ruby/graphics/inkscape.rb b/scripts/context/ruby/graphics/inkscape.rb
new file mode 100644
index 000000000..4495c3070
--- /dev/null
+++ b/scripts/context/ruby/graphics/inkscape.rb
@@ -0,0 +1,103 @@
+# module : graphics/inkscape
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2002-2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+# ['base/variables','variables'].each do |r| begin require r ; rescue Exception ; else break ; end ; end
+# ['graphics/gs','gs'].each do |r| begin require r ; rescue Exception ; else break ; end ; end
+
+require 'base/variables'
+require 'base/system'
+require 'graphics/gs'
+
+class InkScape
+
+ include Variables
+
+ def initialize(logger=nil)
+
+ unless logger then
+ puts('inkscape class needs a logger')
+ exit
+ end
+
+ @variables = Hash.new
+ @logger = logger
+
+ reset
+
+ end
+
+ def reset
+ # nothing yet
+ end
+
+ def supported?(filename)
+ filename =~ /.*\.(svg|svgz)/io
+ end
+
+ def convert(logfile=System.null)
+
+ inpfilename = getvariable('inputfile').dup
+ outfilename = getvariable('outputfile').dup
+ outfilename = inpfilename.dup if outfilename.empty?
+ outfilename.gsub!(/(\.[^\.]*?)$/, ".pdf")
+ tmpfilename = outfilename.gsub(/(\.[^\.]*?)$/, ".ps")
+
+ if inpfilename.empty? || outfilename.empty? then
+ report("no filenames given")
+ return false
+ end
+ if inpfilename == outfilename then
+ report("filenames must differ (#{inpfilename} #{outfilename})")
+ return false
+ end
+ unless FileTest.file?(inpfilename) then
+ report("unknown file #{inpfilename}")
+ return false
+ end
+
+ report("converting #{inpfilename} to #{tmpfilename}")
+
+ # we need to redirect the error info else we get a pop up console
+
+ resultpipe = "--without-gui --print=\">#{tmpfilename}\" 2>#{logfile}"
+
+ arguments = [resultpipe,inpfilename].join(' ').gsub(/\s+/,' ')
+
+ ok = true
+ begin
+ debug("inkscape: #{arguments}")
+ # should work
+ # ok = System.run('inkscape',arguments) # does not work here
+ # but 0.40 only works with this:
+ ok = system("inkscape #{arguments}")
+ # and 0.41 fails with everything
+ rescue
+ report("aborted due to error")
+ return false
+ else
+ return false unless ok
+ end
+
+ ghostscript = GhostScript.new(@logger)
+
+ ghostscript.setvariable('inputfile',tmpfilename)
+ ghostscript.setvariable('outputfile',outfilename)
+
+ report("converting #{tmpfilename} to #{outfilename}")
+
+ ghostscript.convert
+
+ begin
+ File.delete(tmpfilename)
+ rescue
+ end
+ end
+
+end
diff --git a/scripts/context/ruby/graphics/magick.rb b/scripts/context/ruby/graphics/magick.rb
new file mode 100644
index 000000000..f59087bdf
--- /dev/null
+++ b/scripts/context/ruby/graphics/magick.rb
@@ -0,0 +1,161 @@
+# module : graphics/inkscape
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2002-2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+# ['base/variables','variables'].each do |r| begin require r ; rescue Exception ; else break ; end ; end
+
+require 'base/variables'
+
+class ImageMagick
+
+ include Variables
+
+ def initialize(logger=nil)
+
+ unless logger then
+ puts('magick class needs a logger')
+ exit
+ end
+
+ @variables = Hash.new
+ @logger = logger
+
+ reset
+
+ end
+
+ def reset
+ ['compression','depth','colorspace','quality'].each do |key|
+ setvariable(key)
+ end
+ end
+
+ def supported?(filename) # ? pdf
+ filename =~ /.*\.(png|gif|tif|tiff|jpg|jpeg|eps|ai\d*)/io
+ end
+
+ def convert(suffix='pdf')
+
+ inpfilename = getvariable('inputfile').dup
+ outfilename = getvariable('outputfile').dup
+ outfilename = inpfilename.dup if outfilename.empty?
+ outfilename.gsub!(/(\.[^\.]*?)$/, ".#{suffix}")
+
+ if inpfilename.empty? || outfilename.empty? then
+ report("no filenames given")
+ return false
+ end
+ if inpfilename == outfilename then
+ report("filenames must differ (#{inpfilename} #{outfilename})")
+ return false
+ end
+ unless FileTest.file?(inpfilename) then
+ report("unknown file #{inpfilename}")
+ return false
+ end
+
+ if inpfilename =~ /\.tif+$/io then
+ tmpfilename = 'temp.png'
+ arguments = "#{inpfilename} #{tmpfilename}"
+ begin
+ debug("imagemagick: #{arguments}")
+ ok = System.run('imagemagick',arguments)
+ rescue
+ report("aborted due to error")
+ return false
+ else
+ return false unless ok
+ end
+ inpfilename = tmpfilename
+ end
+
+ compression = depth = colorspace = quality = ''
+
+ if getvariable('compression') =~ /(zip|jpeg)/o then
+ compression = " -compress #{$1}"
+ end
+ if getvariable('depth') =~ /(8|16)/o then
+ depth = "-depth #{$1}"
+ end
+ if getvariable('colorspace') =~ /(gray|rgb|cmyk)/o then
+ colorspace = "-colorspace #{$1}"
+ end
+ case getvariable('quality')
+ when 'low' then quality = '-quality 0'
+ when 'medium' then quality = '-quality 75'
+ when 'high' then quality = '-quality 100'
+ end
+
+ report("converting #{inpfilename} to #{outfilename}")
+
+ arguments = [compression,depth,colorspace,quality,inpfilename,outfilename].join(' ').gsub(/\s+/,' ')
+
+ begin
+ debug("imagemagick: #{arguments}")
+ ok = System.run('imagemagick',arguments)
+ rescue
+ report("aborted due to error")
+ return false
+ else
+ return ok
+ end
+
+ end
+
+ def autoconvert
+
+ inpfilename = getvariable('inputfile')
+ outfilename = getvariable('outputfile')
+
+ if inpfilename.empty? || ! FileTest.file?(inpfilename) then
+ report("missing file #{inpfilename}")
+ return
+ end
+
+ outfilename = inpfilename.dup if outfilename.empty?
+ tmpfilename = 'temp.jpg'
+
+ reset
+
+ megabyte = 1024*1024
+
+ ok = false
+
+ if FileTest.size(inpfilename)>2*megabyte
+ setvariable('compression','zip')
+ ok = convert
+ else
+ setvariable('compression','jpeg')
+ if FileTest.size(inpfilename)>10*megabyte then
+ setvariable('quality',85)
+ elsif FileTest.size(inpfilename)>5*megabyte then
+ setvariable('quality',90)
+ else
+ setvariable('quality',95)
+ end
+ report("auto quality #{getvariable('quality')}")
+ setvariable('outputfile', tmpfilename)
+ ok = convert('jpg')
+ setvariable('inputfile', tmpfilename)
+ setvariable('outputfile', outfilename)
+ ok = convert
+ begin
+ File.delete(tmpfilename)
+ rescue
+ report("#{tmpfilename} cannot be deleted")
+ end
+ end
+
+ reset
+
+ return ok
+
+ end
+
+end
diff --git a/scripts/context/ruby/newimgtopdf.rb b/scripts/context/ruby/newimgtopdf.rb
new file mode 100644
index 000000000..3c1636cf2
--- /dev/null
+++ b/scripts/context/ruby/newimgtopdf.rb
@@ -0,0 +1,86 @@
+#!/usr/bin/env ruby
+
+# program : newimgtopdf
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2002-2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+unless defined? ownpath
+ ownpath = $0.sub(/[\\\/]\w*?\.rb/i,'')
+ $: << ownpath
+end
+
+require 'base/switch'
+require 'base/logger'
+
+require 'graphics/magick'
+
+banner = ['ImgToPdf', 'version 1.1.1', '2002-2005', 'PRAGMA ADE/POD']
+
+class Commands
+
+ include CommandBase
+
+ # nowadays we would force a directive, but
+ # for old times sake we handle default usage
+
+ def main
+ filename = @commandline.argument('first')
+
+ if filename.empty? then
+ help
+ else
+ convert
+ end
+ end
+
+ # actions
+
+ def convert
+
+ magick = Magick.new(session)
+
+ ['compression','depth','colorspace','quality','inputpath','outputpath'].each do |v|
+ magick.setvariable(v,@commandline.option(v))
+ end
+
+ @commandline.arguments.each do |fullname|
+ magick.setvariable('inputfile',fullname)
+ magick.setvariable('outputfile',fullname.gsub(/(\..*?$)/io, '.pdf'))
+ if @commandline.option('auto') then
+ magick.autoconvert
+ else
+ magick.convert
+ end
+ end
+ end
+
+end
+
+logger = Logger.new(banner.shift)
+commandline = CommandLine.new
+
+commandline.registerflag('auto')
+
+commandline.registervalue('compression')
+commandline.registervalue('depth')
+commandline.registervalue('colorspace')
+commandline.registervalue('quality')
+
+commandline.registervalue('inputpath')
+commandline.registervalue('outputpath')
+
+
+commandline.registeraction('help')
+commandline.registeraction('version')
+
+commandline.registeraction('convert', 'convert image into pdf')
+
+commandline.expand
+
+Commands.new(commandline,logger,banner).send(commandline.action || 'main')
diff --git a/scripts/context/ruby/newpstopdf.rb b/scripts/context/ruby/newpstopdf.rb
new file mode 100644
index 000000000..aa3a14fef
--- /dev/null
+++ b/scripts/context/ruby/newpstopdf.rb
@@ -0,0 +1,527 @@
+#!/usr/bin/env ruby
+
+# program : pstopdf
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2002-2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+banner = ['PsToPdf', 'version 2.0.0', '2002-2005', 'PRAGMA ADE/POD']
+
+unless defined? ownpath
+ ownpath = $0.sub(/[\\\/]\w*?\.rb/i,'')
+ $: << ownpath
+end
+
+# todo: paden/prefix in magick and inkscape
+# todo: clean up method handling (pass strings, no numbers)
+
+require 'base/switch'
+require 'base/tool'
+require 'base/logger'
+
+require 'graphics/gs'
+require 'graphics/magick'
+require 'graphics/inkscape'
+
+require 'rexml/document'
+
+exit if defined?(REQUIRE2LIB)
+
+class Commands
+
+ include CommandBase
+
+ # nowadays we would force a directive, but
+ # for old times sake we handle default usage
+
+ def main
+ filename = @commandline.argument('first')
+ pattern = @commandline.option('pattern')
+ globfiles(pattern) if filename.empty? && ! pattern.empty?
+ filename = @commandline.argument('first')
+ if filename.empty? then
+ help
+ elsif filename =~ /\.exa$/ then
+ request
+ else
+ convert
+ end
+ end
+
+ # actions
+
+ def convert
+
+ ghostscript = GhostScript.new(logger)
+ magick = ImageMagick.new(logger)
+ inkscape = InkScape.new(logger)
+
+ outpath = @commandline.option('outputpath')
+ unless outpath.empty? then
+ begin
+ File.expand_path(outpath)
+ outpath = File.makedirs(outpath) unless FileTest.directory?(outpath)
+ rescue
+ # sorry
+ end
+ end
+
+ @commandline.arguments.each do |filename|
+
+ filename = Tool.cleanfilename(filename,@commandline)
+ inppath = @commandline.option('inputpath')
+ if inppath.empty? then
+ inppath = '.'
+ fullname = filename # avoid duplicate './'
+ else
+ fullname = File.join(inppath,filename)
+ end
+ if FileTest.file?(fullname) then
+ handle_whatever(ghostscript,inkscape,magick,filename)
+ else
+ report("file #{fullname} does not exist")
+ end
+
+ end
+
+ end
+
+ def request
+
+ # <exa:request>
+ # <exa:application>
+ # <exa:command>pstopdf</exa:command>
+ # <exa:filename>E:/tmp/demo.ps</exa:filename>
+ # </exa:application>
+ # <exa:data>
+ # <exa:variable label='gs:DoThumbnails'>false</exa:variable>
+ # <exa:variable label='gs:ColorImageDepth'>-1</exa:variable>
+ # </exa:data>
+ # </exa:request>
+
+ ghostscript = GhostScript.new(logger)
+ magick = ImageMagick.new(logger)
+ inkscape = InkScape.new(logger)
+
+ dataname = @commandline.argument('first') || ''
+ filename = @commandline.argument('second') || ''
+
+ if dataname.empty? || ! FileTest.file?(dataname) then
+ report('provide valid exa file')
+ return
+ else
+ begin
+ request = REXML::Document.new(File.new(dataname))
+ rescue
+ report('provide valid exa file (xml error)')
+ return
+ end
+ end
+ if filename.empty? then
+ begin
+ if filename = REXML::XPath.first(request.root,"exa:request/exa:application/exa:filename/text()") then
+ filename = filename.to_s
+ else
+ report('no filename found in exa file')
+ return
+ end
+ rescue
+ filename = ''
+ end
+ end
+ if filename.empty? then
+ report('provide valid filename')
+ return
+ elsif ! FileTest.file?(filename) then
+ report("invalid filename #{filename}")
+ return
+ end
+
+ [ghostscript,inkscape,magick].each do |i|
+ i.setvariable('inputfile',filename)
+ end
+
+ # set ghostscript variables
+ REXML::XPath.each(request.root,"/exa:request/exa:data/exa:variable") do |v|
+ begin
+ if (key = v.attributes['label']) and (value = v.text.to_s) then
+ case key
+ when /gs[\:\.](var[\:\.])*(offset)/io then ghostscript.setoffset(value)
+ when /gs[\:\.](var[\:\.])*(method)/io then ghostscript.setvariable('method',value)
+ when /gs[\:\.](var[\:\.])*(.*)/io then ghostscript.setpsoption($2,value)
+ end
+ end
+ rescue
+ end
+ end
+
+ # no inkscape and magick variables (yet)
+
+ handle_whatever(ghostscript,inkscape,magick,filename)
+
+ end
+
+ def watch
+
+ ghostscript = GhostScript.new(logger)
+ magick = ImageMagick.new(logger)
+ inkscape = InkScape.new(logger)
+
+ pathname = commandline.option('watch')
+
+ unless pathname and not pathname.empty? then
+ report('empty watchpath is not supported')
+ exit
+ end
+
+ if pathname == '.' then
+ report("watchpath #{pathname} is not supported")
+ exit
+ end
+
+ if FileTest.directory?(pathname) then
+ if Dir.chdir(pathname) then
+ report("watching path #{pathname}")
+ else
+ report("unable to change to path #{pathname}")
+ exit
+ end
+ else
+ report("invalid path #{pathname}")
+ exit
+ end
+
+ waiting = false
+
+ loop do
+
+ if waiting then
+ report("waiting #{getvariable('delay')}")
+ waiting = false
+ sleep(getvariable('delay').to_i)
+ end
+
+ files = Dir.glob("**/*.*")
+
+ if files and files.length > 0 then
+
+ files.each do |fullname|
+
+ next unless fullname
+
+ if FileTest.directory?(fullname) then
+ debug('skipping path', fullname)
+ next
+ end
+
+ unless magick.supported(fullname) then
+ debug('not supported', fullname)
+ next
+ end
+
+ if (! FileTest.file?(fullname)) || (FileTest.size(fullname) < 100) then
+ debug("skipping small crap file #{fullname}")
+ next
+ end
+
+ debug("handling file #{fullname}")
+
+ begin
+ next unless File.rename(fullname,fullname) # access trick
+ rescue
+ next # being written
+ end
+
+ fullname = Tool.cleanfilename(fullname,@commandline)
+
+ fullname.gsub!(/\\/io, '/')
+
+ filename = File.basename(fullname)
+ filepath = File.dirname(fullname)
+
+ next if filename =~ /gstemp.*/io
+
+ if filepath !~ /(result|done|raw|crop|bound|bitmap)/io then
+ begin
+ File.makedirs(filepath+'/raw')
+ File.makedirs(filepath+'/bound')
+ File.makedirs(filepath+'/crop')
+ File.makedirs(filepath+'/bitmap')
+ debug("creating prefered input paths on #{filepath}")
+ rescue
+ debug("creating input paths on #{filepath} failed")
+ end
+ end
+
+ if filepath =~ /^(.*\/|)(done|result)$/io then
+ debug("skipping file #{fullname}")
+ else
+ report("start processing file #{fullname}")
+ if filepath =~ /^(.*\/*)(raw|crop|bound)$/io then
+ donepath = $1 + 'done'
+ resultpath = $1 + 'result'
+ case $2
+ when 'raw' then method = 1
+ when 'bound' then method = 2
+ when 'crop' then method = 3
+ else method = 2
+ end
+ report("forcing method #{method}")
+ else
+ method = 2
+ donepath = filepath + '/done'
+ resultpath = filepath + '/result'
+ report("default method #{method}")
+ end
+
+ begin
+ File.makedirs(donepath)
+ File.makedirs(resultpath)
+ rescue
+ report('result path creation fails')
+ end
+
+ if FileTest.directory?(donepath) && FileTest.directory?(resultpath) then
+
+ resultname = resultpath + '/' + filename.sub(/\..*$/,'') + '.pdf'
+
+ @commandline.setoption('inputpath', filepath)
+ @commandline.setoption('outputpath', resultpath)
+ @commandline.setoption('method', method)
+
+ if ghostscript.psfile?(fullname) then
+ handle_ghostscript(ghostscript,filename)
+ else
+ handle_magick(magick,filename)
+ end
+
+ sleep(1) # calm down
+
+ if FileTest.file?(fullname) then
+ begin
+ File.copy(fullname,donepath + '/' + filename)
+ File.delete(fullname)
+ rescue
+ report('cleanup fails')
+ end
+ end
+
+ end
+
+ end
+
+ end
+
+ end
+
+ waiting = true
+ end
+
+ end
+
+ private
+
+ def handle_whatever(ghostscript,inkscape,magick,filename)
+ if ghostscript.psfile?(filename) then
+ # report("processing ps file #{filename}")
+ ghostscript.setvariable('pipe',false) if @commandline.option('nopipe')
+ # ghostscript.setvariable('pipe',not @commandline.option('nopipe'))
+ ghostscript.setvariable('colormodel',@commandline.option('colormodel'))
+ ghostscript.setvariable('offset',@commandline.option('offset'))
+ handle_ghostscript(ghostscript,filename)
+ elsif ghostscript.pdffile?(filename) && ghostscript.pdfmethod?(@commandline.option('method')) then
+ # report("processing pdf file #{filename}")
+ handle_ghostscript(ghostscript,filename)
+ elsif inkscape.supported?(filename) then
+ # report("processing non ps/pdf file #{filename}")
+ handle_inkscape(inkscape,filename)
+ elsif magick.supported?(filename) then
+ # report("processing non ps/pdf file #{filename}")
+ handle_magick(magick,filename)
+ end
+ end
+
+ def handle_magick(magick,filename)
+
+ report("converting non-ps file #{filename} into pdf")
+
+ inppath = @commandline.option('inputpath')
+ outpath = @commandline.option('outputpath')
+
+ inppath = inppath + '/' if not inppath.empty?
+ outpath = outpath + '/' if not outpath.empty?
+
+ prefix = @commandline.option('prefix')
+ suffix = @commandline.option('suffix')
+
+ inpfilename = "#{inppath}#{filename}"
+ outfilename = "#{outpath}#{prefix}#{filename.sub(/\.(.*?)$/, '')}#{suffix}.pdf"
+
+ magick.setvariable('inputfile' , inpfilename)
+ magick.setvariable('outputfile', outfilename)
+
+ magick.autoconvert
+
+ end
+
+ def handle_inkscape(inkscape,filename)
+
+ report("converting svg(z) file #{filename} into pdf")
+
+ inppath = @commandline.option('inputpath')
+ outpath = @commandline.option('outputpath')
+
+ inppath = inppath + '/' if not inppath.empty?
+ outpath = outpath + '/' if not outpath.empty?
+
+ prefix = @commandline.option('prefix')
+ suffix = @commandline.option('suffix')
+
+ inpfilename = "#{inppath}#{filename}"
+ outfilename = "#{outpath}#{prefix}#{filename.sub(/\.(.*?)$/, '')}#{suffix}.pdf"
+
+ inkscape.setvariable('inputfile' , inpfilename)
+ inkscape.setvariable('outputfile', outfilename)
+
+ if @commandline.option('verbose') || @commandline.option('debug') then
+ logname = filename.gsub(/\.[^\.]*?$/, '.log')
+ report("log info saved in #{logname}")
+ inkscape.convert(logname) # logname ook doorgeven
+ else
+ inkscape.convert
+ end
+
+ end
+
+ def handle_ghostscript(ghostscript,filename)
+
+ ghostscript.reset
+
+ method = ghostscript.method(@commandline.option('method'))
+ force = ghostscript.method(@commandline.option('force'))
+
+ ghostscript.setvariable('method', method)
+ ghostscript.setvariable('force', force)
+
+ # report("conversion method #{method}")
+
+ inppath = @commandline.option('inputpath')
+ outpath = @commandline.option('outputpath')
+
+ inppath = inppath + '/' if not inppath.empty?
+ outpath = outpath + '/' if not outpath.empty?
+
+ prefix = @commandline.option('prefix')
+ suffix = @commandline.option('suffix')
+
+ ok = false
+
+ if ghostscript.pdfmethod?(method) then
+
+ report("converting pdf file #{filename} into pdf")
+
+ if prefix.empty? && suffix.empty? && inppath.empty? && outpath.empty? then
+ prefix = ghostscript.pdfprefix(method)
+ end
+
+ if ghostscript.pdffile?(filename) then
+
+ filename = filename.sub(/\.pdf$/, '')
+
+ inpfilename = "#{inppath}#{filename}.pdf"
+ outfilename = "#{outpath}#{prefix}#{filename}#{suffix}.pdf"
+
+ ghostscript.setvariable('inputfile' ,inpfilename)
+ ghostscript.setvariable('outputfile',outfilename)
+
+ if FileTest.file?(inpfilename) then
+ ok = ghostscript.convert
+ else
+ report("no file found #{filename}")
+ end
+
+ else
+ report("no pdf file #{filename}")
+ end
+
+ elsif ghostscript.psfile?(filename) then
+
+ if filename =~ /(.*)\.(.*?)$/io then
+ filename, filesuffix = $1, $2
+ else
+ filesuffix = 'eps'
+ end
+
+ report("converting #{filesuffix} (ps) into pdf")
+
+ inpfilename = "#{inppath}#{filename}.#{filesuffix}"
+ outfilename = "#{outpath}#{prefix}#{filename}#{suffix}.pdf"
+
+ ghostscript.setvariable('inputfile' , inpfilename)
+ ghostscript.setvariable('outputfile', outfilename)
+
+ if FileTest.file?(inpfilename) then
+ ok = ghostscript.convert
+ if ! ok && FileTest.file?(outfilename) then
+ begin
+ File.delete(outfilename)
+ rescue
+ end
+ end
+ else
+ report("no file with name #{filename} found")
+ end
+
+ else
+ report('file must be of type eps/ps/ai/pdf')
+ end
+
+ return ok
+
+ end
+
+end
+
+# ook pdf -> pdf onder optie 0, andere kleurruimte
+
+logger = Logger.new(banner.shift)
+commandline = CommandLine.new
+
+commandline.registerflag('debug')
+commandline.registerflag('verbose')
+commandline.registerflag('nopipe')
+
+commandline.registervalue('method',2)
+commandline.registervalue('offset',0)
+
+commandline.registervalue('prefix')
+commandline.registervalue('suffix')
+
+commandline.registervalue('inputpath')
+commandline.registervalue('outputpath')
+
+commandline.registerflag('watch')
+commandline.registerflag('force')
+
+commandline.registervalue('delay',2)
+
+commandline.registervalue('colormodel','cmyk')
+commandline.registervalue('pattern','')
+
+commandline.registeraction('help')
+commandline.registeraction('version')
+
+commandline.registeraction('convert', 'convert ps into pdf')
+commandline.registeraction('request', 'handles exa request file')
+commandline.registeraction('watch', 'watch folders for conversions (untested)')
+
+commandline.expand
+
+logger.verbose if (commandline.option('verbose') || commandline.option('debug'))
+
+Commands.new(commandline,logger,banner).send(commandline.action || 'main')
diff --git a/scripts/context/ruby/newtexexec.rb b/scripts/context/ruby/newtexexec.rb
new file mode 100644
index 000000000..38c9675ca
--- /dev/null
+++ b/scripts/context/ruby/newtexexec.rb
@@ -0,0 +1,588 @@
+banner = ['TeXExec', 'version 6.0.1', '1997-2005', 'PRAGMA ADE/POD']
+
+unless defined? ownpath
+ ownpath = $0.sub(/[\\\/][a-z0-9\-]*?\.rb/i,'')
+ $: << ownpath
+end
+
+require 'base/switch'
+require 'base/logger'
+require 'base/variables'
+require 'base/system'
+
+require 'base/tex'
+
+require 'ftools' # needed ?
+
+require 'base/kpse' # needed ?
+require 'base/pdf' # needed ?
+require 'base/state' # needed ?
+require 'base/file' # needed ?
+
+class Commands
+
+ include CommandBase
+
+ 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')
+ if @commandline.arguments.length > 0 then
+ if @commandline.arguments.first == 'all' then
+ job.setvariable('texformats',job.defaulttexformats)
+ job.setvariable('mpsformats',job.defaultmpsformats)
+ else
+ job.setvariable('texformats',@commandline.arguments)
+ job.setvariable('mpsformats',@commandline.arguments)
+ end
+ end
+ job.makeformats
+ job.inspect && Kpse.inspect if @commandline.option('verbose')
+ end
+ end
+
+ def check
+ if job = TEX.new(logger) then
+ job.checkcontext
+ job.inspect && Kpse.inspect if @commandline.option('verbose')
+ end
+ end
+
+ def process
+ if job = TEX.new(logger) then
+ job.setvariable('files',@commandline.arguments)
+ prepare(job)
+ job.processtex
+ job.inspect && Kpse.inspect if @commandline.option('verbose')
+ 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)
+ prepare(job)
+ job.processmptex
+ job.inspect && Kpse.inspect if @commandline.option('verbose')
+ end
+ end
+
+ def mpxtex
+ if job = TEX.new(logger) then
+ job.setvariable('files',@commandline.arguments)
+ prepare(job)
+ job.processmpxtex
+ job.inspect && Kpse.inspect if @commandline.option('verbose')
+ end
+ end
+
+ # hard coded goodies # to be redone as s-ctx-.. with vars passed as such
+
+ def listing
+ if job = TEX.new(logger) then
+ prepare(job)
+ job.cleanuptemprunfiles
+ files = @commandline.arguments.sort
+ if files.length > 0 then
+ if f = File.open(job.tempfilename('tex'),'w') then
+ backspace = @commandline.checkedoption('backspace', '1.5cm')
+ topspace = @commandline.checkedoption('topspace', '1.5cm')
+ pretty = @commandline.option('pretty')
+ f << "% interface=english\n"
+ f << "\\setupbodyfont[11pt,tt]\n"
+ f << "\\setuplayout\n"
+ f << " [topspace=#{topspace},backspace=#{backspace},\n"
+ f << " header=0cm,footer=1.5cm,\n"
+ f << " width=middle,height=middle]\n"
+ f << "\\setuptyping[lines=yes]\n"
+ f << "\\setuptyping[option=color]\n" if pretty
+ f << "\\starttext\n";
+ files.each do |filename|
+ report("list file: #{filename}")
+ cleanname = cleantexfilename(filename).downcase
+ f << "\\page\n"
+ f << "\\setupfootertexts[\\tttf #{cleanname}][\\tttf \\pagenumber]\n"
+ f << "\\typefile{#{filename}}\n"
+ end
+ f << "\\stoptext\n"
+ f.close
+ job.setvariable('interface','english')
+ job.setvariable('simplerun',true)
+ job.setvariable('files',[job.tempfilename])
+ job.processtex
+ else
+ report('no files to list')
+ end
+ else
+ report('no files to list')
+ end
+ job.cleanuptemprunfiles
+ end
+ end
+
+ def figures
+ # this one will be redone using rlxtools
+ if job = TEX.new(logger) then
+ prepare(job)
+ job.cleanuptemprunfiles
+ files = @commandline.arguments.sort
+ if files.length > 0 then
+ if f = File.open(job.tempfilename('tex'),'w') then
+ job.runtexutil(files,"--figures")
+ figures = @commandline.checkedoption('method', 'a').downcase
+ paperoffset = @commandline.checkedoption('paperoffset', '0pt')
+ backspace = @commandline.checkedoption('backspace', '1.5cm')
+ topspace = @commandline.checkedoption('topspace', '1.5cm')
+ boxtype = @commandline.checkedoption('boxtype','')
+ f << "% format=english\n";
+ f << "\\setuplayout\n";
+ f << " [topspace=#{topspace},backspace=#{backspace},\n"
+ f << " header=1.5cm,footer=0pt,\n";
+ f << " width=middle,height=middle]\n";
+ if @commandline.option('fullscreen') then
+ f << "\\setupinteraction\n";
+ f << " [state=start]\n";
+ f << "\\setupinteractionscreen\n";
+ f << " [option=max]\n";
+ end
+ boxtype += "box" unless boxtype.empty? || (boxtype =~ /box$/io)
+ f << "\\starttext\n";
+ f << "\\showexternalfigures[alternative=#{figures},offset=#{paperoffset},size=#{boxtype}]\n";
+ f << "\\stoptext\n";
+ f.close
+ job.setvariable('interface','english')
+ job.setvariable('simplerun',true)
+ job.setvariable('files',[job.tempfilename])
+ job.processtex
+ File.silentdelete('texutil.tuf')
+ else
+ report('no figures to show')
+ end
+ else
+ report('no figures to show')
+ end
+ job.cleanuptemprunfiles
+ end
+ end
+
+ def modules
+ msuffixes = ['tex','mp','pl','pm','rb']
+ if job = TEX.new(logger) then
+ prepare(job)
+ job.cleanuptemprunfiles
+ files = @commandline.arguments.sort
+ if files.length > 0 then
+ files.each do |fname|
+ fnames = Array.new
+ if FileTest.file?(fname) then
+ fnames << fname
+ else
+ msuffixes.each do |fsuffix|
+ fnames << File.suffixed(fname,fsuffix)
+ end
+ end
+ fnames.each do |ffname|
+ if msuffixes.include?(File.splitname(ffname)[1]) && FileTest.file?(ffname) then
+ if mod = File.open(job.tempfilename('tex'),'w') then
+ job.runtexutil(ffname,"--documents")
+ if ted = File.silentopen(File.suffixed(ffname,'ted')) then
+ firstline = ted.gets
+ if firstline =~ /interface=/o then
+ mod << firstline
+ else
+ mod << "% interface=en\n"
+ end
+ ted.close
+ else
+ mod << "% interface=en\n"
+ end
+ mod << "\\usemodule[abr-01,mod-01]\n"
+ mod << "\\def\\ModuleNumber{1}\n"
+ mod << "\\starttext\n"
+ # todo: global file too
+ mod << "\\readlocfile{#{File.suffixed(ffname,'ted')}}{}{}\n"
+ mod << "\\stoptext\n"
+ mod.close
+ job.setvariable('interface','english') # redundant
+ job.setvariable('simplerun',true)
+ job.setvariable('files',[job.tempfilename])
+ job.processtex
+ ["dvi", "pdf","tuo"].each do |s|
+ File.silentrename(job.tempfilename(s),File.suffixed(ffname,s));
+ end
+ end
+ end
+ end
+ end
+ else
+ report('no modules to process')
+ end
+ job.cleanuptemprunfiles
+ end
+ end
+
+ def arrange
+ if job = TEX.new(logger) then
+ prepare(job)
+ job.cleanuptemprunfiles
+ files = @commandline.arguments.sort
+ if files.length > 0 then
+ if f = File.open(job.tempfilename('tex'),'w') then
+ emptypages = @commandline.checkedoption('addempty', '')
+ paperoffset = @commandline.checkedoption('paperoffset', '1cm')
+ textwidth = @commandline.checkedoption('textwidth', '0cm')
+ backspace = @commandline.checkedoption('backspace', '1.5cm')
+ topspace = @commandline.checkedoption('topspace', '1.5cm')
+ f << "\\definepapersize\n"
+ f << " [offset=#{paperoffset}]\n"
+ f << "\\setuplayout\n"
+ f << " [backspace=#{backspace},\n"
+ f << " topspace=#{topspace},\n"
+ f << " marking=on,\n" if @commandline.option('marking')
+ f << " width=middle,\n"
+ f << " height=middle,\n"
+ f << " location=middle,\n"
+ f << " header=0pt,\n"
+ f << " footer=0pt]\n"
+ unless @commandline.option('noduplex') then
+ f << "\\setuppagenumbering\n"
+ f << " [alternative=doublesided]\n"
+ end
+ f << "\\starttext\n"
+ files.each do |filename|
+ report("arranging file #{filename}")
+ f << "\\insertpages\n"
+ f << " [#{filename}]\n"
+ f << " [#{addempty}]\n" unless addempty.empty?
+ f << " [width=#{textwidth}]\n"
+ end
+ f << "\\stoptext\n"
+ f.close
+ job.setvariable('interface','english')
+ job.setvariable('simplerun',true)
+ job.setvariable('files',[job.tempfilename])
+ job.processtex
+ else
+ report('no files to arrange')
+ end
+ else
+ report('no files to arrange')
+ end
+ job.cleanuptemprunfiles
+ end
+ end
+
+ def select
+ if job = TEX.new(logger) then
+ prepare(job)
+ job.cleanuptemprunfiles
+ files = @commandline.arguments.sort
+ if files.length > 0 then
+ if f = File.open(job.tempfilename('tex'),'w') then
+ selection = @commandline.checkedoption('selection', '')
+ paperoffset = @commandline.checkedoption('paperoffset', '1cm')
+ textwidth = @commandline.checkedoption('textwidth', '0cm')
+ backspace = @commandline.checkedoption('backspace', '1.5cm')
+ topspace = @commandline.checkedoption('topspace', '1.5cm')
+ paperformat = @commandline.checkedoption('paperoffset', 'A4*A4').split(/[\*x]/o)
+ from, to = paperformat[0] || 'A4', paperformat[1] || paperformat[0] || 'A4'
+ f << "\\setuppapersize[#{from}][#{to}]\n"
+ f << "\\definepapersize\n";
+ f << " [offset=#{paperoffset}]\n";
+ f << "\\setuplayout\n";
+ f << " [backspace=#{backspace},\n";
+ f << " topspace=#{topspace},\n";
+ f << " marking=on,\n" if @commandline.option('marking')
+ f << " width=middle,\n";
+ f << " height=middle,\n";
+ f << " location=middle,\n";
+ f << " header=0pt,\n";
+ f << " footer=0pt]\n";
+ f << "\\setupexternalfigures\n";
+ f << " [directory=]\n";
+ f << "\\starttext\n";
+ unless selection.empty? then
+ f << "\\filterpages\n"
+ f << " [#{files.first}][#{selection}][width=#{textwidth}]\n"
+ end
+ f << "\\stoptext\n"
+ f.close
+ job.setvariable('interface','english')
+ job.setvariable('simplerun',true)
+ job.setvariable('files',[job.tempfilename])
+ job.processtex
+ else
+ report('no files to selectt')
+ end
+ else
+ report('no files to select')
+ end
+ job.cleanuptemprunfiles
+ end
+ end
+
+ def copy
+ copyortrim(false,'copy')
+ end
+
+ def trim
+ copyortrim(true,'trim')
+ end
+
+ def copyortrim(trim=false)
+ if job = TEX.new(logger) then
+ prepare(job)
+ job.cleanuptemprunfiles
+ files = @commandline.arguments.sort
+ if files.length > 0 then
+ if f = File.open(job.tempfilename('tex'),'w') then
+ scale = @commandline.checkedoption('scale')
+ scale = (scale * 1000).to_i if scale < 10
+ paperoffset = @commandline.checkedoption('paperoffset', '1cm')
+ f << "\\starttext\n"
+ files.each do |filename|
+ result = @commandline.checkedoption('result','texexec')
+ if (filename !~ /^texexec/io) && (filename !~ /^#{result}/) then
+ report("copying file: #{filename}")
+ f << "\\getfiguredimensions\n"
+ f << " [#{filename}]\n"
+ f << " [page=1"
+ f << ",\n size=trimbox" if trim
+ f << "]\n"
+ f << "\\definepapersize\n"
+ f << " [copy]\n"
+ f << " [width=\\naturalfigurewidth,\n"
+ f << " height=\\naturalfigureheight]\n"
+ f << "\\setuppapersize\n"
+ f << " [copy][copy]\n"
+ f << "\\setuplayout\n"
+ f << " [page]\n"
+ f << "\\setupexternalfigures\n"
+ f << " [directory=]\n"
+ f << "\\copypages\n"
+ f << " [#[filename}]\n"
+ f << " [scale=#{scale},\n"
+ f << " marking=on,\n" if @commandline.option('markings')
+ f << " size=trimbox,\n" if trim
+ f << " offset=#{paperoffset}]\n"
+ end
+ end
+ f << "\\stoptext\n"
+ f.close
+ job.setvariable('interface','english')
+ job.setvariable('simplerun',true)
+ job.setvariable('files',[job.tempfilename])
+ job.processtex
+ else
+ report("no files to #{what}")
+ end
+ else
+ report("no files to #{what}")
+ end
+ job.cleanuptemprunfiles
+ end
+ end
+
+ def combine
+ if job = TEX.new(logger) then
+ prepare(job)
+ job.cleanuptemprunfiles
+ files = @commandline.arguments.sort
+ if files.length > 0 then
+ if f = File.open(job.tempfilename('tex'),'w') then
+ paperoffset = @commandline.checkedoption('paperoffset', '1cm')
+ combination = @commandline.checkedoption('combination','2*2').split(/[\*x]/o)
+ paperformat = @commandline.checkedoption('paperoffset', 'A4*A4').split(/[\*x]/o)
+ 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"
+ if @commandline.option('nobanner') then
+ f << "\\setuplayout\n"
+ f << " [footer=0cm]\n"
+ end
+ f << "\\setupexternalfigures\n"
+ f << " [directory=]\n"
+ f << "\\starttext\n"
+ files.each do |filename|
+ result = @commandline.checkedoption('result','texexec')
+ 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"
+ f << "\\combinepages[#{filename}][nx=#{nx},ny=#{ny}]\n"
+ f << "\\page\n"
+ end
+ end
+ f << "\\stoptext\n"
+ f.close
+ job.setvariable('interface','english')
+ job.setvariable('simplerun',true)
+ job.setvariable('files',[job.tempfilename])
+ job.processtex
+ else
+ report('no files to list')
+ end
+ else
+ report('no files to list')
+ end
+ job.cleanuptemprunfiles
+ end
+ end
+
+ private
+
+ def prepare(job)
+
+ job.booleanvars.each do |k|
+ job.setvariable(k,@commandline.option(k))
+ end
+ job.stringvars.each do |k|
+ job.setvariable(k,@commandline.option(k))
+ end
+ job.standardvars.each do |k|
+ job.setvariable(k,@commandline.option(k))
+ end
+ job.knownvars.each do |k|
+ job.setvariable(k,@commandline.option(k)) unless @commandline.option(k).empty?
+ end
+
+ if (str = @commandline.option('engine')) && ! str.standard? && ! str.empty? then
+ job.setvariable('texengine',str)
+ elsif @commandline.oneof('pdfetex','pdftex','pdf') then
+ job.setvariable('texengine','pdfetex')
+ elsif @commandline.oneof('xetex','xtx') then
+ job.setvariable('texengine','xetex')
+ elsif @commandline.oneof('aleph') then
+ job.setvariable('texengine','aleph')
+ else
+ job.setvariable('texengine','standard')
+ end
+
+ if (str = @commandline.option('backend')) && ! str.standard? && ! str.empty? then
+ job.setvariable('backend',str)
+ elsif @commandline.oneof('pdfetex','pdftex','pdf') then
+ job.setvariable('backend','pdftex')
+ elsif @commandline.oneof('dvipdfmx','dvipdfm','dpx','dpm') then
+ job.setvariable('backend','dvipdfmx')
+ elsif @commandline.oneof('xetex','xtx') then
+ job.setvariable('backend','xetex')
+ elsif @commandline.oneof('aleph') then
+ job.setvariable('backend','dvipdfmx')
+ else
+ job.setvariable('backend','standard')
+ end
+
+ job.setvariable('mpsengine',@commandline.option('engine'))
+
+ end
+
+ def cleantexfilename(filename)
+ filename.gsub(/([\$\_\#])/) do "\\$1" end.gsub(/([\~])/) do "\\string$1" end
+ end
+
+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')
+commandline.registeraction('mptex', 'process mp file')
+commandline.registeraction('mpxtex', 'process mpx file')
+
+commandline.registeraction('listing', 'list of file content')
+commandline.registeraction('figures', 'generate overview of figures')
+commandline.registeraction('modules', 'generate module documentation')
+commandline.registeraction('arrange', 'impose pages (booklets)')
+commandline.registeraction('select', 'select pages from file(s)')
+commandline.registeraction('copy', 'copy pages from file(s)')
+commandline.registeraction('trim', 'trim pages from file(s)')
+commandline.registeraction('combine', 'combine multiple pages')
+
+@@extrastringvars = [
+ 'pages', 'background', 'backspace', 'topspace', 'boxtype', 'tempdir',
+ 'printformat', 'paperformat', 'method', 'scale', 'selection',
+ 'combination', 'paperoffset', 'textwidth', 'addempty', 'logfile',
+ 'startline', 'endline', 'startcolumn', 'endcolumn', 'scale'
+]
+
+@@extrabooleanvars = [
+ 'centerpage', 'noduplex', 'color', 'pretty',
+ 'fullscreen', 'screensaver', 'markings'
+]
+
+if job = TEX.new(logger) then
+
+ job.setextrastringvars(@@extrastringvars)
+ job.setextrabooleanvars(@@extrabooleanvars)
+
+ job.booleanvars.each do |k|
+ commandline.registerflag(k)
+ end
+ job.stringvars.each do |k|
+ commandline.registervalue(k,'')
+ end
+ job.standardvars.each do |k|
+ commandline.registervalue(k,'standard')
+ end
+ job.knownvars.each do |k|
+ commandline.registervalue(k,'')
+ end
+
+end
+
+# todo: register flags -> first one true
+
+commandline.registerflag('pdf')
+commandline.registerflag('pdftex')
+commandline.registerflag('pdfetex')
+
+commandline.registerflag('dvipdfmx')
+commandline.registerflag('dvipdfm')
+commandline.registerflag('dpx')
+commandline.registerflag('dpm')
+
+commandline.registerflag('xetex')
+commandline.registerflag('xtx')
+
+commandline.registerflag('aleph')
+
+commandline.registerflag('all')
+commandline.registerflag('fast')
+
+# generic
+
+commandline.registeraction('help')
+commandline.registeraction('version')
+
+commandline.registerflag('verbose')
+
+commandline.expand
+
+Commands.new(commandline,logger,banner).send(commandline.action || 'main')
diff --git a/scripts/context/ruby/rlxtools.rb b/scripts/context/ruby/rlxtools.rb
new file mode 100644
index 000000000..a3f41b06b
--- /dev/null
+++ b/scripts/context/ruby/rlxtools.rb
@@ -0,0 +1,261 @@
+#!/usr/bin/env ruby
+
+# program : rlxtools
+# copyright : PRAGMA Advanced Document Engineering
+# version : 2004-2005
+# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
+
+banner = ['RlxTools', 'version 1.0.1', '2004/2005', 'PRAGMA ADE/POD']
+
+unless defined? ownpath
+ ownpath = $0.sub(/[\\\/][a-z0-9\-]*?\.rb/i,'')
+ $: << ownpath
+end
+
+require 'base/switch'
+require 'base/logger'
+require 'base/system'
+require 'base/kpse'
+
+require 'ftools'
+require 'rexml/document'
+
+class Commands
+
+ include CommandBase
+
+ # <?xml version='1.0 standalone='yes'?>
+ # <rl:manipulators>
+ # <rl:manipulator name='lowres' suffix='pdf'>
+ # <rl:step>
+ # texmfstart
+ # --verbose
+ # --iftouched=<rl:value name='path'/>/<rl:value name='file'/>,<rl:value name='path'/>/<rl:value name='prefix'/><rl:value name='file'/>
+ # pstopdf
+ # --method=5
+ # --inputpath=<rl:value name='path'/>
+ # --outputpath=<rl:value name='path'/>/<rl:value name='prefix'/>
+ # <rl:value name='file'/>
+ # </rl:step>
+ # </rl:manipulator>
+ # </rl:manipulators>
+ #
+ # <?xml version='1.0' standalone='yes'?>
+ # <rl:library>
+ # <rl:usage>
+ # <rl:type>figure</rl:type>
+ # <rl:state>found</rl:state>
+ # <rl:file>cow.pdf</rl:file>
+ # <rl:suffix>pdf</rl:suffix>
+ # <rl:path>.</rl:path>
+ # <rl:conversion>lowres</rl:conversion>
+ # <rl:prefix>lowres/</rl:prefix>
+ # <rl:width>276.03125pt</rl:width>
+ # <rl:height>200.75pt</rl:height>
+ # </rl:usage>
+ # </r:library>
+
+ def manipulate
+
+ procname = @commandline.argument('first') || ''
+ filename = @commandline.argument('second') || ''
+
+ procname = Kpse.found(procname)
+
+ if procname.empty? || ! FileTest.file?(procname) then
+ report('provide valid manipulator file')
+ elsif filename.empty? || ! FileTest.file?(filename) then
+ report('provide valid resource log file')
+ else
+ begin
+ data = REXML::Document.new(File.new(filename))
+ rescue
+ report('provide valid resource log file (xml error)')
+ return
+ end
+ begin
+ proc = REXML::Document.new(File.new(procname))
+ rescue
+ report('provide valid manipulator file (xml error)')
+ return
+ end
+ report("manipulator file: #{procname}")
+ report("resourcelog file: #{filename}")
+ begin
+ nofrecords, nofdone = 0, 0
+ REXML::XPath.each(data.root,"/rl:library/rl:usage") do |usage|
+ nofrecords += 1
+ variables = Hash.new
+ usage.elements.each do |e|
+ variables[e.name] = e.text.to_s
+ end
+ report("processing record #{nofrecords} (#{variables['file'] || 'noname'}: #{variables.size} entries)")
+ if conversion = variables['conversion'] then
+ report("testing for conversion #{conversion}")
+ if suffix = variables['suffix'] then
+ if file = variables['file'] then
+ report("conversion #{conversion} for suffix #{suffix} for file #{file}")
+ else
+ report("conversion #{conversion} for suffix #{suffix}")
+ end
+ pattern = "@name='#{conversion}' and @suffix='#{suffix}'"
+ if steps = REXML::XPath.first(proc.root,"/rl:manipulators/rl:manipulator[#{pattern}]") then
+ localsteps = steps.deep_clone
+ ['rl:old','rl:new'].each do |tag|
+ REXML::XPath.each(localsteps,tag) do |extras|
+ REXML::XPath.each(extras,"rl:value") do |value|
+ if name = value.attributes['name'] then
+ substititute(value,variables[name.to_s])
+ end
+ end
+ end
+ end
+ old = REXML::XPath.first(localsteps,"rl:old")
+ new = REXML::XPath.first(localsteps,"rl:new")
+ if old && new then
+ old, new = justtext(old.to_s), justtext(new.to_s)
+ variables['old'], variables['new'] = old, new
+ begin
+ [old,new].each do |d|
+ File.makedirs(File.dirname(d))
+ end
+ rescue
+ report("error during path creation")
+ end
+ report("old file #{old}")
+ report("new file #{new}")
+ level = if File.needsupdate(old,new) then 2 else 0 end
+ else
+ level = 1
+ end
+ if level>0 then
+ REXML::XPath.each(localsteps,"rl:step") do |command|
+ REXML::XPath.each(command,"rl:old") do |value|
+ replace(value,old)
+ end
+ REXML::XPath.each(command,"rl:new") do |value|
+ replace(value,new)
+ end
+ REXML::XPath.each(command,"rl:value") do |value|
+ if name = value.attributes['name'] then
+ substititute(value,variables[name.to_s])
+ end
+ end
+ str = justtext(command.to_s)
+ # str.gsub!(/(\.\/)+/io, '')
+ report("command #{str}")
+ System.run(str) unless @commandline.option('test')
+ report("synchronizing #{old} and #{new}")
+ File.syncmtimes(old,new) if level > 1
+ nofdone += 1
+ end
+ else
+ report("no need for a manipulation")
+ end
+ else
+ report("no manipulator found")
+ end
+ else
+ report("no suffix specified")
+ end
+ else
+ report("no conversion needed")
+ end
+ end
+ if nofdone > 0 then
+ jobname = filename.gsub(/\.(.*?)$/,'') # not 'tuo' here
+ tuoname = jobname + '.tuo'
+ if FileTest.file?(tuoname) && (f = File.open(tuoname,'a')) then
+ f.puts("%\n% number of rlx manipulations: #{nofdone}\n")
+ f.close
+ end
+ end
+ rescue
+ report('error in manipulating files')
+ end
+ begin
+ logname = "#{filename}.log"
+ File.delete(logname) if FileTest.file?(logname)
+ File.copy(filename,logname)
+ rescue
+ end
+ end
+
+ end
+
+ private
+
+ def justtext(str)
+ str = str.to_s
+ str.gsub!(/<[^>]*?>/o, '')
+ str.gsub!(/\s+/o, ' ')
+ str.gsub!(/&lt;/o, '<')
+ str.gsub!(/&gt;/o, '>')
+ str.gsub!(/&amp;/o, '&')
+ str.gsub!(/[\/\\]+/o, '/')
+ return str.strip
+ end
+
+ def substititute(value,str)
+ if str then
+ begin
+ if value.attributes.key?('method') then
+ str = filtered(str.to_s,value.attributes['method'].to_s)
+ end
+ if str.empty? && value.attributes.key?('default') then
+ str = value.attributes['default'].to_s
+ end
+ value.insert_after(value,REXML::Text.new(str.to_s))
+ rescue Exception
+ end
+ end
+ end
+
+ def replace(value,str)
+ if str then
+ begin
+ value.insert_after(value,REXML::Text.new(str.to_s))
+ rescue Exception
+ end
+ end
+ end
+
+ def filtered(str,method)
+
+ str = str.to_s # to be sure
+ case method
+ when 'name' then # no path, no suffix
+ case str
+ when /^.*[\\\/](.+?)\..*?$/o then $1
+ when /^.*[\\\/](.+?)$/o then $1
+ when /^(.*)\..*?$/o then $1
+ else str
+ end
+ when 'path' then if str =~ /^(.+)([\\\/])(.*?)$/o then $1 else '' end
+ when 'suffix' then if str =~ /^.*\.(.*?)$/o then $1 else '' end
+ when 'nosuffix' then if str =~ /^(.*)\..*?$/o then $1 else str end
+ when 'nopath' then if str =~ /^.*[\\\/](.*?)$/o then $1 else str end
+ else str
+ end
+ end
+
+end
+
+logger = Logger.new(banner.shift)
+commandline = CommandLine.new
+
+commandline.registeraction('manipulate', ' [--test] manipulatorfile resourselog')
+
+commandline.registeraction('help')
+commandline.registeraction('version')
+
+commandline.registerflag('test')
+
+commandline.expand
+
+Commands.new(commandline,logger,banner).send(commandline.action || 'help')
diff --git a/scripts/context/ruby/texmfstart.rb b/scripts/context/ruby/texmfstart.rb
index 3131c6780..120c73e80 100644
--- a/scripts/context/ruby/texmfstart.rb
+++ b/scripts/context/ruby/texmfstart.rb
@@ -2,7 +2,7 @@
# program : texmfstart
# copyright : PRAGMA Advanced Document Engineering
-# version : 1.05 - 2003/2004
+# version : 1.5.5 - 2003/2005
# author : Hans Hagen
#
# project : ConTeXt / eXaMpLe
@@ -24,17 +24,75 @@
# --exec => exec instead of system
# --iftouched=a,b => only if timestamp a<>b
+# we don't depend on other libs
+
require "rbconfig"
$mswindows = Config::CONFIG['host_os'] =~ /mswin/
$separator = File::PATH_SEPARATOR
-$version = "1.5.2"
+$version = "1.6.0"
if $mswindows then
require "win32ole"
require "Win32API"
+end
+
+exit if defined?(REQUIRE2LIB)
+
+$stdout.sync = true
+$stderr.sync = true
+
+$applications = Hash.new
+$suffixinputs = Hash.new
+$predefined = Hash.new
+
+$suffixinputs['pl'] = 'PERLINPUTS'
+$suffixinputs['rb'] = 'RUBYINPUTS'
+$suffixinputs['py'] = 'PYTHONINPUTS'
+$suffixinputs['jar'] = 'JAVAINPUTS'
+$suffixinputs['pdf'] = 'PDFINPUTS'
+
+$predefined['texexec'] = 'texexec.pl'
+$predefined['texutil'] = 'texutil.pl'
+$predefined['texfont'] = 'texfont.pl'
+$predefined['examplex'] = 'examplex.rb'
+$predefined['concheck'] = 'concheck.rb'
+$predefined['textools'] = 'textools.rb'
+$predefined['ctxtools'] = 'ctxtools.rb'
+$predefined['rlxtools'] = 'rlxtools.rb'
+$predefined['pdftools'] = 'pdftools.rb'
+$predefined['exatools'] = 'exatools.rb'
+$predefined['xmltools'] = 'xmltools.rb'
+$predefined['pstopdf'] = 'pstopdf.rb'
+
+$scriptlist = 'rb|pl|py|jar'
+$documentlist = 'pdf|ps|eps|htm|html'
+
+$crossover = true # to other tex tools, else only local
+
+$applications['unknown'] = ''
+$applications['perl'] = $applications['pl'] = 'perl'
+$applications['ruby'] = $applications['rb'] = 'ruby'
+$applications['python'] = $applications['py'] = 'python'
+$applications['java'] = $applications['jar'] = 'java'
+
+if $mswindows then
+ $applications['pdf'] = ['',"pdfopen --page #{$page} --file",'acroread']
+ $applications['html'] = ['','netscape','mozilla','opera','iexplore']
+ $applications['ps'] = ['','gview32','gv','gswin32','gs']
+else
+ $applications['pdf'] = ["pdfopen --page #{$page} --file",'acroread']
+ $applications['html'] = ['netscape','mozilla','opera']
+ $applications['ps'] = ['gview','gv','gs']
+end
+
+$applications['htm'] = $applications['html']
+$applications['eps'] = $applications['ps']
+
+if $mswindows then
+
GetShortPathName = Win32API.new('kernel32', 'GetShortPathName', ['P','P','N'], 'N')
GetLongPathName = Win32API.new('kernel32', 'GetLongPathName', ['P','P','N'], 'N')
@@ -92,7 +150,11 @@ class File
def File.needsupdate(oldname,newname)
begin
- return File.stat(oldname).mtime != File.stat(newname).mtime
+ if $mswindows then
+ return File.stat(oldname).mtime > File.stat(newname).mtime
+ else
+ return File.stat(oldname).mtime != File.stat(newname).mtime
+ end
rescue
return true
end
@@ -100,38 +162,25 @@ class File
def File.syncmtimes(oldname,newname)
begin
- t = File.mtime(oldname) # i'm not sure if the time is frozen, so we do it here
- File.utime(0,t,oldname,newname)
+ if $mswindows then
+ # does not work (yet)
+ else
+ t = File.mtime(oldname) # i'm not sure if the time is frozen, so we do it here
+ File.utime(0,t,oldname,newname)
+ end
rescue
end
end
-end
-
-$applications = Hash.new
-$suffixinputs = Hash.new
-$predefined = Hash.new
-
-$suffixinputs['pl'] = 'PERLINPUTS'
-$suffixinputs['rb'] = 'RUBYINPUTS'
-$suffixinputs['py'] = 'PYTHONINPUTS'
-$suffixinputs['jar'] = 'JAVAINPUTS'
-$suffixinputs['pdf'] = 'PDFINPUTS'
-
-$predefined['texexec'] = 'texexec.pl'
-$predefined['texutil'] = 'texutil.pl'
-$predefined['texfont'] = 'texfont.pl'
-$predefined['examplex'] = 'examplex.rb'
-$predefined['concheck'] = 'concheck.rb'
-$predefined['textools'] = 'textools.rb'
-$predefined['ctxtools'] = 'ctxtools.rb'
-$predefined['pdftools'] = 'pdftools.rb'
-$predefined['exatools'] = 'exatools.rb'
-$predefined['xmltools'] = 'xmltools.rb'
-$predefined['pstopdf'] = 'pstopdf.rb'
+ def File.timestamp(name)
+ begin
+ "#{File.stat(name).mtime}"
+ rescue
+ return 'unknown'
+ end
+ end
-$scriptlist = 'rb|pl|py|jar'
-$documentlist = 'pdf|ps|eps|htm|html'
+end
def hashed (arr=[])
arg = if arr.class == String then arr.split(' ') else arr.dup end
@@ -158,7 +207,7 @@ end
def launch(filename)
if $browser && $mswindows then
- filename.gsub!(/\.[\/\\]/) do
+ filename = filename.gsub(/\.[\/\\]/) do
Dir.getwd + '/'
end
report("launching #{filename}")
@@ -172,54 +221,89 @@ def launch(filename)
end
def expanded(arg) # no "other text files", too restricted
- arg.gsub(/kpse\:(\S+)/o) do
- original, resolved = $1, ''
+ arg.gsub(/(env)\:([a-zA-Z\-\_\.0-9]+)/o) do
+ method, original, resolved = $1, $2, ''
+ if resolved = ENV[original] then
+ report("environment variable #{original} expands to #{resolved}") unless $report
+ resolved
+ else
+ report("environment variable #{original} cannot be resolved") unless $report
+ original
+ end
+ end . gsub(/(kpse|loc)\:([a-zA-Z\-\_\.0-9]+)/o) do # was: \S
+ method, original, resolved = $1, $2, ''
if $program && ! $program.empty? then
- pstr = "-progname=#{$program}"
+ pstrings = ["-progname=#{$program}"]
else
- pstr = ''
+ pstrings = ['','progname=context']
end
# auto suffix with texinputs as fall back
- begin
- resolved = `kpsewhich #{pstr} #{original}`.chomp
- rescue
- resolved = ''
- end
- # elsewhere in the tree
- if resolved.empty? then
- begin
- resolved = `kpsewhich #{pstr} -format="other text files" #{original}`.chomp
- rescue
- resolved = ''
- end
- end
- if resolved.empty? then
- report("#{original} is not resolved") unless $report
- original
- else
- report("#{original} is resolved to #{resolved}") unless $report
+ if ENV["_CTX_K_V_#{original}_"] then
+ resolved = ENV["_CTX_K_V_#{original}_"]
+ report("environment provides #{original} as #{resolved}") unless $report
resolved
+ else
+ pstrings.each do |pstr|
+ if resolved.empty? then
+ command = "kpsewhich #{pstr} #{original}"
+ report("running #{command}")
+ begin
+ resolved = `#{command}`.chomp
+ rescue
+ resolved = ''
+ end
+ end
+ # elsewhere in the tree
+ if resolved.empty? then
+ command = "kpsewhich #{pstr} -format=\"other text files\" #{original}"
+ report("running #{command}")
+ begin
+ resolved = `#{command}`.chomp
+ rescue
+ resolved = ''
+ end
+ end
+ end
+ if resolved.empty? then
+ report("#{original} is not resolved") unless $report
+ ENV["_CTX_K_V_#{original}_"] = original if $crossover
+ original
+ else
+ report("#{original} is resolved to #{resolved}") unless $report
+ ENV["_CTX_K_V_#{original}_"] = resolved if $crossover
+ resolved
+ end
end
end
end
def runcommand(command)
if $locate then
- print(command)
+ command = command.split(' ').collect do |c|
+ if c =~ /\//o then
+ begin
+ cc = File.expand_path(c)
+ c = cc if FileTest.file?(cc)
+ rescue
+ end
+ end
+ c
+ end . join(' ')
+ print command # to stdout and no newline
elsif $execute then
- report("using 'exec' instead of 'system' call: #{command}") if $verbose
+ report("using 'exec' instead of 'system' call: #{command}")
begin
Dir.chdir($path) if ! $path.empty?
rescue
- report("unable to chdir to: #{$path}") if $verbose
+ report("unable to chdir to: #{$path}")
end
exec(command)
else
- report("using 'system' call: #{command}") if $verbose
+ report("using 'system' call: #{command}")
begin
Dir.chdir($path) if ! $path.empty?
rescue
- report("unable to chdir to: #{$path}") if $verbose
+ report("unable to chdir to: #{$path}")
end
system(command)
end
@@ -230,29 +314,27 @@ def runoneof(application,fullname,browserpermitted)
return true
else
report("starting #{$filename}") unless $report
- print "\n" if $report && $verbose
+ ouput("\n") if $report && $verbose
applications = $applications[application]
if applications.class == Array then
if $report then
- print [fullname,expanded($arguments)].join(' ')
+ output([fullname,expanded($arguments)].join(' '))
return true
else
applications.each do |a|
- if runcommand([a,fullname,expanded($arguments)].join(' ')) then
- return true
- end
+ return true if runcommand([a,fullname,expanded($arguments)].join(' '))
end
end
elsif applications.empty? then
if $report then
- print [fullname,expanded($arguments)].join(' ')
+ output([fullname,expanded($arguments)].join(' '))
return true
else
return runcommand([fullname,expanded($arguments)].join(' '))
end
else
if $report then
- print [applications,fullname,expanded($arguments)].join(' ')
+ output([applications,fullname,expanded($arguments)].join(' '))
return true
else
return runcommand([applications,fullname,expanded($arguments)].join(' '))
@@ -263,7 +345,11 @@ def runoneof(application,fullname,browserpermitted)
end
def report(str)
- print str + "\n" if $verbose ;
+ $stderr.puts(str) if $verbose
+end
+
+def output(str)
+ $stderr.puts(str)
end
def usage
@@ -283,23 +369,35 @@ def usage
print(" texmfstart --page=2 --file=showcase.pdf\n")
print(" texmfstart --program=yourtex yourscript.pl arg-1 arg-2\n")
print(" texmfstart --direct xsltproc kpse:somefile.xsl somefile.xml\n")
- print(" texmfstart bin:xsltproc kpse:somefile.xsl somefile.xml\n")
+ print(" texmfstart bin:xsltproc env:somepreset kpse:somefile.xsl somefile.xml\n")
print(" texmfstart --iftouched=normal,lowres downsample.rb normal lowres\n")
end
# somehow registration does not work out (at least not under windows)
def registered?(filename)
- return ENV["texmfstart.#{filename}"] != nil
+ if $crossover then
+ return ENV["_CTX_K_S_#{filename}_"] != nil
+ else
+ return ENV["texmfstart.#{filename}"] != nil
+ end
end
def registered(filename)
- return ENV["texmfstart.#{filename}"]
+ if $crossover then
+ return ENV["_CTX_K_S_#{filename}_"]
+ else
+ return ENV["texmfstart.#{filename}"]
+ end
end
def register(filename,fullname)
if fullname && ! fullname.empty? then # && FileTest.file?(fullname)
- ENV["texmfstart.#{filename}"] = fullname
+ if $crossover then
+ ENV["_CTX_K_S_#{filename}_"] = fullname
+ else
+ ENV["texmfstart.#{filename}"] = fullname
+ end
return true
else
return false
@@ -307,6 +405,7 @@ def register(filename,fullname)
end
def find(filename,program)
+ filename = filename.sub(/script:/o, '') # so we have bin: and script: and nothing
if $predefined.key?(filename) then
report("expanding '#{filename}' to '#{$predefined[filename]}'")
filename = $predefined[filename]
@@ -333,13 +432,17 @@ def find(filename,program)
end
end
filename.sub!(/^.*[\\\/]/, '')
- # next we look at the current path
- suffixlist.each do |suffix|
- report("locating '#{filename}.#{suffix}' in currentpath")
- fullname = './'+filename+'.'+suffix
- if FileTest.file?(fullname) && register(filename,fullname) then
- report("'#{filename}.#{suffix}' located in currentpath")
- return shortpathname(fullname)
+ # next we look at the current path and the callerpath
+ ownpath = $0.sub(/[\\\/][a-z0-9\-]*?\.rb/i,'')
+ [['.','current'],[ownpath,'caller']].each do |p|
+ suffixlist.each do |suffix|
+ fname = "#{filename}.#{suffix}"
+ fullname = File.join(p[0],fname)
+ report("locating '#{fname}' in #{p[1]} path")
+ if FileTest.file?(fullname) && register(filename,fullname) then
+ report("'#{fname}' located in #{p[1]} path")
+ return shortpathname(fullname)
+ end
end
end
# now we consult environment settings
@@ -408,7 +511,18 @@ def find(filename,program)
return shortpathname(fullname) if register(filename,fullname)
end
end
- return fullname if register(filename,fullname)
+ return shortpathname(fullname) if register(filename,fullname)
+ # let's take a look at the path
+ paths = ENV['PATH'].split($separator)
+ suffixlist.each do |s|
+ paths.each do |p|
+ report("checking #{p} for suffix #{s}")
+ if FileTest.file?(File.join(p,"#{filename}.#{s}")) then
+ fullname = File.join(p,"#{filename}.#{s}")
+ return shortpathname(fullname) if register(filename,fullname)
+ end
+ end
+ end
# bad luck, we need to search the tree ourselves
if (suffixlist.length == 1) && (suffixlist.first =~ /(#{$documentlist})/) then
report("aggressively locating '#{filename}' in document trees")
@@ -540,78 +654,19 @@ def make(filename,windows=false,linux=false)
return false
end
-$stdout.sync = true
-$directives = hashed(ARGV)
-
-$help = $directives['help'] || false
-$filename = $directives['file'] || ''
-$program = $directives['program'] || 'context'
-$direct = $directives['direct'] || false
-$page = $directives['page'] || 0
-$browser = $directives['browser'] || false
-$report = $directives['report'] || false
-$verbose = $directives['verbose'] || false
-$arguments = $directives['arguments'] || ''
-$execute = $directives['execute'] || $directives['exec'] || false
-$locate = $directives['locate'] || false
-
-$path = $directives['path'] || ''
-
-$make = $directives['make'] || false
-$unix = $directives['unix'] || false
-$windows = $directives['windows'] || false
-$stubpath = $directives['stubpath'] || ''
-$indirect = $directives['indirect'] || false
-
-$iftouched = $directives['iftouched'] || false
-
-$openoffice = $directives['oo'] || false
-
-$applications['unknown'] = ''
-$applications['perl'] = $applications['pl'] = 'perl'
-$applications['ruby'] = $applications['rb'] = 'ruby'
-$applications['python'] = $applications['py'] = 'python'
-$applications['java'] = $applications['jar'] = 'java'
-
-if $openoffice then
- if ENV['OOPATH'] then
- if FileTest.directory?(ENV['OOPATH']) then
- report("using open office python") if $verbose
- if $mswindows then
- $applications['python'] = $applications['py'] = "\"#{File.join(ENV['OOPATH'],'program','python.bat')}\""
- else
- $applications['python'] = $applications['py'] = File.join(ENV['OOPATH'],'python')
- end
- report("python path #{$applications['python']}") if $verbose
- else
- report("environment variable 'OOPATH' does not exist") if $verbose
- end
- else
- report("environment variable 'OOPATH' is not set") if $verbose
- end
-end
-
-if $mswindows then
- $applications['pdf'] = ['',"pdfopen --page #{$page} --file",'acroread']
- $applications['html'] = ['','netscape','mozilla','opera','iexplore']
- $applications['ps'] = ['','gview32','gv','gswin32','gs']
-else
- $applications['pdf'] = ["pdfopen --page #{$page} --file",'acroread']
- $applications['html'] = ['netscape','mozilla','opera']
- $applications['ps'] = ['gview','gv','gs']
-end
-
-$applications['htm'] = $applications['html']
-$applications['eps'] = $applications['ps']
-
def process(&block)
if $iftouched then
files = $directives['iftouched'].split(',')
oldname, newname = files[0], files[1]
if oldname && newname && File.needsupdate(oldname,newname) then
+ report("file #{oldname}: #{File.timestamp(oldname)}")
+ report("file #{newname}: #{File.timestamp(newname)}")
+ report("file is touched, processing started")
yield
File.syncmtimes(oldname,newname)
+ else
+ report("file #{oldname} is untouched")
end
else
yield
@@ -619,29 +674,84 @@ def process(&block)
end
-# system("perl -V")
+def main
-if $help || ! $filename || $filename.empty? then
- usage
-else
- report("texmfstart version #{$version}") if $verbose
- if $make then
- if $windows then
- make($filename,true,false)
- elsif $unix then
- make($filename,false,true)
+ $directives = hashed(ARGV)
+
+ $help = $directives['help'] || false
+ $batch = $directives['batch'] || false
+ $filename = $directives['file'] || ''
+ $program = $directives['program'] || 'context'
+ $direct = $directives['direct'] || false
+ $page = $directives['page'] || 0
+ $browser = $directives['browser'] || false
+ $report = $directives['report'] || false
+ $verbose = $directives['verbose'] || (ENV['_CTX_VERBOSE_'] =~ /(y|yes|t|true|on)/io) || false
+ $arguments = $directives['arguments'] || ''
+ $execute = $directives['execute'] || $directives['exec'] || false
+ $locate = $directives['locate'] || false
+
+ $path = $directives['path'] || ''
+
+ $make = $directives['make'] || false
+ $unix = $directives['unix'] || false
+ $windows = $directives['windows'] || false
+ $stubpath = $directives['stubpath'] || ''
+ $indirect = $directives['indirect'] || false
+
+ $iftouched = $directives['iftouched'] || false
+
+ $openoffice = $directives['oo'] || false
+
+ $crossover = false if $directives['clear']
+
+ ENV['_CTX_VERBOSE_'] = 'yes' if $verbose
+
+ if $openoffice then
+ if ENV['OOPATH'] then
+ if FileTest.directory?(ENV['OOPATH']) then
+ report("using open office python")
+ if $mswindows then
+ $applications['python'] = $applications['py'] = "\"#{File.join(ENV['OOPATH'],'program','python.bat')}\""
+ else
+ $applications['python'] = $applications['py'] = File.join(ENV['OOPATH'],'python')
+ end
+ report("python path #{$applications['python']}")
+ else
+ report("environment variable 'OOPATH' does not exist")
+ end
else
- make($filename,$mswindows,!$mswindows)
+ report("environment variable 'OOPATH' is not set")
end
- elsif $browser && $filename =~ /^http\:\/\// then
- launch($filename)
+ end
+
+ if $help || ! $filename || $filename.empty? then
+ usage
+ elsif $batch && $filename && ! $filename.empty? then
+ # todo, take commands from file and avoid multiple starts and checks
else
- process do
- if $direct || $filename =~ /^bin\:/ then
- direct($filename)
+ report("texmfstart version #{$version}")
+ if $make then
+ if $windows then
+ make($filename,true,false)
+ elsif $unix then
+ make($filename,false,true)
else
- run(find(shortpathname($filename),$program))
+ make($filename,$mswindows,!$mswindows)
+ end
+ elsif $browser && $filename =~ /^http\:\/\// then
+ launch($filename)
+ else
+ process do
+ if $direct || $filename =~ /^bin\:/ then
+ direct($filename)
+ else # script: or no prefix
+ run(find(shortpathname($filename),$program))
+ end
end
end
end
+
end
+
+main
diff --git a/scripts/context/ruby/texsync.rb b/scripts/context/ruby/texsync.rb
index 37faf2b30..22b7d46c0 100644
--- a/scripts/context/ruby/texsync.rb
+++ b/scripts/context/ruby/texsync.rb
@@ -2,22 +2,29 @@
# program : texsync
# copyright : PRAGMA Advanced Document Engineering
-# version : 1.1 - 2003/2004
+# version : 2003-2005
# author : Hans Hagen
+#
+# project : ConTeXt / eXaMpLe
+# concept : Hans Hagen
+# info : j.hagen@xs4all.nl
+# www : www.pragma-ade.com
# For the moment this script only handles the 'minimal' context
# distribution. In due time I will add a few more options, like
# synchronization of the iso image.
-banner = ['TeXSync', 'version 1.1', '2002/2004', 'PRAGMA ADE/POD']
+banner = ['TeXSync', 'version 1.1.1', '2002/2004', 'PRAGMA ADE/POD']
unless defined? ownpath
ownpath = $0.sub(/[\\\/]\w*?\.rb/i,'')
$: << ownpath
end
-require 'xmpl/switch'
-require 'exa/logger'
+require 'base/switch'
+require 'base/logger'
+# require 'base/tool'
+
require 'rbconfig'
class Commands
@@ -134,7 +141,7 @@ class Commands
texpaths = ['texmf','texmf-local','texmf-fonts','texmf-mswin','texmf-linux','texmf-macos']
elsif option('terse') then
texpaths = ['texmf','texmf-local','texmf-fonts']
- case Config::CONFIG['host_os']
+ case Config::CONFIG['host_os'] # or: Tool.ruby_platform
when /mswin/ then texpaths.push('texmf-mswin')
when /linux/ then texpaths.push('texmf-linux')
when /darwin/ then texpaths.push('texmf-macosx')
@@ -176,7 +183,7 @@ class Commands
end
-logger = EXA::ExaLogger.new(banner.shift)
+logger = Logger.new(banner.shift)
commandline = CommandLine.new
commandline.registeraction('update', 'update installed tree')
diff --git a/scripts/context/ruby/textools.rb b/scripts/context/ruby/textools.rb
index a1880890d..7d23c7dbc 100644
--- a/scripts/context/ruby/textools.rb
+++ b/scripts/context/ruby/textools.rb
@@ -2,22 +2,28 @@
# program : textools
# copyright : PRAGMA Advanced Document Engineering
-# version : 1.1 - 2002/2004
+# version : 2002-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 = ['TeXTools', 'version 1.2', '2002/2004', 'PRAGMA ADE/POD']
+banner = ['TeXTools', 'version 1.2.1', '2002/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'
-require 'xmpl/switch'
-require 'exa/logger'
# Remark
#
@@ -717,7 +723,7 @@ class Commands
end
-logger = EXA::ExaLogger.new(banner.shift)
+logger = Logger.new(banner.shift)
commandline = CommandLine.new
commandline.registeraction('removemapnames' , '[pattern] [--recurse]')
diff --git a/scripts/context/ruby/xmltools.rb b/scripts/context/ruby/xmltools.rb
index be5bf814c..a57f74450 100644
--- a/scripts/context/ruby/xmltools.rb
+++ b/scripts/context/ruby/xmltools.rb
@@ -2,21 +2,26 @@
# program : xmltools
# copyright : PRAGMA Advanced Document Engineering
-# version : 1.0 - 2002/2004
+# version : 2002-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 = ['XMLTools', 'version 1.1', '2002/2004', 'PRAGMA ADE/POD']
+banner = ['XMLTools', 'version 1.1.1', '2002/2005', 'PRAGMA ADE/POD']
unless defined? ownpath
ownpath = $0.sub(/[\\\/][a-z0-9\-]*?\.rb/i,'')
$: << ownpath
end
-require 'xmpl/switch'
-require 'exa/logger'
+require 'base/switch'
+require 'base/logger'
class String
@@ -312,7 +317,7 @@ class Commands
end
-logger = EXA::ExaLogger.new(banner.shift)
+logger = Logger.new(banner.shift)
commandline = CommandLine.new
commandline.registeraction('dir', 'generate directory listing')