如何在 LuaTeX 中模拟 \message

如何在 LuaTeX 中模拟 \message

如何\message在 LuaTeX 中模拟 Lua 代码中的原语?我想要类似 的内容texio.write('foobarbaz'),但单词 中没有换行符foobarbaz

使用 lualatex 的示例:

\typeout{1}
\message{hellofoobarbaz} \message{foobarbaz}
\message{foobarbaz} \message{foobarbaz}
\message{foobarbaz} \message{foobarbaz}
\message{foobarbaz} \message{foobarbaz}
\message{foobarbaz} \message{foobarbaz}
\message{foobarbaz} \message{foobarbaz}
\typeout{2}
\message{hello}
\directlua{texio.write('foobarbaz ') texio.write('foobarbaz ')}
\directlua{texio.write('foobarbaz ') texio.write('foobarbaz ')}
\directlua{texio.write('foobarbaz ') texio.write('foobarbaz ')}
\directlua{texio.write('foobarbaz ') texio.write('foobarbaz ')}
\directlua{texio.write('foobarbaz ') texio.write('foobarbaz ')}
\directlua{texio.write('foobarbaz ') texio.write('foobarbaz ')}
\directlua{texio.write('foobarbaz ') texio.write('foobarbaz ')}
\directlua{texio.write('foobarbaz ') texio.write('foobarbaz ')}
\directlua{texio.write('foobarbaz ') texio.write('foobarbaz ')}
\csname @@end\endcsname    

我在控制台上得到这个输出:

1
hellofoobarbaz foobarbaz foobarbaz foobarbaz foobarbaz foobarbaz foobarbaz
foobarbaz foobarbaz foobarbaz foobarbaz foobarbaz
2
hellofoobarbaz foobarbaz foobarbaz foobarbaz foobarbaz foobarbaz foobarbaz fooba
rbaz foobarbaz foobarbaz foobarbaz foobarbaz foobarbaz foobarbaz foobarbaz fooba
rbaz foobarbaz foobarbaz )

fooba和之间的换行符rbaz。我希望在“fooba”之前换行。

答案1

没有办法\message从 Lua 访问原语。如果您想写入日志,可以使用texioDavid 的回答中建议的库,或者如果您只想写入终端,print实际上也可以。

不过,你也可以使用协程在 Lua 和 TeX 之间进行异步通信,如最近在

H. Hagen. 在 Lua 中执行 TeX:协同程序。拖船, 39(1):41–43, 2018。https://www.tug.org/TUGboat/tb39-1/tb121hagen-exec.pdf

以下是一些示例代码,它将休眠 1 秒,然后向终端打印“Hello”和一个计数器。这至少需要 1.08.0 版的 LuaTeX texio.closeinput()

\documentclass{article}
\usepackage{luacode}
\begin{luacode*}
local stepper = nil
local stack = {}
local fid = 0xFFFFFF
local goback = "\\luafunction" .. fid .. "\\relax"

function tex.resume()
    if coroutine.status(stepper) == "dead" then
        stepper = table.remove(stack)
    end
    if stepper then
        coroutine.resume(stepper)
    end
end

lua.get_functions_table()[fid] = tex.resume

function tex.yield()
    tex.sprint(goback)
    coroutine.yield()
    texio.closeinput()
end

function tex.routine(f)
    table.insert(stack, stepper)
    stepper = coroutine.create(f)
    tex.sprint(goback)
end
\end{luacode*}
\begin{document}

\begin{luacode*}
tex.routine(function()
        for i = 1, 10 do
            -- some long task
            os.sleep(1) -- sleep 1 second instead
            tex.sprint("\\message{Hello " .. i .. "!}")
            tex.yield()
        end
end)
\end{luacode*}

\end{document}

答案2

也许

\typeout{1}
\message{hellofoobarbaz} \message{foobarbaz}
\message{foobarbaz} \message{foobarbaz}
\message{foobarbaz} \message{foobarbaz}
\message{foobarbaz} \message{foobarbaz}
\message{foobarbaz} \message{foobarbaz}
\message{foobarbaz} \message{foobarbaz}
\typeout{2}
\message{hello}
\directlua{texio.write('foobarbaz ') texio.write('foobarbaz ')}
\directlua{texio.write('foobarbaz ') texio.write('foobarbaz ')}
\directlua{texio.write('foobarbaz ') texio.write('foobarbaz ')}
\directlua{texio.write('foobarbaz ') texio.write('foobarbaz ')}
\directlua{texio.write('foobarbaz ') texio.write('foobarbaz ')}
\directlua{texio.write('foobarbaz ') texio.write('foobarbaz ')}
\directlua{texio.write('foobarbaz ') texio.write('foobarbaz ')}
\directlua{texio.write('foobarbaz ') texio.write('foobarbaz ')}
\directlua{texio.write('foobarbaz ') texio.write('foobarbaz ')}


\typeout{3}
\directlua{
col=0
function zz(s)
local l=string.len(s)
if(col+l > 75) then
col=0
io.write('\string\n')
end
io.write(s)
col=col+l
end
}
\directlua{zz('hello')}
\directlua{zz('foobarbaz ') zz('foobarbaz ')}
\directlua{zz('foobarbaz ') zz('foobarbaz ')}
\directlua{zz('foobarbaz ') zz('foobarbaz ')}
\directlua{zz('foobarbaz ') zz('foobarbaz ')}
\directlua{zz('foobarbaz ') zz('foobarbaz ')}
\directlua{zz('foobarbaz ') zz('foobarbaz ')}
\directlua{zz('foobarbaz ') zz('foobarbaz ')}
\directlua{zz('foobarbaz ') zz('foobarbaz ')}
\directlua{zz('foobarbaz ') zz('foobarbaz ')}


\csname @@end\endcsname 

自己管理列和换行(这意味着你必须从强制换行符开始第一个列)它会产生

1
hellofoobarbaz foobarbaz foobarbaz foobarbaz foobarbaz foobarbaz foobarbaz
foobarbaz foobarbaz foobarbaz foobarbaz foobarbaz
2
hellofoobarbaz foobarbaz foobarbaz foobarbaz foobarbaz foobarbaz foobarbaz foob
arbaz foobarbaz foobarbaz foobarbaz foobarbaz foobarbaz foobarbaz foobarbaz foo
barbaz foobarbaz foobarbaz 
3
hellofoobarbaz foobarbaz foobarbaz foobarbaz foobarbaz foobarbaz foobarbaz 
foobarbaz foobarbaz foobarbaz foobarbaz foobarbaz foobarbaz foobarbaz 
foobarbaz foobarbaz foobarbaz foobarbaz

相关内容