在 Lua 中分配 Box 寄存器

在 Lua 中分配 Box 寄存器

出于各种原因,我想在 Lua 中实现以下内容。宏语言中的递归不是一个好主意 -定义以下超出了输入堆栈大小。我想避免使用 TeX 进行二分字体大小搜索。等等。

您可以忽略此内容。MWE 位于更下方。

% Exceeds input stack size.
\newbox\fittedtextbox
% {1 width} {2 height} {3 starting font size} {4 font step} {5 minimum font size}
\def\startfittedtext#1#2#3#4#5{%
    \def\boxsize#1#2#3#4#5{%
        \setbox\fittedtextbox\vbox{%
            \definebodyfontenvironment[#3]
            \switchtobodyfont[#3]
            \hsize=#1
            \emergencystretch=1ex
            \tolerance=4000
            \hyphenpenalty=8000
            \getbuffer[fittedtext]}}
    \def\stopfittedtext{%
        \stopfittedtextargs{#1}{#2}{#3}{#4}{#5}}
        \ruledvbox to #2{\unvbox\fittedtextbox}}
    \def\stopfittedtextargs#1#2#3#4#5{%
        \boxsize{#1}{#2}{#3}{#4}{#5}
        \ifdim\ht\fittedtextbox>#2
            \stopfittedtextargs{#1}{#2}{\dimexpr#3-#4\relax}{#4}{#5}
        \fi}
    \dostartbuffer[fittedtext][startfittedtext][stopfittedtext]}

\startfittedtext{7cm}{7cm}{12pt}{1pt}{1pt}
\input knuth
\stopfittedtext

核心操作是分配给一个框寄存器。这是我需要在 Lua 中复制的。

\setbox0=\vbox{...}

据我所知,ConTeXt 没有提供适当的 Lua API。函数context.*是输出函数。vbox将输出并tex.box[0]接收的返回值context.vbox,可能nil(尚未检查)。

\startluacode
tex.box[0] = context.vbox(function() context.input("knuth") end)
\stopluacode

这更微妙。TeX 流仅在 Lua 代码块退出时执行。因此tex.box[0]引用来自Lua 代码块。

\def\coreop#1{\setbox0=\vbox{#1}}
\startluacode
context.coreop(function() context.input("knuth") end)
context("%spt", tex.box[0].height/65536)
\stopluacode

同样有此问题:

\startluacode
context("\\setbox0=\\vbox{\\input knuth }")
context("%spt", tex.box[0].height/65536)
\stopluacode

我确实找到了这封电子邮件[1],但哇,这不是我想要的。它确实提到了即将推出更高级别的 API。希望它类似于context.vbox但返回一个节点(这就是寄存器吗?)而不是输出一个框。如果它已经实现,我将不胜感激。如果没有,一定有一些解决方法。一种刷新 TeX 流的方法,或其他任何东西。

[1]lua 相当于 vbox...ht

答案1

有一个tex.runtoks运行本地 TeX 循环的函数:

\starttext
\def\coreop#1{\setbox0=\vbox{#1}}
\startluacode
tex.runtoks(function()
  context.coreop(function() context.input("knuth") end)
end)
context("%spt", tex.box[0].height/65536)
\stopluacode
\stoptext

相关内容