Es gibt \if… Befehle in allen möglichen Variationen: \ifx, \ifnum, \ifdim, \@ifundefined, \@ifpackageloaded, \ifodd, etc., und zusätzlich gibt es noch die persönlichen mit \newif\if… kreierten Befehle.

Doch was genau macht das ganz normale \if, und wann wird dieses verwendet?

gefragt 15 Aug '13, 10:36

Epllus's gravatar image

Epllus
59059
Akzeptiert: 75%

bearbeitet 15 Aug '13, 10:47

Clemens's gravatar image

Clemens
19.0k113060

\if<token1><token2> testet beide Token in Bezug auf den Character-Code. Die Token werden dabei expandiert, wenn es sich um Makros handelt. Ich verwende es v.a. um auf leere Argumente zu testen: \if\relax\detokenize{#1}\relax: wenn #1 leer ist, wird \relax mit \relax verglichen, die Abfrage ist wahr. Enthält #1 irgendwas (selbst \relax), dann ist die Abfrage falsch, weil \detokenize eine Reihe von Charaktern mit Kategorie-Code 12 zurücklässt (was aus \relax sechs Charaktere machen würde).

(15 Aug '13, 10:52) Clemens

@Clemens: Das Leerzeichen (Zeichencode 32) ist bei \detokenize übrigens ein Space-Tokens, bekommt also als Ausnahme Kategorie-Code 10, was natürlich für Dein Beispiel keine Rolle spielt, weil ein Leerzeichen ja nicht nichts ist, auch wenn manche Anwender das anders sehen.

(15 Aug '13, 11:15) saputello

@saputello Ich weiß, ich hatte nur das Gefühl, dass mein Kommentar schon zu lang würde, deshalb hab ich das einfach unterschlagen ;)

(15 Aug '13, 11:20) Clemens

@Clemens Gut zu wissen, dass man auch mit \if testen kann, ob ein Argument leer ist. Bisher kannte ich nur \ifx\\#1\\.

(16 Aug '13, 03:23) Epllus

Nach \if expandiert TeX so lange, bis zwei nicht expandierbare Tokens gefunden werden. Ist das nicht expandierbare Token eine Kontrollsequenz, also beispielsweise ein TeX Primitiv, so wird diesem der Code 256 zugeordnet. Ansonsten wird der Zeichencode des Tokens (kann bei TeX zwischen 0 und 255 liegen, da TeX nur 8-Bit-Zeichen verarbeitet) genommen. Diese beiden Codes werden dann verglichen.

Beispiele:

  • \if\noexpand\end\relax ja\else nein\fi

Ergibt: ja, weil \noexpand\end zu einem nicht expandierbaren \end expandiert und diesem als Kontrollsequenz dann 256 zugeordnet wird und \relax nicht expandierbar ist und direkt 256 zugeordnet bekommt.

  • \ifx abja\else nein\fi

Ergibt: nein, weil a und b nicht expandierbare Tokens sind und der Zeichencode von a und b nicht gleich ist.

  • \def\a{a}\if a\a ja\else nein\fi

Ergibt: ja, weil das erste a nicht expandierbar ist, \a ebenfalls zu a expandiert und dann die beiden a den gleichen Zeichencode haben.

  • \def\a{a}\if \a aja\else nein\fi

Ergibt: ja, weil \a zu a expandiert und dann die beiden a den gleichen Zeichencode haben.

  • \def\a{ab}\def\b{ab}\if \a\b ja\else nein\fi

Ergibt: nein, weil \a zu ab expandiert, das zwei nicht expandierbare Tokens sind, a und b unterschiedlichen Zeichencode haben und damit der \else-Teil ausgeführt wird.

  • \def\a{aa}\def\b{bb}\if \a\b ja\else nein\fi

Ergibt: bbja, weil \a zu aa expandiert, das zwei nicht expandierbare Tokens sind, a und a denselben Zeichencode haben und dann \b ja vor dem \else übrig bleiben.

  • \def\a{aa}\def\b{bb}\ifx \a\b ja\else nein\fi

Ergibt: nein, weil \ifx anders als \if funktioniert.

Als weiterführende Literatur empfehle ich hierzu »TeX by Topic« (Kapitel 13) oder »The TeXbook«.

Im LaTeX-Kern wird \if beispielsweise verwendet, um zeichenweise die Ein-Zeichen-Optionen für die Gleitumgebungsoptionen mit einzelnen Buchstaben zu vergleichen oder die einzelnen Zeichen einer kleinen, römischen Zahl in Großbuchstaben für eine große, römische Zahl zu wandeln oder die Platzierungs-Optionen von \makebox, \parbox, minipage oder tabular zeichenweise mit entsprechenden Buchstaben zu vergleichen.

\@ifundefined und \@ifpackageloaded sind übrigens nicht mit \if, \ifx oder \ifodd zu vergleichen, da sie eine ganz andere Syntax haben. Die \if… … \else … \fi-Syntax ist für diese nicht verwendbar, da TeX bei dieser Syntax eine Abkürzung nimmt, sobald es weiß, ob die Bedingung zutrifft oder nicht. Es wird nämlich je nachdem der true-Teil oder der else-Teil einfach übersprungen, wobei nicht mehr expandiert wird, sondern lediglich Ebenen von \iftrue … \else … \fi und \iffalse … \else … \fi mit berücksichtigt werden. Deshalb darf man auf keinen Fall eine Definition wie:

\def\@ifundefined#1{\expandafter\ifx\csname #1\endcsname\relax}

verwenden. Diese würde beispielsweise in

\iffalse
  \def\test{ok}%
  \@ifundefined\test ok\fi
\else
  not ok
\fi

Zu einem Extra \else-Fehler führen, weil \@ifundefined\test nicht expandiert würde und damit das erste \fi bereits das Ende von \iffalse wäre. Aus genau diesem Grund, ist \@ifundefined im LaTeX-Kern stattdessen eine Anweisung mit drei Argumenten (wobei die letzten beiden von \@firstoftwo oder \@secondoftwo gelesen werden). Ich erwähne das, weil Anfänger gerne solche Fehler machen.

Permanenter link

beantwortet 15 Aug '13, 10:52

saputello's gravatar image

saputello
18.4k22352

bearbeitet 15 Aug '13, 11:21

Perfekt! Danke :)

(16 Aug '13, 03:24) Epllus
Deine Antwort auf die Frage (nicht auf andere Antworten)
Knebel-Vorschau

Folge dieser Frage

Per E-Mail:

Wenn Du Dich anmeldest, kannst Du Updates hier abonnieren

Per RSS:

Antworten

Antworten und Kommentare

Aktuelle Buch-Infos

LaTeX Cookbook

LaTeX Beginners Guide

Limitierter Rabatt ebook
50% Coupon code tDRet6Y

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üge einfach zwei Leerzeichen an die Stelle ein, an der die neue Zeile sein soll.
  • grundlegende HTML-Tags werden ebenfalls unterstützt

Zugeordnete Themen:

×21
×10

Frage gestellt: 15 Aug '13, 10:36

Frage wurde angeschaut: 4,935 Mal

Zuletzt aktualisiert: 16 Aug '13, 03:24