3

I am using the style ext-authoryear-ibid. I am trying to achieve an output like this (shorthand in "[]" if exists):

  1. First cite: (National Aeronautics and Space Administration [NASA], 2022, p. 12)
  2. Second cite: (ibid., p. 14)
  3. Another source: (Doe, John, 2019, p. 550)
  4. n-th cite: (NASA, 2022, p. 102)

Meaning, that only for the first cite, if a shorthand exists, use (1). For all subsequent cites use the shorthand only, but only if there was something cited in between. Otherwise use ibid.

I am currently some code which almost does what I want. The problem is, that it disables the ibid function. MWE:

\documentclass[
    paper=A4,
    fontsize=12pt,
]{article}

\usepackage[
    backend=biber,
    sorting=nyt,
    style=ext-authoryear-ibid,
    citecounter,
    citetracker=true,
]{biblatex}

% Comma between title and year
\renewcommand*{\labelnamepunct}{\adddot\space}
\DeclareDelimFormat{nameyeardelim}{\addcomma\space}

% Hack for shortauthor, disables ibidem
\renewbibmacro*{cite}{%
    \iffieldundef{shorthand}
    {\ifthenelse{\ifnameundef{labelname}\OR\iffieldundef{labelyear}}
        {\usebibmacro{cite:label}%
            \setunit{\printdelim{nonameyeardelim}}}
        {\ifboolexpr{
                test{\ifnameundef{shortauthor}}
                or
                test{\ifciteseen}
            }
            {\printnames{labelname}%
                \setunit{\printdelim{nameyeardelim}}}
            {\printnames[labelname]{author}%
                \ifnumgreater{\value{citecounter}}{1}
                {\setunit{\addspace}%
                    \printtext[parens]{\printnames{labelname}}}%
                {}%
                \setunit{\printdelim{nameyeardelim}}}}%
        \usebibmacro{cite:labeldate+extradate}}
    {\usebibmacro{cite:shorthand}}}

\begin{filecontents*}{testbib.bib}
    @online{test1,
        author = {{National Aeronautics and Space Administration}},
        shortauthor = {NASA},
        title = {Aliens},
        year = {2022}
    }
    
    @online{test2,
        author = {John Doe},
        title = {Generic Names},
        year = {2019}
    }
\end{filecontents*}

\addbibresource{testbib.bib}

\begin{document}
    \parencite[][12]{test1}\par \parencite[][14]{test1} $\rightarrow$ needs to be: (ibid., 2022, p. 14)\par \parencite[][550]{test2}\par \parencite[][102]{test1}
    \printbibliography
\end{document}

Thank you for your support.

1 Answer 1

3

The redefinition of the cite bibmacro shown in the question appears to be based on the definition from authoryear.cbx (ll. 10-18 in v3.17). For your style (ext-authoryear-ibid) the redefinition should be based on the cite bibmacro from authoryear-ibid.cbx (ll. 18-29).

If we change the approach slightly to be more flexible and allow for shorteditor (and indeed for all kinds of short... name fields if you should want to define additional ones) we might end up with

\documentclass{article}

\usepackage[
  backend=biber,
  style=ext-authoryear-ibid,
  citetracker,
]{biblatex}

\DeclareDelimFormat[bib]{nametitledelim}{\adddot\space}
\DeclareDelimFormat{nameyeardelim}{\addcomma\space}

% some auxiliary macros to
% check if we are in the shortauthor/shorteditor case
% and to strip the "short" from those field names to get the "long" field
\makeatletter
\newcommand*{\ifstartswithshort}[1]{\ifstartswithshort@i #1short\stopscanning}
\newcommand*{\ifstartswithshort@i}{}
\def\ifstartswithshort@i#1short#2\stopscanning{\ifblank{#1}}

\newcommand*{\iffieldstartswithshort}[1]{%
  \expandafter\ifstartswithshort
  \expandafter{\expanded{\thefield{#1}}}}

\newcommand*{\stripshort}[1]{\stripshort@i #1\stopscanning}
\newcommand*{\stripshort@i}{}
\def\stripshort@i#1short#2\stopscanning{#2}

\newcommand*{\stripshortfromfield}[1]{%
  \expandafter\stripshort
  \expandafter{\expanded{\thefield{#1}}}}
\makeatother

\renewbibmacro*{cite}{%
  \global\boolfalse{cbx:loccit}%
  \iffieldundef{shorthand}
    {\ifthenelse{\ifciteibid\AND\NOT\iffirstonpage}
       {\usebibmacro{cite:ibid}}
       {\ifthenelse{\ifnameundef{labelname}\OR\iffieldundef{labelyear}}
          {\usebibmacro{cite:label}%
           \setunit{\printdelim{nonameyeardelim}}}
          {\ifciteseen
             {\printnames{labelname}}
             {\iffieldstartswithshort{labelnamesource}
                {\printnames[labelname]{\stripshortfromfield{labelnamesource}}%
                 \setunit{\addspace}%
                 \printtext[parens]{\printnames{labelname}}}
                {\printnames{labelname}}}%
           \setunit{\printdelim{nameyeardelim}}}%
        \usebibmacro{cite:labeldate+extradate}}}
    {\usebibmacro{cite:shorthand}}}

\begin{filecontents*}{\jobname.bib}
@online{test1,
  author      = {{National Aeronautics and Space Administration}},
  shortauthor = {NASA},
  title       = {Aliens},
  year        = {2022},
}
@online{test2,
  author = {John Doe},
  title  = {Generic Names},
  year   = {2019}
}
\end{filecontents*}
\addbibresource{\jobname.bib}

\begin{document}
  \parencite[][12]{test1}

  \parencite[][14]{test1}
  
  \parencite[][550]{test2}
  
  \parencite[][102]{test1}

  \printbibliography
\end{document}

(National Aeronautics and Space Administration [NASA], 2022, p. 12)
(ibid., p. 14)
(Doe, 2019, p. 550)
(NASA, 2022, p. 102)

Note that we didn't use citecounter, we used the simpler \ifciteseen test.

2
  • Thank you very much. This seems to solve it. The only problem I see is that using \caption{\parencite{}} (inside a figure) will introduce the first long name including shorthand in brackets each time. I am afraid, that this can not be easily tackled by biblatex macros. But I would be happy to be proven wrong. Commented Jun 9, 2022 at 13:14
  • 1
    @PeterByron Have a look at tex.stackexchange.com/q/356231/35864.
    – moewe
    Commented Jun 9, 2022 at 15:16

You must log in to answer this question.

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