Отправка и запись в файл

Отправка и запись в файл

Во время компиляции документа Latex страницы «отправляются» по одной. Я понимаю, что это отмечено консольным сообщением [1], [2], [3] и т. д., создающим каждую страницу. Однако, проверив записи в файл DVI, я установил, что файл DVI на самом деле не записывается во время печати этих [n] сообщений. Скорее, данные кэшируются и попадают на диск только в какой-то более поздний момент. Для небольших документов кажется, что все страницы записываются за один раз в конце процесса компиляции.

Чтобы разобраться в этом, я перехватил вызов fwrite. Он не вызывается при каждом отправлении.

Мой вопрос: есть ли способ заставить 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следующая .измененныйкбытьавызовк 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 байт. В любом случае, запись в файл не является постраничной.

Связанный контент