![在纯 TeX 中创建具有可变数量的逗号分隔参数的宏?](https://linux22.com/image/450483/%E5%9C%A8%E7%BA%AF%20TeX%20%E4%B8%AD%E5%88%9B%E5%BB%BA%E5%85%B7%E6%9C%89%E5%8F%AF%E5%8F%98%E6%95%B0%E9%87%8F%E7%9A%84%E9%80%97%E5%8F%B7%E5%88%86%E9%9A%94%E5%8F%82%E6%95%B0%E7%9A%84%E5%AE%8F%EF%BC%9F.png)
我希望创建两个宏:一个接受已知数字,另一个接受未知数量的逗号分隔的参数并对其进行处理。之前已经有几个关于这个问题的答案,请参阅(这里和这里),但他们总是使用现代的 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
。参数在第一次调用中#1
是a
(因为它以逗号分隔),然后是b
,cxy
然后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
。