From 64393514fca3f8f070dcc0f95955d846780d82e0 Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Sun, 18 Dec 2005 00:00:00 +0100 Subject: stable 2005.12.18 --- scripts/context/lua/scite-ctx.lua | 8 +- scripts/context/perl/pdftrimwhite.pl | 531 +++++++++++++++++++++++++++++++++++ scripts/context/perl/texexec.pl | 20 +- scripts/context/perl/texexec.rme | 2 +- scripts/context/ruby/base/tex.rb | 11 +- scripts/context/ruby/runtools.rb | 493 ++++++++++++++++++++++++++++++++ 6 files changed, 1053 insertions(+), 12 deletions(-) create mode 100644 scripts/context/perl/pdftrimwhite.pl create mode 100644 scripts/context/ruby/runtools.rb (limited to 'scripts') diff --git a/scripts/context/lua/scite-ctx.lua b/scripts/context/lua/scite-ctx.lua index b9291fd00..3a19fb4d8 100644 --- a/scripts/context/lua/scite-ctx.lua +++ b/scripts/context/lua/scite-ctx.lua @@ -35,15 +35,15 @@ -- check=check_text -- -- ctx.spellcheck.language=auto --- ctx.spellcheck.wordsize=3 +-- ctx.spellcheck.wordsize=4 -- ctx.spellcheck.wordpath=ENV(CTXSPELLPATH) -- -- ctx.spellcheck.wordfile.all=spell-uk.txt,spell-nl.txt -- -- ctx.spellcheck.wordfile.uk=spell-uk.txt -- ctx.spellcheck.wordfile.nl=spell-nl.txt --- ctx.spellcheck.wordsize.uk=3 --- ctx.spellcheck.wordsize.nl=3 +-- ctx.spellcheck.wordsize.uk=4 +-- ctx.spellcheck.wordsize.nl=4 -- -- command.name.21.*=CTX Action List -- command.subsystem.21.*=3 @@ -487,7 +487,7 @@ local wordsize = props["ctx.spellcheck.wordsize"] local wordpath = props["ctx.spellcheck.wordpath"] if language == '' then language = 'uk' end -if wordsize == '' then wordsize = 3 else wordsize = tonumber(wordsize) end +if wordsize == '' then wordsize = 4 else wordsize = tonumber(wordsize) end local wordfile = "" local wordlist = {} diff --git a/scripts/context/perl/pdftrimwhite.pl b/scripts/context/perl/pdftrimwhite.pl new file mode 100644 index 000000000..e42a8fd49 --- /dev/null +++ b/scripts/context/perl/pdftrimwhite.pl @@ -0,0 +1,531 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' && eval 'exec perl -S $0 $argv:q' + if 0; + +#D \module +#D [ file=pdftrimwhite.pl, +#D version=2000.07.13, +#D title=PDF postprocessing, +#D subtitle=cropping whitespace from pdf files, +#D author=Hans Hagen, +#D date=\currentdate, +#D copyright=PRAGMA ADE] + +#C This module is part of the \CONTEXT\ macro||package and is +#C therefore copyrighted by \PRAGMA. See readme.pdf for +#C details. + +#D This script can be used to crop margins that contain +#D useless information from a \PDF\ image. It does so by: +#D +#D \startitemize[packed,n] +#D \som cropping the image into an alternative file +#D \som determining the boundingbox of the alternative +#D \som cropping the image into a resulting file +#D \stoppacked +#D +#D In the process, some checks are carried out. Step~1 is +#D taken care of by \PDFTEX, step~2 by \GHOSTSCRIPT, using a +#D file generated by \PDFTOPS, and \PDFTEX\ is responsible +#D for step~3. +#D +#D \startuseMPgraphic{original} +#D numeric n ; n = 1cm ; +#D path p ; p := fullsquare xyscaled (8n,12n) ; +#D path q ; q := fullsquare xyscaled (2n,3n) shifted (n,n) ; +#D path r ; r := ((0,0)--(3n,0)) shifted (0, 5.5n) ; +#D path s ; s := ((0,0)--(3n,0)) shifted (0,-5.5n) ; +#D path t ; t := (-2n,-4n) ; +#D path u ; u := p enlarged -.75n ; +#D path v ; v := p enlarged (-1.75n,-2n) shifted (n,1.25n) ; +#D path w ; w := q enlarged .25n ; +#D fill p withcolor .7white ; +#D fill q withcolor .7green ; +#D draw r withpen pencircle scaled .25n withcolor .7green ; +#D draw s withpen pencircle scaled .25n withcolor .7green ; +#D draw t withpen pencircle scaled .50n withcolor .7green ; +#D draw u withpen pencircle scaled .10n withcolor white ; +#D draw v withpen pencircle scaled .10n withcolor .7red ; +#D draw w withpen pencircle scaled .10n ; +#D verbatimtex \tttf \setupframed[frame=off,align=left] etex ; +#D label (btex \framed{crap} etex, center r) ; +#D label (btex \framed{crap} etex, center s) ; +#D label (btex \framed{crap} etex, center t) ; +#D label (btex \framed{graphic} etex, center q) ; +#D label.urt(btex \framed{page} etex, llcorner p) ; +#D label.urt(btex \framed{crop} etex, llcorner u) ; +#D label.lft(btex \framed{leftcrop\\ +#D rightcrop\\ +#D topcrop\\ +#D bottomcrop} etex, .5[ulcorner v,llcorner v]) ; +#D label.bot(btex \framed{offset} etex, .5[llcorner w,lrcorner w]) ; +#D \stopuseMPgraphic +#D +#D \placefigure +#D [here][fig:cropcrap] +#D {Crops and offsets.} +#D {\useMPgraphic{original}} +#D +#D The \TEX\ part has two alternatives, one using \CONTEXT, and +#D another using plain \TEX. The \CONTEXT\ method is slower but +#D can be extended more easily. +#D +#D The script is executed as follows: +#D +#D \starttyping +#D cropcrap [] [] +#D \stoptyping +#D +#D The next call crops \type {test.pdf} to its natural +#D boundingbox. +#D +#D \starttyping +#D cropcrap test +#D \stoptyping +#D +#D If the file has some crap at the bottom, you can say: +#D +#D \starttyping +#D cropcrap test --bottomcrop=2cm +#D \stoptyping +#D +#D This clips 2cm from the bottom. You can clip on all sides +#D individually, in combination or at once, like in: +#D +#D \starttyping +#D cropcrap test --bottomcrop=2cm --crop=1cm +#D \stoptyping +#D +#D The final result is a tightly cropped image. In order to get +#D a 5mm margin around this image, you can say: +#D +#D \starttyping +#D cropcrap test --bottomcrop=2cm --offset=5mm +#D \stoptyping +#D +#D By default, the script intercepts logging messages and +#D writes them to a logfile with the same name as the +#D resulting image and the prefix \type {log}. If no name is +#D given, the name \type {cropcrap} is used for all resulting +#D files. +#D +#D By default, \CONTEXT\ is used. When installed properly, you +#D can also use plain \TEX, by adding a switch \type +#D {--plain}. Partial switched are accepted, so the next call +#D is valid: +#D +#D \starttyping +#D cropcrap test result --bot=2cm --off=5mm --plain +#D \stoptyping +#D +#D The current implementation uses an intermediate \POSTSCRIPT\ +#D file. This may change as \GHOSTSCRIPT\ gets more clever with +#D \PDF\ files. +#D +#D In \in {figure} [fig:cropcrap] the green rectangle is the +#D picture we want to keep. Around this picture, we want a +#D margin, represented by the black rectangle, and specified by +#D \type {--offset}. The white rectangle is the cropbox +#D defined by \type {--crop}. That way we get rid of header +#D and footerlines. The red rectangle results from an +#D additional \type {--leftcrop} and \type {-bottomcrop} and +#D takes care of some content, as represented by the green +#D dot. +#D +#D The \type {--verbose} switch can be used to disable the +#D interception of log messages. + +#D We load a few \PERL\ modules \unknown\ + +use Config ; +use Getopt::Long ; + +use strict ; + +#D \unknown\ and initialize them. + +Getopt::Long::Configure + ("auto_abbrev", + "ignore_case", + "pass_through") ; + +#D Before fetching the switches, we initialize the +#D variables. + +my $Crop = "0cm" ; + +my $LeftCrop = "0cm" ; +my $RightCrop = "0cm" ; +my $TopCrop = "0cm" ; +my $BottomCrop = "0cm" ; + +my $Offset = "0cm" ; + +my $GSbin = "" ; +my $Verbose = 0 ; +my $Help = 0 ; +my $UsePlain = 0 ; + +my $Page = 1 ; + +#D On \MSWINDOWS\ and \UNIX\ the following defaults, combined +#D with the check later, should work out okay. + +my $pdfps = "pdftops" ; +my $gs = "gs" ; + +my $thisisunix = $Config{'osname'} !~ /dos|mswin/i ; + +#D When no resulting file is given, we use \type {cropcrap} +#D as name (checked later). + +my $figurefile = "" ; +my $resultfile = "" ; + +my $programname = "cropcrap" ; + +#D Messages are temporarily saved and written to a log file +#D afterwards. + +my $results = "" ; +my $pipe = "" ; +my $result = "" ; + +#D Unfortunately we need this information, first since +#D \PDFTOPS\ does not honor the cropbox, and second because +#D the vertical coordinated are swapped. + +my $pwidth = 597 ; +my $pheight = 847 ; +my $hoffset = 0 ; +my $voffset = 0 ; + +#D A few more variables. + +my $width = my $height = my $llx = my $lly = my $urx = my $ury = 0 ; + +#D Here are the switches we accept. The \type {--gsbin} switch +#D is a bonus one, and the \type {--help} switch comes +#D naturally. + +&GetOptions + ( "leftcrop=s" => \$LeftCrop , + "rightcrop=s" => \$RightCrop , + "topcrop=s" => \$TopCrop , + "bottomcrop=s" => \$BottomCrop, + "crop=s" => \$Crop , + "offset=s" => \$Offset , + "verbose" => \$Verbose , + "gsbin=s" => \$GSbin , + "plain" => \$UsePlain , + "page=i" => \$Page , + "help" => \$Help ) ; + +#D If asked for, or if no file is given, we provide some +#D help information. + +sub PrintHelp + { print "This is CropCrap\n\n" . + "usage:\n\n" . + "cropcrap [switches] filename result\n\n" . + "switches:\n\n" . + "--crop=\n" . + "--offset=\n" . + "--leftcrop=\n" . + "--rightcrop=\n" . + "--topcrop=\n" . + "--bottomcrop=\n" . + "--gsbin=\n" . + "--page=\n" . + "--plain\n" . + "--verbose\n" } + +#D The preparations: + +sub GetItRight + { if ($Help) + { PrintHelp() ; exit } + $figurefile = $ARGV[0] ; $figurefile =~ s/\.pdf$//oi ; + $resultfile = $ARGV[1] ; $resultfile =~ s/\.pdf$//oi ; + if ($figurefile eq '') + { PrintHelp() ; exit } + unless ($thisisunix) + { $gs = "gswin32c" } + if ($GSbin ne '') + { $gs = $GSbin } + unless (-e "$figurefile.pdf") + { print "Something is terribly wrong: no file found\n" ; + exit } + if (($resultfile eq '')||($resultfile=~/(^\-|\.)/io)) + { $resultfile = $programname } +$pipe = "2>&1" ; + if ($thisisunix) + { $pipe = "2>&1" } } + +#D Something common. + +sub SavePageData + { return "% saving page data +\\immediate\\openout\\scratchwrite=$figurefile.tmp +\\immediate\\write\\scratchwrite + {\\HOffsetBP\\space\\VOffsetBP\\space + \\FigureWidthBP\\space\\FigureHeightBP} +\\immediate\\closeout\\scratchwrite\n" } + +sub MakePageConTeXt + { return "% the real work +\\definepapersize + [Crap] + [width=\\FigureWidth, + height=\\FigureHeight] +\\setuppapersize + [Crap][Crap] +\\setuplayout + [topspace=0cm,backspace=0pt, + height=middle,width=middle, + header=0pt,footer=0pt] +\\starttext + \\startstandardmakeup + \\clip + [voffset=\\VOffset, + hoffset=\\HOffset, + width=\\FigureWidth, + height=\\FigureHeight] + {\\externalfigure[$figurefile.pdf][page=$Page]\\hss} + \\stopstandardmakeup +\\stoptext\n" } + +sub MakePagePlainTeX + { return "% the real work +\\output{} +\\hoffset=-1in +\\voffset=\\hoffset +\\pdfpageheight=\\FigureHeight +\\pdfpagewidth=\\FigureWidth +\\vbox to \\pdfpageheight + {\\offinterlineskip + \\vskip-\\VOffset + \\hbox to \\pdfpagewidth{\\hskip-\\HOffset\\box0\\hss} + \\vss} +\\end\n" } + +sub CalculateClip + { return "% some calculations +\\dimen0=\\figurewidth +\\dimen2=\\figureheight +\\dimen4=$Crop +\\dimen6=$Crop +\\advance\\dimen4 by $LeftCrop +\\advance\\dimen6 by $TopCrop +\\advance\\dimen0 by -\\dimen4 +\\advance\\dimen0 by -$Crop +\\advance\\dimen0 by -$RightCrop +\\advance\\dimen2 by -\\dimen6 +\\advance\\dimen2 by -$Crop +\\advance\\dimen2 by -$BottomCrop +\\edef\\FigureWidth {\\the\\dimen0} +\\edef\\FigureHeight{\\the\\dimen2} +\\edef\\HOffset {\\the\\dimen4} +\\edef\\VOffset {\\the\\dimen6} +\\ScaledPointsToWholeBigPoints{\\number\\dimen0}\\FigureWidthBP +\\ScaledPointsToWholeBigPoints{\\number\\dimen2}\\FigureHeightBP +\\ScaledPointsToWholeBigPoints{\\number\\dimen4}\\HOffsetBP +\\ScaledPointsToWholeBigPoints{\\number\\dimen6}\\VOffsetBP\n" } + +sub RecalculateClip + { return "% some calculations +\\dimen0=${width}bp +\\dimen2=${height}bp +\\dimen4=${hoffset}bp +\\dimen6=${pheight}bp +\\advance\\dimen0 by $Offset +\\advance\\dimen0 by $Offset +\\advance\\dimen2 by $Offset +\\advance\\dimen2 by $Offset +\\advance\\dimen4 by ${llx}bp +\\advance\\dimen4 by -$Offset +\\advance\\dimen6 by -${lly}bp +\\advance\\dimen6 by $Offset +\\advance\\dimen6 by -\\dimen2 +\\advance\\dimen6 by $TopCrop +\\edef\\FigureWidth {\\the\\dimen0} +\\edef\\FigureHeight{\\the\\dimen2} +\\edef\\HOffset {\\the\\dimen4} +\\edef\\VOffset {\\the\\dimen6}\n" } + +#D The previous scripts could be more sparse, but for the +#D moment we prefer readability. Both scripts save some +#D information in temporary file. We choose between them with +#D the following sub routine. + +#D The first pass: + +sub PrepareConTeXt + { return "% interface=en +\\setupoutput[pdftex] +\\getfiguredimensions[$figurefile.pdf][page=$Page]\n" } + +sub PreparePlainTeX + { return "% plain tex alternative, needs recent supp-mis +\\input supp-mis +\\pdfoutput=1 +\\newdimen\\figurewidth +\\newdimen\\figureheight +\\setbox0=\\hbox + {\\immediate\\pdfximage page $Page {$figurefile.pdf}\\pdfrefximage\\pdflastximage} +\\figurewidth=\\wd0 +\\figureheight=\\ht0\n" } + +sub PrepareFirstPass + { open (TEX, ">$resultfile.tex") ; + if ($UsePlain) + { print TEX + PreparePlainTeX . + CalculateClip . + SavePageData . + MakePagePlainTeX } + else + { print TEX + PrepareConTeXt . + CalculateClip . + SavePageData . + MakePageConTeXt } + close TEX } + +#D The second pass looks much like the first one, but this +#D time we don't save information, use the natural +#D boundingbox, and provide the offset. + +sub SetupConTeXt + { return "% interface=en +\\setupoutput[pdftex]\n" } + +sub SetupPlainTeX + { return "% plain tex alternative +\\pdfoutput=1 +\\setbox0=\\hbox + {\\immediate\\pdfximage page $Page {$figurefile.pdf}\\pdfrefximage\\pdflastximage}\n" } + +sub PrepareSecondPass + { open (TEX, ">$resultfile.tex") ; + if ($UsePlain) + { print TEX + SetupPlainTeX . + RecalculateClip . + MakePagePlainTeX } + else + { print TEX + SetupConTeXt . + RecalculateClip . + MakePageConTeXt } + close TEX } + +#D The information we save in the first pass, is loaded here. + +sub FetchPaperSize + { open (TMP,"$figurefile.tmp") ; + while () + { chomp ; + if (/^(\d+) (\d+) (\d+) (\d+) *$/oi) + { $hoffset = $1 ; + $voffset = $2 ; + $pwidth = $3 ; + $pheight = $4 ; + last } } + close (TMP) } + +#D Here we try to find the natural boundingbox. We need to +#D pick up the page dimensions here. + +sub RunTeX + { if ($UsePlain) + { $result = + `pdftex -prog=pdftex -fmt=plain -int=batchmode $resultfile` } + else + { $result = + `texexec --batch --once --purge $resultfile` } +# print $result if $Verbose ; $results .= "$result\n" ; +# $result = `texutil --purge` ; + print $result if $Verbose ; $results .= "$result\n" } + +sub MakePSFile + { $result = + `$pdfps -paperw $pwidth -paperh $pheight $resultfile.pdf $resultfile.ps` ; + print $result if $Verbose ; $results .= "$result\n" } + +sub FindBoundingBox + { $result = +# `$gs -sDEVICE=bbox -dNOPAUSE -dBATCH $resultfile.ps $pipe` ; + `$gs -sDEVICE=bbox -dNOPAUSE -dBATCH $resultfile.pdf $pipe` ; + print $result if $Verbose ; $results .= "$result\n" } + +sub IdentifyCropBox + { RunTeX() ; + FetchPaperSize () ; +# MakePSFile() ; + FindBoundingBox() } + +#D Just to be sure, we check if there is some image data, so +#D that we can retry if something went wrong. Unfortunately we cannot +#D safely check on a high res boundingbox. + +my $digits = '([\-\d\.]+)' ; + +sub ValidatedCropBox + { if ($result =~ /BoundingBox:\s*$digits\s+$digits\s+$digits\s+$digits\s*/mois) + { $llx = $1 ; $lly = $2 ; $urx = $3 ; $ury = $4 } + else + { print "Something is terribly wrong: no boundingbox:\n$result\n" ; exit } + $width = abs($urx - $llx) ; + $height = abs($ury - $lly) ; + if ($width&&$height) + { return 1 } + else + { unless ($width) + { print "Something seems wrong: no width\n" ; + $LeftCrop = "0cm" ; $RightCrop = "0cm" ; $Crop = "0cm" } + unless ($height) + { print "Something seems wrong: no height\n" ; + $TopCrop = "0cm" ; $BottomCrop = "0cm" ; $Crop = "0cm" } + return 0 } } + +#D This is the main cropping routine. + +sub FixCropBox + { RunTeX() } + +#D For error tracing we save the log information in a file. + +sub SaveLogInfo + { open (LOG, ">$resultfile.log") ; + print LOG $results ; + close (LOG) } + +#D We remove all temporary files. + +sub CleanUp + { unless ($Verbose) + { unlink "$resultfile.tex" ; + unlink "$resultfile.tuo" ; + unlink "$resultfile.tui" ; + unlink "$resultfile.ps" ; + unlink "$figurefile.tmp" } } + +#D Here it all comes together. + +GetItRight() ; + +PrepareFirstPass() ; + +IdentifyCropBox () ; + +unless (ValidatedCropBox()) + { PrepareFirstPass() ; + IdentifyCropBox () } + +if (ValidatedCropBox()) + { PrepareSecondPass() ; + FixCropBox() } + +SaveLogInfo() ; + +CleanUp () ; diff --git a/scripts/context/perl/texexec.pl b/scripts/context/perl/texexec.pl index a020727df..e60a7745f 100644 --- a/scripts/context/perl/texexec.pl +++ b/scripts/context/perl/texexec.pl @@ -11,7 +11,7 @@ eval '(exit $?0)' && eval 'exec perl -w -S $0 ${1+"$@"}' && eval 'exec perl -w - #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 therefore copyrighted by \PRAGMA. See readme.pdf for #C details. # Thanks to Tobias Burnus for the german translations. @@ -2010,7 +2010,11 @@ sub checktexformatpath { if ($texformats eq '') { if ($UseEnginePath) { if ($dosish) { - $texformats = `kpsewhich --engine=$TeXExecutable --expand-var=\$TEXFORMATS` ; + if ( $TeXShell =~ /MikTeX/io ) { + $texformats = `kpsewhich --alias=$TeXExecutable --expand-var=\$TEXFORMATS` ; + } else { + $texformats = `kpsewhich --engine=$TeXExecutable --expand-var=\$TEXFORMATS` ; + } } else { $texformats = `kpsewhich --engine=$TeXExecutable --expand-var=\\\$TEXFORMATS` ; } @@ -2365,7 +2369,11 @@ sub LocatedFormatPath { # watch out $engine is lowercase in kpse # expanded paths print " assuming engine : $EnginePath\n"; if (($UseEnginePath)&&($EngineDone)) { - $FormatPath = `$kpsewhich --engine=$EnginePath --show-path=fmt` ; + if ( $TeXShell =~ /MikTeX/io ) { + $FormatPath = `$kpsewhich --alias=$EnginePath --show-path=fmt` ; + } else { + $FormatPath = `$kpsewhich --engine=$EnginePath --show-path=fmt` ; + } } else { $FormatPath = `$kpsewhich --show-path=fmt` ; } @@ -2377,7 +2385,11 @@ sub LocatedFormatPath { # watch out $engine is lowercase in kpse if ($FormatPath eq '') { if (($UseEnginePath)&&($EngineDone)) { if ($dosish) { - $FormatPath = `$kpsewhich --engine=$EnginePath --expand-path=\$TEXFORMATS` ; + if ( $TeXShell =~ /MikTeX/io ) { + $FormatPath = `$kpsewhich --alias=$EnginePath --expand-path=\$TEXFORMATS` ; + } else { + $FormatPath = `$kpsewhich --engine=$EnginePath --expand-path=\$TEXFORMATS` ; + } } else { $FormatPath = `$kpsewhich --engine=$EnginePath --expand-path=\\\$TEXFORMATS` ; } diff --git a/scripts/context/perl/texexec.rme b/scripts/context/perl/texexec.rme index f38b4be7f..43f142f9d 100644 --- a/scripts/context/perl/texexec.rme +++ b/scripts/context/perl/texexec.rme @@ -120,7 +120,7 @@ for miktex set TeXVirginFlag to --initialize for miktex set TeXPassString to --alias=context --translate-file=natural.tcx for miktex set TeXBatchFlag to --interaction=batchmode for miktex set TeXNonStopFlag to --interaction=nonstopmode -for miktex set MpToTeXExecutable to mptotex +for miktex set MpToTeXExecutable to mpto for miktex set MpVirginFlag to --initialize for miktex set MpPassString to --alias=mpost --translate-file=natural.tcx for miktex set MpBatchFlag to --interaction=batchmode diff --git a/scripts/context/ruby/base/tex.rb b/scripts/context/ruby/base/tex.rb index a8a200b72..316cc6941 100644 --- a/scripts/context/ruby/base/tex.rb +++ b/scripts/context/ruby/base/tex.rb @@ -133,8 +133,8 @@ class TEX @@stringvars = [ 'modefile', 'result', 'suffix', 'response', 'path', 'filters', 'usemodules', 'environments', 'separation', 'setuppath', - 'arguments', 'input', 'output', 'randomseed', 'modes', 'filename', - 'modefile', 'ctxfile' + 'arguments', 'input', 'output', 'randomseed', 'modes', 'mode', 'filename', + 'ctxfile' ] @@standardvars = [ 'mainlanguage', 'bodyfont', 'language' @@ -939,8 +939,13 @@ class TEX end opt << "\\setuparranging[#{arrangement.flatten.join(',')}]\n" if arrangement.size > 0 end + # we handle both "--mode" and "--modes", else "--mode" is + # mapped onto "--modefile" if (str = getvariable('modes')) && ! str.empty? then - opt << "\\enablemode[#{modes}]\n" + opt << "\\enablemode[#{str}]\n" + end + if (str = getvariable('mode')) && ! str.empty? then + opt << "\\enablemode[#{str}]\n" end if (str = getvariable('arguments')) && ! str.empty? then opt << "\\setupenv[#{str}]\n" diff --git a/scripts/context/ruby/runtools.rb b/scripts/context/ruby/runtools.rb new file mode 100644 index 000000000..f554057f6 --- /dev/null +++ b/scripts/context/ruby/runtools.rb @@ -0,0 +1,493 @@ +require 'timeout' +require 'ftools' +require 'rbconfig' + +class File + + # we don't want a/b//c + # + # puts File.join('a','b','c') + # puts File.join('/a','b','c') + # puts File.join('a:','b','c') + # puts File.join('a/','/b/','c') + # puts File.join('/a','/b/','c') + # puts File.join('//a/','/b/','c') + + def File.join(*list) + path, prefix = [*list].flatten.join(File::SEPARATOR), '' + path.sub!(/^([\/]+)/) do + prefix = $1 + '' + end + path.gsub!(/([\\\/]+)/) do + File::SEPARATOR + end + prefix + path + end + +end + + +class Job + + $ownfile, $ownpath = '', '' + + def Job::set_own_path(file) + $ownfile, $ownpath = File.basename(file), File.expand_path(File.dirname(file)) + $: << $ownpath + end + + def Job::ownfile + $ownfile + end + + def Job::ownpath + $ownpath + end + +end + +class Job + + def initialize + @startuppath = Dir.getwd + @log = Array.new + @testmode = false + @ownpath = $ownpath + @paths = Array.new + end + + def exit(showlog=false) + Dir.chdir(@startuppath) + show_log if showlog + Kernel::exit + end + + def platform + case Config::CONFIG['host_os'] + when /mswin/ then :windows + else :unix + end + end + + def path(*components) + File.join([*components].flatten) + end + + def found(name) + FileTest.file?(path(name)) || FileTest.directory?(path(name)) + end + + def binary(name) + if platform == :windows then + name.sub(/\.[^\/]+$/o,'') + '.exe' + else + name + end + end + + def suffixed(name,suffix) + if name =~ /\.[^\/]+$/o then + name + else + name + '.' + suffix + end + end + + def expanded(*name) + File.expand_path(File.join(*name)) + end + + def argument(n,default=nil) + ARGV[n] || default + end + + def variable(name,default='') + ENV[name] || default + end + + def change_dir(*dir) + dir, old = expanded(path(*dir)), expanded(Dir.getwd) + unless old == dir then + begin + Dir.chdir(dir) + rescue + error("unable to change to path #{dir}") + else + if old == dir then + error("error in changing to path #{dir}") + else + message("changed to path #{dir}") + end + end + end + # return File.expand_path(Dir.getwd) + end + + def delete_dir(*dir) + begin + dir = path(*dir) + pattern = "#{dir}/**/*" + puts("analyzing dir #{pattern}") + files = Dir.glob(pattern).sort.reverse + files.each do |f| + begin + # FileTest.file?(f) fails on .whatever files + File.delete(f) + rescue + # probably directory + else + puts("deleting file #{f}") + end + end + files.each do |f| + begin + Dir.rmdir(f) + rescue + # strange + else + message("deleting path #{f}") + end + end + begin + Dir.rmdir(dir) + rescue + # strange + else + message("deleting parent #{dir}") + end + Dir.glob(pattern).sort.each do |f| + warning("unable to delete #{f}") + end + rescue + warning("unable to delete path #{File.expand_path(dir)} (#{$!})") + else + message("path #{File.expand_path(dir)} removed") + end + end + + + def create_dir(*dir) + begin + dir = path(*dir) + unless FileTest.directory?(dir) then + File.makedirs(dir) + else + return + end + rescue + error("unable to create path #{File.expand_path(dir)}") + else + message("path #{File.expand_path(dir)} created") + end + end + + def show_dir(delay=0) + _puts_("\n") + print Dir.getwd + ' ' + begin + timeout(delay) do + loop do + print '.' + sleep(1) + end + end + rescue TimeoutError + # ok + end + _puts_("\n\n") + end + + def copy_file(from,to='.',exclude=[]) + to, ex = path(to), [exclude].flatten + Dir.glob(path(from)).each do |file| + tofile = to.sub(/[\.\*]$/o) do File.basename(file) end + _do_copy_(file,tofile) unless ex.include?(File.extname(file)) + end + end + + def clone_file(from,to) + if from and to then + to = File.join(File.basename(from),to) if File.basename(to).empty? + _do_copy_(from,to) + end + end + + def copy_dir(from,to,pattern='*',exclude=[]) + pattern = '*' if ! pattern or pattern.empty? + if from and to and File.expand_path(from) != File.expand_path(to) then + ex = [exclude].flatten + Dir.glob("#{from}/**/#{pattern}").each do |file| + unless ex.include?(File.extname(file)) then + _do_copy_(file,File.join(to,file.sub(/^#{from}/, ''))) + end + end + end + end + + def _do_copy_(file,tofile) + if FileTest.file?(file) and File.expand_path(file) != File.expand_path(tofile) then + begin + create_dir(File.dirname(tofile)) + File.copy(file,tofile) + rescue + error("unable to copy #{file} to #{tofile}") + else + message("file #{file} copied to #{tofile}") + end + else + puts("file #{file} is not copied") + end + end + + def rename_file(from,to) + from, to = path(from), path(to) + begin + File.move(from,to) + rescue + error("unable to rename #{from} to #{to}") + else + message("#{from} renamed to #{to}") + end + end + + def delete_file(pattern) + Dir.glob(path(pattern)).each do |file| + _do_delete_(file) + end + end + + def delete_files(*files) + [*files].flatten.each do |file| + _do_delete_(file) + end + end + + def _do_delete_(file) + if FileTest.file?(file) then + begin + File.delete(file) + rescue + error("unable to delete file #{file}") + else + message("file #{file} deleted") + end + else + message("no file #{File.expand_path(file)}") + end + end + + def show_log(filename=nil) + if filename then + begin + if f = File.open(filename,'w') then + @log.each do |line| + f.puts(line) + end + f.close + end + message("log data written to #{filename}") + rescue + error("unable to write log to #{filename}") + end + else + @log.each do |line| + _puts_(line) + end + end + end + + def _puts_(str) + begin + STDOUT.puts( str) + rescue + STDERR.puts("error while writing '#{str}' to terminal") + end + end + + def puts(message) + @log << message + _puts_(message) + end + + def error(message) + puts("! #{message}") + exit + end + + def warning(message) + puts("- #{message}") + end + + def message(message) + puts("+ #{message}") + end + + def export_variable(variable,value) + value = path(value) if value.class == Array + ENV[variable] = value + message("environment variable #{variable} set to #{value}") + return value + end + + def execute_command(*command) + begin + command = [*command].flatten.join(' ') + message("running '#{command}'") + _puts_("\n") + ok = system(command) + _puts_("\n") + if true then # ok then + message("finished '#{command}'") + else + error("error in running #{command}") + end + rescue + error("unable to run #{command}") + end + end + + def pipe_command(*command) + begin + command = [*command].flatten.join(' ') + message("running '#{command}'") + result = `#{command}` + _puts_("\n") + _puts_(result) + _puts_("\n") + rescue + error("unable to run #{command}") + end + end + + def execute_script(script) + script = suffixed(script,'rb') + script = path(script_path,File.basename(script)) unless found(script) + if found(script) then + begin + message("loading script #{script}") + load(script) + rescue + error("error in loading script #{script} (#{$!})") + else + message("script #{script} finished") + end + else + warning("no script #{script}") + end + end + + def execute_binary(*command) + command = [*command].flatten.join(' ').split(' ') + command[0] = binary(command[0]) + execute_command(command) + end + + def extend_path(pth) + export_variable('PATH',"#{path(pth)}#{File::PATH_SEPARATOR}#{ENV['PATH']}") + end + + def startup_path + @startuppath + end + + def current_path + Dir.getwd + end + + def script_path + @ownpath + end + + def push_path(newpath) + newpath = File.expand_path(newpath) + @paths.push(newpath) + change_dir(newpath) + end + + def pop_path + change_dir(if @paths.length > 0 then @paths.pop else @startuppath end) + end + + # runner = Runner.new + # runner.texmfstart('newtexexec.rb','--help') + + def texmfstart(name,args,verbose=false) + command = ['texmfstart',"#{'--verbose' if verbose}",name,args].flatten.join(' ') + system(command) + end + +end + +class Job + + # copied from texmfstart and patched (message/error), different name + + def use_tree(tree) + unless tree.empty? then + begin + setuptex = File.join(tree,'setuptex.tmf') + if FileTest.file?(setuptex) then + message("tex tree : #{setuptex}") + ENV['TEXPATH'] = tree.sub(/\/+$/,'') # + '/' + ENV['TMP'] = ENV['TMP'] || ENV['TEMP'] || ENV['TMPDIR'] || ENV['HOME'] + case RUBY_PLATFORM + when /(mswin|bccwin|mingw|cygwin)/i then ENV['TEXOS'] = ENV['TEXOS'] || 'texmf-mswin' + when /(linux)/i then ENV['TEXOS'] = ENV['TEXOS'] || 'texmf-linux' + when /(darwin|rhapsody|nextstep)/i then ENV['TEXOS'] = ENV['TEXOS'] || 'texmf-macosx' + # when /(netbsd|unix)/i then # todo + else # todo + end + ENV['TEXMFOS'] = "#{ENV['TEXPATH']}/#{ENV['TEXOS']}" + message("preset : TEXPATH => #{ENV['TEXPATH']}") + message("preset : TEXOS => #{ENV['TEXOS']}") + message("preset : TEXMFOS => #{ENV['TEXMFOS']}") + message("preset : TMP => #{ENV['TMP']}") + IO.readlines(File.join(tree,'setuptex.tmf')).each do |line| + case line + when /^[\#\%]/ then + # comment + when /^(.*?)\s+\=\s+(.*)\s*$/ then + k, v = $1, $2 + ENV[k] = v.gsub(/\%(.*?)\%/) do + ENV[$1] || '' + end + message("user set : #{k} => #{ENV[k]}") + end + end + else + error("no setup file '#{setuptex}'") + end + rescue + warning("error in setup: #{$!}") + end + end + end + +end + +Job::set_own_path($0) + +if Job::ownfile == 'runtools.rb' then + + begin + script = ARGV.shift + if script then + script += '.rb' if File.extname(script).empty? + fullname = File.expand_path(script) + fullname = File.join(Job::ownpath,script) unless FileTest.file?(fullname) + if FileTest.file?(fullname) then + puts("loading script #{fullname}") + Job::set_own_path(fullname) + load(fullname) + else + puts("unknown script #{fullname}") + end + else + puts("provide script name") + end + rescue + puts("fatal error: #{$!}") + end + +end -- cgit v1.2.3