\docsvlist 不适用于宏形式的列表

\docsvlist 不适用于宏形式的列表

在下面的代码中,我尝试了三种方法来构建一个 csv 列表(从 1 到 5 的自然数序列)。

然后我使用\docsvlist(from etoolbox) 来包装列表的每个元素parentheses

所有这些尝试都失败了(请参阅代码)。为什么以及如何使它们按预期工作?

代碼:

\documentclass{article}
\usepackage{etoolbox}

\renewcommand{\do}[1]{(#1)}

% Method 1 to build a csv list
\def\aaa{1,2,3,4,5}

% Method 2 to build a csv list
\def\bbb{%
\newcount\foo
\foo=1
\loop
\ifnum \foo=5 5\else%
\the\foo,%
\advance \foo 1%
\repeat}

% Method 3 to build a csv list
\NewDocumentCommand\SequenceOfNaturalNumbers{mO{,}m}{%
  %{#1-start number},[#2-dilimiter],{#3-end number}
  \ifnum#1=#3 #3%
  \else%
  #1#2\SequenceOfNaturalNumbers{\number\numexpr #1+1}[#2]{#3}%
  \fi%
}
\def\ccc{\SequenceOfNaturalNumbers{1}{5}}

\begin{document}
% Code 1: 
\expandafter\docsvlist\expandafter{\aaa}\\
Q1: typeset 12345, not desired (1)(2)(3)(4)(5), why?
\bigskip

% Code 2:
bbb is : \bbb\\ %typeset 1,2,3,4,5 as expected
\docsvlist\bbb\\ %typeset 1,2,3,4,5, not desired (1)(2)(3)(4)(5)
\expandafter\docsvlist\expandafter{\bbb}\\ %This causes error
Q2: What's wrong with the above line of code?
\bigskip

% Code 3:
ccc is: \ccc\\ %typeset 1,2,3,4,5 as expected
\expandafter\docsvlist\expandafter{\ccc}\\
Q3: Why does the above line of code typeset 1,2,3,4,5, not desired (1)(2)(3)(4)(5)
\end{document}

答案1

该问题与宏无关:简单宏\docsvlist{a,b,c}也会以同样的方式失败:

\documentclass{article}
\usepackage{etoolbox}



% Method 1 to build a csv list
\def\aaa{1,2,3,4,5}

% Method 2 to build a csv list
\def\bbb{%
\newcount\foo % would be better outside
\foo=1
\loop
\ifnum \foo=5 5\else%
\the\foo,%
\advance \foo 1 % space before % needed
\repeat}

% Method 3 to build a csv list
\NewDocumentCommand\SequenceOfNaturalNumbers{mO{,}m}{%
  %{#1-start number},[#2-dilimiter],{#3-end number}
  \ifnum#1=#3 #3%
  \else%
  #1#2\SequenceOfNaturalNumbers{\number\numexpr #1+1}[#2]{#3}%
  \fi%
}
\def\ccc{\SequenceOfNaturalNumbers{1}{5}}

\begin{document}
%\renewcommand{\do}[1]{(#1)}
\docsvlist{a, b, c}

% Code 1: 
\expandafter\docsvlist\expandafter{\aaa}\\
Q1: typeset 12345, not desired (1)(2)(3)(4)(5), why?
\bigskip

\end{document}

\do是用于所有类型列表处理的核心 latex 命令,在任意位置(和 中\begin{document})重新定义,因此只有在处理之前立即设置时才能使用它\do。取消注释 的定义\do,您将看到两个列表都有效。

\expandafter\docsvlist\expandafter{\ccc}

\docsvlist{\SequenceOfNaturalNumbers{1}{5}}

这无法工作,\docsvlist需要,在参数中。


LaTeX 内置了用于映射逗号列表的函数,使这一过程变得更加容易

在此处输入图片描述

\documentclass{article}
% no package needed

\ExplSyntaxOn
\let\listmap\clist_map_inline:nn
\let\listvarmap\clist_map_inline:Nn
\cs_generate_variant:Nn \clist_map_inline:nn {e }
\let\listexpmap\clist_map_inline:en
\let\intmap\int_step_inline:nnnn
\let\addtolist\clist_put_right:Nn
\ExplSyntaxOff

\begin{document}

% map over a list
\listmap{aa,bb,cc}{(#1)}

% list in variable
\def\aaa{11,22,33}

% map over the variable's value
\listvarmap\aaa{(#1)}

% expand to a list, then map
\listexpmap{www,xx,\aaa,zz}{(#1)}

% Numeric loop
% {<start>} {<step>} {<end>} {<code>}
\intmap{5}{1}{10}{(#1)}

% you almost certainly don't need this, build list first
\edef\bbb{}
\intmap{8}{-2}{0}{\addtolist\bbb{item#1}}
\listvarmap\bbb{(#1)}

\end{document}

相关内容