阅读问题如何在最终输出的 PDF 文件中可视化未满的框我认为可以使用 LuaTeX 拦截“Underfull vbox”消息并在该点绘制某种覆盖标记(使用 tikz 或其他)。可能不是很有用,但作为概念验证尝试一下很有趣。
在处理引入标记的适当点或捕获相关信息所需的模式表达之前,我首先尝试了一个更简单的目标,但没有成功。
我的目标是从 lualatex 编写一个文档,将文件的副本复制.log
到另一个.lbk
文件(或任何其他扩展名,无关紧要)。我尝试了以下方法:
我编写了一个 lua 函数
copylog()
,它只是打开.log
,读取其所有内容,然后将其写回到其他文件中:function copylog() local f = io.open(tex.jobname .. ".log", "r") local fo = io.open(tex.jobname .. ".lbk", "w") s = f:read("*all") f:close() fo:write(s) fo:close() end
在我写的文档中
\AtBeginDocument{\directlua{copylog()}}
(我想log
从以前的汇编中读取)。这部分成功了。生成的文件包含部分日志,但不完整,它在
\begin{document}
处理之前几行就停止了。我意识到我读的不是
log
上一次编译的内容,而是当前编译的日志。运行后lualatex
,会打开一个新的日志文件,写入大量前言内容,然后我的 lua 代码会读取所有这些东西(但不会读取后面的内容)。因此我改变了函数执行的点并写道:
\AtEndDocument{\directlua{copylog()}}
,尝试在完成时处理当前编译中的日志。这又失败了。这次我从文件中得到了几行
log
,但不是完整的log
文件。不知何故我预料到了这一点,因为在我的 lua 代码读取日志时它仍然不完整(即使在文档结束后也会转储额外的信息和统计信息),但至少我预计它会包含我的文档生成的部分警告消息。运气不好,复制在\begin{document}
运行之前又结束了。我意识到这是由于缓冲输出造成的。Luatex 已经将我想要的信息写入文件中,但这些信息仍然在某些文件缓冲区中,并未真正写入磁盘,因此我的 lua 函数无法访问。
由于
\end{document}
还太早,无法挂载我的函数,所以我尝试使用回调end_run
,但得到了相同的结果。end_run
文件log
仍然打开,所以我无法获取其完整内容(再次因为缓冲输出)。
从这些实验中我得出了两个问题:
- 在 lualatex 再次打开(并清理)之前,是否可以读取上一次编译的 .log?我猜答案是否定的。显然,该
.log
文件是第一个打开的输出,甚至在文档加载之前。- 是否可以强制从 lua 或 tex 获取
flush()
来自 lua 的日志文件,以便能够读取迄今为止生成的所有消息\end{document}
?
如果以上两个问题的答案是否定的,那么新的问题就出现了:
- 是否有一些回调函数可以用来获取写入的日志消息或终端输出?我尝试了显而易见的函数:
process_output_buffer
和show_error_hook
。第一个函数没有得到任何结果。第二个函数仅由错误消息激活,而不是警告。- 还有其他想法吗?我只想捕获警告消息。应该没那么难...
有没有 luatex 内部专家可以帮助我?
答案1
根据迄今为止收到的评论以及我阅读 LuaTeX 手册后得出的结论,我现在确信无法从我尝试读取文件log
的同一文档中运行的 lua 代码可靠地读取该文件。log
从 lua 打开该文件并读取file.read()
是不可靠的,因为同一个文件已打开并由 TeX 写入,并且由于文件输出是缓冲的,即使我在运行结束时读取了该文件,我也无法获得其完整内容。
另一种方法是使用一些打回来在日志消息写入日志文件时获取它们,这是不可行的,因为 LuaTeX 没有提供任何回调来处理日志消息。最接近的是,show_error_hook
但这个回调只在错误消息时调用,而不是在信息性消息或警告消息时调用。
简而言之,标题中提出的问题的答案是不。
幸运的是,我能够解决我原来的问题以一种不同的、在我看来更好的方式。