发货并写入文件

发货并写入文件

在编译 latex 文档期间,页面一次“发送”一页。我理解这是通过控制台消息 [1]、[2]、[3] 等标记的,每个页面都由控制台消息标记。但是,通过检查对 DVI 文件的写入,我确定 DVI 文件实际上并未在打印这 [n] 条消息时写入。相反,数据似乎被缓存,并且仅在稍后的某个时间点到达磁盘。对于小型文档,似乎所有页面都是在编译过程结束时一次性写入的。

为了调查此事,我拦截了 fwrite 调用。它并非在每次发货时都会被调用。

我的问题是:有没有办法强制 latex 在每次发货时(即在完成编译每页内容时)写入 DVI 文件。这是为了启用我想要实现的一些自定义 dvi 预览功能。

答案1

dvi_buf_size正如您所猜测的,DVI 文件的输出是缓冲的,并且每次只写出一半。

在原始的 Knuth TeX 中,请参阅第594条

DVI 字节输出到缓冲区,而不是直接写入输出文件。这样可以减少子程序调用的开销,从而显著加快计算速度,因为 DVI 字节的输出是 TeX 内部循环的一部分。

另请参阅第 597-598 条,其中详细介绍了实施情况:

  • 字节被写入缓冲区dvi_out
  • 当缓冲区未刷新的部分达到 大小的一半时dvi_bufwrite_dvi将调用该过程,执行实际的写入文件的操作。

在 PdfTeX 中保留了相同的实现(第624–625条)。在实践中,在web2c中,流程write_dvi已更改A称呼fwrite

如果您不关心速度(这对速度可能只有很小的影响:对于大多数 LaTeX 文档,大部分时间都花在扩展宏而不是写入输出文件上),您可以尝试更改 TeX 的实现并重新编译:要么将 改得很dvi_buf_size小(注释说它需要是 8 的倍数,所以 8 可能有效?),要么重新定义dvi_out(旨在将一个字节写入 DVI 缓冲区)以直接使用 将字节写入文件fwrite。很想知道它是否有效!

答案2

我猜测这可能与常量“dvi_buf_size”有关,它在某些发行版中设置为 16384(我不确定我的发行版)。所以我想知道 \shipout 是否只会在页面大小耗尽此缓冲区(或一半)时触发写入文件。事实上,在我的测试中,我看到 dvi 文件写入 8192,这确实是 16384 的一半。

因此,我的理论是 \shipout 不会写入 DVI 文件,它只是将数据发送到 DVI 缓冲区,该缓冲区每 8192 个字节写入文件一次。文档的实际页面结构无关紧要。如果 \shipout 不会导致缓冲区达到 8192 个字节,则不会触发写入文件,如果 \shipout 提供超过 8192 个字节,我推测这将导致写入文件,直到缓冲区小于 8192 个字节。无论如何,写入文件都不是逐页的。

相关内容