summaryrefslogtreecommitdiff
path: root/support/wheretotrim
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/wheretotrim
Initial commit
Diffstat (limited to 'support/wheretotrim')
-rw-r--r--support/wheretotrim/README49
-rwxr-xr-xsupport/wheretotrim/wheretotrim499
-rw-r--r--support/wheretotrim/wheretotrim-pl.dtx756
-rw-r--r--support/wheretotrim/wheretotrim.1324
-rw-r--r--support/wheretotrim/wheretotrim.dtx725
-rw-r--r--support/wheretotrim/wheretotrim.ins59
-rw-r--r--support/wheretotrim/wheretotrim.pdfbin0 -> 340989 bytes
-rw-r--r--support/wheretotrim/wheretotrim.sty94
8 files changed, 2506 insertions, 0 deletions
diff --git a/support/wheretotrim/README b/support/wheretotrim/README
new file mode 100644
index 0000000000..e8c360329a
--- /dev/null
+++ b/support/wheretotrim/README
@@ -0,0 +1,49 @@
+ +---------------------+
+ | WHERETOTRIM |
+ | |
+ | Scott Pakin |
+ | scott+wtt@pakin.org |
+ +---------------------+
+
+Description
+===========
+
+wheretotrim is a Perl script and auxiliary LaTeX package that helps
+LaTeX users reduce their document's page count. It is intended to be
+used with documents that exceed a publisher's specified page-length
+limitation by a small amount (much less than a full column or page).
+wheretotrim reports the page and column on which the least amount of
+text needs to be trimmed to reduce the page count. It works by
+repeatedly rebuilding the given document, analyzing the benefit of
+trimming from each column or page one line of text, then two, then
+three, and so forth until the document's page count decreases.
+
+wheretotrim has been tested only on Linux. It might work on OS X. It
+probably won't work on Windows.
+
+
+Installation
+============
+
+To create wheretotrim.pl and wheretotrim.sty simply run "tex
+wheretotrim.ins". Rename wheretotrim.pl to wheretotrim and install it
+somewhere in your path. Install wheretotrim.sty somewhere where LaTeX
+can find it. See
+http://www.tex.ac.uk/cgi-bin/texfaq2html?label=instpackages for
+general information about installing packages.
+
+
+Copyright and license
+=====================
+
+Copyright (C) 2013 Scott Pakin
+
+This file may be distributed and/or modified under the conditions of
+the LaTeX Project Public License, either version 1.3c of this license
+or (at your option) any later version. The latest version of this
+license is in:
+
+ http://www.latex-project.org/lppl.txt
+
+and version 1.3c or later is part of all distributions of LaTeX
+version 2008/05/04 or later.
diff --git a/support/wheretotrim/wheretotrim b/support/wheretotrim/wheretotrim
new file mode 100755
index 0000000000..2e52478f08
--- /dev/null
+++ b/support/wheretotrim/wheretotrim
@@ -0,0 +1,499 @@
+#! /usr/bin/env perl
+
+########################################
+# Identify opportunities for reducing #
+# the page count of a LaTeX document #
+# #
+# By Scott Pakin <scott+wtt@pakin.org> #
+########################################
+
+use File::Basename;
+use File::Temp qw(tempfile);
+use Getopt::Long;
+use POSIX;
+use Pod::Usage;
+use warnings;
+use strict;
+
+# Define some global variables.
+my $progname = basename $0; # Name of this program
+my $logfile; # LaTeX-generated log file
+my $verbosity = 1; # Level of output verbosity
+my $allpages = 0; # 1=report changes needed for all pages; 0=any page
+my @latexcmd; # Complete command to run LaTeX
+my $ltxfile; # Name of input file
+my $colsperpage = 1; # Number of columns per page (1 or 2)
+my %column2page; # Map from absolute column number to {page, column}
+my $debugexp; # Typeset using an expansion of <page>,<column>,<expansion lines> for debugging
+our $VERSION = "1.0"; # Version number of this program
+
+# Define a subroutine that replaces a file name with its base name and
+# (optionally) new suffix.
+sub basename_newsuffix ($;$)
+{
+ my ($fname, $newsuffix) = @_;
+ my ($basename, undef, undef) = fileparse($fname, qr/\.[^.]*/);
+ $newsuffix = "" if !defined $newsuffix;
+ return $basename . $newsuffix;
+}
+
+# Define a subroutine to create a temporary LaTeX file that modifies a
+# few LaTeX commands then loads the user's document. The subroutine
+# returns the name of the temporary file.
+sub create_latex_file ($$$)
+{
+ my ($columntoexpand, $columnexpandlines, $extrafullcolumns) = @_;
+ my ($modltx, $modltxfile) = tempfile("wtt-XXXXXX",
+ TMPDIR => 1,
+ SUFFIX => ".tex",
+ UNLINK => 1);
+ print $modltx "\\RequirePackage[column=$columntoexpand,expansion=$columnexpandlines,extracols=$extrafullcolumns]{wheretotrim}\n";
+ print $modltx "\\PassOptionsToPackage{draft}{hyperref}\n"; # Avoid "\pdfendlink ended up in different nesting level than \pdfstartlink" errors.
+ print $modltx "\\input{$ARGV[$#ARGV]}\n";
+ close $modltx;
+ return $modltxfile;
+}
+
+# Define a subroutine to run LaTeX on a given filename.
+sub run_latex ($$$$)
+{
+ # Add some additional arguments to the LaTeX command.
+ my ($modltxfile, $columntoexpand, $columnexpandlines, $extrafullcolumns) = @_;
+ my $jobname = basename_newsuffix($ltxfile);
+ @latexcmd = (@ARGV[0..$#ARGV-1], "-jobname=$jobname", $modltxfile);
+
+ # Run LaTeX.
+ if ($verbosity == 1) {
+ if ($columntoexpand == 0) {
+ print "Compiling $ltxfile normally";
+ if ($extrafullcolumns > 0) {
+ printf ", but with %s column%s of padding", $extrafullcolumns, $extrafullcolumns == 1 ? "" : "s";
+ }
+ print " ... ";
+ }
+ elsif ($colsperpage == 1) {
+ my ($page, $col) = @{$column2page{$columntoexpand}};
+ printf "Compiling %s with page %d expanded by %d line%s ... ",
+ $ltxfile, $page, $columnexpandlines, $columnexpandlines == 1 ? "" : "s";
+ }
+ else {
+ my ($page, $col) = @{$column2page{$columntoexpand}};
+ printf "Compiling %s with page %d, column %d expanded by %d line%s ... ",
+ $ltxfile, $page, $col, $columnexpandlines, $columnexpandlines == 1 ? "" : "s";
+ }
+ }
+ elsif ($verbosity > 1) {
+ print "Running @latexcmd\n";
+ }
+ open(LATEX, "-|", "sh", "-c", 'echo X | "$@" 2>&1', "--", $latexcmd[0], @latexcmd[1..$#latexcmd]) || die; # Redirect stderr to stdout as we run.
+ while (my $oneline = <LATEX>) {
+ print $oneline if $verbosity > 1;
+ }
+ close LATEX;
+ my $errcode = $?;
+ if ($verbosity == 1) {
+ print $errcode == 0 ? "done.\n" : "failed.\n";
+ }
+ elsif ($verbosity > 1) {
+ print "Finished running.\n";
+ }
+ return $errcode;
+}
+
+# Define a subroutine to process a log file and return various data
+# extracted from it.
+sub process_log_file ($$$)
+{
+ my ($columntoexpand, $columnexpandlines, $extrafullcolumns) = @_;
+ my %column_map;
+
+ # Extract wheretotrim information lines and the final page count.
+ print "Processing $logfile ... " if $verbosity > 0;
+ my ($numpages, $baselineskip, $textheight) = (0, 0, 0);
+ open(LOGFILE, "<", $logfile) || die "${progname}: Failed to open $logfile ($!)\n";
+ my $infostr = "Package wheretotrim Info";
+ while (my $oneline = <LOGFILE>) {
+ $baselineskip = $1+0 if $oneline =~ /^$infostr: Baseline skip: ([\d.]+)pt/;
+ $textheight = $1+0 if $oneline =~ /^$infostr: Text height: ([\d.]+)pt/;
+ $column_map{$1} = [$2, $3] if $oneline =~ /^$infostr: Column (\d+) is on page (\d+) \((.*)\) on input line/;
+ $numpages = $1 if $oneline =~ /^Output written on.*\((\d+) page/;
+ }
+ close LOGFILE;
+ $numpages-- if $extrafullcolumns > 0;
+ if ($verbosity > 0) {
+ printf "done (%d page%s).\n",
+ $numpages, $numpages == 1 ? "" : "s",
+ }
+ return ($numpages, $baselineskip, $textheight, \%column_map);
+}
+
+# Define a subroutine to run LaTeX and return a page count and other
+# information.
+sub latex_page_count ($$$)
+{
+ # LaTeX wrapper scripts might not like being given LaTeX code on
+ # the command line. We therefore create a temporary file that
+ # prepares LaTeX for programmatically modifying column heights.
+ my ($columntoexpand, $columnexpandlines, $extrafullcolumns) = @_;
+ my $modltxfile = create_latex_file($columntoexpand, $columnexpandlines, $extrafullcolumns);
+
+ # Run latex on the temporary file.
+ my $errcode = run_latex($modltxfile, $columntoexpand, $columnexpandlines, $extrafullcolumns);
+ unlink $modltxfile;
+
+ # Process the log file.
+ return (0, undef, undef, undef) if $errcode != 0;
+ return process_log_file($columntoexpand, $columnexpandlines, $extrafullcolumns);
+}
+
+###########################################################################
+
+# Parse the command line.
+my $wanthelp = 0;
+my $wantversion = 0;
+Getopt::Long::Configure("require_order");
+GetOptions("h|help" => \$wanthelp,
+ "V|version" => \$wantversion,
+ "a|allpages" => \$allpages,
+ "l|logfile=s" => \$logfile,
+ "v|verbose+" => \$verbosity,
+ "d|debug=s" => \$debugexp,
+ "q|quiet" => sub {$verbosity = 0})
+ || pod2usage(-exitval => 2);
+if ($wantversion) {
+ print "wheretotrim $VERSION\n";
+ exit 0;
+}
+pod2usage(-verbose => $verbosity,
+ -exitval => 1) if $wanthelp;
+pod2usage(-message => "${progname}: A latex command must be specified",
+ -exitval => 2) if $#ARGV == -1;
+$ltxfile = basename($ARGV[$#ARGV]);
+$logfile = basename_newsuffix($ARGV[$#ARGV], ".log") if !defined $logfile;
+
+# Determine the document's baseline characteristics.
+my ($basepages, $baselineskip, $textheight, $c2p_ptr) = latex_page_count 0, 0, 0;
+die "${progname}: Failed to build $ltxfile\n" if $basepages == 0;
+%column2page = %$c2p_ptr;
+print "\n" if $verbosity > 0;
+
+# Map an absolute column to a page and column number.
+my $prevpage = 0;
+foreach my $col (sort {$a <=> $b} keys %column2page) {
+ my ($pagenum, $pagename) = @{$column2page{$col}};
+ if ($pagenum == $prevpage) {
+ $column2page{$col} = [$pagenum, 2, $pagename];
+ $colsperpage = 2;
+ }
+ else {
+ $column2page{$col} = [$pagenum, 1, $pagename];
+ }
+ $prevpage = $pagenum;
+}
+
+# If we were given a page, column, and expansion, typeset the document
+# with those parameters and exit.
+if (defined $debugexp) {
+ die "${progname}: Failed to parse \"$debugexp\" into {page, column, expansion}\n" if $debugexp !~ /^(\d+)\D+(\d+)\D+(\d+)$/;
+
+ # Convert page and column number to absolute column number.
+ my ($target_page, $target_col, $expansion) = ($1, $2, $3);
+ my $testcol;
+ while (my ($abscol, $page_col) = each %column2page) {
+ if ($target_page == $page_col->[0] && $target_col == $page_col->[1]) {
+ $testcol = $abscol;
+ last;
+ }
+ }
+ die "${progname}: Failed to map page $target_page, column $target_col to an absolute column number\n" if !defined $testcol;
+
+ # Enlarge the given page.
+ my ($numpages, undef) = latex_page_count $testcol, $expansion, $colsperpage;
+ print "\n" if $verbosity > 0;
+ latex_page_count $testcol, $expansion, 0; # Run again without appending any extra columns.
+ print "\n" if $verbosity > 0;
+ print "Expanding page $target_page, column $target_col by $expansion lines ";
+ if ($numpages == $basepages) {
+ print "does not reduce the page count below $numpages pages.\n";
+ }
+ else {
+ print "reduces the page count from $basepages pages to $numpages pages.\n";
+ }
+ exit 0;
+}
+
+# Determine columns for which no amount of expansion will reduce the
+# page count.
+my $maxexpansion = int($textheight/$baselineskip + 1);
+my @complete = (0, 0+keys %column2page); # Fraction complete (numerator and denominator)
+foreach my $expcol (sort {$a <=> $b} keys %column2page) {
+ my ($numpages, undef) = latex_page_count $expcol, $maxexpansion, $colsperpage;
+ if ($verbosity > 0) {
+ $complete[0]++;
+ printf "Trial runs are %.1f%% complete.\n\n", 100.0*$complete[0]/$complete[1];
+ }
+ delete $column2page{$expcol} if $numpages > 0 && $numpages == $basepages;
+}
+
+# Keep expanding a page by greater and greater amounts until we reduce
+# our page count.
+my %col2savings; # Map from an absolute column to an {expansion, page count} tuple.
+my $target_num_cols = $allpages ? (keys %column2page) : 1; # Minimum number of columns for which to find an expansion amount
+my $minexpansion; # Minimum value of the above that saves a page
+@complete = (0, $maxexpansion*keys %column2page);
+foreach my $expansion (1 .. $maxexpansion) {
+ # Expand each column in turn.
+ foreach my $expcol (sort {$a <=> $b} keys %column2page) {
+ $complete[0]++;
+ next if defined $col2savings{$expcol}; # Already finished
+ next if $column2page{$expcol}->[0] == $basepages && $column2page{$expcol}->[1] == 2; # Second column on the last page
+ my ($numpages, undef) = latex_page_count $expcol, $expansion, $colsperpage;
+ if ($numpages > 0 && $numpages < $basepages) {
+ $col2savings{$expcol} = [$expansion, $numpages];
+ $minexpansion = $expansion if !defined $minexpansion;
+ }
+ if ($verbosity > 0) {
+ printf "Execution is %.1f%% complete.\n\n", 100.0*$complete[0]/$complete[1];
+ }
+ }
+ last if keys %col2savings >= $target_num_cols; # Success
+}
+
+# Restore the document to its original form.
+run_latex $ltxfile, 0, 0, 0;
+printf "Execution is 100.0%% complete.\n\n" if $verbosity > 0;
+
+# Output the space savings.
+if (keys %col2savings == 0) {
+ printf "It does not appear possible to reduce the page count from %d to %d\n",
+ $basepages, $basepages-1;
+ print "by removing any amount of text from any single column.\n\n";
+ exit 0;
+}
+printf "To reduce the page count from %d to %d, do %s following:\n\n",
+ $basepages, $basepages-1, keys %col2savings == 1 ? "the" : "any of the";
+foreach my $abscol (sort {$a <=> $b} keys %col2savings) {
+ my ($expansion, $numpages) = @{$col2savings{$abscol}};
+ my ($page, $col, $pagename) = @{$column2page{$abscol}};
+ print " * Reduce page $page";
+ print " (\"$pagename\")" if $pagename ne $page;
+ print ", column $col" if $colsperpage > 1;
+ printf " by %d %s", $expansion, $expansion == 1 ? "line" : "lines";
+ if ($numpages < $basepages - 1) {
+ printf " (produces %d %s)", $numpages, $numpages == 1 ? "page" : "pages";
+ }
+ print ".\n";
+}
+print "\n";
+my $minpoints = $minexpansion*$baselineskip;
+printf "Note: %d lines = %.1f\" = %.1f cm = %.1f%% of the %s height\n",
+ $minexpansion, $minpoints/72.27, $minpoints/28.45,
+ 100.0*$minpoints/$textheight, $colsperpage == 1 ? "page" : "column";
+
+###########################################################################
+
+__END__
+
+=head1 NAME
+
+wheretotrim - Help reduce the page count of a LaTeX document
+
+=head1 SYNOPSIS
+
+wheretotrim
+[B<--verbose> | B<--quiet>]
+[B<--allpages>]
+[B<--debug>=I<page>,I<column>,I<lines>]
+I<latex command>
+
+wheretotrim [B<--verbose>] B<--help>|B<--version>
+
+=head1 DESCRIPTION
+
+B<wheretotrim> is a tool to help LaTeX users reduce their document's
+page count. It is intended to be used with documents that exceed a
+publisher's specified page-length limitation by a small amount (much
+less than a full column or page). B<wheretotrim> operates by building
+the document repeatedly, successively expanding each column on each
+page by one line height to mimic reducing the amount of text in that
+column by an equivalent amount. If doing so does not reduce the page
+count, B<wheretotrim> repeats the process with two line heights'
+expansion of each column, then three, and so forth until it expands
+each column in turn by the full height of the column. The following
+is some sample output:
+
+ To reduce the page count from 10 to 9, do any of the following:
+
+ * Reduce page 9, column 1 by 12 lines.
+ * Reduce page 9, column 2 by 12 lines.
+ * Reduce page 10, column 1 by 12 lines.
+
+ Note: 12 lines = 2.4" = 6.1 cm = 26.8% of the column height
+
+That is, reducing either column on S<page 9> or the first column on
+S<page 10> by 12 lines is the most expedient way to reduce the
+document's page count. More than S<12 lines> would need to be cut on
+other columns and other pages to achieve the same effect.
+
+=head1 OPTIONS
+
+B<wheretotrim> accepts the following command-line options:
+
+=over 4
+
+=item B<-a>, B<--allpages>
+
+Perform enough extra runs of B<latex> to report the amount of space
+that must be trimmed from I<each> column or page to reduce page count,
+not just the columns or pages to which the page count is the most
+sensitive.
+
+=item B<-v>, B<--verbose>
+
+Display the output of each run of B<latex>. This is useful for
+troubleshooting and to help monitor the progress of long B<latex>
+runs.
+
+=item B<-q>, B<--quiet>
+
+Suppress progress updates and output only the final report.
+
+=item B<-d> I<page>,I<column>,I<lines>, B<--debug>=I<page>,I<column>,I<lines>
+
+Debug B<wheretotrim>'s execution by expanding page I<page>, column
+I<column> by I<lines> line heights and leaving the B<latex> output in
+that state.
+
+=item B<-h>, B<--help>
+
+Summarize usage information and exit. These may be used with
+B<--verbose> to display more extended documentation.
+
+=item B<-V>, B<--version>
+
+Display B<wheretotrim>'s version number and exit.
+
+=back
+
+In addition to the preceding options, B<wheretotrim> requires a
+I<latex command> argument that specifies how to build the document.
+
+=head1 EXAMPLES
+
+For the most basic usage, simply provide a B<latex> command to run:
+
+ wheretotrim latex myfile.tex
+
+or, for example,
+
+ wheretotrim pdflatex myfile.tex
+
+B<wheretotrim> executes the specified command a large number of times
+and finally terminates with a report resembling the following:
+
+ To reduce the page count from 10 to 9, do any of the following:
+
+ * Reduce page 9, column 1 by 12 lines.
+ * Reduce page 9, column 2 by 12 lines.
+ * Reduce page 10, column 1 by 12 lines.
+
+ Note: 12 lines = 2.4" = 6.1 cm = 26.8% of the column height
+
+To ask B<wheretotrim> to report how much space needs to be trimmed on
+each column and page to reduce the total page count, specify the
+B<--allpages> option:
+
+ wheretotrim --allpages latex myfile.tex
+
+The output now looks like the following:
+
+ To reduce the page count from 10 to 9, do any of the following:
+
+ * Reduce page 1, column 1 by 13 lines.
+ * Reduce page 1, column 2 by 13 lines.
+ * Reduce page 2, column 1 by 13 lines.
+ * Reduce page 2, column 2 by 13 lines.
+ * Reduce page 4, column 1 by 13 lines.
+ * Reduce page 4, column 2 by 13 lines.
+ * Reduce page 5, column 1 by 13 lines.
+ * Reduce page 5, column 2 by 13 lines.
+ * Reduce page 6, column 1 by 13 lines.
+ * Reduce page 6, column 2 by 13 lines.
+ * Reduce page 7, column 1 by 13 lines.
+ * Reduce page 7, column 2 by 13 lines.
+ * Reduce page 8, column 1 by 13 lines.
+ * Reduce page 8, column 2 by 13 lines.
+ * Reduce page 9, column 1 by 12 lines.
+ * Reduce page 9, column 2 by 12 lines.
+ * Reduce page 10, column 1 by 12 lines.
+
+ Note: 12 lines = 2.4" = 6.1 cm = 26.8% of the column height
+
+If you're curious how the document managed to shrink substantially as
+the result of a relatively minor text reduction, you can typeset the
+document with a particular page and column enlarged by a given amount:
+
+ wheretotrim --debug=9,1,12 latex myfile.tex
+
+=head1 CAVEATS
+
+B<wheretotrim> hooks into LaTeX's output routines, which are
+notoriously arcane and somewhat fragile. As a result, it is quite
+likely that B<wheretotrim> will fail to analyze a large set of
+documents. Use the B<--verbose> flag to help identify any problems
+that B<latex> encounters.
+
+In many cases, B<wheretotrim> will recover by simply ignoring a few
+possible page and column expansions. For example, certain expansions
+may result in a C<L<Float(s)
+lost|http://www.tex.ac.uk/cgi-bin/texfaq2html?label=fllost>> message.
+In other cases, B<wheretotrim> will fail to analyze any modification
+to the document. For example, it may receive an C<Infinite glue
+shrinkage found in box being split> error from every page and column
+variation it tries. In this particular case, see the discussion at
+L<http://www.michaelshell.org/tex/ieeetran/>.
+
+When B<wheretotrim> is used with a B<latex> auto-build script you may
+need to take measures to force the script to rebuild the document even
+if it appears that no files have changed. For example, B<latexmk>
+should be given the B<-CF> option to force rebuilding:
+
+ wheretotrim latexmk -CF myfile.tex
+
+=head1 RESTRICTIONS
+
+B<wheretotrim> is implemented as a Perl script with an auxiliary LaTeX
+package. It has been tested only on Linux, but I suspect that it
+should also work on S<OS X>. I doubt it will work under Windows,
+though, due to the way the script uses a B<bash>-specific technique
+for redirecting the standard error device into the standard output
+device.
+
+=head1 AUTHOR
+
+Scott Pakin, I<scott+wtt@pakin.org>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2013, Scott Pakin <scott+wtt@pakin.org>
+
+This file may be distributed and/or modified under the conditions of
+the LaTeX Project Public License, either version 1.3c of this license
+or (at your option) any later version. The latest version of this
+license is in:
+
+=over 4
+
+=item E<nbsp>
+
+L<http://www.latex-project.org/lppl.txt>
+
+=back
+
+and version 1.3c or later is part of all distributions of LaTeX
+version 2008/05/04 or later.
+
+=head1 SEE ALSO
+
+latex(1),
+L<the savetrees package|http://www.ctan.org/pkg/savetrees/>
diff --git a/support/wheretotrim/wheretotrim-pl.dtx b/support/wheretotrim/wheretotrim-pl.dtx
new file mode 100644
index 0000000000..f4c41db0f4
--- /dev/null
+++ b/support/wheretotrim/wheretotrim-pl.dtx
@@ -0,0 +1,756 @@
+% ^^A ============================================================
+% ^^A This documented LaTeX code was generated mechanically from a
+% ^^A source Perl script. Please edit the original Perl script
+% ^^A instead of this file.
+% ^^A ============================================================
+%
+% \begingroup
+%
+% ^^A Define a perlsub environment for typesetting and indexing
+% ^^A Perl subroutines.
+% \catcode`\^^B=\active
+% \makeatletter
+% \def\SpecialMainPerlIndex#1{\@bsphack\special@index{%
+% #1\actualchar
+% {\string\ttfamily\space#1}
+% (Perl)%
+% \encapchar main}%
+% \special@index{Perl subroutines:\levelchar#1\actualchar{%
+% \string\ttfamily\space#1}\encapchar
+% main}\@esphack}
+% \newenvironment{perlsub}{^^A
+% \def\bslash{}^^A
+% \catcode`_=12^^A
+% \SpecialEscapechar{\^^B}^^A
+% \let\SpecialMainIndex=\SpecialMainPerlIndex
+% \begin{macro}
+% }{^^A
+% \end{macro}
+% }
+% \makeatother
+%
+% ^^A Here's a hack to prevent code lines beginning with "%" from
+% ^^A being discarded by docstrip yet still have doc typeset them normally.
+% ^^A We prefix each such line with "%<script>" so docstrip will
+% ^^A honor it yet redefine \Module as a no-op so doc won't include
+% ^^A the "%<script>" when typesetting the line.
+% \def\Module#1{}
+%
+% \subsection{Subroutine defintions}
+% \begin{macrocode}
+#! /usr/bin/env perl
+% \end{macrocode}
+% \iffalse
+
+########################################
+# Identify opportunities for reducing #
+# the page count of a LaTeX document #
+# #
+# By Scott Pakin <scott+wtt@pakin.org> #
+########################################
+
+% \fi
+% \begin{macrocode}
+use File::Basename;
+use File::Temp qw(tempfile);
+use Getopt::Long;
+use POSIX;
+use Pod::Usage;
+use warnings;
+use strict;
+% \end{macrocode}
+% \iffalse
+
+% \fi
+%
+% Define some global variables.
+% \iffalse
+# Define some global variables.
+% \fi
+% \begin{macrocode}
+my $progname = basename $0; # Name of this program
+my $logfile; # LaTeX-generated log file
+my $verbosity = 1; # Level of output verbosity
+my $allpages = 0; # 1=report changes needed for all pages; 0=any page
+my @latexcmd; # Complete command to run LaTeX
+my $ltxfile; # Name of input file
+my $colsperpage = 1; # Number of columns per page (1 or 2)
+my %column2page; # Map from absolute column number to {page, column}
+my $debugexp; # Typeset using an expansion of <page>,<column>,<expansion lines> for debugging
+our $VERSION = "1.0"; # Version number of this program
+% \end{macrocode}
+% \iffalse
+
+% \fi
+%
+% \begin{perlsub}{basename_newsuffix}
+% Define a subroutine that replaces a file name with its base name and
+% (optionally) new suffix.
+% \iffalse
+# Define a subroutine that replaces a file name with its base name and
+# (optionally) new suffix.
+% \fi
+% \begin{macrocode}
+sub basename_newsuffix ($;$)
+{
+ my ($fname, $newsuffix) = @_;
+ my ($basename, undef, undef) = fileparse($fname, qr/\.[^.]*/);
+ $newsuffix = "" if !defined $newsuffix;
+ return $basename . $newsuffix;
+}
+% \end{macrocode}
+% \end{perlsub}
+% \iffalse
+
+% \fi
+%
+% \begin{perlsub}{create_latex_file}
+% Define a subroutine to create a temporary \LaTeX{} file that modifies a
+% few \LaTeX{} commands then loads the user's document. The subroutine
+% returns the name of the temporary file.
+% \iffalse
+# Define a subroutine to create a temporary LaTeX file that modifies a
+# few LaTeX commands then loads the user's document. The subroutine
+# returns the name of the temporary file.
+% \fi
+% \begin{macrocode}
+sub create_latex_file ($$$)
+{
+ my ($columntoexpand, $columnexpandlines, $extrafullcolumns) = @_;
+ my ($modltx, $modltxfile) = tempfile("wtt-XXXXXX",
+ TMPDIR => 1,
+ SUFFIX => ".tex",
+ UNLINK => 1);
+ print $modltx "\\RequirePackage[column=$columntoexpand,expansion=$columnexpandlines,extracols=$extrafullcolumns]{wheretotrim}\n";
+ print $modltx "\\PassOptionsToPackage{draft}{hyperref}\n"; # Avoid "\pdfendlink ended up in different nesting level than \pdfstartlink" errors.
+ print $modltx "\\input{$ARGV[$#ARGV]}\n";
+ close $modltx;
+ return $modltxfile;
+}
+% \end{macrocode}
+% \end{perlsub}
+% \iffalse
+
+% \fi
+%
+% \begin{perlsub}{run_latex}
+% Define a subroutine to run \LaTeX{} on a given filename.
+% \iffalse
+# Define a subroutine to run LaTeX on a given filename.
+% \fi
+% \begin{macrocode}
+sub run_latex ($$$$)
+{
+% \end{macrocode}
+% \end{perlsub}
+%
+% Add some additional arguments to the \LaTeX{} command.
+% \iffalse
+ # Add some additional arguments to the LaTeX command.
+% \fi
+% \begin{macrocode}
+ my ($modltxfile, $columntoexpand, $columnexpandlines, $extrafullcolumns) = @_;
+ my $jobname = basename_newsuffix($ltxfile);
+ @latexcmd = (@ARGV[0..$#ARGV-1], "-jobname=$jobname", $modltxfile);
+% \end{macrocode}
+% \iffalse
+
+% \fi
+%
+% Run \LaTeX{}.
+% \iffalse
+ # Run LaTeX.
+% \fi
+% \begin{macrocode}
+ if ($verbosity == 1) {
+ if ($columntoexpand == 0) {
+ print "Compiling $ltxfile normally";
+ if ($extrafullcolumns > 0) {
+ printf ", but with %s column%s of padding", $extrafullcolumns, $extrafullcolumns == 1 ? "" : "s";
+ }
+ print " ... ";
+ }
+ elsif ($colsperpage == 1) {
+ my ($page, $col) = @{$column2page{$columntoexpand}};
+ printf "Compiling %s with page %d expanded by %d line%s ... ",
+ $ltxfile, $page, $columnexpandlines, $columnexpandlines == 1 ? "" : "s";
+ }
+ else {
+ my ($page, $col) = @{$column2page{$columntoexpand}};
+ printf "Compiling %s with page %d, column %d expanded by %d line%s ... ",
+ $ltxfile, $page, $col, $columnexpandlines, $columnexpandlines == 1 ? "" : "s";
+ }
+ }
+ elsif ($verbosity > 1) {
+ print "Running @latexcmd\n";
+ }
+ open(LATEX, "-|", "sh", "-c", 'echo X | "$@" 2>&1', "--", $latexcmd[0], @latexcmd[1..$#latexcmd]) || die; # Redirect stderr to stdout as we run.
+ while (my $oneline = <LATEX>) {
+ print $oneline if $verbosity > 1;
+ }
+ close LATEX;
+ my $errcode = $?;
+ if ($verbosity == 1) {
+ print $errcode == 0 ? "done.\n" : "failed.\n";
+ }
+ elsif ($verbosity > 1) {
+ print "Finished running.\n";
+ }
+ return $errcode;
+}
+% \end{macrocode}
+% \iffalse
+
+% \fi
+%
+% \begin{perlsub}{process_log_file}
+% Define a subroutine to process a log file and return various data
+% extracted from it.
+% \iffalse
+# Define a subroutine to process a log file and return various data
+# extracted from it.
+% \fi
+% \begin{macrocode}
+sub process_log_file ($$$)
+{
+ my ($columntoexpand, $columnexpandlines, $extrafullcolumns) = @_;
+ my %column_map;
+% \end{macrocode}
+% \end{perlsub}
+% \iffalse
+
+% \fi
+%
+% Extract wheretotrim information lines and the final page count.
+% \iffalse
+ # Extract wheretotrim information lines and the final page count.
+% \fi
+% \begin{macrocode}
+ print "Processing $logfile ... " if $verbosity > 0;
+ my ($numpages, $baselineskip, $textheight) = (0, 0, 0);
+ open(LOGFILE, "<", $logfile) || die "${progname}: Failed to open $logfile ($!)\n";
+ my $infostr = "Package wheretotrim Info";
+ while (my $oneline = <LOGFILE>) {
+ $baselineskip = $1+0 if $oneline =~ /^$infostr: Baseline skip: ([\d.]+)pt/;
+ $textheight = $1+0 if $oneline =~ /^$infostr: Text height: ([\d.]+)pt/;
+ $column_map{$1} = [$2, $3] if $oneline =~ /^$infostr: Column (\d+) is on page (\d+) \((.*)\) on input line/;
+ $numpages = $1 if $oneline =~ /^Output written on.*\((\d+) page/;
+ }
+ close LOGFILE;
+ $numpages-- if $extrafullcolumns > 0;
+ if ($verbosity > 0) {
+ printf "done (%d page%s).\n",
+ $numpages, $numpages == 1 ? "" : "s",
+ }
+ return ($numpages, $baselineskip, $textheight, \%column_map);
+}
+% \end{macrocode}
+% \iffalse
+
+% \fi
+%
+% \begin{perlsub}{latex_page_count}
+% Define a subroutine to run \LaTeX{} and return a page count and other
+% information.
+% \iffalse
+# Define a subroutine to run LaTeX and return a page count and other
+# information.
+% \fi
+% \begin{macrocode}
+sub latex_page_count ($$$)
+{
+% \end{macrocode}
+% \end{perlsub}
+%
+% \LaTeX{} wrapper scripts might not like being given \LaTeX{} code on
+% the command line. We therefore create a temporary file that
+% prepares \LaTeX{} for programmatically modifying column heights.
+% \iffalse
+ # LaTeX wrapper scripts might not like being given LaTeX code on
+ # the command line. We therefore create a temporary file that
+ # prepares LaTeX for programmatically modifying column heights.
+% \fi
+% \begin{macrocode}
+ my ($columntoexpand, $columnexpandlines, $extrafullcolumns) = @_;
+ my $modltxfile = create_latex_file($columntoexpand, $columnexpandlines, $extrafullcolumns);
+% \end{macrocode}
+% \iffalse
+
+% \fi
+%
+% Run latex on the temporary file.
+% \iffalse
+ # Run latex on the temporary file.
+% \fi
+% \begin{macrocode}
+ my $errcode = run_latex($modltxfile, $columntoexpand, $columnexpandlines, $extrafullcolumns);
+ unlink $modltxfile;
+% \end{macrocode}
+% \iffalse
+
+% \fi
+%
+% Process the log file.
+% \iffalse
+ # Process the log file.
+% \fi
+% \begin{macrocode}
+ return (0, undef, undef, undef) if $errcode != 0;
+ return process_log_file($columntoexpand, $columnexpandlines, $extrafullcolumns);
+}
+% \end{macrocode}
+% \iffalse
+
+###########################################################################
+
+% \fi
+%
+% \subsection{Main program execution}
+% Parse the command line.
+% \iffalse
+# Parse the command line.
+% \fi
+% \begin{macrocode}
+my $wanthelp = 0;
+my $wantversion = 0;
+Getopt::Long::Configure("require_order");
+GetOptions("h|help" => \$wanthelp,
+ "V|version" => \$wantversion,
+ "a|allpages" => \$allpages,
+ "l|logfile=s" => \$logfile,
+ "v|verbose+" => \$verbosity,
+ "d|debug=s" => \$debugexp,
+ "q|quiet" => sub {$verbosity = 0})
+ || pod2usage(-exitval => 2);
+if ($wantversion) {
+ print "wheretotrim $VERSION\n";
+ exit 0;
+}
+pod2usage(-verbose => $verbosity,
+ -exitval => 1) if $wanthelp;
+pod2usage(-message => "${progname}: A latex command must be specified",
+ -exitval => 2) if $#ARGV == -1;
+$ltxfile = basename($ARGV[$#ARGV]);
+$logfile = basename_newsuffix($ARGV[$#ARGV], ".log") if !defined $logfile;
+% \end{macrocode}
+% \iffalse
+
+% \fi
+%
+% Determine the document's baseline characteristics.
+% \iffalse
+# Determine the document's baseline characteristics.
+% \fi
+% \begin{macrocode}
+my ($basepages, $baselineskip, $textheight, $c2p_ptr) = latex_page_count 0, 0, 0;
+die "${progname}: Failed to build $ltxfile\n" if $basepages == 0;
+%<script>%column2page = %$c2p_ptr;
+print "\n" if $verbosity > 0;
+% \end{macrocode}
+% \iffalse
+
+% \fi
+%
+% Map an absolute column to a page and column number.
+% \iffalse
+# Map an absolute column to a page and column number.
+% \fi
+% \begin{macrocode}
+my $prevpage = 0;
+foreach my $col (sort {$a <=> $b} keys %column2page) {
+ my ($pagenum, $pagename) = @{$column2page{$col}};
+ if ($pagenum == $prevpage) {
+ $column2page{$col} = [$pagenum, 2, $pagename];
+ $colsperpage = 2;
+ }
+ else {
+ $column2page{$col} = [$pagenum, 1, $pagename];
+ }
+ $prevpage = $pagenum;
+}
+% \end{macrocode}
+% \iffalse
+
+% \fi
+%
+% If we were given a page, column, and expansion, typeset the document
+% with those parameters and exit.
+% \iffalse
+# If we were given a page, column, and expansion, typeset the document
+# with those parameters and exit.
+% \fi
+% \begin{macrocode}
+if (defined $debugexp) {
+ die "${progname}: Failed to parse \"$debugexp\" into {page, column, expansion}\n" if $debugexp !~ /^(\d+)\D+(\d+)\D+(\d+)$/;
+% \end{macrocode}
+% \iffalse
+
+% \fi
+%
+% Convert page and column number to absolute column number.
+% \iffalse
+ # Convert page and column number to absolute column number.
+% \fi
+% \begin{macrocode}
+ my ($target_page, $target_col, $expansion) = ($1, $2, $3);
+ my $testcol;
+ while (my ($abscol, $page_col) = each %column2page) {
+ if ($target_page == $page_col->[0] && $target_col == $page_col->[1]) {
+ $testcol = $abscol;
+ last;
+ }
+ }
+ die "${progname}: Failed to map page $target_page, column $target_col to an absolute column number\n" if !defined $testcol;
+% \end{macrocode}
+% \iffalse
+
+% \fi
+%
+% Enlarge the given page.
+% \iffalse
+ # Enlarge the given page.
+% \fi
+% \begin{macrocode}
+ my ($numpages, undef) = latex_page_count $testcol, $expansion, $colsperpage;
+ print "\n" if $verbosity > 0;
+ latex_page_count $testcol, $expansion, 0; # Run again without appending any extra columns.
+ print "\n" if $verbosity > 0;
+ print "Expanding page $target_page, column $target_col by $expansion lines ";
+ if ($numpages == $basepages) {
+ print "does not reduce the page count below $numpages pages.\n";
+ }
+ else {
+ print "reduces the page count from $basepages pages to $numpages pages.\n";
+ }
+ exit 0;
+}
+% \end{macrocode}
+% \iffalse
+
+% \fi
+%
+% Determine columns for which no amount of expansion will reduce the
+% page count.
+% \iffalse
+# Determine columns for which no amount of expansion will reduce the
+# page count.
+% \fi
+% \begin{macrocode}
+my $maxexpansion = int($textheight/$baselineskip + 1);
+my @complete = (0, 0+keys %column2page); # Fraction complete (numerator and denominator)
+foreach my $expcol (sort {$a <=> $b} keys %column2page) {
+ my ($numpages, undef) = latex_page_count $expcol, $maxexpansion, $colsperpage;
+ if ($verbosity > 0) {
+ $complete[0]++;
+ printf "Trial runs are %.1f%% complete.\n\n", 100.0*$complete[0]/$complete[1];
+ }
+ delete $column2page{$expcol} if $numpages > 0 && $numpages == $basepages;
+}
+% \end{macrocode}
+% \iffalse
+
+% \fi
+%
+% Keep expanding a page by greater and greater amounts until we reduce
+% our page count.
+% \iffalse
+# Keep expanding a page by greater and greater amounts until we reduce
+# our page count.
+% \fi
+% \begin{macrocode}
+my %col2savings; # Map from an absolute column to an {expansion, page count} tuple.
+my $target_num_cols = $allpages ? (keys %column2page) : 1; # Minimum number of columns for which to find an expansion amount
+my $minexpansion; # Minimum value of the above that saves a page
+@complete = (0, $maxexpansion*keys %column2page);
+foreach my $expansion (1 .. $maxexpansion) {
+% \end{macrocode}
+%
+% Expand each column in turn.
+% \iffalse
+ # Expand each column in turn.
+% \fi
+% \begin{macrocode}
+ foreach my $expcol (sort {$a <=> $b} keys %column2page) {
+ $complete[0]++;
+ next if defined $col2savings{$expcol}; # Already finished
+ next if $column2page{$expcol}->[0] == $basepages && $column2page{$expcol}->[1] == 2; # Second column on the last page
+ my ($numpages, undef) = latex_page_count $expcol, $expansion, $colsperpage;
+ if ($numpages > 0 && $numpages < $basepages) {
+ $col2savings{$expcol} = [$expansion, $numpages];
+ $minexpansion = $expansion if !defined $minexpansion;
+ }
+ if ($verbosity > 0) {
+ printf "Execution is %.1f%% complete.\n\n", 100.0*$complete[0]/$complete[1];
+ }
+ }
+ last if keys %col2savings >= $target_num_cols; # Success
+}
+% \end{macrocode}
+% \iffalse
+
+% \fi
+%
+% Restore the document to its original form.
+% \iffalse
+# Restore the document to its original form.
+% \fi
+% \begin{macrocode}
+run_latex $ltxfile, 0, 0, 0;
+printf "Execution is 100.0%% complete.\n\n" if $verbosity > 0;
+% \end{macrocode}
+% \iffalse
+
+% \fi
+%
+% Output the space savings.
+% \iffalse
+# Output the space savings.
+% \fi
+% \begin{macrocode}
+if (keys %col2savings == 0) {
+ printf "It does not appear possible to reduce the page count from %d to %d\n",
+ $basepages, $basepages-1;
+ print "by removing any amount of text from any single column.\n\n";
+ exit 0;
+}
+printf "To reduce the page count from %d to %d, do %s following:\n\n",
+ $basepages, $basepages-1, keys %col2savings == 1 ? "the" : "any of the";
+foreach my $abscol (sort {$a <=> $b} keys %col2savings) {
+ my ($expansion, $numpages) = @{$col2savings{$abscol}};
+ my ($page, $col, $pagename) = @{$column2page{$abscol}};
+ print " * Reduce page $page";
+ print " (\"$pagename\")" if $pagename ne $page;
+ print ", column $col" if $colsperpage > 1;
+ printf " by %d %s", $expansion, $expansion == 1 ? "line" : "lines";
+ if ($numpages < $basepages - 1) {
+ printf " (produces %d %s)", $numpages, $numpages == 1 ? "page" : "pages";
+ }
+ print ".\n";
+}
+print "\n";
+my $minpoints = $minexpansion*$baselineskip;
+printf "Note: %d lines = %.1f\" = %.1f cm = %.1f%% of the %s height\n",
+ $minexpansion, $minpoints/72.27, $minpoints/28.45,
+ 100.0*$minpoints/$textheight, $colsperpage == 1 ? "page" : "column";
+% \end{macrocode}
+% \iffalse
+
+###########################################################################
+
+__END__
+
+=head1 NAME
+
+wheretotrim - Help reduce the page count of a LaTeX document
+
+=head1 SYNOPSIS
+
+wheretotrim
+[B<--verbose> | B<--quiet>]
+[B<--allpages>]
+[B<--debug>=I<page>,I<column>,I<lines>]
+I<latex command>
+
+wheretotrim [B<--verbose>] B<--help>|B<--version>
+
+=head1 DESCRIPTION
+
+B<wheretotrim> is a tool to help LaTeX users reduce their document's
+page count. It is intended to be used with documents that exceed a
+publisher's specified page-length limitation by a small amount (much
+less than a full column or page). B<wheretotrim> operates by building
+the document repeatedly, successively expanding each column on each
+page by one line height to mimic reducing the amount of text in that
+column by an equivalent amount. If doing so does not reduce the page
+count, B<wheretotrim> repeats the process with two line heights'
+expansion of each column, then three, and so forth until it expands
+each column in turn by the full height of the column. The following
+is some sample output:
+
+ To reduce the page count from 10 to 9, do any of the following:
+
+ * Reduce page 9, column 1 by 12 lines.
+ * Reduce page 9, column 2 by 12 lines.
+ * Reduce page 10, column 1 by 12 lines.
+
+ Note: 12 lines = 2.4" = 6.1 cm = 26.8% of the column height
+
+That is, reducing either column on S<page 9> or the first column on
+S<page 10> by 12 lines is the most expedient way to reduce the
+document's page count. More than S<12 lines> would need to be cut on
+other columns and other pages to achieve the same effect.
+
+=head1 OPTIONS
+
+B<wheretotrim> accepts the following command-line options:
+
+=over 4
+
+=item B<-a>, B<--allpages>
+
+Perform enough extra runs of B<latex> to report the amount of space
+that must be trimmed from I<each> column or page to reduce page count,
+not just the columns or pages to which the page count is the most
+sensitive.
+
+=item B<-v>, B<--verbose>
+
+Display the output of each run of B<latex>. This is useful for
+troubleshooting and to help monitor the progress of long B<latex>
+runs.
+
+=item B<-q>, B<--quiet>
+
+Suppress progress updates and output only the final report.
+
+=item B<-d> I<page>,I<column>,I<lines>, B<--debug>=I<page>,I<column>,I<lines>
+
+Debug B<wheretotrim>'s execution by expanding page I<page>, column
+I<column> by I<lines> line heights and leaving the B<latex> output in
+that state.
+
+=item B<-h>, B<--help>
+
+Summarize usage information and exit. These may be used with
+B<--verbose> to display more extended documentation.
+
+=item B<-V>, B<--version>
+
+Display B<wheretotrim>'s version number and exit.
+
+=back
+
+In addition to the preceding options, B<wheretotrim> requires a
+I<latex command> argument that specifies how to build the document.
+
+=head1 EXAMPLES
+
+For the most basic usage, simply provide a B<latex> command to run:
+
+ wheretotrim latex myfile.tex
+
+or, for example,
+
+ wheretotrim pdflatex myfile.tex
+
+B<wheretotrim> executes the specified command a large number of times
+and finally terminates with a report resembling the following:
+
+ To reduce the page count from 10 to 9, do any of the following:
+
+ * Reduce page 9, column 1 by 12 lines.
+ * Reduce page 9, column 2 by 12 lines.
+ * Reduce page 10, column 1 by 12 lines.
+
+ Note: 12 lines = 2.4" = 6.1 cm = 26.8% of the column height
+
+To ask B<wheretotrim> to report how much space needs to be trimmed on
+each column and page to reduce the total page count, specify the
+B<--allpages> option:
+
+ wheretotrim --allpages latex myfile.tex
+
+The output now looks like the following:
+
+ To reduce the page count from 10 to 9, do any of the following:
+
+ * Reduce page 1, column 1 by 13 lines.
+ * Reduce page 1, column 2 by 13 lines.
+ * Reduce page 2, column 1 by 13 lines.
+ * Reduce page 2, column 2 by 13 lines.
+ * Reduce page 4, column 1 by 13 lines.
+ * Reduce page 4, column 2 by 13 lines.
+ * Reduce page 5, column 1 by 13 lines.
+ * Reduce page 5, column 2 by 13 lines.
+ * Reduce page 6, column 1 by 13 lines.
+ * Reduce page 6, column 2 by 13 lines.
+ * Reduce page 7, column 1 by 13 lines.
+ * Reduce page 7, column 2 by 13 lines.
+ * Reduce page 8, column 1 by 13 lines.
+ * Reduce page 8, column 2 by 13 lines.
+ * Reduce page 9, column 1 by 12 lines.
+ * Reduce page 9, column 2 by 12 lines.
+ * Reduce page 10, column 1 by 12 lines.
+
+ Note: 12 lines = 2.4" = 6.1 cm = 26.8% of the column height
+
+If you're curious how the document managed to shrink substantially as
+the result of a relatively minor text reduction, you can typeset the
+document with a particular page and column enlarged by a given amount:
+
+ wheretotrim --debug=9,1,12 latex myfile.tex
+
+=head1 CAVEATS
+
+B<wheretotrim> hooks into LaTeX's output routines, which are
+notoriously arcane and somewhat fragile. As a result, it is quite
+likely that B<wheretotrim> will fail to analyze a large set of
+documents. Use the B<--verbose> flag to help identify any problems
+that B<latex> encounters.
+
+In many cases, B<wheretotrim> will recover by simply ignoring a few
+possible page and column expansions. For example, certain expansions
+may result in a C<L<Float(s)
+lost|http://www.tex.ac.uk/cgi-bin/texfaq2html?label=fllost>> message.
+In other cases, B<wheretotrim> will fail to analyze any modification
+to the document. For example, it may receive an C<Infinite glue
+shrinkage found in box being split> error from every page and column
+variation it tries. In this particular case, see the discussion at
+L<http://www.michaelshell.org/tex/ieeetran/>.
+
+When B<wheretotrim> is used with a B<latex> auto-build script you may
+need to take measures to force the script to rebuild the document even
+if it appears that no files have changed. For example, B<latexmk>
+should be given the B<-CF> option to force rebuilding:
+
+ wheretotrim latexmk -CF myfile.tex
+
+=head1 RESTRICTIONS
+
+B<wheretotrim> is implemented as a Perl script with an auxiliary LaTeX
+package. It has been tested only on Linux, but I suspect that it
+should also work on S<OS X>. I doubt it will work under Windows,
+though, due to the way the script uses a B<bash>-specific technique
+for redirecting the standard error device into the standard output
+device.
+
+=head1 AUTHOR
+
+Scott Pakin, I<scott+wtt@pakin.org>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2013, Scott Pakin <scott+wtt@pakin.org>
+
+This file may be distributed and/or modified under the conditions of
+the LaTeX Project Public License, either version 1.3c of this license
+or (at your option) any later version. The latest version of this
+license is in:
+
+=over 4
+
+=item E<nbsp>
+
+L<http://www.latex-project.org/lppl.txt>
+
+=back
+
+and version 1.3c or later is part of all distributions of LaTeX
+version 2008/05/04 or later.
+
+=head1 SEE ALSO
+
+latex(1),
+L<the savetrees package|http://www.ctan.org/pkg/savetrees/>
+% \fi
+%
+% \endgroup
+%
+%
+%
+% The \progname{wheretotrim} script ends with
+% \href{http://perldoc.perl.org/perlpod.html}{POD}-format documentation.
+% This is not listed here because it is largely redundant with the
+% contents of Sections~\ref{sec:introduction} and~\ref{sec:usage}.
+% See those sections for documentation about \progname{wheretotrim}'s usage.
+% \endinput
diff --git a/support/wheretotrim/wheretotrim.1 b/support/wheretotrim/wheretotrim.1
new file mode 100644
index 0000000000..2cf8ba4deb
--- /dev/null
+++ b/support/wheretotrim/wheretotrim.1
@@ -0,0 +1,324 @@
+.\" Automatically generated by Pod::Man 2.25 (Pod::Simple 3.16)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. \*(C+ will
+.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.ie \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. nr % 0
+. rr F
+.\}
+.el \{\
+. de IX
+..
+.\}
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "WHERETOTRIM 1"
+.TH WHERETOTRIM 1 "2013-05-14" "v1.0" ""
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "NAME"
+wheretotrim \- Help reduce the page count of a LaTeX document
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+wheretotrim
+[\fB\-\-verbose\fR | \fB\-\-quiet\fR]
+[\fB\-\-allpages\fR]
+[\fB\-\-debug\fR=\fIpage\fR,\fIcolumn\fR,\fIlines\fR]
+\&\fIlatex command\fR
+.PP
+wheretotrim [\fB\-\-verbose\fR] \fB\-\-help\fR|\fB\-\-version\fR
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+\&\fBwheretotrim\fR is a tool to help LaTeX users reduce their document's
+page count. It is intended to be used with documents that exceed a
+publisher's specified page-length limitation by a small amount (much
+less than a full column or page). \fBwheretotrim\fR operates by building
+the document repeatedly, successively expanding each column on each
+page by one line height to mimic reducing the amount of text in that
+column by an equivalent amount. If doing so does not reduce the page
+count, \fBwheretotrim\fR repeats the process with two line heights'
+expansion of each column, then three, and so forth until it expands
+each column in turn by the full height of the column. The following
+is some sample output:
+.PP
+.Vb 1
+\& To reduce the page count from 10 to 9, do any of the following:
+\&
+\& * Reduce page 9, column 1 by 12 lines.
+\& * Reduce page 9, column 2 by 12 lines.
+\& * Reduce page 10, column 1 by 12 lines.
+\&
+\& Note: 12 lines = 2.4" = 6.1 cm = 26.8% of the column height
+.Ve
+.PP
+That is, reducing either column on page\ 9 or the first column on
+page\ 10 by 12 lines is the most expedient way to reduce the
+document's page count. More than 12\ lines would need to be cut on
+other columns and other pages to achieve the same effect.
+.SH "OPTIONS"
+.IX Header "OPTIONS"
+\&\fBwheretotrim\fR accepts the following command-line options:
+.IP "\fB\-a\fR, \fB\-\-allpages\fR" 4
+.IX Item "-a, --allpages"
+Perform enough extra runs of \fBlatex\fR to report the amount of space
+that must be trimmed from \fIeach\fR column or page to reduce page count,
+not just the columns or pages to which the page count is the most
+sensitive.
+.IP "\fB\-v\fR, \fB\-\-verbose\fR" 4
+.IX Item "-v, --verbose"
+Display the output of each run of \fBlatex\fR. This is useful for
+troubleshooting and to help monitor the progress of long \fBlatex\fR
+runs.
+.IP "\fB\-q\fR, \fB\-\-quiet\fR" 4
+.IX Item "-q, --quiet"
+Suppress progress updates and output only the final report.
+.IP "\fB\-d\fR \fIpage\fR,\fIcolumn\fR,\fIlines\fR, \fB\-\-debug\fR=\fIpage\fR,\fIcolumn\fR,\fIlines\fR" 4
+.IX Item "-d page,column,lines, --debug=page,column,lines"
+Debug \fBwheretotrim\fR's execution by expanding page \fIpage\fR, column
+\&\fIcolumn\fR by \fIlines\fR line heights and leaving the \fBlatex\fR output in
+that state.
+.IP "\fB\-h\fR, \fB\-\-help\fR" 4
+.IX Item "-h, --help"
+Summarize usage information and exit. These may be used with
+\&\fB\-\-verbose\fR to display more extended documentation.
+.IP "\fB\-V\fR, \fB\-\-version\fR" 4
+.IX Item "-V, --version"
+Display \fBwheretotrim\fR's version number and exit.
+.PP
+In addition to the preceding options, \fBwheretotrim\fR requires a
+\&\fIlatex command\fR argument that specifies how to build the document.
+.SH "EXAMPLES"
+.IX Header "EXAMPLES"
+For the most basic usage, simply provide a \fBlatex\fR command to run:
+.PP
+.Vb 1
+\& wheretotrim latex myfile.tex
+.Ve
+.PP
+or, for example,
+.PP
+.Vb 1
+\& wheretotrim pdflatex myfile.tex
+.Ve
+.PP
+\&\fBwheretotrim\fR executes the specified command a large number of times
+and finally terminates with a report resembling the following:
+.PP
+.Vb 1
+\& To reduce the page count from 10 to 9, do any of the following:
+\&
+\& * Reduce page 9, column 1 by 12 lines.
+\& * Reduce page 9, column 2 by 12 lines.
+\& * Reduce page 10, column 1 by 12 lines.
+\&
+\& Note: 12 lines = 2.4" = 6.1 cm = 26.8% of the column height
+.Ve
+.PP
+To ask \fBwheretotrim\fR to report how much space needs to be trimmed on
+each column and page to reduce the total page count, specify the
+\&\fB\-\-allpages\fR option:
+.PP
+.Vb 1
+\& wheretotrim \-\-allpages latex myfile.tex
+.Ve
+.PP
+The output now looks like the following:
+.PP
+.Vb 1
+\& To reduce the page count from 10 to 9, do any of the following:
+\&
+\& * Reduce page 1, column 1 by 13 lines.
+\& * Reduce page 1, column 2 by 13 lines.
+\& * Reduce page 2, column 1 by 13 lines.
+\& * Reduce page 2, column 2 by 13 lines.
+\& * Reduce page 4, column 1 by 13 lines.
+\& * Reduce page 4, column 2 by 13 lines.
+\& * Reduce page 5, column 1 by 13 lines.
+\& * Reduce page 5, column 2 by 13 lines.
+\& * Reduce page 6, column 1 by 13 lines.
+\& * Reduce page 6, column 2 by 13 lines.
+\& * Reduce page 7, column 1 by 13 lines.
+\& * Reduce page 7, column 2 by 13 lines.
+\& * Reduce page 8, column 1 by 13 lines.
+\& * Reduce page 8, column 2 by 13 lines.
+\& * Reduce page 9, column 1 by 12 lines.
+\& * Reduce page 9, column 2 by 12 lines.
+\& * Reduce page 10, column 1 by 12 lines.
+\&
+\& Note: 12 lines = 2.4" = 6.1 cm = 26.8% of the column height
+.Ve
+.PP
+If you're curious how the document managed to shrink substantially as
+the result of a relatively minor text reduction, you can typeset the
+document with a particular page and column enlarged by a given amount:
+.PP
+.Vb 1
+\& wheretotrim \-\-debug=9,1,12 latex myfile.tex
+.Ve
+.SH "CAVEATS"
+.IX Header "CAVEATS"
+\&\fBwheretotrim\fR hooks into LaTeX's output routines, which are
+notoriously arcane and somewhat fragile. As a result, it is quite
+likely that \fBwheretotrim\fR will fail to analyze a large set of
+documents. Use the \fB\-\-verbose\fR flag to help identify any problems
+that \fBlatex\fR encounters.
+.PP
+In many cases, \fBwheretotrim\fR will recover by simply ignoring a few
+possible page and column expansions. For example, certain expansions
+may result in a \f(CW\*(C`Float(s)
+lost <http://www.tex.ac.uk/cgi-bin/texfaq2html?label=fllost>\*(C'\fR message.
+In other cases, \fBwheretotrim\fR will fail to analyze any modification
+to the document. For example, it may receive an \f(CW\*(C`Infinite glue
+shrinkage found in box being split\*(C'\fR error from every page and column
+variation it tries. In this particular case, see the discussion at
+<http://www.michaelshell.org/tex/ieeetran/>.
+.PP
+When \fBwheretotrim\fR is used with a \fBlatex\fR auto-build script you may
+need to take measures to force the script to rebuild the document even
+if it appears that no files have changed. For example, \fBlatexmk\fR
+should be given the \fB\-CF\fR option to force rebuilding:
+.PP
+.Vb 1
+\& wheretotrim latexmk \-CF myfile.tex
+.Ve
+.SH "RESTRICTIONS"
+.IX Header "RESTRICTIONS"
+\&\fBwheretotrim\fR is implemented as a Perl script with an auxiliary LaTeX
+package. It has been tested only on Linux, but I suspect that it
+should also work on \s-1OS\s0\ X. I doubt it will work under Windows,
+though, due to the way the script uses a \fBbash\fR\-specific technique
+for redirecting the standard error device into the standard output
+device.
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+Scott Pakin, \fIscott+wtt@pakin.org\fR
+.SH "COPYRIGHT AND LICENSE"
+.IX Header "COPYRIGHT AND LICENSE"
+Copyright (C) 2013, Scott Pakin <scott+wtt@pakin.org>
+.PP
+This file may be distributed and/or modified under the conditions of
+the LaTeX Project Public License, either version 1.3c of this license
+or (at your option) any later version. The latest version of this
+license is in:
+.IP "\" 4
+http://www.latex\-project.org/lppl.txt <http://www.latex-project.org/lppl.txt>
+.PP
+and version 1.3c or later is part of all distributions of LaTeX
+version 2008/05/04 or later.
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\fIlatex\fR\|(1),
+the savetrees package <http://www.ctan.org/pkg/savetrees/>
diff --git a/support/wheretotrim/wheretotrim.dtx b/support/wheretotrim/wheretotrim.dtx
new file mode 100644
index 0000000000..de8c5c1df1
--- /dev/null
+++ b/support/wheretotrim/wheretotrim.dtx
@@ -0,0 +1,725 @@
+% \iffalse meta-comment
+%
+% Copyright (C) 2013 by Scott Pakin <scott+wtt@pakin.org>
+% -------------------------------------------------------
+%
+% This file may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3c
+% of this license or (at your option) any later version.
+% The latest version of this license is in:
+%
+% http://www.latex-project.org/lppl.txt
+%
+% and version 1.3c or later is part of all distributions of LaTeX
+% version 2008/05/04 or later.
+%
+% \fi
+%
+% \iffalse
+%<*driver>
+\ProvidesFile{wheretotrim.dtx}
+%</driver>
+%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
+%<package>\ProvidesPackage{wheretotrim}
+%<*package>
+ [2013/05/15 v1.0 Helper package for the wheretotrim script]
+%</package>
+%
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{tabularx}
+\usepackage{type1cm}
+\usepackage{pifont}
+\usepackage{needspace}
+\usepackage[bookmarksopen]{hyperref}
+\EnableCrossrefs
+\CodelineIndex
+\RecordChanges
+\begin{document}
+ \DocInput{wheretotrim.dtx}
+% \PrintChanges
+ \makeatletter
+ \let\orig@index@prologue=\index@prologue
+ \def\index@prologue{%
+ \phantomsection\addcontentsline{toc}{section}{Index}
+ \orig@index@prologue
+ }%
+ \makeatother
+ \Needspace{12\baselineskip}
+ \begingroup
+ \catcode`\_=12
+ \PrintIndex
+ \endgroup
+\end{document}
+%</driver>
+% \fi
+%
+% \CheckSum{180}
+%
+% \CharacterTable
+% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+% Digits \0\1\2\3\4\5\6\7\8\9
+% Exclamation \! Double quote \" Hash (number) \#
+% Dollar \$ Percent \% Ampersand \&
+% Acute accent \' Left paren \( Right paren \)
+% Asterisk \* Plus \+ Comma \,
+% Minus \- Point \. Solidus \/
+% Colon \: Semicolon \; Less than \<
+% Equals \= Greater than \> Question mark \?
+% Commercial at \@ Left bracket \[ Backslash \\
+% Right bracket \] Circumflex \^ Underscore \_
+% Grave accent \` Left brace \{ Vertical bar \|
+% Right brace \} Tilde \~}
+%
+%
+% \changes{v1.0}{2013/05/15}{Initial version}
+%
+% \GetFileInfo{wheretotrim.dtx}
+%
+% \DoNotIndex{\",\$,\%,\(,\),!,\D,\d,\n}
+% \DoNotIndex{\addtocounter,\def,\edef,\fi,\gdef,\ifnum,\let}
+% \DoNotIndex{\newcommand,\newcounter,\noexpand,\noindent,\par,\relax}
+% \DoNotIndex{\setcounter,\space,\the,\value,\xdef}
+% \newcommand{\see}[1]{\textit{see} #1}
+% \index{command-line options|see{program options}}
+%
+% ^^A Define a few logical styles to help typeset the documentation.
+% \DeclareRobustCommand{\pkgname}[1]{^^A
+% \mbox{\textsf{#1}}^^A
+% \SortIndex{packages}{packages>\textsf{#1}}^^A
+% \SortIndex{#1}{\textsf{#1} (package)}}
+% \DeclareRobustCommand{\optname}[1]{^^A
+% \mbox{\texttt{#1}}^^A
+% \SortIndex{package options}{package options>\texttt{#1}}^^A
+% \SortIndex{#1}{\texttt{#1} (package option)}}
+% \DeclareRobustCommand{\progname}[1]{^^A
+% \mbox{\texttt{#1}}^^A
+% \SortIndex{programs}{programs>\texttt{#1}}^^A
+% \SortIndex{#1}{\texttt{#1} (program)}}
+% \DeclareRobustCommand{\longopt}[1]{^^A
+% \mbox{\textbf{-{}-#1}}^^A
+% \SortIndex{program options}{program options>\texttt{-{}-#1}}^^A
+% \SortIndex{#1}{\texttt{-{}-#1} (program option)}}
+%
+% ^^A Specify this document's metadata.
+% \title{The \textsf{wheretotrim} package\thanks{This document
+% corresponds to \textsf{wheretotrim}~\fileversion, dated \filedate.}}
+% \author{Scott Pakin \\ \texttt{scott+wtt@pakin.org}}
+% \hypersetup{^^A
+% pdfauthor={Scott Pakin},
+% pdftitle={The wheretotrim package},
+% pdfsubject={Determine where to cut text to most easily reduce page count}
+% }
+%
+% \maketitle
+% \sloppy
+%
+% \section{Introduction}
+% \label{sec:introduction}
+%
+% \progname{wheretotrim} is a tool to help \LaTeX\ users reduce their
+% document's page count. It is intended to be used with documents that
+% exceed a publisher's specified page-length limitation by a small
+% amount (much less than a full column or page). \progname{wheretotrim}
+% is therefore similar to the \pkgname{savetrees} package in that both
+% seek to reduce page count. The two differ in that \pkgname{savetrees}
+% saves space by altering document formatting while
+% \progname{wheretotrim} suggests where text can be removed to reduce
+% page count without altering any formatting. \progname{wheretotrim}
+% and \pkgname{savetrees} are compatible with each other, though:
+% \progname{wheretotrim} can safely be run on a document that includes a
+% |\usepackage{savetrees}|.
+%
+% \progname{wheretotrim} operates by building the document repeatedly,
+% successively expanding each column on each page by one line height to
+% mimic reducing the amount of text in that column by an equivalent
+% amount. If doing so does not reduce the page count,
+% \progname{wheretotrim} repeats the process with two line heights'
+% expansion of each column, then three, and so forth until it expands
+% each column in turn by the full height of the column. The following
+% is some sample output for a single-column document when
+% \progname{wheretotrim} is run with the \longopt{allpages} option
+% (cf.~Section~\ref{sec:cmdline}):
+% \begin{verbatim}
+% To reduce the page count from 11 to 10, do any of the following:
+%
+% * Reduce page 2 by 8 lines.
+% * Reduce page 5 by 7 lines.
+% * Reduce page 6 by 7 lines.
+% * Reduce page 7 by 7 lines.
+% * Reduce page 8 by 7 lines.
+% * Reduce page 9 by 7 lines.
+% * Reduce page 10 by 5 lines.
+% * Reduce page 11 by 5 lines.
+%
+% Note: 5 lines = 1.0" = 2.5 cm = 11.1% of the page height
+% \end{verbatim}
+%
+% \noindent
+% That is, reducing either page~10 or page~11 by five lines is the most
+% expedient way to reduce the document's page count. Seven lines would
+% need to be cut from page~5, 6, 7, or~8 to achieve the same effect, and
+% eight lines would need to be cut from page~2. In contrast, no amount
+% of text trimming on pages~1, 3, or~4 will reduce the page count.
+%
+% \section{Usage}
+% \label{sec:usage}
+%
+% Sections~\ref{sec:cmdline}--\ref{sec:restrictions} explain how to use
+% \progname{wheretotrim}.
+%
+% \subsection{Command-line options}
+% \label{sec:cmdline}
+%
+% Run \progname{wheretotrim} as follows:
+%
+% \DeleteShortVerb{\|}
+% \begin{quote}
+% \raggedright
+% \progname{wheretotrim}
+% [\longopt{allpages}]
+% [\longopt{verbose} \textbar\ \longopt{quiet}]
+% [\longopt{debug}=\meta{page},\meta{column},\meta{lines}]
+% \meta{latex command}
+% \end{quote}
+% \noindent
+% or
+% \begin{quote}
+% \raggedright
+% \progname{wheretotrim} [\longopt{verbose}] \longopt{help} \textbar\ \longopt{version}
+% \end{quote}
+% \MakeShortVerb{\|}
+%
+% \progname{wheretotrim} accepts the following command-line options:
+%
+% \begin{description}
+% \item[-a, \longopt{allpages}] Perform enough extra runs of
+% \progname{latex} to report the amount of space that must be
+% trimmed from \emph{each} column or page to reduce page count, not
+% just the columns or pages to which the page count is the most
+% sensitive.
+%
+% \item[-v, \longopt{verbose}] Display the output of each run of
+% \progname{latex}. This is useful for troubleshooting and to help
+% monitor the progress of long \progname{latex} runs.
+%
+% \item[-q, \longopt{quiet}] Suppress progress updates and output only the
+% final report.
+%
+% \item[-d \meta{page},\meta{column},\meta{lines},
+% \longopt{debug}=\meta{page},\meta{column},\meta{lines}] Debug
+% \progname{wheretotrim}'s execution by expanding page \meta{page},
+% column \meta{column} by \meta{lines} line heights and leaving the
+% \progname{latex} output in that state.
+%
+% \item[-h, \longopt{help}] Summarize usage information and exit.
+% These may be used with \longopt{verbose} to display more extended
+% documentation.
+%
+% \item[-V, \longopt{version}] Display \progname{wheretotrim}'s version
+% number and exit.
+% \end{description}
+%
+% In addition to the preceding options, \progname{wheretotrim} requires
+% a \meta{latex command} argument that specifies how to build the
+% document.
+%
+% \subsection{Examples}
+% \label{sec:examples}
+%
+% For the most basic usage, simply provide a \progname{latex} command to
+% run:
+%
+% \begin{verbatim}
+% wheretotrim latex myfile.tex
+% \end{verbatim}
+%
+% \noindent
+% or, for example,
+%
+% \begin{verbatim}
+% wheretotrim pdflatex myfile.tex
+% \end{verbatim}
+%
+% \progname{wheretotrim} executes the specified command a large number
+% of times and finally terminates with a report resembling the
+% following:
+%
+% \begin{verbatim}
+% To reduce the page count from 10 to 9, do any of the following:
+%
+% * Reduce page 9, column 1 by 12 lines.
+% * Reduce page 9, column 2 by 12 lines.
+% * Reduce page 10, column 1 by 12 lines.
+%
+% Note: 12 lines = 2.4" = 6.1 cm = 26.8% of the column height
+% \end{verbatim}
+%
+% To ask \progname{wheretotrim} to report how much space needs to be
+% trimmed on each column and page to reduce the total page count,
+% specify the \longopt{allpages} option:
+%
+% \begin{verbatim}
+% wheretotrim --allpages latex myfile.tex
+% \end{verbatim}
+%
+% The output now looks like the following:
+%
+% \begin{verbatim}
+% To reduce the page count from 10 to 9, do any of the following:
+%
+% * Reduce page 1, column 1 by 13 lines.
+% * Reduce page 1, column 2 by 13 lines.
+% * Reduce page 2, column 1 by 13 lines.
+% * Reduce page 2, column 2 by 13 lines.
+% * Reduce page 4, column 1 by 13 lines.
+% * Reduce page 4, column 2 by 13 lines.
+% * Reduce page 5, column 1 by 13 lines.
+% * Reduce page 5, column 2 by 13 lines.
+% * Reduce page 6, column 1 by 13 lines.
+% * Reduce page 6, column 2 by 13 lines.
+% * Reduce page 7, column 1 by 13 lines.
+% * Reduce page 7, column 2 by 13 lines.
+% * Reduce page 8, column 1 by 13 lines.
+% * Reduce page 8, column 2 by 13 lines.
+% * Reduce page 9, column 1 by 12 lines.
+% * Reduce page 9, column 2 by 12 lines.
+% * Reduce page 10, column 1 by 12 lines.
+%
+% Note: 12 lines = 2.4" = 6.1 cm = 26.8% of the column height
+% \end{verbatim}
+%
+% If you're curious how the document managed to shrink substantially as
+% the result of a relatively minor text reduction, you can typeset the
+% document with a particular page and column enlarged by a given amount:
+%
+% \begin{verbatim}
+% wheretotrim --debug=9,1,12 latex myfile.tex
+% \end{verbatim}
+%
+% \subsection{Caveats}
+% \label{sec:caveats}
+%
+% \progname{wheretotrim} hooks into \LaTeX's output routines, which are
+% notoriously arcane and somewhat fragile. As a result, it is quite
+% likely that \progname{wheretotrim} will fail to analyze a large set of
+% documents. Use the \longopt{verbose} flag to help identify any
+% problems that \progname{latex} encounters.
+%
+% In many cases, \progname{wheretotrim} will recover by simply ignoring
+% a few possible page and column expansions. For example, certain
+% expansions may result in a
+% \href{http://www.tex.ac.uk/cgi-bin/texfaq2html?label=fllost}{\texttt{Float(s)
+% lost}} message. In other cases, \progname{wheretotrim} will fail
+% to analyze any modification to the document. For example, it may
+% receive an \texttt{Infinite glue shrinkage found in box being split}
+% error from every page and column variation it tries. In this
+% particular case, see the discussion at
+% \url{http://www.michaelshell.org/tex/ieeetran/}.
+%
+% When \progname{wheretotrim} is used with a \progname{latex} auto-build
+% script you may need to take measures to force the script to rebuild
+% the document even if it appears that no files have changed. For
+% example, \progname{latexmk} should be given the |-CF| option to force
+% rebuilding:
+%
+% \begin{verbatim}
+% wheretotrim latexmk -CF myfile.tex
+% \end{verbatim}
+%
+% \subsection{Restrictions}
+% \label{sec:restrictions}
+%
+% \progname{wheretotrim} is implemented as a Perl script with an
+% auxiliary \LaTeXe\ package. It has been tested only on Linux, but I
+% suspect that it should also work on OS~X. I doubt it will work
+% under Windows, though, due to the way the script uses a
+% \progname{bash}-specific technique for redirecting the standard error
+% device into the standard output device.
+%
+%
+% \StopEventually{}
+%
+% \iffalse
+%<*package>
+% \fi
+%
+% \section{Package implementation}
+%
+% This section presents the commented \LaTeX\ source code for the
+% \pkgname{wheretotrim} package. Read this section if you want to learn
+% how the package is implemented. Note that the package is not intended
+% to be used explicitly (i.e.,~via |\usepackage|) but rather implicitly
+% by the \progname{wheretotrim} Perl script.
+%
+% \subsection{Theory of operation}
+%
+% The \pkgname{wheretotrim} package mimics the effect of reducing a
+% given page and column of a document by a given number of line heights.
+% For simplicity, it does so by enlarging the specified column (so
+% as to fit additional lines of text) rather than by reducing the
+% amount of text in that column.
+%
+% Users are not expected to load the \pkgname{wheretotrim} package
+% explicitly. Instead, whenever the \progname{wheretotrim} script needs
+% to observe the effect of enlarging a given column, it creates a
+% temporary |.tex| file using the following template:
+%
+% \begingroup
+% \ttfamily
+% \begin{tabbing}
+% ~~~~\=|\RequirePackage[|\=\kill
+% \>|\RequirePackage[|\> column={\normalfont\meta{absolute column}}], \\
+% \> \> expansion={\normalfont\meta{lines}}, \\
+% \> \> extracols={\normalfont\meta{padding columns}}]|{wheretotrim}| \\
+% \> |\PassOptionsToPackage{draft}{hyperref}| \\
+% \> |\input{|{\normalfont\meta{filename}}|}| \\
+% \end{tabbing}
+% \endgroup
+%
+% \noindent
+% where \meta{absolute column} is the absolute column number to expand
+% (with the first column on the first page being numbered~ 1);
+% \meta{lines} is the number of line heights (multiples of
+% |\baselineskip|) by which to enlarge that column; \meta{padding
+% columns} is the number of extra full columns to append to the
+% document (cf.~Section~\ref{sec:page-spillover}); and \meta{filename}
+% is the name of the user's top-level \LaTeX\ file.
+%
+% The \pkgname{wheretotrim} package works by modifying various \TeX- and
+% \LaTeX-internal commands. At every |\shipout|, \pkgname{wheretotrim}
+% increases the absolute page counter. Whenever \LaTeX\ constructs a
+% column using |\@makecol|, \pkgname{wheretotrim} logs the current
+% absolute page and column numbers and invokes \LaTeX's
+% |\enlargethispage| macro when on the target page and column number.
+% Because |\@makecol| is not called for every column,
+% \pkgname{wheretotrim} additionally modifies |\clearpage| and
+% |\maketitle| also to conditionally enlarge the current column.
+%
+% At the end of the document, \pkgname{wheretotrim} outputs
+% |\baselineskip| and |\textheight|, as these are needed by the
+% \progname{wheretotrim} script.
+%
+% \subsection{Package options}
+% \label{sec:pkg-opts}
+%
+% The \pkgname{wheretotrim} package accepts three package
+% options---\optname{column}, \optname{expansion}, and
+% \optname{extracols}---which are described
+% below in the context of, respectively, |\wtt@target@column|,
+% |\wtt@column@expand|, and |\wtt@extra@full@columns|.
+%
+% \begin{macro}{\wtt@target@column}
+% |\wtt@target@column| is set by the \optname{column} option and
+% defaults to nonexistent column~0. It specifies the absolute column
+% number to expand.
+% \begin{macrocode}
+\newcommand{\wtt@target@column}{0}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\wtt@column@expand}
+% The |\wtt@column@expand| length---implemented as an ordinary
+% macro---is set by the \optname{expansion} option and defaults to
+% 0\,pt. It specifies the number of lines by which to expand that
+% column (i.e.,~the multiple of |\baselineskip|).
+% \begin{macrocode}
+\newcommand{\wtt@column@expand}{0pt}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\wtt@extra@full@columns}
+% |\wtt@extra@full@columns| is set by the \optname{extracols} option and
+% specifies the number of additional, dummy, full columns to append to
+% the end of the document to force spillover onto an additional page.
+% \begin{macrocode}
+\newcommand{\wtt@extra@full@columns}{0}
+% \end{macrocode}
+% \end{macro}
+%
+% We use the \pkgname{keyval} package to help with option processing as
+% it's widely available and \pkgname{wheretotrim}'s option-processing
+% needs are fairly simple.
+% \begin{macrocode}
+\RequirePackage{keyval}
+% \end{macrocode}
+% \begin{macrocode}
+\define@key{wtt}{column}{\gdef\wtt@target@column{#1}}
+\define@key{wtt}{expansion}{%
+ \xdef\wtt@column@expand{#1\noexpand\baselineskip}%
+}
+\define@key{wtt}{extracols}{\gdef\wtt@extra@full@columns{#1}}
+% \end{macrocode}
+%
+% \begin{macro}{\next}
+% Process our options. We need to expand |\CurrentOption| before
+% passing it to \pkgname{keyval}'s |\setkeys| macro, however.
+% \begin{macrocode}
+\DeclareOption*{%
+ \edef\next{\noexpand\setkeys{wtt}{\CurrentOption}}%
+ \next
+}
+\ProcessOptions\relax
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Column enlargement}
+% \label{sec:col-enlarge}
+%
+% \begin{macro}{\c@wtt@true@page}
+% The \pkgname{wheretotrim} package needs to keep track of the current
+% page number. The |page| counter is unsuitable for this task because
+% it is really a page \emph{name}. That is, (1)~it is not necessarily
+% numeric (e.g.,~it may be a roman numeral while in the document's front
+% matter), and (2)~it is not necessarily unique (e.g.,~|page| may be~|1|
+% on the title page, abstract, and first page of text). To address this
+% limitation we define a |wtt@true@page| counter and, with the help of
+% the \pkgname{everyshi} package, prepare for it to be incremented on
+% every \TeX\ page shipout.
+% \begin{macrocode}
+\newcounter{wtt@true@page}
+\setcounter{wtt@true@page}{1}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\RequirePackage{everyshi}
+\EveryShipout{\addtocounter{wtt@true@page}{1}}
+% \end{macrocode}
+%
+% \begin{macro}{\c@wtt@column@num}
+% The \pkgname{wheretotrim} package also needs to keep track of the
+% current absolute column number. By ``absolute'' we mean a running
+% column number that does not reset to~1 on each page. We define a
+% |wtt@column@num| counter to hold the current column number, and,
+% below, we modify \LaTeXe's |\@makecol| macro to increment it. Note
+% that some pages may contain fewer pages than others due to, for
+% example, |\clearpage| calls that cause pages to ship out early.
+% \begin{macrocode}
+\newcounter{wtt@column@num}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\wtt@makecol}
+% Before redefining |\@makecol|, we store its old definition in
+% |\wtt@makecol|.
+% \begin{macrocode}
+\let\wtt@makecol=\@makecol
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@makecol}
+% |\@makecol| is \LaTeXe's primary mechanism for typesetting a column:
+%
+% \begin{center}
+% \small
+% \begin{tabularx}{\linewidth}{@{}rX@{}}
+% \hspace{1em}|\@makecol|:
+% & Makes the contents of |\box||255| plus the accumulated footnotes,
+% plus the floats in |\@toplist| and |\@botlist|, into a single
+% column of height |\@colht| (unless the page height has been
+% locally changed), which it puts into box |\@outputbox|. It puts
+% boxes in |\@midlist| back onto |\@freelist| and restores
+% |\maxdepth|.
+% \end{tabularx}
+% \end{center}
+%
+% Here, we augment |\@makecol| with code to report the current column
+% and page number---and for the user's convenience, page name
+% (|\thepage|). Our redefined |\@makecol| then increments the current
+% absolute column number and compares it against |\wtt@target@column|.
+% If equal, it uses \LaTeXe's |\enlargethispage| to increase the column
+% height. Finally, it invokes the original |\@makecol| (stored in
+% |\wtt@makecol| to typeset the column.
+% \begin{macrocode}
+\def\@makecol{%
+ \PackageInfo{wheretotrim}%
+ {Column \thewtt@column@num\space is on page
+ \thewtt@true@page\space (\thepage)}%
+ \addtocounter{wtt@column@num}{1}%
+ \ifnum\value{wtt@column@num}=\wtt@target@column
+ \enlargethispage{\wtt@column@expand}%
+ \fi
+ \wtt@makecol
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\wtt@clearpage}
+% Before redefining |\clearpage|, we store its old definition in
+% |\wtt@clearpage|.
+% \begin{macrocode}
+\let\wtt@clearpage=\clearpage
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\clearpage}
+% \LaTeXe's |\clearpage| macro frustrates the \pkgname{wheretotrim}
+% package's attempts to enlarge a given column. We therefore redefine
+% |\clearpage| first to perform its ordinary behavior (stored in
+% |\wtt@clearpage|, then to check the value of the preceding penalty
+% item. If the last penalty is -10001 then this is an opportune time to
+% insert an |\enlargethispage| (assuming the current column is equal to
+% |\wtt@target@column|). Because |\clearpage| may be called multiple
+% times in a row and may be followed by |\@makecol| we restore the
+% column counter to its prior value after comparing it to
+% |\wtt@target@column| so it is not multiply incremented.
+%
+% Note that |\cleardoublepage| internally calls |\clearpage| so it is
+% sufficient to redefine only |\clearpage|.
+% \begin{macrocode}
+\gdef\clearpage{%
+ \wtt@clearpage
+ \ifnum\lastpenalty=-10001\relax
+ \addtocounter{wtt@column@num}{1}%
+ \ifnum\value{wtt@column@num}=\wtt@target@column
+ \enlargethispage{\wtt@column@expand}%
+ \fi
+ \addtocounter{wtt@column@num}{-1}%
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+% Wait until after the |\begin{document}| to redefine |\maketitle| in
+% case |\maketitle| is modified before that point.
+% \begin{macrocode}
+\AtBeginDocument{%
+% \end{macrocode}
+% \begin{macro}{\wtt@maketitle}
+% Before redefining |\maketitle|, we store its old definition in
+% |\wtt@maketitle|.
+% \begin{macrocode}
+ \let\wtt@maketitle=\maketitle
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\maketitle}
+% |\maketitle| is problematic macro for the \pkgname{wheretotrim}
+% package because of the way it switches into two-column mode within a
+% one-column document (via \LaTeXe's |\twocolumn| macro). For lack of a
+% more general solution we redefine |\maketitle| to enlarge the column
+% only after typesetting the title and only when in two-column mode.
+% Otherwise, the |\enlargethispage| inserted by |\@makecol| already had
+% its intended effect.
+% \begin{macrocode}
+ \gdef\maketitle{%
+ \wtt@maketitle
+ \if@twocolumn
+ \ifnum\value{wtt@column@num}=\wtt@target@column
+ \enlargethispage{\wtt@column@expand}%
+ \fi
+ \fi
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Page spillover}
+% \label{sec:page-spillover}
+%
+% Normally, it would not be possible to reduce page count by enlarging
+% the last column by any amount. The trick we use here is to add to the
+% end of the document a full column or two to make the document spill
+% over onto an additional page, as illustrated by
+% Figure~\ref{fig:page-spillover}. Thus, enlarging the last column by
+% the height of the text it contains will enable a padding column to
+% shift into that column and reduce the page count.
+%
+% \begin{figure}[htbp]
+% \centering
+% \fbox{^^A
+% \begin{minipage}[t][3cm]{1cm}
+% \fontsize{2}{2}\selectfont\raggedright
+% \vspace{4pt}
+% Quisque fringilla, felis eu ultricies commodo, tortor justo lobortis
+% est, sit amet molestie ligula lorem at urna. Duis sit amet ligula
+% odio, sed varius massa. Duis lacinia odio elit. Nam adipiscing orci
+% eu lectus tincidunt porta rhoncus in nisl. Mauris tincidunt mollis
+% malesuada.
+% \end{minipage}
+% \begin{minipage}[t][3cm]{1cm}
+% \mbox{}
+% \end{minipage}
+% }
+% \begin{minipage}[t][3cm]{1cm}
+% \vspace{1cm}
+% \fontsize{36}{36}\ding{220}
+% \end{minipage}
+% ~^^A
+% \fbox{^^A
+% \begin{minipage}[t][3cm]{1cm}
+% \fontsize{2}{2}\selectfont\raggedright
+% \vspace{4pt}
+% Quisque fringilla, felis eu ultricies commodo, tortor justo lobortis
+% est, sit amet molestie ligula lorem at urna. Duis sit amet ligula
+% odio, sed varius massa. Duis lacinia odio elit. Nam adipiscing orci
+% eu lectus tincidunt porta rhoncus in nisl. Mauris tincidunt mollis
+% malesuada.
+% \end{minipage}
+% \begin{minipage}[t][3cm]{1cm}
+% \rule[-2.9cm]{1cm}{2.8cm}
+% \end{minipage}
+% }
+% \fbox{^^A
+% \begin{minipage}[t][3cm]{1cm}
+% \rule[-2.9cm]{1cm}{2.8cm}
+% \end{minipage}
+% \begin{minipage}[t][3cm]{1cm}
+% \mbox{}
+% \end{minipage}
+% }
+% \caption{Padding a document with extra columns to induce page spillover}
+% \label{fig:page-spillover}
+% \end{figure}
+%
+% \begin{macrocode}
+\AtEndDocument{%
+% \end{macrocode}
+% Add zero, one, or two columns of padding (a |\parbox| of width
+% |\linewidth| and height |\textheight|) based on the value of
+% |\wtt@extra@full@columns| (set by the \optname{extracols} package
+% option).
+% \begin{macrocode}
+ \ifnum\wtt@extra@full@columns>0\relax
+ \noindent\parbox[t][\textheight]{\linewidth}{%
+ \rule{\linewidth}{\baselineskip}}\par
+ \ifnum\wtt@extra@full@columns>1\relax
+ \noindent\parbox[t][\textheight]{\linewidth}{%
+ \rule{\linewidth}{\baselineskip}}\par
+ \fi
+ \fi
+% \end{macrocode}
+% Also at the end of the document, output the value of |\baselineskip|
+% and the value of |\textheight|, as these are read by the
+% \progname{wheretotrim} script.
+% \begin{macrocode}
+ \PackageInfo{wheretotrim}%
+ {Baseline skip: \the\baselineskip}%
+ \PackageInfo{wheretotrim}%
+ {Text height: \the\textheight}%
+}
+% \end{macrocode}
+%
+% \iffalse
+%</package>
+% \fi
+%
+% \section{Script implementation}
+%
+% This section presents the commented \LaTeX\ source code for the
+% \progname{wheretotrim} Perl script. Read this section if you want
+% to learn how the script is implemented.
+%
+% \iffalse
+%<*script>
+% \fi
+%
+% \DocInput{wheretotrim-pl.dtx}
+%
+% \iffalse
+%</script>
+% \fi
+%
+% \Finale
+\endinput
diff --git a/support/wheretotrim/wheretotrim.ins b/support/wheretotrim/wheretotrim.ins
new file mode 100644
index 0000000000..8181629029
--- /dev/null
+++ b/support/wheretotrim/wheretotrim.ins
@@ -0,0 +1,59 @@
+%%
+%% Copyright (C) 2013 by Scott Pakin <scott+wtt@pakin.org>
+%%
+%% This file may be distributed and/or modified under the conditions of
+%% the LaTeX Project Public License, either version 1.3c of this license
+%% or (at your option) any later version. The latest version of this
+%% license is in:
+%%
+%% http://www.latex-project.org/lppl.txt
+%%
+%% and version 1.3c or later is part of all distributions of LaTeX version
+%% 2008/05/04 or later.
+%%
+
+\input docstrip.tex
+\keepsilent
+
+\usedir{tex/latex/wheretotrim}
+
+\preamble
+
+This is a generated file.
+
+Copyright (C) 2013 by Scott Pakin <scott+wtt@pakin.org>
+
+This file may be distributed and/or modified under the conditions of
+the LaTeX Project Public License, either version 1.3c of this license
+or (at your option) any later version. The latest version of this
+license is in:
+
+ http://www.latex-project.org/lppl.txt
+
+and version 1.3c or later is part of all distributions of LaTeX
+version 2008/05/04 or later.
+
+\endpreamble
+
+\generate{\file{wheretotrim.sty}{\from{wheretotrim.dtx}{package}}}
+
+\nopreamble
+\nopostamble
+\generate{\file{wheretotrim.pl}{\from{wheretotrim-pl.dtx}{script}}}
+
+\obeyspaces
+\Msg{*************************************************************}
+\Msg{* *}
+\Msg{* To finish the installation, move wheretotrim.sty into a *}
+\Msg{* directory searched by TeX and wheretotrim.pl into a *}
+\Msg{* directory in your executable search path (and preferably *}
+\Msg{* rename the file from wheretotrim.pl to just wheretotrim). *}
+\Msg{* *}
+\Msg{* To produce the documentation run the file wheretotrim.dtx *}
+\Msg{* through LaTeX. *}
+\Msg{* *}
+\Msg{* Happy TeXing! *}
+\Msg{* *}
+\Msg{*************************************************************}
+
+\endbatchfile
diff --git a/support/wheretotrim/wheretotrim.pdf b/support/wheretotrim/wheretotrim.pdf
new file mode 100644
index 0000000000..eaf44c967c
--- /dev/null
+++ b/support/wheretotrim/wheretotrim.pdf
Binary files differ
diff --git a/support/wheretotrim/wheretotrim.sty b/support/wheretotrim/wheretotrim.sty
new file mode 100644
index 0000000000..b81ecc5815
--- /dev/null
+++ b/support/wheretotrim/wheretotrim.sty
@@ -0,0 +1,94 @@
+%%
+%% This is file `wheretotrim.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% wheretotrim.dtx (with options: `package')
+%%
+%% This is a generated file.
+%%
+%% Copyright (C) 2013 by Scott Pakin <scott+wtt@pakin.org>
+%%
+%% This file may be distributed and/or modified under the conditions of
+%% the LaTeX Project Public License, either version 1.3c of this license
+%% or (at your option) any later version. The latest version of this
+%% license is in:
+%%
+%% http://www.latex-project.org/lppl.txt
+%%
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2008/05/04 or later.
+%%
+\NeedsTeXFormat{LaTeX2e}[1999/12/01]
+\ProvidesPackage{wheretotrim}
+ [2013/05/15 v1.0 Helper package for the wheretotrim script]
+\newcommand{\wtt@target@column}{0}
+\newcommand{\wtt@column@expand}{0pt}
+\newcommand{\wtt@extra@full@columns}{0}
+\RequirePackage{keyval}
+\define@key{wtt}{column}{\gdef\wtt@target@column{#1}}
+\define@key{wtt}{expansion}{%
+ \xdef\wtt@column@expand{#1\noexpand\baselineskip}%
+}
+\define@key{wtt}{extracols}{\gdef\wtt@extra@full@columns{#1}}
+\DeclareOption*{%
+ \edef\next{\noexpand\setkeys{wtt}{\CurrentOption}}%
+ \next
+}
+\ProcessOptions\relax
+\newcounter{wtt@true@page}
+\setcounter{wtt@true@page}{1}
+\RequirePackage{everyshi}
+\EveryShipout{\addtocounter{wtt@true@page}{1}}
+\newcounter{wtt@column@num}
+\let\wtt@makecol=\@makecol
+\def\@makecol{%
+ \PackageInfo{wheretotrim}%
+ {Column \thewtt@column@num\space is on page
+ \thewtt@true@page\space (\thepage)}%
+ \addtocounter{wtt@column@num}{1}%
+ \ifnum\value{wtt@column@num}=\wtt@target@column
+ \enlargethispage{\wtt@column@expand}%
+ \fi
+ \wtt@makecol
+}
+\let\wtt@clearpage=\clearpage
+\gdef\clearpage{%
+ \wtt@clearpage
+ \ifnum\lastpenalty=-10001\relax
+ \addtocounter{wtt@column@num}{1}%
+ \ifnum\value{wtt@column@num}=\wtt@target@column
+ \enlargethispage{\wtt@column@expand}%
+ \fi
+ \addtocounter{wtt@column@num}{-1}%
+ \fi
+}
+\AtBeginDocument{%
+ \let\wtt@maketitle=\maketitle
+ \gdef\maketitle{%
+ \wtt@maketitle
+ \if@twocolumn
+ \ifnum\value{wtt@column@num}=\wtt@target@column
+ \enlargethispage{\wtt@column@expand}%
+ \fi
+ \fi
+ }%
+}
+\AtEndDocument{%
+ \ifnum\wtt@extra@full@columns>0\relax
+ \noindent\parbox[t][\textheight]{\linewidth}{%
+ \rule{\linewidth}{\baselineskip}}\par
+ \ifnum\wtt@extra@full@columns>1\relax
+ \noindent\parbox[t][\textheight]{\linewidth}{%
+ \rule{\linewidth}{\baselineskip}}\par
+ \fi
+ \fi
+ \PackageInfo{wheretotrim}%
+ {Baseline skip: \the\baselineskip}%
+ \PackageInfo{wheretotrim}%
+ {Text height: \the\textheight}%
+}
+\endinput
+%%
+%% End of file `wheretotrim.sty'.