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 \relax
comando 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.sty
arquivo:
\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}
emsandbox.sty
; - Comentando a linha
\RequirePackage{unicode-math}
emsandbox.sty
; \usepackage{sandbox}
Substituir a linhamain.tex
pelo conteúdo principal desandbox.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 sandbox
ocorrerá 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 sandbox
arquivo para garantir que o código do gancho esteja ordenado:
> Execution order (after applying rules):
> fontspec-luatex, amsmath, unicode-math-luatex, sandbox.