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