LuaLaTeX: найдите истинную высоту многоколоночной среды (серии vboxes) с помощью библиотеки узлов

LuaLaTeX: найдите истинную высоту многоколоночной среды (серии vboxes) с помощью библиотеки узлов

Как найти истинную высоту (и другие размеры) содержимого среды multicols на мини-странице с помощью библиотеки узлов LuaTeX? До сих пор в моих экспериментах с библиотекой узлов luatex я мог использовать post_linebreak_filter для игры с узлами hlist, но не знаю, как получить доступ к узлам vlist и запросить их. Из руководства luatex я вижу, что можно запросить размеры узла с помощьюnode.dimensions(<node> n) . Хотя я не знаю, как пройтись по содержимому мини-страницы, чтобы добраться до вывода vboxes средой multicols. Пройдя их, я потенциально мог бы найти максимальную высоту среди vboxes, чтобы определить истинную высоту.

Было бы дополнительно полезно, если бы кто-нибудь мог подсказать, как использовать инструмент визуализации nodelist https://gist.github.com/pgundlach/556247может использоваться для визуализации содержимого мини-страницы. (Примечание: извините за внешнюю ссылку, это, похоже, стандартный инструмент визуализации, но он не доступен на ctan в виде пакета)

Вот мой тестовый код, ниже представлен снимок экрана с результатами, и я с нетерпением жду возможности узнать истинные размеры текста из 3 колонок, которые отличаются от указанного значения размера мини-страницы (4 дюйма), окружающей среду multicols.

% 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для доступа к последнему узлу TeX, вставленному перед какой-либо командой Lua. Это можно использовать в качестве отправной точки для сканирования назад, пока не найдете нужный узел. Например: (Здесь мы измеряем содержащий 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}

Отсюда вы также можете использовать элемент `.head списка hlist для доступа к скрытым в нем 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 вставляет некоторый интервал, который включается при использовании точек и getvpos, но не включается при просмотре необработанных полей.

Связанный контент