答案1
和朋友的默认定义\Big
将分隔符设置为左分隔符,因此在其上添加下标最终会成为分隔列表中的第一个元素,因此不会相对于分隔符放置。可以通过以\Big
相反的方式定义和朋友来避免这种情况:将分隔符设为右分隔符,这样下标就成为整个分隔列表的下标。
虽然这可以修复位置,但它会对下标的放置方式产生副作用(大多数\nulldelimiterskip
为零,样式始终为脚本样式),但对于大多数用例来说,这并不重要。
鉴于amsmath
定义\big
基于\bBigg@
它足以改变该宏的定义:
\documentclass{article}
\usepackage{amsmath}
\makeatletter
\renewcommand \bBigg@[2]{%
{\@mathmeasure\z@{\nulldelimiterspace\z@}%
{\left.\vcenter to#1\big@size{}\right#2}%
\box\z@}}
\makeatother
\newcommand{\veca}{|_{\vec{a}}}
\begin{document}
\[
\frac{f(\vec{x})}{g(\vec{x})}\bigg\veca \qquad \frac{f(\vec{x})}{g(\vec{x})}\bigg|_{\vec{a}}
\]
\end{document}
答案2
这是@DavidCarlisle 建议采用veca
可选参数的实现,不同之处在于我建议将其设置\biggr
为可选参数的默认值。
\documentclass{article}
\usepackage{amssymb}
\providecommand{\veca}[1][\biggr]{#1\vert_{\vec{a}}}
\begin{document}
\[
\frac{f(\vec{x})}{g(\vec{x})}\veca
\quad
\frac{u(\vec{x})}{v(\vec{x})}\veca[\Bigr]
\quad
h(\vec{z})\veca[]
\]
\end{document}
答案3
这更多的是一种评论而不是答案,但是这种构造在 ConTeXt LMTX(即使用 luametatex 引擎)中可以开箱即用。
\define\veca{\rvert_{\vec{a}}}
\starttext
\startformula
\frac{f(\vec{x})}{g(\vec{x})}\Bigg\veca \qquad \frac{f(\vec{x})}{g(\vec{x})}\Bigg|_{\vec{a}}
\stopformula
\stoptext
这使
我不确定内部有什么不同才能使其正常工作。
\bigg
请注意和的大小\Bigg
不同,因为 ConTeXt 对分隔符的缩放略有不同,并且下标的位置也不同(这是因为 luatex 引擎从字体中读取间距值;在 lualatex 中也会获得类似的间距)。
答案4
\documentclass{article}
\usepackage{amsmath}
\usepackage{expl3}
\makeatletter
\ExplSyntaxOn
\cs_set_eq:NN \better_big:nn \bBigg@
\cs_set:Npn \bBigg@ #1#2 {
\tl_set:Nx \arg_rest_tokens { \tl_tail:N {#2} }
\tl_set:Nx \arg_first_token { \tl_head:N {#2} }
\tl_set:Nx \arg_first_token_exp { \tl_head:f {#2} }
\exp_last_unbraced:No \token_if_eq_meaning:NNT \arg_first_token \delimiter {
\use_none_delimit_by_q_nil:w
}
\exp_last_unbraced:No \token_if_eq_meaning:NNF \arg_first_token_exp \delimiter {
\exp_last_unbraced:Nno \str_if_in:nnF {\{\}} {\arg_first_token} {
\int_compare:nF { \exp_last_unbraced:NNV \delcode`\arg_first_token > 0 } {
\use_none_delimit_by_q_nil:w
}
}
}
\better_big:nn {#1} {\arg_first_token} \arg_rest_tokens
\use_none_delimit_by_q_stop:w
\use_none_delimit_by_q_nil:w \q_nil
\better_big:nn {#1}{#2}
\use_none_delimit_by_q_stop:w \q_stop
}
\ExplSyntaxOff
\makeatother
\newcommand{\veca}{|_{\vec{a}}}
\newcommand{\ketb}{\rangle^*}
\newcommand{\lnorm}{\|}
\newcommand{\rnorm}{\|_\infty}
\begin{document}
Custom macros next to \verb|\Big, \bigg|, etc
\[
\frac{f(\vec{x})}{g(\vec{x})}\bigg\veca \qquad
\big\lnorm A\vec{x} \big\rnorm \qquad
\Big|\Phi(t)\Big\ketb
\]
Doesn't break the regular behaviour
\[
\frac{f(\vec{x})}{g(\vec{x})}\bigg|_{\vec{a}} \qquad
\big\| A\vec{x} \big\|_\infty \qquad
\Big|\Phi(t)\Big\rangle^*
\]
\end{document}
这个问题本身看起来相当简单,不是吗?然而,说实话,它似乎比我最初想象的要难得多。
我花了很多功夫才终于解决了这个问题。我必须感谢所有为此做出贡献并帮助我解决相关问题的人。
解释
所有\big
,\bigg
,\Big
,\Bigg
均定义于amsmath
就像这样
\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
因此更改仅需应用于\bBigg@
首先想到的就是简单地扩展\big
s 命令的参数。乍一看这可行,但实际上它破坏了一些情况,例如\big\vert
会导致错误。
因此,最终实现的想法如下:检查参数是否可扩展,如果是,则检查扩展的第一个参数,即\veca
的扩展{|_\vec{a}}
,然后我检查该列表的第一个标记,如果它是分隔符,那么我仅将其传递给命令\big
,其他所有内容都只是向右附加。