Redefinindo \include

Redefinindo \include

Uma escolha intrigante feita por Leslie Lamport foi definir \includede forma a emitir um \clearpageantes de ler o arquivo. Isso tem me intrigado há algum tempo, pois não é uma escolha muito boa em termos de interface do autor. Esta questão tem duas partes:

  1. Existem razões válidas para esta decisão?
  2. O que pode acontecer se o comando for redefinido?

O MWE abaixo mostra essa redefinição (nomeei o comando, \includexmas funciona muito bem mesmo, se for nomeado \include). Minha própria suspeita é que isso foi introduzido desde o início para resolver problemas com o twocolumns, mas não há nada explicando source2eessa decisão.

\documentclass{book}
\usepackage{filecontents}
\makeatletter
\def\includex#1{\relax
  \ifnum\@auxout=\@partaux
    \@latex@error{\string\include\space cannot be nested}\@eha
  \else \@includex#1 \fi}

\def\@includex#1 {%
  %\clearpage
  \if@filesw
    \immediate\write\@mainaux{\string\@input{#1.aux}}%
  \fi
  \@tempswatrue
  \if@partsw
    \@tempswafalse
    \edef\reserved@b{#1}%
    \@for\reserved@a:=\@partlist\do
      {\ifx\reserved@a\reserved@b\@tempswatrue\fi}%
  \fi
  \if@tempswa
    \let\@auxout\@partaux
    \if@filesw
      \immediate\openout\@partaux #1.aux
      \immediate\write\@partaux{\relax}%
    \fi
    \@input@{#1.tex}%
    %\clearpage
    \@writeckpt{#1}%
    \if@filesw
      \immediate\closeout\@partaux
    \fi
  \else
    \deadcycles\z@
    \@nameuse{cp@#1}%
  \fi
  \let\@auxout\@mainaux
}
\begin{filecontents}{A.tex}
This is file A
This is the A file
\end{filecontents}
\begin{filecontents}{B.tex}
This is the B file
\end{filecontents}
\begin{filecontents}{C.tex}
This is the C file
\end{filecontents}
\includeonly{A,C}
\begin{document}
\includex{A}
\includex{B}
\includex{C}
\end{document}

Responder1

O objetivo do \includemecanismo é permitir a compilação parcial do documento ao fazer uma quantidade modesta de alterações sem a necessidade de recompilar o documento completo e ainda obter referências cruzadas, etc., resolvidas corretamente (mesmo para partes fora da parte atual sob a faca).

Para que isso funcione, a parte ou partes incluídas devem ser independentes, no sentido de que alterações nela não tornam automaticamente (e sempre) inválida a formatação de outras partes não incluídas. Para tornar isso possível (pelo menos para alterações menores), são necessários os seguintes pré-requisitos:

  • O mecanismo precisa garantir que pequenas alterações no comprimento do texto na parte que está sendo compilada não resultem em alterações de formatação em outras partes não compiladas
  • Flutuadores nas partes compiladas precisam ser colocados nas partes compiladas

Se algum dos pontos acima não for válido, o uso \includeresultaria (quase) sempre em documentos inválidos, enquanto no esquema atual você pode incluir todas as peças individualmente e ainda assim chegar e manter um documento válido. (Só para constar, quando produzimos a primeira edição do LaTeX Companion demoramos muito para compilar este livro e até mesmo a segunda edição levou cerca de 30 minutos em 2004 para compilar todos os exemplos + todas as páginas e reexecutar o livro inteiro (acho que 5 vezes) para que todas as referências cruzadas fossem resolvidas com sucesso. Portanto, construir as coisas capítulo por capítulo foi essencial e mesmo assim a compilação demorou muito :-)

É claro que o primeiro ponto será inválido no momento em que muito texto for adicionado ou removido, de modo que o documento resultante fique uma ou mais páginas mais longas ou mais curtas.

Portanto, usar quebras de página nos limites das partes incluídas é simplesmente necessário para fazer o mecanismo valer a pena, em primeiro lugar, e \clearpageé necessário usá-lo para garantir que os flutuadores permaneçam dentro da parte incluída e não se movam para dentro ou para fora.

@egreg já deu a explicação adicional de que o mecanismo para gravar dados do arquivo aux funciona apenas \shipoutpara que não seja possível (ou pelo menos não é fácil) garantir que coisas como referências cruzadas ou dados para índice analítico sejam ' não perdi. Tecnicamente, alguém poderia pensar na possibilidade de gerenciar isso, mas usando mais de um arquivo aux por inclusão, mas isso não resolveria o ponto acima.

Finalmente, isso não é algo que a equipe do Projeto LaTeX inventou, mas remonta ao design original de Leslie Lamport e existia desde o LaTeX 2.08 (pelo menos), antes de 1986.

Responder2

Vamos supor que você tenha

\include{fileA}
\include{fileB}

Se não houver \clearpagequando fileAtermina e o TeX começa a ler fileB, pode haver um \writerelativo a fileApendente e ele será perdido: os \writecomandos relativos a \labelsão executados no envio, não imediatamente. Quando ocorrer o próximo envio, o fileA.auxarquivo já estará fechado.

Se você tentar seu exemplo adicionando um \labelcomando a cada um,nenhumdeles serão gravados em qualquer lugar (menos no .logarquivo), pois o envio acontece quando os .auxarquivos já foram fechados.

informação relacionada