5

The goal

My objective is to have continuous page (and possibly section) counters for several independent documents. The purpose is a cumulative dissertation where each paper should retain the journal's layout as much as possible, but the school requires continuous pagination. It's arguably going to look ugly, like several papers glued together, but that's essentially what it is.

I'm aware that the clean way to proceed would probably be to extract the formatting information from the journals' .cls-files and pack into environments, but that would probably be a lot of work for someone as illiterate in plain TeX as I am. Therefore, I've tried, with some success, an alternative approach: a hack using the xr package. But there are some residual issues.

Let me first explain what I've been doing:

My setup

I have a main file which includes the introduction and conclusions. Its pagecounter and sectioncounter should both start at 1, so I have to update them with the values fed in from the last chapter of the body only at the breaking point. I have been having problems when trying to use \setcounter{page}{\pageref{external-endfile}} within the document which seem to have to do with the representation of \pageref's output as a string rather than an integer, and seem to be triggered by the babel package so I feed the numbers into a \newcounter which I then read into the actual counters when needed. Here's what this main file looks like:

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

Besides that, I have a file for the chapter, which looks like this:

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

With this setup, I only need to run two times each "pdflatex introandextro", "pdflatex file1" and again "pdflatex introandextro" to get a continuous page and section numbering. (I have a shell script to do that for me.) I also have a Python script to extract all toc-relevant information from the different aux-files and compile the main file with that as its toc in order to get a table of contents referencing all sections no matter which file they appear in which mostly works as it should.

As it should, \addtocounter{page}{\pageref{introendfile}} imports the pagecounter at the end of the introduction into file1. Also as it should, \setcounter{section}{\ref{introendfile}} eats the section part of the external references return value (1.2 in this case) and appropriately uses it to set the section counter. Unfortunately, it doesn't know what to do with the rest of the expression, so it spits it out again, writing ".2" on top of the page. That's ugly, so I'm trying to get rid of it. My hunch is that the best method for this would be to temporarily redefine \label within \exportcounters so that it only sends the topmost sectioning command to .aux and .toc, but my plain tex is not good enough to know where to start.

Residual Issues

So my question: Can anyone give me hints how to redefine the \label-command appropriately? In other words, how do I make it tell the .aux-file \newlabel{endfile}{{<thesection>}{12}} rather than \newlabel{endfile}{{<\thesection>.<\thesubsection>}{12}} despite being embedded in a subsection or deeper? (Alternatively, how do I strip the part from '.' on away before feeding it into \setcounter{section}{...}? I've tried \SubStringBefore but that produces a string rather than a number, throwing me a "Missing number, treated as zero" error during compilation.)

A second issue I'm having is that the need to insert an explicit \newpage where I want the first page to end in both documents, otherwise it would run on for two pages worth of text. This behavior seems to be triggered by xr (or the conjunction of xr and lipsum). Is this a known issue, and are there any workarounds that don't involve explicit \newpages?

Another (really quite minor) issue is that pdflatex complains about the use of \ref in the preamble ("Missing \begin{document}"), but I'm fine with just ignoring that if the result looks right.

Or maybe it's possible to tackle this problem from quite a different angle? Is there a tool to assist people who don't understand much plain TeX in packing .cls formatting commands into an environment? Something like \importasenvironment{<environmentname>}{<classname>.cls}?

2 Answers 2

5

Importing of the page and section value from a previous document can be achieved by package zref, module lastpage and xr.

First document

The first document DocumentA saves the properties pagevalue and sectionvalue to the property list LastPage that is written by the label LastPage, set by package zref-lastpage.

Example file DocumentA.tex, the first document:

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

Package zref-lastpage does the work:

  • Getting to the real end of the document (via package atveryend).
  • Writing to the .aux file via \immediate\write. \label uses \write to get the page number correct, but this requires a next page to be output. After the last page, there is no such page. Also the package takes care of the correction for the page number.

The .aux file contains:

\zref@newlabel{LastPage}{\default{4}\page{2}\abspage{2}\pagevalue{2}\sectionvalue{4}}

Next document

The next document imports the data from the label LastPage of the previous document and sets the counters. It also uses the code of the previous document to define the properties and to write the counter values for the next document.

Example file DocumentB.tex, the next document:

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

Then the first section of the second document Section E of second document is numbered with 5 and starts on page 3.

1
  • Thank you. It's also fairly easy to adapt your solution to the situation where a main file is broken up by external documents (e.g. a main file with the introduction and conclusions, and the chapters of the body in one or more external files). I had a stab at it as demonstrated.
    – JakobMST
    Jul 14, 2013 at 11:43
2

Heiko Oberdiek's answer solves the base case of several documents that just build on each other perfectly.

For the somewhat more complex case of a main file that includes portions both before and after the chapters to be included, i.e. that passes on its counters to an external document at an arbitrary point in the document and then retrieves the same or another external documents' counters also within the document, I managed a tweak by defining \importcounters and \exportcounters commands and call them in the appropriate places. It can probably be further reduced, but this is as close as I get at the moment building on Heiko Oberdiek's post.

\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, the only change is that I feed the counters on pre-LastIntroPage rather than pre-LastPage.)

My next goal is to work out how to use write18 to make the main file pause and move to the compilation of the dependent files before moving on, but that's for a separate question.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .