命令以逗号分隔命令

命令以逗号分隔命令

我正在尝试创建一个名为的命令\newcscommand,它允许我定义用逗号分隔的值的命令。

以下是我目前所掌握的信息

\documentclass{article}
\usepackage{xparse}

\newcommand{\newcscommand}[3]{
  \NewDocumentCommand{ #1 }{ >{\SplitArgument{#2 - 1}{,}}m }{\csname aux\endcsname##1} % the auxiliary command should be named 'auxtest' instead of just aux
  \newcommand{\aux}[#2]{#3} % same here
}

\newcscommand{\test}{3}{#1 is #2 a #3.}
\begin{document}
\test{This, just, test}
\end{document}

我使用辅助命令来拆分逗号分隔的列表,该命令应称为“aux +命令的名称',然而我无法让它工作,所以我把它保留为 MWE 中的“aux”,这当然是错误的,因为如果我调用newcscommand两次,我会收到错误。

我知道我必须csnameendcsname某种方式使用,但我还没有弄清楚。

我怎样才能让它工作?有没有我不知道的完全不同且更好的方法可以做到这一点?

答案1

你的想法很好,但是正确的expl3编程更好:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\newcscommand}{mO{0}m}
 {
  \NewDocumentCommand{#1}{ >{\SplitArgument{#2-1}{,}}m }
    {
     \use:c { __noibe_\cs_to_str:N #1:\prg_replicate:nn{#2}{n} } ##1
    }
  \cs_new:cn { __noibe_\cs_to_str:N #1:\prg_replicate:nn{#2}{n} } { #3 }
 }

\ExplSyntaxOff

\newcscommand{\test}[3]{#1 is #2 a #3.}

\begin{document}

\test{This, just, test}

\end{document}

请注意,的语法\newcscommand类似于\newcommand

诀窍确实是创建一个在签名中具有正确数量参数的宏。

一种避免每次执行调用\use:c和的变体,因为控制序列名称是在定义时构建的。\prg_replicate:nn\test\exp_not:c

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\newcscommand}{mO{0}m}
 {
  \exp_args:Nnne \NewDocumentCommand{#1}{ >{\SplitArgument{#2-1}{,}}m }
   {
    \exp_not:c { __noibe_\cs_to_str:N #1:\prg_replicate:nn{#2}{n} } ##1
   }
  \cs_new:cn { __noibe_\cs_to_str:N #1:\prg_replicate:nn{#2}{n} } { #3 }
}
\exp_args_generate:n { nne }

\ExplSyntaxOff

\newcscommand{\test}[3]{#1 is #2 a #3.}

\begin{document}

\test{This, just, test}

\end{document}

答案2

这不会检查列表长度,但可以做到这一点。同样,可以将参数添加到\foreachitem循环中。

\documentclass{article}
\usepackage{listofitems}
\newcommand\test[1]{%
  \readlist*\mylist{#1}%
  \mylist[1] is \mylist[2] a \mylist[3].
}
\begin{document}
\test{This, just, test}
\end{document}

在此处输入图片描述

这是一个示例,其中参数的数量可能会有所不同,但需要考虑到:

\documentclass{article}
\usepackage{listofitems}
\newcommand\test[1]{%
  \readlist*\mylist{#1}%
  There are \mylistlen{} arguments:
  \foreachitem \z \in \mylist[]{\ifnum\zcnt=1\relax\else, \fi(\zcnt) \z}.
}
\begin{document}
\test{This, just, test}

\test{This, just, test, today, Hallelujah}
\end{document}

在此处输入图片描述

答案3

我最终明白了:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\newcommand{\newcscommand}[3]{
  \NewDocumentCommand{ #1 }{ >{\SplitArgument{#2 - 1}{,}}m }{\csname aux\cs_to_str:N #1\endcsname##1}
  \expandafter\newcommand\csname aux\cs_to_str:N #1\endcsname[#2]{#3}
}

\ExplSyntaxOff

\newcscommand{\test}{3}{#1 is #2 a #3.}
\begin{document}
\test{This, just, test}
\end{document}

相关内容