Zeilen 1099-1121 der Datei pgfmanual-en-macros.tex

Zeilen 1099-1121 der Datei pgfmanual-en-macros.tex

Ich versuche zu verstehen, wie Befehle für die Verwendung in LaTeX-Dokumentationen gesetzt werden. Zur Verdeutlichung:nichtLaTeX zum Erstellen von Dokumentation verwenden, anstatt Dokumentation in LaTeX über die Verwendung von LaTeX zu schreiben (wie in den Handbüchern). Soweit mir bekannt ist, gibt es dafür (leider) keinen Begriff, der LaTeX-Dokumentation vom Erstellen von Dokumentation mit LaTeX unterscheidet.

Zeilen 1099-1121 der Datei pgfmanual-en-macros.tex

https://www.ctan.org/pkg/pgf?lang=en

Dieser Code „sieht für mich so aus“, als würde er AT-Zeichen entfernen, aber ich weiß es nicht. Warum ist das notwendig? Wie funktioniert es?

{
  \makeatletter
  \global\let\myempty=\@empty
  \global\let\mygobble=\@gobble
  \catcode`\@=12
  \gdef\getridofats#1@#2\relax{%
    \def\getridtest{#2}%
    \ifx\getridtest\myempty%
      \expandafter\def\expandafter\strippedat\expandafter{\strippedat#1}
    \else%
      \expandafter\def\expandafter\strippedat\expandafter{\strippedat#1\protect\printanat}
      \getridofats#2\relax%
    \fi%
  }

  \gdef\removeats#1{%
    \let\strippedat\myempty%
    \edef\strippedtext{\stripcommand#1}%
    \expandafter\getridofats\strippedtext @\relax%
  }

  \gdef\stripcommand#1{\expandafter\mygobble\string#1}
}

Argumentation

Der Grund, warum ich das verstehen möchte, ist, dass ich anscheinend Befehle mit dem folgenden Code setzen kann. Ich vermute, es gibt Fälle, in denen meine Idee nicht funktioniert.

Es gibt auch Einschränkungen:

  • Füge Befehle mit Argumenten ein, sodass ich sie (in NewEnvironmit #1) als Beispiel unter der Erklärung setzen kann (z. B. würde \hello{input1} und dann die Verwendung #1in NewEnvironnicht funktionieren)

\documentclass{article}
\usepackage{fontspec}
\usepackage{environ}
\NewEnviron{command}[1]{% 
\begin{minipage}[t]{.3\textwidth}
\texttt{\string#1}
\end{minipage}
\hfill
\begin{minipage}[t]{.7\textwidth}
\BODY
\end{minipage}
\xdef\putcommandexample{\BODY}% Set BODY to variable http://tex.stackexchange.com/a/14392/13552
}%
\begin{document}
\section{Friendly Commands}
\begin{command}{\hello}
This command greets the reader in a friendly manner.
\end{command}
\begin{command}{\goodbye}
This command greets the reader in a friendly manner.
\end{command}
\end{document}

Randbemerkung für Interessierte: Statt minipages habe ich die Befehle auch mit dem Paket in den Rand gesetzt marginnote. Sieht ganz gut aus.

\NewEnviron{command}[1]{% 
\reversemarginpar\marginnote{\texttt{\string#1}}
\BODY
\par
}%

Ausgabe

Bildbeschreibung hier eingeben

Antwort1

Die Frage„Warum ist es notwendig?“Dazu müsste man die gesamte Dokumentation lesen. Wie es funktioniert, ist leicht zu erkennen.

Das Makro \getridofatsentscheidet, ob das, was im Eingabestrom bis darauf folgt, \relaxeinen Kategoriecode 12 enthält @.

Es ist jedoch besser, zunächst einmal zu sehen, wie \removeatses funktioniert. Es sollte einen Befehlsnamen alsverspanntArgument; zunächst wird \strippedateine leere Tokenliste initialisiert. Dann

\edef\strippedtext{\stripcommand#1}

Dies setzt \strippedtexteine Zeichenfolge, die den Befehlsnamen ohne Backslash enthält, da dies nicht der Fall ist.

\expandafter\mygobble\string#1

Beispielsweise \removeats{\abc@def}wird \expandafter\mygobble\string\abc@defdies zunächst \abc@defin eine Zeichenfolge mit Zeichen der Kategorie 12 umgewandelt (aber mit Kategoriecode 11 für Buchstaben, die nach erscheinen @, wenn das Makro in einem \makeatotherKontext aufgerufen wird) und dann \mygobbleder Backslash verbraucht.

Nach dieser Vorbereitung \expandafter\getridofats\strippedtext @\relaxwird aufgerufen, was die folgenden Token im Eingabestrom erzeugt:

\getridofats abc@def@\relax

Wenn wir uns die Definition von ansehen \getridofats, sehen wir, dass #1ist abc, während #2ist def@. Wenn der Aufruf \removeats{\abcdef}gesehen worden wäre, würde der Eingabestrom enthalten

\getridofats abcdef@\relax

und #1wäre abcdef, während #2leer wäre.

Das Makro \getridtestist so definiert, dass es auf erweitert wird #2; im ersten Fall ist es nicht leer, im zweiten Fall ist es das.

Danach \ifx\getridtest\myemptywird im zweiten Fall „true“ und im ersten Fall „false“ zurückgegeben.

Angenommen, der Test gibt true zurück (zweiter Fall). Dann

\expandafter\def\expandafter\strippedat\expandafter{\strippedat abcdef}

ausgeführt, was #1(in diesem Fall abcdef) an den vorherigen Wert von anhängt \strippedat. Dies mag nutzlos erscheinen, da \strippedates auf leer initialisiert wurde. Aber wir werden später sehen, was im „falschen“ Fall passiert.

Angenommen, der Test gibt false zurück (erster Fall). Dann

  \expandafter\def\expandafter\strippedat\expandafter{\strippedat abc\protect\printanat}%
  \getridofats def@\relax

ist erledigt: Das erste Stück wird an angehängt \strippedat, dann wird \protect\printanatdas Makro \getridofatserneut aufgerufen, um den letzten Block zu verarbeiten.

Meiner Meinung nach kein besonders gut geschriebenes Makro. Die Aufrufe

\removeats\abcdef
\removeats\abc@def
\removeats\ab@cd@ef

führen \strippedatzu enthalten, bzw.

abcdef
abc\protect\printanat def
ab\protect\printanat cd\protect\printanat ef

wobei \printanatdefiniert ist durch

\def\printanat{\char`\@}

Natürlich \protectist es definitiv nicht erforderlich, sofern das Makro mit definiert ist \def\printanat{\char64 }, aber das ist eine persönliche Entscheidung. Da die Dokumentation mit LaTeX verarbeitet wird, hätte ich mich wahrscheinlich für entschieden

\DeclareRobustCommand{\printanat}{\char`\@ }

(Beachten Sie das Leerzeichen am Ende. Es ist falsch, es nicht zu haben.)

Offenbar dient der Mechanismus dazu, das Schreiben @von Zeichen in die .auxDatei zu vermeiden und so Probleme mit ihrem Kategoriencode (der beim Lesen von LaTeX-Hilfsdateien auf 11 gesetzt wird) zu vermeiden.


expl3Version, die in einem Kontext ausgegeben werden soll, in dem @der Kategoriecode 12 vorliegt.

\ExplSyntaxOn
\cs_new_protected:Npn \removeats #1
 {
  \tl_set:Nx \strippedat { \cs_to_str:N #1 }
  \tl_replace_all:Nnn \strippedat { @ } { \protect\printanat }
 }
\ExplSyntaxOff

verwandte Informationen