对电子工具箱列表中第一个和/或最后一个项目的特殊处理

对电子工具箱列表中第一个和/或最后一个项目的特殊处理

etoolbox有没有一种简单的方法可以以特殊方式处理基于 的列表中的第一个和/或最后一个项目?这是一个简单的例子:

\documentclass{article}

\usepackage{etoolbox}

\begin{document}

\forcsvlist{\listadd\namelist}{Tom, Dick, Harry, Jack}

\renewcommand*{\do}[1]{; #1}
\dolistloop{\namelist}

\renewcommand*{\do}[1]{#1, }
\dolistloop{\namelist}

\end{document}

输出为

; 汤姆; 迪克; 哈利; 杰克

汤姆、迪克、哈利、杰克,

我将如何改变上述代码来创建输出

汤姆;迪克;哈利;杰克

汤姆、迪克、哈利和杰克

如果可以将第一项的格式定义为 简单 ,#1而将其余项的格式定义为 ,则第一个输出将很容易实现。如果可以将除第一个项和最后一个项之外; #1的所有项的格式定义为 ,则第二个输出将很容易实现。, #1#1and #1

请注意,我正在寻找etoolbox列表的解决方案,而不是其他列表结构。

答案1

对于第一个问题,我会定义\do在条目前面加上\process,其初始含义只是将其自身重新定义为所需的分隔符:

\newcommand{\semicolonlist}[1]{%
  \def\process{\def\process{; }}%
  \def\do##1{\process##1}%
  \dolistloop{#1}}

\semicolonlist\namelist

对于第二个问题,可以处理列表一次以获取元素的数量,然后在第二遍中使用该信息:

\newcommand{\commaorandlist}[1]{%
  \count255=0
  \def\do##1{\advance\count255 1 \chardef\finalitem=\count255 }%
  \dolistloop{#1}%
  \count255=0
  \def\do##1{\advance\count255 1
    \ifnum\count255=\finalitem
      \space and\space
    \else
      \ifnum\count255=1
      \else
    ,\space
      \fi
    \fi##1}
  \dolistloop{#1}}

\commaorandlist\namelist    

这些命令打印列表;如果您需要在可扩展的上下文中使用它们,您可以这样做,比如说\commaorandlist

\newcommand{\xcommaorandlist}[2]{%
  \count255=0
  \def\do##1{\advance\count255 1 \chardef\finalitem=\count255 }%
  \dolistloop{#1}%
  \count255=0
  \toks0={}% 
  \def\do##1{\advance\count255 1
    \edef\next{%
      \ifnum\count255=\finalitem
    \space and\space
      \else
        \ifnum\count255=1
        \else
          ,\space
        \fi
      \fi
    }
    \toks2={##1}%

    \edef\next{\the\toks0 \next \the\toks2}%
    \toks0=\expandafter{\next}%
  }%
  \dolistloop{#1}%
  \edef#2{\the\toks0 }%
}

然后调用

\xcommaorandlist\namelist\finallist
\hypersetup{pdfauthor={\finallist}}

答案2

这里有一个简单的解决方案,它也计算列表,并使用计数器来定位列表内的最后一个元素:

\documentclass{article}

\usepackage{etoolbox}

\begin{document}
\newcounter{elementcount}
\forcsvlist{\stepcounter{elementcount}\listadd\namelist}{Tom, Dick, Harry, Jack}

\number\value{elementcount}:
\def\do#1{%
 \ifnumequal{\value{elementcount}}{1}{%
  #1}{\addtocounter{elementcount}{-1}#1,~}%   
}
\dolistloop{\namelist}

\end{document}

相关内容