diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/easylatex/easylatex.pl |
Initial commit
Diffstat (limited to 'support/easylatex/easylatex.pl')
-rw-r--r-- | support/easylatex/easylatex.pl | 434 |
1 files changed, 434 insertions, 0 deletions
diff --git a/support/easylatex/easylatex.pl b/support/easylatex/easylatex.pl new file mode 100644 index 0000000000..a440195f75 --- /dev/null +++ b/support/easylatex/easylatex.pl @@ -0,0 +1,434 @@ +#!/usr/bin/perl + +use English; +use Getopt::Declare; + + + +###################### +# ARGUMENT PROCESSING +###################### +#$inFilename = $ARGV[0]; + +use vars qw ($inFilename $POSTSCRIPT_OUTPUT $PDF_OUTPUT $PDFLATEX_OUTPUT $ALLOW_EMBEDDED_CODE $PARTIAL_DOCUMENT); + +use vars qw ($EASYLATEXSTORE_MAIN_RESERVED_WORD $StorageIndex); + +$StorageIndex = 0; + +$EASYLATEXSTORE_MAIN_RESERVED_WORD = 'EASYLATEXSTORE-MAIN-RESERVED-WORD'; + +#test4 + + +$argSpecification = q( + -ps Create a postscript output file (by calling latex, and then dvips) + {$POSTSCRIPT_OUTPUT = 1;} + + -pdf Create a pdf output file (by calling latex, and then dvipdf) + {$PDF_OUTPUT = 1;} + + -pdflatex Create a pdf output file (by calling pdflatex -- use this if there's screwy errors in the file generated by -pdf) + {$PDFLATEX_OUTPUT = 1;} + + --partial This file is not a full LaTeX document, just a partial one (to be \\include'd, for instance) + {$PARTIAL_DOCUMENT = 1;} + + -e Allow execution of embedded code (advanced feature) + {$ALLOW_EMBEDDED_CODE = 1;} + + <input> The input file + {$inFilename = $input;} + ); + + + +$args = new Getopt::Declare($argSpecification); + +#print "ARG: $inFilename\n $j\nPO: $POSTSCRIPT_OUTPUT, PDF: $PDF_OUTPUT"; + +###################### +# DEFINE GLOBAL CONSTANTS +###################### + +use vars qw($EASYLATEX_DIR @TRANSFORM_PATHS $PS_OUTPUT_COMMANDS $PDF_OUTPUT_COMMANDS $PDFLATEX_OUTPUT_COMMANDS $outFilename $stripFilename); + +# doing both ways; todo; clean up global var declr + +$PS_OUTPUT_COMMANDS = <<'EOF' ; +system('latex',$outFilename); +system('dvips',"${stripFilename}.dvi", "-o${stripFilename}.ps"); +EOF + +$PDF_OUTPUT_COMMANDS = <<'EOF' ; +system('latex',$outFilename); +system('dvipdf',"${stripFilename}.dvi"); +EOF + +$PDFLATEX_OUTPUT_COMMANDS = <<'EOF' ; + + +while ($out =~ /\{([^}]+?\.eps)\}/g) { + push(@eps_files_to_convert, $1); +} + +$out =~ s/\{([^}]+?)\.eps\}/{\1.pdf}/g; +foreach $file (@eps_files_to_convert) { + system('epstopdf', $file); +} + +open(OUT, '>'.$outFilename); +print OUT $out; +close(OUT); + +system('pdflatex',$outFilename); +EOF + + +# +# I'll assume most distos have psfrag and leave this out for now... +# +# use Cwd; +#$cwd = cwd(); +#$ENV{TEXINPUTS} .= ":$cwd/psfrag"; +#$ENV{DVIPSHEADERS} .= ":$cwd/psfrag"; + + +###################### +# MAIN +###################### + +init(); + +$in = readFile($inFilename); +$stripFilename = stripFilename($inFilename); +$outFilename = $stripFilename . '.tex'; + +### preprocess the file + +### 1) if it doesn't end with a newline, add one +if (substr($in,-1) ne "\n") {$in = $in . "\n";} + +### 2) convert DOS-style newlines to UNIX-style (strip linefeeds) +while ($in =~ s/\r$//g) {} + +### 3) store verbatims +$in = storeVerbatims($in); + + +## first, make a copy of the input +open(OUT, '>'.$outFilename); +print OUT $in; +close(OUT); + +## now, run the transforms on it +foreach $transform (@TRANSFORM_PATHS) { + if (-x $transform) + { + system("$transform", "$outFilename", "$EASYLATEX_DIR", @TRANSFORM_ARGS); + + unlink "$outFilename.bak"; + unlink "$outFilename.bak.bak"; + } + elsif ($transform =~ /.*\.pl$/) + { + #print STDERR "about to do $transform\n"; + #$ENV{'PERL5OPT'} = 'i'; + use English; + #print STDERR "$EXECUTABLE_NAME -i.bak $transform $outFilename $EASYLATEX_DIR $TRANSFORM_ARGS[0]\n"; + system("$EXECUTABLE_NAME -i.bak $transform", "$outFilename", "$EASYLATEX_DIR", @TRANSFORM_ARGS); + + unlink "$outFilename.bak"; + unlink "$outFilename.bak.bak"; + } + else { + print STDERR "Skipping $transform -- can't figure out how to execute it\ +n"; + } + #print "\n\nJUST DID $transform\n\n"; + + #print "\n\nJUST DID $transform on $outFilename\n\n"; +# system('cat', "$outFilename"); +} + +## first, make a copy of the input +open(OUT, $outFilename); +local undef $/; +my $out = <OUT>; +close(OUT); + + +### 3) unstore verbatims +$out = unstoreVerbatims($out); + +open(OUT, '>'.$outFilename); +print OUT $out; +close(OUT); + + +## do post-processing if requested +postProcess($out); + + +###################### +# end of MAIN +###################### + + + +sub init +{ + findEasylatexDir(); + initListOfTransforms(); + if ($PARTIAL_DOCUMENT) { + push(@TRANSFORM_ARGS, '--partial'); + } + $TRANSFORM_ARGS = join(' ', @TRANSFORM_ARGS); + #print "DBG: #$TRANSFORM_ARGS#\n"; +} + +sub postProcess { + my ($out) = @_; + + + open(FILE, $outFilename); + local undef $/; + my $file = <FILE>; + close(FILE); + + #TODO: may not work with pdflatex + if ($file =~ /\\bibliography{(.*)\.bib}/) { + system('latex',$outFilename); + system('bibtex',$1); + } + + system('latex',$outFilename); + + + if ($POSTSCRIPT_OUTPUT) + { + eval $PS_OUTPUT_COMMANDS; + } + + if ($PDF_OUTPUT) + { + eval $PDF_OUTPUT_COMMANDS; + } + + if ($PDFLATEX_OUTPUT) + { + eval $PDFLATEX_OUTPUT_COMMANDS; + } +} + + +########################################################################### +# findEasylatexDir +# looks through a searchpath for the easylatex directory. +# die if it can't find it. +########################################################################### +sub findEasylatexDir { + local @easylatex_dir_searchpath; + + push(@easylatex_dir_searchpath,"./easylatex"); + push(@easylatex_dir_searchpath,"$ENV{HOME}/.easylatex"); + push(@easylatex_dir_searchpath,'/usr/lib/easylatex'); + + $EASYLATEX_DIR = ''; + foreach $path (@easylatex_dir_searchpath) + { + if (( -e $path && -d $path)) { + $EASYLATEX_DIR = $path; + } + } + + errorCheckEasylatexDir(); +} + +#################################################### +# errorCheckEasylatexDir +# if the easylatex or the transform directories +# don't exist or aren't directories, then die +#################################################### +sub errorCheckEasylatexDir { + if (! $EASYLATEX_DIR) + { + die "Can't find easylatex directory. The program probably isn't installed correctly; please see documentation or run quickInstall. Aborting (looked for the directory in " . join(', ', @easylatex_dir_searchpath) . ")"; + + } + + if (! ( -e "$EASYLATEX_DIR/transforms" && -d "$EASYLATEX_DIR/transforms")) + { + die "I found the easylatex directory at $EASYLATEX_DIR, but didn't find the directory $EASYLATEX_DIR/transforms. The program probably isn't installed correctly; please see documentation. Aborting."; + + } + +# TODO: add to docs +} + +########################################################################### +# initListOfTransforms +# makes a list of the paths of the transforms to run +# (1) lists the files in the transform directory, +# (2) filters out files starting with '.' or '#' or ending with '~', +# (3) sorts the resulting list, +# (4) prepends the path to each file, +# (5) leaves the result in the global variable @TRANSFORM_PATHS +########################################################################### +sub initListOfTransforms { + + my %fullPath; + +##### list the files in the transform directory + opendir(TRANSFORMDIR, "$EASYLATEX_DIR/transforms") || die "can't opendir $EASYLATEX_DIR/transforms. The program probably isn't installed correctly; please see documentation. Aborting."; + @TRANSFORM_PATHS = readdir(TRANSFORMDIR); + closedir(TRANSFORMDIR); + +#### remember the path + foreach $path (@TRANSFORM_PATHS) + { + $fullPath{$path} = "$EASYLATEX_DIR/transforms/" . $path; + } + + +##### if allowed, add the embedded code transforms + if ($ALLOW_EMBEDDED_CODE) { + opendir(EMBEDDED_CODE_TRANSFORMDIR,"$EASYLATEX_DIR/embed_transforms"); + @EMBEDDED_CODE_TRANSFORM_PATHS = readdir(EMBEDDED_CODE_TRANSFORMDIR); + closedir(EMBEDDED_CODE_TRANSFORMDIR); + + foreach $path (@EMBEDDED_CODE_TRANSFORM_PATHS) + { + $fullPath{$path} = "$EASYLATEX_DIR/embed_transforms/" . $path; + } + + push(@TRANSFORM_PATHS, @EMBEDDED_CODE_TRANSFORM_PATHS); + # add this to the @TRANSFORM_PATHS list +} + + + +##### filter + @TRANSFORM_PATHS = grep(!/^\./,@TRANSFORM_PATHS); + @TRANSFORM_PATHS = grep(!/^\#/,@TRANSFORM_PATHS); + @TRANSFORM_PATHS = grep(!/~$/,@TRANSFORM_PATHS); + @TRANSFORM_PATHS = grep(!/math_mode_symbol_list.txt/,@TRANSFORM_PATHS); + @TRANSFORM_PATHS = grep(!/config.txt/,@TRANSFORM_PATHS); + +#### sort + @TRANSFORM_PATHS = sort(@TRANSFORM_PATHS); + + +#### prepend the path + foreach $path (@TRANSFORM_PATHS) + { + $path = $fullPath{$path}; + } + + +# use Data::Dumper; print Dumper(@TRANSFORM_PATHS); + + + +} + +###################### +# UTILITY SUBROUTINES +###################### + +###################### +# string readFile($fileName) +# reads in and returns the contents of file $fileName +###################### + +sub readFile { + my ($fileName) = @_; + my $file; + + local undef $INPUT_RECORD_SEPARATOR; + open(INFILE, $fileName); + $file = <INFILE>; + close INFILE; + + return $file; +} + +###################### +# string calculateOutFilename($inFilename) +###################### + +sub stripFilepath { + my ($inFilename) = @_; + my $stripFilepath; + + $stripFilename = $inFilename; + + $stripFilename =~ s/.txt//; + + return $stripFilepath; + +} + + +sub stripFilename { + my ($inFilename) = @_; + my $stripFilename; + + $stripFilename = $inFilename; + + $stripFilename =~ s/.txt//; + + $stripFilename =~ s/.*\///; + + return $stripFilename; + +} + + +###################### +# "store" subroutines +###################### + +sub storeVerbatims { + my ($file) = @_; + + ${notSlashRE_begin} = '(^|(?!\\).)'; + ${notSlashRE} = '(?!\\).'; + + $file =~ s/(\\begin{verbatim}.*?\\end{verbatim})/store($1)/egs; + $file =~ s/\\begin{latex}(.*?)\\end{latex}/store($1)/egs; + $file =~ s/(\\newcommand.*)/store($1)/eg; + $file =~ s/(\\includegraphics(?:\[[^\]]*\])?{[^}]+})/store($1)/egs; + # TODO: there's a bug in the last line (i think, maybe) + $file =~ s/(%%.*)/store($1)/eg; + + + return $file; +} + +sub unstoreVerbatims { + my ($file) = @_; + +# print STDERR "UNSTORE:\n\n".$file; + + while ($file =~ s/ ?${EASYLATEXSTORE_MAIN_RESERVED_WORD}-(\d+)-${EASYLATEXSTORE_MAIN_RESERVED_WORD} ?/$Stored{$1}/egs) {} + + $file =~ s/\\begin{latex}//g; + $file =~ s/\\end{latex}//g; + + return $file; +} + + + +sub store { + # got this idea from UseMod + my ($toBeStored) = @_; + + $Stored{$StorageIndex} = $toBeStored; +# print STDERR "STORED: $toBeStored\n"; + +# print STDERR "REPLACEDW: ".${EASYLATEXSTORE_RESERVED_WORD}.'_' . $StorageIndex . '_'.${EASYLATEXSTORE_RESERVED_WORD}; + + return ' '.${EASYLATEXSTORE_MAIN_RESERVED_WORD}.'-' . $StorageIndex++ . '-'.${EASYLATEXSTORE_MAIN_RESERVED_WORD}.' '; +} |