LuaLaTeX: Finden Sie die wahre Höhe der Multicols-Umgebung (Reihe von Vboxes) mithilfe der Knotenbibliothek

LuaLaTeX: Finden Sie die wahre Höhe der Multicols-Umgebung (Reihe von Vboxes) mithilfe der Knotenbibliothek

Wie finde ich die wahre Höhe (und andere Abmessungen) des Inhalts einer Multicols-Umgebung in einer Miniseite mithilfe der LuaTeX-Knotenbibliothek? Bisher konnte ich bei meinen Experimenten mit der Luatex-Knotenbibliothek post_linebreak_filter verwenden, um mit Hlist-Knoten zu spielen, weiß aber nicht, wie ich auf Vlist-Knoten zugreife und sie abfrage. Aus dem Luatex-Handbuch erkenne ich, dass man die Abmessungen eines Knotens mithilfe von abfragen kann node.dimensions(<node> n). Allerdings weiß ich nicht, wie ich den Inhalt der Miniseite durchsuche, um zu den von der Multicols-Umgebung ausgegebenen Vboxen zu gelangen. Indem ich sie durchsuche, könnte ich möglicherweise die maximale Höhe unter den Vboxen finden, um die wahre Höhe zu bestimmen.

Es wäre eine zusätzliche Hilfe, wenn jemand vorschlagen könnte, ob/wie das Tool zur Knotenlistenvisualisierung https://gist.github.com/pgundlach/556247kann verwendet werden, um den Inhalt der Miniseite zu visualisieren. (Hinweis: Bitte entschuldigen Sie den externen Link, dies scheint eine Art Standard-Visualisierungstool zu sein, ist aber auf ctan nicht als Paket verfügbar.)

Hier ist mein Testcode, darunter der Screenshot der Ausgabe, und ich freue mich darauf, die tatsächlichen Abmessungen des dreispaltigen Textes herauszufinden, der sich von der angegebenen Wertgröße der Miniseite (4 Zoll) unterscheidet, die die mehrspaltige Umgebung umgibt.

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

Screenshot der Ausgabe, die den untersuchten mehrspaltigen Text zeigt

Antwort1

Bevor wir uns mit der nodeBibliothek befassen, möchten wir darauf hinweisen, dass solche Messungen viel einfacher durchgeführt werden können, indem man einfach die Position auf der Seite vorher und nachher vergleicht:

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

Wenn Sie die Knotenbibliothek verwenden möchten, würde ich vorschlagen, tex.nest.top.tailauf den letzten TeX-Knoten zuzugreifen, der vor einem Lua-Befehl eingefügt wurde. Dies kann als Startpunkt verwendet werden, um zurückzuscannen, bis Sie den gesuchten Knoten finden. Beispiel: (Hier messen wir die, die hlistalle drei s enthält vlist, dies entspricht der Höhe der maximalen 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}

Von hier aus können Sie auch das `.head-Member der hlist verwenden, um auf die darin versteckten vlists zuzugreifen:

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

Möglicherweise fällt Ihnen auf, dass insbesondere die erste Version einen höheren Wert liefert. Der Grund dafür ist, dass Multicols Leerzeichen einfügt, die bei der Verwendung von Punkten und getvpos berücksichtigt werden, bei der Betrachtung von Rohboxen jedoch nicht.

verwandte Informationen