67

I found a cool trick in the LaTeX wikibook which allows the square root sign to be altered such that it "closes" over its contents. Here's an example:

closed root

("closed" root on the left, normal one on the right)

The way they do this is as follows:

% 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}}

The cool thing is that (as far as I've tested it) this works regardless of the math font and with pdftex as well as xetex. However what is not possible is mulitple roots, such as \sqrt[3]{a}. Those produce incorrect output when this "trick" is being used.

So my question is, is somebody able to tweak this code so that it works for multiple roots as well?

3 Answers 3

53

Here's an example redefining the internal macro \r@@t of 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}

cubic and normal roots

Edit: \LetLtxMacro{\oldsqrt}{\sqrt} instead of \let\oldsqrt\sqrt because \sqrt takes an optional argument (as advised by egreg)

6
  • Because egreg says that one should use \LetLtxMacro instead of \let in this case, but notes that your solution is otherwise more efficient I propose a hybrid of both solutions. I'll submit an edit of your answer...
    – Matthias
    Commented Sep 28, 2011 at 22:56
  • @egreg: Since Stefan confirmed that the redefinition was necessary to "close" normal square roots (like I said), I again propose a hybrid of your solution and his. I.e. = Stefan's solution but with \LetLtxMacro instead of \let. Editing now...
    – Matthias
    Commented Sep 29, 2011 at 20:39
  • 1
    @Matthias: Very good! Approved, I just added \usepackage{letltxmacro}. So we could remove all now obsolete comments.
    – Stefan Kottwitz
    Commented Sep 29, 2011 at 22:25
  • It should be noted that the redefinition must be done after loading the amsmath package (or not loading amsmath at all), because otherwise amsmath defines \r@@t again. (I would also prefer \kern 0.08em instead of \,, but this is just a matter of taste and I'm not sure whether that would be wide enough.)
    – Stephen
    Commented Nov 5, 2011 at 18:59
  • @StefanKottwitz Interestingly, the symbol looks a bit weird for my documents, see, e.g., this picture. Commented Mar 17, 2020 at 22:15
37
\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}}

Don't use that symbol.

Note on \LetLtxMacro

When we say \newcommand{\xyz}[2][ABC]{-#1-#2-} (just to show an easy example), the actual definition of \xyz is

\@protected@testopt \xyz \\xyz {ABC}

The first command checks whether we are in normal typesetting or in "special situations" (for instance, when arguments are massaged to write them in auxiliary files). In the latter case it does an easy thing: it eats up everything leaving only \protect\xyz (which is A Good Thing in these situations).

In the former case it looks at the following character, in order to see if we have specified the optional argument or not. I won't go into the details, but only show the important steps.

  1. The call is \xyz{XYZ} The result here is \\xyz[ABC]{XYZ}

  2. The call is \xyz[DEF]{XYZ}
    The result here is \\xyz[DEF]{XYZ}

In both cases the relevant command is \\xyz. Yes, with a backslash in its name! It's not possible to express it in a standard way: to call it one has to do \csname\string\xyz\endcsname, but this is not the point. What's the definition of \\xyz? Here's what TeX says:

> \\xyz=\long macro:
[#1]#2->-#1-#2-.

The first argument is precisely what's between the square brackets.

Suppose now that we do

\let\oldxyz\xyz
\renewcommand{\xyz}[2][U]{\oldxyz[#1]{#2}}

and that \xyz[T]{XYZ} appears in "normal typesetting". I'll show the steps on successive lines:

\xyz[T]{XYZ}
\\xyz[T]{XYZ}
\oldxyz[T]{XYZ}
\\xyz[T]{XYZ}
\oldxyz[T]{XYZ}
\\xyz[T]{XYZ}
...

and TeX goes into infinite loop. This is because \\xyz has been given a meaning by \renewcommand and it's easy to check that this meaning is

> \\xyz=\long macro:
[#1]#2->\oldxyz [#1]{#2}.

and \oldxyz meaning is exactly the same as the original \xyz which will find \\xyz which has the new definition.

Here's where \LetLtxMacro comes to the rescue: when we say

\LetLtxMacro{\oldxyz}{\xyz}

we not only say \let\oldxyz\xyz, but also \let\\oldxyz\\xyz (with the strange command names that are not directly writable) and change the meaning of \oldxyz so that it expands to

\@protected@textopt \oldxyz \\oldxyz {ABC}

Moral

Don't use \let\oldxyz\xyz when \xyz takes an optional argument, unless you know exactly what you're doing.

8
  • What do you mean "don't use that symbol"?
    – Matthias
    Commented Sep 28, 2011 at 22:07
  • 5
    I find it unnecessary and ugly. :) What do you need it for?
    – egreg
    Commented Sep 28, 2011 at 22:10
  • 4
    Well, I kind of like it this way. This is the way I draw root symbols on paper. I guess it's just a matter of taste.
    – Matthias
    Commented Sep 28, 2011 at 22:24
  • 10
    One should never use the trick \let\oldxyz\xyz when \xyz is defined with \newcommand and takes an optional argument (it's very risky). OTOH, that redefinition is not needed, as you observe, so Stefan's (amended) solution is more efficient.
    – egreg
    Commented Sep 28, 2011 at 22:35
  • 3
    I wish I could upvote it 10 times. Very didactic and concise answer, thanks! Commented Sep 30, 2011 at 12:32
8

Doing my first stackexchange post over ever:) After taking a look at the differences to this post, I combined the answer of Stefan Kottwitz, Stephens comment, and the nicer repositioning of the root index using \uproot and \leftroot from this article into one nice sqare root:

\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}

Now the added box won't be higher than the actual root in bigger fonts. It also results in the height of the added box to be dependent on wether \boldmath is used as well. I still do not like the extra spacing in front of \frac[n]{a} as described here, and I have no idea how to get it implemented... The bracket behavior with inline math mode is also far from desired I would say.

roots

I'm curious if anyone can get that working as well and get an even nicer "closed" square root.

EDIT1: Bracket issue fixed: changed \uproot{2} to \uproot{1}. roots

6
  • 2
    Welcome to the site! Commented Nov 3, 2015 at 18:37
  • 2
    It would be nice to have a working document around this code ;-)
    – user31729
    Commented Nov 3, 2015 at 18:52
  • @ChristianHupfer thanks for the tip, does my current edit live up to the usual format standards for posts like these?
    – ddelange
    Commented Nov 3, 2015 at 21:25
  • 1
    @DaviddeL. Yes, it does
    – user31729
    Commented Nov 3, 2015 at 21:26
  • 1
    Thanks for this! I was able to comment out the \renewcommand* just before \makeatother and have a new command for a bracketed root while preserving the old \sqrt construction as well. Commented May 3, 2017 at 21:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .