3

In several different contexts in the TikZ part of the TikZ & PGF manual for version 3.0.1a a temporary suspension of the construction of the current path is mentioned:

  • The description of the \pgfextra{<code>} command, p. 162

    The construction of the path is temporarily suspended and the 〈code〉 is executed. Then, the path construction is resumed.

  • The description of the \path ... pic path operation, p. 252

    When a pic is encountered, the current path is suspended and a new internal scope is started.

  • The description of the \path ... graph path operation, p. 262

    When this command is encountered on a path, the construction of the current path is suspended (similarly to an edge command or a node command). In a local scope, the 〈options〉 are first executed with the key path /tikz/graphs using the following command...

What exactly does this mean?

percusse suggested that this concept can be implemented using the pgfinterruptpath environment described in the PGF part of the manual, on p. 972. Maybe it can, but not naively. Indeed, a naive implementation would translate

\draw (-1,0) graph{ O[red] } -- (1,0);

which renders as

A simple TikZ graph

into

  \pgfmoveto{\pgfpoint{-1cm}{0cm}}
  \begin{pgfinterruptpath}
    \pgfsetfillcolor{red}
    \pgfnode{rectangle}{center}{O}{}{\pgfusepath{discard}}
  \end{pgfinterruptpath}
  \pgflineto{\pgfpoint{1cm}{0cm}}
  \pgfusepath{stroke}

which renders as

The same graph in PGF

Observe that in the former picture, the graph is on top of the path, whereas in the latter one, it is vice versa.

  • 1
    Also you can read about \pgfinterruptpath in the manual – percusse Jul 31 '17 at 9:33
  • 1
    I think looking at examples can help you: tex.stackexchange.com/a/82449/1952 or tex.stackexchange.com/search?q=pgfextra+ – Ignasi Jul 31 '17 at 13:05
  • 2
    You don't need to understand how Postscript works to draw things in TeX. This is really not your concern. Let it do its thing. Or spare a week to read the internals. You are really trying to understand pages of TeX code with two examples and a paragraph in the manual. That's just waste of time in my opinion. – percusse Aug 1 '17 at 8:58
  • 1
    \pgfextra, pic and \path graph take different approaches to "path suspension" (which can be seen in the source code) so the use of this phrase in the manual should not be taken to imply the same underlying basic level operations are occurring, but merely a high level description of what is going on. – Mark Wibrow Aug 1 '17 at 10:45
  • 2
    1. Open a TeX box, 2. \pgfinterruptpath, 3. Do the graph, 4. \endpgfinterruptpath, 5. End the box which now contains the graph, 6. Carry on with the the path. When the path is "finished" (i.e., stroked, filled etc) the box is either inserted beforehand (so behind the path) or afterwards (so in front of the path). The relevant code is the macros \tikz@lib@graph@parser@ and \tikz@lib@graphs@normal@main in tikzlibrarygraphs.code.tex and \tikz@finish in tikz.code.tex. The "box" is the \tikz@whichbox (actually it is a macro which refers to either \tikz@figbox or \tikz@figbox@bg) – Mark Wibrow Aug 1 '17 at 13:15
1

As Mark Wibrow wrote in a comment, \pgfextra, pic and graph don't all take the same approach to "path suspension". There are two approaches to path suspension: the one taken by \pgfextra, and the one taken by node. The other path components: edge, graph and pic are, in a way, treated by the TikZ "engine" like special kinds of nodes, and, in particular, their approach to "path suspension" is like the one taken by nodes.

The explanations below are very rough approximations to what is actually going on in the source code. The code snippets are for illustration purposes only; they are not copied verbatim from the source code, but are the result of extreme, almost grotesque, simplification of the actual implementation. Those who want to understand how TikZ is really implemented, should read the source code.

The \pgfextra approach

When \pgfextra{<body>} is "executed", the path parser yields control temporarily to the top-level TikZ picture parser. However, this happens without closing any existing TeX scope or starting any new one, and the engine's internal state remains unchanged, so all the internal data structures created so far along the path remain intact as control changes hands.

Once the top-level parser has finished processing <body>, control returns to the path parser, which picks up right after the \pgfextra{<body>} command. As before, this control switch does not involve the creation or destruction of TeX scopes, and does not affect the engine's state.

These explanations can be restated more formally as follows. Suppose the top-level TikZ picture parser is called \tikz@parser and takes one argument (\def\tikz@parser#1{...}), and that the TikZ path parser is called \path@parser. Then the execution of the path

\path <before> \pgfextra{<extra>} <after>;

proceeds as follows.

  1. The path statement expands to

    \path@parser <before> \pgfextra{<extra>} <after>;
    
  2. The path parser scans the input consecutively, so the above line eventually reduces to

    \path@parser \pgfextra{<extra>} <after>;
    
  3. This expands to

    \tikz@parser{<extra>} \path@parser <after>;
    

The node approach

A node is typeset into a TeX box that is saved to a TeX box register. A node can be saved to one of two boxes: the foreground box or the background box. All the nodes for which the option behind path was specified are appended to the background box, whereas the rest of the nodes are appended to the foreground box.

At the end of the path, the two boxes' contents, consisting of low-level typesetting directives (aka \specials), are written to the dvi file: first the background box, then the normal path, and finally the foreground box.

Paths are processed in textual order. Since nodes and normal path-construction operations can be textually intermixed, it is essential to take precautions that a node's path will not be treated as a natural continuation of the normal path. Therefore, when a node is first processed, a TeX scope is opened, a copy of the current path is saved to a local "private variable", and the current path is reset, i.e. set to the empty path. Similarly, the path options are saved and reset.

When the node has finished typesetting to the appropriate TeX box, the TeX scope is closed, and the saved path and options are restored.

To put it more formally, the execution of the path

\path <before> node <node specification> <after>;

proceeds as follows.

  1. The path statement expands to

    \path@parser <before> node <node specification> <after>;
    
  2. The path parser scans the input consecutively, so the above line eventually reduces to

    \path@parser node <node specification> <after>;
    
  3. This expands to

    \begin{pgfinterruptpath}%
        \def\options{}%
        \ifx<current node is `behind path`>%
            \setbox\bg@box\hbox{\unbox\bg@box<typeset current node per specs>}%
        \else%
            \setbox\fg@box\hbox{\unbox\fg@box<typeset current node per specs>}%
        \fi%
    \end{pgfinterruptpath}%
    \path@parser<after>;
    

    Note that the pgfinterruptpath environment automatically surrounds its body with a \begingroup ... \endgroup pair.

| improve this answer | |

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.