
Читая о пакетах, которые позволяюткрюкмакросы для определенных событий, я наткнулся на эту команду, \shipout
. Поиск в интернете не сильно помог, но если я не ошибаюсь, это как-то связано с созданием новых страниц (или нет?).
Мой вопрос в том, что именно это такое \shipout
, что оно делает и как оно делает то, что оно делает? (т.е. что происходит на низком уровне в фоновом режиме)
решение1
Это довольно просто: \shipout
это примитив. Его синтаксис
\shipout ⟨box⟩
где ⟨box⟩ полностью указан на странице 278 TeXbook:
⟨box⟩ →
\box
⟨8-битное число⟩ |\copy
⟨8-битное число⟩
|\lastbox
|\vsplit
⟨8-битное число⟩to
⟨dimen⟩
|\hbox
⟨box specification⟩{
⟨horizontal mode material⟩}
|\vbox
⟨box specification⟩{
⟨vertical mode material⟩}
|\vtop
⟨box specification⟩{
⟨vertical mode material⟩}
⟨box specification⟩ →to
⟨dimen⟩⟨filler⟩ |spread
⟨dimen⟩⟨filler⟩ | ⟨filler⟩
Можно, например, сказать
\shipout\hbox{Hello world}
и будет создана одна страница в файле DVI или PDF. Конечно, никто не хочет использовать \shipout
этот способ. Его основное применение — в выходной процедуре, которая вызывается, когда TeX решает, что у него достаточно материала для извлечения полной страницы. Текущий основной вертикальный список разделяется на выбранном разрыве страницы, и его содержимое упаковывается в \box255
, с которым может работать выходная процедура. Например, выходная процедура Plain TeX делает
\shipout\vbox{
\makeheadline
\pagebody
\makefootline
}
\advancepageno
\ifnum\outputpenalty>-\@MM
\else
\dosupereject
\fi
поэтому отправляется полная страница, украшенная верхними и нижними колонтитулами. Содержимое \box255
обрабатывается \pagebody
. Процедура вывода в LaTeX намного сложнее.
Что можно сделать, так \shipout
это переопределить так, чтобы он выполнял другие задачи. Самый старый набор макросов, который делал что-то подобное, был quire.tex
(все еще доступен на CTAN и TeX Live)
\def\q_init
{\global\q_sheetnr=0\global\q_qnr=0
\global\let\q_oldship=\shipout
\global\let\shipout=\q_boat
\xdef\q_cycles{\the\deadcycles}%
\global\let\endquire=\q_endquire
}
Он сохраняет примитивное значение \shipout
в команде \q_oldship
(макросы используют его _
как маркер «private») и переопределяет его как \q_boat
, который выполнит некоторые задания и в конечном итоге вызовет \q_oldship
. Например, его можно настроить для размещения двух выходных страниц на одной физической странице или для создания шестнадцатистраничных запросов (отсюда и название пакета).
Пакет atbegshi
делает то же самое. Он переопределяется \shipout
так, чтобы иметь возможность подключаться между вызовом \shipout
и фактической отправкой страницы.
Что именно делает примитив, \shipout
так это преобразует вертикальный список, который ему подается, в низкоуровневые инструкции печати (формат DVI или PDF, в зависимости от значения , \pdfoutput
если используется pdftex
или , XDV, если используется , только DVI для Knuth TeX). Между тем, он выполняет все отложенные операции, расширяя токены по мере их выполнения: таким образом ссылки на номер страницы гарантированно будут правильными, поскольку они вычисляются при отправке страницы.luatex
xetex
\write
решение2
ОтTeXbook, Глава 23: Процедуры вывода, страница 254:
Примитивная команда TeX
\shipout
<box> на самом деле вызывает вывод. Она отправляет содержимое коробки вdvi
файл, который является основным выходным файлом TeX; после завершения работы TeX файлdvi
будет содержать компактную аппаратно-независимую кодировку инструкций, которые точно определяют, что должно быть напечатано. Когда коробка отправляется, TeX отображает значения\count0
through\count9
на вашем терминале, как описано в Главе 15; эти десять счетчиков также записываются вdvi
файл, где их можно использовать для идентификации страницы. Все команды\openout
,\closeout
, и\write
, которые появляются внутри коробки, выполняются в их естественном порядке по мере отправки этой коробки. Поскольку\write
команда расширяет макросы, как описано в Главе 21, механизм сканирования TeX может обнаруживать синтаксические ошибки во время\shipout
выполнения a. Если\tracingoutput
не равно нулю во время a\shipout
, содержимое отправляемой коробки записывается в ваш файл журнала в символической форме. Вы можете указать это\shipout
где угодно, а не только в процедуре вывода.