当我研究 finl 的解析器时,我正在考虑如何处理命令参数,并想知道我当前的设置是否足够。
目前,参数的类型要么是解析文本,要么是解析数学。考虑一下大多数命令,参数总是被视为其中之一,例如,有一些简单情况,例如\mathrm
的参数总是被视为数学,而\textrm
的参数总是被视为文本(对于\sqrt
、\section
和大多数其他命令也是如此)。
显然,用户可以轻松地执行以下操作:
\NewDocumentCommand{\foo}{ m }{#1}
这是一个很简单的情况,参数将按照其上下文要求的方式进行处理,但一般来说,这种上下文感知的参数处理有实际应用吗?
答案1
核心发行版中的一个例子是,\textcolor
它可能不是最好的设计,但不像\textsf
\textcolor
不强制执行文本模式,所以
\textcolor{red}{a+b} $\textcolor{red}{a+b}$
将第一个 a+b 设置为文本,将第二个设置为数学。不过我认为这不是一个值得效仿的好例子。
请注意,这实际上就像您的简单\foo
示例一样,它不会主动测试数学,而只是允许参数失败。
答案2
正如用户 ABC 在评论中所说,\tikzmarknode
tikzmark 包中的命令在环境模式下设置其内容。它首先测试我们是否处于数学模式,然后使用它\mathchoice
来选择正确的样式。目的是让它对用户透明,有点像你的\foo
命令,但因为它必须将其参数放在一个框中,所以它在内部必须稍微复杂一些。\subnode
来自同一包的命令也做同样的事情。
答案3
有些命令会根据单独的命令切换其预期输入。例如,stackengine
包定义了命令\stackText
和\stackMath
切换所有堆叠命令的输入(默认为文本)。
梅威瑟:
\documentclass{article}
\usepackage{stackengine}
\begin{document}
\stackunder{a}{b} \stackunder{$a$}{$b$} $\stackunder{a}{b}$
% $\stackon{\alpha}{\beta}$ % error
\vspace{5mm}
\stackMath
\stackunder{a}{b} \stackunder{$a$}{$b$} \stackunder{\alpha}{\beta} $\stackunder{a}{b} \stackunder{\alpha}{\beta}$
% \stackunder{$\alpha$}{$\beta$} % error
\end{document}
结果:
请注意,有点令人惊讶的是,\stackunder{$a$}{$b$}
after\stackMath
是在文本模式下排版的,因为\stackMath
在参数中添加了一层数学模式,从而抵消了现有的数学模式。事实上,在这种模式下\stackunder{$\alpha$}{$\beta$}
会导致错误。
另一个例子来自评论\underline
:
\underline{a+b} \underline{$\alpha+\beta$} $\underline{a+b} \underline{\alpha+\beta}$
全部有效,其中参数a+b
在数学模式内排版为数学,在数学模式外排版为文本。