我在想,因为 LaTeX 的架构是 TeX 之上的预处理器的集合,所以某些宏在理论上可以在它们收到的内容的参数中执行某种查找和替换操作。
动机:我们有很多数学环境。如果可以扫描输入中是否存在某些元素,那么其中很多都可以统一为一个。例如:如果环境sequation
未检测到宏,则为无编号环境;如果环境看到带有可选换行符的不平衡长方程,则为\label
多行环境;如果环境看到多个模式或类似情况,则为无编号环境。breqn
align
split
= &
问题:是否可以编写这样的宏/环境?如果可以,我该怎么做?
尝试解决方案:我有一种强烈的怀疑,认为这个cleveref
包里有一些有趣的东西。问题是它也有很多引用语义,而且可能只能查找 cleveref 特有的东西,而这些东西对我想要做的事情来说没那么有用。
答案1
etoolbox
提供允许您在 内\patchcmd{<cmd>}{<search>}{<replace>}{<success>}{<failure>}
搜索并将其替换为。它还允许分支替换结果是否为或。我在下面使用了这种方法:<search>
<cmd>
<replace>
<success>
<failure>
\documentclass{article}
\usepackage{environ,etoolbox}
\usepackage{amsmath}
% Generic math display
\NewEnviron{mathenvironment}{%
% \patchcmd{<cmd>}{<search>}{<replace>}{<success>}{<failure>}
\patchcmd{\BODY}
{\label}% Search for \label
{\label}% If found, replace with \label
{% \label is present
\patchcmd{\BODY}
{&}% Search for &
{&}% If found, replace with &
{% \label and & is present
\begin{align}
\BODY
\end{align}
}{% \label is present, but & is not
\begin{equation}
\BODY
\end{equation}
}%
}
{% \label is not present
\[
\BODY
\]
}
}
\begin{document}
\begin{mathenvironment}
f(x) = a x^2 + b x + c
\end{mathenvironment}
\begin{mathenvironment}
f(x) = a x^2 + b x + c \label{eqn:quadratic-1}
\end{mathenvironment}
\begin{mathenvironment}
f(x) &= a_1 x^2 + b_1 x + c_1 \label{eqn:quadratic-2} \\
g(y) &= a_2 y^2 + b_2 y + c_2 \label{eqn:quadratic-3}
\end{mathenvironment}
\end{document}
的整个主体mathenvironment
被捕获在 内\BODY
,然后进行修补以识别存在(或不存在)的元素并进行相应的条件处理。如果需要,您可以嵌套这些元素以查看元素的组合并进行相应的条件处理。
请注意,\patchcmd
正在寻找明确的匹配,因此不会找到任何隐式内容(例如搜索\test
,例如,其中\test
是 中宏的扩展/替换文本的一部分mathenvironment
)。因此,如果您有宏作为搜索项的替换,它将失败。
如果您要搜索多个案例,并排除某些案例,最好使用正则表达式来识别要作为条件的模式,而不是将内容嵌套在里面\patchcmd
。使用 LaTeX3 可能会更好地处理这些正则表达式。