I'm not getting the output I want from my LaTeX code, and I think the problem is that I'm not expanding things at the right times.
Code
\documentclass{article}
\usepackage{tikz}
\usepackage{etextools}
\makeatletter
% The result of calling
% \@defineLine{foo}{35}
% is that the command \wickerson@foo@pos gets defined as 35.
\newcommand*\@defineLine[2]{%
\typeout{Defining wickerson@#1@pos = #2}
\expandafter\xdef\csname wickerson@##1@pos\endcsname{#2}
}
% Project the pos-field from the line with the given
% identifier. For instance, if \wickerson@foo@pos=35 then
% \@getLinePos{foo}
% will give 35.
\xdef\@getLinePos#1{\csname wickerson@#1@pos\endcsname}
% A comma-separated list of "active" lines. Each element is
% a line identifier.
\newcommand*\@activeLines{}
% Add the given identifier to the list of active lines.
\newcommand*\@addToActiveLines[1]{%
\ifx\@activeLines\@empty\else\g@addto@macro\@activeLines{,}\fi
\g@addto@macro\@activeLines{#1}
}
% Remove the given identifier from the list of active lines.
\newcommand*\@removeFromActiveLines[1]{%
\@expandtwoargs\@removeelement{#1}\@activeLines\@activeLines
}
% Print each active line identifier, associated with its
% corresponding pos field. Typical output:
% {a ↦ 10, b ↦ 30, c ↦ 50, d ↦ 70,}
\newcommand*\@printState{%
Current state: $\{
\foreach\i in \@activeLines {%
\i \mapsto \@getLinePos\i,
}
\}$ \par
}
\begin{document}
\foreach \x/\xvalue in {a/10, b/30, c/50, d/70} {
\ExpandNextTwo\@defineLine{\x}{\xvalue}
\ExpandNext\@addToActiveLines{\x}
\@printState
}
\foreach \x in {a, c} {
\ExpandNext\@removeFromActiveLines{\x}
\@printState
}
\end{document}
Explanation
The first foreach-loop cycles over a list of pairs, building up a function from identifiers (e.g. a
,b
,etc.) to numbers. The values of this function are stored in a series of macros (e.g. \wickerson@a@pos
stores the value of the function for identifier a
), and the domain of this function is the comma-separated list \@activeLines
. Initially \@activeLines
is empty, and by the end it is a,b,c,d
.
I print my function after each iteration of the loop. By the end I expect to print
{a↦10, b↦30, c↦50, d↦70}
but instead it prints
{a↦70, b↦70, c↦70, d↦70}
I suspect the problem is when I add a mapping to my function, I'm not expanding the value enough, and so it changes when I add another mapping. I thought using ExpandNextTwo
from etextools
would expand everything nicely, but it doesn't seem to have helped. Any ideas?
The second foreach-loop tries to remove some of the mappings from my function, with the help of the \@removeelement
command. Unfortunately, it doesn't work. The mapping is only removed within the scope of the current loop iteration, and by the next iteration, the mapping has returned. I suspect the problem is that the \@removeelement
is not redefining \@activeLines
globally, but I don't know how to fix this. Any ideas? (I hope I don't need to switch to the expl3
syntax to achieve this, because that would be require quite a drastic change to my code!)