luatex: latelua の実行順序、囲むノードリストへの影響、およびその内部動作

luatex: latelua の実行順序、囲むノードリストへの影響、およびその内部動作

luatex に関する私の考察では、不思議の国のアリスのように、latelua の内部動作がはっきりしない点が 1 つあります。私の理解では、ページに出力されるすべての素材は、tex の「ノード」のネストされたリンク リスト (おそらく別々、おそらく深い) として構築され、保存されます。また、私の知る限り、latelua は、その内容を、実行時に後で処理されるノードとして、その外側のリンク リストに配置します (したがって、接頭辞は「late」です)。latelua コードは、それを含むノード リストがページに表示されるときに実行されます。つまり、それは何ページも後になる可能性があり、おそらく、含まれているノード リストがドキュメントに表示される回数だけ実行されます。また、さらに素晴らしいことに、ノード リストは分割または結合して新しいノードを作成し、別のページに再度配置することができます。そこで、関連する質問をいくつか挙げます。latelua ノードに関する情報は、luatex エンジンでどのように維持されますか? それらを処理する特別なデータ構造はありますか (おそらくパフォーマンスのためでしょうか)。テーブルを使用したカラーリング スキームのようなもので、たとえば、latelua ノードに遭遇すると、その親ノードにフラグが設定され、luatex 実行が親ノードに戻るときに上流に運ばれるとします。このようなスキームでは、ノードリストの分割と結合を尊重する必要があります。または、別のデータ構造はなく、コンテンツをページに出荷する直前に、luatex はそのページに表示されるコンテンツのネストされたノードリスト全体を走査し、実行する必要がある latelua ノードがあるかどうかを確認します (今回は)。そうである場合、つまり、latelua ノード用の特別なデータ構造が別個に存在せず、出荷されるノードリスト全体が走査される場合、luatex はとにかくページに表示されるノードリストを完全に走査する必要があるためでしょうか。そうである場合、なぜ出荷直前にノードリスト全体を走査するのでしょうか。出荷プロセスに、事前に作成された PDF ページ コンテンツ (出荷の準備ができていて、走査しないように要求する) を取得してパフォーマンスを向上させる方法はありますか。そうである場合、どうすればそれを実行できますか。一度に 1 つの質問をするのが一般的に受け入れられている規範ですが、ここで私が尋ねる質問は密接に関連しているため、その規範を破っています。また、その方が読者にとって有益である可能性があります (luatex に関する英語の本がないため)。

答え1

\writeこのメカニズムは古典的なTeXとまったく同じです(\immediate\writeのようになります\directlua

考慮する

\documentclass{article}

\showoutput
\showboxdepth3
\begin{document}

a

\write20{write 1}

b

\latelua{print 'latelua 2'}

c

\immediate\write20{immediate write 3}

d

\directlua{print 'directlua 4'}

e

\end{document}

これにより、端末出力が生成されます

immediate write 3
directlua 4

Completed box being shipped out [1]

この時点では、2 つの非即時形式は実行されていないが、2 つの即時形式は実行されていることを示しています。

次にTeXはページ1の処理を開始し、ボックスノード構造をPDF出力に変換し、ターミナルにボックスノード構造が表示されます。

Completed box being shipped out [1]
\vbox(633.0+0.0)x407.0, direction TLT
.\glue 16.0
.\vbox(617.0+0.0)x345.0, shifted 62.0, direction TLT
..\vbox(12.0+0.0)x345.0, glue set 12.0fil, direction TLT
...\glue 0.0 plus 1.0fil
...\hbox(0.0+0.0)x345.0, direction TLT
..\glue 25.0
..\glue(\lineskip) 0.0
..\vbox(550.0+0.0)x345.0, glue set 491.94745fil, direction TLT
...\write-{}
...\glue(\topskip) 5.52
...\hbox(4.48+0.11)x345.0, glue set 325.0fil, direction TLT []
...\write-{write 1}
...\glue(\parskip) 0.0 plus 1.0
...\glue(\baselineskip) 4.95
...\hbox(6.94+0.11)x345.0, glue set 324.44fil, direction TLT []
...\latelua0{print 'latelua 2'}
...\glue(\parskip) 0.0 plus 1.0
...\glue(\baselineskip) 7.41
...\hbox(4.48+0.11)x345.0, glue set 325.56fil, direction TLT []
...\glue(\parskip) 0.0 plus 1.0
...\glue(\baselineskip) 4.95
...\hbox(6.94+0.11)x345.0, glue set 324.44fil, direction TLT []
...\glue(\parskip) 0.0 plus 1.0
...\glue(\baselineskip) 7.41
...\hbox(4.48+0.11)x345.0, glue set 325.56fil, direction TLT []
...\glue -0.11
...\glue 0.0 plus 1.0fil
...\glue 0.0
...\glue 0.0 plus 0.0001fil
..\glue(\baselineskip) 23.34
..\hbox(6.66+0.0)x345.0, glue set 170.0fil, direction TLT
...\glue 0.0 plus 1.0fil
...\TU/lmr/m/n/10 1
...\glue 0.0 plus 1.0fil

ここで、write ノードと latelua ノードはボックス内の whatsit ノードのままであり、指定された引数からの評価されていないテキストのみが含まれていることがわかります。

...\write-{write 1}

そして

...\latelua0{print 'latelua 2'}

次にLaTeXは端末に表示されているフォントマップを読み取ります。

{/usr/local/texlive/2020/texmf-var/fonts/map/pdftex/updmap/pdftex.map}

そして最後にPDFを書き込むと、writeノードとlateluaノードに到達し、その内容が実行され、ターミナルに次のように表示されます。

write 1
latelua 2

関連情報