2

I'd like to reproduce the results of this post using the numeric-comp citestyle. Using the solution as-is, I get an error saying "Macro 'cite' undefined", and nothing comes out boldfaced.

I tried changing cite to cite:comp in the relevant lines (see below), and got some boldface out of that, but not consistently. It looks like the last number in a compressed range does not get boldface unless it is followed by another boldface number, but I don't know why. Any help would be much appreciated. Thanks!

MWE:

\documentclass{article}
\usepackage{filecontents}
\usepackage[backend=biber,style = numeric-comp, sortcites]{biblatex}
\usepackage[colorlinks=true, breaklinks, allcolors = blue]{hyperref}
\DeclareSourcemap{%
  \maps[datatype=bibtex]{%
    \map{%
      \step[fieldsource=author, match=Doe, final]%
      \step[fieldset=keywords, fieldvalue=doe]%
    }%
  }%
}
\begin{filecontents}{\jobname.bib}
@Book{p1,
  author =       "Joe Bar",
  title =        "A Scientific Article 1",
  year =         "1995"  
}
@Book{p2,
  author =       "John Doe",
  title =        "A Scientific Article 2",
  year =         "1985"  
}
@Book{p3,
  author =       "A. U. Thor and John Doe",
  title =        "A Scientific Article 3",
  year =         "1975"  
}
@Book{p4,
  author =       "A. U. Thor and John Doe",
  title =        "A Scientific Article 4",
  year =         "2010"  
}
@Book{p5,
  author =       "Jane Zaz",
  title =        "A Scientific Article 5",
  year =         "2005"  
}
@Book{p6,
  author =       "Jane Zaz",
  title =        "A Scientific Article 6",
  year =         "2015"  
}
@Book{p7,
  author =       "Jane Zaz and John Doe",
  title =        "A Scientific Article 7",
  year =         "2020"  
}
\end{filecontents}
\addbibresource{\jobname.bib}

\DeclareFieldFormat{keywordcite}{\ifkeyword{doe}{\mkbibbold{#1}}{#1}} \csletcs{old:cite:comp}{abx@macro@cite:comp} \renewbibmacro{cite:comp}{\printtext[keywordcite]{\csuse{old:cite:comp}}}

\nocite{*} \begin{document}

In \cite{p2, p3, p4, p6}, 2 and 4 should be \textbf{bold}.

In \cite{p2, p3, p4, p7}, 2, 4, and 7 should be \textbf{bold}.

In \cite{p1, p3, p4, p5, p6, p7}, 3 and 7 should be \textbf{bold}.

In \cite{p1, p2, p3}, 3 should be \textbf{bold}.

In \cite{p1, p2, p3, p7}, 3 and 7 should be \textbf{bold}.

\printbibliography \end{document}

enter image description here

UPDATE:

I was able to make things a little better by adding the lines

\csletcs{old:cite:dump}{abx@macro@cite:dump}
\renewbibmacro{cite:dump}{\printtext[keywordcite]{\csuse{old:cite:dump}}}

enter image description here

Still not a complete solution, though.

1 Answers1

2

Compared to other citation styles, the code of numeric-comp is incredibly complex. The different bits of the citation output are produced by different helper bibmacros and in order for the compress feature to work properly it is even necessary to print the data of certain entries "out of scope" (i.e. the citation of a certain entry may be printed when a different entry is being processed - at that time we cannot easily access other data of the entry).

This makes it pretty challenging to achieve what you want. It is not just a matter of wrapping a single bibmacro in \printtext[keywordcite], because that bibmacro may end up printing citations to other entries as well and may even not print the "current" entry at all. First we need to inject a \printtext[keywordcite]{...} in every bibmacro that produces citation output for the entry currently in scope. Then we need to "remember" the keyword status of citations that are printed "out of scope" and use this remembered status for the bibmacros that print data "out of scope". Hence we end up with the following 100-line monstrosity.

The following code was designed and tested for the current version of biblatex (v3.16 from 2020-12-31). If I recall correctly it needs at least v3.15a (2020-08-23) and will not work with older versions.

\documentclass{article}

\usepackage[backend=biber,style = numeric-comp, sortcites]{biblatex}

\usepackage[colorlinks=true, breaklinks, allcolors = blue]{hyperref}

\DeclareSourcemap{% \maps[datatype=bibtex]{% \map{% \step[fieldsource=author, match=Doe, final]% \step[fieldset=keywords, fieldvalue=doe]% }% }% }

\makeatletter \DeclareFieldFormat{keywordcite}{\ifkeyword{doe}{\mkbibbold{#1}}{#1}}

\newcommand*{\cbx@if@lastkeyword@doe}{} \let\cbx@if@lastkeyword@doe@secondoftwo

\DeclareFieldFormat{lastkeywordcite}{\cbx@if@lastkeyword@doe{\mkbibbold{#1}}{#1}}

\renewbibmacro{cite:comp:comp}{% \cbx@iflabelprefixequalslast {\ifnumequal{\thefield{labelnumber}}{\value{cbx@tempcntb}} {\savefield{entrykey}{\cbx@lastkey}% \savefield{labelnumber}{\cbx@lastnumber}% \ifkeyword{doe} {\global\let\cbx@if@lastkeyword@doe@firstoftwo} {\global\let\cbx@if@lastkeyword@doe@secondoftwo}% \stepcounter{cbx@tempcnta}} {\ifnumequal{\thefield{labelnumber}}{\value{cbx@tempcntb}-1} {% current cite is exactly* the same a previous source % this can only happen if the same source is cited twice % and sortcites is turned off % print nothing } {\usebibmacro{cite:comp:end}}}} {\usebibmacro{cite:comp:end}}% \setcounter{cbx@tempcntb}{\thefield{labelnumber}}% \savefield{labelprefix}{\cbx@lastprefix}}

\renewbibmacro{cite:comp:inset}{% \stepcounter{cbx@tempcntd}% \ifboolexpr{ togl {cbx:subentrycomp} and test {\cbx@iflabelnumberandprefixequallast}} {\ifnumequal{\thefield{entrysetcount}}{\value{cbx@tempcntd}} {\savefield{entrykey}{\cbx@lastkey}% \savefield{entrysetcount}{\cbx@lastentrysetcount}% \ifkeyword{doe} {\global\let\cbx@if@lastkeyword@doe@firstoftwo} {\global\let\cbx@if@lastkeyword@doe@secondoftwo}% \stepcounter{cbx@tempcntc}} {\ifnumequal{\thefield{entrysetcount}}{\value{cbx@tempcntd}-1} {% current cite is exactly* the same a previous source % this can only happen if the same source is cited twice % and sortcites is turned off % print nothing } {\usebibmacro{cite:dump:inset}% \ifnumgreater{\value{cbx@tempcntd}}{-1} {\setunit{\multicitesubentrydelim}} {}% \usebibmacro{cite:print:subentry:comp}}}} {\usebibmacro{cite:dump}% \ifnumgreater{\value{cbx@tempcntb}}{-1} {\multicitedelim} {}% \setcounter{cbx@tempcntd}{-1}% \usebibmacro{cite:print:subentry:full}% \savefield{labelprefix}{\cbx@lastprefix}% \savefield{labelnumber}{\cbx@lastnumber}}% \setcounter{cbx@tempcntd}{\thefield{entrysetcount}}% \setcounter{cbx@tempcntb}{-1}}

\renewbibmacro*{cite:print:shorthand}{% \printtext[bibhyperref]{% \printtext[keywordcite]{% \printfield{shorthand}}}}

\renewbibmacro*{cite:print:labelnumber}{% \printtext[bibhyperref]{% \printtext[keywordcite]{% \printfield{labelprefix}% \printfield{labelnumber}}}}

\renewbibmacro*{cite:print:subentry:comp}{% \printtext[bibhyperref]{% \printtext[keywordcite]{% \printfield{entrysetcount}}}}

\renewbibmacro*{cite:print:subentry:full}{% \printtext[bibhyperref]{% \printtext[keywordcite]{% \printfield{labelprefix}% \printfield{labelnumber}% \printfield{entrysetcount}}}}

\renewbibmacro*{cite:print:last:subentry:comp}{% \printtext[bibhyperref:lastkey]{% \printtext[lastkeywordcite]{% \printtext[entrysetcount]{\cbx@lastentrysetcount}}}}

\renewbibmacro*{cite:print:last:labelnumber}{% \printtext[bibhyperref:lastkey]{% \printtext[lastkeywordcite]{% \ifdef\cbx@lastprefix {\printtext[labelprefix]{\cbx@lastprefix}} {}% \printtext[labelnumber]{\cbx@lastnumber}}}} \makeatother

\begin{filecontents}{\jobname.bib} @Book{p1, author = {Joe Bar}, title = {A Scientific Article 1}, year = {1995}, } @Book{p2, author = {John Doe}, title = {A Scientific Article 2}, year = {1985}, } @Book{p3, author = {A. U. Thor and John Doe}, title = {A Scientific Article 3}, year = {1975}, } @Book{p4, author = {A. U. Thor and John Doe}, title = {A Scientific Article 4}, year = {2010}, } @Book{p5, author = {Jane Zaz}, title = {A Scientific Article 5}, year = {2005}, } @Book{p6, author = {Jane Zaz}, title = {A Scientific Article 6}, year = {2015}, } @Book{p7, author = {Jane Zaz and John Doe}, title = {A Scientific Article 7}, year = {2020}, } \end{filecontents} \addbibresource{\jobname.bib}

\begin{document} In \cite{p2, p3, p4, p6}, 2 and 4 should be \textbf{bold}.

In \cite{p2, p3, p4, p7}, 2, 4, and 7 should be \textbf{bold}.

In \cite{p1, p3, p4, p5, p6, p7}, 3 and 7 should be \textbf{bold}.

In \cite{p1, p2, p3}, 3 should be \textbf{bold}.

In \cite{p1, p2, p3, p7}, 3 and 7 should be \textbf{bold}.

\printbibliography \end{document}

Output is
"In [2–4, 6], 2 and 4 should be bold.
In [2–4, 7], 2, 4, and 7 should be bold.
In [1, 3–7], 3 and 7 should be bold.
In [1–3], 3 should be bold.
In [1–3, 7], 3 and 7 should be bold."
with the expected numbers in bold.

moewe
  • 175,683
  • My god... you are my hero. Out of curiosity, do you have a (relatively simple) explanation for why adding the cite:comp and cite:dump lines I used did almost all of the work, but failed in the first case? – skewlkid521 Nov 05 '21 at 16:25
  • 1
    @skewlkid521 Roughly for the reason mentioned briefly in the first paragraph. With all other citation styles an entry is printed when it is processed. But numeric-comp can only decide if/how to print an entry if it has examined the citations that come after it. So some citations are printed "after" they were processed. ... – moewe Nov 05 '21 at 16:43
  • 1
    ... The "4" in the first citation [2-4, 7] is printed when the corresponding entry is no longer in scope (i.e. after the entry has been processes by the cite loop). (biblatex remembers the relevant bits for the citation label, but not all entry data.) In particular the \ifkeyword at that point does not correspond to the entry 4 but to a different entry. – moewe Nov 05 '21 at 16:43