Das Ziel

Das Ziel

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 TeXwie ich. Daher habe ich mit einigem Erfolg einen alternativen Ansatz ausprobiert: einen Hack mit dem xrPaket. 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 \pagerefund vom babelPaket ausgelöst zu werden scheinen, daher füge ich die Zahlen in ein ein, \newcounterdas 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 tocrelevanten Informationen aus den verschiedenen auxDateien zu extrahieren und die Hauptdatei damit zu kompilieren, um tocein 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, \labelinnerhalb vorübergehend neu zu definieren \exportcounters, sodass es nur den obersten Abschnittsbefehl an .auxund 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 \newpagein 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 xrund lipsum) ausgelöst zu werden. Ist das ein bekanntes Problem und gibt es Workarounds, die keine expliziten \newpageZeichen erfordern?

Ein weiteres (eigentlich recht kleines) Problem ist, dass pdflatex sich über die Verwendung von \refin 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, .clsFormatierungsbefehle 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 lastpageund erfolgen xr.

Erstes Dokument

Das erste Dokument DocumentAspeichert die Eigenschaften pagevalueund sectionvaluedie Eigenschaftenliste , die durch das vom Paket festgelegte LastPageLabel geschrieben wird .LastPagezref-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-lastpageerledigt die Arbeit:

  • Anreise zumrealEnde des Dokuments (über Paket atveryend).
  • Das Schreiben in die .auxDatei über \immediate\write. \labelverwendet \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 .auxDatei 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 LastPagedes 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 documentmit 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 \importcountersund \exportcountersan 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.texbesteht die einzige Änderung darin, dass ich die Zähler auf pre-LastIntroPagestatt auf einspeise pre-LastPage.)

Mein nächstes Ziel besteht darin, herauszufinden, wie ich write18die Hauptdatei anhalten und mit der Kompilierung der abhängigen Dateien fortfahren kann, bevor es weitergeht, aber das ist eine andere Frage.

verwandte Informationen