Linux ip-172-26-7-228 5.4.0-1103-aws #111~18.04.1-Ubuntu SMP Tue May 23 20:04:10 UTC 2023 x86_64
Your IP : 18.191.91.15
#! /usr/bin/env perl
##########################################################
# Bundle all the files needed to build a LaTeX document. #
# By Scott Pakin <scott+bdoc@pakin.org> #
##########################################################
########################################################################
# bundledoc #
# Copyright (C) 2014 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.2"; # Specify the version of bundledoc.
use File::Basename;
use File::Copy;
use File::Spec::Functions qw(abs2rel 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: Linux + kpathsea
my %uservariable;
$uservariable{"bundle"} = '(tar -cvf - $BDINPUTS | gzip --best > $BDBASE.tar.gz)';
$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, @listdeps); # 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 $filename = $_[0];
$filename = "\"$filename\"" if $filename =~ /\s/ && substr($filename, 0, 1) ne '"';
my $command = $uservariable{find};
$command =~ s/[\$\%]BDINPUTS\%?/$filename/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;
# If --listdeps was specified, output the list of dependencies.
if (@listdeps) {
@dependencies = map {abs2rel($_)} @dependencies if grep /^rel$/, @listdeps;
print join("\n", @dependencies), "\n";
exit 0 if grep /^only$/, @listdeps;
}
# 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,
'listdeps=s' => \@listdeps,
'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}\"";
# Expand and sanity check @listdeps.
@listdeps = map {s/\s+//g; split /,/} @listdeps;
foreach my $ldep (@listdeps) {
if ($ldep !~ /^(rel|only|yes|no)$/) {
pod2usage (-message => "${progname}: Invalid --listdeps option \"$ldep\"",
-exitval => 1,
-verbose => 0);
}
}
@listdeps = () if grep /^no$/, @listdeps;
# 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<listdeps>=[yes|no|only|rel]...]
[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
of 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<--listdeps>=[yes|no|only|rel]...] (default: C<no>)
C<--listdeps> accepts one or more of C<yes>, C<no>, C<only>, or C<rel>
as a comma-separated list. As long as C<no> does not appear in this
list, B<bundledoc> outputs all of the main LaTeX file's dependencies.
If the list contains C<rel>, then B<bundledoc> outputs the list of
dependencies with relative pathnames. If the list contains C<only>,
then B<bundledoc> exits after displaying the list, without producing
an archive.
=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 now has B<bundledoc> use B<kpsewhich> to find LaTeX
files; older version of MikTeX required the rather nonstandard
B<initexmf> for this purpose.
=item F<texlive-unix-arlatex.cfg>
This is a variant of F<texlive-unix.cfg> that uses B<arlatex> instead
of B<gzip> to archive files. B<arlatex> is a script included in the
B<bundledoc> distribution that generates a self-extracting F<.tex>
file based on LaTeX's C<filecontents> environment.
=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 Z<OS X>) 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
arlatex(1), gzip(1), kpsewhich(1), latex(1), perl(1), zip(1),
the B<snapshot> documentation
=head1 AUTHOR
Scott Pakin, I<scott+bdoc@pakin.org>
|