LuaLaTeX: Encontre a verdadeira altura do ambiente multicols (série de vboxes) usando a biblioteca de nós

LuaLaTeX: Encontre a verdadeira altura do ambiente multicols (série de vboxes) usando a biblioteca de nós

Como encontrar a verdadeira altura (e outras dimensões) do conteúdo do ambiente multicols na minipágina usando a biblioteca de nós LuaTeX? Até agora, em meus experimentos com a biblioteca de nós luatex, consegui usar post_linebreak_filter para brincar com nós hlist, mas não sei como acessar os nós vlist e consultá-los. No manual do luatex, vejo que é possível consultar as dimensões de um nó usando node.dimensions(<node> n). Embora eu não saiba como percorrer o conteúdo da minipágina para chegar à saída dos vboxes pelo ambiente multicols. Ao percorrê-los, eu poderia encontrar a altura máxima entre os vboxes para determinar a altura verdadeira.

Seria de ajuda adicional se alguém pudesse sugerir se/como a ferramenta de visualização de lista de nós https://gist.github.com/pgundlach/556247pode ser usado para visualizar o conteúdo da minipágina. (Observação: desculpe pelo link externo, parece ser uma espécie de ferramenta de visualização padrão, mas não está disponível no ctan como um pacote)

Aqui está meu código de teste, abaixo está a captura de tela da saída, e estou ansioso para encontrar as verdadeiras dimensões do texto de 3 colunas que é diferente do tamanho do valor especificado da minipágina (4 pol.) em torno do ambiente 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}

captura de tela da saída que mostra o texto de várias colunas sob investigação

Responder1

Antes de discutir a nodebiblioteca, a maneira muito mais fácil de fazer tais medições é apenas comparar a posição na página antes e depois:

% 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}

Se você quiser usar a biblioteca de nós, sugiro usar tex.nest.top.tailpara acessar o último nó TeX inserido antes de algum comando Lua. Isso pode ser usado como ponto de partida para fazer uma varredura até encontrar o nó que você está procurando. Por exemplo: (Aqui estamos medindo hlisttodos os três vlists, isso corresponde à altura da vlist máxima.)

% 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}

A partir daqui, você também pode usar o membro `.head do hlist para acessar as vlists ocultas nele:

% 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}

Você pode notar que especialmente a primeira versão oferece um valor mais alto. A razão para isso é que multicols insere algum espaçamento que é incluído ao usar pontos e getvpos, mas não incluído ao olhar para caixas brutas.

informação relacionada