24

While creating a series of graphics (using TikZ) in ConTeXt, I frequently use ConTeXt's buffer to "copy-paste" code. Is there a LaTeX package that implements this feature?

Since most LaTeX users may not know what buffers do, let me explain that. Suppose I want to draw a graph in steps: in the first step, only draw the nodes, in the second step draw the edges, in the third step highlight a part of the graph.

In ConTeXt, I would do this as follows:

\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

This will give me a pdf file with three pages, that build up the graph in steps. How do I do the same in LaTeX?

I can use the preview package to extract TikZ pictures on individual pages, but don't know how to build the graph in steps. One option is to use beamer overlays to create the graph in steps, but creating a presentation for each figure appears to be an overkill. I can just copy paste code, but that is difficult to maintain in the long run. Any suggestions?

Edit

The proposed solution of storing the contents in a macro does not always work. For example

\documentclass{minimal}
\usepackage{tikz}

\def\NODES
  {\matrix
    {
    \node (a) {$a$} ; & \node (b) {$b$} ; \\
    } ;
  }

\begin{document}
\begin{tikzpicture}
  \NODES
\end{tikzpicture}
\end{document}

gives

! Package pgfbasematrix Error: Single ampersand used with wrong catcode.

Any other suggestions?

  • 8
    Wow, thats a cool feature of ConTeXt that I hadn't heard about. Now I'm not the oldest of hands at LaTeX, but I've never heard of any similar feature. Perhaps you could define each step with newcommand and call them later, but other than that, not too sure. – Joel Berger Nov 14 '10 at 3:02
  • How does context work around the problem you note in the update? I assume it must use \scantokens. – Will Robertson Nov 20 '10 at 6:19
  • 2
    @Will: the content is treated as a verbatim block that is processed one line at a time, ending with the literal string "\stopbuffer" at the start of a line. – Taco Hoekwater Nov 20 '10 at 8:17
12

Not really a proper answer, but perhaps it is useful as hint:

Based on what buffers do, the filecontents environment combined with \input (for \getbuffer) and \verbatiminput (for \typebuffer) comes closest, I think.

  • Thanks. filecontents does work the same way as buffers in MkII. I can use \begin{filecontents}{\jobname-nodes.tmp} ... \end{filecontents} and then just \input{\jobname-nodes.tmp}. I think that this the most failsafe solution because no catcode trickery is required. – Aditya Nov 20 '10 at 15:08
11

The following code shows three possible solutions to the updated question.

\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}
  • What does \scantokens do? The other two I understand (and had been thinking about), but might not be clear in general. – Antal Spector-Zabusky Nov 20 '10 at 2:16
  • 3
    @antal it retokenises its argument with the current catcode settings. Equivalent to writing the argument verbatim to a file and \input-ing it in again. Using \scantokens here would be my favored approach, I think. – Will Robertson Nov 20 '10 at 6:21
  • 1
    @Antal: One should add that \scantokens is an e-TeX primitive (that I'd never heard of until now). – Hendrik Vogt Nov 20 '10 at 9:12
  • Thanks. I did not know that tikz sets & to be active. All three solutions work perfectly. – Aditya Nov 20 '10 at 15:05
9

Based on Joel's comment above, I'd just write

\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

You could write a wrapper to implement a more ConTeXt-like buffer interface, but for this simple example I think it's fine as-is.

  • Yeah, probably should have submitted as an answer, but was too busy to mock up a demo. Well done. – Joel Berger Nov 14 '10 at 4:23
  • Thanks. For this case, this seems to be the easiest way to go. (ConTeXt buffers do other things also, but I do not need those features in this case). – Aditya Nov 14 '10 at 4:36
  • 1
    This solution does not always work. See the updated question. – Aditya Nov 20 '10 at 0:43
3

You can emulate a poor man's buffer using toks registers and e-TeX's \scantokens. As you can see \typebuffer does not work as intended but \getbuffer seems to work fine.

\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

enter image description here

0

You could use the Beamer package which works well with Tikz.

\documentclass{beamer}
\usepackage{tikz}
\begin{document}
\begin{frame}
\begin{tikzpicture}
\onslide<+->{
% tikz code for drawing nodes
}
\onslide<+->{
% tikz code for drawing edges
}
\onslide<+->{
% tikz code for highlight a part
}
\end{tikzpicture}
\end{frame}
\end{document}

I am actually looking for the ConTeXt equivalent of this. Thanks for your tip in your question. But do you know if and how ConTeXt could do it without generating multiple pages for these "overlays" (in the language of Beamer)? Beamer has a really good manual called the Beamer Guide.

  • This is a neat use of Beamer's overlays, although I think not quite as general as ConTeXt's buffer concepts i.e. this is restricted to same frame effects. – Dai Bowen Oct 22 '16 at 10:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.