Skip to content

biblatex not settling down when mixing numeric & non-numeric styles #70

Closed
iXce opened this Issue Jan 19, 2013 · 22 comments

2 participants

@iXce
iXce commented Jan 19, 2013

I use biblatex with two different bibliography styles, one with authoryear style (for publications) and the other one with simple numeric style for online references, but pdflatex never really settles down. The issue is that because of the defernumbers/omitnumbers options I have to run pdflatex/biber/pdflatex/pdflatex to get the numbers right for the numeric ones (basically the references which are in the authoryear style are first not ignored in the numbering, so you need to run pdflatex twice to let biblatex recompute the correct ones), but this last pdflatex run is going to change the width of the text size of the references, and thus might change the page breaks and move other references to other pages, thus requiring a rerun of pdflatex. Which would be perfectly fine if biblatex (using version 2.4 + biber 1.4, but I think I have the same issue with 2.5/1.5 on another computer) hadn't a cycling behavior : one more run of pdflatex changes the numbers back to the wrong ones, and you have to rerun one more time to get the right numbers... which changes the page breaks again, and you're stuck. The following almost-MWE (I had to include the alternative environment & citation command for @online entries to demonstrate the issue, not sure how to shrink it down) exhibits the cycling behavior of the defernumbers/omitnumbers options, which is (I think) the root cause of my issue :

\documentclass{article}

\usepackage[style=authoryear,backend=biber,labelnumber,defernumbers]{biblatex}

\DeclareCiteCommand{\citeonline}[\mkbibbrackets]
  {\usebibmacro{prenote}}
  {\usebibmacro{citeindex}%
   \printtext[bibhyperref]{%
     \printfield{prefixnumber}%
     \printfield{labelnumber}}}
  {\multicitedelim}
  {\usebibmacro{postnote}}

\defbibenvironment{online}
  {\list
     {\printtext[labelnumberwidth]{%
  \iffieldundef{shorthand}
    {\printfield{prefixnumber}%
     \printfield{labelnumber}}
    {\printfield{shorthand}}}}
     {\setlength{\labelwidth}{\labelnumberwidth}%
      \setlength{\leftmargin}{\labelwidth}%
      \setlength{\labelsep}{\biblabelsep}%
      \addtolength{\leftmargin}{\labelsep}%
      \setlength{\itemsep}{\bibitemsep}%
      \setlength{\parsep}{\bibparsep}}%
      \renewcommand*{\makelabel}[1]{\hss##1}}
  {\endlist}
  {\item}

\begin{filecontents*}{test.bib}
@article{TehAuthor2013,
  author = "TehAuthor",
  year = 2013,
  journal = "Random Thoughts about science",
  title = "Blablabla",
}
@online{TSE2011,
  author = "TSE",
  year = 2011,
  url = "http://tex.stackexchange.com/blabla",
}
\end{filecontents*}
\bibliography{test.bib}

\title{}
\begin{document}

\parencite{TehAuthor2013} \\
\parencite{TSE2011}

\printbibliography[heading=subbibliography,title={In print},nottype=online,omitnumbers]
\printbibliography[heading=subbibliography,title={Online},sorting=none,type=online,env=online]

\end{document}

I first asked this question on tex.stackexchange.com, and it seems this is a bug, so here's the bug report. Could you look at it ? Thanks !

@plk
Owner
plk commented Jan 19, 2013

Urgh. I did a lot of work with this issue not so long ago and I had hoped it was fixed. Although that was perhaps different because it wasn't interacting woth page breaks.

@iXce
iXce commented Jan 19, 2013

Well yeah, it works fine when there is no page break issue. The provided example correctly stops asking for reruns after pdflatex/biber/pdflatex/pdflatex, but if you run pdflatex one more time it changes the numbers again and asks for a rerun.

@plk plk added a commit that referenced this issue Jan 21, 2013
@plk Attmpted fix for #70 2849ae3
@plk
Owner
plk commented Jan 21, 2013

I think/hope that I know what the problem is. Can you get biblatex2.sty from the dev branch and drop it over your 2.5 install version and try that?

@iXce
iXce commented Jan 21, 2013

Did that, but the behavior is still there (numbers being reset to the wrong ones and then to the right ones endlessly)

@plk
Owner
plk commented Jan 21, 2013

Really? With that fix, for me your example works ok. I run tex/biber/tex/tex and then it looks right. I run tex again and it asks to re-run (which it must as defernumbers is being used) and then I re-run. There are no more re-run messages and the output numbering is the same as after the first tex/bib/tex/tex cycle. You have to check the output only after latex stops asking for re-runs.

@plk
Owner
plk commented Jan 21, 2013

I see that I didn't read your description correctly. I have to think about whether this is possible - there is a .aux file involved and so usually two runs are needed to be stable when using defernumbers.

@iXce
iXce commented Jan 21, 2013

Okai, well then that's right for the simple example, but it never stops asking for reruns in my case, because the numbers keep changing, which keeps changing the pagebreaks (so when the numbers get right I have to rerun to get the right pagebreaks with the "small" numbers, but then it goes back to the wrong numbers again, so I have to rerun to get the right numbers, which changes the pagebreaks again). Isn't there a way to stabilize the numbers after the initial tex/biber/tex/tex runs ?
If you're not afraid and need a test example, here is the big project I'm working on (28M), entry file being these.tex : [link removed for privacy]

@plk
Owner
plk commented Jan 21, 2013

Ok, the issue is that it keeps asking for re-runs, not that the numbers are wrong before re-runs are done, that's expected. I suspect it's asking for re-runs for two different reasons - does it say in your big example - "page breaks have changed, please re-run" or whatever?

@iXce
iXce commented Jan 21, 2013

Yes, that's exactly the issue : two different causes for reruns which interlace and lead to a neverending situation

@plk plk added a commit that referenced this issue Jan 21, 2013
@plk Undid fix for #70 as it was spurious 9d61241
@iXce
iXce commented Jan 21, 2013

About the messages it says this on the first run :
Package biblatex Warning: Please (re)run Biber on the file:
(biblatex) these
(biblatex) and rerun LaTeX afterwards.

And then on any subsequent run it always says :
Package biblatex Warning: Please rerun LaTeX.
(biblatex) Page breaks have changed.

@iXce
iXce commented Jan 21, 2013

Hmm, so as far as I understand the issue, we need a way to store in the .aux file that the numbering is now correct unless the citation orders changes again (so we need to store the current order of citations keys as well). If the .aux says the numbering is correct && the citations are in the same order as before, ignore defernumbers and just use the stored labelnumbers (which would have to be stored if they aren't already) ?

@plk
Owner
plk commented Jan 22, 2013

You're absolutely correct but in fact this is what we already do and it's why your minimal example without page break problems works at all (the tricky part is when some \printbibliography macros have omitnumbers and some don't etc.). What I really need is to be able to reproduce the real problem with page breaks on a manageable example ...

@iXce
iXce commented Jan 22, 2013

Hm, we can probably do it making a single-line page with a few numbered and authoryear refs on the line so that it overflows to a second page when changing the numbers ?
Also, the more I think about it the less I understand why the extra pdflatex run changes the numbers back : what has changed that requires redoing the numbers ? Is the stuff stored between the second and third passes changed/removed by the third pass so that the fourth pdflatex pass can't build on it ?

@plk
Owner
plk commented Jan 22, 2013

Can you construct an example? The multiple run thing is quite complex. Basically, biblatex either has to consume localnumber information from the .aux or write it to the .aux if it's not there. After the second run, it's not there so the only option is to write it and that triggers an automatic re-run message. It has to write it on the third run as you might have changed omitnumbers options, added more \printbibliography commands or whatever (such a change doesn't change citations or citation order so you can't detect it that easily). So, since you had a third run which wrote localnumber information, you need a fourth run to consume that information and use it correctly. This is just necessary because latex is a one-pass per document architecture so you have to save state externally and run again - there is no other way to deal with document-wide dynamic information that you can't determine completely until \end{document}.

@iXce
iXce commented Jan 22, 2013

I see, so the issue is that right after pdflatex/biber/pdflatex we assume we haven't "changed omitnumbers options, added more \printbibliography commands or whatever", but we don't propagate this assumption after the third pdflatex run. This makes a lot of sense. Though we could maybe still keep the same computed labelnumbers after the third pdflatex run, and only change them if we detect they are wrong (due to some options/extra printbibliography changes), no ?
I'm going to try crafting a simple, minimal example.

@plk
Owner
plk commented Jan 22, 2013

Yes, we could add many special tests to see if things have changed but at that point, it's getting rather crowded with special cases. I already added quite a few of these in order to generate re-run messages when citations are delete/added or when sorting is "none" and the citations set is the same but the order changes (because this changes localnumber with no sorting). What you would have to detect for what you want is really hard and messy - \printbibliography macros, their order, their options, the exact sorting for each and worse, per-entry options which impact this (which is pretty much impossible). It's a thousand times easier and in fact more reliable just to re-run to be sure it's all done.

@iXce
iXce commented Jan 22, 2013

I see. Here is a pretty much minimal example :

\documentclass{article}

\usepackage[paperwidth=4in,paperheight=0.8in]{geometry}

\usepackage[style=authoryear,backend=biber,labelnumber,defernumbers]{biblatex}

\DeclareCiteCommand{\citeonline}[\mkbibbrackets]
  {\usebibmacro{prenote}}
  {\usebibmacro{citeindex}%
   \printtext[bibhyperref]{%
     \printfield{prefixnumber}%
     \printfield{labelnumber}}}
  {\multicitedelim}
  {\usebibmacro{postnote}}

\defbibenvironment{online}
  {\list
     {\printtext[labelnumberwidth]{%
  \iffieldundef{shorthand}
    {\printfield{prefixnumber}%
     \printfield{labelnumber}}
    {\printfield{shorthand}}}}
     {\setlength{\labelwidth}{\labelnumberwidth}%
      \setlength{\leftmargin}{\labelwidth}%
      \setlength{\labelsep}{\biblabelsep}%
      \addtolength{\leftmargin}{\labelsep}%
      \setlength{\itemsep}{\bibitemsep}%
      \setlength{\parsep}{\bibparsep}}%
      \renewcommand*{\makelabel}[1]{\hss##1}}
  {\endlist}
  {\item}

\begin{filecontents*}{test.bib}
@article{TehAuthor2010,
  author = "TehAuthor",
  year = 2010,
  journal = "Random Thoughts about science",
  title = "Blablabla",
}
@article{TehAuthor2011,
  author = "TehAuthor",
  year = 2011,
  journal = "Random Thoughts about science",
  title = "Blablabla",
}
@article{TehAuthor2012,
  author = "TehAuthor",
  year = 2012,
  journal = "Random Thoughts about science",
  title = "Blablabla",
}
@article{TehAuthor2013,
  author = "TehAuthor",
  year = 2013,
  journal = "Random Thoughts about science",
  title = "Blablabla",
}
@article{TehAuthor2014,
  author = "TehAuthor",
  year = 2014,
  journal = "Random Thoughts about science",
  title = "Blablabla",
}
@online{TSE2011a,
  author = "TSE",
  year = 2011,
  url = "http://tex.stackexchange.com/blabla",
}
@online{TSE2011b,
  author = "TSE",
  year = 2011,
  url = "http://tex.stackexchange.com/blabla",
}
@online{TSE2011c,
  author = "TSE",
  year = 2011,
  url = "http://tex.stackexchange.com/blabla",
}
@online{TSE2011d,
  author = "TSE",
  year = 2011,
  url = "http://tex.stackexchange.com/blabla",
}
@online{TSE2011e,
  author = "TSE",
  year = 2011,
  url = "http://tex.stackexchange.com/blabla",
}
@online{TSE2011f,
  author = "TSE",
  year = 2011,
  url = "http://tex.stackexchange.com/blabla",
}
\end{filecontents*}
\bibliography{test.bib}

\title{}
\begin{document}

blabla \cite{TehAuthor2010}
blabla \cite{TehAuthor2011}
blabla \cite{TehAuthor2012}
blabla \cite{TehAuthor2013}
blabla \cite{TehAuthor2014}
ble ble
\citeonline{TSE2011a} blu blu blo blo bli bli
\citeonline{TSE2011b} blu blu blo blo bli bli
\citeonline{TSE2011c} blu blu blo blo bli bli
\citeonline{TSE2011d} blu blu blo blo bli bli
\citeonline{TSE2011d} blu blu blo blo bli bli
\citeonline{TSE2011f} blu blu blo blo bli bli

\printbibliography[heading=subbibliography,title={In print},nottype=online,omitnumbers]
\printbibliography[heading=subbibliography,title={Online},sorting=none,type=online,env=online]

\end{document}

A very weird thing is that it seems to behave perfectly if I remove the "author" fields of the @online entries.

@iXce
iXce commented Jan 22, 2013

Ah hm, the removal of the author field was just an artifact -- removing author made the entries be sorted in the order as they appear in the file, which simply looked good, but that's just an artifact. Let's keep the author fields and forget my c omment.

@plk
Owner
plk commented Jan 22, 2013

Ok, thanks, I'll run the minimal example tomorrow try to see what's happening.

@plk plk added a commit that referenced this issue Jan 28, 2013
@plk Another attempted fix for #70 8ed90f9
@plk
Owner
plk commented Jan 28, 2013

Can you pull the dev branch biblatex2.sty and try that? I can get your example to work now. It needs three runs after biber to settle down, one for pagebreaks and two for defernums. If this works, I think adding a note in the manual about having to delete .aux if you change options like "defernumbers" or "omitnumbers" would be adequate. There is no way to completley detect all possible changes which impact deferred numbering.

@iXce
iXce commented Jan 28, 2013

Looks perfect ! Works great on my big project, it's settling down alright after pdflatex/biber/pdflatex*3 as you said. Thanks a lot :)

@plk
Owner
plk commented Jan 28, 2013

Good. I'll close this for now but re-open if you find any problems. I'll look at it a bit more, to try to see if I can see any issues with this solution.

@plk plk closed this Jan 28, 2013
@plk plk added a commit that referenced this issue Jan 28, 2013
@plk Updated doc for #70 fix 1851727
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.