Tudo sobre \shipout

Tudo sobre \shipout

Ao ler sobre pacotes que permitemganchomacros para determinados eventos, me deparei com este comando, \shipout. Pesquisar na internet não ajudou muito mas se não me engano está de alguma forma relacionado à criação de novas páginas (ou não?).

Minha pergunta é: o que é exatamente \shipout, o que faz e como faz o que faz? (ou seja, o que está acontecendo em baixo nível em segundo plano)

Responder1

Isso é muito fácil: \shipouté primitivo. Sua sintaxe é

\envio ⟨caixa⟩

onde ⟨box⟩ é completamente especificado na página 278 do TeXbook:

⟨caixa⟩ → \box⟨número de 8 bits⟩ | \copy⟨Número de 8 bits⟩
  | \lastbox| \vsplit⟨Número de 8 bits⟩ to⟨dimen⟩
  | \hbox⟨especificação da caixa⟩ {⟨material do modo horizontal⟩ }
  | \vbox⟨especificação da caixa⟩ {⟨material de modo vertical⟩ }
  | \vtop⟨especificação da caixa⟩ {⟨material do modo vertical⟩ }
⟨especificação da caixa⟩ → to⟨dimen⟩⟨filler⟩ | spread⟨dimen⟩⟨filler⟩ | ⟨preenchimento⟩

Poderíamos, por exemplo, dizer

\shipout\hbox{Hello world}

e uma página no arquivo DVI ou PDF será criada. Claro que ninguém quer usar \shipoutdesta forma. Seu principal uso é na rotina de saída que é chamada quando o TeX decide que possui material suficiente para ejetar uma página inteira. A lista vertical principal atual é dividida na quebra de página escolhida e seu conteúdo é empacotado em \box255, sobre o qual a rotina de saída pode atuar. Por exemplo, a rotina de saída do Plain TeX faz

\shipout\vbox{
  \makeheadline
  \pagebody
  \makefootline
}
\advancepageno
\ifnum\outputpenalty>-\@MM
\else
  \dosupereject
\fi

assim, uma página inteira, adornada com cabeçalhos e rodapés, é enviada. O conteúdo de \box255é massageado por \pagebody. A rotina de saída no LaTeX é muito mais complicada.

O que se pode fazer é redefinir \shipoutpara que outras funções sejam realizadas. O conjunto de macros mais antigo que fez algo assim foi quire.tex(ainda disponível no CTAN e 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
   }

Ele salva o significado primitivo de \shipoutno comando \q_oldship(as macros usam _como um marcador 'privado') e o redefine como \q_boat, que fará alguns trabalhos e eventualmente chamará \q_oldship. Por exemplo, ele pode ser configurado para colocar duas páginas de saída na mesma página física ou para fazer questionários de dezesseis páginas (daí o nome do pacote).

O pacote atbegshifaz o mesmo. Ele redefine \shipoutpara que possa conectar-se entre a chamada \shipoute o envio real da página.

O que exatamente a primitiva \shipoutfaz é transformar a lista vertical com a qual é alimentada em instruções de impressão de baixo nível (formato DVI ou PDF, de acordo com o valor de \pdfoutputif pdftexou luatexfor usado, XDV se xetexfor usado, apenas DVI para Knuth TeX). Enquanto isso, ele executa todas \writeas operações atrasadas, expandindo os tokens à medida que avança: desta forma, as referências ao número da página são garantidas como corretas, porque são computadas quando a página está sendo enviada.

Responder2

DeTeXbook, Capítulo 23: Rotinas de saída, página 254:

O comando primitivo \shipout<box> do TeX é o que realmente causa a saída. Ele envia o conteúdo da caixa para o dviarquivo, que é o principal arquivo de saída do TeX; após a conclusão do TeX, o dviarquivo conterá uma codificação compacta de instruções, independente do dispositivo, que especifica exatamente o que deve ser impresso. Quando uma caixa é enviada, o TeX exibe os valores de \count0through \count9em seu terminal, conforme explicado no Capítulo 15; esses dez contadores também ficam registrados no dviarquivo, onde podem ser utilizados para identificar a página. Todos os comandos \openout, \closeout, e \writeque aparecem dentro da caixa são executados em sua ordem natural conforme a caixa é enviada. Como um \writecomando expande macros, conforme explicado no Capítulo 21, o mecanismo de varredura do TeX pode detectar erros de sintaxe enquanto um comando \shipoutestá em andamento. Se \tracingoutputfor diferente de zero no momento de a \shipout, o conteúdo da caixa enviada será gravado em seu arquivo de log em formato simbólico. Você pode dizer \shipoutem qualquer lugar, não apenas em uma rotina de saída.

informação relacionada