# How can I automatically surround each new item in a token list with braces as delimiters?

I'd like to know how to create a macro that can append new elements/items to a macro list (token list) BUT also adds { and } around each added item.

Example I'd like it to save each new item like this:

\appendtocslist{tokenlist}{newitem}


yields {newitem} in the list.

Why Because I can easily parse the list with \readcslist.

I am not sure if also separating each value with a comma (or some other separator) is necessary.

# Append to Command Sequence (CS) List

• Smart enough to initiate a new macro if none exist iwth does not exist.
• It uses csname to allow for dynamic macro names.
• It currently uses a trailing comma character , as a separator/delimiter.

Code

\long\def\appendtocslist#1#2{% #1 = List ID (no backslash) #2=New Item to Append
% I chose this complicated csname form of the list-making because it can accept dynamic csnames using counters
\expandafter\ifx\csname#1\endcsname\relax\expandafter\xdef\csname#1\endcsname{#2,}\else% Macro Existence Check
\expandafter\xdef\csname#1\expandafter\expandafter\expandafter\endcsname
\expandafter\expandafter\expandafter
{\csname #1\endcsname#2,}\fi%Append expansion of #1 with #2, delimit with ,. ^^J appears as newline in terminal or space when typeset and does not work as a delimiter
}%


# Code

\documentclass{article}
\usepackage{fontspec}% xelatex

\makeatletter

\long\def\appendtocslist#1#2{% #1 = List ID (no backslash) #2=New Item to Append
% I chose this complicated csname form of the list-making because it can accept dynamic csnames using counters
\expandafter\ifx\csname#1\endcsname\relax\expandafter\xdef\csname#1\endcsname{#2,}\else% Macro Existence Check
\expandafter\xdef\csname#1\expandafter\expandafter\expandafter\endcsname
\expandafter\expandafter\expandafter
{\csname #1\endcsname#2,}\fi%Append expansion of #1 with #2, delimit with ,. ^^J appears as newline in terminal or space when typeset and does not work as a delimiter
}%

\@tempcnta=1%
\checknextarg%
}
\long\def\checknextarg{%
% My job is to check for another arg and trigger a recursive cycle.
% for \@ifnextchar to check, so we say \bgroup, which means literal {
% I am only important if there are exactly two args.
}
\long\def\recursivecycle#1{%
% My job is to eat each argument recursively until I
% cannot find any more { characters. I ignore spaces.
% If I reach the end, I run whatever is in false area of \@ifnextchar
\@ifnextchar\bgroup{\recursivecycle}{\finalcall}}
\def\finalcall{Total n of args: \the\@tempcnta}
\makeatother
\begin{document}
Hello.
\appendtocslist{mylist}{a}
\appendtocslist{mylist}{b}
\appendtocslist{mylist}{c}

% \expandafter\readargs\expandafter{\mylist} % wouldn't this be nice!%

\end{document}

• Do you want also the comma? – egreg Feb 1 '18 at 15:03
• @egreg Glad you asked first. What do you recommend from your knowledge of dealing with these things? Is it necessary if I have everything surrounded in braces for future manipulation e.g. element extraction or prepending/appending new elements? – Jonathan Komar Feb 1 '18 at 15:03
• I would avoid to reinvent the wheel and use expl3. And definitely not absorb items until no more { are found. This is very dangerous and useless: \readcslist{{a}{b}{c}} is much simpler and safer. – egreg Feb 1 '18 at 15:08
• @egreg I was trying to avoid expl3, not to undermind the project or your efforts. – Jonathan Komar Feb 1 '18 at 15:13
• What's the connection between \appendtocslist and \readcslist? I see none. – egreg Feb 1 '18 at 15:14

\documentclass{article}

\makeatletter
% syntactic sugar
\def\expandtwice{\unexpanded\expandafter\expandafter\expandafter}
% append to list (or create it)
\newcommand\appendtocslist[2]{%
% #1 = Macro Name without \ (list name), #2=New Item to Append
\ifcsname#1\endcsname
\expandafter\xdef\csname#1\endcsname{%
% the previous items
\expandtwice{\csname#1\endcsname}%
% the new item
{#2}%
}%
\else
% the list doesn't exist yet, create it
\expandafter\gdef\csname#1\endcsname{{#2}}
\fi
}
% read n-argument types (ignoring spaces)
\@tempcnta=1
\checknextarg
}
\long\def\checknextarg{%
\@ifnextchar\bgroup{\recursivecycle}{\finalcall}%
}
\long\def\recursivecycle#1{%
\checknextarg
}
\def\finalcall{Total n of args: \the\@tempcnta}
\makeatother
\begin{document}
Hello.
\appendtocslist{mylist}{a}
\appendtocslist{mylist}{b}
\appendtocslist{mylist}{c}

\texttt{\expandafter\meaning\csname mylist\endcsname}

\end{document}


• I just realized that \xdef should be \protected@xdef to maintain the effect of \protect when appending things like \textit or \textbf. Obviously, you used my minimal example, but I wanted to note this here for posterity. – Jonathan Komar Feb 28 '18 at 14:49
• @JonathanKomar Yes, that would be necessary if #2 contains “dangerous” items. – egreg Feb 28 '18 at 17:31

In response to the question "I'd like to know how to create a macro that can append new elements/items to a macro list (token list) BUT also adds { and } around each added item."

\documentclass{article}
\usepackage[T1]{fontenc}
\newtoks\mylist

• Good stuff. I think it helps to know that this is shortened form of \newcommand\addtotoklist[2]{#1=\expandafter{\the#1{#2}}} . In other words, skip ahead to expand the list as it is first, then put #2 after it, then the whole line of junk (tokens) will be assigned to #1. – Jonathan Komar Feb 3 '18 at 17:15