
Durante a compilação de um documento látex, as páginas são “enviadas” uma de cada vez. Entendo que isso está marcado pela mensagem do console [1], [2], [3] etc, criando cada página. No entanto, ao inspecionar as gravações no arquivo DVI, estabeleci que o arquivo DVI não foi realmente gravado no momento da impressão dessas [n] mensagens. Em vez disso, parece que os dados são armazenados em cache e só chegam ao disco posteriormente. Para documentos pequenos, parece que todas as páginas são escritas de uma só vez no final do processo de compilação.
Para investigar isso, interceptei a chamada fwrite. Não é chamado em todos os embarques.
Minha dúvida é: existe uma maneira de forçar o latex a gravar no arquivo DVI a cada envio, ou seja, quando ele termina de compilar cada página de conteúdo. Isso é para ativar algumas funcionalidades personalizadas de visualização de dvi que desejo implementar.
Responder1
Como você adivinhou, a saída para o arquivo DVI é armazenada em buffer e gravada metade de dvi_buf_size
cada vez.
No Knuth TeX original, consulte§594:
Os bytes DVI são enviados para um buffer em vez de serem gravados diretamente no arquivo de saída. Isso torna possível reduzir a sobrecarga das chamadas de sub-rotina, acelerando assim de forma mensurável a computação, uma vez que a saída de bytes DVI faz parte do loop interno do TeX.
Veja também §597–598 que detalha a implementação:
- Bytes são gravados no buffer com
dvi_out
- Quando a parte não liberada do buffer atinge metade do tamanho de
dvi_buf
, o procedimentowrite_dvi
é chamado, que faz a gravação real no arquivo.
No PdfTeX a mesma implementação é mantida (§624–625). Na prática, no web2c, o procedimento write_dvi
émudadoparaserachamarpara fwrite
.
Se você não se importa com a velocidade (na qual isso provavelmente terá apenas um pequeno efeito: para a maioria dos documentos LaTeX, a maior parte do tempo é gasto expandindo macros em vez de gravar no arquivo de saída), você pode tentar alterar a implementação de TeX e recompilação: alterando para dvi_buf_size
muito pequeno (um comentário diz que precisa ser um múltiplo de 8, então talvez 8 funcione?) ou redefinindo dvi_out
(que se destina a gravar um byte no buffer DVI) para escreva o byte no arquivo diretamente com fwrite
. Ficarei curioso para saber se funciona!
Responder2
Eu acho que isso pode ter a ver com a constante "dvi_buf_size", que é definida como 16384 em algumas distribuições (não tenho certeza sobre a minha). Então, eu me pergunto se \shipout só acionará uma gravação no arquivo se a página size esgota esse buffer (ou metade dele). E, de fato, em meus testes estou vendo gravações de arquivo dvi de 8192, que na verdade é metade de 16384.
Então minha teoria é que \shipout não grava no arquivo DVI, apenas envia os dados para o buffer DVI, que é gravado no arquivo a cada 8.192 bytes. A estrutura real da página do documento é irrelevante. Se o \shipout não fizer com que o buffer atinja 8.192 bytes, ele não acionará uma gravação no arquivo, e se o \shipout entregar mais de 8.192 bytes, especulo que isso causará gravações no arquivo até que o buffer seja menor que 8192 bytes. De qualquer forma, as gravações no arquivo não são página por página.