Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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?

share|improve this question
add comment

2 Answers 2

up vote 29 down vote accepted

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)

share|improve this answer
    
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 Sep 28 '11 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 Sep 29 '11 at 20:39
1  
@Matthias: Very good! Approved, I just added \usepackage{letltxmacro}. So we could remove all now obsolete comments. –  Stefan Kottwitz Sep 29 '11 at 22:25
    
I also referred to this solution on the discussion page of the LaTeX wikibook entry where I found the original code. I did not update the wiki itself (yet). –  Matthias Oct 2 '11 at 12:53
    
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 Nov 5 '11 at 18:59
add comment
\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.

share|improve this answer
    
What do you mean "don't use that symbol"? –  Matthias Sep 28 '11 at 22:07
1  
I find it unnecessary and ugly. :) What do you need it for? –  egreg Sep 28 '11 at 22:10
2  
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 Sep 28 '11 at 22:24
    
Same question for you: do you think your solution has some advantage over Stefan's? –  Matthias Sep 28 '11 at 22:27
8  
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 Sep 28 '11 at 22:35
show 3 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.