\ThisStyle \SavedStyle quälend langsam ... Alternativen?

\ThisStyle \SavedStyle quälend langsam ... Alternativen?

Beim Arbeiten mit benutzerdefinierten Hutglyphen mit der ersten Version vondiese Lösung, pdflatexdas Kompilieren eines Dokuments dauerte sehr lange. In der verlinkten Antwort wird darauf hingewiesen, dass es sich um eine langsamere Lösung handelt, aber das war zunächst ziemlich langsam, was aber nicht weiter schlimm war. Dann wurde es gerade noch erträglich langsam, nachdem ich zwei gestapelte Hüte verwendet hatte. Und nachdem ich nachgeforscht und drei Hüte gestapelt hatte, wurde es ewig langsam.

Hier ist ein kurzer Grund:

  \documentclass[12pt, a4paper]{article}
  \usepackage{scalerel}

  \begin{document}
  \ensuremath{
  \ThisStyle{
      \SavedStyle\ThisStyle{
      \SavedStyle\ThisStyle{
      \SavedStyle\ThisStyle{
      \SavedStyle\ThisStyle{
      \SavedStyle\ThisStyle{
      \SavedStyle\ThisStyle{
      \SavedStyle\ThisStyle{
          \SavedStyle . }}}}}}}
  }}
  \end{document}

pdflatexMit oder dauert das 15 Sekunden latex. Wenn wir eine Verschachtelungsebene entfernen, sind es nur noch 2 Sekunden. Wenn wir eine Ebene mehr als im Beispiel hinzufügen, kommen wir auf 269 Sekunden.

Offensichtlich passiert hier etwas Exponentielles.scalerel.sty, der Code für \SavedStyleund \ThisStylelautet wie folgt:

\def\SavedStyle{\csname @mstyle\m@switch\endcsname}


\newcommand\ThisStyle[1]{%
  \ifmmode%
    \def\@mmode{T}\mathchoice%
      {\edef\m@switch{D}\LMex=1ex\relax\LMpt=1pt\relax#1}%
      {\edef\m@switch{T}\LMex=1ex\relax\LMpt=1pt\relax#1}%
      {\edef\m@switch{S}\LMex=\scriptstyleScaleFactor ex\relax%
                        \LMpt=\scriptstyleScaleFactor pt\relax#1}%
      {\edef\m@switch{s}\LMex=\scriptscriptstyleScaleFactor ex\relax%
                        \LMpt=\scriptscriptstyleScaleFactor pt\relax#1}%
  \else%
    \def\@mmode{F}%
    \edef\m@switch{T}\LMex=1ex\relax\LMpt=1pt\relax#1%
  \fi%
}

Ich vermute, dass das Argument \ThisStyleauf jeder Ebene viermal erweitert wird. Mit anderen Worten: \mathchoicees ist nicht faul.

Gibt es eine Möglichkeit, das #1Äußere dieser \mathchoiceArgumente zu entfernen und trotzdem das gleiche Verhalten beizubehalten? Bleiben diese \m@switchund \LMexDefinitionen über das nächste " " hinaus bestehen }?

Wenn nicht, gibt es einen anderen Ansatz, um das Äquivalent zu erreichen \ThisStyle? \SavedStyleMir fällt nichts ein, was in linearer Zeit in Bezug auf die Verschachtelungstiefe funktionieren würde und bei Vorhandensein von Reentrancy immer noch korrekt funktionieren würde.

Antwort1

Kurze Antwort: Nein – es gibt keine Möglichkeit, dies in allen Situationen oder in einem LaTeX-Durchgang korrekt zu tun.


Nach viel Lernen und Experimentieren scheint es, dass der einzige Weg, dies zu umgehen, so etwas ist wieManuels Antwort und Kommentar hier. Es gibt kein \whatIsTheMathStyleHere(es sei denn, wir sind auf LuaTeX). Der\mathchoicecommand ist ein TeX-Grundelement.Die Wahl der vier Optionen erfolgtspätUm zu verstehen, was "spät" bedeutet, müssen wir uns bewusst machen, dass TeXeinige Verdauungsphasen: Auge, Mund,Speiseröhre, Magen, von denen jeder das logische Dokument in eine Form umwandelt, die dem endgültigen visuellen Dokument näher kommt, wobei eine Teilmenge der semantisch bedeutsamen Token durchgearbeitet wird.Manchmal geht es zum vorherigen Stadium zurück.(Aber rechtfertigt die fast zu gute, um wahr zu sein, schriftstellerische Intelligenz, die wir mittlerweile erwarten, nicht ein gewisses Maß an Komplexität?) Also, das Zeug rund um\mathchoice Undinnerhalb seiner Argumente wird makroerweitert, bevor \mathchoicees selbst angewendet wird. Tatsächlich werden, soweit ich das beurteilen kann, nicht nur Erweiterungen, sondern auch andere TeX-Befehle wie \ifxvor verarbeitet \mathchoice, sodass es innerhalb jeder Verarbeitungsphase mehrere geschichtete Unterphasen geben könnte?

Manuels Alternative, genannt \mathcase, verwendet einen cleveren Trick, bei dem ein nanoskaliger Raum eingefügt wird, dessen Größe vom mathematischen Stil abhängt. Anschließend wird die Größe des Raums überprüft und der Stil bestimmt. Wie kann das funktionieren, wenn der endgültige mathematische Stil überall erst bestimmt werden soll, nachdem das Dokument eine vollständig aufgelöste Struktur hat? Dies geschieht mithilfe des zref-saveposPakets. In der Dokumentation für zreffindet sich ein Hinweis:

Die Seitenposition ist nicht sofort bekannt. Zuerst muss die Seite von der asynchronen Ausgaberoutine von TEX erstellt werden. Der Zeitpunkt, zu dem die Position bekannt ist, ist daher der Zeitpunkt der Seitenausgabe. Daher ist ein Referenzsystem nützlich, bei dem die Informationen im ersten Durchlauf aufgezeichnet und für den zweiten Durchlauf verfügbar gemacht werden.

Mit anderen Worten: Der richtige Mathematikstil wird bestimmt beiversenden, ab diesem Zeitpunkt kann es in keiner \ifoder anderen Entscheidungsstrukturen mehr verwendet werden, wird aber in der AUX-Datei gespeichert (wie Sie sehen können, wenn Sie die AUX-Datei für das folgende Beispiel untersuchen) und wird beim zweiten Durchgang verfügbar.

Leider führt dies zu folgendem Problem bei kaskadierenden mathematischen Stilen, die sich in einer verschachtelten Reihe von \mathcases ausbreiten: Wenn die Verschachtelung N-Ebenen tief ist, ist die Stabilität des Dokuments erst garantiert, wenn es N-mal kompiliert wurde. Beispiel:

(Das ist vonManuels Antwort, wo ich gerade den Dokumenttext geändert habe.)

\documentclass{scrartcl}

\usepackage{mathtools}


\usepackage{zref-savepos}
\newcount\mmstynum
\newcount\tmpnum
\protected\def\getmsty
 {\global\advance\mmstynum1 %
  \expandafter\getstyA\expandafter{\number\mmstynum}}
\protected\def\getstyA#1%
 {\zsaveposx{mmsty-#1-a}%
  \mathchoice{\kern4sp}{\kern3sp}{\kern2sp}{\kern1sp}%
  \zsaveposx{mmsty-#1-b}
  \tmpnum=\numexpr
            \zposx{mmsty-#1-b} - \zposx{mmsty-#1-a}
          \relax
   \ifcase\tmpnum\or\kern-1sp \or\kern-2sp \or\kern-3sp \or\kern-4sp \fi}
\protected\def\mstycase
 {\ifcase\tmpnum\expandafter\gobblefour\or\expandafter\usefourth\or
   \expandafter\usethird\or\expandafter\usesecond\or
   \expandafter\usefirst\else\expandafter\gobblefour\fi}
\protected\def\mathcase{\getmsty\mstycase}

\long\def\gobblefour#1#2#3#4{}
\long\def\usefourth#1#2#3#4{#4}
\long\def\usethird#1#2#3#4{#3}
\long\def\usesecond#1#2#3#4{#2}
\long\def\usefirst#1#2#3#4{#1}


\def\tmpa{If this prints it means it doesn't work}
\newcommand*\foo
 {\mathcase % compare with \mathchoice
   {\def\tmpa{displaystyle}}
   {\def\tmpa{textstyle}}
   {\def\tmpa{scriptstyle}}
   {\def\tmpa{scriptscriptstyle}}
  \text\tmpa}

\let\savedstyle\displaystyle

\def\thisstyle#1{\begingroup\mathcase{\let\savedstyle\displaystyle}{\let\savedstyle\textstyle}{\let\savedstyle\scriptstyle}{\let\savedstyle\scriptscriptstyle}#1\endgroup}

\begin{document}

\[
\sum \scriptstyle \sum \thisstyle{%
    \fbox{\( \sum \savedstyle \sum \thisstyle{%
    \fbox{\( \sum \savedstyle \sum \thisstyle{%
    \fbox{\( \sum \savedstyle \sum \)}%
    }\)}%
    }\)}%
}
\]

\end{document}

Wenn wir uns das PDF während der Kompilierung im TeXworks-Viewer ansehen, sehen wir:

Nach dem ersten Durchgang:

1

Nach dem zweiten Durchgang:

2. Platz

Nach dem dritten Durchgang:

3. Platz

Nach dem vierten Durchgang:

4. Platz

Die Lösung opfert also die Anzahl der Durchläufe, um die Geschwindigkeit jedes einzelnen Durchlaufs zu verbessern. (Es wäre allerdings gut, wenn Sie auch gewarnt würden, wenn das Dokument noch nicht stabil ist.) Auch wenn es keine perfekte Lösung ist, bin ich davon überzeugt, dass dies angesichts der Natur von TeX (und es ist unwahrscheinlich, dass sich TeX selbst in dieser Hinsicht in absehbarer Zukunft ändern wird) die beste mögliche Alternative ist.

Es gibt auch das mathstylePaket (siehe Diskussion hier), das umgeht, \mathchoiceindem es alle Trennzeichen im Mathematikmodus nutzt (abernicht \(offensichtlich!) und fügen eine Logik ein, um den Überblick über den aktuellen Mathematikstil zu behalten, der nicht mit TeX übereinstimmt. Aber wie inAdityas Kommentar hier, es gibt Fälle, in denen es das Verhalten von TeX nicht vorhersagen kann. Zum Beispiel bei der Verwendung von \over, \atopTeX-Primitiven. (Der Kommentar ist allerdings 5 ​​Jahre alt. Vielleicht ist er inzwischen besser geworden?)

Die beste Lösung besteht also darin, die Anzahl \mathchoiceder Verschachtelungsebenen zu reduzieren (beachten Sie, dass a in , , \mathchoiceenthalten ist ).\ThisStyle\text\mathpalette ) nach Möglichkeit zu reduzieren (z. B.Ich habe ein paar redundante \TextStyles in der Vorgängerfrage entfernt), oder wenn Sie den mathematischen Stil mit gesundem Menschenverstand ableiten können, könnten Sielokal neu definieren \mathchoice, um es kurzzuschließen.

Alles in allem ist es ein überraschendes Ergebnis. Dies ist das erste Mal, dass ich etwas mit LaTeX machen wollte und es sich als unpraktisch herausstellte. Außerdem \mathchoicebin ich beim Herumprobieren auf alle Schrecken von Makrosprachen gestoßen, bei denen man nie genau weiß, was in welcher Reihenfolge expandiert. (Schauen Sie sich einfach die „klassische“ Methode an, \expandafter\expandafter\expandafter\expandafter\expandafter...nämlichdiese Lösung, und Sie wissen, dass etwas nicht stimmt.) Und schließlich \mathchoicescheint die Semantik von für Software aus den Siebzigern etwas ineffizient zu sein, selbst wenn ihr eigentlicher Zweck nur darin besteht, ein einzelnes benutzerdefiniertes Symbol zu setzen ...

verwandte Informationen