Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

As I understood the macro \AtBeginDocument, whatever it says will be run right after \begin{document}. In other words, it will follow whatever else there is in the preamble. But I've noticed that it matters when in the preamble \AtBeginDocument is run. Consider the following example, taken from Cite and sort author with lowercase prefix (biblatex).

When the line \AtBeginDocument{\toggletrue{blx@useprefix}} is placed before biblatex is loaded, the author van Helten is sorted under v in the bibliography. The biblatex option useprefix has in other words been changed to true. This is expected, since \toggletrue{blx@useprefix} is activated at the beginning of the document, thus overriding the option useprefix = false which was set in the preamble.

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{filecontents}
\AtBeginDocument{\toggletrue{blx@useprefix}}
\usepackage[style=authoryear, useprefix = false]{biblatex}
\renewbibmacro*{begentry}{\midsentence}
\begin{filecontents}{\jobname.bib}
@ARTICLE{vanhelten1891,
    AUTHOR = "W. van Helten",
    TITLE = "Grammatisches",
    JOURNALTITLE = "Beiträge zur Geschichte der deutschen Sprache und Literatur",
    YEAR = "1891",
    PAGES = "455--488",
    VOLUME = "15"}
@BOOK{mccartney1967,
    AUTHOR = "Paul McCartney",
    TITLE = "Hey Jude",
    YEAR = "1967"}
\end{filecontents}
\addbibresource{\jobname.bib}
\begin{document}
\cites{vanhelten1891}{mccartney1967}
\printbibliography
\end{document}

enter image description here

But when \AtBeginDocument{\toggletrue{blx@useprefix}} is placed after biblatex is loaded, the author van Helten is sorted under h in the bibliography. The biblatex option useprefix = false has in other words not been overridden by \toggletrue{blx@useprefix}. Why is this? Shouldn't \AtBeginDocument{\toggletrue{blx@useprefix}} be executed last anyway, and therefore override whatever the option useprefix is set to in the preamble?

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{filecontents}
\usepackage[style=authoryear, useprefix = false]{biblatex}
\AtBeginDocument{\toggletrue{blx@useprefix}}
\renewbibmacro*{begentry}{\midsentence}
\begin{filecontents}{\jobname.bib}
@ARTICLE{vanhelten1891,
    AUTHOR = "W. van Helten",
    TITLE = "Grammatisches",
    JOURNALTITLE = "Beiträge zur Geschichte der deutschen Sprache und Literatur",
    YEAR = "1891",
    PAGES = "455--488",
    VOLUME = "15"}
@BOOK{mccartney1967,
    AUTHOR = "Paul McCartney",
    TITLE = "Hey Jude",
    YEAR = "1967"}
\end{filecontents}
\addbibresource{\jobname.bib}
\begin{document}
\cites{vanhelten1891}{mccartney1967}
\printbibliography
\end{document}

enter image description here

share|improve this question
    
The \AtBeginDocument macro appends its contents to a token list, which is expanded right after \begin{document}. Hence, if you first issue \AtBeginDocument{\toggletrue{blx@useprefix}} and biblatex appends \togglefalse{blx@useprefix}, because it is loaded afterwards the togglefalse part stands last and "wins". –  Henri Menke May 15 at 15:37
    
@HenriMenke You mean that biblatex also appends \togglefalse{blx@useprefix} to the same "token list" that \AtBeginDocument appends \toggletrue{blx@useprefix} to? –  Sverre May 15 at 15:40
    
That's my guess. I don't know for sure, but you can of course look it up in the biblatex code. –  Henri Menke May 15 at 15:43
    
Just like I guessed: \AtBeginDocument{...\blx@bblinput...} where \def\blx@bblinput{...\blx@blxinit...} and \appto\blx@blxinit{...\def\ifuseprefix{\iftoggle{blx@useprefix}...}. Hence \toggle____{blx@useprefix} is buried deep inside \AtBeginDocument. –  Henri Menke May 15 at 15:49
    
Sorry, \AtBeginDocument is not a token list, but a macro, which is extended via \g@addto@macro on every occurrence. –  Henri Menke May 15 at 15:54
show 1 more comment

2 Answers 2

up vote 9 down vote accepted

The \AtBeginDocument macro appends its contents to the macro \@begindocumenthook which is expanded right after \begin{document}. Hence, if you first issue \AtBeginDocument{\toggletrue{blx@useprefix}} and biblatex appends \togglefalse{blx@useprefix} (due to useprefix=false), because it is loaded afterwards the togglefalse part stands last and "wins".

If we look inside biblatex1.sty, we can see

\AtBeginDocument{...\blx@bblinput...}
...
\def\blx@bblinput{...\blx@blxinit...}
...
\appto\blx@blxinit{...\def\ifuseprefix{\iftoggle{blx@useprefix}}...}

If we now consider expansion then this is equivalent to

\AtBeginDocument{...\def\ifuseprefix{\iftoggle{blx@useprefix}}...}

Keeping this in mind, your code

\AtBeginDocument{\toggletrue{blx@useprefix}}
\usepackage[style=authoryear, useprefix = false]{biblatex}

reduces to something like

\AtBeginDocument{\toggletrue{blx@useprefix}\togglefalse{blx@useprefix}}

where \togglefalse is being executed after \toggletrue, hence the switch is set to false at \begin{document}.

share|improve this answer
add comment

If you (or a packages you load) go

\AtBeginDocument{\newcommand\zz{}}

...

\AtBeginDocument{\zz}

Then just before the document starts, LaTeX will do

\newcommand\zz{}\zz

and nothing bad will happen.

Now, if you load packages in another order so the effective usage is:

\AtBeginDocument{\zz}

...

\AtBeginDocument{\newcommand\zz{}}

then at the start of the document LaTeX will do

\zz\newcommand\zz{}

and generate an undefined command error as \zz is used before it is defined.

share|improve this answer
    
But this is because the order of macros internally to \AtBeginDocument is wrong. That's not quite the scenario illustrated in my question, is it? –  Sverre May 15 at 15:55
    
@Sverre It is not exactly your scenario, but it shows, that the order of \AtBeginDocument statements is very important. –  Henri Menke May 15 at 15:56
    
@Sverre more or less but just using simpler code. Basically I wanted to highlight that it only matters if two things are added to the begin document hook as the order they are executed is the order they are added, so the expectation should be that it matters when you use this hook (if you suspect any package you are using uses it) the exact details of what goes wrong in each case differ of course –  David Carlisle May 15 at 15:57
    
@HenriMenke Yes, but this is about the order of multiple instances of \AtBeginDocument. It seems rather straightforward that that order matters when those commands are executed. –  Sverre May 15 at 15:58
    
@Sverre your question is all about multiple instances of AtBeginDocument the ones you do and the ones biblatex does –  David Carlisle May 15 at 15:59
show 3 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.