2

Goal: I would like to have a macro that substitutes different commands depending in whether in displayed math mode or not. In particular, it should generate fixed-size angular brackets in text lines, \langle ... \rangle, but variable-size in displayed math, \left<...\right>.

Motivation: The macro should be universal because mathematical expressions may be often moved between displayed and non-displayed expressions (I write a textbook, edit it, re-edit etc). It would be a source of typos if I needed to change the expression code each time when moving it from or to displayed math. The above example with the angular brackets is the standard notation for averaging in the physics literature.

The first attempt is in the MWE below. It works for inline math, but fails to substitute correctly when in the display mode. LaTeX reacts with "Missing \right. inserted" or "Bad math environment delimiter" depending on the usage of $$ or \[ and \], respectively. Compilation in the batch mode generates an output with the correct size of left bracket, but wrong right one. This result does not depend on the usage of \def or \newcommand. It is tested to be the same for square brackets [...].

The system: Mac OS 12.7.2., LaTeX: <This is pdfTeX, Version 3.141592653-2.6-1.40.24 (TeX Live 2022) (preloaded format=latex) restricted \write18 enabled. entering extended mode (./mwe.tex LaTeX2e <2021-11-15> patch level 1 L3 programming layer <2022-02-24>>

Now an MWE:

\documentclass{article}
\def \la{\ifinner \langle \else \left< \fi }
\def \ra{\ifinner \rangle \else \right> \fi }
\begin{document}
The macros work in the text line: $\la \int \Omega_n^2 dt \ra$, 
but do not in the displayed math. Obviously, the 
false text is not expanded properly, but why?  
\[
\la \int \Omega_n^2 dt \ra 
\]
\end{document}
16
  • 1
    \ifinner basically never does anything useful in tex. Jan 8 at 9:45
  • Welcome to TeX.SE!
    – Mensch
    Jan 8 at 9:45
  • 1
    Welcome. // Can you please EDIT your question and add some motivation for your question? E.g. why do you want this, and what will you achieve once you have it? Etc. Thank you
    – MS-SPO
    Jan 8 at 10:09
  • 1
    I would use \DeclarePairedDelimiter from mathtools which will give you \foo{xxx} making <xxx> with control over the size of < used. Jan 8 at 10:51
  • 1
    your definitions give errors as \ifinner is false in the display math (it is not false in all display math, it would be true in an align) but then it starts \left< and after that the math is set with \ifinner true and so the test at the right takes the other branch. The \ifinner on the right will never be false. Jan 8 at 10:54

3 Answers 3

4

I advise against using this approach. It won't generally do “the right thing”.

Anyway, since the customer is always right, you can exploit amsmath \if@display conditional.

\documentclass{article}
\usepackage{amsmath}

\makeatletter
\newcommand{\la}{\if@display\left\fi\langle}
\newcommand{\ra}{\if@display\right\fi\rangle}
\makeatother

\begin{document}

The macros work in the text line: $\la \int \Omega_n^2 \, dt \ra$,
and also in displayed math
\[
\la \int \Omega_n^2 \, dt \ra
\]
\begin{align}
I=\la \int \Omega_n^2 \, dt \ra
\end{align}
\begin{gather}
I=\la \int \Omega_n^2 \, dt \ra
\end{gather}

\end{document}

enter image description here

2
  • Thank you egreg! It works. I just wonder, how does the integral symbol know if it is inline or displayed? Is the method the same? Jan 9 at 11:58
  • @VKphysicist That's essentially built in TeX. See the rules in Appendix G of the TeXbook.
    – egreg
    Jan 9 at 13:19
3

\ifinner tests a low level aspect of TeX's state but it basically never does anything useful in tex in relation to any document level elements.

Here, in \la it tests True in inline math and False in \[ but would test true in amsmath display environments such as gather or align as they enter displaystyle via
$\displaystyle display math$ not
$$ display math$$

However the test is always True in \ra as either the expression was already inner, or if \ifinner was false at the start \la will execute \left< which sets \ifinner true as all math within the left-right pair is in inner mode. So you never execute the matching \right.

Also \left..\right should be avoided in cases where stretching is not needed as it affects the horizontal spacing.

A more robust mechanism is provided by mathtools which also corrects for the horizontal spacing from left-right.

enter image description here

\documentclass{article}
\def\test{\relax\ifinner T\else F\fi}

\usepackage{mathtools}

\DeclarePairedDelimiter\ang\langle\rangle

\begin{document}

a $\test  \ang{\int \Omega_n^2 dt}  \ang[\big]{\int \Omega_n^2 dt}$

\[
\test \ang{\int \Omega_n^2 dt}  \ang*{\int \Omega_n^2 dt}  \ang[\Big]{\int \Omega_n^2 dt}
\]

\begin{equation}
  \test \ang{\int \Omega_n^2 dt}  \ang*{\int \Omega_n^2 dt} \ang[\Big]{\int \Omega_n^2 dt}
\end{equation}

\begin{gather}
  \test \ang{\int \Omega_n^2 dt}  \ang*{\int \Omega_n^2 dt} \ang[\Big]{\int \Omega_n^2 dt}
\end{gather}
\end{document}
5
  • Thank you David! The explanation of the error is very clear and it is nicely illustrated with your '\test'. It looks suitable to use '\ang*' as a universal command, but it puts also '\left...\right' in inline math, which I would like to avoid (please, correct me if I am wrong). Jan 9 at 11:44
  • see last line \ang does not use left/right \ang* does Jan 9 at 11:47
  • Do I understand it correctly that \ang{X} is equivalent to \langle X \rangle, while \ang*{X} is \left\langle X \right\rangle? If so, the commands for inline and displayed math need to be different, without or with the star, respectively. Jan 9 at 12:35
  • @VKphysicist except it fixes the horizontal spacing (like mleftright package) but as shown above I wouldn't use the * form often, it's often too big, the \Big version is big enough on the last row. But yes it doesn't do quite what you ask (as tex doesn't really support exactly what you asked for) Jan 9 at 14:28
  • Thank you anyway. I learned a lot from this conversation. Jan 9 at 16:27
1

TeX switches the typesetting-mode to "inner" when encountering a \left-delimiter in math mode.

So it seems the issue is about expanding \ifinner at the right moment in time.

You can use \expanded for having the \ifinner-tests evaluated before any more typesetting and hereby switching the typesetting-mode takes place:

\documentclass{article}
\newcommand*\la{\ifinner\else\expandafter\left\fi\langle}%
\newcommand*\ra{\ifinner\else\expandafter\right\fi\rangle}%
\begin{document}
The macros work in the text line: $\la \int \Omega_n^2 dt \ra$, 
and also do work in the displayed math.
\[%
\expanded{\la \unexpanded{\int \Omega_n^2 dt} \ra}
\]%
\end{document}

In some situations the circumstance that this way \la and \ra and thus \langle/\left\langle and \rangle/\right\rangle get expanded completely might be a problem.

You can have a macro wrap these into \unexpanded as well:

\documentclass{article}
\newcommand\inangle[1]{%
  \expanded{%
    \ifinner\else\unexpanded{\left}\fi\unexpanded{\langle}%
    \unexpanded{#1}%
    \ifinner\else\unexpanded{\right}\fi\unexpanded{\rangle}%
  }%
}%
\begin{document}
The macros work in the text line: $\inangle{\int \Omega_n^2 dt}$, 
and also do work in the displayed math.
\[\inangle{\int \Omega_n^2 dt}\]
\end{document}

enter image description here

Caveat:

As already noted by David Carlisle in his answer, these approaches in any case fail with LaTeX-environments where stuff actually is not typeset in display mode but is typeset in inline mode with display style selected via \displaystyle.

You must log in to answer this question.

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