使用bundledoc打包LaTeX宏包依赖
我遇到过由于宏包不够新导致的latex编译失败。那么有没有办法将我们编译当前文档需要的宏包打包呢?
办法就是使用bundledoc
. 我用的texlive2017(脚本位置:E:\texlive\2016\texmf-dist\scripts\bundledoc\bundledoc
), 看起来这个宏包有点旧了, 需要修复下。
脚本的修复
P.S. 最新版的bundledoc(2018/05/23, Version 3.3)一下两个问题都已经修复。请直接更新。
首先它是一个perl脚本, 其中有个新建临时目录的函数tmpnam
已经弃用了, 这个好像不是非常影响。
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 |
# 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
的结构, 我们需要将其改成\\{([^}]*)\\}
.
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# 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年以后的宏包打包, 则可以将上述代码片段改为
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# 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
文档如下:
1 2 3 4 5 |
\RequirePackage{snapshot} \documentclass{amsart} \begin{document} Hello world! \end{document} |
这里的关键是需要第一行的\RequirePackage{snapshot}
产生宏包依赖列表test.dep
. 例如上面的代码产生的宏包依赖列表为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
\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
1 2 3 4 |
# 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.
发表回复