Ich bin hier schon mehrmals auf den Befehl \detokenize gestoßen. Was macht der eigentlich genau?

gefragt 26 Sep '13, 16:08

welle's gravatar image

welle
106222631
Akzeptiert-Rate: 0%

bearbeitet 26 Jun '14, 16:41

gast3's gravatar image

gast3
(ausgesetzt)


Vereinfacht gesagt wandelt \detokenize alle Token seines Arguments außer den Leerzeichen in Tokens der Klasse other. Die Leerzeichen bleiben Leerzeichen-Token. Interessant ist das vor allem deshalb, weil damit auch keine Befehle mehr expandiert werden. Beispiel:

Open in Online-Editor
\documentclass{article}

\begin{document}
{\ttfamily\detokenize{\das\ginge\ohne\detokenize\schief}}
\end{document}

Zu beachten ist dabei, dass hier die (nicht definierten) Befehle trotzdem zunächst als solche gelesen werden, es wird also zuerst ein Befehlstoken generiert. Dieses wird jedoch nicht als solches expandiert, sondern statt der Expansion in other Token gewandelt. Deshalb sind in der Ausgabe Leerzeichen. Das ist beispielsweise in der folgenden Situation wichtig:

Open in Online-Editor
\documentclass{article}

\begingroup
\catcode`\@=0 % @ ist jetzt ein Escape-Zeichen wie \
\gdef\test{\detokenize{@aber@was@passiert@hier}}
\endgroup

\begin{document}
\ttfamily\test
\end{document}

Wie man sieht, werden die Befehlstoken hier nicht mit @, sondern mit \ ausgegeben, genau wie sie auch von \show in die Log-Datei geschrieben oder von \meaning ausgegeben werden. Das ist nun einmal die interne TeX-Darstellung von Befehlstoken (zumindest solange \escapechar nicht geändert wird).

Die genaue Beschreibung findet sich im e-TeX-Manual, da es sich dabei um eine Erweiterung von e-TeX handelt.

Permanenter link

beantwortet 26 Sep '13, 17:50

saputello's gravatar image

saputello
11.1k174365
Akzeptiert-Rate: 51%

bearbeitet 07 Jul '15, 10:05

Da @saputello ja schon wie gewohnt hervorragend geklärt hat, was \detokenize macht, dachte ich, ich gebe vielleicht ein kleines Beispiel, wo man es einsetzen kann. Das folgende definiert einen Befehl \ifempty{<test>}{<wahr>}{<falsch>}:

\makeatletter
\newcommand\ifempty[1]{%
  \if\relax\detokenize{#1}\relax
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}
\makeatletter

Wie in Was macht if? geklärt wurde, expandiert \if so lange, bis es zwei nicht expandierbare Token findet und vergleicht dann deren Zeichencodes. Da \detokenize expandierbar ist, gibt in dieser Definition von \ifempty{<test>}{<wahr>}{<falsch>} der \if-Test nur dann <wahr> zurück, wenn das Argument wirklich leer ist. Wenn #1 leer ist, dann expandiert \detokenize zu nichts und \if vergleicht \relax mit \relax:

\if\relax\detokenize{}\relax => \if\relax\relax => wahr

Wenn #1 nun ein Leerzeichen ist, dann wird \relax mit dem Lehrzeichen verglichen und gibt <falsch> zurück. Das würde mit

\if\relax#1\relax

nicht funktionieren, da das Leerzeichen hier nach dem ersten \relax ignoriert würde. (Das entspräche also eher einem \ifblank.) Auch eine Eingabe von \relax würde <falsch> ergeben, was mit \if\relax#1\relax ebenfalls <wahr> ergäbe. Das \relax wird von \detokenize ja in eine Reihe von Zeichen mit Kategorie-Code 12 verwandelt, weshalb nun \relax mit \ verglichen wird.

Nachdem das alles gesagt wurde: mit etoolbox stehen einem zahlreiche solcher Test-Makros bereit, man muss sie also gar nicht selbst implementieren.

Permanenter link

beantwortet 27 Sep '13, 21:29

cgnieder's gravatar image

cgnieder
22.1k253463
Akzeptiert-Rate: 60%

bearbeitet 27 Sep '13, 21:30

Deine Antwort
Vorschau umschalten

Folgen dieser Frage

Per E-Mail:

Wenn sie sich anmelden, kommen Sie für alle Updates hier in Frage

Per RSS:

Antworten

Antworten und Kommentare

Markdown-Grundlagen

  • *kursiv* oder _kursiv_
  • **Fett** oder __Fett__
  • Link:[Text](http://url.com/ "Titel")
  • Bild?![alt Text](/path/img.jpg "Titel")
  • nummerierte Liste: 1. Foo 2. Bar
  • zum Hinzufügen ein Zeilenumbruchs fügen Sie einfach zwei Leerzeichen an die Stelle an der die neue Linie sein soll.
  • grundlegende HTML-Tags werden ebenfalls unterstützt

Frage-Themen:

×52
×22
×2

gestellte Frage: 26 Sep '13, 16:08

Frage wurde gesehen: 24,186 Mal

zuletzt geändert: 07 Jul '15, 10:05