3

Very often there are questions like: "Why are the square roots so ugly? Why is there a difference in height?"

$\sqrt{x} \, \sqrt{y} \, \sqrt{X}$

Then the answers all sound like: "Use \phantom, \mathstrut or \smash[b]." Not really satisfying as all the suggestions are adjustments by hand.

Now we have had LuaTeX since more than 10 years. Why isn't there any solution with lua callbacks?

A good \sqrt sign should...

  • have a minimum height (example: by inserting \phantom{0}).
  • not grow into depth when there are only descenders of letters or subscripts (\smash[b]). Of couse the bottom should not be smashed when there is a big fraction or another big constuction.
  • ignore \underbraces.

If I had more knowledge about LuaTeX I would try to create an MWE. In the LuaTeX manual we find radical nodes and so on. Maybe someome has an idea.

EDIT (as an answer to projetmbc's comment):

The first of my suggestions would lead to the same square root height for \sqrt x, \sqrt X and \sqrt 2.

The second one would lead to equal heigt for $\sqrt g$, \sqrt x and \sqrt{x_1}.

The third one would prevent the square root sign from growing for an underbrace: $\sqrt{\underbrace{something}_{something}}$

I cannot imagine a solution without LuaTeX.

16
  • 1
    @Mico: See my example above ($\sqrt{x} \, \sqrt{y} \, \sqrt{X}$). This leads to 3 different square root signs (ugly). A solution is desireable because the adjustments by hand are annoying. Feb 12 at 18:25
  • 1
    I accept other opinions, but I don't like the inconsistent square root signs. And many other users dislike them, too. Otherwise we wouldn't see such questions. Feb 12 at 18:31
  • 1
    @projetmbc: See edit. :) Feb 12 at 18:44
  • 1
    Would you be willing to give a list of those who dislike them? Perhaps their problems have been answered. Feb 12 at 19:13
  • 2
    There are only solutions by hand. You have to insert \smash[b] or \phantom by hand. With LuaTeX automatic solutions should be possible. Feb 12 at 19:16

2 Answers 2

12

I'm not convinced that it's an improvement to force (most) \sqrt expressions to have surds with the same height and depth. But, as always, if you really understand what you're doing, you'll probably be ok using the one-size-fits-almost-all approach.

The following, LuaLaTeX-based solution features (a) a utility LaTeX macro called \lsqrt and (b) two Lua functions: lsqrt does almost all of the real work, and checkroot (which is called by lsqrt) contains a list of conditions; if one (or more) of these conditions is met, \lsqrt does nothing special, i.e., it behaves like the basic \sqrt macro.

The default height of the horizontal bar of the square root symbol generated by \lsqrt is set so that something such as k^2 will just fit. Note that this is a bit taller than what the OP required; however, as the difference in heights is just 0.6pt (at least for Computer Modern with 10pt as the main document font size), I think it's justifiable to go for this ever so slightly greater height. Of course, if you prefer a height that accomodates k but not k^2, just change both instances of \\vphantom{k^2} to \\vphantom{k}. (Aside: the \\ double-backslash symbol occurs because for Lua, \ has a special meaning too; however, the Lua-special and TeX-special meanings of \ are completely different. To output a single backslash character in Lua, it's necessary to input \\.)

enter image description here

% !TEX TS-program = lualatex
\documentclass{article} 
\usepackage{amsmath}
\usepackage{luacode} % for 'luacode*' env. and '\luastringN' macro

%% Lua-side code: 2 Lua functions: checkoptargroot, lsqrt
\begin{luacode*}
function checkroot ( s )
  if       s:find ( "\\[dt]?frac" ) -- \frac term
        or s:find ( "\\int" )       -- integral symbol
        or s:find ( "\\sum" )       -- summation symbol
        or s:find ( "%^%s?%b{}" )   -- exponent term encased in matching curly braces
     then
       return true
  else
       return false
  end
end

function lsqrt ( b , s ) -- this function does most of the work
  if b=="" then -- no optional argument was provided to "\lsqrt"
    if checkroot ( s ) then
      tex.sprint ( "\\sqrt{".. s .."}" ) -- nothing special to do
    else
      tex.sprint ( "\\sqrt{\\smash{".. s ..
                   "}\\vphantom{k^2}}\\vphantom{"..s.."}" )
    end
  else -- need to handle non-empty optional argument
    if checkroot ( s ) then
      tex.sprint ( "\\sqrt["..b.."]{".. s .."}" ) -- nothing special to do
    else
      tex.sprint ( "\\sqrt["..b.."]{\\smash{".. s ..
                   "}\\vphantom{k^2}}\\vphantom{"..s.."}" )
    end    
  end
end
\end{luacode*}

%% LaTeX-side code: utility macro to access the 'lsqrt' function
\newcommand\lsqrt[2][]{\directlua{lsqrt(\luastringN{#1},\luastringN{#2})}}

\begin{document}

$\sqrt{y}$  $\sqrt{x}$  $\sqrt{t}$  $\sqrt{k}$  $\sqrt{b_q^2}$ vs.\
$\lsqrt{y}$ $\lsqrt{x}$ $\lsqrt{t}$ $\lsqrt{k}$ $\lsqrt{b_q^2}$

\medskip
$\sqrt[3]{y}$  $\sqrt[4]{x}$  $\sqrt[5]{t}$  $\sqrt[6]{k}$  $\sqrt[7]{b_q^2}$ vs.\
$\lsqrt[3]{y}$ $\lsqrt[4]{x}$ $\lsqrt[5]{t}$ $\lsqrt[6]{k}$ $\lsqrt[7]{b_q^2}$

\medskip
$\sqrt{\frac{1}{2}}$     $\lsqrt{\frac{1}{2}}$,
$\sqrt[3]{\dfrac{1}{5}}$ $\lsqrt[3]{\dfrac{1}{5}}$,
$\sqrt{a_q^{-x^2/2}}$    $\lsqrt{a_q^{-x^2/2}}$

\end{document} 
15
  • 1
    Nice solution, this meets most of the requirements of the asker without being overly complicated I think. Note that (given the remarks of the asker that LuaLaTeX would probably be needed) this kind of approach could also be done with regex matching in expl3 for other compilers, or even with \IfSubStr from the xstring package.
    – Marijn
    Feb 13 at 15:18
  • @Marijn - Thanks. Indeed, if somebody wants to come up with an latex3/regex solution, that would be quite welcome. (I won't be the one providing the alternative solution, though, as I'm much more familier with Lua and its string functions than with latex3 and its syntax.)
    – Mico
    Feb 13 at 15:59
  • 1
    @Mico: I have added or s:find ( "\\[l]?sqrt") as you suggested. $\lsqrt{\lsqrt 2}$ looks perfect, but $\lsqrt{\lsqrt j}$ not. I think the \vphantoms in the lua code should be collected in the case of nested roots and added after all the nested roots have been typeset. ;) Feb 13 at 19:34
  • 1
    @Mico Can I use your code in a GPL project?
    – projetmbc
    Feb 14 at 15:11
  • 1
    @projetmbc - You are more than welcome to use use my code any way you see fit. :-)
    – Mico
    Feb 14 at 15:15
2

I think that you will not find one version that will fit you perfectly for all cases, and, as mentioned in a comment, I think this is something for the macro package. Since you have gotten a satisfying LaTeX answer, I provide a ConTeXt one, hopefully to help somebody.

In ConTeXt you have the possibilities to do setups and define your own instances of mathradicals. By default, the \sqrt has a strut that has height but no depth, but that can be changed. Also, as we will see, it is possible to set the height and depth of content. Let us show some examples

\usemodule[visual] % for \fakewords only

\starttext

\fakewords{25}{30}

\startformula
  \sqrt{y}+\sqrt{x} + \sqrt{b_q^2} + \sqrt{\frac{1}{5}} + \root[n=3]{x+y}
  \breakhere
  \sqrt[depth=1sp]{y} + \sqrt[strut=no]{x} + \sqrt[depth=1sp]{b_q^2} + \sqrt[depth=6pt]{\frac{1}{5}} + \sqrt[depth=1sp][3]{x+y}
\stopformula

\fakewords{25}{30}

\definemathradical
  [mysqrt]
  [depth=1sp]

\startformula
  \mysqrt{y} + \mysqrt{x} + \mysqrt{b_q^2} + \mysqrt{\frac{1}{5}} + \mysqrt[depth=6pt]{\frac{1}{5}} + \mysqrt[3]{x+y}
\stopformula

\fakewords{25}{30}

\startformula
  \sqrt{\int_a^c 2x\dd x} 
  = 
  \sqrt{\underbrace{c^2-a^2}_{=b^2}}
  = 
  \sqrt[depth=4pt]{\underbrace{c^2-a^2}_{=b^2}} 
  =
  \mysqrt{\underbrace{c^2-a^2}_{=b^2}} 
\stopformula

\fakewords{25}{30}

\stoptext

Compiling this file with context gives the result:

A very radical image

Some comments:

  • The first line in the first displayed formula shows the default \sqrt{}
  • The second line in the first displayed formula shows some variants, as we can get them by inserting options to the \sqrt macro.
  • For the third displayed formula, we have introduced our own instance of a math radical, \mysqrt, with the help of \definemathradical. To set the depth explicitly we need to set it to some non-zero value (this is by old construction, and the value zero will give just the original version back). We set it to something very small, 1sp. Note in the fraction 1/5 that it looks better with a slightly modified depth (that we can add as an optional argument to \mysqrt).
  • In the last displayed formula we show also some formula with an underbrace. Here you see three versions, and you can choose yourself which one you prefer.

A curiosity: After discussions with Hans, we agreed that using the name sqrt in \sqrt[3]{x} is a bit strange, so from now on the base math radical in ConTeXt will be \root instead of \sqrt (but with \sqrt as a copy of it, not to break compatibility). There will also be support for input like \root[n=3]{x} instead of \root[3]{x}.

You must log in to answer this question.

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