我正在使用.latexmkrc
为我的工作流程设置配置latexmk
,但在路径/查找问题上遇到了死胡同。
我目前的设置(用作 MWE)
.latexmkrc
:
# Set the program used to generate the PDF
# 1: pdflatex
# 2: postscript conversion, don't use this
# 3: dvi conversion, don't use this
# 4: lualatex
# 5: xelatex
$pdf_mode = 1;
# Move all axuiliary files to a separate directory, so they do not clutter up the project directory
$emulate_aux = 1;
$aux_dir = "tmp";
# Move the compiled files (and synctex) to a separate directory
$out_dir = 'build';
set_tex_cmds(" --shell-escape -interaction=nonstopmode -file-line-error -synctex=1 ");
$clean_ext .= ' %R.figlist %R-figure* %R.makefile fls.tmp';
$latex = 'internal tikzlatex latex %B %O %S';
$pdflatex = 'internal tikzlatex pdflatex %B %O %S';
$lualatex = 'internal tikzlatex lualatex %B %O %S';
$xelatex = 'internal tikzlatex xelatex %B %O %S';
$hash_calc_ignore_pattern{'pdf'} = '^(/CreationDate|/ModDate|/ID)';
$hash_calc_ignore_pattern{'ps'} = '^%%CreationDate';
sub tikzlatex {
my ($engine, $base, @args) = @_;
my $ret = 0;
print "Tikzlatex: ===Running '$engine @args'...\n";
$ret = system( $engine, @args );
print "Tikzlatex: Fixing .fls file ...\n";
system "echo INPUT \"$aux_dir1$base.figlist\" > \"$aux_dir1$base.fls.tmp\"";
system "echo INPUT \"$aux_dir1$base.makefile\" >> \"$aux_dir1$base.fls.tmp\"";
system "cat \"$aux_dir1$base.fls\" >> \"$aux_dir1$base.fls.tmp\"";
rename "$aux_dir1$base.fls.tmp", "$aux_dir1$base.fls";
if ($ret) { return $ret; }
if ( -e "$aux_dir1$base.makefile" ) {
system "echo \"$aux_dir1$base.makefile\"";
if ($engine eq 'xelatex') {
print "Tikzlatex: ---Correcting '$aux_dir1$base.makefile' made under xelatex\n";
system( 'perl', '-i', '-p', '-e', 's/^\^\^I/\t/', "$aux_dir1$base.makefile" );
}
elsif ($engine eq 'latex') {
print "Tikzlatex: ---Correcting '$aux_dir1$base.makefile' made under latex\n";
system( 'perl', '-i', '-p', '-e', 's/\.epsi/\.ps/', "$aux_dir1$base.makefile" );
}
print "Tikzlatex: ---Running 'make -f $aux_dir1$base.makefile' ...\n";
if ($aux_dir) {
# latexmk has set $ENV{TEXINPUTS} in this case.
my $SAVETEXINPUTS = $ENV{TEXINPUTS};
$ENV{TEXINPUTS} = good_cwd().$search_path_separator.$ENV{TEXINPUTS};
pushd( $aux_dir );
$ret = system "make", "-j", "5", "-f", "$base.makefile";
&popd;
$ENV{TEXINPUTS} = $SAVETEXINPUTS;
}
else {
$ret = system "make", "-j", "5", "-f", "$base.makefile";
}
if ($ret) {
print "Tikzlatex: !!!!!!!!!!!!!! Error from make !!!!!!!!! \n",
" The log files for making the figures '$aux_dir1$base-figure*.log'\n",
" may have information\n";
}
}
else {
print "Tikzlatex: No '$aux_dir1$base.makefile', so I won't run make.\n";
}
return $ret;
}
mwe.tex
:(不起作用)
% mwe.tex
\documentclass{article}
\usepackage{tikz,pgfplots, pgfplotstable}
\usetikzlibrary{external}
% NOTE: data.csv cannot be generated fromfilecontents, as it end up in /tmp then
\tikzexternalize[
mode=list and make,
only named=true,%
] % activate
\begin{document}
\begin{figure}
\tikzsetnextfilename{external-figure}%
% \tikzpicturedependsonfile{src/data.csv}
\input{src/figure.tikz}
\end{figure}
\end{document}
src/data.csv
:
x, y
0, 0
1, 1
src/figure.tikz
:
\begin{tikzpicture}
\pgfplotstableread[
col sep = comma,
]{src/data.csv}{\dataX}
\begin{axis}
\addplot table from {\dataX};
\end{axis}
\end{tikzpicture}%
问题描述:
在编译期间,make -f tmp/mwe.makefile
找不到文件tmp/data.csv
,但必须给出相对于根文件的文件以供常规输入。
我希望能够继续使用 aux-dir 设置,以便将我的文档创建的大量临时文件与源文件和输出文件分开。
我不认为这是一个问题pgfplotstable
,但在使用辅助目录时,这通常是搜索路径的问题。pgfplotstable
应该理解为一个例子。
调查的解决方案:
- 如果我进入
\pgfplotstableread
,mwe.tex
它就不会成为输入的一部分,而是latexmk
可以顺利运行。我更喜欢将数据加载捆绑在 tikzpicture 环境内,就像在我的 MW(n)E 中一样。* - 显而易见的下一步:移出
\pgfplotstableread
环境tikzpicture
,但将其保持在环境内部,src/figure.tikz
这是一个可接受的解决方案,但也会引发错误。
寻求建议
我迷茫了,不知道下一步该怎么做。有人能给我一些建议吗:
- 如何实现期望的行为?
- 如何自动修改makefile
externalize
并list-and-make
相应地创建?
答案1
我采纳了 John Collins 的评论并.latexmkrc
相应地改进了我的评论。要试用它,请将其与我的 M(n)WE 中最初提供的其他文件一起运行。
.latexmkrc
:
# Set the program used to generate the PDF
# 1: pdflatex
# 2: postscript conversion, don't use this
# 3: dvi conversion, don't use this
# 4: lualatex
# 5: xelatex
$pdf_mode = 1;
# Move all axuiliary files to a separate directory, so they do not clutter up the project directory
$emulate_aux = 1;
$aux_dir = "tmp";
# Move the compiled files (and synctex) to a separate directory
$out_dir = 'build';
# This is the directory latexmk links for makefiles inside the $aux_dir: Place all external resources here.
$source_dir = "src";
# Produce less console output
$silent = 1;
set_tex_cmds(" --shell-escape -interaction=nonstopmode -file-line-error -synctex=1 ");
$clean_ext .= ' %R.figlist %R-figure* %R.makefile fls.tmp';
$latex = 'internal tikzlatex latex %B %O %S';
$pdflatex = 'internal tikzlatex pdflatex %B %O %S';
$lualatex = 'internal tikzlatex lualatex %B %O %S';
$xelatex = 'internal tikzlatex xelatex %B %O %S';
$hash_calc_ignore_pattern{'pdf'} = '^(/CreationDate|/ModDate|/ID)';
$hash_calc_ignore_pattern{'ps'} = '^%%CreationDate';
sub tikzlatex {
my ($engine, $base, @args) = @_;
my $ret = 0;
print "Tikzlatex: ===Running '$engine @args'...\n";
$ret = system( $engine, @args );
print "Tikzlatex: Fixing .fls file ...\n";
system "echo INPUT \"$aux_dir1$base.figlist\" > \"$aux_dir1$base.fls.tmp\"";
system "echo INPUT \"$aux_dir1$base.makefile\" >> \"$aux_dir1$base.fls.tmp\"";
system "cat \"$aux_dir1$base.fls\" >> \"$aux_dir1$base.fls.tmp\"";
rename "$aux_dir1$base.fls.tmp", "$aux_dir1$base.fls";
if ($ret) { return $ret; }
if ( -e "$aux_dir1$base.makefile" ) {
system "echo \"$aux_dir1$base.makefile\"";
if ($engine eq 'xelatex') {
print "Tikzlatex: ---Correcting '$aux_dir1$base.makefile' made under xelatex\n";
system( 'perl', '-i', '-p', '-e', 's/^\^\^I/\t/', "$aux_dir1$base.makefile" );
}
elsif ($engine eq 'latex') {
print "Tikzlatex: ---Correcting '$aux_dir1$base.makefile' made under latex\n";
system( 'perl', '-i', '-p', '-e', 's/\.epsi/\.ps/', "$aux_dir1$base.makefile" );
}
print "Tikzlatex: ---Running 'make -f $aux_dir1$base.makefile' ...\n";
if ($aux_dir) {
# latexmk has set $ENV{TEXINPUTS} in this case.
my $SAVETEXINPUTS = $ENV{TEXINPUTS};
$ENV{TEXINPUTS} = good_cwd().$search_path_separator.$ENV{TEXINPUTS};
# since some files are trying to get source files during compilation of the externalize list-and-make makefile, provide them with a symlink to the source files:
$current_dir = getcwd();
$existing_file = "$current_dir/$source_dir";
$new_file = "$current_dir/$aux_dir/$source_dir";
my $symlink_exists = eval { symlink ( $existing_file, $new_file);; 1 };
if (not($symlink_exists)) {
print "Tikzlatex: ---Creation of symlink failed. Please create a symlink from '$aux_dir/$source_dir' to '<document root>/$source_dir' manually.\n";
}
pushd( $aux_dir );
$ret = system "make", "-j", "5", "-f", "$base.makefile";
&popd;
$ENV{TEXINPUTS} = $SAVETEXINPUTS;
}
else {
$ret = system "make", "-j", "5", "-f", "$base.makefile";
}
if ($ret) {
print "Tikzlatex: !!!!!!!!!!!!!! Error from make !!!!!!!!! \n",
" The log files for making the figures '$aux_dir1$base-figure*.log'\n",
" may have information\n";
}
}
else {
print "Tikzlatex: No '$aux_dir1$base.makefile', so I won't run make.\n";
}
return $ret;
}
我特别想指出以下添加的几行:
# This is the directory latexmk links for makefiles inside the $aux_dir: Place all external resources here.
$source_dir = "src";
# since some files are trying to get source files during compilation of the externalize list-and-make makefile, provide them with a symlink to the source files:
$current_dir = getcwd();
$existing_file = "$current_dir/$source_dir";
$new_file = "$current_dir/$aux_dir/$source_dir";
my $symlink_exists = eval { symlink ( $existing_file, $new_file);; 1 };
if (not($symlink_exists)) {
print "Tikzlatex: ---Creation of symlink failed. Please create a symlink from '$aux_dir/$source_dir' to '<document root>/$source_dir' manually.\n";
}
它会自动生成查找外部依赖项所需的符号链接(在大多数平台上)。
手动创建符号链接不是一个选项,因为我担心其他用户会删除$aux_dir
,而不知道或不记得重新安装符号链接。
如果有人愿意提出建议,我很乐意改进我的脚本。