定义宏,扫描上标和/或下标,“吸收”它们并移动它们的参数

定义宏,扫描上标和/或下标,“吸收”它们并移动它们的参数

我有很多数学宏,根据定义,它们已经有上标和/或下标,例如

\newcommand*{\mymathsym}{x^{\text{foo}}_{\text{bar}}}

在正文中,这些符号经常需要额外的上下标。这意味着,作者必须记住将主符号放在一对 {} 括号中,否则会出现双重上下标错误。

\begin{equation}
  {\mymathsym}^{\text{extra}}
\end{equation}

额外的上标变成了次要上标,并且设置得稍微高一点、小一点: 额外的上标 这有两个缺点:a) 在特殊的应用领域中,从概念的角度来看,两个上标都处于同一层次。换句话说,两个上标实际上都应该打印为列表“foo,extra”,而相反的顺序“extra,foo”同样好。b) 如果主上标和下标的长度非常不平衡,则次要上标设置得相距很远,例如

\newcommand*{\mymathsymlong}{x^{\text{foo}}_{\text{very long foobar}}}

\begin{equation}
{\mymathsymlong}^{\text{extra}}
\end{equation}

产量 相距较远的上标

作为一种解决方法,我目前使用以下定义,它采用可选参数并将该参数附加到内部上标:

\newcommand*{\mymathsymext}[1][]{x^{\text{foo}\if!#1!\else, #1\fi}_{\text{very long foobar}}}

(注意:我知道条件\if!#1!不是测试空参数的正确方法,因为如果参数扩展为,它就会失败!。但我想你明白宏的作用了。)

它用作

\begin{equation}
\mymathsymext \qquad\text{vs.}\qquad \mymathsymext[\text{extra}]
\end{equation}

并得出 在此处输入图片描述 然而,这有两个主要缺点:a)\newcommand仅支持单个可选参数。因此,我需要在设计时决定最终是否需要额外的上标或额外的下标。我无法同时支持两者。b) 用户必须记住放置额外上标/下标的不寻常语法。

问题:

如何定义一个\mymathsymsuper

  • 向前扫描,如果它后面跟着一个上标字符^<tok> 和/或下标字符_<tok>,并且每个字符后面都跟着一个附加标记 <tok>
  • “吸收它们”,并且
  • 将 <tok> 移动到其内部 sup-/subscript 的末尾,以逗号分隔?

完整 MWE:

\documentclass{article}

\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage[utf8]{inputenc}
\usepackage{amsmath}

\newcommand*{\mymathsym}{x^{\text{foo}}_{\text{bar}}}

\newcommand*{\mymathsymlong}{x^{\text{foo}}_{\text{very long foobar}}}

\newcommand*{\mymathsymext}[1][]{x^{\text{foo}\if!#1!\else, #1\fi}_{\text{very long foobar}}}

\begin{document}

Here, the author must know that \verb#\mymathsym# has already a super- and subscript and must remember to put the main symbol into a pair of \{\}-braces, otherwise a double sup-/subscript error occurs.
The extra superscript becomes a secondary superscript and it set slightly higher and smaller:
\begin{equation}
{\mymathsym}^{\text{extra}}
\end{equation}

If the primary sup- and subscript are very unbalanced in their length, the secondary subscript is set very far apart:
\begin{equation}
{\mymathsymlong}^{\text{extra}}
\end{equation}

This extended macro takes an optional argument and ``absorbs'' the extra superscript into the primary superscript:
\begin{equation}
\mymathsymext \qquad\text{vs.}\qquad \mymathsymext[\text{extra}]
\end{equation}
Still, the author must remember this ``unusual'' syntax and it only supports either an extra super- or subscript, bot not both.

\paragraph{Question:}
How does one define a macro \verb#\mymathsymsuper# that
\begin{itemize}
  \item scans ahead if it followed by a superscript character $\verb!^!\langle \mathit{token}_\text{sup}\rangle$ and/or subscript character $\verb!_!\langle \mathit{token}_\text{sub}\rangle$ each followed by an    additional token $\mathit{token}_\text{sup}$ and $\mathit{token}_\text{sub}$ resp.
  \item ``absorbs them'', and
  \item moves $\mathit{token}_\text{sup}$ and/or $\mathit{token}_\text{sub}$ to end of its internal sup-/subscript separated by a comma?
\end{itemize}

\end{document}

答案1

这很简单xparse

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}

\NewDocumentCommand{\mymathsym}{e{^_}}{%
  x^{\mathrm{foo}\IfValueT{#1}{,#1}}_{\mathrm{bar}\IfValueT{#2}{,#2}}%
}

\begin{document}

\begin{gather}
\mymathsym \\
\mymathsym^{\mathrm{extrasup}} \\
\mymathsym_{\mathrm{extrasub}} \\
\mymathsym^{\mathrm{extrasup}}_{\mathrm{extrasub}} \\
\mymathsym_{\mathrm{extrasub}}^{\mathrm{extrasup}}   
\end{gather}

\end{document}

在此处输入图片描述

使用e{^_}宏可以预先查找^_(以任意顺序)并将#1上标分配给#2下标。您可以测试是否存在\IfValueT\IfValueTF如果您想对不存在的下标/上标执行某些操作,可以使用或)。

相关内容