Bedingte Makros

Bedingte Makros

Ziel:Ich hätte gern ein Makro, das verschiedene Befehle ersetzt, je nachdem, ob der Mathematikmodus angezeigt wird oder nicht. Insbesondere sollte es spitze Klammern mit fester Größe in Textzeilen erzeugen, \langle ... \rangleaber mit variabler Größe in angezeigten mathematischen Zeilen \left<...\right>.

Motivation:Das Makro sollte universell sein, da mathematische Ausdrücke häufig zwischen angezeigten und nicht angezeigten Ausdrücken verschoben werden können (ich schreibe ein Lehrbuch, bearbeite es, bearbeite es erneut usw.). Es wäre eine Quelle von Tippfehlern, wenn ich den Ausdruckscode jedes Mal ändern müsste, wenn ich ihn von oder zu angezeigter Mathematik verschiebe. Das obige Beispiel mit den spitzen Klammern ist die Standardnotation für die Mittelwertbildung in der Physikliteratur.

Der erste Versuchist im MWE unten. Es funktioniert für Inline-Mathematik, aber im Anzeigemodus wird es nicht korrekt ersetzt. LaTeX reagiert mit „Fehlendes \right. eingefügt“ oder „Ungültiges mathematisches Umgebungstrennzeichen“, je nach Verwendung von $$oder \[bzw. \]. Die Kompilierung im Batchmodus erzeugt eine Ausgabe mit der richtigen Größe der linken Klammer, aber der falschen rechten. Dieses Ergebnis hängt nicht von der Verwendung von \def oder \newcommand ab. Es wurde getestet, dass es für eckige Klammern dasselbe ist [...].

Das System:Mac OS 12.7.2., LaTeX: <Dies ist pdfTeX, Version 3.141592653-2.6-1.40.24 (TeX Live 2022) (vorinstalliertes Format=Latex) eingeschränkt \write18 aktiviert. Wechsel in den erweiterten Modus (./mwe.tex LaTeX2e <2021-11-15> Patchlevel 1 L3-Programmierebene <2022-02-24>>

Jetzt ein 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}

Antwort1

Ich rate von diesem Ansatz ab. Er führt im Allgemeinen nicht zum „Richtigen“.

Da der Kunde immer Recht hat, können Sie amsmath \if@displaybedingte Vorteile nutzen.

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

Bildbeschreibung hier eingeben

Antwort2

\ifinnertestet einen Aspekt des TeX-Zustands auf niedriger Ebene, tut aber grundsätzlich nie etwas Nützliches in Tex in Bezug auf Elemente auf Dokumentebene.

Hier in \laden TestsWAHRin Inline-Mathematik undFALSCHin, würde aber in Anzeigeumgebungen wie oder als \[wahr getestet werden, wenn sie den Anzeigestil über nicht eingebenamsmathgatheralign
$\displaystyle display math$
$$ display math$$

Der Test ist jedoch immerWAHRin \ra, da der Ausdruck entweder bereits innerlich war oder, wenn \ifinnerer am Anfang falsch war, \laausgeführt wird \left< , was true setzt \ifinner, da alle mathematischen Berechnungen innerhalb des Links-Rechts-Paares im inneren Modus erfolgen. Sie führen also nie die passende aus \right.

\left..\rightSollte auch in Fällen vermieden werden, in denen eine Dehnung nicht erforderlich ist, da sie den horizontalen Abstand beeinflusst.

Es steht ein robusterer Mechanismus zur Verfügung, mathtoolsder auch den horizontalen Abstand von links nach rechts korrigiert.

Bildbeschreibung hier eingeben

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

Antwort3

TeX schaltet den Satzmodus auf „inner“ um, wenn \leftim Mathematikmodus ein -Trennzeichen auftritt.

Es scheint also darum zu gehen, \ifinnerzum richtigen Zeitpunkt zu expandieren.

Mit diesem Befehl können Sie \expandeddie \ifinner-Tests auswerten lassen, bevor ein weiterer Satz erfolgt und dabei der Satzmodus umgeschaltet wird:

\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 manchen Situationen kann der Umstand, dass dieser Weg \laund \raund somit \langle/ \left\langleund \rangle/ \right\ranglevollständig ausgebaut werden, ein Problem darstellen.

\unexpandedSie können diese auch in ein Makro einbetten lassen :

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

Bildbeschreibung hier eingeben

Vorbehalt:

Wie bereits erwähnt vonDavid Carlisle in seiner Antwort, diese Ansätze schlagen in jedem Fall bei LaTeX-Umgebungen fehl, wo der Inhalt nicht im Anzeigemodus, sondern im Inline-Modus mit einem über ausgewählten Anzeigestil gesetzt wird \displaystyle.

verwandte Informationen