\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

컴파일 후에는 알파 기호를 인쇄하지만 베타 기호도 인쇄해야 합니다...! 이것은 첫 번째 놀라운 행동입니다.

하면 더욱 신비로워요어느 하나다음 세 가지 중:

  • 의 줄에 주석 \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> }

for 후크가 sandboxfor 후크보다 먼저 발생하므로 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.

관련 정보