\include 재정의

\include 재정의

Leslie Lamport가 내린 당황스러운 선택은 파일을 읽기 전에 \includea를 발행하는 방식으로 정의하는 것이었습니다. \clearpage이것은 작성자 인터페이스 측면에서 그다지 좋은 선택이 아니기 때문에 한동안 저를 혼란스럽게 했습니다. 이 질문은 두 부분으로 구성됩니다.

  1. 이 결정에 대한 타당한 이유가 있습니까?
  2. 명령이 재정의되면 무엇이 깨질 수 있나요?

아래의 MWE는 이러한 재정의를 보여줍니다(명령 이름을 지정했지만 \includex이름이 로 지정되어 있어도 잘 작동합니다 \include). 이것이 초기에 의 문제를 해결하기 위해 도입된 것이라는 내 자신의 의심은 있지만 이 결정을 설명하는 twocolumns데는 아무것도 없습니다 .source2e

\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}

답변1

이 메커니즘의 목적은 \include전체 문서를 다시 컴파일할 필요 없이 약간의 변경을 수행할 때 문서를 부분적으로 컴파일할 수 있도록 허용하고 상호 참조 등을 올바르게 해결하는 것입니다(칼 아래의 현재 부분 외부 부분에도 해당).

이것이 작동하려면 포함된 부분이 자체 포함되어야 합니다. 즉, 변경 사항이 포함되지 않은 다른 부분의 형식을 자동으로(그리고 항상) 렌더링하지 않는다는 의미입니다. 이를 가능하게 하려면(적어도 작은 변경의 경우) 다음 전제 조건이 필요합니다.

  • 메커니즘은 컴파일되는 부분의 텍스트 길이가 약간 변경되어도 컴파일되지 않은 다른 부분의 형식이 변경되지 않도록 보장해야 합니다.
  • 컴파일된 부분의 플로트는 컴파일된 부분에 배치되어야 합니다.

위의 사항 중 하나라도 유효하지 않은 경우 사용하면 \include(거의) 항상 유효하지 않은 문서가 생성되는 반면, 현재 체계에서는 모든 부분을 개별적으로 포함하고 여전히 유효한 문서를 도착하고 유지할 수 있습니다. (참고로 우리가 LaTeX Companion의 초판을 제작했을 때 이 책을 편집하는 데 오랜 시간이 걸렸으며 2004년에는 두 번째 판에서도 모든 예제와 모든 페이지를 편집하고 전체 책을 다시 실행하는 데 약 30분이 걸렸습니다. 시간) 모든 상호 참조를 성공적으로 해결하려면 장별로 구성하는 것이 필수적이었고 심지어 컴파일하는 데도 시간이 오래 걸렸습니다.

물론 결과 문서의 페이지가 하나 이상 길어지거나 짧아지는 등 많은 텍스트가 추가되거나 제거되는 순간 첫 번째 요점은 유효하지 않게 됩니다.

따라서 포함된 부분의 경계에서 페이지 나누기를 사용하는 것은 처음부터 메커니즘의 가치를 높이는 데 필요하며 \clearpage플로트가 포함된 부분 내에 머물고 들어오거나 나가지 않도록 하기 위해 사용이 필요합니다.

@egreg는 이미 보조 파일 데이터를 작성하는 메커니즘이 \shipout상호 참조나 목차에 대한 데이터와 같은 것을 보장하는 것이 불가능하거나 적어도 쉽지 않다는 추가 설명을 제공했습니다. 길을 잃지 않았습니다. 기술적으로 이를 관리할 가능성을 생각할 수 있지만 포함당 둘 이상의 aux 파일을 사용하면 위의 문제가 해결되지 않습니다.

마지막으로, 이것은 LaTeX 프로젝트 팀이 발명한 것이 아니며 Leslie Lamport의 원래 디자인으로 돌아가며 (적어도) LaTeX 2.08부터 1986년 이전까지 존재했습니다.

답변2

당신이 가지고 있다고 가정하자

\include{fileA}
\include{fileB}

\clearpagewhen end 가 없고 fileATeX가 읽기를 시작하면 , 보류 중인 관련 fileB명령이 있을 수 있으며 손실될 수 있습니다. 관련 명령은 즉시 수행되는 것이 아니라 출고 시 수행됩니다. 다음 출고가 발생하면 파일은 이미 닫혀 있을 것입니다.\writefileA\write\labelfileA.aux

예제를 추가해 보면\label ,없음파일이 이미 닫혀 있을 .log때 배송이 발생하기 때문에 그 중 어느 곳에나(파일 제외) 기록됩니다 ..aux

관련 정보