発送してファイルに書き込む

発送してファイルに書き込む

LaTeX ドキュメントのコンパイル中、ページは 1 ページずつ「出力」されます。これは、各ページを作成するコンソール メッセージ [1]、[2]、[3] などでマークされていると理解しています。ただし、DVI ファイルへの書き込みを検査すると、これらの [n] メッセージが印刷された時点では DVI ファイルが実際に書き込まれていないことがわかりました。むしろ、データはキャッシュされ、後でディスクに書き込まれるようです。小さなドキュメントの場合、すべてのページがコンパイル プロセスの最後に 1 回で書き込まれるようです。

これを調査するために、fwrite 呼び出しを傍受しました。これはすべての shipout で呼び出されるわけではありません。

私の質問は、LaTeX が各ページのコンテンツのコンパイルを完了するたびに、DVI ファイルに書き込むように強制する方法があるかどうかです。これは、実装したいカスタム DVI プレビュー機能を有効にするためです。

答え1

ご想像のとおり、DVI ファイルへの出力はバッファリングされ、dvi_buf_size一度に半分ずつ書き出されます。

オリジナルのKnuth TeXでは、§594:

DVI バイトは、出力ファイルに直接書き込まれるのではなく、バッファに出力されます。これにより、サブルーチン呼び出しのオーバーヘッドを削減でき、DVI バイトの出力が TeX の内部ループの一部となるため、計算速度が大幅に向上します。

実装の詳細については、§597~598も参照してください。

  • バイトはバッファに書き込まれ、dvi_out
  • バッファのフラッシュされていない部分が のサイズの半分に達するとdvi_buf、 プロシージャwrite_dviが呼び出され、ファイルへの実際の書き込みが行われます。

PdfTeXでも同じ実装が維持されます(§624–625)。実際には、Web2Cでは、手順は次のwrite_dviようになります。かわったなれ1つの電話fwrite

速度を気にしないのであれば (いずれにせよ、速度への影響はごくわずかです。ほとんどの LaTeX ドキュメントでは、ほとんどの時間が出力ファイルへの書き込みではなくマクロの展開に費やされます)、TeX の実装を変更して再コンパイルしてみてください。 をdvi_buf_size非常に小さく変更するか (コメントには 8 の倍数にする必要があると書かれているので、8 でうまくいくかもしれません)、 を再定義してdvi_out(これは 1 バイトを DVI バッファに書き込むことを目的としています)、 でバイトをファイルに直接書き出しますfwrite。うまくいくかどうか知りたいですね。

答え2

これは定数「dvi_buf_size」と関係があるのではないかと思います。この定数は、一部のディストリビューションでは 16384 に設定されています (私のディストリビューションではよくわかりません)。そのため、ページ サイズがこのバッファ (またはその半分) を使い果たした場合にのみ、\shipout がファイルへの書き込みをトリガーするのではないかと思います。実際、私のテストでは、dvi ファイルへの書き込みは 8192 で、これは確かに 16384 の半分です。

したがって、私の理論では、\shipout は DVI ファイルに書き込まず、データを DVI バッファに送信するだけで、8192 バイトごとにファイルに書き込まれます。ドキュメントの実際のページ構造は関係ありません。\shipout によってバッファが 8192 バイトに達しない場合は、ファイルへの書き込みはトリガーされません。また、\shipout によって 8192 バイトを超えるデータが配信された場合は、バッファが 8192 バイト未満になるまでファイルへの書き込みが発生すると推測されます。いずれにしても、ファイルへの書き込みはページごとに行われるわけではありません。

関連情報