集成 latexmk 和 TikZ 外部模式=list 和 make

集成 latexmk 和 TikZ 外部模式=list 和 make

我一直在研究使用它latexmk来创建我的文档,因为它可以自动处理文档需要完全处理的次数等。因此,例如,latexmk -pdf file.tex只需运行一次简单操作pdflatex,并bibtex根据需要多次运行即可解决所有引用。

我想知道在模式下使用TikZ/库时是否有可能不失去这样做的能力。如果使用,则会生成/ makefile,但不会自动调用它。您可以手动运行 makefile,当然,这将生成图形文件,但问题是,就其而言,文件保持不变,因此再次运行不会将新生成的图形插入文档中。externallist and makelist and makeTikZexternallatexmklatexmk.texlatexmk

因此,假设在模式下file.tex使用TikZ/ ,则会发生以下情况:externallist and make

  • latexmk -pdf file.tex生成 pdf 并为尚未生成的图形插入占位符。
  • make -f file.makefile处理并生成图形的pdf文件。
  • latexmk -pdf file.tex不执行任何操作,因为源文件没有改变。

我认为有一种方法可以在第二遍中强制生成 pdf latexmk,但这意味着即使源文件保持不变也会发生这种情况。

我想知道是否有办法latexmk“自动”处理所有这些问题?那就太好了!

以下是一个可以帮助大家入门的 MWE:

\documentclass{article}

\usepackage{tikz,pgfplots}
\usetikzlibrary{external}
\tikzexternalize[mode=list and make]

\begin{filecontents}{plot.tikz}
\begin{tikzpicture}
  \begin{axis}
    \addplot coordinates {(1,1) (2,2) (3,3)};
  \end{axis}
\end{tikzpicture}%
\end{filecontents}

\begin{document}
  \input{plot.tikz}
\end{document}

答案1

这不是 latexmk 自动化,但如果源 .tex 文件没有改变,它可以避免重新编译:

latexmk -pdf file.tex
make -n -f file.makefile > /dev/null | grep pdflatex > /dev/null
if [ $? -eq 0 ] ; then
  make -f file.makefile
  latexmk -g -pdf file.tex
fi

如果自动生成的 makefile 实际上不会编译任何图形,则字符串“pdflatex”将不会出现在试运行的输出中;否则,图形将被编译,并且 latexmk 被迫至少再进行一次编译。


或者,这里有一个大多数时候都能正常工作的 latexmkrc 文件:在第一次调用 pdflatex 之后,它每次调用 latexmk 都会运行一次外部 makefile。

如果您从头开始编译文档,latexmk 很可能会多次运行 pdflatex,因此第一次运行后将包含这些图形。如果您不是从头开始构建,那么 latexmk 很可能会识别出已包含外部图形,看到它们已被外部 makefile 更新,然后由于依赖项的变化而决定再次运行 pdflatex。

警告:这是我第一次编写 perl:

our %externalflag = ();

$pdflatex = 'internal mypdflatex %O %S %B';

sub mypdflatex {
  our %externalflag;
  my $n = scalar(@_);
  my @args = @_[0 .. $n - 2];
  my $base = $_[$n - 1];

  system 'pdflatex', @args;
  if ($? != 0) {
    return $?
  }
  if ( !defined $externalflag->{$base} ) {
    $externalflag->{$base} = 1;
    system ("$make -j8 -f $base.makefile");
  }
  return $?;
}

答案2

这不是对您的问题的直接回答,而是实现您的总体目标的另一种方法:外包 TikZ 图片并仅在它们发生变化时重建它们。

这可以使用standalone班级

\documentclass{article}
\usepackage[mode=buildnew]{standalone}

\begin{filecontents}{plot.tex}
\documentclass[tikz]{standalone}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
  \begin{axis}
    \addplot coordinates {(1,1) (2,2) (3,3)};
  \end{axis}
\end{tikzpicture}%
\end{document}
\end{filecontents}

\begin{document}
  \includestandalone{plot}
\end{document}

这可以很好地满足您的需求,因为您已经将 TikZ 图片放在单独的文件中有了 ,一切都会“自动”运行latexmk。警告:文件必须有扩展名.tex而不是 ,.tikz并且您必须添加几行代码。

答案3

抱歉,我发了旧帖,但这是我在这里第一次查找这个问题几天后发现的一个窍门。

就上下文而言,我正在使用latexmk -pvc(即在“连续预览”模式下),使用 okular 作为 pdf 查看器,使用 Kate 作为文本编辑器;不过这应该没关系。


latexmkrc

$analyze_input_log_always=1;
$default_files=("file.tex");
$make="make -k -j 6"; # `-k`: keep trying on errors; -j 6: six parallel jobs
$use_make_for_missing_files=1; # probably only this is needed
$pdf_mode=4; # use lualatex
set_tex_cmds('--shell-escape --synctex=1 %O %S'); # generate source mapping

我对乳胶等了解不够,不知道哪些部分是真正需要的;也许就$use_make_for_missing_files=1足够了。

latexmk 文档中的某个地方有提示用于\typeout{(filename)}声明依赖项,但是仔细研究代码就会发现,如果该文件不存在,则会丢弃该提示。但是,如果我们让它听起来更可怕,它会保留下来:

Tikzfile.makefile使用虚拟目标创建一个allimages。但是,如果错误消息未指定扩展名,latexmk 将尝试其中几个,但不会真正构建纯名称。因此,我们使用这个假错误消息:

\typeout{}
\typeout{No file "allimages.pdf".}
\typeout{}

并创建一个新的makefile以将其重定向到 tikz 生成的目标:
makefile

-include file.makefile
allimages.pdf: allimages

(确保没有allimages.texallimages.pdf


注意事项:

  • 这是第一次使用乳胶,因此使用时请自行承担风险。
  • 我无法让它与自定义一起工作out_dir\tikzsetexternalprefix{figures/}但是没问题。
  • 即使一切顺利,latexmk 也会在其摘要中列出虚假错误消息。
  • 我建议设置一个\tikzfigurename,以便在开始时添加新图像不会破坏所有内容,
  • \tikzfiguredependsonfile需要走了 \tikzfigurename,但在此之前\begin{tikzpicture}
  • 我遇到过一些情况,我破坏了一些预先存在的图像,而 latexmk 在目标已经失败后决定尝试make处理每个单独的图像allimages。如果错误发生需要很长时间,这可能会很烦人。
  • 很难看出所有图像是否都编译正确,因为任何 make 输出都将被后续的 latex 运行所掩盖。尝试查看每个 *.log 是否也有一个 *.pdf。

额外好处:使用单独的 makefile,您甚至可以定义自己的(隐式)数据预处理方案。通过 触发这些方案\tikzpicturedependsonfile

相关内容