Загадочный выбор, сделанный Лесли Лэмпортом, заключался в определении \include
таким образом, чтобы выдать \clearpage
перед чтением файла. Это меня уже давно озадачивает, так как это не очень хороший выбор с точки зрения интерфейса автора. Этот вопрос состоит из двух частей:
- Есть ли веские причины для такого решения?
- Что может сломаться, если переопределить команду?
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, потребовалась уйма времени, чтобы скомпилировать эту книгу, и даже второе издание заняло около 30 минут в 2004 году, чтобы скомпилировать все примеры + все страницы и перепройти всю книгу (я думаю, 5 раз), чтобы успешно разрешить все перекрестные ссылки. Поэтому построение всего по главам было важным, и даже тогда компиляция заняла много времени :-)
Конечно, первый пункт станет недействительным в тот момент, когда будет добавлено или удалено много текста, например, если результирующий документ станет на одну или несколько страниц длиннее или короче.
Таким образом, использование разрывов страниц на границах включенных частей просто необходимо для того, чтобы сделать механизм полезным в первую очередь, а также необходимо \clearpage
для того, чтобы гарантировать, что плавающие элементы остаются внутри включенной части и не перемещаются внутрь или наружу.
@egreg уже дал дополнительное объяснение, что механизм записи данных aux-файла работает только \shipout
для того, чтобы было невозможно (или, по крайней мере, нелегко) гарантировать, что такие вещи, как перекрестные ссылки или данные для оглавления не будут потеряны. Технически можно было бы придумать возможность управлять этим, но используя более одного aux-файла на включение, но это не решит проблему выше.
Наконец, это не изобретение команды проекта LaTeX, это восходит к оригинальному проекту Лесли Лэмпорта и существовало с версии LaTeX 2.08 (по крайней мере), то есть до 1986 года.
решение2
Предположим, у вас есть
\include{fileA}
\include{fileB}
Если нет \clearpage
when fileA
ends и TeX начинает читать fileB
, может быть \write
относительное к fileA
pending и оно потеряется: \write
команды относительно \label
выполняются при shipout, а не немедленно. Когда произойдет следующий shipout, fileA.aux
файл уже будет закрыт.
Если вы попробуете ваш пример, добавив \label
команду к каждому из них,никтоиз них будут записаны куда угодно (но не в .log
файл), поскольку отправка происходит, когда .aux
файлы уже закрыты.