PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Abfrage ob command definiert



javatar
23-12-2013, 00:09
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.


\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.
<inserted text>
$
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.
<inserted text>
$
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

sommerfee
23-12-2013, 00:19
Da fehlt \makeatletter und \makeatother in deinem Beispiel, so geht's:


\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:



\documentclass{scrartcl}
\usepackage[utf8]{inputenc}

\newcommand{\test}{Beispeil}

\begin{document}
\ifdefined\test
xyz%
\else
abc%
\fi
\end{document}

javatar
23-12-2013, 01:05
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.

sommerfee
23-12-2013, 01:13
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.)

cgnieder
23-12-2013, 01:15
Okay, dieses \makeatletter und \makeatother war mir schon immer etwas suspekt,

Siehe z.B. Was machen eigentlich \makeatletter und \makeatother? (http://texwelt.de/wissen/fragen/1)


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:


\documentclass{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage{etoolbox}
\newcommand{\test}{Beispeil}

\begin{document}
\makeatletter
\ifdef\test{abc}{xyz}
\makeatother
\end{document}

Grüße

klops
23-12-2013, 10:55
Da mit scrartcl auch scrbase bereits geladen wird, kann man auch einfach \ifundefinedorrelax verwenden:
\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 (http://mirrors.ctan.org/macros/latex/contrib/koma-script/doc/scrguide.pdf) zu entnehmen.

javatar
23-12-2013, 12:17
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

\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?

cgnieder
23-12-2013, 12:38
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

javatar
23-12-2013, 15:03
Weil ich vergessen habe, sie nach dem Copy&Paste zu entfernen...

Alles klar, danke nochmals und schöne Feiertage

rstuby
26-12-2013, 22:54
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?

sommerfee
27-12-2013, 10:07
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/questions/134881/how-can-i-automatically-center-all-floats-including-subfloats/ (Dort wird \subcaption@minipage gepatcht, was prompt nach einem Paketupdate nicht mehr so geklappt hat.)

klops
28-12-2013, 16:14
In DTK 3/2013 (http://www.dante.de/DTK/Ausgaben/dtk2013.html) gab es dazu übrigens einen Artikel: »Was ist eigentlich: die Besonderheit des @-Zeichens in Befehlsnamen?«, der leider noch nicht frei verfügbar ist.