为什么运行 \AtBeginDocument 时这很重要?

为什么运行 \AtBeginDocument 时这很重要?

据我理解,宏中\AtBeginDocument的内容将在 之后立即运行\begin{document}。换句话说,它将遵循序言中的其他内容。但我注意到,序言中的\AtBeginDocument运行时间很重要。请考虑以下示例,取自使用小写前缀引用和排序作者(biblatex)

当行\AtBeginDocument{\toggletrue{blx@useprefix}}放置在biblatex加载之前时,作者在参考书目中van Helten排在下方。换句话说,选项已更改为。这是预料之中的,因为在文档开头激活了,从而覆盖了序言中设置的选项。vbiblatexuseprefixtrue\toggletrue{blx@useprefix}useprefix = false

\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}

在此处输入图片描述

但当\AtBeginDocument{\toggletrue{blx@useprefix}}放置 biblatex加载后,作者在参考书目中van Helten排在下方。换句话说,该选项未被覆盖。为什么会这样?无论如何都不应该最后执行,因此会覆盖序言中设置的选项?hbiblatexuseprefix = false\toggletrue{blx@useprefix}\AtBeginDocument{\toggletrue{blx@useprefix}}useprefix

\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}

在此处输入图片描述

答案1

宏将其内容附加到紧接着展开的\AtBeginDocument宏中。因此,如果您首先发出并附加(由于),因为它在之后加载,所以 togglefalse 部分排在最后并“获胜”。\@begindocumenthook\begin{document}\AtBeginDocument{\toggletrue{blx@useprefix}}biblatex\togglefalse{blx@useprefix}useprefix=false

如果我们往里面看biblatex1.sty,我们可以看到

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

如果我们现在考虑扩展,那么这相当于

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

记住这一点,你的代码

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

简化为类似

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

在哪里\togglefalse执行 \toggletrue,因此在 时开关被设置为 false \begin{document}

答案2

如果你(或你加载的包裹)去

\AtBeginDocument{\newcommand\zz{}}

...

\AtBeginDocument{\zz}

然后在文档开始之前,LaTeX 将会执行

\newcommand\zz{}\zz

不会有任何不好的事情发生。

现在,如果您按照另一种顺序加载包,那么有效用法是:

\AtBeginDocument{\zz}

...

\AtBeginDocument{\newcommand\zz{}}

然后在文档的开头 LaTeX 将会这样做

\zz\newcommand\zz{}

并生成未定义的命令错误,因为\zz它在定义之前被使用。

相关内容