根据逗号分隔列表调用命令

根据逗号分隔列表调用命令

我有几个命令,称为\catato \catd。现在我需要一个命令,它循环遍历给定的逗号分隔列表,并调用相应的命令。我目前的方法是:

\documentclass[10pt,a4paper]{article}
\usepackage[latin1]{inputenc}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{graphicx}
\usepackage{tikz}
\newcommand{\cata}{Hello a\newline}
\newcommand{\catb}{Hello b\newline}
\newcommand{\catc}{Hello c\newline}
\newcommand{\catd}{Hello d\newline}
\newcommand{\cat}[1]{%
\expandafter\newcommand\csname cat#1\endcsname%
}
\newcommand{\loopover}[1]{
\foreach \i in {#1}{
    \cat\i}
}
\begin{document}

Hello World\\
\loopover{a, b, c, d}
\end{document}

我的预期输出是:

Hello World
Hello a
Hello b
Hello c
Hello d

如果我改为\loopover{a,b,c,d}\loopover{a,a,c}我想得到这个

Hello World
Hello a
Hello a
Hello c

到目前为止,我得到了错误LaTeX Error: Command \cata already defined.,这是有道理的。还有其他方法可以实现我的目的吗?
编辑:我想在之后扩展命令,因此当前的情况可能有点误导。我想让命令\cata自行调用,而不是重写它。

最终的应用程序如下所示:

\documentclass[10pt,a4paper]{article}
\usepackage[latin1]{inputenc}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{graphicx}
\usepackage{tikz}
\usepackage{tocloft}
\newcommand{\lista}{List a}
\newcommand{\listb}{List b}
\newcommand{\listc}{List c}
\newcommand{\listd}{List d}
\newlistof{cata}{expa}{\lista}
\newlistof{catb}{expb}{\listb}
\newlistof{catc}{expc}{\listc}
\newlistof{catd}{expd}{\listd}
\newcommand{\cata}[1]{%
    \refstepcounter{cata}
    \par\noindent\textbf{cata \thecata. #1}
    \addcontentsline{expa}{cata}
    {\protect\numberline{\thechapter.\thecata}#1}\par
}
\newcommand{\catb}[1]{%
    \refstepcounter{catb}
    \par\noindent\textbf{catb \thecatb. #1}
    \addcontentsline{expb}{catb}
    {\protect\numberline{\thechapter.\thecatb}#1}\par
}
\newcommand{\catc}[1]{%
    \refstepcounter{catc}
    \par\noindent\textbf{catc \thecatc. #1}
    \addcontentsline{expc}{catc}
    {\protect\numberline{\thechapter.\thecatc}#1}\par
}
\newcommand{\catd}[1]{%
    \refstepcounter{catd}
    \par\noindent\textbf{catd \thecatd. #1}
    \addcontentsline{expd}{catd}
    {\protect\numberline{\thechapter.\thecatd}#1}\par
}

\newcommand{\cat}[2]{%
\expandafter\newcommand\csname cat#1\endcsname{#2}%
}
\newcommand{\loopover}[2]{
\foreach \i in {#1}{
    \cat\i{#2}}
}
\begin{document}
\tableofcontents
\newpage
\lista\newline
\listb\newline
\listc\newline
\listd\newline
\chapter{TestA}
\cat{a,b}{Test}
\end{document}

我想循环给{a,b}定的列表\cat,并调用相应的命令以添加{Test}到该内容表中。

答案1

目前还不清楚为什么\cat<x>每次都要重新定义:

\documentclass[10pt,a4paper]{article}

\usepackage{tikz} % \foreach
\newcommand{\cata}{Hello a\newline}
\newcommand{\catb}{Hello b\newline}
\newcommand{\catc}{Hello c\newline}
\newcommand{\catd}{Hello d\newline}
\newcommand{\loopover}[1]{%
  \foreach \i in {#1}{\csname cat\i\endcsname}%
}
\begin{document}

\noindent
Hello World\\
\loopover{a, b, c, d}
\loopover{a, a, c}

\end{document}

在此处输入图片描述

一个简单的实现xparse

\documentclass[10pt,a4paper]{article}

\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\loopover}{m}
 {
  \clist_map_inline:nn { #1 } { \use:c { cat ##1 } }
 }
\ExplSyntaxOff

\newcommand{\cata}{Hello a\newline}
\newcommand{\catb}{Hello b\newline}
\newcommand{\catc}{Hello c\newline}
\newcommand{\catd}{Hello d\newline}

\begin{document}

\noindent
Hello World\\
\loopover{a, b, c, d}
\loopover{a, a, c}

\end{document}

这具有几个优点\foreach:例如,它会自动修剪逗号分隔列表中项目周围的空格,并且不会隐藏组中的循环周期。

\clist_map_inline:nn是循环制作功能\use:c及其expl3术语\csname...\endcsname


更新

更复杂的代码属于同一解决方案。只需定义

 \newcommand{\loopover}[2]{%
   \foreach \x in {#1}{\csname cat\x\endcsname{#2}}%
 }

这没有问题:如果\xa,则\cata标记形成并且它会{#2}像往常一样吸收参数。

答案2

不确定您的示例是否只是一个更复杂用例的示例。但就您的问题而言,您可以使用xparsedescription环境。

输出

在此处输入图片描述

代码

\documentclass{article}
\usepackage{enumitem}
\usepackage{xparse}

\setlist[description]{itemsep=.3\baselineskip, font=\normalfont}

\NewDocumentCommand\mylist{>{\SplitList{,}}m}
  {
    \begin{description}
      \ProcessList{#1}{ \insertl }
    \end{description}
  }
\newcommand\insertl[1]{\item[Hello] #1}

\begin{document}
\noindent 
Hello world \par

\mylist{
    a, b, c, d
}%

\end{document}

相关内容