从 LuaTeX 访问 .log 消息。可以吗?

从 LuaTeX 访问 .log 消息。可以吗?

阅读问题如何在最终输出的 PDF 文件中可视化未满的框我认为可以使用 LuaTeX 拦截“Underfull vbox”消息并在该点绘制某种覆盖标记(使用 tikz 或其他)。可能不是很有用,但作为概念验证尝试一下很有趣。

在处理引入标记的适当点或捕获相关信息所需的模式表达之前,我首先尝试了一个更简单的目标,但没有成功。

我的目标是从 lualatex 编写一个文档,将文件的副本复制.log到另一个.lbk文件(或任何其他扩展名,无关紧要)。我尝试了以下方法:

  1. 我编写了一个 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 
    
  2. 在我写的文档中\AtBeginDocument{\directlua{copylog()}}(我想log从以前的汇编中读取)。

    这部分成功了。生成的文件包含部分日志,但不完整,它在\begin{document}处理之前几行就停止了。

    我意识到我读的不是log上一次编译的内容,而是当前编译的日志。运行后lualatex,会打开一个新的日志文件,写入大量前言内容,然后我的 lua 代码会读取所有这些东西(但不会读取后面的内容)。

  3. 因此我改变了函数执行的点并写道:\AtEndDocument{\directlua{copylog()}},尝试在完成时处理当前编译中的日志。

    这又失败了。这次我从文件中得到了几行log,但不是完整的log文件。不知何故我预料到了这一点,因为在我的 lua 代码读取日志时它仍然不完整(即使在文档结束后也会转储额外的信息和统计信息),但至少我预计它会包含我的文档生成的部分警告消息。运气不好,复制在\begin{document}运行之前又结束了。

    我意识到这是由于缓冲输出造成的。Luatex 已经将我想要的信息写入文件中,但这些信息仍然在某些文件缓冲区中,并未真正写入磁盘,因此我的 lua 函数无法访问。

  4. 由于\end{document}还太早,无法挂载我的函数,所以我尝试使用回调end_run,但得到了相同的结果。end_run文件log仍然打开,所以我无法获取其完整内容(再次因为缓冲输出)。

从这些实验中我得出了两个问题:

  1. 在 lualatex 再次打开(并清理)之前,是否可以读取上一次编译的 .log?我猜答案是否定的。显然,该.log文件是第一个打开的输出,甚至在文档加载之前。
  2. 是否可以强制从 lua 或 tex 获取flush()来自 lua 的日志文件,以便能够读取迄今为止生成的所有消息\end{document}

如果以上两个问题的答案是否定的,那么新的问题就出现了:

  1. 是否有一些回调函数可以用来获取写入的日志消息或终端输出?我尝试了显而易见的函数:process_output_buffershow_error_hook。第一个函数没有得到任何结果。第二个函数仅由错误消息激活,而不是警告。
  2. 还有其他想法吗?我只想捕获警告消息。应该没那么难...

有没有 luatex 内部专家可以帮助我?

答案1

根据迄今为止收到的评论以及我阅读 LuaTeX 手册后得出的结论,我现在确信无法从我尝试读取文件log的同一文档中运行的 lua 代码可靠地读取该文件。log

从 lua 打开该文件并读取file.read()是不可靠的,因为同一个文件已打开并由 TeX 写入,并且由于文件输出是缓冲的,即使我在运行结束时读取了该文件,我也无法获得其完整内容。

另一种方法是使用一些打回来在日志消息写入日志文件时获取它们,这是不可行的,因为 LuaTeX 没有提供任何回调来处理日志消息。最接近的是,show_error_hook但这个回调只在错误消息时调用,而不是在信息性消息或警告消息时调用。

简而言之,标题中提出的问题的答案是

幸运的是,我能够解决我原来的问题以一种不同的、在我看来更好的方式

相关内容