2

I'm authoring a biblatex style and I'd like to make available to users a custom citation command that takes an optional parameter additional to those supported by biblatex natively. That is, in addition to the optional prenote and postnote, and the mandatory key.

For example I'd want to support something like these command variations:

% Explicit arguments to the additional parameter
\customcite{barker_2016_swiss}{apples}\\
\customcite[see][p. 25]{barker_2016_swiss}{oranges}\\

 % Some default when the additional parameter not supplied
\customcite[see][p. 25]{barker_2016_swiss}\\

% Relevant defaults when none of the optional parameters supplied.
\customcite{barker_2016_swiss}\\ 

... where barker_2016_swiss is a key and apples and oranges are arguments to the additional (optional) parameter.

I'm not wedded to the additional parameter being passed through braces {} rather than brackets []. Indeed I'm a bit confused about the circumstances under which tex/latex might support passing arguments through braces {} rather than brackets []. So if the command needed to be something like ...

 \customcite[see][p. 25][oranges]{barker_2016_swiss}\\

... I can't see that this would present any special difficulty.

apples and oranges are silly hypotheticals to keep things simple and make this TeX question general enough to be of benefit to others (in my production code I'll be passing to a DateTimePrecision parameter arguments like "daylevel, timelevel, etc"). But the general idea is to use this user supplied argument in a Select Case type statement (I use IfEqCase in this latex context) to alter the format of the citation on an ad hoc basis. E.g. so I might end up with, continuing the silly and simple example,:

(see Barker Apples are healthy, p. 25)
(see Barker Oranges are fun, p. 25)

How might we refactor \DeclareCiteCommand in one's style, or code some other technique, to support this sort of \customcite?

I might also want to refactor \DeclareAutoCiteCommand to the same end. I presume if it can be done for \DeclareCiteCommand then the same solution would more or less apply for \DeclareAutoCiteCommand.

My Minimum Working Example (MWE) that follows doesn't quite get me there but illustrates where I'm trying to head:

In my C:\MyDevDirectory\

authoryear-jlb-mwe.bbx.

\ProvidesFile{authoryear-jlb-mwe.bbx}
[2016/11/16 v1.0 JLB's modification of authoryear.bbx]

\RequireBibliographyStyle{authoryear}

\endinput

So authoryear-jlb-mwe.bbx is just a stub that doesn't do anything and is irrelevant for current purposes.

authoryear-jlb-mwe.cbx

\ProvidesFile{authoryear-jlb-mwe.cbx}
[2016/11/16 v1.0 JLB's modification of authoryear.cbx]

\RequireCitationStyle{authoryear}

% I've successfully modifed this command from authoryear.cbx
% to take an additonal parameter
\renewbibmacro{cite:labelyear+extrayear}[1][oranges]{%
  \addspace
  \IfEqCase{#1}{
    {oranges}{Oranges are fun}%
    {apples}{Apples are healthy}%
    {bananas}{Bananas are tasty}%
  }[Unknown clause in cite:labelyear+extrayear]%
}%

\renewbibmacro*{cite}[1][apples]{%
  \iffieldundef{shorthand}
    {\ifthenelse{\ifnameundef{labelname}\OR\iffieldundef{labelyear}}
       {\usebibmacro{cite:label}%
        \setunit{\printdelim{nonameyeardelim}}}
       {\printnames{labelname}%
        \setunit{\printdelim{nameyeardelim}}}%
     \usebibmacro{cite:labelyear+extrayear}[#1]} % Passing the argument along
    {\usebibmacro{cite:shorthand}}}

% How to redefine \DeclareCiteCommand to take an additional
% argument to pass along deeper to other redefined commands?
\DeclareCiteCommand{\customcite}[\mkbibparens]
  {\usebibmacro{prenote}}%
  {\usebibmacro{citeindex}
   \usebibmacro{cite}[bananas]} % Passing the argument along
  {\multicitedelim}
  {\usebibmacro{postnote}}

% Another approach? But it doesn't hook 
% into the facilities that \DeclareCiteCommand exposes.
% \newcommand*{\jlbCiteViaNewcommand}[4][see]{
%     (#1 #3 \usebibmacro{cite:labelyear+extrayear}[#4] ZZZZ, #2)
% }

\endinput

As you can see I'm able to override the authoryear.cbx commands with \renewbibmacro{cite:labelyear+extrayear} and \renewbibmacro*{cite} to take an additional parameter without problem. \renewbibmacro*{cite} passes this parameter along to the endpoint \renewbibmacro{cite:labelyear+extrayear} without problem. And within \DeclareCiteCommand{\customcite} I can pass an argument to \renewbibmacro*{cite} without problem.

The chief issue is I don't know how to refactor \DeclareCiteCommand{\customcite} to take an additional parameter "in the front". That is, from a user coding something like \customcite[see][p. 25]{barker_2016_swiss}{oranges}

Biblatex-CustomStyle-Mwe.tex

\documentclass{article}

\begin{filecontents}{\jobname.bib}
@article{barker_2016_swiss,
  author = {Barker, Anne},
  title = {Swiss Voters Say No to Guaranteed Free Money},
  date = {2016-06-06T18:20:00+10:00},
  journaltitle = {ABC News}
}

@book{nietzsche_1969_thus,
  author = {Nietzsche, Friedrich Wilhelm},
  date = {1969},
  origdate = {1883},
  title = {Thus Spoke Zarathustra: A Book for Everyone and No One},
  publisher = {{Penguin Books}}
}
\end{filecontents}

\usepackage[%
  alldates=ymd, % year, short, long, terse, comp, ymd, edtf
  alldatesusetime=true,
  alltimes=24h,
  seconds=true,
  timezones=true,
  datezeros=true,
  dateabbrev=false,
  dateera=secular,
  datecirca=true,
  dateuncertain=true,
  style=authoryear-jlb-mwe,
  sorting=none,
]{biblatex}

\addbibresource{\jobname.bib}

\begin{document}

\section{Native Commands (although internals modified)}

\autocite[see][25]{barker_2016_swiss}\\
\parencite[see][25]{nietzsche_1969_thus}\\
\autocite{nietzsche_1969_thus}\\

\section{Custom command}

\customcite[see][p. 25]{barker_2016_swiss} \\


%\section{Desired command formats (currently not operational)}
%
%\customcite[see][p. 25]{barker_2016_swiss}\\ 
%\customcite{barker_2016_swiss}{apples}\\
%\customcite[see][p. 25]{barker_2016_swiss}{apples}\\
%\customcite[see][p. 25]{nietzsche_1969_thus}{oranges}\\
%\customcite[see][p. 25]{barker_2016_swiss}\\
%
%% Maybe a redfinition of autocite too?
%\autocite[see][p. 25]{barker_2016_swiss}\\ 
%\autocite{barker_2016_swiss}{apples}\\
%\autocite[see][p. 25]{barker_2016_swiss}{apples}\\
%\autocite[see][p. 25]{nietzsche_1969_thus}{oranges}\\
%\autocite[see][p. 25]{barker_2016_swiss}\\


\printbibliography

\end{document} 

... The output from this tex file shows how I'm currently successful in modifying internals to pick up on values passed to my core Select statement (\IfEqCase) ... but it won't work if the Desired command formats (currently not operational) section is uncommented: since \customcite (and \autocite) are not yet refactored to take an additional parameter (not already supported natively by biblatex).

There is a simarly worded Tex Stack Exchange question Help with additional parameter for DeclareCiteCommand. But it looks like the questioner is aiming at something quite different, and so the answers there don't seem to apply.

Update:

I've posted what I'm trying to achieve generally, as "Style spec: authoryear with datetime precision variation. #516", at https://github.com/plk/biblatex/issues/516.

  • biblatex has a very intricate system of providing arguments to its macros defined via \DeclareCiteCommand (even more so for the macros defined by \DeclareMultiCiteCommand). I don't think there is a straightforward way to extend the number of arguments beyond what is available so far without going really deep into internals (and possibly braking lots of stuff) or essentially trying to recreate everything biblatex does via xparse. Both options don't look very appealing to me. What exactly do you need that option for? Maybe there is a smarter way to do it than what you tried so far. – moewe Nov 23 '16 at 8:06
  • 1
    Imho adding an additional argument would be quite a pain. I would probably go for a syntax like \cite[See ...][<!oranges!>12]{key} and then change the macros which process the postnote field to retrieve the oranges and get whatever output you want. – Ulrike Fischer Nov 23 '16 at 9:46
  • Maïeul Rou­quette's biblatex-source-division uses the approach outlined by Ulrike above, there one passes additional information in round brackets via the postnote field to the \cite command. – moewe Nov 23 '16 at 16:38
  • Thanks UlrikeFischer and moewe. Smuggling the option in through the postnote looks like the way to do it. That's a clever workaround. moewe, I appreciate being warned off refactoring DeclareCiteCommand as likely to be too involved. The answer to "What exactly do you need that option for?" is now posted as "Style spec: authoryear with datetime precision variation. #516", at github.com/plk/biblatex/issues/516. To future visitors to this thread, I intend to return with a worked example based on the postnote smuggling technique. – John Bentley Nov 26 '16 at 8:27
1

biblatex defines the cite commands with a lot of internal trickery. It is not easy to add an additional argument without rewriting the entire \DeclareCiteCommand infrastructure and possibly breaking it along the way. Alternatively, one would have to reproduce the current behaviour with xparse or low-level trickery. None of the two options sounds too promising.

You can fake an additional argument by smuggling it in through the postnote argument. This is what Maïeul Rou­quette's biblatex-source-division does successfully. His code is based on Audrey's answer to Optional argument within another optional argument in biblatex \cite.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.