![使用带有指定 --output-directory 的 memoize 包](https://linux22.com/image/474394/%E4%BD%BF%E7%94%A8%E5%B8%A6%E6%9C%89%E6%8C%87%E5%AE%9A%20--output-directory%20%E7%9A%84%20memoize%20%E5%8C%85.png)
我正在尝试配置 memoize 包,但在尝试将 --output-directory 选项传递给 LuaLatex 时遇到问题。从查看输出文件及其最终结果来看,似乎 memoize 错误地写入了输出目录,但没有从中读取。使用下面的 MWE:
\documentclass{article}
\usepackage[memo dir]{memoize}
\usepackage[linguistics]{forest}
\usepackage{fontspec}
\setmainfont{Charis SIL}
\begin{document}
A test document.
\begin{forest}
[S
[NP]
[VP]
]
\end{forest}
\end{document}
该包使用简单命令正常运行,但却因一般错误lualatex untitled.tex
而失败。lualatex --output-directory=output untitled.tex
我也尝试过添加,\mmzset{prefix=output/}
但没有成功。
答案1
好消息:Memoize 确实支持了--output-directory
,或者更准确地说,一旦 TeXLive 2024 发布,它就会支持它。让我解释一下。
Memoize 的提取脚本尊重环境变量的值TEXMF_OUTPUT_DIRECTORY
,将要由 TeXLive 2024 引入(所以,很快!)。(事实上,新变量被认为是解决 Memoize 问题的解决方案--output-directory
,我非常感谢 Karl Berry 找出解决方案并实施它!)在 TeXLive 2024 中,(a)设置TEXMF_OUTPUT_DIRECTORY
将是指定 的替代方法--output-directory
,并且(b)无论输出目录如何设置,其值都将由嵌入式作业(如 Memoize 提取脚本)接收的环境变量反映TEXMF_OUTPUT_DIRECTORY
。底线:11 天内,一切将立即可用。
同时,解决方法是TEXMF_OUTPUT_DIRECTORY
手动设置:
TEXMF_OUTPUT_DIRECTORY=output lualatex --output-directory=output untitled.tex
现在坏消息:虽然这已经过测试,并且适用于pdftex
引擎,但似乎不适用于luatex
。或者更确切地说,只要正确生成和提取了外部变量,一切就都正常,但利用外部变量会失败,因为lualatex
不会在输出目录中搜索它们(与不同pdflatex
)。我会尽快调查。
一种解决方法是将备忘录目录从输出目录软链接到当前目录,但我意识到 OP 的设置可能不允许这样做。从包含untitled.tex
运行的目录中:
ln -s output/untitled.memo.dir
答案2
我想补充一下 Sašo Živanović 的回答,可以配置 latexmk 以使用带有输出目录的 memoize。
以下是 latexmkrc 文件中的内容。 (请注意,此配置的改进版本将在下一个版本的 latexmk(v. 4.84)中出现。此处的解决方案仅适用于 Unix 类型操作系统(linux 和 macOS)上的 TeXLive,并且仅当 latexmk 使用 lualatex for pdflatex 来编译 .tex 文件时才有效。)
$pdf_mode = 4; # Use lualatex. Set to 1 for pdflatex, 5 for xelatex.
# You can have separate build and output directories, or they can be
# the same, e.g., by $out_dir = $aux_dir = 'output';
$out_dir = 'output';
$aux_dir = 'build';
$emulate_aux = 1;
# Get latexmk -C to delete memoize-generated files, at least
# when the default setting in memoize for the prefix of .memo
# and .pdf files is used.
push @generated_exts, 'mmz', 'mmz.log', '%R.*.memo', '%R.*.pdf';
&set_tex_cmds( 'internal latex_memoize %C %B %S -synctex=1 %O' );
sub latex_memoize {
print "============= I am latex_memoize \n";
# Ensure TEX_OUTPUT_DIRECTORY is set. (In v. >=4.84 of latexmk, this
# will not be necessary, since latexmk will make the setting itself.)
local %ENV = %ENV;
foreach ( 'TEXMF_OUTPUT_DIRECTORY' ) {
$ENV{$_} = $aux_dir;
print "latex_memoize: ENV{$_} = '$ENV{$_}'\n";
}
my ($cmd, $base, $source, @args) = @_;
my $tex_log = "$aux_dir1$base.log";
my $mmz_file = "$aux_dir1$base.mmz";
my @tex_cmd = ($cmd, @args, $source );
my @memo_cmd = ("memoize-extract.pl", '-F', 'latex', $mmz_file );
print "latex_memoize: Running\n '@tex_cmd'\n";
my $ret = system @tex_cmd;
if (! -e $mmz_file) {
print "latex_memoize: No mmz file '$mmz_file', so memoize is not being used.\n";
return $ret;
}
# Use (not-currently-documented) latexmk subroutine to determine
# whether mmz file was generated in current run:
if ( ! test_gen_file_time( $mmz_file) ) {
warn "latex_memoize: Mmz file '$mmz_file' exists, but wasn't generated\n",
" in this run so memoize is not **currently** being used.\n";
return $ret;
}
# Fix up dependency information in log file:
my $mmz_fh = undef;
my $tex_log_fh = undef;
if (! open( $mmz_fh, '<', $mmz_file ) ) {
print "latex_memoize: Cannot open mmz file '$mmz_file':\n $!\n";
return $ret;
}
if (! open( $tex_log_fh, '>>', $tex_log ) ) {
warn "latex_memoize: Cannot open log file '$tex_log': $!\n";
close $mmz_fh;
return $ret;
}
while ( <$mmz_fh> ) {
s/\s*$//;
my $source = undef;
if ( /^\\mmzNewExtern\s+{([^}]+)}/ ) {
# We have a new memo item without a corresponding pdf file
# Put a suitable message in the log file, so that latexmk will
# know to run *latex again, when it analyzes the results of
# the current run.
$file = "$aux_dir1$1";
print "latex_memoize: new extern for memoize: '$file'\n";
print $tex_log_fh "No file $file\n";
}
}
close $tex_log_fh;
close $mmz_fh;
# Run memoize-extract.pl now. Then missing pdf files are
# created, which will provoke latexmk into rerunning *latex.
# It also handles the case that the memoize package is used
# with the external=no option. (But gives no problem when
# the option is not used.)
# It also allows the use of separate aux and output directories
# which would otherwise give a problem, since in that situation
# latexmk will move the pdf file from the aux directory to the
# output directory, where it is no longer accessible to
# memoize-extract.pl.
print "Running\n @memo_cmd\n";
my $ret2 = system @memo_cmd;
if ($ret2) { return $ret2; }
return $ret;
}
这已在 TeXLive 2023 和 2024 以及所有 pdflatex、lualatex 和 xelatex 上进行了测试。(在 Windows 上,当文件名称中包含非 ASCII 字符时可能会出现一些问题,但我尚未检查。)
正如问题评论中提到的,使用输出目录有一些复杂性。使事情正常工作的方法已经编入 latexmk 中;这是许多年前完成的,非常简单,但不是您想从命令行定期执行的操作。我发现使用 latexmk 可以让我避免提到的困难。