
Das Ziel
Mein Ziel ist es, fortlaufende Seiten- (und möglicherweise Abschnitts-)Zähler für mehrere unabhängige Dokumente zu haben. Der Zweck ist eine kumulative Dissertation, bei der jedes Papier das Layout der Zeitschrift so weit wie möglich beibehalten sollte, die Schule jedoch eine fortlaufende Seitennummerierung verlangt. Es wird wohl hässlich aussehen, wie mehrere zusammengeklebte Papiere, aber das ist es im Wesentlichen.
Mir ist bewusst, dass die saubere Vorgehensweise wahrscheinlich darin bestehen würde, die Formatierungsinformationen aus den .cls
-Dateien der Journale zu extrahieren und in Umgebungen zu packen, aber das wäre wahrscheinlich eine Menge Arbeit für jemanden, der so ungebildet ist TeX
wie ich. Daher habe ich mit einigem Erfolg einen alternativen Ansatz ausprobiert: einen Hack mit dem xr
Paket. Aber es gibt noch einige Restprobleme.
Lassen Sie mich zunächst erklären, was ich getan habe:
Mein Setup
Ich habe eine Hauptdatei, die die Einleitung und die Schlussfolgerungen enthält. Der Seitenzähler und der Abschnittszähler sollten beide bei 1 beginnen, daher muss ich sie nur am Bruchpunkt mit den Werten aktualisieren, die aus dem letzten Kapitel des Hauptteils eingegeben wurden. Ich hatte Probleme beim Versuch, \setcounter{page}{\pageref{external-endfile}}
innerhalb des Dokuments zu verwenden, die anscheinend mit der Darstellung der Ausgabe von als Zeichenfolge und nicht als Ganzzahl zu tun haben \pageref
und vom babel
Paket ausgelöst zu werden scheinen, daher füge ich die Zahlen in ein ein, \newcounter
das ich dann bei Bedarf in die eigentlichen Zähler einlese. So sieht diese Hauptdatei aus:
\documentclass{article}
\usepackage{xr} %imports labels from external document
\externaldocument[finalCh]{file1} %prefix external labels to avoid name clashes
\newcounter{finalcount}
\setcounter{finalcount}{\pageref{finalChendfile}}% probably not the most elegant way to pack the input file's page number into a numberical variable, but it works.
\stepcounter{finalcount}% +1 since counters are initialised at 0
\newcounter{othersectioncount}
\setcounter{othersectioncount}{\ref{finalChendfile}}
\usepackage{ifthen} %conditionals
\newcommand{\exportcounters}{
\ifthenelse{%
\isodd{\thepage}} % if current page is odd-numbered
{\newpage \ % new page, forced space to make sure the following command is actually parsed, i.e. the page not treated as totally empty
}%
{\relax}
\label{endfile}
\newpage
}
%... other packages
\usepackage[english]{babel} %for some reason I don't understand, this clashes with treating \pageref as a number, so you have to put it *after* determining the page number
\usepackage{lipsum}
\begin{document}
\tableofcontents
\section{Introduction}
\subsection{Subsection}
\lipsum[1-2]
\newpage
\subsection{Another subsection}
\exportcounters
\setcounter{section}{\theothersectioncount}
\section{Conclusions}
\setcounter{page}{\thefinalcount} %load the final pagenumber of the last chapter here
\lipsum[4-40]
\end{document}
Außerdem habe ich eine Datei für das Kapitel, die so aussieht:
\documentclass{article}
\usepackage{substr}
\usepackage{xr} %imports labels from external document
\usepackage{ifthen} %conditionals
\externaldocument[intro]{introandextro} %prefix external labels to avoid name clashes
\addtocounter{page}{\pageref{introendfile}}
\newcommand{\exportcounters}{
\ifthenelse{%
\isodd{\thepage}} % if current page is odd-numbered
{\newpage \ % new page, forced space to make sure the following command is actually parsed, i.e. the page not treated as totally empty
}%
{\relax}
\label{endfile}
\newpage
}
\usepackage{lipsum}
%\setcounter{section}{2}
\begin{document}
\setcounter{section}{\ref{introendfile}}
\section{Chapter I}
\subsection{intro}
\lipsum[1-4]
\newpage
\subsection{Chapter 1 body}
\lipsum[5-44]
\exportcounters
\label{endfile}
\end{document}
Mit diesem Setup muss ich nur jeweils zwei Mal „pdflatex introandextro“, „pdflatex file1“ und erneut „pdflatex introandextro“ ausführen, um eine fortlaufende Seiten- und Abschnittsnummerierung zu erhalten. (Ich habe ein Shell-Skript, das das für mich erledigt.) Ich habe auch ein Python-Skript, um alle toc
relevanten Informationen aus den verschiedenen aux
Dateien zu extrahieren und die Hauptdatei damit zu kompilieren, um toc
ein Inhaltsverzeichnis zu erhalten, das auf alle Abschnitte verweist, egal in welcher Datei sie erscheinen, und das meistens so funktioniert, wie es soll.
Wie vorgesehen \addtocounter{page}{\pageref{introendfile}}
importiert es den Seitenzähler am Ende der Einleitung in Datei1. Außerdem \setcounter{section}{\ref{introendfile}}
frisst es wie vorgesehen den Abschnittsteil des Rückgabewerts der externen Referenzen (in diesem Fall 1,2) und verwendet ihn entsprechend, um den Abschnittszähler festzulegen. Leider weiß es nicht, was es mit dem Rest des Ausdrucks anfangen soll, also spuckt es ihn erneut aus und schreibt „.2“ oben auf die Seite. Das ist hässlich, also versuche ich, es loszuwerden. Ich vermute, dass die beste Methode dafür darin besteht, \label
innerhalb vorübergehend neu zu definieren \exportcounters
, sodass es nur den obersten Abschnittsbefehl an .aux
und sendet .toc
, aber mein einfacher Text ist nicht gut genug, um zu wissen, wo ich anfangen soll.
Restprobleme
Meine Frage also: Kann mir jemand Tipps geben, wie ich den \label
-Befehl entsprechend neu definieren kann? Anders ausgedrückt: Wie bringe ich es dazu, die .aux
-Datei zu informieren \newlabel{endfile}{{<thesection>}{12}}
, anstatt sie \newlabel{endfile}{{<\thesection>.<\thesubsection>}{12}}
trotz der Einbettung in einen Unterabschnitt oder tiefer zu entfernen? (Alternativ: Wie entferne ich den Teil ab '.', bevor ich ihn in einfüge \setcounter{section}{...}
? Ich habe es versucht \SubStringBefore
, aber das erzeugt eine Zeichenfolge statt einer Zahl, was mir während der Kompilierung den Fehler „Fehlende Zahl, wird als Null behandelt“ anzeigt.)
Ein zweites Problem, das ich habe, ist, dass ich \newpage
in beiden Dokumenten ein explizites Zeichen einfügen muss, wo die erste Seite enden soll, da es sonst zwei Seiten Text ergeben würde. Dieses Verhalten scheint durch xr
(oder die Verbindung von xr
und lipsum
) ausgelöst zu werden. Ist das ein bekanntes Problem und gibt es Workarounds, die keine expliziten \newpage
Zeichen erfordern?
Ein weiteres (eigentlich recht kleines) Problem ist, dass pdflatex sich über die Verwendung von \ref
in der Präambel beschwert („Fehlendes \begin{document}“), aber für mich ist es kein Problem, das einfach zu ignorieren, wenn das Ergebnis richtig aussieht.
Oder kann man das Problem vielleicht auch von einer ganz anderen Seite angehen? Gibt es ein Tool, das Leuten, die nicht viel von einfachem TeX verstehen, dabei hilft, .cls
Formatierungsbefehle in eine Umgebung zu packen? So etwas wie \importasenvironment{<environmentname>}{<classname>.cls}
?
Antwort1
Der Import der Seiten- und Abschnittswerte aus einem vorherigen Dokument kann über Paket zref
, Modul lastpage
und erfolgen xr
.
Erstes Dokument
Das erste Dokument DocumentA
speichert die Eigenschaften pagevalue
und sectionvalue
die Eigenschaftenliste , die durch das vom Paket festgelegte LastPage
Label geschrieben wird .LastPage
zref-lastpage
Beispieldatei DocumentA.tex
, das erste Dokument:
\documentclass{article}
\usepackage{zref-lastpage}
\makeatletter
\zref@ifpropundefined{pagevalue}{% it is defined by some modules of zref
\zref@newprop*{pagevalue}[0]{\number\value{page}}%
}{}
\zref@newprop{sectionvalue}[0]{\number\value{section}}%
\zref@addprops{LastPage}{pagevalue,sectionvalue}
\makeatother
\begin{document}
\section{Section A of first document}
\section{Section B of first document}
\newpage
\section{Section C of first document}
\section{Section D of first document}
\end{document}
Das Paket zref-lastpage
erledigt die Arbeit:
- Anreise zumrealEnde des Dokuments (über Paket
atveryend
). - Das Schreiben in die
.aux
Datei über\immediate\write
.\label
verwendet\write
, um die Seitenzahl richtig zu bekommen, erfordert aber die Ausgabe einer Folgeseite. Nach der letzten Seite gibt es keine solche Seite. Auch die Korrektur der Seitenzahl übernimmt das Paket.
Die .aux
Datei enthält:
\zref@newlabel{LastPage}{\default{4}\page{2}\abspage{2}\pagevalue{2}\sectionvalue{4}}
Nächstes Dokument
Das nächste Dokument importiert die Daten aus dem Etikett LastPage
des vorherigen Dokuments und legt die Zähler fest. Es verwendet außerdem den Code des vorherigen Dokuments, um die Eigenschaften zu definieren und die Zählerwerte für das nächste Dokument zu schreiben.
Beispieldatei DocumentB.tex
, das nächste Dokument:
\documentclass{article}
\usepackage{zref-lastpage,zref-xr}
\makeatletter
\zref@ifpropundefined{pagevalue}{% it is defined by some modules of zref
\zref@newprop*{pagevalue}[0]{\number\value{page}}%
}{}
\zref@newprop{sectionvalue}[0]{\number\value{section}}%
\zref@addprops{LastPage}{pagevalue,sectionvalue}
\zexternaldocument[pre-]{DocumentA}\relax
\zref@ifrefundefined{pre-LastPage}{%
\@latex@error{Zref label `LastPage' of `DocumentA' is undefined}\@ehc
}{%
\setcounter{page}{%
\numexpr\zref@extractdefault{pre-LastPage}{pagevalue}{0}+1\relax
}%
\setcounter{section}{%
\zref@extractdefault{pre-LastPage}{sectionvalue}{0}%
}%
}
\makeatother
\begin{document}
\section{Section E of second document}
\section{Section F of second document}
\newpage
\section{Section G of second document}
\section{Section H of second document}
\end{document}
Anschließend wird der erste Abschnitt des zweiten Dokuments Section E of second document
mit 5 nummeriert und beginnt auf Seite 3.
Antwort2
Die Antwort von Heiko Oberdiek löst den Grundfall mehrerer aufeinander aufbauender Dokumente perfekt.
Für den etwas komplexeren Fall einer Hauptdatei, die sowohl Abschnitte vor als auch nach den einzubindenden Kapiteln enthält, also ihre Zähler an beliebiger Stelle im Dokument an ein externes Dokument weitergibt und dann innerhalb des Dokuments die Zähler desselben oder eines anderen externen Dokuments abruft, ist mir eine Optimierung gelungen, indem ich Befehle definiert \importcounters
und \exportcounters
an den entsprechenden Stellen aufgerufen habe. Es lässt sich wahrscheinlich noch weiter reduzieren, aber näher komme ich dem im Moment nicht, wenn ich auf Heiko Oberdieks Beitrag aufbaue.
\documentclass{article}
\usepackage{zref-lastpage,zref-xr}
\makeatletter
\zref@ifpropundefined{pagevalue}{% it is defined by some modules of zref
\zref@newprop*{pagevalue}[0]{\number\value{page}}%
}{}
\zref@newprop{sectionvalue}[0]{\number\value{section}}%
%\zref@addprops{LastPage}{pagevalue,sectionvalue}%
\zexternaldocument[pre-]{DocumentB}\relax
\zref@ifrefundefined{pre-LastPage}{%
\@latex@error{Zref label `LastPage' of `DocumentB' is undefined}\@ehc
}{%
\newcounter{@otherpage}
\setcounter{@otherpage}{%
\numexpr\zref@extractdefault{pre-LastPage}{pagevalue}{0}+1\relax
}%
\newcounter{@othersection}
\setcounter{@othersection}{%
\zref@extractdefault{pre-LastPage}{sectionvalue}{0}%
}%
}
\newcommand{\importcounters}{% enables importing the external page and section counters at an arbitrary point in the document
\setcounter{section}{\the@othersection}
\setcounter{page}{\the@otherpage}
}
\newcommand{\exportcounters}{% exporting counters after the intro rather than at the end of the document
\cleardoublepage \ %
\zref@labelbyprops{LastIntroPage}{pagevalue,sectionvalue}
}
\makeatother
\usepackage[english]{babel}
\begin{document}
\section{Section A of first document}
\section{Section B of first document}
\exportcounters
\newpage
\importcounters
\section{Section C of first document}
\section{Section D of first document}
\subsection{D 1}
\subsection{D 2}
\end{document}
(In DocumentB.tex
besteht die einzige Änderung darin, dass ich die Zähler auf pre-LastIntroPage
statt auf einspeise pre-LastPage
.)
Mein nächstes Ziel besteht darin, herauszufinden, wie ich write18
die Hauptdatei anhalten und mit der Kompilierung der abhängigen Dateien fortfahren kann, bevor es weitergeht, aber das ist eine andere Frage.