3

This syntax evaluate={...} is documented on page 704/1318 of the math library . I'm quoting from the manual:

/tikz/evaluate=<statements> (no default) This key simply executes \tikzmath{<statements>}.

example page

The following sections describe the miniature language that this library provides and can be used in the \tikzmath command and the evaluate key. The language consists only of simple keywords and expressions but the mini-parser allows you to format code in a reasonably versatile way (much like the tikz parser) except that all the keywords must be followed by at least one space. This is the second most important thing to remember (after remembering to insert semi-colons at the end of every statement).

And yet it works within a foreach loop without the need to load the math library.

Many answers here use the syntax evaluate={...} within a foreach loop instead of using the syntax documented on page 1003/1318 of the manual, which is I recall:

/pgf/foreach/evaluate=<variable> as <macro> using <formula>

For example here, Peter Grill uses it here.

The manual shows its use on page 1045/1318 to illustrate the macro

\pgfmathtodigitlist{<macro>}{<number>}

with this code:

\documentclass[margin=2mm,tikz]{standalone}
\begin{document}

\pgfmathsetbasenumberlength{8} \begin{tikzpicture}[x=0.25cm, y=0.25cm] \foreach \n [count=\y] in {0, 60, 102, 102, 126, 102, 102, 102, 0}{ \pgfmathdectobase{\binary}{\n}{2} \pgfmathtodigitlist{\digitlist}{\binary} \foreach \digit [count=\x, evaluate={\c=\digit*50+15;}] in \digitlist \fill [fill=black!\c] (\x, -\y) rectangle ++(1,1); } \end{tikzpicture} \end{document}

that produces this result

page 1045

  • Why does this syntax evaluate={...}, which is defined (unless I am mistaken) in the math library, work without this library being loaded in a foreach loop?

Translated with www.DeepL.com/Translator (free version)

AndréC
  • 24,137
  • strange you've not got any answer... Have you tried https://topanswers.xyz/tex ? Marmot will know. – JeT Aug 05 '20 at 20:41
  • No, it is not strange, to answer this question, it is necessary to dive into the TikZ source code. And for that, you need time. – AndréC Aug 05 '20 at 20:50
  • 2
    These two evaluate are different things. In tikzlibrarymath.code.tex, there is \tikzset{evaluate/.code={\tikz@math{#1}}}. And in pgffor.code.tex, there is evaluate/.code=\pgffor@assign@evaluatetrue\pgffor@assign@oncefalse\pgffor@assign@parse{#1}, so statements of two evaluate are actually processed in different ways. But as you say, to explain clearly need dive deeper into the source code. – ZhiyuanLck Aug 11 '20 at 07:50

1 Answers1

4

/pgf/foreach/evaluate is coded in pgffor.code.tex and is irrelavant with tikz library math.

From the code

evaluate/.code=\pgffor@assign@evaluatetrue\pgffor@assign@oncefalse\pgffor@assign@parse{#1}

you can see statements of evaluate are processed by \pgffor@assign@parse

\def\pgffor@assign@parse#1{%
    \pgfutil@in@;{#1}%
    \ifpgfutil@in@%
    \else%
        \pgfutil@in@={#1}%
    \fi%
    \ifpgfutil@in@%
        \pgffor@assign@@parse#1;\pgffor@stop;%
    \else%
        \pgffor@assign@parse@old#1\pgffor@stop%%
    \fi%
}

If there is a ; in the argument, the parser is \pgffor@assign@@parse, otherwise \pgffor@assign@parse@old which corresponds to the syntax /pgf/foreach/evaluate=<variable> as <macro> using <formula>.

In \pgffor@assign@@parse, \pgffor@assign@@@parse with different arguments is invoked according to whether there is a = in the statement.

\def\pgffor@assign@@parse#1;{%
    \def\pgffor@test{#1}%
    \ifx\pgffor@test\pgffor@stop%
        \let\pgffor@next=\relax%
    \else%
        \let\pgffor@next=\pgffor@assign@@parse%
        \ifx\pgffor@test\pgfutil@empty%
        \else%
            \pgfutil@in@={#1}%
            \ifpgfutil@in@%
                \pgffor@assign@@@parse#1\pgffor@stop%
            \else%
                \pgffor@assign@@@parse#1=#1\pgffor@stop%
            \fi%
        \fi%
    \fi%
    \pgffor@next}

\def\pgffor@assign@@@parse#1=#2\pgffor@stop{% \ifpgffor@assign@evaluate% \ifpgffor@assign@once% \pgfutil@append@tomacro{\pgffor@assign@once@code}{\pgfmathparse{#2}\let#1=\pgfmathresult}% \pgfutil@append@tomacro{\pgffor@remember@once@code}{\noexpand\def\noexpand#1{#2}}% \else \pgfutil@append@tomacro{\pgffor@assign@before@code}{\pgfmathparse{#2}\let#1=\pgfmathresult}% \fi% \else% \ifpgffor@assign@once% \pgfutil@append@tomacro{\pgffor@assign@once@code}{\def#1{#2}}% \pgfutil@append@tomacro{\pgffor@remember@once@code}{\noexpand\def\noexpand#1{#2}}% \else \pgfutil@append@tomacro{\pgffor@assign@before@code}{\def#1{#2}}% \fi% \fi% }

ZhiyuanLck
  • 4,516
  • +1 Very nice ! From this source code, is it possible for you to document the syntax of this evaluate{}? Are there any differences with that of the math library? – AndréC Aug 11 '20 at 09:28