我遇到过由于宏包不够新导致的latex编译失败。那么有没有办法将我们编译当前文档需要的宏包打包呢?
办法就是使用bundledoc
. 我用的texlive2017(脚本位置:E:\texlive\2016\texmf-dist\scripts\bundledoc\bundledoc
), 看起来这个宏包有点旧了, 需要修复下。
脚本的修复
P.S. 最新版的bundledoc(2018/05/23, Version 3.3)一下两个问题都已经修复。请直接更新。
首先它是一个perl脚本, 其中有个新建临时目录的函数tmpnam
已经弃用了, 这个好像不是非常影响。
# 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;
其次, 它的正则表达式{([^\}]*)}
不正确, 因为根据*.dep
的结构, 我们需要将其改成\\{([^}]*)\\}
.
# 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 = "";
如果我们只需要将2017年以后的宏包打包, 则可以将上述代码片段改为
# 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*\{((2017|2018)[^}]*)\}\s*$/); my $filetype = $1; my $filename = $2; my $versioninfo = $3; # Extract the subdirectory if one exists. my $subdir = dirname $filename; my $qname = "";
脚本的使用
新建test.tex
文档如下:
\RequirePackage{snapshot} Hello world!
这里的关键是需要第一行的\RequirePackage{snapshot}
产生宏包依赖列表test.dep
. 例如上面的代码产生的宏包依赖列表为:
\RequireVersions{ *{application}{TeX} {1990/03/25 v3.x} *{format} {LaTeX2e} {2017-04-15 v2.e} *{package}{snapshot} {2002/03/05 v1.14} *{class} {amsart} {2017/10/31 v2.20.4} *{package}{amsmath} {2017/09/02 v2.17a} *{package}{amstext} {2000/06/29 v2.01} *{package}{amsgen} {1999/11/30 v2.0} *{package}{amsbsy} {1999/11/29 v1.2d} *{package}{amsopn} {2016/03/08 v2.02} *{file} {umsa.fd} {2013/01/14 v3.01} *{package}{amsfonts} {2013/01/14 v3.01} *{file} {umsa.fd} {2013/01/14 v3.01} *{file} {umsb.fd} {2013/01/14 v3.01} }
接着, 我们需要在test.tex
同目录下创建bundledoc
配置文件bundledoc.cfg
# basic config file for use of arlatex + bundledoc bundle: (arlatex --document=$BDBASE.tex $BDINPUTS | tar -cvf - $BDINPUTS | gzip --best > $BDBASE-all.tar.gz ) sink: > /dev/null 2>&1 find: kpsewhich -progname=latex $BDINPUTS
最后, 如果你使用修改后的脚本的话, 运行
bundledoc --config=bundledoc.cfg --verbose test.dep
则得到打包后的压缩文件test-all.tar.gz
需要注意的是, 我们需要压缩文件的软件tar与gzip.
本作品采用创作共用版权协议, 要求署名、非商业用途和保持一致. 转载本站内容必须也遵循署名-非商业用途-保持一致的创作共用协议.