8

I am using the biblatex package and I am trying to modify the \cites command.

The \cites command is defined as

\cites(<pre>)(<post>)[<pre>][<post>]{<key>}...[<pre>][<post>]{<key>}

I'll add some indexes to clarifiy what I'm trying to do.

\cites(<pre_0>)(<post_0>)[<pre_1>][<post_1>]{<key_1>}...[<pre_n>][<post_n>]{<key_n>}

pre_0 will be shown preceding the multicite and post_0 will be shown at the end.

I am trying to write a new command, that behaves exactly like \cites does, with the difference that pre_1 to pre_n are filled with a default value.

All I achieved until now is to use a default value for pre_0 using

\newcommand{\compares}{\cites[Cf. ]}

but I don't need to use pre_0. If it were an optional paramter to my new command, it would be nice, but it's not a must.

I was able to do this for the \cite command like this(Cf. is the default):

\newcommand{\compare}[2][]{\cite[Cf.][#1]{#2}}

Now I'd like to have the same behaviour for the \cites command. How can I achieve this?

2 Answers 2

6

I am only starting to learn how to beat on biblatex. In general, you are trying to declare a new multicite command. For the numeric style the \cites is defined by

\DeclareMultiCiteCommand{\cites}[\mkbibbrackets]{\cite}{\multicitedelim}

so we want

\DeclareMultiCiteCommand{\mycites}[\mkbibbrackets]{\mycite}{\multicitedelim}

We now need to define \mycite to do what we want. Again starting from teh original numeric style

\DeclareCiteCommand{\cite}[\mkbibbrackets]
  {\usebibmacro{prenote}}
  {\usebibmacro{citeindex}%
   \usebibmacro{cite}}
  {\multicitedelim}
  {\usebibmacro{postnote}}

we can go to

\DeclareCiteCommand{\mycite}[\mkbibbrackets]
  {\usebibmacro{myprenote}}
  {\usebibmacro{citeindex}%
   \usebibmacro{cite}}
  {\multicitedelim}
  {\usebibmacro{mypostnote}}

leaving us to define \myprenote and \mypostnote. The originals are defined in biblatex.def as

\newbibmacro*{prenote}{%
  \iffieldundef{prenote}
    {}
    {\printfield{prenote}%
     \setunit{\prenotedelim}}}

\newbibmacro*{postnote}{%
  \iffieldundef{postnote}
    {}
    {\setunit{\postnotedelim}%
     \printfield{postnote}}}

This is where I am not exactly sure what is best. One solution is

\newbibmacro*{myprenote}{x\space}
\newbibmacro*{mypostnote}{, y}

where x and y are whatever you want them to be. I don't think this is really the bibltex way and I think slightly better is

\newbibmacro*{myprenote}{\printtext{x}\setunit{\prenotedelim}}
\newbibmacro*{mypostnote}{\printtext{\addcomma\space y}\setunit{\postnotedelim}}

but I don't really understand what this is doing and I think we should be using field formatting. Putting it all together

\documentclass{article}
\usepackage{biblatex}
\addbibresource{biblatex-examples.bib}
\newbibmacro*{myprenote}{\printtext[prenote]{x}\setunit{\prenotedelim}}
\newbibmacro*{mypostnote}{\printtext[postnote]{\addcomma\space y}\setunit{\postnotedelim}}
\DeclareCiteCommand{\mycite}[\mkbibbrackets]
  {\usebibmacro{myprenote}}
  {\usebibmacro{citeindex}%
   \usebibmacro{cite}}
  {\multicitedelim}
  {\usebibmacro{mypostnote}}
\DeclareMultiCiteCommand{\mycites}[\mkbibbrackets]{\mycite}{\multicitedelim}

\begin{document}
\cites(a)(b)[x][y]{angenendt}[x][y]{bertram}

\mycites(a)(b){angenendt}{bertram}
\end{document}
4
  • +1, looks very promising! I'll give it a try. I won't forget to accept it, if it is my road to success ;) Thank you!!
    – jlordo
    Jan 25, 2013 at 17:07
  • 2
    +1 This is the right idea. To make the definition easier try, say: \newrobustcmd*{\cfautocites}{\AtNextCite{\renewbibmacro*{multiprenote}{\bibstring{confer}\prenotedelim}}\autocites}. This approach should work for any citation command, except maybe \textcites from the verbose styles.
    – Audrey
    Jan 25, 2013 at 17:13
  • @Audrey thank you for the vote of encouragement, but your comment/answer doesn't seem to match my answer at all. If you get a chance I would love to see you expand it into an answer.
    – StrongBad
    Jan 25, 2013 at 18:04
  • 2
    @DanielE.Shub All you really do in defining \mycite is take \cite and use different prenote and postnote macros. My suggestion takes the same approach, but hooks in the redefinition with \AtNextCite.
    – Audrey
    Jan 25, 2013 at 18:27
8

The \AtNextCite hook allows you to easily define variants of existing citation commands.

\newrobustcmd*{\mycite}{\AtNextCite{<code>}\cite}

In <code> you can modify biblatex counters, generic commands, bibliography macros or formatting directives. These changes are applied only to the following \cite. Citation argument parsing can be left to biblatex. A mulitcite variant of \mycite can be defined similarly:

\newrobustcmd*{\mycites}{\AtNextCite{<code>}\cites}

Here's an example addressing your question. In the new citation commands you can override the default prenote \bibstring{confer} by providing a non-empty prenote argument.

\documentclass{article}
\usepackage[style=verbose,maxnames=1]{biblatex}

\newrobustcmd*{\cfautocite}{\cfcitehook\autocite}
\newrobustcmd*{\Cftextcite}{\cfcitehook\Textcite}
\newrobustcmd*{\cfautocites}{\cfcitehook\autocites}
\newrobustcmd*{\Cftextcites}{\cfcitehook\Textcites}

\newrobustcmd*{\cfcitehook}{%
  \AtNextCite{\renewbibmacro*{prenote}{\usebibmacro{prenote:confer}}}}

\newbibmacro*{prenote:confer}{%
  \iffieldundef{prenote}
    {\bibstring{confer}}
    {\printfield{prenote}}%
  \setunit{\prenotedelim}}

\newcommand{\cmd}[1]{\texttt{\textbackslash #1}}
\addbibresource{biblatex-examples.bib}

\begin{document}
\null\vfill\noindent
\cmd{Textcite}: \Textcite[e.g.][10]{companion} showed that... \\
\cmd{autocite}: Filler text \autocite[10]{companion,knuth:ct:a}. \\
\cmd{Textcites}: \Textcites[10]{companion}[e.g.][]{knuth:ct:a}{glashow} showed that... \\
\cmd{autocites}: Filler text \autocites[10]{companion}[e.g.][]{knuth:ct:a}{glashow}. \\\\
\cmd{Cfextcite}: \Cftextcite[e.g.][10]{companion} showed that... \\
\cmd{cfautocite}: Filler text \cfautocite[10]{companion,knuth:ct:a}. \\
\cmd{Cftextcites}: \Cftextcites[10]{companion}[e.g.][]{knuth:ct:a}{glashow} showed that...\\
\cmd{cfautocites}: Filler text \cfautocites[10]{companion}[e.g.][]{knuth:ct:a}{glashow}.
\end{document}

The same approach works for multiprenote - a field that can't be accessed via \DeclareCiteCommand or \DeclareMultiCiteCommand.

\newrobustcmd*{\cfmulticitehook}{%
  \AtNextCite{\renewbibmacro*{multiprenote}{\usebibmacro{multiprenote:confer}}}}

\renewbibmacro*{multiprenote:confer}{%
  \iffieldundef{multiprenote}
    {\bibstring{confer}}
    {\printfield{multiprenote}}%
  \setunit{\prenotedelim}}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .