Definieren Sie ein Makro, das nach hoch- und/oder tiefgestellten Zeichen sucht, diese „absorbiert“ und ihr Argument verschiebt

Definieren Sie ein Makro, das nach hoch- und/oder tiefgestellten Zeichen sucht, diese „absorbiert“ und ihr Argument verschiebt

Ich habe viele mathematische Makros, die bereits per Definition einen Hoch- und/oder Tiefgestellten haben, also so etwas wie

\newcommand*{\mymathsym}{x^{\text{foo}}_{\text{bar}}}

Im Textkörper benötigen diese Symbole häufig einen zusätzlichen Hoch-/Tiefstellungsindex. Das bedeutet, dass der Autor daran denken muss, das Hauptsymbol in ein Paar {}-Klammern zu setzen, da sonst ein doppelter Hoch-/Tiefstellungsfehler auftritt.

\begin{equation}
  {\mymathsym}^{\text{extra}}
\end{equation}

Der Extra-Hochindex wird zum Sekundär-Hochindex und dieser wird etwas höher und kleiner gesetzt: zusätzlicher hochgestellter Dies hat zwei Nachteile: a) Im speziellen Anwendungsbereich stehen beide Hochindexe konzeptionell auf der gleichen Hierarchieebene. Mit anderen Worten, eigentlich müssten beide Hochindexe als Liste "foo, extra" gedruckt werden und die umgekehrte Reihenfolge "extra, foo" wäre ebenso gut. b) Wenn Primär-Hochindex und -Subindex sehr ungleich lang sind, wird der Sekundär-Hochindex weit auseinander gesetzt, z.B.

\newcommand*{\mymathsymlong}{x^{\text{foo}}_{\text{very long foobar}}}

Und

\begin{equation}
{\mymathsymlong}^{\text{extra}}
\end{equation}

Erträge weit auseinander liegende hochgestellte Zahl

Als Workaround verwende ich derzeit die folgende Definition, die ein optionales Argument annimmt und das Argument an den internen hochgestellten Index anhängt:

\newcommand*{\mymathsymext}[1][]{x^{\text{foo}\if!#1!\else, #1\fi}_{\text{very long foobar}}}

(Anm.: Ich weiß, dass die Bedingung \if!#1!nicht die richtige Art ist, um auf ein leeres Argument zu testen, weil sie fehlschlägt, wenn das Argument zu einem erweitert wird !. Aber ich denke, Sie verstehen, was das Makro macht.)

Es wird verwendet als

\begin{equation}
\mymathsymext \qquad\text{vs.}\qquad \mymathsymext[\text{extra}]
\end{equation}

und ergibt Bildbeschreibung hier eingeben Dies hat jedoch zwei große Nachteile: a) \newcommandunterstützt nur ein einziges optionales Argument. Daher muss ich beim Entwurf entscheiden, ob eventuell ein zusätzlicher Hoch- oder Tiefstand benötigt wird. Ich kann nicht beides unterstützen. b) Der Benutzer muss sich eine ungewöhnliche Syntax für die Platzierung zusätzlicher Hoch-/Tiefstände merken.

Frage:

Wie definiert man ein Makro, \mymathsymsuperdas

  • ^durchsucht weiter, wenn darauf ein hochgestelltes Zeichen <tok> und/oder ein tiefgestelltes Zeichen <tok> folgt, _jeweils gefolgt von einem zusätzlichen Token <tok>
  • "absorbiert sie" und
  • verschiebt <tok> an das Ende seines internen Sup-/Subskripts, getrennt durch ein Komma?

Vollständiges MWE:

\documentclass{article}

\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage[utf8]{inputenc}
\usepackage{amsmath}

\newcommand*{\mymathsym}{x^{\text{foo}}_{\text{bar}}}

\newcommand*{\mymathsymlong}{x^{\text{foo}}_{\text{very long foobar}}}

\newcommand*{\mymathsymext}[1][]{x^{\text{foo}\if!#1!\else, #1\fi}_{\text{very long foobar}}}

\begin{document}

Here, the author must know that \verb#\mymathsym# has already a super- and subscript and must remember to put the main symbol into a pair of \{\}-braces, otherwise a double sup-/subscript error occurs.
The extra superscript becomes a secondary superscript and it set slightly higher and smaller:
\begin{equation}
{\mymathsym}^{\text{extra}}
\end{equation}

If the primary sup- and subscript are very unbalanced in their length, the secondary subscript is set very far apart:
\begin{equation}
{\mymathsymlong}^{\text{extra}}
\end{equation}

This extended macro takes an optional argument and ``absorbs'' the extra superscript into the primary superscript:
\begin{equation}
\mymathsymext \qquad\text{vs.}\qquad \mymathsymext[\text{extra}]
\end{equation}
Still, the author must remember this ``unusual'' syntax and it only supports either an extra super- or subscript, bot not both.

\paragraph{Question:}
How does one define a macro \verb#\mymathsymsuper# that
\begin{itemize}
  \item scans ahead if it followed by a superscript character $\verb!^!\langle \mathit{token}_\text{sup}\rangle$ and/or subscript character $\verb!_!\langle \mathit{token}_\text{sub}\rangle$ each followed by an    additional token $\mathit{token}_\text{sup}$ and $\mathit{token}_\text{sub}$ resp.
  \item ``absorbs them'', and
  \item moves $\mathit{token}_\text{sup}$ and/or $\mathit{token}_\text{sub}$ to end of its internal sup-/subscript separated by a comma?
\end{itemize}

\end{document}

Antwort1

Mit ist es ein Kinderspiel xparse:

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}

\NewDocumentCommand{\mymathsym}{e{^_}}{%
  x^{\mathrm{foo}\IfValueT{#1}{,#1}}_{\mathrm{bar}\IfValueT{#2}{,#2}}%
}

\begin{document}

\begin{gather}
\mymathsym \\
\mymathsym^{\mathrm{extrasup}} \\
\mymathsym_{\mathrm{extrasub}} \\
\mymathsym^{\mathrm{extrasup}}_{\mathrm{extrasub}} \\
\mymathsym_{\mathrm{extrasub}}^{\mathrm{extrasup}}   
\end{gather}

\end{document}

Bildbeschreibung hier eingeben

Mit e{^_}sucht das Makro voraus nach ^oder _(in beliebiger Reihenfolge) und weist #1dem #2Hoch-/Tiefstand zu. Sie können mit auf das Vorhandensein testen \IfValueT(oder \IfValueTFwenn Sie eine Aktion mit einem fehlenden Hoch-/Tiefstand ausführen möchten).

verwandte Informationen