\AtBeginDocument e pacotes

\AtBeginDocument e pacotes

Aqui está um comportamento muito intrigante do compilador (Lua)LaTeX. Na situação abaixo, a saída depende se algum código está colocado em um pacote ou diretamente no arquivo principal; pedir um \relaxcomando extra no início do documento altera o comportamento; e não consigo identificar a origem de algum bug misterioso... Gostaria de entender o que acontece nos bastidores do compilador para produzir tal comportamento, a fim de evitar comportamentos indesejados semelhantes na sequência!

A situação é a seguinte. Deixe o seguinte documento main.tex:

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

junto com o seguinte sandbox.styarquivo:

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

Após a compilação, ele imprime algum símbolo alfa, enquanto deveria ter impresso algum símbolo beta...! Este é o primeiro comportamento surpreendente.

Ainda mais misterioso, se eu fizer issoqualquerdos três seguintes:

  • Comentando a linha \AtBeginDocument{\relax}em sandbox.sty;
  • Comentando a linha \RequirePackage{unicode-math}em sandbox.sty;
  • \usepackage{sandbox}Substituir a linha main.texpelo conteúdo principal de sandbox.sty(ou seja, as três linhas sendo o conteúdo real do pacote),

então ele imprime algum beta, como inicialmente esperado... Isso parece completamente incoerente! Alguém tem alguma pista para uma explicação?...

Responder1

Conforme observado nos comentários, isso tem a ver com o comportamento de adição de ganchos. O material é adicionado aos ganchos e a ordem padrão é que os arquivos 'anteriores' tenham seu conteúdo de gancho executado mais cedo,excetoas entradas de nível superior (o documento do usuário) são as últimas. Podemos ver isso se adicionarmos \ShowHook{begindocument}à entrada, o que dá:

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

Observe que o gancho for sandboxocorrerá antes do for unicode-math, então o último 'ganhará' por redefinir a mesma entrada.

O objetivo do sistema de gancho é permitir o controle do pedido. Então você só precisa adicionar

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

ao seu sandboxarquivo para garantir que o código do gancho esteja ordenado:

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

informação relacionada