6

What is the right way to define a macro with an optional argument that can be called within the <postnote> optional argument to biblatex \cite?

The last two \cite below don't work.

(Unless they are enclosed in braces as the third and fourth \cite)

enter image description here

\documentclass{article}
\usepackage{xparse}
\usepackage[backend=biber, style=authortitle]{biblatex}
\usepackage{ifthen}
\usepackage{filecontents}

\DeclareFieldFormat{postnote}{#1}
\bibliography{mybib.bib}

\begin{filecontents}{mybib.bib}
@Book{mykey, author={Author}, title={Title}, journal={Journal}, year={1950}}
\end{filecontents}

\newcommand         \x [2][] {\ifthenelse{\equal{#1}{}}{}{(#1)}#2}
\NewDocumentCommand \y {mo}  {#1\IfValueT{#2}{(#2)}}

\begin{document}

\cite [\x{100}]      {mykey}

\cite [\y{100}]      {mykey}

\cite [{\x[a]{100}}] {mykey}

\cite [{\y{100}[a]}] {mykey}

\cite [\x[a]{100}]   {mykey}

\cite [\y{100}[a]]   {mykey}

\end{document}
2
  • 3
    Adding the braces is the right thing to do. {} matching is built in to the TeX parser (that is matching characters of catcode 1 and 2) LaTeX [] options are parsed with a delimited macro so they end at the first ] without counting nested []. So you need the {} to hide the inner square bracket. Jan 23, 2013 at 23:31
  • @DavidCarlisle That's true for commands defined using the standard LaTeX method (which is what biblatex does), but not those using xparse, which does deal correctly with the nesting here.
    – Joseph Wright
    Jan 24, 2013 at 15:25

1 Answer 1

11

The postnote formatting directive already acts on the contents of the postnote field. Its default definition can be found in biblatex.def:

\DeclareFieldFormat{postnote}{\mkpageprefix[pagination]{#1}}

Passing macros like \x{100} to the postnote argument prevents biblatex from recognizing page references. So you should modify the directive instead. The example below takes this approach. Postnotes can be specified in the form:

\cite[<prenote>][(<postnote prefix>)(<postnote suffix>)<postnote stem>]{<key>}

where the postnote prefix and suffix arguments are optional. When only one is given it is assumed to be a suffix. New directives are used to format each of the three postnote parts.

\documentclass{article}
\usepackage{biblatex}
\usepackage[colorlinks]{hyperref}

% just for demonstration
\ExecuteBibliographyOptions{parentracker=false}
\renewcommand*{\multicitedelim}{\addsemicolon\space}

\DeclareFieldFormat{postnote:stem}{%
  \addcolon\space\mkcomprange[{\mkpageprefix[pagination]}]{#1}}
\DeclareFieldFormat{postnote:prefix}{#1}
\DeclareFieldFormat{postnote:suffix}{\addcomma\space#1}
\DeclareFieldFormat{postnote}{\mkpostnote{#1}}

\makeatletter

\newrobustcmd*{\mkpostnote}[1]{\mkpostnote@i#1&}

\def\mkpostnote@i{%
  \@ifnextchar(%)
    {\mkpostnote@ii}
    {\mkpostnote@ii()}}

\def\mkpostnote@ii(#1){%
  \@ifnextchar(%)
    {\mkpostnote@iii(#1)}
    {\mkpostnote@iii()(#1)}}

\def\mkpostnote@iii(#1)(#2)#3&{%
  \ifblank{#1}{}{%
    \blx@getformat\cbx@postnote@prefix@fmt{ffd}{}{postnote:prefix}%
    \cbx@postnote@prefix@fmt{#1}}%
  \ifblank{#3}{}{%
    \blx@getformat\cbx@postnote@stem@fmt{ffd}{}{postnote:stem}%
    \cbx@postnote@stem@fmt{#3}}%
  \ifblank{#2}{}{%
    \blx@getformat\cbx@postnote@suffix@fmt{ffd}{}{postnote:suffix}%
    \cbx@postnote@suffix@fmt{#2}}}
\def\cbx@postnote@stem@fmt{}
\def\cbx@postnote@prefix@fmt{}
\def\cbx@postnote@suffix@fmt{}

\makeatother

\addbibresource{biblatex-examples.bib}
\begin{document}
\subsection*{Without postnote affixes}
\cite[See][]{companion}
\cite[See][10]{companion}
\cite[See][11--19]{companion}
\cite[See][11--19 and the last section]{companion}
\cites[10]{companion}[e.g.][]{ctan}[11--19]{markey}[10]{knuth:ct}
\cites(See)()[11--19]{companion}{ctan,markey,knuth:ct}
\subsection*{With postnote affixes}
\cite[See][(post)]{companion}
\cite[See][(post)10]{companion}
\cite[See][(pre)()11--19]{companion}
\cite[See][(pre)(post)11--19 and the last section]{companion}
\cites[10]{companion}[e.g.][()(post)]{ctan}[11--19]{markey}[(pre)()10]{knuth:ct}
\cites(See)()[(pre)(post)11--19]{companion}{ctan,markey,knuth:ct}
\printbibliography
\end{document}

enter image description here

You must log in to answer this question.

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