LuaLaTeX:使用节点库查找多列环境(一系列 vbox)的真实高度

LuaLaTeX:使用节点库查找多列环境(一系列 vbox)的真实高度

如何使用 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所有三个vlists 的,这确实对应于最大 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 时包括,但在查看原始框时不包括。

相关内容