如何处理通过命令传递的逗号分隔列表

如何处理通过命令传递的逗号分隔列表

当传递逗号分隔的列表时,逗号会被忽略,即列表变成单个项目,我似乎找不到阻止这种情况的方法。我应该怎么做才能使附加代码中的 TEST C 实现“提取”列表中项目的预期结果?

\documentclass{article}
\usepackage{pgffor}
\newcommand{\setstr}[2]{\expandafter\def\csname#1\endcsname{#2}}
\newcommand{\getstr}[1]{\csname#1\endcsname}
\newcommand{\PROCESS}[1]
{
The list items are:
 \foreach \i in {#1}
 {
   (\i)
 }
}
\newcommand{\SETC}[2]{\setstr{C#1}{#2}}
\newcommand{\RUN}[1]{
\expandafter\PROCESS\expandafter{\getstr{C#1}}
}
\begin{document}
%
% The following works
%
\noindent{TEST A:}
\PROCESS{a,b,c,d}
\newline
%
% and the following also works
%
\noindent{TEST B:}
\newcommand{\A}{a,b,c,d}
\expandafter\PROCESS\expandafter{\A}
\newline
%
% but this  does not work
%
\noindent{TEST C:}
\SETC{1}{a,b,c,d}%
\RUN{1}%
\newline
\end{document}

答案1

正如 Qrrbrbirlbel 在评论中所说,这是一个扩展问题;\getstr需要三个扩展步骤,而不仅仅是一个。

\documentclass{article}
\usepackage{pgffor}
\newcommand{\setstr}[2]{\expandafter\def\csname#1\endcsname{#2}}
\newcommand{\getstr}[1]{\csname#1\endcsname}
\newcommand{\PROCESS}[1]{%
The list items are:
 \foreach \i in {#1}
 {%
   (\i)
 }%
}
\newcommand{\SETC}[2]{\setstr{C#1}{#2}}
\makeatletter
\newcommand{\RUN}[1]{%
  \begingroup\protected@edef\x{\endgroup\protect\PROCESS{\getstr{C#1}}}\x
}
\makeatother

\begin{document}
%
% The following works
%
\noindent{TEST A:}
\PROCESS{a,b,c,d}

%
% and the following also works
%
\newcommand{\A}{a,b,c,d}

\noindent{TEST B:}
\expandafter\PROCESS\expandafter{\A}

%
% also this works
%
\SETC{1}{a,b,c,d}

\noindent{TEST C:}
\RUN{1}

\end{document}

在此处输入图片描述

稍微不同的方法可以更好地保留逗号分隔列表的结构。

\documentclass{article}
\usepackage{pgffor}
\newcommand{\setstr}[2]{\expandafter\def\csname#1\endcsname{\unexpanded{#2}}}
\newcommand{\getstr}[1]{\csname#1\endcsname}
\newcommand{\PROCESS}[1]{%
The list items are:
 \foreach \i in {#1}
 {%
   (\i)
 }%
}
\newcommand{\SETC}[2]{\setstr{C#1}{#2}}
\newcommand{\RUN}[1]{%
  \begingroup\edef\x{\endgroup
  \noexpand\PROCESS{\getstr{C#1}}}\x
}
\begin{document}
%
% The following works
%
\noindent{TEST A:}
\PROCESS{a,b,c,d}

%
% and the following also works
%
\newcommand{\A}{a,b,c,d}

\noindent{TEST B:}
\expandafter\PROCESS\expandafter{\A}

%
% also this works
%
\SETC{1}{a,b,c,\textbf{d}}

\noindent{TEST C:}
\RUN{1}

\getstr{C1}

\end{document}

答案2

虽然 OP 可能只对 LaTeX 解决方案感兴趣,但在这里我将提供一个 ConTeXt 解决方案。

该命令\processcommacommand有两个参数。第一个参数是逗号分隔的列表,可以是宏,第二个参数是用于处理列表项的宏。示例:

\define[1]\doprocess
  {(#1)}

\define\somelist
  {foo, bar, baz}

\starttext
  \processcommacommand
    [alpha, \math{\beta}, gamma]
    \doprocess

  \processcommacommand
    [\somelist]
    \doprocess

  \expandafter\processcommacommand\expandafter
    [\somelist]
    \doprocess
\stoptext

截屏

相关内容