我正在尝试为数学运算符创建一个宏\jjoin
,它大致产生以下行为:
内联:\bigvee^{(J)}
,下标(通常为i \in I
)位于通常位置(如在渲染中\bigvee^{(J)}_{i \in I}
);
显示样式:(J)
位于与内联方程式相同的位置,即右上方,但位于i \in I
下方,\bigvee
如通常的显示样式一样。
我尝试了以下定义\jjoin
,但无济于事:
\mathop{\bigvee{}^{(J)}}
(i \in I
出现得太靠右了,因为(J)
在确定表达式的中间部分时要考虑该部分);\makebox[0]{\ensuremath{\hphantom{\bigvee}^{(J)}}}\bigvee
(我不确定为什么会失败,但是的位置(J)
变化很大;也许是因为\ensuremath
不记得是否\jjoin
在显示模式下调用?);
但这就是我对 (La)TeX 的了解。
我见过#99538但结果与我上面的第一次尝试相同。
梅威瑟:
\documentclass[a4paper]{article}
\usepackage{amssymb,amsmath}
\newcommand{\jjoin}{\mathop{\bigvee\nolimits^{(J)}}}
\begin{document}
Inline: $\jjoin \qquad \jjoin_{i\in I}$
Display: \[\jjoin \qquad \jjoin_{i\in I}\]
\end{document}
注意:这是我在 TeX.SE 上的第一个问题;我希望我没有犯太多初学者的错误。欢迎指出。
答案1
这应该完全按照预期工作:
\documentclass[a4paper]{article}
\usepackage{amssymb,amsmath}
\pagestyle{empty}
\makeatletter
\newcommand*\jjoin{\@ifnextchar_\jj@in\jj@@n}
\newcommand*\jj@@n{\bigvee\nolimits^{(J)}}
\newcommand*\jj@in[2]{\mathchoice
{\mathop{\jj@@n}_{#2\phantom{(J)}}}%
{\jj@@n_{#2}}%
{\jj@@n_{#2}}%
{\jj@@n_{#2}}%
}
\makeatother
\begin{document}
Inline: $A=\jjoin B \qquad A=\jjoin_{i\in I} B_i$
Display: \[A=\jjoin B \qquad A=\jjoin_{i\in I} B_i\]
\end{document}
答案2
这个答案解决了剩下的问题David Carlisle 的解决方案后面的符号与显示样式版本中的上标冲突。
\documentclass[a4paper]{article}
\usepackage{amssymb,amsmath}
\usepackage{mathtools}
\makeatletter
\newcommand*{\jjoin}{%
\@ifnextchar_{\@jjoin}{%
\@ifnextchar\sub{\@jjoin@sub}{%
\bigvee\nolimits^{(J)}%
}%
}%
}
\def\@jjoin_#1{%
\mathpalette\@@jjoin{#1}%
}
\def\@jjoin@sub\sub#1{%
\mathpalette\@@jjoin{#1}%
}
\def\@@jjoin#1#2{%
\ifx#1\displaystyle
\sbox0{$\m@th\displaystyle\bigvee$}%
\sbox2{$\m@th\displaystyle\bigvee\nolimits^{(J)}\kern-\scriptspace$}%
\sbox4{$\m@th\displaystyle\bigvee_{#2}\kern-\scriptspace$}%
\mathop{\bigvee\nolimits^{\mathrlap{(J)}}\kern-\scriptspace}_{#2}%
\dimen@=\dimexpr
\wd2-\wd0 %
\ifdim\wd4>\wd0 %
-.5\dimexpr\wd4-\wd0\relax
\fi
\relax
\ifdim\dimen@>\z@
\kern\dimen@
\fi
\else
\bigvee\nolimits^{(J)}_{#2}%
\fi
}
\makeatother
\begin{document}
Inline: $A\jjoin X \qquad A\jjoin_{i\in I}X$
\bigskip
Display: $\displaystyle A\jjoin X\qquad A\jjoin_{i\in I}X$
\bigskip
Inline: $A\jjoin_{i\in I\cup K}X \qquad A\jjoin_{i\in I\cup K\cup L}X$
\bigskip
Display:
$\displaystyle A\jjoin_{i\in I\cup K}X \qquad A\jjoin_{i\in I\cup K\cup L}X$
\end{document}
评论:
- 如果后面的下标前面有
_
或,则该下标将被捕获为宏参数\sub
。 \displaystyle
是通过使用 来检测的\mathpalette
。- 仅当 为有效且给出下标时才需要特殊处理。然后计算
\displaystyle
重叠上标的量并将其添加到表达式之后。(J)
\kern
- 十以下的偶数盒子寄存器可用于本地分配。
\m@th
消除的影响\mathsurround
,因为我们里面一个公式。\mathrlap
不足以获得没有水平间距的上标,因为 TeX 会\scriptspace
在下标或上标后添加。- 由于和
\mathpalette
下标在显示样式中的测量,下标被调用了五次。除非下标包含全局赋值或具有副作用的命令(例如\write
,\typeout
),否则这通常不是问题。但是\mathpalette
/\mathchoice
是仅有的\over
由于 TeX和类似的原语,可以以可靠的方式获取数学样式。
答案3
\documentclass{article}
\usepackage{mathtools}
\begin{document}
$\mathop{\bigvee{}^{\mathrlap{(J)}}}_{i\in I}$
\bigskip
\[\mathop{\bigvee{}^{\mathrlap{(J)}}}_{i\in I}\]
\end{document}
如果稍微改变标记,则之后的空间控制会更容易:
\documentclass{article}
\usepackage{mathtools}
\begin{document}
$\mathop{\bigvee{}^{\mathrlap{(J)}}}_{i\in I}X$
\bigskip
\[\mathop{\bigvee{}^{\mathrlap{(J)}}}_{i\in I}X\]
\newcommand\foo[1][]{%
\mathop{{}\bigvee{}^{\mathrlap{(J)}}}_{#1}\mathchoice
{\scriptstyle\phantom{(J)}}{}{}{}}
$\foo[i\in I] X$
\bigskip
\[\foo[i\in I] X\]
\end{document}