结合 Beamer、Animate、Tikz 和 Listings 时出现奇怪的错误

结合 Beamer、Animate、Tikz 和 Listings 时出现奇怪的错误

我正在制作一些幻灯片,展示 Java 代码的实际执行方式。因此,我正在使用 animate 包来生成动画。

无需赘述,我编写了一个宏来帮助我生成动画图像。这些图像由 Tikz 生成:

\newcommand{\methodexec}[4]{\begin{tikzpicture}[yscale=-1]
\draw (0,0) rectangle (10,5);
\begin{scope}[xshift=0cm,yshift=0cm]
\node[anchor=north west] (C) at (0,0) {\begin{minipage}{3in}\lstinputlisting[linebackgroundcolor={\ifthenelse{\value{lstnumber}=#2}{\color{green}}{}}]{programs/#1}\end{minipage}};
\end{scope}
\begin{scope}[yscale=-1,yshift=-5 cm]
\setcounter{tmpA}{1}
\foreach \n in {#3} {
 \coordinate (X) at (8.5,0.5*\arabic{tmpA});
 \node[pointerbox] (box\n) at (X) {};
 \node[pointerdot] (ptr\n) at (X) {};
 \node[anchor=west] (\n) at (box\n.east) {\small{\texttt{\n}}};
 \addtocounter{tmpA}{1}
}
\end{scope}
\begin{scope}[xshift=0.25,yshift=2.5 cm]
#4
\end{scope}
\end{tikzpicture}}

该宏的一个示例是\methodexec{code.java}{1}{}{}

除了我将这些图片整合到动画中时,一切都正常:

\begin{animateinline}{1}
\methodexec{code.java}{1}{}{}\newframe
\methodexec{code.java}{2}{}{}
\end{animateinline}

编译器正确编译了图像但报告了一些错误:

<a0,fr0> (./programs/code.java) ! Argument of \l@lstlisting has an extra }. <inserted text> \par l.11 }\newframe Runaway argument? ! Paragraph ended before \l@lstlisting was complete. <to be read again> \par l.11 }\newframe 

当然,您可以说我可以忽略这些错误。但是我认为我的代码有问题,而且 Kile.vrb在报告错误时会打开框架文件(我在fragile模式下编译此类框架),这种行为很烦人。

編輯:如 MWE 所說:

test.tex

\documentclass[handout]{beamer}
\usepackage{tikz,listings,lstlinebgrd}
\usepackage[controls]{animate}
\usetikzlibrary{calc,shapes,fit}
\lstset{language=Java,basicstyle=\tiny\ttfamily,breaklines=true}
\tikzset{pointer/.style={->,thick,black},pointerdot/.style={fill=black,circle,inner sep=0pt,minimum size=0.125cm},pointerbox/.style={draw=black,rectangle,minimum size=0.25 cm}}
\newcounter{tmpA}
\newcommand{\methodexec}[4]{\begin{tikzpicture}[yscale=-1]
\draw (0,0) rectangle (10,5);
\begin{scope}[xshift=0cm,yshift=0cm]
\node[anchor=north west] (C) at (0,0) {\begin{minipage}{3in}\lstinputlisting[linebackgroundcolor={\ifthenelse{\value{lstnumber}=#2}{\color{green}}{}}]{programs/#1}\end{minipage}};
\end{scope}
\begin{scope}[yscale=-1,yshift=-5 cm]
\setcounter{tmpA}{1}
\foreach \n in {#3} {
 \coordinate (X) at (8.5,0.5*\arabic{tmpA});
 \node[pointerbox] (box\n) at (X) {};
 \node[pointerdot] (ptr\n) at (X) {};
 \node[anchor=west] (\n) at (box\n.east) {\small{\texttt{\n}}};
 \addtocounter{tmpA}{1}
}
\end{scope}
\begin{scope}[xshift=0.25,yshift=2.5 cm]
#4
\end{scope}
\end{tikzpicture}}
\begin{document}
\begin{frame}[fragile]{Some title}
\begin{animateinline}{1}
\methodexec{code.java}{1}{}{}\newframe
\methodexec{code.java}{2}{}{}\newframe
\methodexec{code.java}{3}{}{}
\end{animateinline}
\end{frame}
\end{document}

并且code.java(在programs目录中):

foo
bar
baz

有什么想法吗?解决方法(例如软件包的变体listings)也很有帮助。

EDIT2:这显然与包有关listings,因为使用minted解决了问题。但这并不能解释为什么listings会产生此错误。


John Wickerson 补充道:我做了一个更简单的 MWE,排除了 TikZ 是罪魁祸首的可能性。Beamer、Animate 和 Listings 都仍然是嫌疑对象。

\documentclass{beamer}
\usepackage{listings}
\usepackage{animate}
\usepackage{filecontents}
\begin{filecontents*}{code.java}
foo
bar
baz
\end{filecontents*}
\begin{document}
\begin{frame}[fragile]{Some title}
\begin{animateinline}{1}
\lstinputlisting{code.java}
\end{animateinline}
\end{frame}
\end{document}

答案1

仅当文档使用pdflatex或排版时才会出现此错误lualatex,而xelatexlatex++dvips可以ps2pdf顺利运行。

animate首先使用 LaTeX 命令将动画帧内容放入一个框中\savebox。然后使用 pdfTeX 中的命令将填充的框提炼为 PDF 表单 XObject \pdfxform。如果框中包含listings相关材料,则最后一步失败。

pdftex和的最小测试用例lualatex(不animate涉及)是

\documentclass{beamer}
\usepackage{listings}

\usepackage{filecontents}
\begin{filecontents*}{code.java}
foo
bar
baz
\end{filecontents*}

\newsavebox\listing

\begin{document}
\begin{frame}[fragile]{Some title}

\savebox\listing{\lstinputlisting{code.java}}
\immediate\pdfxform\listing%

\end{frame}
\end{document}

其他引擎不使用\pdfxform,因此不会显示此错误。

作为一种解决方法,我建议使用previewstandalone包生成单独的 PDF,并在各个页面上包含动画帧。然后可以使用命令为该多页 PDF 制作动画\animategraphics

相关内容