\AtBeginDocument 和包

\AtBeginDocument 和包

這是 (Lua)LaTeX 編譯器的一個非常令人費解的行為。在下面的情況下,輸出取決於某些程式碼是放在包中還是直接放在主文件中;\relax在文件開頭請求額外的命令會改變行為;而且我無法確定一些神秘錯誤的來源...我想了解編譯器在產生這種行為的背後發生了什麼,以避免在續集中出現類似的不良行為!

情況如下。讓以下文件main.tex

\documentclass{minimal}
\usepackage{sandbox}
\begin{document}
$\alpha$
\end{document}

連同以下sandbox.sty文件:

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{sandbox}
\AtBeginDocument{\relax}
\RequirePackage{unicode-math}
\AtBeginDocument{\renewcommand\alpha{\beta}}
\endinput

編譯後,它會印出一些 alpha 符號,而它應該會印一些 beta...!這是第一個令人驚訝的行為。

更神秘的是,如果我這麼做的話任何一個以下三者中:

  • 評論該\AtBeginDocument{\relax}sandbox.sty
  • 評論該\RequirePackage{unicode-math}sandbox.sty
  • \usepackage{sandbox}將in 的行替換main.tex為核心內容sandbox.sty(即,三行是套件的實際內容),

然後它會列印一些測試版,正如最初預期的那樣......這似乎完全不連貫!有大佬幫忙解釋一下嗎?

答案1

正如評論中所指出的,這與添加掛鉤的行為有關。材料被添加到鉤子中,預設順序是“較早”的文件更早執行其鉤子內容,除了頂級條目(使用者文件)位於最後。我們可以看到,如果我們加入\ShowHook{begindocument}輸入中,就會得到:

-> The hook 'begindocument':
> Code chunks:
>     sandbox -> \relax \renewcommand \alpha {\beta }
>     fontspec-luatex -> \tl_set_eq:NN \cyrillicencoding \g_fontspec_encoding_t
l \tl_set_eq:NN \latinencoding \g_fontspec_encoding_tl \RenewDocumentCommand \o
ldstylenums {m}{\__fontspec_main_oldstylenums:n {##1}}\fontspec_maybe_setup_mat
hs: 
>     amsmath -> \reset@strutbox@ \MakeRobust \dddot \MakeRobust \ddddot \Umath
charnumdef \std@minus \Umathcodenum `\-\relax \Umathcharnumdef \std@equal \Umat
hcodenum `\=\relax \expandafter \let \csname overleftarrow \endcsname \@undefin
ed \expandafter \let \csname overrightarrow \endcsname \@undefined \MakeRobust 
\overrightarrow \MakeRobust \overleftarrow \MakeRobust \overleftrightarrow \Mak
eRobust \underrightarrow \MakeRobust \underleftarrow \MakeRobust \underleftrigh
tarrow 
>     unicode-math-luatex -> \__um_define_math_chars: \tl_if_eq:onT {\g__fontsp
ec_mathrm_tl }{\rmdefault }{\__fontspec_setmathrm_hook:nn {}{}}\tl_if_eq:onT {\
g__fontspec_mathsf_tl }{\sfdefault }{\__fontspec_setmathsf_hook:nn {}{}}\tl_if_
eq:onT {\g__fontspec_mathtt_tl }{\ttdefault }{\__fontspec_setmathtt_hook:nn {}{
}}\bool_if:NF \g__um_main_font_defined_bool \__um_load_lm: \__um_setup_mathtext
: \__um_define_prime_commands: \__um_define_prime_chars: \cs_new_protected:Npn 
\__um_patch_url: {\tl_put_left:Nn \Url@FormatString {\__um_switch_to:n {literal
}}\tl_put_right:Nn \UrlSpecials {\do \`{\mathchar `\`}\do \'{\mathchar `\'}\do 
\${\mathchar `\$}\do \&{\mathchar `\&}}}\@ifpackageloaded {url}{\__um_patch_url
: }{}\cs_new_protected:Npn \__um_patch_mathtools_B: {\cs_set_eq:NN \MToverbrack
et \overbracket \cs_set_eq:NN \MTunderbracket \underbracket \AtBeginDocument {\
msg_warning:nn {unicode-math}{mathtools-overbracket}\cs_set:Npn \downbracketfil
l ####1####2{\tl_set:Nn \l_MT_bracketheight_fdim {.27ex}\downbracketend {####1}
{####2}\leaders \vrule \@height ####1\@depth \z@ \hfill \downbracketend {####1}
{####2}}\cs_set:Npn \upbracketfill ####1####2{\tl_set:Nn \l_MT_bracketheight_fd
im {.27ex}\upbracketend {####1}{####2}\leaders \vrule \@height \z@ \@depth ####
1\hfill \upbracketend {####1}{####2}}\cs_set_eq:NN \Uoverbracket \overbracket \
cs_set_eq:NN \Uunderbracket \underbracket \cs_set_eq:NN \overbracket \MToverbra
cket \cs_set_eq:NN \underbracket \MTunderbracket }}\@ifpackageloaded {mathtools
}{\__um_patch_mathtools_B: }{}\cs_new_protected:Npn \__um_patch_mathtools_C: {\
msg_warning:nn {unicode-math}{mathtools-colon}\DeclareDocumentCommand \dblcolon
 {}{\Colon }\DeclareDocumentCommand \coloneqq {}{\coloneq }\DeclareDocumentComm
and \Coloneqq {}{\Coloneq }\DeclareDocumentCommand \eqqcolon {}{\eqcolon }}\@if
packageloaded {mathtools}{\__um_patch_mathtools_C: }{}\Umathcharnumdef \std@min
us \Umathcodenum `-\Umathcharnumdef \std@equal \Umathcodenum `=\debug_suspend: 
\__um_resolve_greek: \debug_resume: \@ifpackageloaded {amsmath}{}{\__um_redefin
e_radical: }\__um_setup_active_frac: \g__um_secret_hook_tl 
> Document-level (top-level) code (executed last):
>     ---
> Extra code for next invocation:
>     ---
> Rules:
>     ---
> Execution order:
>     sandbox, fontspec-luatex, amsmath, unicode-math-luatex.
<recently read> }

請注意,掛鉤 forsandbox將出現在 for 之前unicode-math,因此後者將「獲勝」以重新定義相同條目。

掛鉤系統的要點是允許控制排序。所以你只需要添加

\DeclareHookRule{begindocument}{sandbox}{after}{unicode-math-luatex}
\DeclareHookRule{begindocument}{sandbox}{after}{unicode-math-xetex}

到您的sandbox文件中以確保掛鉤程式碼已排序:

> Execution order (after applying rules):
>     fontspec-luatex, amsmath, unicode-math-luatex, sandbox.

相關內容