…的参数有一个额外的},递归宏

…的参数有一个额外的},递归宏

注意:这(不幸的是)不是一个简单的“修复匹配的括号”问题,请阅读整个问题。

我正在编写一个命令来修复间距\vec——默认情况下间距太小,导致与箭头和以下字形发生冲突,例如(\vec p)。但是,只需重新定义命令,如

\makeatletter
\let\oldvec\vec
\def\vec#1{\oldvec{#1}\@ifnextchar{^}{\kern 1pt}{}}
\makeatother

在向量同时具有上标的情况下不起作用下标。因此,需要一个递归处理即将到来的上标和下标的命令。

目前,我正在使用以下解决方案(针对 Stix/Times 进行了优化,因此在 Computer Modern 中可能看起来不太好)。但是,包含单个命令(该命令带有一个参数)的下标将失败,除非原子被括在括号中(例如\vec a_\textup{max}不起作用,\vec a_{\textup{max}}并且\vec a_\pi起作用)。

梅威瑟:

\documentclass{article}

\makeatletter
\let\oldvec\vec
\def\vec#1{\oldvec{#1}\vec@}
\def\vec@{%
    \@ifnextchar{_}{\vec@sub}{%
    \@ifnextchar{^}{\vec@sup}{{\kern 0.5pt}}}%
}%
\def\vec@sub#1#2{_{\kern -0.75pt #2}\vec@}
\def\vec@sup#1#2{^{\kern 2pt #2}\vec@}
\makeatother

\begin{document}
% works
\[ \vec s_{\textrm{max}} \]

% doesn't work
\[ \vec s_\textrm{max} \]
\end{document}

错误代码:

! Argument of \textrm  has an extra }.
<inserted text>
                \par
l.16 \[ \vec s_\textrm
                      {max} \]

\vec@sub我认为这与在给出参数之前结束一个组的and命令有关\vec@sup(以便解析器看到{\vec{a}_\textrm}{a}或出现某些情况并感到恐慌),但我不完全确定如何解决这个问题。

全面披露:此代码是“改编的”(即几乎完全复制)这个答案@siracusa 撰写,它涉及的 TeX 代码肯定比我通常的技能水平要高一些。我读过我能找到的等等\@ifnextchar,但我对这里涉及的所有元素并不是 100% 确定。

感谢您帮助解决这个奇怪的问题!

答案1

使用原始下标的工作方式_\textrm{a}是原始行为的一个不幸的副作用。使用宏参数很难支持这一点,而且无论如何都是不正确的 latex 语法,因此最好只是记录它不受支持,就像这里使用宏的其他包一样,例如 breqn 或 tex4ht 等。

事实上,它之所以能起作用,是因为它是一个 tex 基元而不是宏,还取决于和类似命令(扩展为单个括号组)_的内部细节。例如,外表相似的构造不起作用,并且需要。\textrmx_\fbox{a}x_{\fbox{a}}

如果_将其制成宏,那么它(很可能)会失去查找隐藏在宏内的括号的能力。如果_使用而不是\fbox\textrm{x},那么您将获得与所示基本相同的错误,因为\fbox会得到只是 \textrm作为参数。正确的标记是\fbox{\textrm{a}}

相关内容