2

I'm trying to follow an author-year citation style which requires citations of the form "blah blah (A Corporation with a Long Name (ACWALN) 2018) … … something (ACWALN 2005)", but only if the long-named corporation is cited multiple times.

That is, I need to handle four cases for each name in the list:

  1. A natural person (detectable by a given name), print just the surname or surname plus disambiguation initials as in default biblatex authoryear.cbx every time
  2. A corporation cited only once, print the full name (the one in the author field)
  3. A corporation cited for the first time which is then cited again, print the full name followed by the short name in brackets if there is one
  4. A corporation cited for a subsequent time, print the short name if it exists and the long name if it doesn't.

Presumably I need to use \cbx@ifnameseen to select the appropriate name to print based on its value, then write all the names that are cited more than once to the aux file in suitable macros so the next time the file is processed the correct first citation can be printed.

Is there a better way to achieve this, and if not, has anyone implemented it before?

(No, I can't just use a sane citation style, and the official endnote style file doesn't work correctly so using Word instead of latex wouldn't help.)

2 Answers 2

1

This is much more complicated than David's answer, but it works on a name and not an entry level.

The basic strategy is the same, just that instead of \ifciteseen we use \cbx@ifnameseen from Automatically cite author's name in full the first time it appears and instead of citecounter we implement a name counter that counts occurrences of one specific name. To be able to deal with name lists and uniqueness properly we use the new extended name format (cf. Bibtex/Biber: how to cite an author using Ethiopian conventions?).

\documentclass{article}

\begin{filecontents*}[force]{corp.dbx}
\DeclareDatamodelConstant[type=list]{nameparts}{prefix,family,suffix,given,long,short}
\end{filecontents*}

\usepackage[style=authoryear,citecounter,citetracker,datamodel=corp]{biblatex}

\DeclareSortingNamekeyTemplate[corp]{
  \keypart{
    \namepart{long}
  }
}

\DeclareUniquenameTemplate[corp]{
  \namepart[base]{short}
  \namepart{long}
}

\makeatletter
%%% nametracker
% provides \cbx@ifnameseen to check if a name was seen already
% requires use of \cbx@nametracker{\thefield{hash}}
% in the appropriate place
\newrobustcmd*{\cbx@nametracker@global}[1]{%
  \xifinlistcs{#1}{cbx@bseen@names@\the\c@refsection}
    {}
    {\listcsxadd{cbx@bseen@names@\the\c@refsection}{#1}}}

\newrobustcmd*{\cbx@nametracker@context}[1]{%
  \iftoggle{blx@footnote}
    {\xifinlistcs{#1}{cbx@fseen@names@\the\c@refsection}
       {}
       {\listcsxadd{cbx@fseen@names@\the\c@refsection}{#1}}}
    {\xifinlistcs{#1}{cbx@bseen@names@\the\c@refsection}
       {}
       {\listcsxadd{cbx@bseen@names@\the\c@refsection}{#1}}}}

\newrobustcmd*{\cbx@ifnameseen@global}[1]{%
  \xifinlistcs{#1}{cbx@bseen@names@\the\c@refsection}}

\newrobustcmd*{\cbx@ifnameseen@context}[1]{%
  \iftoggle{blx@footnote}%
    {\xifinlistcs{#1}{cbx@fseen@names@\the\c@refsection}}%
    {\xifinlistcs{#1}{cbx@bseen@names@\the\c@refsection}}}

\DeclareBibliographyOption[string]{nametracker}[true]{%
  \ifcsdef{blx@opt@nametracker@#1}
    {\csuse{blx@opt@nametracker@#1}}
    {\blx@err@invopt{nametracker=#1}{}}}

\def\blx@opt@nametracker@global{%
  \let\cbx@ifnameseen\cbx@ifnameseen@global
  \let\cbx@nametracker\cbx@nametracker@global}

\let\blx@opt@nametracker@true\blx@opt@nametracker@global

\def\blx@opt@nametracker@false{%
  \protected\long\def\cbx@ifnameseen##1##2##3{##3}%
  \let\cbx@nametracker\relax}

\def\blx@opt@nametracker@context{%
  \let\cbx@ifnameseen\cbx@ifnameseen@context
  \let\cbx@nametracker\cbx@nametracker@context}

\appto\blx@secinit{%
  \ifcsundef{cbx@bseen@names@\the\c@refsection}
    {\global\cslet{cbx@bseen@names@\the\c@refsection}\@empty}
    {}%
  \ifcsundef{cbx@fseen@names@\the\c@refsection}
    {\global\cslet{cbx@fseen@names@\the\c@refsection}\@empty}
    {}}

\InitializeCitationStyle{%
  \global\cslet{cbx@bseen@names@\the\c@refsection}\@empty
  \global\cslet{cbx@fseen@names@\the\c@refsection}\@empty}

\ExecuteBibliographyOptions{nametracker=context}

%%% namecounter
% defines \namecounter{<hash>}
% requires \cbx@countname{\thefield{hash}} in the appropriate place
\def\blx@namecount@global#1{%
  0\csuse{blx@namecount@\the\c@refsection @#1}%
}
\def\blx@namecount@context#1{%
  0%
  \iftoggle{blx@footnote}
    {\csuse{blx@fnnamecount@\the\c@refsection @#1}}
    {\csuse{blx@namecount@\the\c@refsection @#1}}%
}

\protected\def\blx@aux@namecount#1#2{%
  \csnumgdef{blx@namecount@#1@#2}{%
    \csuse{blx@namecount@#1@#2}+1}}
\protected\def\blx@aux@fnnamecount#1#2{%
  \csnumgdef{blx@fnnamecount@#1@#2}{%
    \csuse{blx@fnnamecount@#1@#2}+1}}

\let\abx@aux@namecount\@gobbletwo
\let\abx@aux@fnnamecount\@gobbletwo

\AtEndDocument{%
  \let\abx@aux@namecount\@gobbletwo
  \let\abx@aux@fnnamecount\@gobbletwo}

\def\blx@countname@global#1{%
  \ifbool{@filesw}
    {\ifbool{citetracker}
       {\immediate\write\@mainaux{%
          \string\abx@aux@namecount
          {\the\c@refsection}{#1}}}
       {}}
    {}}

\def\blx@countname@context#1{%
  \ifbool{@filesw}
    {\ifbool{citetracker}
       {\immediate\write\@mainaux{%
          \iftoggle{blx@footnote}
            {\string\abx@aux@fnnamecount}
            {\string\abx@aux@namecount}%
          {\the\c@refsection}{#1}}}
       {}}
    {}}

\DeclareBibliographyOption[boolean]{namecounter}[true]{%
  \ifcsdef{blx@opt@namecounter@#1}
    {\csuse{blx@opt@namecounter@#1}}
    {\blx@err@invopt{namecounter=#1}{}}}
\def\blx@opt@namecounter@true{%
  \let\cbx@namecount\blx@namecount@global
  \let\cbx@countname\blx@countname@global
  \let\abx@aux@namecount\blx@aux@namecount
  \let\abx@aux@fnnamecount\blx@aux@namecount
  \booltrue{citetracker}}
\def\blx@opt@namecounter@context{%
  \let\cbx@namecount\blx@namecount@context
  \let\cbx@countname\blx@countname@context
  \let\abx@aux@namecount\blx@aux@namecount
  \let\abx@aux@fnnamecount\blx@aux@fnnamecount
  \booltrue{citetracker}}
\def\blx@opt@namecounter@false{%
  \let\cbx@namecount\@gobbleone
  \let\cbx@countname\@gobbleone
  \let\abx@aux@namecount\@gobbletwo
  \let\abx@aux@fnnamecount\@gobbletwo}

\ExecuteBibliographyOptions{namecounter=context}

%%% name formats
\DeclareNameFormat{given-family}{%
  \ifsortingnamekeytemplatename{corp}
    {\usebibmacro{name:corp}
       {\namepartlong}
       {\empty}}
    {\ifgiveninits
       {\usebibmacro{name:given-family}
         {\namepartfamily}
         {\namepartgiveni}
         {\namepartprefix}
         {\namepartsuffix}}
       {\usebibmacro{name:given-family}
         {\namepartfamily}
         {\namepartgiven}
         {\namepartprefix}
         {\namepartsuffix}}}%
  \usebibmacro{name:andothers}}

\DeclareNameFormat{family-given}{%
  \ifsortingnamekeytemplatename{corp}
    {\usebibmacro{name:corp}
       {\namepartlong}
       {\empty}}
    {\ifgiveninits
       {\usebibmacro{name:family-given}
         {\namepartfamily}
         {\namepartgiveni}
         {\namepartprefix}
         {\namepartsuffix}}
       {\usebibmacro{name:family-given}
         {\namepartfamily}
         {\namepartgiven}
         {\namepartprefix}
         {\namepartsuffix}}}%
  \usebibmacro{name:andothers}}

\DeclareNameAlias{sortname}{family-given}

\DeclareNameFormat{labelname}{%
  \ifuniquenametemplatename{corp}
    {\usebibmacro{labelname:corp}}
    {\usebibmacro{labelname:normal}}%
  \usebibmacro{name:andothers}%
  \cbx@nametracker{\thefield{hash}}%
  \cbx@countname{\thefield{hash}}}

\newbibmacro{labelname:corp}{%
  \ifboolexpr{    (   test {\iffieldequalstr{uniquepart}{short}}
                   or test {\iffieldequalstr{uniquepart}{base}})
              and test {\ifnumgreater{\cbx@namecount{\thefield{hash}}}{1}}}
    {\cbx@ifnameseen{\thefield{hash}}
       {\usebibmacro{name:corp}
          {\empty}
          {\namepartshort}}
       {\usebibmacro{name:corp:both}
          {\namepartlong}
          {\namepartshort}}} 
    {\usebibmacro{name:corp}
       {\namepartlong}
       {\empty}}}

\newbibmacro{labelname:normal}{%
  \ifcase\value{uniquename}%
    \usebibmacro{name:family}
      {\namepartfamily}
      {\namepartgiven}
      {\namepartprefix}
      {\namepartsuffix}%
  \or
    \ifuseprefix
      {\usebibmacro{name:given-family}
        {\namepartfamily}
        {\namepartgiveni}
        {\namepartprefix}
        {\namepartsuffixi}}
      {\usebibmacro{name:given-family}
        {\namepartfamily}
        {\namepartgiveni}
        {\namepartprefixi}
        {\namepartsuffixi}}%
  \or
    \usebibmacro{name:given-family}
      {\namepartfamily}
      {\namepartgiven}
      {\namepartprefix}
      {\namepartsuffix}%
  \fi}

\newbibmacro*{name:corp}[2]{%
  \usebibmacro{name:delim}{#1#2}%
  \usebibmacro{name:hook}{#1#2}%
  \ifdefvoid{#1}{}{\mkbibnamecorplong{#1}}%
  \ifdefvoid{#2}{}{\mkbibnamecorpshort{#2}}}

\newbibmacro*{name:corp:both}[2]{%
  \usebibmacro{name:delim}{#1}%
  \usebibmacro{name:hook}{#1}%
  \mkbibnamecorplong{#1}%
  \ifdefvoid{#2}{}{\space\mkbibnamecorpshortintro{#2}}}

\newcommand*\mkbibnamecorplong{\mkbibnamefamily}
\newcommand*\mkbibnamecorpshort{\mkbibnamecorplong}
\newcommand*{\mkbibnamecorpshortintro}[1]{\mkbibbrackets{\mkbibnamecorpshort{#1}}}
\makeatother

\begin{filecontents}[force]{\jobname.bib}
@book{SCA,
  author = {long={Some Corporate Author}, short={SCA}, nametemplates=corp},
  title = {Title},
  location = {Location},
  publisher = {Publisher},
  date = {2018}
}
@book{SCAb,
  author = {long={Some Corporate Author}, short={SCA}, nametemplates=corp},
  title = {Title},
  location = {Location},
  publisher = {Publisher},
  date = {2017}
}
@book{ACA,
  author = {long={Another Corporate Author}, nametemplates=corp},
  title = {Another Title},
  location = {Location},
  publisher = {Publisher},
  date = {2017}
}
@book{YACA,
  author = {long={Yet Another Corporate Author}, short={YACA}, nametemplates=corp},
  title = {Yet Another Title},
  location = {Location},
  publisher = {Publisher},
  date = {2016}
}
@book{Author,
  author = {Author, Personal},
  title = {Yet Another Title},
  location = {Location},
  publisher = {Publisher},
  date = {2015}
}
@book{ElkAPA,
  author = {Anne Elk and long={American Psychological Association}, short={APA}, nametemplates=corp},
  title = {On the Psychology of Brontosauruses},
  location = {Location},
  publisher = {Publisher},
  date = {1974}
}
@book{HumphreyAPA,
  author = {Humphrey Appleby and long={American Psychological Association}, short={APA}, nametemplates=corp},
  title = {The Civil Service},
  location = {Location},
  publisher = {Publisher},
  date = {1981}
}
\end{filecontents}
\addbibresource{\jobname.bib}
\addbibresource{biblatex-examples.bib}

\begin{document}
\parencite{sigfridsson}

\parencite{SCA}; \parencite{SCA}

\parencite{ACA}; \parencite{ACA}

\parencite{YACA,SCAb}

\parencite{Author,ElkAPA}

\parencite{HumphreyAPA}

\printbibliography
\end{document}

(Sigfridsson and Ryde 1998) (Some Corporate Author [SCA] 2018); (SCA 2018) (Another Corporate Author 2017); (Another Corporate Author 2017) (Yet Another Corporate Author 2016; SCA 2017) (Author 2015; Elk and American Psychological Association [APA] 1974) (Appleby and APA 1981)

5
  • Thank you, that's almost exactly the format I need. I just added in a context sensitive \finalnamedelim and changed the brackets used for abbreviations, and it appears to be perfect.
    – Philip
    Sep 3, 2018 at 12:11
  • @Philip The linked question makes me think you want APA style. biblatex-apa provides the best APA style implementation for LaTeX that I know of, but unfortunately its handling of author abbreviations is not ideal. See github.com/plk/biblatex-apa/issues/63
    – moewe
    Sep 3, 2018 at 12:15
  • @Philip I edited my answer to tex.stackexchange.com/q/359426/35864 to use more modern methods and make it simpler.
    – moewe
    Sep 3, 2018 at 12:37
  • One minor point: it doesn't seem to work when there's only one corporate author (however many times it appears). That's not a problem for my current document (I only noticed because I compiled just one section), but it is peculiar.
    – Philip
    Sep 5, 2018 at 3:24
  • @Philip Could be github.com/plk/biber/issues/234
    – moewe
    Sep 5, 2018 at 4:22
1

You can achieve this using the citetracker and citecounter options of biblatex along with the shortauthor field.

In this solution I redefine the the cite bibmacro (from authoryear.cbx) to add a number of tests. The logic is:

  • If there is no shortauthor field or the entry key has previously been seen (using \ifciteseen
    • then just do the default which is to print the labelname.
  • Else
    • Print the author in the labelname format
    • Then, if this entry key appears more than once in the current ref section, print the labelname in brackets (this will contain the shortauthor)
  • Finally, print the labeldate

MWE

\documentclass{article}
\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@book{SCA,
  author = {{Some Corporate Author}},
  shortauthor = {SCA},
  title = {Title},
  location = {Location},
  publisher = {Publisher},
  date = {2018}
}
@book{ACA,
  author = {{Another Corporate Author}},
  title = {Another Title},
  location = {Location},
  publisher = {Publisher},
  date = {2017}
}
@book{YACA,
  author = {{Yet Another Corporate Author}},
  shortauthor = {YACA},
  title = {Yet Another Title},
  location = {Location},
  publisher = {Publisher},
  date = {2016}
}
@book{Author,
  author = {Author, Personal},
  title = {Yet Another Title},
  location = {Location},
  publisher = {Publisher},
  date = {2015}
}
\end{filecontents}
\usepackage[style=authoryear,citecounter,citetracker]{biblatex}
\addbibresource{\jobname.bib}
\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{document}
\parencite{SCA}; \parencite{SCA}

\parencite{ACA}; \parencite{ACA}

\parencite{YACA}

\parencite{Author}
\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 .