eval '(exit $?0)' && eval 'exec perl -w -S $0 ${1+"$@"}' && eval 'exec perl -w -S $0 $argv:q' if 0 ; #D \module #D [ file=texexec.pl, #D version=2004.08.29, #D title=running \ConTeXt, #D subtitle=\TEXEXEC, #D author=Hans Hagen, #D date=\currentdate, #D copyright={PRAGMA / Hans Hagen \& Ton Otten}] #C #C This module is part of the \CONTEXT\ macro||package and is #C therefore copyrighted by \PRAGMA. See licen-en.pdf for #C details. # Thanks to Tobias Burnus for the german translations. # Thanks to Thomas Esser for hooking it into web2c # Thanks to Taco Hoekwater for suggesting improvements # Thanks to Wybo Dekker for the advanced help interface and making it strict # Thanks to Fabrice Popineau for windows path trickery and fixes # (I still have to completely understand the help code -) #D We started with a hack provided by Thomas Esser. This #D expression replaces the unix specific line \type #D {#!/usr/bin/perl}. #D History has learned that writing wrappers like this is quite painful #D because of differences between platforms, changes in the tex command #D line flags (fmt), default behaviour (e.g. 8 bit), and the assumption #D that everyone runs the same tex and that distributers take care of #D everything. Well, the result is a messy script like this ... Sorry. use strict ; #~ use warnings ; # strange warnings, todo # todo: second run of checksum of mp file with --nomprun changes # todo: warning if no args # todo: <<<< in messages # todo: cleanup use Cwd; use Time::Local; use Config; use Getopt::Long; use Class::Struct; # needed for help subsystem use FindBin; use File::Compare; my %ConTeXtInterfaces; # otherwise problems with strict my %ResponseInterface; # since i dunno how to allocate else my %Help; #D In this script we will launch some programs and other #D scripts. \TEXEXEC\ uses an ini||file to sort out where #D those programs are stored. Two boolean variables keep #D track of the way to call the programs. In \TEXEXEC, #D \type {$dosish} keeps track of the operating system. #D It will be no surprise that Thomas Esser provided me #D the neccessary code to accomplish this. $ENV{"MPXCOMMAND"} = "0"; # otherwise loop my $TotalTime = time; # start random seed hack # # This hack is needed since tex has 1 minute resolution, so # we need to be smaller about 1440 (== 24*60 == tex's max time) # in which case (david a's) random calculator will overflow. # my ( $sec, $min, $rest ) = gmtime; # my $RandomSeed = $min * 60 + $sec; # # # i have to look up the mod function -) # # if ( $RandomSeed > 2880 ) { $RandomSeed -= 2880 } # if ( $RandomSeed > 1440 ) { $RandomSeed -= 1440 } my ($sec, $min) = gmtime; my $RandomSeed = ($min * 60 + $sec) % 2880; # else still overflow # See usage of $Random and $RandomSeed later on. # # end random seed hack my $dosish = ( $Config{'osname'} =~ /^(ms)?dos|^os\/2|^mswin/i ); my $escapeshell = ( ($ENV{'SHELL'}) && ($ENV{'SHELL'} =~ m/sh/i )); my $TeXUtil = 'texutil'; my $TeXExec = 'texexec'; my $MetaFun = 'metafun'; my $MpToPdf = 'mptopdf'; $Getopt::Long::passthrough = 1; # no error message $Getopt::Long::autoabbrev = 1; # partial switch accepted my $AddEmpty = ''; my $Alone = 0; my $Optimize = 0; my $ForceTeXutil = 0; my $Arrange = 0; my $BackSpace = '0pt'; my $Background = ''; my $CenterPage = 0; my $ConTeXtInterface = 'unknown'; my $Convert = ''; my $DoMPTeX = 0; my $DoMPXTeX = 0; my $EnterBatchMode = 0; my $EnterNonStopMode = 0; my $Environments = ''; my $Modules = ''; my $FastMode = 0; my $FinalMode = 0; my $Format = ''; my $MpDoFormat = ''; my $HelpAsked = 0; my $Version = 0; my $MainBodyFont = 'standard'; my $MainLanguage = 'standard'; my $MainResponse = 'standard'; my $MakeFormats = 0; my $Markings = 0; my $Mode = ''; my $NoArrange = 0; my $NoDuplex = 0; my $NOfRuns = 8; my $NoMPMode = 0; my $NoMPRun = 0; my $NoBanner = 0; my $AutoMPRun = 0; my $OutputFormat = 'standard'; my $Pages = ''; my $PageScale = '1000'; # == 1.0 my $PaperFormat = 'standard'; my $PaperOffset = '0pt'; my $PassOn = ''; my $PdfArrange = 0; my $PdfSelect = 0; my $PdfCombine = 0; my $PdfOpen = 0; my $PdfClose = 0; my $AutoPdf = 0; my $PrintFormat = 'standard'; my $ProducePdfT = 0; my $ProducePdfM = 0; my $ProducePdfX = 0; my $ProducePdfXTX = 0; my $Input = ""; my $Result = ''; my $Suffix = ''; my $RunOnce = 0; my $Selection = ''; my $Combination = '2*4'; my $SilentMode = 0; my $TeXProgram = ''; my $TeXTranslation = ''; my $TextWidth = '0pt'; my $TopSpace = '0pt'; my $TypesetFigures = 0; my $ForceFullScreen = 0; my $ScreenSaver = 0; my $TypesetListing = 0; my $TypesetModule = 0; my $UseColor = 0; my $Verbose = 0; my $PdfCopy = 0; my $PdfTrim = 0; my $LogFile = ""; my $MpyForce = 0; my $InpPath = ""; my $AutoPath = 0; my $RunPath = ""; my $Arguments = ""; my $Pretty = 0; my $SetFile = ""; my $TeXTree = ""; my $TeXRoot = ""; my $Purge = 0; my $Separation = ""; my $ModeFile = ""; my $GlobalFile = 0; my $AllPatterns = 0; my $ForceXML = 0; my $Random = 0; my $Filters = ''; my $NoMapFiles = 0 ; my $Foxet = 0 ; my $TheEnginePath = 0 ; my $Paranoid = 0 ; my $NotParanoid = 0 ; my $StartLine = 0 ; my $StartColumn = 0 ; my $EndLine = 0 ; my $EndColumn = 0 ; # makempy : my $MakeMpy = ''; &GetOptions( "arrange" => \$Arrange, "batch" => \$EnterBatchMode, "nonstop" => \$EnterNonStopMode, "color" => \$UseColor, "centerpage" => \$CenterPage, "convert=s" => \$Convert, "environments=s" => \$Environments, "usemodules=s" => \$Modules, "xml" => \$ForceXML, "xmlfilters=s" => \$Filters, "fast" => \$FastMode, "final" => \$FinalMode, "format=s" => \$Format, "mpformat=s" => \$MpDoFormat, "help" => \$HelpAsked, "version" => \$Version, "interface=s" => \$ConTeXtInterface, "language=s" => \$MainLanguage, "bodyfont=s" => \$MainBodyFont, "results=s" => \$Result, "response=s" => \$MainResponse, "make" => \$MakeFormats, "mode=s" => \$Mode, "module" => \$TypesetModule, "figures=s" => \$TypesetFigures, "fullscreen" => \$ForceFullScreen, "screensaver" => \$ScreenSaver, "listing" => \$TypesetListing, "mptex" => \$DoMPTeX, "mpxtex" => \$DoMPXTeX, "noarrange" => \$NoArrange, "nomp" => \$NoMPMode, "nomprun" => \$NoMPRun, "nobanner" => \$NoBanner, "automprun" => \$AutoMPRun, "once" => \$RunOnce, "output=s" => \$OutputFormat, "pages=s" => \$Pages, "paper=s" => \$PaperFormat, "passon=s" => \$PassOn, "path=s" => \$InpPath, "autopath" => \$AutoPath, "pdf" => \$ProducePdfT, "pdm" => \$ProducePdfM, "pdx" => \$ProducePdfX, "xtx" => \$ProducePdfXTX, "pdfarrange" => \$PdfArrange, "pdfselect" => \$PdfSelect, "pdfcombine" => \$PdfCombine, "pdfcopy" => \$PdfCopy, "pdftrim" => \$PdfTrim, "scale=s" => \$PageScale, "selection=s" => \$Selection, "combination=s" => \$Combination, "noduplex" => \$NoDuplex, "paperoffset=s" => \$PaperOffset, "backspace=s" => \$BackSpace, "topspace=s" => \$TopSpace, "markings" => \$Markings, "textwidth=s" => \$TextWidth, "addempty=s" => \$AddEmpty, "background=s" => \$Background, "logfile=s" => \$LogFile, "print=s" => \$PrintFormat, "suffix=s" => \$Suffix, "runs=s" => \$NOfRuns, "silent" => \$SilentMode, "tex=s" => \$TeXProgram, "verbose" => \$Verbose, "alone" => \$Alone, "optimize" => \$Optimize, "texutil" => \$ForceTeXutil, "mpyforce" => \$MpyForce, "input=s" => \$Input, "arguments=s" => \$Arguments, "pretty" => \$Pretty, "setfile=s" => \$SetFile, # obsolete "purge" => \$Purge, #### yet undocumented ################# "runpath=s" => \$RunPath, "random" => \$Random, "makempy=s" => \$MakeMpy, "allpatterns" => \$AllPatterns, "separation=s" => \$Separation, "textree=s" => \$TeXTree, "texroot=s" => \$TeXRoot, "translate=s" => \$TeXTranslation, "pdfclose" => \$PdfClose, "pdfopen" => \$PdfOpen, "autopdf" => \$AutoPdf, "modefile=s" => \$ModeFile, # additional modes file "globalfile" => \$GlobalFile, "nomapfiles" => \$NoMapFiles, "foxet" => \$Foxet, "engine" => \$TheEnginePath, "paranoid" => \$Paranoid, "notparanoid" => \$NotParanoid, #### experiment "startline=s" => \$StartLine, "startcolumn=s" => \$StartColumn, "endline=s" => \$EndLine, "endcolumn=s" => \$EndColumn ); # don't check name if ($Foxet) { $ProducePdfT = 1 ; $ForceXML = 1 ; $Modules = "foxet" ; $Purge = 1 ; } # a set file (like blabla.bat) can set paths now if ( $SetFile ne "" ) { load_set_file( $SetFile, $Verbose ); $SetFile = "" } # later we will do a second attempt. $SIG{INT} = "IGNORE"; if ( $ARGV[0] && $ARGV[0] =~ /\.mpx$/io ) { # catch -tex=.... bug in mpost $TeXProgram = ''; $DoMPXTeX = 1; $NoMPMode = 1; } #### if ($Paranoid) { $ENV{shell_escape} = 'f' ; $ENV{openout_any} = 'p' ; $ENV{openin_any} = 'p' ; } elsif ($NotParanoid) { $ENV{shell_escape} = 't' ; $ENV{openout_any} = 'p' ; $ENV{openin_any} = 'a' ; } if ($ENV{openin_any} eq 'p') { $Paranoid = 1 ; # extra test in order to set readlevel } if (($ENV{shell_escape} eq 'f') || ($ENV{SHELL_ESCAPE} eq 'f')) { $AutoMPRun = 1 ; } if ($ScreenSaver) { $ForceFullScreen = 1; $TypesetFigures = 'c'; $ProducePdfT = 1; $Purge = 1; } if ( $DoMPTeX || $DoMPXTeX ) { $RunOnce = 1; $ProducePdfT = 0; $ProducePdfX = 0; $ProducePdfM = 0; $ProducePdfXTX = 0; } if ( $PdfArrange || $PdfSelect || $PdfCopy || $PdfTrim || $PdfCombine ) { $ProducePdfT = 1; $RunOnce = 1; } if ($ProducePdfT) { $OutputFormat = "pdftex" } elsif ($ProducePdfM) { $OutputFormat = "dvipdfm" } elsif ($ProducePdfX) { $OutputFormat = "dvipdfmx" } elsif ($ProducePdfXTX) { $OutputFormat = "xetex" } if ( $ProducePdfXTX ) { $TeXProgram = 'xetex' ; # ignore the default pdfetex engine $PassOn .= ' -no-pdf ' ; # Adam Lindsay's preference } if ($AutoPdf) { $PdfOpen = $PdfClose = 1 ; } # this is our hook into paranoid path extensions, assumes that # these three vars are part of path specs in texmf.cnf foreach my $i ('TXRESOURCES','MPRESOURCES','MFRESOURCES') { foreach my $j ($RunPath,$InpPath) { if ($j ne '') { if ($ENV{$i} ne '') { $ENV{$i} = $ENV{$i} . ',' . $j ; } else { $ENV{$i} = $j ; } } } } if ( $RunOnce || $Pages || $TypesetFigures || $TypesetListing ) { $NOfRuns = 1 } if ( ( $LogFile ne '' ) && ( $LogFile =~ /\w+\.log$/io ) ) { open( LOGFILE, ">$LogFile" ); *STDOUT = *LOGFILE; *STDERR = *LOGFILE; } my $Program = " TeXExec 5.2.4 - ConTeXt / PRAGMA ADE 1997-2005"; print "\n$Program\n\n"; if ($Verbose) { print " current path : " . cwd . "\n" } my $pathslash = '/'; if ( $FindBin::Bin =~ /\\/ ) { $pathslash = "\\" } my $cur_path = ".$pathslash"; # we need to handle window's "Program Files" path (patch by Fabrice P) my $own_path = "$FindBin::Bin/"; my $own_type = $FindBin::Script; my $own_quote = ( $own_path =~ m/^[^\"].* / ? "\"" : "" ); my $own_stub = ""; if ( $own_type =~ /(\.pl|perl)/oi ) { $own_stub = "perl " } if ( $own_type =~ /(\.(pl|bin|exe))$/io ) { $own_type = $1 } else { $own_type = '' } sub checked_path { my $path = shift; if ( ( defined($path) ) && ( $path ne '' ) ) { $path =~ s/[\/\\]/$pathslash/go; $path =~ s/[\/\\]*$//go; $path .= $pathslash; } else { $path = ''; } return $path; } sub checked_file { my $path = shift; if ( ( defined($path) ) && ( $path ne '' ) ) { $path =~ s/[\/\\]/$pathslash/go; } else { $path = ''; } return $path; } sub CheckPath { my ( $Key, $Value ) = @_; if ( ( $Value =~ /\// ) && ( $Value !~ /\;/ ) ) # no multipath test yet { $Value = checked_path($Value); unless ( -d $Value ) { print " error : $Key set to unknown path $Value\n"; } } } # set to # for