luatex:latelua 執行順序、對封閉節點清單的影響及其內部運作原理

luatex:latelua 執行順序、對封閉節點清單的影響及其內部運作原理

在我對 luatex 的思考中,也許就像愛麗絲夢遊仙境一樣,不太清楚的一件事是 Latelua 的內部運作原理。據我了解,要在頁面上輸出的所有材料都被構建並存儲為(可能是單獨的,可能是深層的)tex“節點”的嵌套鏈接列表。另外,據我所知latelua將其內容放入其封閉的鍊錶中作為稍後在執行時處理的節點(因此前綴“late”)。 Latelua 程式碼在包含它的節點清單將出現在頁面上時執行,這意味著它可以在許多頁面之後執行,並且可能執行包含節點清單在文件中出現的次數。此外,為了增加效果,節點列表可以被拆分或連接以形成新的節點列表,然後再將它們再次放置在其他頁面上。那麼這裡有一堆相關的問題:luatex引擎中如何維護latelua節點的資訊?是否有特殊的資料結構來處理它們(也許是為了效能?)。就像一些表格的著色方案一樣:比方說,當遇到一個 Latelua 節點時,會在其父節點中設定一個標誌,並在 luatex 執行移回父節點時將其帶到上游。這樣的方案必須尊重節點清單的拆分和連結。或者是沒有單獨的資料結構......在將內容發送到頁面之前,luatex 會遍歷該頁面上內容的整個嵌套節點列表,並檢查是否存在必須執行的 Latelua 節點(這次大約)?如果是這樣,即latelua節點沒有單獨的特殊資料結構,並且要遍歷整個要運出的節點列表,是否是因為luatex無論如何都需要完全遍歷要出現在頁面上的節點列表?如果是,那麼為什麼它在發貨之前會遍歷整個節點清單?有沒有辦法讓shipout進程抓取一些預先烘焙的pdf頁面內容(準備好shipout,並要求它不要遍歷)並獲得更好的性能?如果是的話,那麼如何才能做到這一點?一次問一個問題是一種普遍接受的規範,但在這裡我打破了規範,因為我提出的問題是緊密相連的,這對讀者來說可能更有利(因為沒有關於 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]

表明此時兩個非立即形式尚未執行,但兩個立即形式已執行。

然後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

相關內容