Neudefinition von \include

Neudefinition von \include

Eine rätselhafte Entscheidung von Leslie Lamport war, \includeso zu definieren, dass \clearpagevor dem Lesen der Datei ein ausgegeben wird. Das hat mich schon seit einiger Zeit verwirrt, da es in Bezug auf die Autorenschnittstelle keine sehr gute Wahl ist. Diese Frage besteht aus zwei Teilen:

  1. Gibt es triftige Gründe für diese Entscheidung?
  2. Was kann möglicherweise kaputt gehen, wenn der Befehl neu definiert wird?

Das folgende MWE zeigt eine solche Neudefinition (ich habe den Befehl benannt, \includexaber er funktioniert auch einwandfrei, wenn er den Namen hat \include). Ich persönlich vermute, dass dies schon früh eingeführt wurde, um Probleme mit zu lösen twocolumns, aber im wird source2ediese Entscheidung nicht erklärt.

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

Antwort1

Der Zweck des \includeMechanismus besteht darin, bei geringfügigen Änderungen eine teilweise Kompilierung des Dokuments zu ermöglichen, ohne das gesamte Dokument erneut kompilieren zu müssen und trotzdem Querverweise usw. korrekt aufgelöst zu bekommen (auch auf Teile außerhalb des aktuellen Teils).

Damit dies funktioniert, müssen die eingebundenen Teile in sich geschlossen sein, in dem Sinne, dass Änderungen daran nicht automatisch (und immer) die Formatierung anderer, nicht eingebundener Teile ungültig machen. Um dies (zumindest für kleinere Änderungen) zu ermöglichen, sind folgende Voraussetzungen erforderlich:

  • Der Mechanismus muss sicherstellen, dass kleine Änderungen der Textlänge im zu kompilierenden Teil nicht zu Formatierungsänderungen in anderen, nicht kompilierten Teilen führen.
  • Floats in den kompilierten Teilen müssen in den kompilierten Teilen platziert werden

Wenn einer der oben genannten Punkte nicht zutrifft, \includewürde die Verwendung von (fast) immer zu ungültigen Dokumenten führen, während Sie im aktuellen Schema alle Teile einzeln einbinden und trotzdem ein gültiges Dokument erhalten können. (Nur zur Info: Als wir die erste Ausgabe des LaTeX Companion erstellten, dauerte es ewig, dieses Buch zusammenzustellen, und selbst für die zweite Ausgabe im Jahr 2004 dauerte es etwa 30 Minuten, alle Beispiele + alle Seiten zusammenzustellen und das ganze Buch (ich glaube, 5 Mal) erneut auszuführen, um alle Querverweise erfolgreich aufzulösen. Es war also unerlässlich, die Dinge Kapitel für Kapitel aufzubauen, und selbst dann dauerte das Kompilieren lange :-)

Natürlich ist der erste Punkt hinfällig, sobald viel Text hinzugefügt oder entfernt wird, also das resultierende Dokument um eine oder mehrere Seiten länger oder kürzer wird.

Die Verwendung von Seitenumbrüchen an den Grenzen der eingeschlossenen Teile ist also einfach notwendig, damit sich der Mechanismus überhaupt lohnt, und sie \clearpageist erforderlich, um sicherzustellen, dass die Floats innerhalb des eingeschlossenen Teils bleiben und sich nicht hinein- oder hinausbewegen.

@egreg hat bereits die zusätzliche Erklärung gegeben, dass der Mechanismus zum Schreiben von AUX-Dateidaten nur funktioniert, \shipoutsodass es nicht möglich (oder zumindest nicht einfach) wäre, sicherzustellen, dass Dinge wie Querverweise oder Daten für das Inhaltsverzeichnis nicht verloren gehen. Technisch könnte man sich eine Möglichkeit vorstellen, dies zu verwalten, aber mehr als eine AUX-Datei pro Include zu verwenden, aber das würde den obigen Punkt nicht lösen.

Schließlich handelt es sich hierbei nicht um eine Erfindung des LaTeX-Projektteams, sondern sie geht auf den ursprünglichen Entwurf von Leslie Lamport zurück und existierte seit (mindestens) LaTeX 2.08, also vor 1986.

Antwort2

Nehmen wir an, Sie haben

\include{fileA}
\include{fileB}

Wenn kein „ \clearpagewenn fileAendet“ angegeben ist und TeX mit dem Lesen beginnt fileB, könnte ein \writerelativer Befehl zu fileAausstehend sein und dieser geht verloren: Die \writerelativen Befehle zu \labelwerden beim Versand ausgeführt, nicht sofort. Beim nächsten Versand fileA.auxist die Datei bereits geschlossen.

Wenn Sie Ihr Beispiel ausprobieren und ein\label jedem einen Befehl hinzufügen,keinerdavon werden überall hin geschrieben (aber nicht in die .logDatei), weil der Versand erfolgt, wenn die .auxDateien bereits geschlossen wurden.

verwandte Informationen