附加到命令序列 (CS) 列表

附加到命令序列 (CS) 列表

我想知道如何创建一个宏,该宏可以将新元素/项附加到宏列表(标记列表),但也可以添加{}围绕每个添加的项目。

例子我希望它像这样保存每个新项目:

\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}

在此处输入图片描述

相关内容