Macros condicionales

Macros condicionales

Meta:Me gustaría tener una macro que sustituya diferentes comandos dependiendo de si se muestra en modo matemático o no. En particular, debería generar corchetes angulares de tamaño fijo en líneas de texto, \langle ... \ranglepero de tamaño variable en matemáticas mostradas \left<...\right>.

Motivación:La macro debe ser universal porque las expresiones matemáticas a menudo se pueden mover entre expresiones mostradas y no mostradas (escribo un libro de texto, lo edito, lo reedito, etc.). Sería una fuente de errores tipográficos si necesitara cambiar el código de expresión cada vez que lo muevo desde o hacia las matemáticas mostradas. El ejemplo anterior con corchetes angulares es la notación estándar para promediar en la literatura de física.

El primer intentoestá en el MWE a continuación. Funciona para matemáticas en línea, pero no sustituye correctamente cuando está en el modo de visualización. LaTeX reacciona con "Falta \right. Insertado" o "Delimitador de entorno matemático incorrecto" dependiendo del uso de $$o \[y \], respectivamente. La compilación en modo por lotes genera una salida con el tamaño correcto del corchete izquierdo, pero con el derecho incorrecto. Este resultado no depende del uso de \def o \newcommand. Se prueba que es el mismo para los corchetes [...].

El sistema:Mac OS 12.7.2., LaTeX: <Esto es pdfTeX, versión 3.141592653-2.6-1.40.24 (TeX Live 2022) (formato precargado=latex) restringido \write18 habilitado. ingresando al modo extendido (./mwe.tex LaTeX2e <2021-11-15> nivel de parche 1 capa de programación L3 <2022-02-24>>

Ahora una 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}

Respuesta1

Recomiendo no utilizar este enfoque. Generalmente no hará "lo correcto".

De todos modos, como el cliente siempre tiene la razón, puedes explotar amsmath \if@displayel condicional.

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

ingrese la descripción de la imagen aquí

Respuesta2

\ifinnerprueba un aspecto de bajo nivel del estado de TeX pero básicamente nunca hace nada útil en tex en relación con ningún elemento a nivel de documento.

Aquí, en \lasus pruebas.Verdaderoen matemáticas en línea yFALSOpero \[se probaría como verdadero en amsmathentornos de visualización como gathero aligncuando ingresan al estilo de visualización a través de
$\displaystyle display math$no
$$ display math$$

Sin embargo la prueba es siempreVerdaderoporque \rala expresión ya era interna o si \ifinnerera falsa al principio \lase ejecutará, \left< lo que se establece \ifinnercomo verdadero ya que todas las matemáticas dentro del par izquierda-derecha están en modo interno. Entonces nunca ejecutas la coincidencia \right.

También \left..\rightse debe evitar en los casos en los que no sea necesario estirar ya que afecta el espaciado horizontal.

Se proporciona un mecanismo más robusto mathtoolsque también corrige el espaciado horizontal de izquierda a derecha.

ingrese la descripción de la imagen aquí

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

Respuesta3

TeX cambia el modo de composición tipográfica a "interno" cuando encuentra un \leftdelimitador en el modo matemático.

Entonces parece que la cuestión es expandirse \ifinneren el momento adecuado.

Puede utilizar \expandedpara \ifinnerevaluar las pruebas antes de realizar más composición tipográfica y, por lo tanto, cambiar el modo de composición tipográfica:

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

En algunas situaciones, la circunstancia de que este camino \lay \rapor lo tanto \langle/ \left\langley \rangle/ \right\ranglese expanda por completo puede ser un problema.

\unexpandedTambién puedes hacer que una macro los incluya en :

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

ingrese la descripción de la imagen aquí

Advertencia:

Como ya señaló porDavid Carlisle en su respuesta., estos enfoques, en cualquier caso, fallan en entornos LaTeX donde las cosas en realidad no se componen en modo de visualización, sino en modo en línea con el estilo de visualización seleccionado a través de \displaystyle.

información relacionada