2

What it says on the tin.

In case it isn't clear enough, what I would like is for $...$ to be typeset as \smash{$...$}, except \smash also affects horizontal spacing (see the question I linked to below) and I'd like it to only affect vertical spacing.

In other words, I'd like some preamble code that does two things:

  1. Make \smash only affect vertical spacing.
  2. Treat all instances of $...$ as \smash{$...$}.

(This question very specifically requests both vertical and horizontal smashing of inline maths, so mine is not a duplicate of it.)

18
  • 1
    Please clarify what you mean by "smash".
    – Mico
    Commented May 7, 2022 at 7:28
  • 4
    There are other ways of preserving baseline spacing, if that is your real intention here. As always a small complete test document would help. Of course in gneral this should never be needed, the point of inline math is to lay out the math in a way that does not disturb the line spacing. Commented May 7, 2022 at 7:53
  • 1
    by default the example you show would not disturb the line spacing, so there is something you are not telling us about your setup. While disturbing the spacing is typographically bad, it's not as bad as overprinting the line above (which is what you get with no warning from \smash ) so the real fix is to fix whatever settings you have that is causing the original issue. See this, \baselineskip not \lineskip used so even spacing Commented May 7, 2022 at 8:42
  • 1
    \documentclass{article} \showoutput \showboxdepth=3 \begin{document} aaa bbb ccc ddd ee $\vec{E}=\vec{E}_0\,e^{ikz}$ aaa bbb ccc ddd ee $\vec{E}=\vec{E}_0\,e^{ikz}$ aaa bbb ccc ddd ee $\vec{E}=\vec{E}_0\,e^{ikz}$ aaa bbb ccc ddd ee $\vec{E}=\vec{E}_0\,e^{ikz}$ aaa bbb ccc ddd ee $\vec{E}=\vec{E}_0\,e^{ikz}$ aaa bbb ccc ddd ee $\vec{E}=\vec{E}_0\,e^{ikz}$ aaa bbb ccc ddd ee $\vec{E}=\vec{E}_0\,e^{ikz}$ \end{document} Commented May 7, 2022 at 8:43
  • 1
    @Dr.ManuelKuehner I haven't actually had time to play with LuaLaTeX to see whether I can implement Mico's solution without anything else breaking, so, unfortunately, the answer is "soon (TM)". Sorry to David and Mico!
    – Rain
    Commented Jan 4, 2023 at 1:58

2 Answers 2

5

By default the example shown will fit within the line spacing so no \smash is needed

\documentclass{article}
\showoutput
\showboxdepth=3
\begin{document}
aaa bbb ccc ddd ee $\vec{E}=\vec{E}_0\,e^{ikz}$
aaa bbb ccc ddd ee $\vec{E}=\vec{E}_0\,e^{ikz}$
aaa bbb ccc ddd ee $\vec{E}=\vec{E}_0\,e^{ikz}$
aaa bbb ccc ddd ee $\vec{E}=\vec{E}_0\,e^{ikz}$
aaa bbb ccc ddd ee $\vec{E}=\vec{E}_0\,e^{ikz}$
aaa bbb ccc ddd ee $\vec{E}=\vec{E}_0\,e^{ikz}$
aaa bbb ccc ddd ee $\vec{E}=\vec{E}_0\,e^{ikz}$
\end{document}

Produces

enter image description here

and the log confirms \baselineskip (rather than \lineskip) is used.

...\hbox(9.67221+1.49998)x345.0, glue set 0.34198 []
...\penalty 150
...\glue(\baselineskip) 0.8278
...\hbox(9.67221+1.49998)x345.0, glue set 0.45447 []
...\penalty 150
...\glue(\baselineskip) 0.8278
...\hbox(9.67221+1.49998)x345.0, glue set 9.86978fil []

For a larger expression

\documentclass{article}
\showoutput
\showboxdepth=3
\begin{document}
aaa bbb ccc ddd ee $\frac{X^2}{Y_3}=\frac{X^2}{Y_3}_0\,e^{ikz}$
aaa bbb ccc ddd ee $\frac{X^2}{Y_3}=\frac{X^2}{Y_3}_0\,e^{ikz}$
aaa bbb ccc ddd ee $\frac{X^2}{Y_3}=\frac{X^2}{Y_3}_0\,e^{ikz}$
aaa bbb ccc ddd ee $\frac{X^2}{Y_3}=\frac{X^2}{Y_3}_0\,e^{ikz}$
aaa bbb ccc ddd ee $\frac{X^2}{Y_3}=\frac{X^2}{Y_3}_0\,e^{ikz}$
aaa bbb ccc ddd ee $\frac{X^2}{Y_3}=\frac{X^2}{Y_3}_0\,e^{ikz}$
aaa bbb ccc ddd ee $\frac{X^2}{Y_3}=\frac{X^2}{Y_3}_0\,e^{ikz}$
\end{document}

You get

enter image description here

and the log confirms TeX gave up using \baselineskip:

...\hbox(10.17732+4.9484)x345.0, glue set 0.26582 []
...\penalty 150
...\glue(\lineskip) 1.0
...\hbox(10.17732+4.9484)x345.0, glue set 0.15062 []
...\glue(\lineskip) 1.0
...\hbox(10.17732+4.9484)x345.0, glue set 0.28621 []
...\penalty 150
...\glue(\lineskip) 1.0
...\hbox(10.17732+4.9484)x345.0, glue set 282.19075fil []

You can set \lineskiplimit so that baseline space is preserved even if the lines do not fit:

\documentclass{article}
\showoutput
\showboxdepth=3
\setlength\lineskiplimit{-\maxdimen}
\begin{document}
aaa bbb ccc ddd ee $\frac{X^2}{Y_3}=\frac{X^2}{Y_3}_0\,e^{ikz}$
aaa bbb ccc ddd ee $\frac{X^2}{Y_3}=\frac{X^2}{Y_3}_0\,e^{ikz}$
aaa bbb ccc ddd ee $\frac{X^2}{Y_3}=\frac{X^2}{Y_3}_0\,e^{ikz}$
aaa bbb ccc ddd ee $\frac{X^2}{Y_3}=\frac{X^2}{Y_3}_0\,e^{ikz}$
aaa bbb ccc ddd ee $\frac{X^2}{Y_3}=\frac{X^2}{Y_3}_0\,e^{ikz}$
aaa bbb ccc ddd ee $\frac{X^2}{Y_3}=\frac{X^2}{Y_3}_0\,e^{ikz}$
aaa bbb ccc ddd ee $\frac{X^2}{Y_3}=\frac{X^2}{Y_3}_0\,e^{ikz}$
\end{document}

This produces

enter image description here

and log

...\hbox(10.17732+4.9484)x345.0, glue set 0.26582 []
...\penalty 150
...\glue(\baselineskip) -3.12572
...\hbox(10.17732+4.9484)x345.0, glue set 0.15062 []
...\glue(\baselineskip) -3.12572
...\hbox(10.17732+4.9484)x345.0, glue set 0.28621 []
...\penalty 150
...\glue(\baselineskip) -3.12572
...\hbox(10.17732+4.9484)x345.0, glue set 282.19075fil []

Showing that baseline spacing preservd even if that forces negative space between lines.

The cure here is worse than the problem though, over-printed illegible text is typographically worse than uneven line space.

This is (I think) the effect that you wanted, by asking for \smash to be applied everywhere but in practice it is better not to do this and just apply \smash conditionally in places where you know there is no over-printing (because a tall item on this line is not aligned with a deep descender on the line above so that you can overlap the bounding boxes without overlapping text)

5
  • Thanks for the answer. That does fix my problem with inline maths, but it messes with equations (at least with align, haven't tested other environments: compare \documentclass{article}\usepackage{amsmath}\setlength\lineskiplimit{-\maxdimen}\begin{document}\noindent$|$\\$|$\\$|\vec{E}^{\,\text{t}}=\vec{E}^{\,\text{t}}_0\,e^{ikz}$\\$|$\\$|$\\$|$\\\begin{align}1+1=2\end{align}Hello.\end{document} to that same code without the \setlength\lineskiplimit{-\maxdimen} bit.
    – Rain
    Commented May 7, 2022 at 9:18
  • Re applying \smash on a case-by-case basis where I know there aren't any deep descenders causing illegible text, I'd much rather avoid illegible text on a case-by-case basis by rewording the problematic text or moving the problematic maths to an align environment if rewording isn't possible. it's just less work for me that way.
    – Rain
    Commented May 7, 2022 at 9:21
  • You could patch align to reset lineskiplimit locally @Rain Commented May 7, 2022 at 9:25
  • Ooh, that could work! I'll look into it.
    – Rain
    Commented May 7, 2022 at 9:39
  • 3
    @Rain re "less work" there must be something wrong with your document settings if this comes up often at all. Setting lineskip limit or globally smash will give overprinting with no warning so is much more fragile than allowing the default spacing when you can always mechanically check the log for instances of \lineskip and adjust as needed. But your default baseline space should be large enough to hold your standard line text, it seems you have it set too small. I would never use the setting I show here for a document to be published. Commented May 7, 2022 at 10:30
3

Additional comment, prompted by the some of the OP's comments: If your document contains a lot of inline math material -- not that there's anything wrong with that! -- you may want to preemptively increase the value of \baselineskip. If the default value of \baselineskip for the font you employ is "120% of the nominal font size" and if the nominal font size is 10pt, you could execute

\fontsize{10}{13}\selectfont

for the document as a whole, in order to avoid most, if not almost all, instances of \lineskip having to be increased beyond \baselineskip. For sure, the case of \vec{E} forcing an increase in \lineskip would no longer be relevant.

The suggestion to increase \baselineskip preemptively is by no means arbitrary or hackish. For instance, in the preface of the book Concrete Mathematics by Graham, Knuth, and Patashnik -- which (unsurprisingly) contains a lot of inline math material, the Concrete Roman text font (an "Egyptienne" of slab-serif variant of Computer Modern), and the "Euler" math font -- the authors discussed that by increasing the value of \baselineskip from 12pt to 13pt, they immediately got rid of almost all cases of inline math forcing an increase in \lineskip. If a typographic solution prompted by inline math considerations is good enough for Knuth and his co-authors, you may want to see if it "works" for you too, right?

By the way, the \fontsize{10}{13}\selectfont approach increases the value of \baselineskip everywhere, including for document elements, such as tabular-like environments, for which no increase in \baselinskip may be needed or desired. To keep tables nice and compact, you could choose -- as an alternative to running \fontsize{10}{13}\selectfont -- to load the setspace package (with the option nodisplayskipstretch) and issue the instruction \setstretch{1.0833} in the preamble. Note that a factor of 1.083 is still barely a third of what the \onehalfspacing directive would entail.


Here's a LuaLaTeX-based solution. To acitivate it, execute \SmashOn; to deactivate it, execute \SmashOff. When \SmashOn is executed, the Lua function smash is assigned to LuaTeX's process_input_buffer callback, where it acts as a preprocessor on the input stream, i.e., it does its stuff before TeX starts its own processing of the input material. The "stuff" it does is to replace all instances of $...$, with \smash{$...%}, just as you require.

There are (at least) three limitations to this approach, the first of which should be the most relevant one in practice.

  1. The inline math material is assumed to be all on one line -- no line breaks allowed. No exception.

  2. You mustn't use $$ to initiate and terminate display math mode. This shouldn't be much of a constraint at all, though, as you should never be using $$ in a LaTeX document. See Why is \[ ... \] preferable to $$ ... $$? for a longer discussion of this subject.

  3. You don't use \$ to display dollar symbols. If you do, be sure to run \SmashOff before the instance(s) of \$ -- and \SmashOn to reactivate the Lua function if and when needed -- or replace the instances of \$ with \textdollar.

That said, I can't imagine a compelling use case for wanting to (vertically) smash all inline math material. If you require it, you're almost certainly doing something wrong. If you have instances of e^{ikz} in inline math mode, consider replacing them with \exp(ikz). Your readers will actually be grateful for you if you did this.


enter image description here

% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{amsmath}  % for '\dfrac' macro
\usepackage{lipsum}   % filler text
\usepackage{luacode}  % for 'luacode' env.
\begin{luacode}
   function smash ( s )
     return ( s:gsub ( "%b$$" , "\\smash{%1}" ) )
   end
\end{luacode}
\newcommand\SmashOn{\directlua{luatexbase.add_to_callback (
   "process_input_buffer", smash, "smash" )}}
\newcommand\SmashOff{\directlua{luatexbase.remove_from_callback (
   "process_input_buffer", "smash" )}}
  
\begin{document} 
\hrule % draw line to illustrate width of textblock
\lipsum[1][1-5] $\dfrac{\dfrac{v}{v}}{\dfrac{w}{x}}$ \lipsum[1][5-8]
\hrule
\SmashOn % activate the Lua function
\lipsum[1][1-5] $\dfrac{\dfrac{v}{v}}{\dfrac{w}{x}}$ \lipsum[1][5-8]
\hrule
\SmashOff % deactivate the Lua function 
\lipsum[1][1-5] $\dfrac{\dfrac{v}{v}}{\dfrac{w}{x}}$ \lipsum[1][5-8]
\hrule
\end{document}
22
  • this does apply \smash though so doesn't do what is asked, which is avoid the boxing which affects the horizonal spacing. Commented May 7, 2022 at 8:53
  • Thanks for your answer. Will this work in XeLaTeX? Does something like XeLuaLaTeX even exist? (:
    – Rain
    Commented May 7, 2022 at 9:23
  • 1
    @Rain no his wouldn't work in xelatex (but there are very few documents that need xetex features and can not use luatex instead) Commented May 7, 2022 at 9:28
  • 3
    @Rain there are no fonts that you can use with xetex that you can not use with luatex. Commented May 7, 2022 at 9:30
  • 1
    @wrb98 - You could replace ( s:gsub ( "%b$$" , "\\smash{%1}" ) with ( s:gsub ( "([gpqy])" , "\\smash{%1}" ). Note that you will have to use \SmashOff ahead of any and all control words, so as to avoid a macro such as \go being "processed". Note also that with this approach, any kerning pairs involving the four characters would be ignored. If that's a problem, give ( s:gsub ( "(%a+)" , "\\smash[b]{%1}" ) a try. (%a is Lua's "magic character" to match any letter, and + means "one or more repetitions".) Remark: you'll need to load the amsmath package for the [b] option.
    – Mico
    Commented Oct 30, 2023 at 15:40

You must log in to answer this question.

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