在纯 TeX 中创建具有可变数量的逗号分隔参数的宏?

在纯 TeX 中创建具有可变数量的逗号分隔参数的宏?

我希望创建两个宏:一个接受已知数字,另一个接受未知数量的逗号分隔的参数并对其进行处理。之前已经有几个关于这个问题的答案,请参阅(这里这里),但他们总是使用现代的 LaTeX 软件包,例如xparse。例如,我可以通过以下方式创建一个新的分数命令(已知参数数量)

\ExplSyntaxOn
\makeatletter
    \def\numargs{2}
    \NewDocumentCommand{\frc}{>{\SplitArgument{\numargs-1}{,}}m}{\@frc@#1}
    \NewDocumentCommand{\@frc@}{mm}{\frac{#1}{#2}}
\makeatother
\ExplSyntaxOff

并将其与 一起使用\frc{1,2},实际上与 相同\frac{1}{2}。另一个示例是使用 创建粗体列表(参数数量未知)

\ExplSyntaxOn
\NewDocumentCommand{\bflist}{m}{\clist_map_inline:nn{#1}{\@bflist@{##1}}}
\newcommand{\@bflist@}[1]{\bf #1}
\ExplSyntaxOff

并将其与\bflist{a, b, c, d, e, f}等一起使用,这将创建粗体列表ABCDEF这两种解决方案都使用现代 LaTeX 工具;我想知道,有没有办法在纯 TeX 中创建这些命令?或者至少,在不使用外部包的情况下在 LaTeX 中创建这些命令?

答案1

使用 Plain TeX 的解决方案非常简单(或者更准确地说:仅使用 TeX 原始命令)

% fixed number of args:
\def\frc#1{\frcA#1\end}
\def\frcA#1,#2\end{{#1\over #2}}

test: $\frc{a,b}$

% unknown number of args:
\def\boldlist#1{\boldlistA #1,\end,}
\def\boldlistA #1#2,{%
   \ifx\end#1\else {\bf#1#2}\expandafter \boldlistA\fi
}

test: \boldlist{a, b, c, d, e, f}

\bye

请注意,\boldlistA使用第一个不分隔的参数#1,然后使用第二个分隔的参数#2,以便删除逗号后的空格。我们不需要在\frc宏中执行此操作,因为它适用于 TeX 忽略空格的数学模式。

第二个例子更详细:假设语法:\boldlist{a,b,cxy,d}逗号后没有空格。然后我们可以定义:

\def\boldlist#1{\boldlistA #1,\end,}
\def\boldlistA #1,{%
   \ifx\end#1\else {\bf#1}\expandafter \boldlistA\fi
}

这是 的递归调用\boldlistA。参数在第一次调用中#1a(因为它以逗号分隔),然后是bcxy然后d是 ,最后是\end。测试\ifx\end#1停止此递归。

如果您想在参数前(逗号后)使用可选空格,但又想忽略它们,即它们\boldlist{a, b, cxy,d}\boldlistA分隔#1#1是第一个非空格标记,TeX 会忽略空格。#2用逗号分隔。在第一种情况下它是空的:#1=a,,#2=empty在第二种情况下它是空的#1=b,它前面的空格被忽略,,#2=empty但在第三种情况下它不为空:#1=c,它前面的空格被忽略,#2=xy

相关内容