\AtBeginDocument y paquetes

\AtBeginDocument y paquetes

He aquí un comportamiento muy desconcertante del compilador (Lua)LaTeX. En la situación siguiente, el resultado depende de si algún código se coloca en un paquete o directamente en el archivo principal; pedir un \relaxcomando adicional al principio del documento cambia el comportamiento; y no logro identificar la fuente de algún error misterioso... ¡Me gustaría entender qué sucede bajo el capó del compilador para producir tal comportamiento, para evitar comportamientos no deseados similares en la secuela!

La situación es la siguiente. Deja el siguiente documento main.tex:

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

junto con el siguiente sandbox.styarchivo:

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

¡Después de compilar, imprime algún símbolo alfa, mientras que debería haber impreso algo de beta...! Este es el primer comportamiento sorprendente.

Aún más misterioso, si lo hagocualquierade los tres siguientes:

  • Comentando la línea \AtBeginDocument{\relax}en sandbox.sty;
  • Comentando la línea \RequirePackage{unicode-math}en sandbox.sty;
  • Reemplazar la línea \usepackage{sandbox}por main.texel contenido principal de sandbox.sty(es decir, las tres líneas son el contenido real del paquete),

luego imprime algo de beta, como se esperaba inicialmente... ¡Eso parece completamente incoherente! ¿Alguien tiene alguna pista para una explicación?...

Respuesta1

Como se señaló en los comentarios, esto tiene que ver con el comportamiento de agregar ganchos. El material se agrega a los ganchos y el orden predeterminado es que los archivos "anteriores" ejecuten el contenido del gancho antes.exceptolas entradas de nivel superior (el documento de usuario) son las últimas. Podemos ver que si sumamos \ShowHook{begindocument}a la entrada, lo que da:

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

Tenga en cuenta que el gancho for sandboxocurrirá antes que el for unicode-math, por lo que este último "ganará" al redefinir la misma entrada.

El objetivo del sistema de gancho es permitir el control de los pedidos. Entonces solo necesitas agregar

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

a su sandboxarchivo para asegurarse de que el código de enlace esté ordenado:

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

información relacionada