Seite 1 von 2

Eigener Befehl mit optionalem Argument und Fallunterscheidun

Verfasst: Sa 4. Sep 2010, 21:33
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]

Re: Eigener Befehl mit optionalem Argument und Falluntersche

Verfasst: Sa 4. Sep 2010, 22:07
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

Verfasst: Sa 4. Sep 2010, 22:26
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.

Verfasst: Sa 4. Sep 2010, 23:02
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

Verfasst: Sa 4. Sep 2010, 23:12
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 ...

Verfasst: Sa 4. Sep 2010, 23:45
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

Verfasst: So 5. Sep 2010, 00:10
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!

Verfasst: So 5. Sep 2010, 08:32
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

Verfasst: So 5. Sep 2010, 10:38
von talueng
Sehr schön, vielen Dank nochmal! :)

Verfasst: So 5. Sep 2010, 11:21
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.