使用参数前先展开

使用参数前先展开

这个问题是我试图解决主要问题(MWE 在那里)。

我意识到使用宏

\newcommand{\veca}{|_{\vec{a}}}

next to\bigg被视为单个 token,因此这两个查询具有相同的输出

\bigg\veca
\bigg{|_{\vec{a}}}

在此处输入图片描述

我不知道如何定义\veca它首先被扩展的方式,所以我尝试重新定义,\bigg以便第二个参数总是扩展一次

我查阅了一下,amsmath.sty发现所有\big\Big、都是使用 定义的:\bigg\Bigg\bBigg@

\renewcommand{\big}{\bBigg@\@ne}
\renewcommand{\Big}{\bBigg@{1.5}}
\renewcommand{\bigg}{\bBigg@\tw@}
\renewcommand{\Bigg}{\bBigg@{2.5}}
\ifx\leavevmode@ifvmode\@undefined
\def\bBigg@#1#2{%
  {\@mathmeasure\z@{\nulldelimiterspace\z@}%
     {\left#2\vcenter to#1\big@size{}\right.}%
   \box\z@}}
\else
\def\bBigg@#1#2{\leavevmode@ifvmode
  {\@mathmeasure\z@{\nulldelimiterspace\z@}%
     {\left#2\vcenter to#1\big@size{}\right.}%
   \box\z@}}
\fi

以下是我尝试使用以下方法实现扩展expl3

\documentclass{article}
\usepackage{amsmath}

\newcommand{\veca}{|_{\vec{a}}}

\makeatletter
\ExplSyntaxOn

\cs_set_eq:NN \better_big:nn \bBigg@
\cs_generate_variant:Nn \better_big:nn {no}

\cs_set:Npn \bBigg@ #1#2 {
    \better_big:no #1 #2
}

\ExplSyntaxOff
\makeatother

\begin{document}

\[
\frac{f(\vec{x})}{g(\vec{x})}\bigg\veca \qquad
\frac{f(\vec{x})}{g(\vec{x})}\bigg|_{\vec{a}}
\]

\end{document}

但它似乎根本不起作用 在此处输入图片描述


任何建议都非常感谢。纯 LaTeX2 解决方案也非常受欢迎。

答案1

您几乎已经完成了。但是 o 型扩展默认会为结果加上括号,因此您需要一个不带括号的扩展。

\documentclass{article}
\usepackage{amsmath}

\newcommand{\veca}{|_{\vec{a}}}

\makeatletter
\ExplSyntaxOn

\cs_set_eq:NN \better_big:nn \bBigg@

\cs_set:Npn \bBigg@ #1#2 {
    \exp_last_unbraced:Nno \better_big:nn {#1} {#2}
}

\ExplSyntaxOff
\makeatother

\begin{document}

\[
\frac{f(\vec{x})}{g(\vec{x})}\bigg\veca \qquad
\frac{f(\vec{x})}{g(\vec{x})}\bigg|_{\vec{a}}
\]

\end{document}

请注意的 o 扩展#2必须是括号平衡的。


请注意,这将破坏其他一些用法,例如参见评论。我认为解决此问题的一种方法是测试内部宏是否是“想要扩展”的宏,例如

\cs_set:Npn \bBigg@ #1#2 {
    \tl_if_eq:nnTF {#2} {\veca} {
        \exp_last_unbraced:Nno \better_big:nn {#1} {#2}
    }
    {
        \better_big:nn {#1} {#2}
    }
}

(看,TeX 不是魔法。然后如果你想要某个系统将宏标记为“是否要扩展”,你可以定义一些辅助宏等。它很快变得复杂。functional包做了一些类似的事情来查看参数中的内部宏是否“是一个函数”)

相关内容