I thought a good use of part of my Sunday would be to (re?)learn a little Perl and make my life a bit easier. Suppose you have a paper that’s split up into many files. This script will parse your main LaTeX file and generate a single LaTeX file for the whole paper. It searches recursively for “\input{}” commands and replaces them with the relevant file. It seems to be functional enough to use, but everyone has their own LaTeX usage conventions, so YMMV.
This is particularly handy for submitting papers to ArXiV, which requires a single .tex file, and cutting and pasting in 20 little files can become a bit of a pain. With the perl script for stripping comments, you can generate the .tex for your ArXiV submission on the fly.
I spent a little time searching for a script like this online, since I’m sure many people have written such a thing, but I didn’t turn anything up. Hopefully this will be of use to others looking for a similar hack. Sorry for the lines getting chopped off in the display — it should show up if you cut and paste the text.
#!/usr/bin/perl
# mergetex.pl
#
# Script for merging tex files into a single monolithic file. This
# script should make it easy to generate an ArXiV-friendly single
# .tex file from a paper that is broken into subfiles using LaTeX's
# \input{} command.
#
# USAGE:
# ./mergetex.pl [input] [output]
# ./mergetex.pl mypaper.tex mypaperMerged.tex
#
# mergetex takes two arguments, the [input] file and the [output]
# file into which the merged files should go. It recursively
# searches [input] and adds any file given by uncommented \input{}
# commands.
#
# v0.1 by Anand Sarwate (asarwate@alum.mit.edu) with tips from Erin Rhode.
use IO::File;
if ( scalar(@ARGV) != 2) {
die "Syntax Error : use 'mergetex.pl [input] [output]'"
}
$infile = shift;
$outfile = shift;
print "Generating tex file from $infile and storing in $outfile.\n";
my $outputfh = new IO::File($outfile, "w") or die "Could not open $outfile: $!\n";
my $inputfh = new IO::File($infile, "r") or die "Could not open $infile: $!\n";
parsetex($inputfh,$infile);
$outputfh->close();
sub parsetex {
my $fh = shift;
my $file = shift;
print "Found $file. Merging into $outfile.\n";
while () {
# strip out comments
$decom = $_;
$decom =~ s/^\%.*$/\%/;
$decom =~ s/([^\\])\%.*$/\1\%/g;
# search for lines with "\input{}"
if ($decom =~ /\\input{(.*?)}/) {
#get new file name
if ($1 =~ /.tex/) {
my $newfile = $1;
} else {
$newfile = $1 . ".tex";
}
# recurse to input new file
my $newfh = new IO::File($newfile, "r") or die "Could not open $infile: $!\n";
parsetex($newfh,$newfile);
}
else {
$outputfh->print($decom);
}
}
$fh->close();
}