#!/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;} 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 = ; 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 = ; 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 = ; 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}.' '; }