在 ConTeXt 中创建一系列图形(使用 TikZ)时,我经常使用 ConTeXt 的缓冲区来“复制粘贴”代码。是否有实现此功能的 LaTeX 包?
由于大多数 LaTeX 用户可能不知道缓冲区的作用,让我来解释一下。假设我想分步绘制一个图形:第一步,只绘制节点,第二步绘制边,第三步突出显示图形的一部分。
在 ConTeXt 中,我将按如下方式执行此操作:
\startbuffer[nodes]
% tikz code for drawing nodes
\stopbuffer
\startbuffer[edges]
% tikz code for drawing edges
\stopbuffer
\startbuffer[highlight]
% tikz code for highlight a part
\stopbuffer
\starttext
\startTEXpage \getbuffer[nodes] \stopTEXpage
\startTEXpage \getbuffer[nodes,edges] \stopTEXpage
\startTEXpage \getbuffer[nodes,edges,highlight] \stopTEXpage
\stoptext
这将给我一个包含三页的 pdf 文件,其中分步构建了图表。如何在 LaTeX 中执行相同操作?
我可以使用预览包提取单个页面上的 TikZ 图片,但不知道如何分步构建图表。一种选择是使用 beamer 叠加层分步创建图表,但为每个图创建演示文稿似乎有点过头了。我可以直接复制粘贴代码,但从长远来看这很难维护。有什么建议吗?
编辑
建议将内容存储在宏中的解决方案并不总是有效。例如
\documentclass{minimal}
\usepackage{tikz}
\def\NODES
{\matrix
{
\node (a) {$a$} ; & \node (b) {$b$} ; \\
} ;
}
\begin{document}
\begin{tikzpicture}
\NODES
\end{tikzpicture}
\end{document}
给出
!软件包 pgfbasematrix 错误:单个“&”符号与错误的 catcode 一起使用。
还有其他建议吗?
答案1
这不是一个真正正确的答案,但也许它可以作为提示:
基于缓冲区的作用,我认为,filecontents
结合\input
(for \getbuffer
) 和\verbatiminput
(for \typebuffer
) 的环境最接近。
答案2
下面的代码显示了更新后问题的三种可能的解决方案。
\documentclass{minimal}
\usepackage{tikz}
\def\NODESa
{\matrix
{
\node (a) {$a$} ; & \node (b) {$b$} ; \\
} ;
}
\def\NODESb
{\matrix[ampersand replacement=\&]
{
\node (a) {$a$} ; \& \node (b) {$b$} ; \\
} ;
}
\begingroup
\catcode`\&=\active
\def\x#1{#1}%
\x{%
\endgroup
\def\NODESc
{\matrix
{
\node (a) {$a$} ; & \node (b) {$b$} ; \\
} ;
}
}
\begin{document}
\begin{tikzpicture}
\scantokens\expandafter{\NODESa}
\end{tikzpicture}
\begin{tikzpicture}
\NODESb
\end{tikzpicture}
\begin{tikzpicture}
\NODESc
\end{tikzpicture}
\end{document}
答案3
根据 Joel 的上述评论,我只想写
\def\buffernodes{
% tikz code for drawing nodes
}
\def\bufferedges{
% tikz code for drawing edges
}
\def\bufferhighlight{
% tikz code for highlight a part
}
\buffernodes
\newpage
\buffernodes\bufferedges
\newpage
\buffernodes\bufferedges\bufferhighlight
您可以编写一个包装器来实现更像 ConTeXt 的缓冲区接口,但对于这个简单的例子,我认为这样就足够了。
答案4
toks
你可以使用寄存器和 e-TeX 来模拟穷人的缓冲区\scantokens
。正如你所见,\typebuffer
它并没有按预期工作,但\getbuffer
似乎工作正常。
\def\setverb{\def\do##1{\catcode`##1=12}\dospecials}
\newtoks\buffer
\def\startbuffer{\begingroup\setverb\tt\dobuffer}
{\catcode`\|=0 |catcode`|\=12
|long|gdef|dobuffer#1\stopbuffer{%
|expandafter|global|buffer={#1}%
|endgroup}}
\def\typebuffer{{\tt\the\buffer}}
\def\getbuffer{\expandafter\scantokens\expandafter{\the\buffer}}
\startbuffer
\def\x{abc}
\x
Hello World!
This is a poor man's buffer.
\stopbuffer
\typebuffer
\bigbreak
\getbuffer
\bye