I'm trying to set up a program in order to iterate over a list of elements formatted like [number1][content1][number2][content2]
. The following code is a minimal not working example: (in real code the variable \@list
would be defined inputting a whole file).
\documentclass[a4paper,11pt]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[italian]{babel}
\makeatletter
\newif\ifendlist%
\endlistfalse%
\errorcontextlines 10000
\tracingmacros5
\def\@list{[1][A string][1][Another string][2][Yet another one]}
\def\@grabnextelement[#1][#2]{%
\gdef\@elementnumber{#1}%
\gdef\@elementcontent{#2}%
}
\def\@nextelement{%
\@ifnextchar[\@grabnextelement\endlisttrue%
}
\def\@advancelist{%
\expandafter\protected@xdef\expandafter\@list{\expandafter\@nextelement\@list}%
}
\def\printlist{%
\loop\unless\ifendlist%
\@advancelist%
\@elementnumber \hskip 1.5em \@elementcontent
\repeat%
}
\makeatother
\begin{document}
\printlist%
\end{document}
I don't understand why, if I try to execute the above code, I get an error:
! Argument of \reserved@a has an extra }.
<inserted text>
\par
<to be read again>
}
\iterate ->\unless \ifendlist \@advancelist
\@elementnumber \hskip 1.5em \@e...
\loop ...elax \expandafter \iterate \fi }\iterate
\let \iterate \relax
l.38 \printlist
%
I'm not a TeX wizard, but I tried to protect all edef and xdef.
Can someone point out what is happening here?
More informations about the expansions:
\printlist ->\loop \unless \ifendlist \@advancelist \@elementnumber \hskip 1.5em \@elementcontent \par \repeat
\loop #1\repeat ->\def \iterate {#1\relax \expandafter \iterate \fi }\iterate \let \iterate \relax
#1<-\unless \ifendlist \@advancelist \@elementnumber \hskip 1.5em \@elementcontent \par
\iterate ->\unless \ifendlist \@advancelist \@elementnumber \hskip 1.5em \@elementcontent \par \relax \expandafter \iterate \fi
\@advancelist ->\expandafter \protected@xdef \expandafter \@list {\expandafter \@nextelement \@list }
\protected@xdef ->\let \@@protect \protect \let \protect \@unexpandable@protect \afterassignment \restore@protect \xdef
\@list ->[1][A string][1][Another string][2][Yet another one]
\@nextelement ->\@ifnextchar [\@grabnextelement \endlisttrue
\@ifnextchar #1#2#3->\let \reserved@d =#1\def \reserved@a {#2}\def \reserved@b {#3}\futurelet \@let@token \@ifnch
#1<-[
#2<-\@grabnextelement
#3<-\endlisttrue
\reserved@a #10#2{->\expandafter \def \expandafter \it@ccap \reserved@b #10{
I do see there is some odd thing going on with \reserved@a
, but I don't realize how it could be solved and why it is happening.
Best Answer
You can't use
\@ifnextchar
in a\protected@xdef
as it doesn't work via expansion however do you need the loop and definitions at all, as opposed to simply evaluating the list?