From 33aff2d593d60382ba6f85c9753502fc4c206f4a Mon Sep 17 00:00:00 2001 From: Andrew Stacey Date: Fri, 12 Apr 2024 21:06:17 +0100 Subject: [PATCH] Patches TikZ's foreach to remember more information between iterations This commit adds more information to what TikZ remembers between foreach iterations, and does so in a way that makes it easier to add other macros and dimensions to the list of things it remembers, both at the code level and via keys. Fixes #356, #1047, #1303, #1313 Signed-off-by: Andrew Stacey --- doc/generic/pgf/CHANGELOG.md | 1 + .../pgf/frontendlayer/tikz/tikz.code.tex | 78 +++++++++++++++---- 2 files changed, 63 insertions(+), 16 deletions(-) diff --git a/doc/generic/pgf/CHANGELOG.md b/doc/generic/pgf/CHANGELOG.md index d27a1ab42..67b5ace4b 100644 --- a/doc/generic/pgf/CHANGELOG.md +++ b/doc/generic/pgf/CHANGELOG.md @@ -12,6 +12,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Fixed +- Foreach in path remembers nodes between iterations #356, #1047, #1303, #1313 - Typo in animations `end on` key #1273 - Output bounding box adjustment in pgfsys-dvisvgm.def #1275 - Fix shadings under LuaMetaTeX diff --git a/tex/generic/pgf/frontendlayer/tikz/tikz.code.tex b/tex/generic/pgf/frontendlayer/tikz/tikz.code.tex index d9b1743b9..31d260c02 100644 --- a/tex/generic/pgf/frontendlayer/tikz/tikz.code.tex +++ b/tex/generic/pgf/frontendlayer/tikz/tikz.code.tex @@ -2580,28 +2580,77 @@ \def\tikz@fchar oreach{\tikz@foreach}% +% +% These are to allow \foreach to remember macros and dimensions between iterations +% + +\def\tikzforeach@smugglers@cove{} +\let\tikztostart=\relax + +\def\tikzforeach@smuggle@macro#1{% + \pgfutil@ifx#1\relax{}{% + \expandafter + \pgfutil@g@addto@macro + \expandafter + \tikzforeach@smugglers@cove + \expandafter + {% + \expandafter\def\expandafter#1\expandafter{#1}% + }% + }% +} + +\def\tikzforeach@smuggle@dimen#1{% + \pgfutil@ifx#1\relax{}{% + \expandafter + \pgfutil@g@addto@macro + \expandafter + \tikzforeach@smugglers@cove + \expandafter + {% + \expandafter#1\expandafter=\the#1\relax% + }% + }% +} + +\def\tikzforeach@smugglers@loot{% + % + \tikzforeach@smuggle@macro\tikz@moveto@waiting% + \tikzforeach@smuggle@macro\tikztostart% + \tikzforeach@smuggle@macro\tikz@tangent% + % + \tikzforeach@smuggle@dimen\tikz@lastx% + \tikzforeach@smuggle@dimen\tikz@lasty% + \tikzforeach@smuggle@dimen\tikz@lastxsaved% + \tikzforeach@smuggle@dimen\tikz@lastysaved% + % +} + +\tikzset{ + remember macro/.code={ + \tikzforeach@smuggle@macro#1 + }, + remember dimension/.code={ + \tikzforeach@smuggle@dimen#1 + } +} + + \def\tikz@foreach{% \def\pgffor@beginhook{% - \tikz@lastx=\tikz@foreach@save@lastx% - \tikz@lasty=\tikz@foreach@save@lasty% - \tikz@lastxsaved=\tikz@foreach@save@lastxsaved% - \tikz@lastysaved=\tikz@foreach@save@lastysaved% + \tikzforeach@smugglers@cove% + \gdef\tikzforeach@smugglers@cove{}% \setbox\tikz@figbox=\box\tikz@tempbox% \setbox\tikz@figbox@bg=\box\tikz@tempbox@bg% \expandafter\tikz@scan@next@command\pgfutil@firstofone}% \def\pgffor@endhook{\pgfextra{% - \xdef\tikz@foreach@save@lastx{\the\tikz@lastx}% - \xdef\tikz@foreach@save@lasty{\the\tikz@lasty}% - \xdef\tikz@foreach@save@lastxsaved{\the\tikz@lastxsaved}% - \xdef\tikz@foreach@save@lastysaved{\the\tikz@lastysaved}% + \tikzforeach@smugglers@loot% \global\setbox\tikz@tempbox=\box\tikz@figbox% \global\setbox\tikz@tempbox@bg=\box\tikz@figbox@bg% \pgfutil@gobble}}% \def\pgffor@afterhook{% - \tikz@lastx=\tikz@foreach@save@lastx% - \tikz@lasty=\tikz@foreach@save@lasty% - \tikz@lastxsaved=\tikz@foreach@save@lastxsaved% - \tikz@lastysaved=\tikz@foreach@save@lastysaved% + \tikzforeach@smugglers@cove% + \gdef\tikzforeach@smugglers@cove{}% \let\pgffor@beginhook\relax% \let\pgffor@endhook\relax% \let\pgffor@afterhook\relax% @@ -2610,10 +2659,7 @@ \tikz@scan@next@command}% \global\setbox\tikz@tempbox=\box\tikz@figbox% \global\setbox\tikz@tempbox@bg=\box\tikz@figbox@bg% - \xdef\tikz@foreach@save@lastx{\the\tikz@lastx}% - \xdef\tikz@foreach@save@lasty{\the\tikz@lasty}% - \xdef\tikz@foreach@save@lastxsaved{\the\tikz@lastxsaved}% - \xdef\tikz@foreach@save@lastysaved{\the\tikz@lastysaved}% + \tikzforeach@smugglers@loot% \foreach}%