![为什么运行 \AtBeginDocument 时这很重要?](https://linux22.com/image/290607/%E4%B8%BA%E4%BB%80%E4%B9%88%E8%BF%90%E8%A1%8C%20%5CAtBeginDocument%20%E6%97%B6%E8%BF%99%E5%BE%88%E9%87%8D%E8%A6%81%EF%BC%9F.png)
据我理解,宏中\AtBeginDocument
的内容将在 之后立即运行\begin{document}
。换句话说,它将遵循序言中的其他内容。但我注意到,序言中的\AtBeginDocument
运行时间很重要。请考虑以下示例,取自使用小写前缀引用和排序作者(biblatex)。
当行\AtBeginDocument{\toggletrue{blx@useprefix}}
放置在biblatex
加载之前时,作者在参考书目中van Helten
排在下方。换句话说,选项已更改为。这是预料之中的,因为在文档开头激活了,从而覆盖了序言中设置的选项。v
biblatex
useprefix
true
\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
排在下方。换句话说,该选项未被覆盖。为什么会这样?无论如何都不应该最后执行,因此会覆盖序言中设置的选项?h
biblatex
useprefix = 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
它在定义之前被使用。