diff options
author | Karl Berry <karl@freefriends.org> | 2010-04-10 22:08:00 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2010-04-10 22:08:00 +0000 |
commit | 963b665a04c33ddcfe04234426c8bca1942589bf (patch) | |
tree | 2416c1045ecd8aaa916a512cf7a05cd4055661f9 /Build/source/texk | |
parent | 5406b8e0ea1d596600f773e766975256e4087c51 (diff) |
add bundledoc 3.0 (10apr10)
git-svn-id: svn://tug.org/texlive/trunk@17794 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk')
5 files changed, 1097 insertions, 0 deletions
diff --git a/Build/source/texk/texlive/linked_scripts/ChangeLog b/Build/source/texk/texlive/linked_scripts/ChangeLog index 474c3984104..c4df6388162 100644 --- a/Build/source/texk/texlive/linked_scripts/ChangeLog +++ b/Build/source/texk/texlive/linked_scripts/ChangeLog @@ -1,3 +1,7 @@ +2010-04-11 Karl Berry <karl@tug.org> + + * Makefile.am (nobase_dist_scriptx_SCRIPTS): add bundledoc. + 2010-03-09 Karl Berry <karl@tug.org> * Makefile.am (nobase_dist_script_SCRIPTS): add de-macro. diff --git a/Build/source/texk/texlive/linked_scripts/Makefile.am b/Build/source/texk/texlive/linked_scripts/Makefile.am index 0d18474b808..90cfb6353a9 100644 --- a/Build/source/texk/texlive/linked_scripts/Makefile.am +++ b/Build/source/texk/texlive/linked_scripts/Makefile.am @@ -16,6 +16,8 @@ bin_SCRIPTS = scriptxdir = ${prefix}/texmf/scripts nobase_dist_scriptx_SCRIPTS = \ a2ping/a2ping.pl \ + bundledoc/arlatex \ + bundledoc/bundledoc \ simpdftex/simpdftex \ tetex/e2pall.pl \ tetex/texdoctk.pl \ diff --git a/Build/source/texk/texlive/linked_scripts/Makefile.in b/Build/source/texk/texlive/linked_scripts/Makefile.in index 2f3784d6392..397528c4e04 100644 --- a/Build/source/texk/texlive/linked_scripts/Makefile.in +++ b/Build/source/texk/texlive/linked_scripts/Makefile.in @@ -165,6 +165,8 @@ bin_SCRIPTS = scriptxdir = ${prefix}/texmf/scripts nobase_dist_scriptx_SCRIPTS = \ a2ping/a2ping.pl \ + bundledoc/arlatex \ + bundledoc/bundledoc \ simpdftex/simpdftex \ tetex/e2pall.pl \ tetex/texdoctk.pl \ diff --git a/Build/source/texk/texlive/linked_scripts/bundledoc/arlatex b/Build/source/texk/texlive/linked_scripts/bundledoc/arlatex new file mode 100755 index 00000000000..3b94dcaff52 --- /dev/null +++ b/Build/source/texk/texlive/linked_scripts/bundledoc/arlatex @@ -0,0 +1,283 @@ +#! /usr/bin/env perl + +################################################### +# Combine a bunch of ancillary files into a LaTeX # +# document using the filecontents* environment. # +# # +# By Scott Pakin <scott+bdoc@pakin.org> # +################################################### + +######################################################################## +# arlatex # +# Copyright (C) 2010 Scott Pakin # +# # +# This program 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. # +# # +# This program consists of the file bundledoc and all the files listed # +# in the Files section of the associated README file. # +######################################################################## + +use 5.006; # Fail gracefully if we're not using Perl v5.6.0. +our $VERSION = "1.02"; # Specify the version of arlatex. +use Getopt::Long; +use Pod::Usage; +use File::Basename; +use File::Find; +require File::Spec; +use strict; + +my $progname = basename($0); # Name of this program +my $latexfile; # Main LaTeX document +my $outfile = "-"; # Output file (default is standard output) + +###################################################################### + +# Include a file using the filecontents* environment. +sub includefile ($) +{ + my $filename = $_[0]; + my $basefilename = basename $filename; + open (SOMEFILE, "<$filename") || die "${progname}: $! ($filename)\n"; + print OUTFILE "\\begin{filecontents*}{$basefilename}\n"; + print OUTFILE <SOMEFILE>; + print OUTFILE "\\end{filecontents*}\n"; + close SOMEFILE; +} + +###################################################################### + +# Parse the command line. +GetOptions ('version' => sub { print "arlatex $VERSION\n"; exit -1 }, + 'help'=> sub {pod2usage (-exitval => 0, -verbose => 1)}, + 'document=s' => \$latexfile, + 'outfile=s' => \$outfile) || + pod2usage (-exitval => -1, -verbose => 0); +pod2usage (-exitval => -1, -verbose => 0) if !defined $latexfile; +if (!-e $latexfile) { + my $newlatexfile = "$latexfile.tex"; + if (!-e $newlatexfile) { + die "${progname}: File $latexfile does not exist\n"; + } + else { + $latexfile = $newlatexfile; + } +} + +# Read the entire input file. +open (LATEXFILE, "<$latexfile") || die "${progname}: $! ($latexfile)\n"; +my @entirefile = <LATEXFILE>; +close LATEXFILE; + +# Open the output file, write any initial comments, and then include +# all of the files specified on the command line using the filecontents* +# environment. Finally, include the rest of the input file. +open (OUTFILE, ">$outfile") || die "${progname}: $! ($outfile)\n"; +while ($entirefile[0] =~ /^\s*(\%.*)?$/) { + print OUTFILE (shift @entirefile); +} +my @expandedARGV; +foreach my $filename (@ARGV) { + if (-f $filename) { + push @expandedARGV, $filename; + } + else { + find ({wanted => sub {push @expandedARGV, File::Spec->rel2abs($_) if -f $_}, + follow => 1}, + $filename); + } +} +foreach my $filename (@expandedARGV) { + includefile ($filename); + print OUTFILE "\n"; +} +print OUTFILE @entirefile; +close OUTFILE; +exit 0; + +###################################################################### + +=head1 NAME + +arlatex - archive a number of ancillary LaTeX files into a master +F<.tex> file + + +=head1 SYNOPSIS + +arlatex +[B<--outfile>=I<filename>F<.tex>] +B<--document>=I<filename>F<.tex> +I<filename> +... + +arlatex +B<--version> + +arlatex +B<--help> + + +=head1 DESCRIPTION + +B<arlatex> is an archiving program like B<shar>, B<tar>, B<zip>, etc. +Unlike those other archivers, however, B<arlatex> is designed +specifically for use with LaTeX. B<arlatex> takes the name of a +master F<.tex> file and a number of ancillary files used by that +master file (e.g., F<.tex>, F<.sty>, F<.cls>, and F<.eps> files). +From these, B<arlatex> outputs a single file that, when it's run +through B<latex>, both regenerates the ancillary files and compiles +the document into a F<.dvi> file. + +B<arlatex> has a few advantages over other archiving programs: + +=over 4 + +=item * + +The F<.tex> files produced by B<arlatex> are in a plain-text format. +They are therefore perfectly portable and trivial to e-mail to +colleagues. + +=item * + +B<arlatex> needs only LaTeX to run. There is no dependence on any +external tools. + +=item * + +There is no explicit extraction step. As the generated document is +run through B<latex>, it extracts the ancillary files and builds the +document in the same step. The user running B<latex> may not even +notice that additional files are being produced. + +=back + +B<arlatex> works by writing a number of S<C<\begin{filecontents*}> ...> +C<\end{filecontents*}> blocks to the output file, followed by the +contents of the master file. (In fact, any LaTeX comments at the +beginning of the master file are hoisted to the top of the generated +file. This enables the author to draw attention, if so desired, to +the fact that ancillary files will be generated.) The +C<filecontents*> environment, part of standard LaTeX2e, writes its +contents verbatim to a specified file. + + +=head1 OPTIONS + +=over 4 + +=item B<--version> + +Output the B<arlatex> script's version number. + +=item B<--help> + +Output brief B<arlatex> usage information. + +=item B<--document>=I<.tex file> + +Specify the master document. The output from B<arlatex> is this file +with all of the other files named on the command line prepended to it. +Note that C<--document> is a I<mandatory> parameter; B<arlatex> will +abort with an error message if C<--document> is not specified. + +=item B<--outfile>=I<.tex file> + +Specify the output file. The output file looks just like the master +document, but with a number of C<filecontents*> environments preceding +the C<\documentclass> line. If C<--outfile> is not specified, output +will be written to the standard output device. + +=back + + +=head1 EXAMPLES + +Suppose you have a paper called F<paper.tex> that loads a custom +package with C<\usepackage{mypackage}>. You want to submit the paper +to a conference, but you want to be absolutely certain that +F<mypackage.sty> doesn't get lost as your paper is shuttled from +person to person. Here's how B<arlatex> can be of use: + + arlatex --document=paper.tex mypackage.sty --outfile=paper-submit.tex + +When F<paper-submit.tex> is processed with B<latex>, it builds just +like the original F<paper.tex>, except that it additionally creates a +F<mypackage.sty> in the current directory: + + This is TeX, Version 3.14159 (Web2C 7.3.1) + (paper-submit.tex + LaTeX2e <1999/12/01> patch level 1 + Babel <v3.6Z> and hyphenation patterns for american, french, german, + ngerman, italian, nohyphenation, loaded. + + LaTeX Warning: Writing file `./mypackage.sty'. + + (/usr/share/texmf/tex/latex/base/article.cls + Document Class: article 1999/09/10 v1.4a Standard LaTeX document class + (/usr/share/texmf/tex/latex/base/size12.clo)) (mypackage.sty) + . + . + . + +As another example, here's how you could bundle together all of the +files needed to build a large document for longevity: + + arlatex --document=thesis.tex abstract.tex introduction.tex + background.tex approach.tex experiments.tex relatedwork.tex + conclusions.tex before.eps after.eps fast.eps slow.eps + podunkUthesis.cls --outfile=thesis-all.tex + +As the number of files to archive together increases it becomes more +cumbersome to run B<arlatex> manually. Fortunately, using B<arlatex> +with B<bundledoc> is straightforward. B<bundledoc> finds all of the +files needed to build the document, and B<arlatex> combines them into +a single file. The following are examples of the C<bundle:> line you +might use in a B<bundledoc> configuration file: + +=over 1 + +=item Unix: + + bundle: (arlatex --document=$BDBASE.tex $BDINPUTS \ + --outfile=$BDBASE-all.tex) + +=item Windows: + + bundle: arlatex --document=%BDBASE%.tex %BDINPUTS% \ + --outfile=%BDBASE%-all.tex + +=back + +See the B<bundledoc> documentation for more information. + + +=head1 CAVEATS + +B<arlatex> makes use of LaTeX2e's C<filecontents*> environment. +C<filecontents*> refuses to overwrite an existing file. However, it +also refuses to create a file that exists I<anywhere> that LaTeX can +find it. That is, if the user running B<latex> on an +B<arlatex>-generated F<.tex> file already has a +F</usr/share/texmf/tex/latex/whatever/whatever.sty> file then +C<filecontents*> will refuse to create a F<whatever.sty> file, even in +a different directory. + + +=head1 SEE ALSO + +bundledoc(1), latex(1), shar(1), tar(1), zip(1) + + +=head1 AUTHOR + +Scott Pakin, I<scott+bdoc@pakin.org> diff --git a/Build/source/texk/texlive/linked_scripts/bundledoc/bundledoc b/Build/source/texk/texlive/linked_scripts/bundledoc/bundledoc new file mode 100755 index 00000000000..169ca869ab3 --- /dev/null +++ b/Build/source/texk/texlive/linked_scripts/bundledoc/bundledoc @@ -0,0 +1,806 @@ +#! /usr/bin/env perl + +########################################################## +# Bundle all the files needed to build a LaTeX document. # +# By Scott Pakin <scott+bdoc@pakin.org> # +########################################################## + +######################################################################## +# bundledoc # +# Copyright (C) 2010 Scott Pakin # +# # +# This program 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. # +# # +# This program consists of the file bundledoc and all the files listed # +# in the Files section of the associated README file. # +######################################################################## + +use 5.006; # Fail gracefully if we're not using Perl v5.6.0. +our $VERSION = "3.0"; # Specify the version of bundledoc. +use File::Basename; +use File::Copy; +use File::Spec::Functions qw(catfile devnull rel2abs rootdir updir); +use File::Path; +use Getopt::Long; +use Pod::Usage; +use POSIX; +use warnings; +use strict; + +###################################################################### + +# Variables the user can override with a configuration file +# DEFAULTS: Unix + kpathsea +my %uservariable; +$uservariable{"bundle"} = '(tar -cvf - $BDINPUTS | compress > $BDBASE.tar.Z)'; +$uservariable{"find"} = 'kpsewhich -progname=latex $BDINPUTS'; +$uservariable{"sink"} = '> ' . devnull() . ' 2>&1'; + +# OS path separator (Is there a better way to get this?) +my $pathsep = catfile ("", ""); + +# File that lists original directory names +my $manifest = "MANIFEST"; + +# Cleaned-up name of this Perl script +my $progname = basename($0); + +# Other global variables +my ($verbose, $keepdirs, $depfile, $localonly); # Taken from the command line +my (@exclude_files, @include_files); # Taken from the command line +my ($texfile, $docdirname); # Derived from $depfile +my %subdirs; # Map from a qualified name to its subdirectory + +###################################################################### + +# Find a file in the LaTeX hierarchy and fully qualify it, +# or abort if we can't. +sub qualifyname ($) +{ + my $command = $uservariable{find}; + $command =~ s/[\$\%]BDINPUTS\%?/$_[0]/g; + $command =~ s/[\$\%]BDBASE\%?/$ENV{"BDBASE"}/g; + my $qualified = `$command` || + die "${progname}: \"$uservariable{find}\" (BDINPUTS=\"$_[0]\") failed to find $_[0]\n"; + chomp $qualified; + $qualified = rel2abs $qualified; + return $qualified; +} + +# Execute a command, and return an error message if it fails. +sub executecmd ($) +{ + my $command = ($verbose ? $_[0] : "$_[0] $uservariable{sink}"); + $command =~ s/[\$\%]BDINPUTS\%?/$ENV{"BDINPUTS"}/g; + $command =~ s/[\$\%]BDBASE\%?/$ENV{"BDBASE"}/g; + my $retval; + + if ($verbose) { + print "EXECUTING: $command\n"; + print " (BDINPUTS = $ENV{BDINPUTS})\n"; + } + if ($pathsep eq "\\") { + # Dirty trick to work around idiotic "\" --> "/" conversion + $retval = system qq("$command"); + } + else { + $retval = system $command; + } + die "${progname}: $!. Failing command was:\n\t$command\n" if $retval; +} + +# Read a configuration file, and set %uservariable accordingly. +sub process_config_file ($) +{ + my $configfile = $_[0]; + my $prevline = ""; + open (CONFIGFILE, "<$configfile") || die "${progname}: $! ($configfile)\n"; + while (my $oneline=<CONFIGFILE>) { + # Read a line and trim it. + chomp $oneline; + $oneline =~ s/^\s+//; + $oneline =~ s/\s+$//; + + # Determine if we should process the line now, later, or never. + next if $oneline =~ /^\#.*$/; # Discard comments. + if ($oneline =~ m|^(.*)\\$|) { # Handle line continuations. + $prevline .= $1; + next; + } + $oneline = $prevline . $oneline; + $prevline = ""; + next if $oneline =~ /^\s*$/; # Discard blank lines. + + # Parse the line. + $oneline =~ /^(\w+)\s*:\s*(.*)$/; + $uservariable{lc($1)} = $2; + } + close CONFIGFILE; +} + +# Find all dependencies listed in the input file. +sub find_dependencies () +{ + open (DEPFILE, "<$depfile") || die "${progname}: $! ($depfile)\n"; + my $braced = "{([^\}]*)}"; # Regular expression for a braced name + my @dependencies; # List of fully-qualified filenames + @dependencies = qualifyname $texfile; + while (my $oneline=<DEPFILE>) { + # Parse an input line into its component fields. + next if !($oneline =~ /^\s*\*$braced\s*$braced\s*$braced\s*$/); + my $filetype = $1; + my $filename = $2; + my $versioninfo = $3; + + # Extract the subdirectory if one exists. + my $subdir = dirname $filename; + my $qname = ""; + + # Determine what to do based on the file type. + # NOTE: The PROCESSDEP block currently ignores the following + # file types: + # + # * application + # * tfm + # * format + PROCESSDEP: + { + $filetype eq "package" && do { + $qname = qualifyname("$filename.sty"); + last PROCESSDEP; + }; + $filetype eq "class" && do { + $qname = qualifyname("$filename.cls"); + last PROCESSDEP; + }; + $filetype eq "file" && do { + $qname = qualifyname("$filename"); + last PROCESSDEP; + }; + } + + # If the file is of one of the above types, add the qualified + # name to the list of dependencies. In addition, if it is in + # a proper subdirectory, add an entry to the subdirs hash. + unless ($qname eq "") { + push @dependencies, $qname; + $subdirs{$qname} = $subdir unless $subdir eq "."; + } + } + close DEPFILE; + @dependencies = sort @dependencies; + + # If --localonly was specified, discard dependencies that are not + # in the same directory as the .tex file (or a subdirectory + # thereof). + if ($localonly) { + my @newdeps; + my $texdir = dirname qualifyname $texfile; + my $lentexdir = length $texdir; + my $numdeleted = 0; + foreach my $dep (@dependencies) { + if (substr($dep, 0, $lentexdir) ne $texdir) { + $numdeleted++; + } + else { + push @newdeps, $dep; + } + } + @dependencies = @newdeps; + print "OMITTING $numdeleted non-local file(s)\n" if $verbose; + } + + # If --exclude was specified, discard all dependencies containing + # excluded text as a substring. + my $numexcluded = 0; + foreach my $excluded (@exclude_files) { + my @newdeps; + foreach my $dep (@dependencies) { + if ($dep =~ /\Q$excluded\E/) { + $numexcluded++; + } + else { + push @newdeps, $dep; + } + } + @dependencies = @newdeps; + } + print "OMITTING $numexcluded excluded file(s)\n" if $verbose && $numexcluded; + + # If --include was specified, include the corresponding files. + my $numextras = 0; + foreach my $include_glob (@include_files) { + foreach my $include_file (glob $include_glob) { + push @dependencies, $include_file; + $numextras++; + } + } + print "INCLUDING $numextras additional file(s)\n" if $verbose && $numextras; + + # Remove duplicates. + my %uniquedeps; + foreach my $dep (@dependencies) { + $uniquedeps{$dep} = 1; + } + my $numdups = @dependencies - keys %uniquedeps; + print "REMOVING $numdups duplicate file(s)\n" if $verbose && $numdups; + @dependencies = sort keys %uniquedeps; + + # Return the list of dependencies. + return @dependencies; +} + +###################################################################### + +# Parse and process the command-line options. +my $showhelp = ""; +$keepdirs = 0; +$verbose = 0; +$localonly = 0; +GetOptions ('texfile=s' => \$texfile, + 'directory=s' => \$docdirname, + 'manifest:s' => \$manifest, + 'keepdirs!' => \$keepdirs, + 'localonly!' => \$localonly, + 'exclude=s' => \@exclude_files, + 'include=s' => \@include_files, + 'config=s' => sub { process_config_file($_[1]) }, + 'verbose!' => \$verbose, + 'version' => sub { print "bundledoc $VERSION\n"; exit -1 }, + 'help' => \$showhelp) || pod2usage (-exitval => -1, -verbose => 0); +pod2usage (-exitval => 0, + -verbose => 1) if $showhelp && $verbose; +pod2usage (-message => "(For more detailed help, enter \"$0 --help --verbose\".)", + -exitval => 0, + -verbose => 0) if $showhelp; +pod2usage (-message => "${progname}: Too few arguments", + -exitval => -1, + -verbose => 0) if $#ARGV==-1; +$depfile = shift; # Dependencies from snapshot.sty +($texfile = $depfile) =~ s/\.[^.]*$/.tex/ if !$texfile; # Main LaTeX source file +($docdirname = basename($depfile)) =~ s/\.[^.]*$// if !$docdirname; # Name to use for the document directory +($ENV{"BDBASE"} = rel2abs($depfile)) =~ s/\.[^.]*$//; # May be needed by user-defined variables +print "BDBASE = '$ENV{BDBASE}'\n" if $verbose; +$ENV{"BDBASE"} = "\"$ENV{BDBASE}\""; + +# Create a bundled file. +my @dependencies = find_dependencies(); +if ($keepdirs) { + # Put absolute pathnames in the tar file. + # QUESTIONS: Does this work with multiple drive letters in Windows? + # What about UNC names? + chdir rootdir() || die "${progname}: $! (".rootdir().")\n"; + $ENV{"BDINPUTS"} = join (" ", map {s|^/+||; s/\"//g; "\"$_\""} @dependencies); + executecmd $uservariable{"bundle"}; +} +else { + # Copy each of the dependencies to a temporary directory and tar it up. + my $tempdir = tmpnam(); + my $tempdir2 = catfile $tempdir, $docdirname; + print "CREATING $tempdir\n" if $verbose; + mkdir ($tempdir, 0777) || die "${progname}: $! ($tempdir)\n"; + print "CREATING $tempdir2\n" if $verbose; + mkdir ($tempdir2, 0777) || die "${progname}: $! ($tempdir2)\n"; + foreach my $dep (@dependencies) { + # If the current dependency is in a subdirectory of the + # original location, create the same subdirectory in the + # temporary directory and copy the file there. Otherwise just + # copy it to the root of the temporary directory. + my $targetdir = $tempdir2; + if (my $sd = $subdirs{$dep}) { + $targetdir = catfile($targetdir, $sd); + unless (-d $targetdir) { + print "CREATING $targetdir\n" if $verbose; + mkpath($targetdir, 0, 0777) || die "${progname}: $! ($targetdir)\n"; + } + } + copy ($dep, $targetdir) || die "${progname}: $! ($targetdir)\n"; + } + if ($manifest ne "") { + my $manifest = catfile $tempdir2, $manifest; + my $manifestdir = dirname $manifest; + unless (-d $manifestdir) { + print "CREATING $manifestdir\n" if $verbose; + mkpath($manifestdir, 0, 0777) || die "${progname}: $! ($manifestdir)\n"; + } + print "WRITING $manifest\n" if $verbose; + open (MANIFEST, ">$manifest") || die "${progname}: $! ($manifest)\n"; + print MANIFEST join ("\n", @dependencies), "\n"; + close MANIFEST; + } + chdir $tempdir || die "${progname}: $! ($tempdir)\n"; + $ENV{"BDINPUTS"} = "\"$docdirname\""; + executecmd $uservariable{"bundle"}; + + # Clean up our mess. + # NOTE: We rmtree $tempdir2 and rmdir $tempdir because rmtree + # complained on WinNT when trying to remove a top-level + # directory (e.g., "\s4r."). + print "REMOVING $tempdir2\n" if $verbose; + rmtree $tempdir2, 0, 1; + chdir (updir()); + print "REMOVING $tempdir\n" if $verbose; + rmdir $tempdir || die "${progname}: $! ($tempdir)\n"; +} +print "FINISHED.\n" if $verbose; +exit 0; + +__END__ + +###################################################################### + +=head1 NAME + +bundledoc - bundle all the files needed by a LaTeX document + + +=head1 SYNOPSIS + +bundledoc +[B<--version>] +[B<--help>] +[B<-->[B<no>]B<verbose>] +[B<--texfile>=I<file>] +[B<--directory>=I<directory>] +[B<-->[B<no>]B<localonly>] +[B<--exclude>=I<string>] +[B<--include>=I<filespec>] +[B<--manifest>=I<file>] +[B<-->[B<no>]B<keepdirs>] +[B<--config>=I<file>] +I<.dep file> + + +=head1 DESCRIPTION + +B<bundledoc> is a post-processor for the B<snapshot> package that +bundles together all the classes, packages, and files needed to build +a given LaTeX document. It reads the F<.dep> file that B<snapshot> +produces, finds each of the files mentioned therein, and packages them +into a single archive file (e.g., a F<.tar.gz> file), suitable for +moving across systems, transmitting to a colleague, etc. + +As the simplest example possible, consider a LaTeX file called, say, +F<hello.tex>: + + \RequirePackage{snapshot} % Needed by bundledoc + \documentclass[11pt]{article} + + \begin{document} + Hello, world! + \end{document} + +The C<\RequirePackage{snapshot}> causes a F<hello.dep> file to be produced. +When B<bundledoc> is then given C<hello.dep> as an argument, it locates the +dependent files -- F<snapshot.sty>, F<article.cls>, and F<size11.clo> -- +and bundles them into a single archive file, along with F<hello.tex> and a +F<MANIFEST> file (described in L<"OPTIONS">, below). + + +=head1 OPTIONS + +In the following descriptions, I<somefile> refers to the name of your +main LaTeX document (no extension). + +B<bundledoc> requires the name of the dependency file produced by +B<snapshot> (normally I<somefile>F<.dep>). The following options may +also be given: + +=over 4 + +=item B<--version> + +Output the B<bundledoc> script's version number. This overrides all the +remaining options. + +=item B<--help> + +Give a brief usage message. This overrides all of the remaining options. + +=item B<-->[B<no>]B<verbose> (default: C<noverbose>) + +B<bundledoc> normally does not output anything except error messages. +With C<--verbose>, it outputs copious status messages. + + +=item B<--texfile>=I<main .tex file> (default: I<somefile>F<.tex>) + +B<snapshot>'s dependency file does not list the main LaTeX file (the +one that gets passed to B<latex>). In order for B<bundledoc> to find +and bundle that file, B<bundledoc> assumes it has the same name as the +B<snapshot> dependency file but with a F<.tex> extension. If this is +not the case, then use C<--texfile> to specify the correct filename. + +=item B<--directory>=I<archive directory> (default: I<somefile>) + +When B<bundledoc> creates an archive (e.g., a F<.tar> or F<.zip> file) +containing the document's files, it puts all of them in a directory to +avoid cluttering the current directory with files. If the given +dependency file is called I<somefile>F<.dep> then the resulting +archive will, by default, store all the dependent files in a +I<somefile> directory. To change the directory name use the +C<--directory> option. + +=item B<-->[B<no>]B<localonly> (default: C<nolocalonly>) + +Although B<bundledoc> normally archives all of the files named in the +F<.dep> file, the C<--localonly> option tells B<bundledoc> to exclude +all files located in a directory other than the F<.tex> file's +directory or one of its subdirectories. + +=item B<--exclude>=I<string> (default: I<none>) + +While C<--localonly> causes files outside of the F<.tex> file's +directory tree to be omitted from the archive, C<--exclude> provides +finer-grained control over files to omit from the archive. The +C<--exclude> option, which can be specified repeatedly on the command +line, causes all files whose name contains I<string> to be omitted +from the archive. + +=item B<--include>=I<filespec> (default: I<none>) + +The C<--include> option, which can be specified repeatedly on the +command line, instructs B<bundledoc> to include in the archive all of +the files matching I<filespec>, even if they're not referenced in the +F<.dep> file. + +=item B<--manifest>=I<manifest file> (default: F<MANIFEST>) + +In addition to the dependent files, B<bundledoc> includes in the +archive file one extra file called, by default, ``F<MANIFEST>''. +F<MANIFEST> is a text file that lists the original filenames of all +the dependencies. To change the filename from ``F<MANIFEST>'' to +something else, use the C<--manifest> option. As a special case, +C<--manifest=""> tells B<bundledoc> not to include a manifest file at +all. + +=item B<-->[B<no>]B<keepdirs> (default: C<nokeepdirs>) + +Normally, the archive file that B<bundledoc> produces contains a +single directory -- and subdirectories, if the document refers +explicitly to them -- in which all the dependent files lie. If +C<--keepdirs> is specified, all the dependent files are stored with +their original pathnames. For example, if F<somefile.tex> depends on +F<figures/somefigure.eps>, F<article.cls>, and F<snapshot.sty>, then +the I<somefile> archive will normally contain the following files: + +=over 4 + +=item * + +F<somefile/somefile.tex> + +=item * + +F<somefile/figures/somefigure.eps> + +=item * + +F<somefile/article.cls> + +=item * + +F<somefile/snapshot.sty> + +=item * + +F<somefile/MANIFEST> + +=back + +However, C<--keepdirs> will cause the I<somefile> archive to contain +the following sorts of filenames instead: + +=over 4 + +=item * + +F<home/me/mydocs/somefile.tex> + +=item * + +F<home/me/mydocs/figures/somefigure.eps> + +=item * + +F<usr/share/texmf/tex/latex/base/article.cls> + +=item * + +F<usr/share/texmf/tex/latex/snapshot/snapshot.sty> + +=back + +C<--directory> is not used when C<--keepdirs> is in effect. In +addition, no manifest file is written to the archive file as it +contains redundant information. + +=item B<--config>=I<configuration file> (default: E<lt>noneE<gt>) + +The C<--config> option is used to point B<bundledoc> to the +appropriate configuration (F<.cfg>) file for your TeX distribution and +operating system. B<bundledoc> comes with a few configuration files +and it's easy to write more. See L<"CONFIGURATION FILES"> (below) for +a description of the configuration file format. + +=back + + +=head1 CONFIGURATION FILES + +=head2 Format + +Configuration files follow a fairly simple format. Lines beginning with +C<#> are comments. Blank lines are ignored. All other lines are of the +form: + + variable: value + +The current version of B<bundledoc> recognizes the following variables: + +=over 4 + +=item B<bundle> + +The command to use to bundle a set of files into a single archive file + +=item B<sink> + +The affix to a command to discard its output + +=item B<find> + +The command to find a file within the TeX tree(s). + +=back + +Values that are too long for one line can be split across multiple lines +by using C<\> as the line-continuation symbol. + +There are two environment variables that B<bundledoc> makes available +for use by configuration-file commands: C<BDBASE>, which is set to +I<somefile> (as in L<"OPTIONS">), and C<BDINPUTS>, which is set to a +space-separated list of files that a command is to operate upon. That +is, when the command associated with C<bundle> is running, C<BDINPUTS> +contains the list of all the files that are to be archived. In +contrast, when the command associated with C<find> is running, +C<BDINPUTS> contains the name of the file to search for. + +=head2 Examples + +The following configuration file parallels B<bundledoc>'s default +values of the various configuration-file variables, which represents a +kpathsea-based TeX distribution running on a generic Unix system, +which doesn't necessarily have any of the GNU tools, such as B<gzip> +or GNU B<tar>: + + # "Default" configuration file + # By Scott Pakin <scott+bdoc@pakin.org> + + bundle: (tar -cvf - $BDINPUTS | compress > $BDBASE.tar.Z) + sink: > /dev/null 2>&1 + find: kpsewhich -progname=latex $BDINPUTS + +The parentheses in the C<bundle:> line tell the Unix shell to run the +command in a subshell. This is to make the C<sink:> affix work +properly (i.e., so there aren't two C<E<gt>>'s in the same command). + +Notice how the commands treat C<BDBASE> and C<BDINPUTS> like any other +environment variables in a Unix shell, using C<$> to take their value. +Other operating systems use different conventions for referring to +environment variables. For instance, a configuration file for a +Windows-based TeX distribution would use C<%BDBASE%> and C<%BDINPUTS%> +instead. + +The value for C<sink:> is specific to an operating system. The value +for C<find:> is specific to a TeX distribution. C<bundle:> is where +the most opportunity for customization lies. You can use C<bundle:> +to specify your favorite archive format. For example, you can produce +a shar file on Unix with something like: + + bundle: (shar --archive-name="$BDBASE" $BDINPUTS > $BDBASE.sh) + +or a CAB file on Microsoft Windows with something like: + + bundle: cabarc -r -p N %BDBASE%.cab %BDINPUTS% + + +=head1 EXAMPLES + +Assume that F<myfile.dep> was produced from F<myfile.tex> by following +the instructions in L<the Description section|/"DESCRIPTION">. The +following command produces a F<.zip> file with the MikTeX TeX +distribution running on Microsoft Windows: + + bundledoc --config=miktex.cfg myfile.dep + +(In practice, it's probably necessary to specify to C<--config> the +complete path to B<bundledoc>'s F<miktex.cfg> configuration file.) + +The following builds a F<.tar.gz> archive with the TeX Live +distribution running on a Unix-like operating system. B<bundledoc> +will produce verbose output describing its operations. All files not +in the same directory tree as F<myfile.tex> and all files containing +".fd" or ".sty" in their names are omitted. However, all F<.bib> +files in the current directory will be included in the archive even +though none of them are referenced by F<myfile.dep>. Finally, no +F<MANIFEST> file will be produced. + + bundledoc --config=texlive-unix.cfg --verbose --localonly \ + --exclude=.fd --exclude=.cfg --include="*.bib" --manifest="" \ + myfile.dep + + +=head1 FILES + +The user must have previously installed F<snapshot.sty> and used it to +produce a dependency file for his document. Besides that, the set of +external files needed by B<bundledoc> is system-specific and depends on the +configuration file used. (See L<"CONFIGURATION FILES">, above.) + +B<bundledoc> currently comes with two configuration files: + +=over 4 + +=item F<texlive-unix.cfg> + +Configuration file for TeX Live installations on Unix or Linux. TeX +Live is a kpathsea-based TeX distribution that runs on various flavors +of Unix and Microsoft Windows. F<texlive-unix.cfg> assumes you have +B<gzip> and uses it to produce a F<.tar.gz> archive file. The +configuration file has B<bundledoc> use B<kpsewhich> to find LaTeX +files. + +=item F<miktex.cfg> + +Configuration file for MikTeX installations. MikTeX is a popular TeX +distribution for Microsoft Windows. F<miktex.cfg> assumes you have +B<zip> and uses it to produce a F<.zip> archive file. The +configuration file has B<bundledoc> use the rather nonstandard +B<initexmf> to find LaTeX files. + +=back + + +=head1 NOTES + +=head2 Including and excluding files + +The C<--localonly>, C<--exclude>, and C<--include> options provide +control over the archive's contents. C<--exclude> and C<--include> +can be specified repeatedly on the command line. The order in which +these options are specified is immaterial; B<bundledoc> processes file +inclusions and exclusions in the following order: + +=over 4 + +=item 1. + +All files referenced by the F<.dep> file are added to the list of +files to archive. + +=item 2. + +If C<--localonly> is specified, all files not found in the F<.tex> +file's directory are removed from the list. + +=item 3. + +For each C<--exclude> string specified, all files containing that +string are removed from the list. + +=item 4. + +For each C<--include> file specification, the set of files designated +by its expansion are added to the list. + +=back + + +=head2 Issues When Running Under Microsoft Windows + +First, because B<bundledoc> is a Perl script, you should do one of the +following to run it under Windows: + +=over 4 + +=item * + +C<perl bundledoc> + +=item * + +Rename F<bundledoc> to F<bundledoc.pl> and run C<bundledoc.pl>. (This +is assuming you have a file association set up for F<.pl>.) + +=item * + +Run the B<pl2bat> script (if you have it) to convert F<bundledoc> to +F<bundledoc.bat>, then run C<bundledoc>. + +=back + +Second, Windows uses a multi-rooted filesystem (i.e., multiple drive +letters). I wouldn't be surprised if bad things were to happen if the +files to be bundled are scattered across drives. In addition, Windows +supports ``UNC'' filenames, which have no drive letter at all, just a +machine and share name. UNC filenames are also untested waters for +B<bundledoc>. Be careful! + + +=head2 Testing Status + +I have tested B<bundledoc> only with Perl v5.6.0 and later and only on +the following platforms: + +=over 4 + +=item * + +Linux + TeX Live + +=item * + +Linux + teTeX + +=item * + +Windows NT + MiKTeX + +=item * + +Solaris + ??? (something kpathsea-based) + +=back + +It is my hope that B<bundledoc> works on many more platforms than +those. I tried to make the program itself fairly independent of the +operating system; only the configuration files should have to change +to run B<bundledoc> on a different system. + +=head2 Future Work + +I'd like B<bundledoc> to work on as wide a variety of TeX +distributions as possible. If your platform is significantly +different from the ones listed in L<"Testing Status"> (e.g., if you're +running MacOS) and you need to create a substantially different +configuration file from F<texlive-unix.cfg> and F<miktex.cfg>, please +send it to me at the address listed in L<"AUTHOR"> so I can include it +in a future version of B<bundledoc>. (I make no promises, though). + +Once B<bundledoc> works on all the major operating systems and TeX +distributions it would be really convenient if I could get +B<bundledoc> to detect the platform it's running on and automatically +select an appropriate configuration file. + +Finally, it would be handy for B<bundledoc> to include fonts in the +archive file. At a minimum, it should include F<.tfm> files, but it +would be even better if it included F<.mf>, F<.pfb>, F<.ttf>, and +other common font formats, as well. + +=head2 Acknowledgments + +Thanks to Fabien Vignes-Tourneret for suggesting what became the +C<--localonly> option and for a discussion that led to the +C<--exclude> and C<--include> options; and to Marius Kleiner for +updating B<bundledoc> to properly handle document subdirectories. + + +=head1 SEE ALSO + +gzip(1), kpsewhich(1), latex(1), perl(1), zip(1), the B<snapshot> +documentation + + +=head1 AUTHOR + +Scott Pakin, I<scott+bdoc@pakin.org> |