我发现了一个很酷的技巧LaTeX 维基百科这使得平方根符号可以改变,使其“闭合”在其内容之上。以下是一个例子:
(左边是“封闭”根,右边是正常根)
他们这样做的方式如下:
% New definition of square root:
% it renames \sqrt as \oldsqrt
\let\oldsqrt\sqrt
% it defines the new \sqrt in terms of the old one
\def\sqrt{\mathpalette\DHLhksqrt}
\def\DHLhksqrt#1#2{%
\setbox0=\hbox{$#1\oldsqrt{#2\,}$}\dimen0=\ht0
\advance\dimen0-0.2\ht0
\setbox2=\hbox{\vrule height\ht0 depth -\dimen0}%
{\box0\lower0.4pt\box2}}
很酷的是(据我测试过),无论使用什么数学字体,使用 pdftex 和 xetex,这都可以正常工作。然而,不可能出现多重根,例如\sqrt[3]{a}
。当使用此“技巧”时,它们会产生错误的输出。
所以我的问题是,有人可以调整此代码以使其也适用于多个根吗?
答案1
\r@@t
下面是重新定义内部宏的示例latex.ltx
:
\documentclass{article}
\usepackage{letltxmacro}
\makeatletter
\let\oldr@@t\r@@t
\def\r@@t#1#2{%
\setbox0=\hbox{$\oldr@@t#1{#2\,}$}\dimen0=\ht0
\advance\dimen0-0.2\ht0
\setbox2=\hbox{\vrule height\ht0 depth -\dimen0}%
{\box0\lower0.4pt\box2}}
\LetLtxMacro{\oldsqrt}{\sqrt}
\renewcommand*{\sqrt}[2][\ ]{\oldsqrt[#1]{#2}}
\makeatother
\begin{document}
\[ \sqrt[3]{\frac{a}{b}} \quad \sqrt{\frac{a}{b}} \]
\end{document}
编辑: \LetLtxMacro{\oldsqrt}{\sqrt}
而不是\let\oldsqrt\sqrt
因为\sqrt
采用可选参数(如 egreg 建议的那样)
答案2
\usepackage{letltxmacro}
\LetLtxMacro{\oldsqrt}{\sqrt}
\renewcommand{\sqrt}[1][\hphantom{3}]{%
\def\DHLindex{#1}\mathpalette\DHLhksqrt}
\def\DHLhksqrt#1#2{%
\setbox0=\hbox{$#1\oldsqrt[\DHLindex]{#2\,}$}\dimen0=\ht0
\advance\dimen0-0.2\ht0
\setbox2=\hbox{\vrule height\ht0 depth -\dimen0}%
{\box0\lower0.4pt\box2}}
不要使用那个符号。
注意\LetLtxMacro
当我们说\newcommand{\xyz}[2][ABC]{-#1-#2-}
(仅举一个简单的例子)时,的实际定义\xyz
是
\@protected@testopt \xyz \\xyz {ABC}
第一个命令检查我们是在正常排版还是在“特殊情况”(例如,当参数被修改以将其写入辅助文件时)。在后一种情况下,它会做一件简单的事情:它会吃掉所有内容,只留下\protect\xyz
(这是一件好事在这些情况下)。
在前一种情况下,它会查看以下字符,以查看我们是否指定了可选参数。我不会详细介绍,只展示重要的步骤。
调用的是
\xyz{XYZ}
结果如下\\xyz[ABC]{XYZ}
调用的是
\xyz[DEF]{XYZ}
结果如下\\xyz[DEF]{XYZ}
在这两种情况下,相关命令都是\\xyz
。是的,其名称中有一个反斜杠!无法以标准方式表达它:要调用它,必须执行\csname\string\xyz\endcsname
,但这不是重点。 的定义是什么\\xyz
?以下是 TeX 的说法:
> \\xyz=\long macro:
[#1]#2->-#1-#2-.
第一个参数正是方括号之间的内容。
假设我们现在这样做
\let\oldxyz\xyz
\renewcommand{\xyz}[2][U]{\oldxyz[#1]{#2}}
并且\xyz[T]{XYZ}
以“正常排版”显示。我将逐行展示这些步骤:
\xyz[T]{XYZ}
\\xyz[T]{XYZ}
\oldxyz[T]{XYZ}
\\xyz[T]{XYZ}
\oldxyz[T]{XYZ}
\\xyz[T]{XYZ}
...
TeX 会陷入无限循环。这是因为\\xyz
已经被赋予了意义,\renewcommand
并且很容易检查这个意义是否
> \\xyz=\long macro:
[#1]#2->\oldxyz [#1]{#2}.
含义\oldxyz
与原来的 \xyz
将会找到\\xyz
哪个具有新的定义。
这就是\LetLtxMacro
解决办法:当我们说
\LetLtxMacro{\oldxyz}{\xyz}
我们不仅说\let\oldxyz\xyz
,而且\let\\oldxyz\\xyz
(使用不能直接写入的奇怪命令名称)和改变的含义,\oldxyz
使其扩展为
\@protected@textopt \oldxyz \\oldxyz {ABC}
道德
不要使用\let\oldxyz\xyz
带有\xyz
可选参数的函数,除非你确切知道自己在做什么。
答案3
这是我有史以来第一个 stackexchange 帖子:)在查看了以下差异之后这帖子中,我结合了 Stefan Kottwitz 的回答、Stephens 的评论,以及使用 \uproot 和 \leftroot 对根索引进行更好的重新定位这文章变成一个很好的平方根:
\documentclass{article}
\usepackage{letltxmacro}
\usepackage{amsmath}
\LetLtxMacro{\OldSqrt}{\sqrt}
\newcommand{\ClosedSqrt}[1][\hphantom{3}]{\def\DHLindex{#1}\mathpalette\DHLhksqrt}
\makeatletter
\newcommand*\bold@name{bold}
\def\DHLhksqrt#1#2{%
\setbox0=\hbox{$#1\OldSqrt{#2\,}$}\dimen0=\ht0\relax%
\advance\dimen0-0.2\ht0\relax% size of the added box is still 0.2 times ht0
\setbox2=\hbox{\vrule height\ht0 depth -\dimen0}%
{\hbox{$#1\expandafter\OldSqrt\expandafter[\DHLindex]{#2\,}$}
\lower\ifx\math@version\[email protected]\else0.4pt\fi\box2}
}
% root index positioning and added space at the end, mostly noticeable in inline math mode
\renewcommand*{\sqrt}[2][\ ]{\ClosedSqrt[\leftroot{-2}\uproot{1}#1]{#2}\kern0.1em}
\makeatother
\begin{document}
\begin{flalign}
&\left(\sqrt[\beta]{42}\right) = \left(\sqrt{42}\right), \beta = 2&
\end{flalign}
\noindent In $ \left(\sqrt[\beta]{42}\right) = \left(\sqrt{42}\right) , \beta = 2$ between some text.
\end{document}
现在,在较大的字体中,添加的框不会高于实际的根。这也导致添加的框的高度取决于是否也使用了 \boldmath。我仍然不喜欢 \frac[n]{a} 前面的额外间距,如所述这里,我不知道如何实现它...我想说,内联数学模式的括号行为也远远达不到预期。
我很好奇是否有人可以使它正常工作并得到更好的“封闭”平方根。