Anzeige:
Ergebnis 1 bis 12 von 12

Thema: Abfrage ob command definiert

  1. #1
    Registrierter Benutzer
    Registriert seit
    04.11.2012
    Beiträge
    23

    Abfrage ob command definiert

    Guten Abend,

    ich brauche ein Konstrukt, dass es mir erlaubt, zu überprüfen ob ein bestimmtes command definiert ist. Konkret handelt es sich da um ein als command definiertes Datum. Ist dies gesetzt soll das Datum mit Text auf der Titelseite erscheinen, sonst soll da nichts stehen. Ich hatte da so in diese Richtung gedacht, allerdings bin ich mir nicht sicher, ob das wirklich der richtige weg ist.

    Code:
    \documentclass{scrartcl}
    \usepackage[utf8]{inputenc}
    
    \newcommand{\test}{Beispeil}
    
    \begin{document}
    \@ifundefined{test}{abc}{xyz} 
    \end{document}
    Hier hätte ich gerne den String "abc", wenn die \newcommand Zeile da steht, wenn ich die auskommentiere solllte stattdessen "xyz" gedruckt werden. In der log-File steht dazu
    ! You can't use `\spacefactor' in vertical mode.
    \@->\spacefactor
    \@m
    l.7 \@
    ifundefined{test}{abc}{xyz}
    Sorry, but I'm not programmed to handle this case;
    I'll just pretend that you didn't ask for it.
    If you're in the wrong mode, you might be able to
    return to the right one by typing `I}' or `I$' or `I\par'.

    ! Missing $ inserted.

    $
    l.7 \@
    ifundefined{test}{abc}{xyz}
    I've inserted a begin-math/end-math symbol since I think
    you left one out. Proceed, with fingers crossed.

    LaTeX Font Info: External font `cmex10' loaded for size
    (Font) <7> on input line 7.
    LaTeX Font Info: External font `cmex10' loaded for size
    (Font) <5> on input line 7.
    ! Missing $ inserted.

    $
    l.8 \end{document}

    I've inserted a begin-math/end-math symbol since I think
    you left one out. Proceed, with fingers crossed.

    Missing character: There is no \E8 in font cmex10!
    [1

  2. #2
    Registrierter Benutzer Avatar von sommerfee
    Registriert seit
    02.07.2006
    Beiträge
    1.603
    Da fehlt \makeatletter und \makeatother in deinem Beispiel, so geht's:
    Code:
    \documentclass{scrartcl}
    \usepackage[utf8]{inputenc}
    
    \newcommand{\test}{Beispeil}
    
    \begin{document}
    \makeatletter
    \@ifundefined{test}{abc}{xyz} 
    \makeatother
    \end{document}
    Alternativ kann man auch eTeX-Syntax verwenden:

    Code:
    \documentclass{scrartcl}
    \usepackage[utf8]{inputenc}
    
    \newcommand{\test}{Beispeil}
    
    \begin{document}
    \ifdefined\test
      xyz%
    \else
      abc%
    \fi
    \end{document}
    Geändert von sommerfee (23-12-2013 um 10:20 Uhr)

  3. #3
    Registrierter Benutzer
    Registriert seit
    04.11.2012
    Beiträge
    23
    Okay, dieses \makeatletter und \makeatother war mir schon immer etwas suspekt, daher hab ich die zweite Variante benutzt und konnte mein Problem so lösen. Vielen Dank.

  4. #4
    Registrierter Benutzer Avatar von sommerfee
    Registriert seit
    02.07.2006
    Beiträge
    1.603
    Zitat Zitat von javatar Beitrag anzeigen
    Okay, dieses \makeatletter und \makeatother war mir schon immer etwas suspekt
    Da ist eigentlich nichts suspektes dran; wenn man Makros mit @ im Namen definieren oder benutzen möchte, muß man den Code entweder in ein LaTeX-Paket packen (und mit \usepackage einbinden), oder aber mit \makeatletter... \makeatother klammern. (Dies soll die Verwendung oder gar das ungewollte Überschreiben von internen Makros in regulären Dokumenten erschweren.)

  5. #5
    Registrierter Benutzer Avatar von cgnieder
    Registriert seit
    06.04.2011
    Ort
    Herrenberg
    Beiträge
    254
    Zitat Zitat von javatar Beitrag anzeigen
    Okay, dieses \makeatletter und \makeatother war mir schon immer etwas suspekt,
    Siehe z.B. Was machen eigentlich \makeatletter und \makeatother?

    daher hab ich die zweite Variante benutzt und konnte mein Problem so lösen. Vielen Dank.
    Wenn Du gerne auf die TeX-Syntax verzichten möchtest und die lieber eine LaTeX-Syntax hättest, dann gäbe es dafür auch noch etoolbox' Wrapper:

    Code:
    \documentclass{scrartcl}
    \usepackage[utf8]{inputenc}
    \usepackage{etoolbox}
    \newcommand{\test}{Beispeil}
    
    \begin{document}
    \makeatletter
    \ifdef\test{abc}{xyz} 
    \makeatother
    \end{document}
    Grüße
    Clemens

  6. #6
    Registrierter Benutzer
    Registriert seit
    09.12.2005
    Beiträge
    1.326
    Da mit scrartcl auch scrbase bereits geladen wird, kann man auch einfach \ifundefinedorrelax verwenden:
    Code:
    \documentclass{scrartcl}
    \usepackage[utf8]{inputenc}
    
    \newcommand{\test}{Beispeil}
    
    \begin{document}
    \verb|\test| is \ifundefinedorrelax{test}{un}{}definiert.
    \end{document}
    Näheres zu der Anweisung ist der KOMA-Script-Anleitung zu entnehmen.

  7. #7
    Registrierter Benutzer
    Registriert seit
    04.11.2012
    Beiträge
    23
    Die Funktion vpn den beiden Befehlen hatte ich im Prinzip schon verstanden, ich kam bisher nur nie in die Situation diese verwenden zu müssen und hatte daher wahrscheinlich noch Berühungsängste. Bishre war mir nur die Logik dahinter nicht klar, warum man das @ verwendet, wenn man weiß, dass man das immer so ein Konstrukt rum basteln muss, aber die Begründung hast du jetzt ja drekt mit geliefert.

    Nur noch eine Frage zu den Code von cgnieder
    Code:
    \documentclass{scrartcl}
    \usepackage[utf8]{inputenc}
    \usepackage{etoolbox}
    \newcommand{\test}{Beispeil}
    
    \begin{document}
    \makeatletter
    \ifdef\test{abc}{xyz} 
    \makeatother
    \end{document}
    Warum hier die \make.. Befehle, da ist doch gar kein @ drin?

  8. #8
    Registrierter Benutzer Avatar von cgnieder
    Registriert seit
    06.04.2011
    Ort
    Herrenberg
    Beiträge
    254
    Zitat Zitat von javatar Beitrag anzeigen
    Nur noch eine Frage zu den Code von cgnieder
    [...]
    Warum hier die \make.. Befehle, da ist doch gar kein @ drin?
    Weil ich vergessen habe, sie nach dem Copy&Paste zu entfernen...

    Grüße
    Clemens

  9. #9
    Registrierter Benutzer
    Registriert seit
    04.11.2012
    Beiträge
    23
    Zitat Zitat von cgnieder Beitrag anzeigen
    Weil ich vergessen habe, sie nach dem Copy&Paste zu entfernen...
    Alles klar, danke nochmals und schöne Feiertage

  10. #10
    Registrierter Benutzer
    Registriert seit
    06.03.2010
    Ort
    St. Petersburg, Russland
    Beiträge
    2.468
    Meiner Ansicht nach wird das @ einfach für Befehle benutzt, die mehr für Insider-Sachen gedacht sind. Die also "normalerweise" innerhalb von Paketen oder Klassen geregelt werden und nicht im Dokument, und wenn doch, dann soll derjenige, der das macht, sich wenigstens ein bisschen damit auskennen. Es ist also schon so gedacht, dass man da erst mal Berührungsängste hat. Oder sehe ich das jetzt ganz falsch?

  11. #11
    Registrierter Benutzer Avatar von sommerfee
    Registriert seit
    02.07.2006
    Beiträge
    1.603
    Zitat Zitat von rstuby Beitrag anzeigen
    Oder sehe ich das jetzt ganz falsch?
    Nicht ganz falsch, aber IMHO auch nicht ganz richtig. Eigentlich sind Makros mit @ im Namen interne Makros, die außerhalb des jeweiligen Paketes nicht verwendet werden sollten (und schon gar nicht in Dokumenten), da sie sich in zukünftigen Versionen ändern können. Viele interne Makros von LaTeX (wie etwa \@ifundefined) werden aber mittlerweile von so vielen Paketen verwendet, daß sie nicht mehr in ihrer Schnittstelle geändert werden, weil dann zuviele Pakete nicht mehr korrekt funktionieren würden. LaTeX2e verwendet sogar einige interne Makros nicht mehr (wie z.B. \@tempa), um Problemen mit vorhandenen Paketen aus dem Wege zu gehen.

    Ähnlich ist es mit Makros mit @ in Paketen. Um sich z.B. in das wrapfig-Paket einzuklinken, muß das caption-Paket Makros mit @ im Namen von wrapfig umdefinieren, der Zweck heiligt quasi die Mittel, obwohl es alles andere als schön ist. Es ist ja auch recht unwahrscheinlich, daß sich am wrapfig-Paket nach über 10 Jahren noch etwas ändert ;-) Bei vielen anderen Paketen haben sich das aber andere Paketautoren auch gedacht, z.B. beim endfloat-Paket. Als ich nach sehr vielen Jahren die Version 2.5 veröffentlicht hatte, funktionierten einige Dokumente und Dokumentenklassen nicht mehr, da sie auf interne Makros mit @ im Namen zurückgegriffen hatten, die es aber in Folge der Funktionserweiterungen der Version 2.5 so nicht mehr gab bzw. geändert wurden. Als Folge habe ich dann die Versionen 2.5a bis 2.5d herausgebracht, die keinerlei Änderungen für den Benutzer hatten, sondern nur versucht haben, bezüglich der internen Makros kompatibler zu sein; dies geht so weit, daß sogar alte Makros wieder zur Verfügung gestellt werden, die das Paket selber gar nicht (mehr) verwendet. Das ist zwar eigentlich der falsche Weg, aber viele Dokumentenklassen und Pakete werden nun einmal nicht mehr gepflegt und werden deswegen nicht mehr angepasst - der Anwender wäre also ansonsten der Dumme gewesen, und das muß ja nicht sein.

    Zusammenfassend kann man sagen: LaTeX-Makros mit @ im Namen kann man größtenteils nehmen, da mittlerweile "Standard" und die Entwicklung von LaTeX sowieso schon sehr lange im Endstadium ist. Paket-Makros mit @ im Namen sollte man nicht nehmen, nur dann, wenn es keinen anderen Weg gibt. Wenn das Paket noch gepflegt wird, sollte man lieber zusammen mit dem Autor des Paketes einen sauberen Weg erarbeiten. Ansonsten kommt z.B. sowas dabei heraus: http://tex.stackexchange.com/questio...ing-subfloats/ (Dort wird \subcaption@minipage gepatcht, was prompt nach einem Paketupdate nicht mehr so geklappt hat.)

  12. #12
    Registrierter Benutzer
    Registriert seit
    09.12.2005
    Beiträge
    1.326
    In DTK 3/2013 gab es dazu übrigens einen Artikel: »Was ist eigentlich: die Besonderheit des @-Zeichens in Befehlsnamen?«, der leider noch nicht frei verfügbar ist.

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •