如何使用 LuaTeX 节点库找到 mini-page 中 multicols 环境内容的真实高度(和其他尺寸)?到目前为止,在我使用 luatex 节点库的实验中,我已经能够使用 post_linebreak_filter 来处理 hlist 节点,但不知道如何访问 vlist 节点并查询它们。从 luatex 手册中,我看到可以使用来查询节点的尺寸node.dimensions(<node> n)
。虽然我不知道如何遍历 minipage 的内容以获取 multicols 环境输出的 vbox。通过遍历它们,我有可能找到 vbox 中的最大高度来确定真实高度。
如果有人可以建议是否/如何使用节点列表可视化工具,那将会更加有帮助 https://gist.github.com/pgundlach/556247可用于可视化 minipage 的内容。(注意:请原谅外部链接,这似乎是一种标准的可视化工具,但在 ctan 包中不可用)
这是我的测试代码,下面是输出的屏幕截图,我希望找到 3 列文本的真实尺寸,它与多列环境周围的 minipage(4in)指定的值大小不同。
% lualatex vboxdimensions.tex
\documentclass[notitlepage,letterpaper]{article}
\usepackage{lua-visual-debug}
\usepackage[english]{babel}
\usepackage{blindtext}
\usepackage{multicol}
\begin{document}
\blindtext[1]\vspace{\baselineskip}
\noindent\begin{minipage}[t][4in][t]{\textwidth}%
% STARTPOINT for dimension measurement
\begin{multicols}{3}%
\blindtext[2]
\end{multicols}%
% ENDPOINT for dimension measurement
\end{minipage}
\blindtext[1]
\end{document}
答案1
在讨论该node
库之前,进行此类测量的更简单的方法是比较前后页面上的位置:
% lualatex vboxdimensions.tex
\documentclass[notitlepage,letterpaper]{article}
\usepackage{lua-visual-debug}
\usepackage[english]{babel}
\usepackage{blindtext}
\usepackage{multicol}
\begin{document}
\showoutput
\blindtext[1]\vspace{\baselineskip}
\noindent\begin{minipage}[t][4in][t]{\textwidth}%
% STARTPOINT for dimension measurement
\latelua{
assert(measurement_y == nil, "global variable already in use")
measurement_y = pdf.getvpos()
}%
\begin{multicols}{3}%
\blindtext[2]
\end{multicols}%
\latelua{
texio.write_nl(string.format("\csstring\%fin measured\string\n", (measurement_y - pdf.getvpos()) / tex.sp'1in'))
measurement_y = nil
}%
% ENDPOINT for dimension measurement
\end{minipage}
\blindtext[1]
\end{document}
如果您想使用节点库,我建议使用 来tex.nest.top.tail
访问在某些 Lua 命令之前插入的最后一个 TeX 节点。这可以用作扫描的起点,直到找到您要查找的节点。例如:(这里我们测量包含hlist
所有三个vlist
s 的,这确实对应于最大 vlist 的高度。)
% lualatex vboxdimensions.tex
\documentclass[notitlepage,letterpaper]{article}
\usepackage{lua-visual-debug}
\usepackage[english]{babel}
\usepackage{blindtext}
\usepackage{multicol}
\begin{document}
\showoutput
\blindtext[1]\vspace{\baselineskip}
\noindent\begin{minipage}[t][4in][t]{\textwidth}%
% STARTPOINT for dimension measurement
\begin{multicols}{3}%
\blindtext[2]
\end{multicols}%
\directlua{
local hlist_id = node.id'hlist' % The id we are looking for
local last_tail = tex.nest.top.tail % Start at the end of the list TeX is working on
while last_tail.id \string~= hlist_id do last_tail = last_tail.prev end % Move to the previous node until a hlist is found
texio.write_nl(string.format("\csstring\%fin measured\string\n", (last_tail.height+last_tail.depth) / tex.sp'1in'))}%
% ENDPOINT for dimension measurement
\end{minipage}
\blindtext[1]
\end{document}
从这里,您还可以使用 hlist 的 .head 成员来访问隐藏在其中的 vlist:
% lualatex vboxdimensions.tex
\documentclass[notitlepage,letterpaper]{article}
\usepackage{lua-visual-debug}
\usepackage[english]{babel}
\usepackage{blindtext}
\usepackage{multicol}
\begin{document}
\showoutput
\blindtext[1]\vspace{\baselineskip}
\noindent\begin{minipage}[t][4in][t]{\textwidth}%
% STARTPOINT for dimension measurement
\begin{multicols}{3}%
\blindtext[2]
\end{multicols}%
\directlua{
local hlist_id = node.id'hlist' % The id we are looking for
local last_tail = tex.nest.top.tail % Start at the end of the list TeX is working on
while last_tail.id \string~= hlist_id do last_tail = last_tail.prev end % Move to the previous node until a hlist is found
% Now last_tail is the hlist containing the vlists.
for n in node.traverse_id(node.id'vlist', last_tail.head) do
% Now n is one of the inner vlists.
texio.write_nl(string.format("Found column of height \csstring\%fin.",(n.height+n.depth)/tex.sp'1in'))
end}%
% ENDPOINT for dimension measurement
\end{minipage}
\blindtext[1]
\end{document}
您可能会注意到,特别是第一个版本给出了更高的值。原因是 multicols 插入了一些间距,这些间距在使用 points 和 getvpos 时包括,但在查看原始框时不包括。