Warum interagieren amsmath und \char auf diese Weise?

Warum interagieren amsmath und \char auf diese Weise?

Ich habe dies entdeckt, als ich versuchte, \char neu zu definieren, um die Eigenschaft eines Felds zu bezeichnen, und eine seltsame Fehlermeldung erhielt. Unten finden Sie ein Minimalbeispiel, um das Seltsame zu demonstrieren, das passiert ist.

\documentclass[12pt]{article}

\usepackage{amsmath}

\renewcommand{\char}{\stepcounter{section}}

\begin{document}

\section{test}

test$1 + 1 = 2$test$2 + 2 = 4$test

\section{test}

test$1 + 1 = 2$test$2 + 2 = 4$test

\section{test}

\end{document}

Wenn Sie dies setzen, erhalten Sie die Abschnitte mit den Nummern 1, 3 und 4. Beim Experimentieren damit habe ich festgestellt, dass die erste Inline-Mathematik-, Display-Mathematik- oder Align-Umgebung eines Dokuments dazu führt, dass \char einmal aufgerufen wird, und von da an scheint nichts anderes in der Lage zu sein, es erneut aufzurufen. Dies geschieht NUR, wenn das amsmath-Paket geladen ist. Was in aller Welt ist hier los? Gibt es eine Möglichkeit für mich, \char neu zu definieren, ohne seltsame Probleme zu verursachen?

Antwort1

tl;dr

Ist es möglich, sicher neu zu definieren \char? Nicht ohneeine Mengevon Arbeit, die sich als nutzlos erweisen würde.

Tun Sie dies niemals \renewcommandauf einen Befehl, den Sie nicht kennen. Für Ihren Befehl tun Sie

\DeclareMathOperator{\Char}{char}

und verwenden Sie \Char. Oder vielleicht \fldcharwählen Sie den Namen, den Sie für am besten halten, abernicht \char.

Erweiterte Antwort

Der konkrete Fehler ist darauf zurückzuführen, dass es in seinem Makro ein Makro amsmathverwendet , das jedes Mal ausgeführt wird, wenn nach einer Änderung der Schriftgröße zum ersten Mal eine mathematische Formel erscheint.\char\resetMathstrut@

\def\resetMathstrut@{%
  \begingroup
  \setbox\z@\hbox{%
    \mathchardef\@tempa\mathcode`\(\relax
    \def\@tempb##1"##2##3{\the\textfont"##3\char"}%
    \expandafter\@tempb\meaning\@tempa \relax
  }%
 \edef\@tempa{%
     \ht\Mathstrutbox@\the\ht\z@\relax
     \dp\Mathstrutbox@\the\dp\z@\relax}%
  \expandafter\endgroup\@tempa
}

Es ist nicht wirklich notwendig zu beschreiben, was dieses Makro macht, außer zu sagen, dass es eine mathematische Strebe einrichtet, die in den Ausrichtungsumgebungen verwendet werden soll.

Mit Ihrem Code wird dieses Makro nur einmal ausgeführt, aber wenn Sie dem Argument eine Formel hinzufügen, \sectionwerden Sie sehen, dass es noch einmal ausgeführt wird.

Gibt es eine Möglichkeit, sicher neu zu definieren \char? Ja, die gibt es: Erstellen Sie Ihre eigene Kopie des gesamten LaTeX-Baums, fügen Sie \let\primitivechar\charam Anfang von (der Kopie von) hinzu latex.ltxund ersetzen Sie dann jedes andere Vorkommen von \charim gesamten Baum durch \primitivechar. Kompilieren Sie dann die Formate neu. Sie wissen nie, welches Paket verwenden könnte \char.

Eine Folge von ack(oder grep) erzählt, was \char8682 Mal in insgesamt 960 Dateien vorkommt:

> ack -ch '\\char[^a-z]' /usr/local/texlive/2022/texmf-dist/tex/latex/
8682
> ack -cl '\\char' /usr/local/texlive/2022/texmf-dist/tex/latex/ | wc -l
960

Bedenken Sie jedoch, dass niemand außer Ihnen LaTeX auf Ihrem Dokument ausführen kann. Die Antwort auf Ihre Frage lautet also:

Ja, aber aus praktischen Gründen nein.

Einige Hintergründe. Eines der ursprünglichen Ziele von LaTeX3 war es,undefiniertjedes Primitiv und ersetzte sie durch Aliase. Das Team erkannte jedoch, dass dies unpraktisch ist, da dies bedeuten würde, dass praktisch kein aktuelles Paket mit der neuen Version verwendet werden könnte, und es gibt Tausende davon!

Warum wurde dieser Schritt im ursprünglichen LaTeX nicht durchgeführt? Es gibt verschiedene Gründe. Hier sind die wichtigsten:

  1. Als LaTeX geschrieben wurde, war reines TeX das einzige verfügbare Format und LaTeX übernahm mehrere einfache Konstrukte.

  2. der Übergang von einfachem zu LaTeX wäre einfacher und würde die Wiederverwendung von Code ermöglichen;

  3. Computerspeicher war knapp;Wirklichspärlich.

Als LaTeX2e veröffentlicht wurde, hätte dies eine Gelegenheit sein können, das Projekt, jedes Primitiv mit Aliasen zu versehen und durch Aliase zu ersetzen, fortzusetzen, da es nicht so viele Pakete gab. Aber LaTeX würde auf praktisch keiner Maschine laufen, da jeder Alias ​​Speicherplatz beansprucht. Heutzutage sind solche Speicherüberlegungen kein Problem mehr, aber es gibt Tausende von Paketen.

In einigen Fällen ist es möglich, ein Grundelement neu zu definieren, aber nur, um sein Verhalten ein wenig zu ändern: LaTeX macht dies \inputbeispielsweise mit , aber die Neudefinition \inputruft letztendlich immer den Alias ​​des Grundelements auf.

Antwort2

\charist das TeX-Primitiv, um auf ein Zeichen per Nummer zuzugreifen. Eine Neudefinition würde also alle Arten von Latex-Konstrukten zerstören, nicht nuramsmath

\documentclass{article}

\renewcommand{\char}{\stepcounter{section}}


\begin{document}

\begin{picture}(0,0)
\put(0,0){\circle{5}}
\end{picture}
\end{document}

LaTeX kann keinen Kreis der richtigen Größe auswählen.

Verwenden Sie es immer \newcommand, um versehentliche Neudefinitionen zu vermeiden. Verwenden Sie es nur, \renewcommandwenn Sie das Verhalten aller Verwendungen eines vorhandenen Befehls ändern möchten.

verwandte Informationen