Skip to content

Instantly share code, notes, and snippets.

@moewew
Created April 5, 2019 19:21
Show Gist options
  • Save moewew/df9eb6e4f730350084b9a3fb371621a9 to your computer and use it in GitHub Desktop.
Save moewew/df9eb6e4f730350084b9a3fb371621a9 to your computer and use it in GitHub Desktop.
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[style=authoryear-comp]{biblatex}
\addbibresource{biblatex-examples.bib}
\renewbibmacro*{cite}{%
<\the\value{overallcitecount}/\the\value{overallcitetotal}>
[\the\value{citecount}/\the\value{citetotal}]}
\begin{document}
% leaking counts with \cite (probably the smuggling?)
A \cite{sigfridsson,worman,nussbaum}
B \cite{sigfridsson}
C \cites{sigfridsson,sigfridsson}
D \cites{sigfridsson}{worman}
E \cites{sigfridsson,sigfridsson}
RESET \setcounter{overallcitecount}{0}\setcounter{overallcitetotal}{0}
% comparison with \cites
A \cites{sigfridsson}{worman}{geer}
B \cite{sigfridsson}
C \cite{sigfridsson,worman}
D \cite{sigfridsson}
RESET \setcounter{overallcitecount}{0}\setcounter{overallcitetotal}{0}
% \forcsvlist over the list of keys does not drop duplicates, hence
% may give inflated values
A \cites{sigfridsson,worman,sigfridsson}
\end{document}
@moewew
Copy link
Author

moewew commented May 18, 2019

Thank you very much for looking into this again. And sorry for not replying sooner.

The smuggling business still feels a bit weird to me especially given the different levels of grouping that we have to care about (as you found out yourself). So global variables still feel a bit safer to me, but that would mean initialising those variables properly, which is probably also going to be a hassle. ...

Of the two options for the sorting thingy I think I prefer option 2. Option 1 is very clever and I'd probably prefer it for an answer on TeX.SX, but if this goes into the package itself it feels wrong to manipulate the macros in such a way. It might be worth thinking about splitting the bits of the original loop macro that we need off into a new macro and use that as a basis for the normal cite and the multicite loop. That way we could avoid the code duplication by externalising the shared code to a macro that is used in both situations. (Come to think of it that might in the end even look similar to option 1.)

The point about sorting multicites before things even start is very relevant and in fact I also thought that it might be worth trying to tackle overallcitecount and sorting-multicites (plk/biblatex#214) together. Unfortunately, the last time I tried to look into sorting multicites there were too many details that made my head spin, so I gave up. The main issue is that each 'multicite group' may contain multiple citations (\cites[34]{sigfridsson,worman}[cf.][45]{nussbaum,geer}) and it is not clear to me how this should be sorted: Should we sort only the groups or the entire list of keys over all groups? How should a group with several items sort (by first item in the unsorted list, by first item when sorted; how would we break ties ...)? Plus, we need to keep track of the pre- and postnotes.

@PhelypeOleinik
Copy link

PhelypeOleinik commented May 18, 2019

Don't worry about the time, I'm doing this for procrastination fun, so there's no need to hurry :)

About the smuggling, I think it's mostly safe, the issue was that I completely overlooked normal citation commands in my first attempt. But I think switching to a global counter is relatively easy. The initialisation of the counter is done in non-global mode anyhow, so I would just need to make the assignments global. The only additional thing that would be necessary (I think) is a cleanup at the end of the citation command to reset the counter to zero (or some special value, say -1, to indicate an “uninitialised” value). On the other hand one might want the value of overallcitetotal after the citation command for whatever reason, so perhaps the cleanup should be in the beginning of the citation command. I'm open to suggestions here.

About the sorting, if we were to change more of BibLaTeX's code it would be ideal to have a dedicated sorting macro which would do exclusively that, so it could be safely used anywhere without clever misuse of macros :) I'd need to understand exactly what each part of \blx@citeloop does to split the code without breaking anything. Now that we're at it: does BibLaTeX have a set of tests which I can use to check how much code I have broken?

I'm not sure I understood correctly what you meant with the sorting of multicite commands. If I did, I think that the sorting of should remain as it is: each group sorted individually (ie, \cites{b,a}{b,b} would be \cites{a,b}{b}) and the groups should be left as input (ie, \cites{b}{a} would remain that way). I think that sorting over all groups is problematic, first because the ambiguity of \cites{a,b}{b}: would it be \cites{a}{b} or \cites{a,b}? This would get worse with pre- and postnotes because the citations could get misplaced relative to the notes. Furthermore, from what I understand the whole purpose of the multicite commands is for the user to separate them in logical groups, so I think this should remain. What could be done, however, is to issue a warning in cases like \cites{a,b}{b} saying that b is duplicated. If things are done this way the pre- and postnotes shouldn't be a problem at all when sorting the multicite groups (I might have overlooked something, though. I do that often :).

I'll leave you my mail if you want to reach me there: moc.liamg ⟨at⟩ 1o.h.ehp (reversed :)

P.S.: I subscribed to this Gist to get notifications :)

@moewew
Copy link
Author

moewew commented May 19, 2019

There is precedence for using global variables and (re-)initialising them at the beginning of the relevant commands (at least on a .cbx level, see for example https://github.com/plk/biblatex/blob/master/tex/latex/biblatex/cbx/authoryear-icomp.cbx), so that would not be unnatural.

Unfortunately, we only have a limited test suite written in Perl. https://github.com/plk/biblatex/tree/dev/obuild. I usually run it as follows from the root of the git folder

./obuild/build.sh install 3.13 ~/texmf
./obuild/build.sh test
./obuild/build.sh testoutput

You'll need a matching version of Biber in your PATH. If you start from current dev that would be the dev version from sourceforge (https://sourceforge.net/projects/biblatex-biber/files/biblatex-biber/development/binaries/). If you start from master Biber 2.12 should be fine.

The test suite only runs on the files in https://github.com/plk/biblatex/tree/dev/doc/latex/biblatex/examples and thus only tests a very limited subset of biblatex's functionality. Joseph worked on l3build tests a while ago (https://github.com/plk/biblatex/tree/l3build-tests), but since most things we'd want to test are typesetting-related and not of the pure function evaluation type that proved difficult.

Sorting multicites is a feature request that comes up from time to time. People see that \cite{sigfrisson,worman,nussbaum,geer} gets sorted if the turn on sortcites=true and then also want \cites{sigfrisson}{worman}{nussbaum}{geer} to give the same result (plk/biblatex#214 is a bit low on details, but https://tex.stackexchange.com/q/65809/35864 has an MWE that shows what I mean). I thought that if we are digging in the implementation of the multicite commands anyway and have to look at sorting we might as well look if something like this is feasible. But there are quite a few conceptual issues here.

@PhelypeOleinik
Copy link

Okay, I'll make the counter global with initialisation at the beginning of the citation command.

The test suite is something to start with, I'll use it. Random thought: testing typesetting is tricky, but I think that the output of \loggingoutput might be something to start with. Given the same settings the boxes TeX make should remain the same. Plus, with pdfTeX and LuaTeX it is possible to have reproducible PDFs (https://tex.stackexchange.com/q/440270/134574), so it might be used as well. I'll learn how to use l3build to do something about that.

I think that sorting the multicites will be awkward, but it can be done. However I believe that it should not be activated by sortcites. I think that a new option (a good name would be IKnowThatThisIsn'tThePurposeOfMulticitesButI'llDoThisAnyway ;-) should be added to make that work. Certainly possible, given an enough amount of code :)

I'm working on it. Right now I'm trying to understand how the sorting algorithm works to start messing around with it. As soon as I have something new I send you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment