列表的全局定义

列表的全局定义

我在网上找到了某种列表,并让它按预期工作。命令“addtoaliste”正在向列表“aliste”添加一个参数。它由 newcommands 定义,因此我无法让它在 enumerate 等环境中工作,因为任何更改都只能在本地完成。

我将尝试更改我实施的列表,使其与全局定义 (gdef) 配合使用。但首先是我的“命令代码”:

\documentclass{scrartcl}
\usepackage{ifthen}

\newcommand{\aliste}[1]{\empty}
\def\zaliste#1\relax{\def\aliste##1{#1}}
\newcommand{\addtoaliste}[1]{%
    \ifthenelse{\equal{\aliste{}}{}}{
    \expandafter\zaliste\aliste{##1}#1\relax}
    {\expandafter\zaliste\aliste{##1},#1\relax}
}

\begin{document}
    Value: \aliste{}\\ %Returns empty list
    \addtoaliste{1}
    Value: \aliste{} %Returns 1
    \begin{enumerate}
        \item First Point. 
        \addtoaliste{2}
    \end{enumerate}
    Value: \aliste{} %shall return 1,2, but still returns 1
\end{document}

我尝试了一些更改并得到以下结果,但它仍然没有按预期工作:

\documentclass{scrartcl}
\usepackage{ifthen}

\gdef\aliste#1{}
\gdef\zaliste#1{\relax{\gdef\aliste##1{#1}}}
\gdef\addtoaliste#1{%
    \ifthenelse{\equal{\aliste{}}{}}{
    \expandafter\zaliste\aliste{##1}#1\relax}
    {\expandafter\zaliste\aliste{##1},#1\relax}
}

\begin{document}
Value: \aliste{}\\ %Returns empty list
\addtoaliste{1}
Value: \aliste{}\\ %Returns 1
\begin{enumerate}
    \item First Point. 
    \addtoaliste{2}
\end{enumerate}
Value: \aliste{}
\end{document}

答案1

使用\gdef不会真正改变代码:\gdef意味着“全局定义”,但宏内的代码应该进行全局定义。所以

\def\zaliste#1\relax{\gdef\aliste##1{#1}}

将是解决方案,只要宏开始起作用,但事实并非如此。

问题在于

\def\zaliste#1{\relax{\gdef\aliste##1{#1}}}

一副额外的牙套会毁掉一切:应该是

\def\zaliste#1\relax{\gdef\aliste##1{#1}}

因此参数被 界定\relax。事实上

\documentclass{scrartcl}
\usepackage{ifthen}

\def\aliste#1{}
\def\zaliste#1\relax{\gdef\aliste##1{#1}}
\def\addtoaliste#1{%
    \ifthenelse{\equal{\aliste{}}{}}{%
    \expandafter\zaliste\aliste{##1}#1\relax}%
    {\expandafter\zaliste\aliste{##1},#1\relax}%
}

\begin{document}

Value: \aliste{} %Returns empty list

\addtoaliste{1}
Value: \aliste{} %Returns 1

\begin{enumerate}
    \item First Point.
    \addtoaliste{2}
\end{enumerate}
Value: \aliste{}

\end{document}

生产

在此处输入图片描述

我不确定你为什么\aliste要用参数来定义,这只会让事情变得复杂。在下面,我还改为\gdef以便\xdef扩展值,以防你想使用类似的东西\addtoalist{\arabic{enumi}}

\documentclass{scrartcl}
\usepackage{ifthen}

\def\aliste{}
\def\zaliste#1\relax{\xdef\aliste{#1}} % \xdef for full expansion
\def\addtoaliste#1{%
  \ifthenelse{\equal{\aliste}{}}{%
    \expandafter\zaliste\aliste#1\relax
  }{\expandafter\zaliste\aliste,#1\relax
  }%
}

\begin{document}

Value: \aliste %Returns empty list

\addtoaliste{1}
Value: \aliste %Returns 1

\begin{enumerate}
    \item First Point.
    \addtoaliste{2}
\end{enumerate}
Value: \aliste

\end{document}

将产生完全相同的结果。

我建议采用一种不同的方法,它可以支持您想要的任意数量的列表。

\documentclass{scrartcl}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\startlist}{m}
 {
  \clist_clear_new:c { g_wuagh_list_#1_clist }
 }
\NewDocumentCommand{\addtolist}{mm}
 {
  % add the item
  \clist_gput_right:cx { g_wuagh_list_#1_clist } { #2 }
 }
\NewExpandableDocumentCommand{\uselist}{om}
 {
  \IfNoValueTF { #1 }
   {
    \clist_use:cn { g_wuagh_list_#2_clist } { , }
   }
   {
    \clist_item:cn { g_wuagh_list_#2_clist } { #1 }
   }
 }
\ExplSyntaxOff

\startlist{a}

\begin{document}

Value: \uselist{a} %Returns empty list

\addtolist{a}{A}
Value: \uselist{a} %Returns 1

\begin{enumerate}
    \item First Point.\addtolist{a}{\arabic{enumi}}
    \item Second Point.\addtolist{a}{\arabic{enumi}}
\end{enumerate}
Value: \uselist{a}

Item: \uselist[1]{a} % returns A

Item: \uselist[2]{a} % returns 1


\end{document}

在此处输入图片描述

如您所见,您还可以通过索引访问列表项。

答案2

您可以使用etoolbox为您管理列表(添加和处理/打印):

在此处输入图片描述

\documentclass{article}

\usepackage{etoolbox}

% https://tex.stackexchange.com/a/89187/5764
% \printlist[<separator>]{<list>}
\newcommand{\printlist}[2][,]{%
  \def\itemdelim{\def\itemdelim{#1}}% Item delimiter delayed by one cycle
  \renewcommand*{\do}[1]{\itemdelim##1}% How each item is processed
  \dolistcsloop{#2}}% Process CSV list
\newcommand{\addtoaliste}{\listcsgadd{aliste}}

\begin{document}

Value: \printlist{aliste} % Returns empty list

\addtoaliste{1}

Value: \printlist{aliste} % Returns 1
\begin{enumerate}
  \item First Point. 
  \addtoaliste{2}
\end{enumerate}
Value: \printlist{aliste} % Returns 1,2

\end{document}

列表打印使用狡猾的 (La)TeX 技巧

相关内容