尝试构建更智能(上下文敏感)的宏

尝试构建更智能(上下文敏感)的宏

我想建立一个宏,可以正确识别调用它的上下文,并根据上下文适当地设置模式和字体大小。

昨天我开始构建一个宏,在点名称上绘制一个弧形符号。 但后来我意识到它不知道自己是否在数学模式中被调用。所以我决定添加这样的功能。

当然,我必须想办法打破它。所以这里的例子只是我发现的宏似乎不知道其正确上下文的几个例子。

这是MWE:

\documentclass{article}
\usepackage{amsmath,amssymb}
\usepackage{tikz}

\makeatletter

\newsavebox\ae@frown@box
\begin{lrbox}{\ae@frown@box}
  \begin{tikzpicture}
    %% to not have unwanted white space being added to the height
    \begin{pgfinterruptboundingbox}
      \path[fill] (0,0) to [out=50,in=130] 
                  (2,0) to [out=150,in=30] 
                  cycle;
    \end{pgfinterruptboundingbox}
    %% to give my "box" some kind of width and height.
    \path (0,0) -- (2,0.45);
  %%  \draw[red] (current bounding box.north east) rectangle (current bounding box.south west);
  \end{tikzpicture}
\end{lrbox}

\def\ae@frown{\usebox{\ae@frown@box}}
\let\aefrown\ae@frown
\newsavebox\ae@tmp@box
\newcommand\arc[1]{%
  \begingroup
  \ifmmode
    \ifinner
      \sbox\ae@tmp@box{$#1$}%%
    \else
      \sbox\ae@tmp@box{$\displaystyle#1$}%%
    \fi
  \else\sbox\ae@tmp@box{#1}%%
  \fi
  \ooalign{%%
    \raisebox{\ht\ae@tmp@box}{%%
      \resizebox{\wd\ae@tmp@box}{!}{%%
        \ae@frown}}%%
    \cr
    \usebox{\ae@tmp@box}}%%
  \endgroup
    }

\makeatother

\pagestyle{empty}
\setlength{\parskip}{2ex}
\setlength{\parindent}{0pt}
\begin{document}

Gallia est omnis divisa in partes tres, quarum unam incolunt Belgae,
aliam Aquitani, tertiam qui ipsorum lingua Celtae, nostra Galli
appellantur. Hi omnes lingua, institutis, legibus inter se differunt.

In-line style: $ \int_0^2 x^2\mathrm{d}x   \text{  vs  }   \arc{\int_0^2 x^2\mathrm{d}x} $

Displaystyle I:
\[
  \int_0^2 x^2\mathrm{d}x
  \text{  vs  }
  \arc{\int_0^2 x^2\mathrm{d}x}
\]

Displaystyle invoked from within in-line style:
$\displaystyle 
  \int_0^2 x^2\mathrm{d}x
  \text{  vs  }
  \arc{\int_0^2 x^2\mathrm{d}x}
$

Displaystyle within \verb=align=
\begin{align*}
  y &=\int_0^2 x^2      \mathrm{d}x
  \intertext{  vs  }
  y &=\arc{\int_0^2 x^2 \mathrm{d}x}
\end{align*}

\end{document}

在此处输入图片描述

我没想到我的宏会忽略\displaystyle开关。这促使我在环境中对其进行测试align*。我知道的其他上下文是分数的分子/分母和字体大小缩放的上标/下标:我不知道如何测试其中任何一个。

所以我有一堆看起来非常密切相关的问题:

  • 我如何让我的宏知道何时使用\displaystyle?例如,当我使用开关时,\displaystyle我希望我的宏能够识别它,但目前它不能。
  • 测试模式后,我是否正确设置了模式?换句话说,如果我发现自己不再处于内联数学模式,我是否应该\displaystyle切换模式样式,或者是否有更好的方法?
  • 我如何测试我是否处于分数或上标/下标中?

我知道一般人不赞成在一条帖子中发布多个问题,但这些问题似乎联系非常紧密,所以把它们放在一起比分开更有意义。但是,如果社区希望我将它们分开发布,我一定会编辑我的问题并这样做。

最后,我并不真正关心这个特定宏的视觉美感。这是一个纯粹的教育练习。我不打算电弧我的积分!

答案1

所有这些问题的答案基本上都是:你不能。这一切都是为了支持原始\over语法,这意味着 TeX 在执行命令时不知道最终会进入什么模式。

这就是为什么有\mathchoice将命令 4 次设置为 4 个内部框的原因,使用所有 4 种样式显示文本脚本和脚本脚本和之后TeX 根据所需的样式选择其中一个框。

此外,除非您在对齐单元格的开头使用或 etex ,否则\ifmmode无法可靠地告诉您处于数学模式,否则在诸如或之类的环境中,当 Tex 正在寻找时它将扩展为 false,即使不存在并且单元格启动数学模式也将由对齐模板插入启动。\DeclareRobustCommand\protected\defalignarray\omit\omit$

相关内容