我想知道如何创建一个宏,该宏可以将新元素/项附加到宏列表(标记列表),但也可以添加{
并}
围绕每个添加的项目。
例子我希望它像这样保存每个新项目:
\appendtocslist{tokenlist}{newitem}
{newitem}
列表中的收益。
为什么因为我可以轻松地用 解析列表\readcslist
。
我不确定是否还需要用逗号(或其他分隔符)分隔每个值。
附加到命令序列 (CS) 列表
- 如果不存在任何宏,则足够智能地启动一个新的宏。
- 它使用 csname 来允许动态宏名称。
- 它目前使用尾随逗号字符作为分隔符/定界符。
代码
\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
}%
代码
\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
}%
\long\def\readcslist#1{%
\@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.
\@ifnextchar\bgroup{\recursivecycle}{\advance\@tempcnta1\finalcall}% \@ifnextchar ignores spaces
}
\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
\advance\@tempcnta by 1% add one for next arg
\@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}
\readcslist{d}{e}{f}
% \expandafter\readargs\expandafter{\mylist} % wouldn't this be nice!%
\end{document}
答案1
\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)
\long\def\readcslist#1{%
\@tempcnta=1
\checknextarg
}
\long\def\checknextarg{%
\@ifnextchar\bgroup{\recursivecycle}{\finalcall}%
}
\long\def\recursivecycle#1{%
\advance\@tempcnta by 1 % add one for next arg
\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}
\readcslist{d}{e}{f}
\expandafter\readcslist\mylist
\end{document}
答案2
回答这个问题“我想知道如何创建一个宏,该宏可以将新元素/项目附加到宏列表(标记列表),但还会在每个添加的项目周围添加 { 和 }。”
\documentclass{article}
\usepackage[T1]{fontenc}
\newtoks\mylist
\newcommand\addtotoklist[2]{#1\expandafter{\the#1{#2}}}
\begin{document}
\addtotoklist\mylist{a}
\addtotoklist\mylist{b}
\addtotoklist\mylist{cde}
\detokenize\expandafter{\the\mylist}
\end{document}