Eigener Befehl mit optionalem Argument und Fallunterscheidun

Redefinition von Makros, Definition eigener Befehle sowie neuer Umgebungen


talueng
Forum-Anfänger
Forum-Anfänger
Beiträge: 39
Registriert: Mo 31. Mai 2010, 13:32

Eigener Befehl mit optionalem Argument und Fallunterscheidun

Beitrag von talueng »

Ich möchte mir einen eigenen Zitationsbefehl basteln, der \cite{} ersetzt:

1. Argument: BibTeX-Key.
2. Argument: Seitenzahl (von).
3. Argument (optional): Seitenzahl (bis).

Aufruf dann als: \ct{BibTeXKey}{von}{bis} (z.B. \ct{Lee1990}{23}{40}

Der Befehl soll dann folgendes ausgeben:

- Wenn das optionale Argument fehlt: \cite{#1}, S. #2 (z.B. \cite{Lee1990}, S. 23)
- Wenn das optionale Argument gegeben ist:
... Wenn die Differenz aus bis-von=1 ist: \cite{#1}, S. #2 f. (z.B. \cite{Lee1990}, S. 23 f.)
... Wenn die Differenz aus bis-von<=5 ist: \cite{#1}, S. #2 ff. (z.B. \cite{Lee1990}, S. 23 ff.)
... Wenn die Differenz aus bis-von>5 ist: \cite{#1}, S. #2--#3. (z.B. \cite{Lee1990}, S. 23--40)

Bislang habe ich folgende Anfangslösung:
\newcommand*{\ct}[3]{%
	\cite{#1}, S. #2
 	\ifx\relax#3\relax
 	\else
    --#3
	\fi
} 
Das gibt mir aber leider immer den zweiten Fall aus, auch wenn der dritte Paramter eigentlich weggelassen wird (lt. diesem Beitrag sollte bei Weglassen des dritten Parameters eigentlich der else-Fall ausgeführt werden).[/b]

CrazyHorse
Forum-Guru
Forum-Guru
Beiträge: 252
Registriert: Di 16. Mär 2010, 09:39

Re: Eigener Befehl mit optionalem Argument und Falluntersche

Beitrag von CrazyHorse »

talueng hat geschrieben:Ich möchte mir einen eigenen Zitationsbefehl basteln, der \cite{} ersetzt:

1. Argument: BibTeX-Key.
2. Argument: Seitenzahl (von).
3. Argument (optional): Seitenzahl (bis).

Aufruf dann als: \ct{BibTeXKey}{von}{bis} (z.B. \ct{Lee1990}{23}{40}
etwas abgeändert, das optionale Argument ist vorne:
\documentclass{article}

\newcounter{testA}
\makeatletter
\newcommand*\ct[2][]{%
  \cite{#2}\ifx\relax#1\relax\else, S\,%
  \expandafter\Seite@i#1-\@nil\fi}
\def\Seite@i#1-#2\@nil{%
  \ifx\relax#2\relax %    ohne -
    #1\else
    \setcounter{testA}{#2}%
    \addtocounter{testA}{-#1}%
    \ifnum\thetestA=1
       1f.\else\ifnum\thetestA<6 
         1ff.\else1-23.\fi\fi\fi}
\makeatother

\begin{document}

A~\ct{foo}
B~\ct[10]{foo}
C~\ct[1-2]{foo}
D~\ct[1-4]{foo}
E~\ct[17-33]{foo}

\begin{thebibliography}{xxx}
\bibitem{foo}Foo, bar, baz 2010
\end{thebibliography}

\end{document}
Herbert

talueng
Forum-Anfänger
Forum-Anfänger
Beiträge: 39
Registriert: Mo 31. Mai 2010, 13:32

Beitrag von talueng »

Hallo Herbert, danke vielmals. Leider scheint es einen kleinen Haken zu geben:

Der folgende Aufruf:

Vgl. \ct{Benner2009} \\%
Vgl. \ct[23]{Benner2009} \\%
Vgl. \ct[23-24]{Benner2009} \\%
Vgl. \ct[23-27]{Benner2009} \\%
Vgl. \ct[24-500]{Benner2009b} \\%
führt bei mir zur Ausgabe:


Vgl. Benner(2009a) -- korrekt.
Vgl. Benner(2009a),S.23 -- korrekt.
Vgl. Benner(2009a),S.-1f. -- nicht korrekt.
Vgl. Benner(2009a),S.-1ff. -- nicht korrekt.
Vgl. Benner(2009b),S.-1–23-. -- nicht korrekt.

CrazyHorse
Forum-Guru
Forum-Guru
Beiträge: 252
Registriert: Di 16. Mär 2010, 09:39

Beitrag von CrazyHorse »

talueng hat geschrieben:Hallo Herbert, danke vielmals. Leider scheint es einen kleinen Haken zu geben:

Der folgende Aufruf:

Vgl. \ct{Benner2009} \\%
Vgl. \ct[23]{Benner2009} \\%
Vgl. \ct[23-24]{Benner2009} \\%
Vgl. \ct[23-27]{Benner2009} \\%
Vgl. \ct[24-500]{Benner2009b} \\%
führt bei mir zur Ausgabe:


Vgl. Benner(2009a) -- korrekt.
Vgl. Benner(2009a),S.23 -- korrekt.
Vgl. Benner(2009a),S.-1f. -- nicht korrekt.
Vgl. Benner(2009a),S.-1ff. -- nicht korrekt.
Vgl. Benner(2009b),S.-1–23-. -- nicht korrekt.
das war ein wenig schnell gestrickt ...
\def\Seite@i#1-#2-#3\@nil{%
  \ifx\relax#2\relax %    ohne -
    #1\else
    \setcounter{testA}{#2}%
    \addtocounter{testA}{-#1}%
    \ifnum\thetestA=1
       1f.\else\ifnum\thetestA<6 
         1ff.\else1--23.\fi\fi\fi}
sollte gehen.

Herbert

talueng
Forum-Anfänger
Forum-Anfänger
Beiträge: 39
Registriert: Mo 31. Mai 2010, 13:32

Beitrag von talueng »

Leider auch nicht. :( Das führt jetzt zu zwei Fehlermeldungen:
Runaway argument?
24]{Benner2009} \\Vgl. \ct[23-27]{Benner2009} \\Vgl. \ct[24-500]{BeETC.
! File ende while scanning use of \Seite@i.
! Extra \else.
\@include ...ediate \closeout \@partaux \fi \else
\deadcycles \z@ \@nameuse ...

CrazyHorse
Forum-Guru
Forum-Guru
Beiträge: 252
Registriert: Di 16. Mär 2010, 09:39

Beitrag von CrazyHorse »

talueng hat geschrieben:Leider auch nicht. :( Das führt jetzt zu zwei Fehlermeldungen:
Bei mir nicht ...
\documentclass{article}

\newcounter{testA}
\makeatletter
\newcommand*\ct[2][]{%
  \cite{#2}\ifx\relax#1\relax\else, S\,%
  \expandafter\Seite@i#1--\@nil\fi}
\def\Seite@i#1-#2-#3\@nil{%
  \ifx\relax#2\relax %    ohne -
    #1\else
    \setcounter{testA}{#2}%
    \addtocounter{testA}{-#1}%
    \ifnum\thetestA=1
       1f.\else\ifnum\thetestA<6 
         1ff.\else1--23.\fi\fi\fi}
\makeatother

\begin{document}


Vgl. \ct{foo} \\%
Vgl. \ct[23]{foo} \\%
Vgl. \ct[23-24]{foo} \\%
Vgl. \ct[23-27]{foo} \\%
Vgl. \ct[24-500]{foo} 

\begin{thebibliography}{xxx}
\bibitem{foo}Foo, bar, baz 2010
\end{thebibliography}

\end{document}
Herbert

talueng
Forum-Anfänger
Forum-Anfänger
Beiträge: 39
Registriert: Mo 31. Mai 2010, 13:32

Beitrag von talueng »

Jetzt funktioniert er zwar, gibt aber wieder falsches aus:

Aufruf:
Vgl. \ct[45]{Benner2009} \\%
Vgl. \ct[45-46]{Benner2009} \\%
Vgl. \ct[45-48]{Benner2009} \\%
Vgl. \ct[45-500]{Benner2009b} \\%
Vgl. Benner(2009a), S 45
Vgl. Benner(2009a), S 1f.
Vgl. Benner(2009a), S 1ff.
Vgl. Benner(2009b), S 1–23.
Offenbar habe ich die Fehlerstellen aber selbst gefunden, jedenfalls scheint es jetzt zu funktionieren. Vielleicht kannst Du trotzdem nochmal als zweites Auge drübergucken. Folgende Fehler habe ich geändert:

a) Hinter dem "S" fehlte ein Punkt -> "S."
b) Offenbar sind überall ein paar Rauten (#) verloren gegangen, weshalb es zu den fehlerhaften Ausgaben kam:
b1) 1f.\else\ifnum -> #1f.\else\ifnum
b2) 1ff.\else1--23. -> #1ff.\else#1--#2
c) Am Ende von b2) war ein Punkt zuviel
d) Ausserdem habe ich zwischen Seitenzahl und "f." (bzw. "ff.") noch der typografischen Schönheit halber ein geschütztes Leerzeichen eingefügt.

Vollständiger Code:
\newcounter{testA}
\makeatletter
\newcommand*\ct[2][]{%
  \cite{#2}\ifx\relax#1\relax\else, S.\,%
  \expandafter\Seite@i#1--\@nil\fi}
\def\Seite@i#1-#2-#3\@nil{%
  \ifx\relax#2\relax %    ohne -
    #1\else
    \setcounter{testA}{#2}%
    \addtocounter{testA}{-#1}%
    \ifnum\thetestA=1
       #1\,f.\else\ifnum\thetestA<6
         #1\,ff.\else#1--#2.\fi\fi\fi}
\makeatother 
Vielen Dank für die schöne Lösung, hätte ich alleine nie hinbekommen und hilft mir sehr!

CrazyHorse
Forum-Guru
Forum-Guru
Beiträge: 252
Registriert: Di 16. Mär 2010, 09:39

Beitrag von CrazyHorse »

talueng hat geschrieben: Vollständiger Code:
\newcounter{testA}
\makeatletter
\newcommand*\ct[2][]{%
  \cite{#2}\ifx\relax#1\relax\else, S.\,%
  \expandafter\Seite@i#1--\@nil\fi}
\def\Seite@i#1-#2-#3\@nil{%
  \ifx\relax#2\relax %    ohne -
    #1\else
    \setcounter{testA}{#2}%
    \addtocounter{testA}{-#1}%
    \ifnum\thetestA=1
       #1\,f.\else\ifnum\thetestA<6
         #1\,ff.\else#1--#2.\fi\fi\fi}
\makeatother 
ja, so sollte es eigentlich gleich sein ...

Herbert

talueng
Forum-Anfänger
Forum-Anfänger
Beiträge: 39
Registriert: Mo 31. Mai 2010, 13:32

Beitrag von talueng »

Sehr schön, vielen Dank nochmal! :)

Benutzeravatar
KOMA
TeX-Entwickler
TeX-Entwickler
Beiträge: 2958
Registriert: Fr 4. Jul 2008, 17:28
Kontaktdaten:

Beitrag von KOMA »

talueng hat geschrieben:
\ifnum\thetestA=1
\theZählername sollte man nie für nummerische Vergleiche heranziehen, weil das die Ausgabe des Zählers ist und auch bei eigenen Zählern nicht sichergestellt ist, dass die nicht jemand aus irgendwelchen Gründen ändern. Besser ist, direkt den Wert des Zählers zu verwenden, also \value{Zählername} und damit in diesem Fall:
\ifnum \value{testA}=1
An dieser Stelle ist übrigens auch das Leerzeichen bzw. der Zeilenumbruch nach der 1 ganz wichtig, damit TeX das Lesen der Zahl wirklich beendet. Will man auf Nummer sicher gehen, kann man auch ein \relax hinter die Zahl stellen.

Antworten