2

The following macro is defined in the TikZ source code (specifically in <tex installation directory>/tex/generic/pgf/frontendlayer/tikz/tikz.code.tex).

\def\tikz@scan@next@command{%
  \ifx\tikz@collected@onpath\pgfutil@empty%
  \else%
    \tikz@invoke@collected@onpath%
  \fi%
  \afterassignment\tikz@handle\let\pgf@let@token=%
}

What is the purpose of the \afterassignment in this context?

I'm not asking about \afterassignmet in general, though I sure won't mind a recap about how this construct works in general. But I'm particularly interested in what it means within the above macro in light of what the macro is supposed to do. A similar usage occurs many times in the TikZ source code. I hope that if I understand the example above, I'll understand it once and for all.

Evan Aad
  • 11,066
  • 1
    It simply swallows one token and executes \tikz@handle. – egreg Aug 08 '17 at 16:15
  • @egreg: Thanks. Could you please explain in more detail how this works? Also, is there no simpler and more intuitive way to accomplish the same effect? – Evan Aad Aug 08 '17 at 16:16
  • 1
    it allows you to see a following token { which you can not grab as #1 , you could use \futurelet but no one has ever called \futurelet intuitive. – David Carlisle Aug 08 '17 at 16:22
  • @DavidCarlisle: How do you know that the following token will be an opening brace? Could you please explain in more detail how this works? Also, how would an equivalent futurelet expression look like? – Evan Aad Aug 08 '17 at 16:25
  • no you don't know it is a following brace but using \let rather than #1 means that if the following text is {abc} you just grab the { not the whole group (see my answer) – David Carlisle Aug 08 '17 at 16:39

2 Answers2

10

It is similar to \futurelet in that it \let s the command name to the following token (ignoring one optional space) but unlike \futurelet it consumes the token

enter image description here

\documentclass{article}


\def\zza{\afterassignment\zzx\let\tmp=}
\def\zzb{\futurelet\tmp\zzx}
\def\zzc#1{\def\tmp{#1}\zzx}

\def\zzx{[tmp is \texttt{\meaning\tmp}] }


\begin{document}

A \zza xyz

B \zzb xyz

C \zzc xyz


A \zza {xyz

B \zzb {xyz}

C \zzc {xyz}

\end{document}

Note that the constructs A and B both use \let so "see" the following { whereas C which uses a macro argument "sees" the entire brace group. A though removes the token from the input so x only appears once, and there needs to be no matching } for the {, however using \zzb with \futurelet leaves the token in the input stream (so x appears twice and you need a matching } as the { does start a group as well as being assigned to \tmp.

David Carlisle
  • 757,742
1

I just want to complement David's answer with an explanation of the purpose this construct serves in the context of the macro listed in the original post.

When a

\path<body>

statement is encountered at the beginning of the input stream inside a TikZ environment, it is rewritten as

\tikz@scan@next@command <body>

\tikz@scan@next@command then assigns <body>'s first token to \pgf@let@token, and the last expression is rewritten as

\tikz@handle <body tail>

where <body tail> is obtained from <body> by deleting <body>'s first token.

\tikz@handle is a long switch statement that dispatches an appropriate handler based on the value of \pgf@let@token, so based on <body>'s first token.

Every handler gobbles down a chunk from the beginning of the input stream, processes it, and finally repositions \tikz@scan@next@command at the beginning of the reduced input stream:

\tikz@scan@next@command <reduced body>

where <reduced body> is what remains of <body tail> after the handler has bitten off a chunk from its head.

Thus \tikz@scan@next@command serves as a forward-moving cursor that is advanced by the handlers, and points to the current position in the input stream. The token this cursor is pointing at determines which handler will be dispatched next.

In these terms what the line

\afterassignment\tikz@handle\let\pgf@let@token=

does is removing the token at the cursor's position from the input stream, and assigning this token to \pgf@let@token.

Evan Aad
  • 11,066