0

I'm trying to have shorthands introduced at first \cite, \parencite, etc., and \textcite, but then simply use for all further citations. For \parencite etc I follow moewe's solution from Custom abbreviation for citation in bibtex . For \textcite I follow gusbrs's answer Biblatex: How to get year in parenthesis with /textcite & shorthand to have shorthand with intro in first \textcite. I am also using moewe's ext-authoryear-comp style. This results in an error when I use \textcite with multiple bib entries:

! Package biblatex Error: Unbalanced parentheses or brackets.

MWE:

\documentclass[american]{article}
\usepackage{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{csquotes}
\usepackage[backend=biber,style=ext-authoryear-comp,citetracker=true]{biblatex}
\DefineBibliographyStrings{english}{citedas = {hereafter}}

\begin{filecontents}[overwrite]{\jobname.bib} @article{jd14, author = {Doe, J.}, title = {Some Title}, journal = {Some Journal}, year = {2014}, shorthand = {JD14}, } @book{jd13, author = {Smith, J.}, title = {Pro Contractiōnibus}, year = {2013}, shorthand = {JD13}, } @article{jd12, author = {Bar, F.}, title = {No Shorthand}, journal = {Yet Another Journal}, year = {2012}, } @book{jd11, author = {Nominatus, N.}, title={Adversus Contractiōnēs}, year={2011}, } \end{filecontents}

\addbibresource{\jobname.bib}

% shorthandintro with first \cite, \parencite, etc, shorthand only after \newbibmacro*{longcite}{% \ifthenelse{\ifnameundef{labelname}\OR\iffieldundef{labelyear}} {\usebibmacro{cite:label}% \setunit{\addspace}} {\printnames{labelname}% \setunit{\nameyeardelim}}% \usebibmacro{cite:labeldate+extradate}}

\renewbibmacro*{cite}{% \ifciteseen {\iffieldundef{shorthand} {\usebibmacro{longcite}} {\usebibmacro{cite:shorthand}}} {\usebibmacro{longcite} \usebibmacro{shorthandintro}}}

% shorthandintro with first \textcite, etc, shorthand only after \renewbibmacro*{textcite}{% \ifnameundef{labelname} {\iffieldundef{shorthand} {\usebibmacro{cite:label}% \setunit{% \global\booltrue{cbx:parens}% \printdelim{nonameyeardelim}\bibopenparen}% \ifnumequal{\value{citecount}}{1} {\usebibmacro{prenote}} {}% \usebibmacro{cite:labelyear+extrayear}} {\usebibmacro{cite:shorthand}}} {\iffieldundef{shorthand} {\printnames{labelname}% \setunit{% \global\booltrue{cbx:parens}% \printdelim{nameyeardelim}\bibopenparen}% \ifnumequal{\value{citecount}}{1} {\usebibmacro{prenote}} {}% \usebibmacro{citeyear}} {\ifciteseen {\usebibmacro{cite:shorthand}} {\printnames{labelname}% \setunit{% \global\booltrue{cbx:parens}% \printdelim{nameyeardelim}\bibopenparen}% \ifnumequal{\value{citecount}}{1} {\usebibmacro{prenote}} {}% \iffieldundef{labelyear} {\usebibmacro{cite:label} \setunit{\addcomma\addspace}% \iffieldundef{shorthandintro} {\printtext{\bibstring{citedas}}} {\printtext{\printfield{shorthandintro}}} \usebibmacro{cite:shorthand}} {\usebibmacro{cite:labelyear+extrayear} \setunit{\addcomma\addspace}% \iffieldundef{shorthandintro} {\printtext{\bibstring{citedas}}} {\printtext{\printfield{shorthandintro}}} \usebibmacro{cite:shorthand}}}}}}

\begin{document} \textcite{jd14} argued in favor of shorthands on the basis of \citetitle{jd13} \parencite{jd13}.

\textcite{jd11} and \textcite{jd12} %but alas \textcite{jd11,jd12} doesn't work forcefully attacked \cite[17-18]{jd14} and \cite[19-20]{jd13}.

\printbibliography \end{document}

Here's the output I would like to achieve:

Desired result

One can see in the MWE, that if \textcite{jd11,jd12} is used instead of \textcite{jd11} and \textcite{jd12}, then the error quoted above results.

gusbrs did suggest looking at moewe's answer, but prior to moewe's editing, that solution doesn't print shorthands after the first citation.

After moewe's revision of that solution, if gusbrs's code above is replaced with

\newbibmacro*{shorthandintro:noparen}{%
  \iffieldundef{shorthandintro}
    {\iffieldundef{shorthand}
       {}
       {\setunit{\addcomma\space}%
        \bibstring{citedas}\space
        \printfield{shorthand}}}
    {\setunit{\addcomma\space}%
     \printfield{shorthandintro}}}

\newbibmacro*{cite:normal}{% \ifthenelse{\ifnameundef{labelname}\OR\iffieldundef{labelyear}} {\usebibmacro{cite:label}% \setunit{\printdelim{nonameyeardelim}}} {\printnames{labelname}% \setunit{\printdelim{nameyeardelim}}}% \printtext{\bibopenparen}% \usebibmacro{cite:labeldate+extradate}}

\renewbibmacro*{cite}{% \ifciteseen {\iffieldundef{shorthand} {\usebibmacro{cite:normal}% \printtext{\bibcloseparen}} {\usebibmacro{cite:shorthand}}} {\usebibmacro{cite:normal}% \usebibmacro{shorthandintro:noparen}% \printtext{\bibcloseparen}}}

\textcite{jd11,jd12} works as desired, but the initial \textcite{jd14} no longer yields the shorthand intro.

ss1789
  • 559
  • The answers in the linked thread were written for style=authoryear, style=authoryear-comp, already needs more intricate code, even more so style=ext-authoryear-comp,. I fixed a logic error in my answer to the linked question, but it will probably still not be applicable for you. Please explain exactly what you would like to see in the output (in particular if pre- and postnotes are involved, what you want to happen if you cite several entries from the same author one with shorthand one without, keep in mind that \texctcite always mentions the author with shortand, do you want that?) – moewe Mar 18 '21 at 07:24
  • I probably forgot a few cases, but what output would you want to see in https://gist.github.com/moewew/918a4d85a4f7226ceaa8fdceb0a05a0d – moewe Mar 18 '21 at 07:29
  • @moewe: I edited the question to make clearer what I was trying to achieve. Perhaps one has to simply rely on \textcite{ref1} and \textcite{ref2} instead of \textcite{ref1,ref2}. – ss1789 Mar 18 '21 at 16:52
  • No I firmly belive that \textcite{ref1,ref2} would be the correct way to cite here and that it should work. Relying on \textcite{ref1} and \textcite{ref2} instead is really a kludge. The code you have copied is simply not suitable for the style you are using, so errors or weird output are to be expected. I'll see what I can do, but I can't promise I will be able to come up with a solution tonight. You may want to have a look at the code I posted above and explain what output you would like to see in that example. It contains more test cases that are relevant here. – moewe Mar 18 '21 at 17:13
  • It would be extremely helpful if you could explain the desired output in more detail (based on the MWE I linked above). For example I'd really need to know what you want \textcite{jd14} again \textcite[34]{jd14} to show. Do you want the second \textcite to show just "JD14" or "Doe (JD14)"? (Surprisingly the former is much harder to get right in the current \textcite framework). – moewe Mar 21 '21 at 07:13
  • Many thanks for taking the trouble. Looking at the github MWE, I'm hoping to get as output from the first line after \begin{document}, i.e., \textcite{jd14} again \textcite[34]{jd14}, this: Doe, Smith and Bar (2014, hereafter JD14) again JD14, p. 34. If the second \textcite could yield JD14(34), that'd be great too. So it looks like maybe luckily it's the easier option. The second line's output should be See Doe, Smith and Bar (2015, hereafter JD15, p. 45) again see JD15, p. 45. The third line: JD14, JD15 again JD14, JD15. I'll continue with the remaining lines in the next comment. – ss1789 Mar 21 '21 at 21:06
  • The 4th,6th, and 7th lines are perfect. The 5th line I hope to have Bar (2012) and JD14 again Bar (2012) and JD14. – ss1789 Mar 21 '21 at 21:08
  • Mhhh. Isn't is inconsistent to want the subsequent \textcite{jd14} in line 1 to yield "JD14", but the combined \textcite{jd13,jd15} "Doe, Smith and Bar (2013, JD15)"? If you want just "JD14" in the first line, I would have expected "Doe, Smith and Bar (2013) and JD15" for consistency. Note that standard behaviour of \textcite is to always print the labelname, so if you don't want it, then you have to actively work against that (and all the code that assumes it). – moewe Mar 21 '21 at 21:21
  • You're quite right, "Doe, Smith and Bar (2013) and JD15" is what I want. Brain cramp. – ss1789 Mar 24 '21 at 01:11
  • Works wonderfully, thanks again. – ss1789 Mar 27 '21 at 21:12

1 Answers1

1

The answers to Biblatex: How to get year in parenthesis with /textcite & shorthand were written for the style authoryear used in that question. authoryear-comp is much more complex than authoryear and ext-authoryear-comp adds a few more layers on top of authoryear-comp. So you really cannot expect to make the code work here without modification.

Here is an attempt to implement something that comes close to the desired output with ext-authoryear-comp. Most of the code was already there, but we needed to change the logic a bit to get to where we are now.

\documentclass[british,a4paper]{article}
\usepackage{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{csquotes}
\usepackage[backend=biber, style=ext-authoryear-comp, citetracker=true]{biblatex}
\DefineBibliographyStrings{english}{citedas = {hereafter}}

\makeatletter \newbibmacro*{shorthandintro:noparen}{% \iffieldundef{shorthandintro} {\iffieldundef{shorthand} {} {\setunit{\addcomma\space}% \bibstring{citedas}\space \printfield{shorthand}}} {\setunit{\addcomma\space}% \printfield{shorthandintro}}}

\newcommand*{\ifshorthandonlycite}{% \iffieldundef{shorthand} {@secondoftwo} {\ifciteseen}}

\renewbibmacro*{cite}{% \ifshorthandonlycite {\usebibmacro{cite:shorthand}% \usebibmacro{cite:reinit}} {\ifboolexpr{test {\ifnameundef{labelname}} or test {\iffieldundef{labelyear}}} {\usebibmacro{cite:label}% \setunit{% \global\booltrue{cbx:parens}% \printdelim{nonameyeardelim}% \csuse{extblx@citedelim@\blx@delimcontext @inner@open}}% \usebibmacro{cite:labeldate+extradate}% \usebibmacro{cite:reinit}} {\iffieldequals{namehash}{\cbx@lasthash} {\ifboolexpr{ test {\iffieldequals{labelyear}{\cbx@lastyear}} and ( test {\ifnumequal{\value{multicitecount}}{0}} or test {\iffieldundef{postnote}}) and test {\iffieldundef{shorthand}}} {\setunit{\printdelim{extradateonlycompcitedelim}}% \usebibmacro{cite:extradate}} {\setunit{\compcitedelim}% \usebibmacro{cite:labeldate+extradate}% \savefield{labelyear}{\cbx@lastyear}}} {\printnames{labelname}% \setunit{% \global\booltrue{cbx:parens}% \printdelim{nameyeardelim}% \csuse{extblx@citedelim@\blx@delimcontext @inner@open}}% \usebibmacro{cite:labeldate+extradate}% \savefield{namehash}{\cbx@lasthash}% \savefield{labelyear}{\cbx@lastyear}}% \usebibmacro{shorthandintro:noparen}% \iffieldundef{shorthand} {} {\global\undef\cbx@lastyear}}}% \setunit{% \ifbool{cbx:parens} {\csuse{extblx@citedelim@\blx@delimcontext @inner@close}% \global\boolfalse{cbx:parens}} {}% \multicitedelim}}

\renewbibmacro*{textcite}{% \ifshorthandonlycite {\ifnumequal{\value{citecount}}{1} {\usebibmacro{prenote}} {}% \usebibmacro{cite:shorthand}% \global\undef\cbx@lastyear} {\iffieldequals{namehash}{\cbx@lasthash} {\ifboolexpr{test {\iffieldequals{labelyear}{\cbx@lastyear}} and (test {\ifnumequal{\value{multicitecount}}{0}} or test {\iffieldundef{postnote}}) and test {\iffieldundef{shorthand}}} {\setunit{\printdelim{extradateonlycompcitedelim}}% \usebibmacro{cite:extradate}} {\setunit{\compcitedelim}% \usebibmacro{cite:labeldate+extradate}% \usebibmacro{shorthandintro:noparen}% \iffieldundef{shorthand} {\savefield{labelyear}{\cbx@lastyear}} {\global\undef\cbx@lastyear}}} {\ifnameundef{labelname} {\usebibmacro{cite:label}% \setunit{% \global\booltrue{cbx:parens}% \printdelim{nonameyeardelim}% \csuse{extblx@citedelim@\blx@delimcontext @inner@open}}% \ifnumequal{\value{citecount}}{1} {\usebibmacro{prenote}} {}% \usebibmacro{cite:labeldate+extradate}% \usebibmacro{shorthandintro:noparen}} {\printnames{labelname}% \setunit{% \global\booltrue{cbx:parens}% \printdelim{nameyeardelim}% \csuse{extblx@citedelim@\blx@delimcontext @inner@open}}% \ifnumequal{\value{citecount}}{1} {\usebibmacro{prenote}} {}% \iffieldundef{labelyear} {\usebibmacro{cite:label}} {\usebibmacro{cite:labeldate+extradate}}% \usebibmacro{shorthandintro:noparen}% \iffieldundef{shorthand} {\savefield{labelyear}{\cbx@lastyear}} {\global\undef\cbx@lastyear}}% \stepcounter{textcitecount}% \savefield{namehash}{\cbx@lasthash}}}% \setunit{% \ifbool{cbx:parens} {\csuse{extblx@citedelim@\blx@delimcontext @inner@close}% \global\boolfalse{cbx:parens}} {}% \textcitedelim}}

\renewbibmacro*{textcite:postnote}{% \iffieldundef{postnote} {} {\ifbool{cbx:parens} {\setunit{\printdelim{postnotedelim}}} {\setunit{% \global\booltrue{cbx:parens}% \printdelim{nameyeardelim}% \csuse{extblx@citedelim@\blx@delimcontext @inner@open}}}% \printfield{postnote}}% \ifnumequal{\value{multicitecount}}{\value{multicitetotal}} {\setunit{}% \printtext{% \ifbool{cbx:parens} {\csuse{extblx@citedelim@\blx@delimcontext @inner@close}% \global\boolfalse{cbx:parens}} {}}} {\setunit{% \ifbool{cbx:parens} {\csuse{extblx@citedelim@\blx@delimcontext @inner@close}% \global\boolfalse{cbx:parens}} {}% \textcitedelim}}}

\DeclareCiteCommand{\textcite}[\cbx@textcite@init\cbx@textcite] {\gdef\cbx@savedkeys{}% \citetrackerfalse% \pagetrackerfalse% \DeferNextCitekeyHook% \usebibmacro{cite:init}} {\ifthenelse{\iffirstcitekey\AND\value{multicitetotal}>0} {\protected@xappto\cbx@savedcites{()(\thefield{multipostnote})}% \global\clearfield{multipostnote}} {}% \xappto\cbx@savedkeys{\thefield{entrykey},}% \iffieldundef{shorthand} {} {\booltrue{citetracker}% \ifciteseen {\gundef\cbx@lasthash} {}% \boolfalse{citetracker}}% \iffieldequals{namehash}{\cbx@lasthash} {} {\stepcounter{textcitetotal}% \savefield{namehash}{\cbx@lasthash}}} {} {\protected@xappto\cbx@savedcites{% [\thefield{prenote}][\thefield{postnote}]{\cbx@savedkeys}}} \makeatother

\begin{filecontents}{\jobname.bib} @article{jd14, author = {Doe, J. and Smith, J. and Bar, F.}, title = {Some Title}, journal = {Some Journal}, year = {2014}, shorthand = {JD14}, } @article{jd15, author = {Doe, J. and Smith, J. and Bar, F.}, title = {Some Title}, journal = {Some Journal}, year = {2015}, shorthand = {JD15}, } @article{jd13, author = {Doe, J. and Smith, J. and Bar, F.}, title = {No shorthand here}, journal = {Some Other Journal}, year = {2013}, } @article{b12, author = {Bar, F.}, title = {Also No shorthand}, journal = {Yet Another Journal}, year = {2012}, } \end{filecontents} \addbibresource{\jobname.bib}

\begin{document} 1 \textcite{jd14} again \textcite{jd14}.

2 \textcite[see][45]{jd15} again \textcite[see][45]{jd15}.

3 \textcite{jd14,jd15} again \textcite{jd14,jd15}.

4 \textcite{jd13,jd15} again \textcite{jd13,jd15}.

5 \textcite{b12,jd14} again \textcite{b12,jd14}.

6 Just for comparison \textcite{jd13}. \textcite{b12,jd13} works

7 \textcite[34-36]{jd13} again \textcite[see][34-36]{jd13}

\citereset

1 \parencite{jd14} again \parencite{jd14}.

2 \parencite[see][45]{jd15} again \parencite[see][45]{jd15}.

3 \parencite{jd14,jd15} again \parencite{jd14,jd15}.

4 \parencite{jd13,jd15} again \parencite{jd13,jd15}.

5 \parencite{b12,jd14} again \parencite{b12,jd14}.

6 Just for comparison \parencite{jd13}. \parencite{b12,jd13} works

7 \parencite[34-36]{jd13} again \parencite[see][34-36]{jd13}

\printbibliography \end{document}

Doe, Smith and Bar (2014, hereafter JD14) again JD14.

moewe
  • 175,683