3

I would like to retain only a subset of pages, i.e. those which have been marked with the tag command \keepthispage and have come up with the following preamble commands.

\RequirePackage{atbegshi}
\RequirePackage{etoolbox}
\newbool{keeppage}
\boolfalse{keeppage}
\AtBeginShipout{%
\ifbool{keeppage}
    {\global\boolfalse{keeppage}}
    {\global\boolfalse{keeppage}\AtBeginShipoutDiscard}}
\newcommand{\keepthispage}{\global\booltrue{keeppage}}

This works nicely except that also all labels on pages not included in the output are not written to the aux file, and therefore I end up with a lot of missing references. As explained by Heiko Oberdiek in reply to a different question, it is first necessary to process the complete file without page suppression, e.g. by adding \renewcommand{\keepthispage}{} and commenting out the \AtBeginShipout command below the above snippet, and then rerun it by using \nofiles.

However, this requires editing the file between runs. Is there a way to achieve this outcome by running latex/pdflatex twice on the same input file without requiring editing of the file in between (automated editing such as use of sed also does not count as the .tex file in question is autogenerated, and the user expects that he can just run it through latex - instead latex should detect if it is in the first or second pass, and behave appropriately).

3
  • Are you using hyperref at all? What about page references via \pageref?
    – Werner
    Mar 12, 2015 at 0:29
  • ...and what is DIFkeeppage? Come to think of it, you should just create a complete document that we can compile and replicate your current problem rather than having to create our own. It's just the right thing to do. It should start with \documentclass and end with \end{document}.
    – Werner
    Mar 12, 2015 at 0:33
  • @Werner I simplified a slightly more complicated use case in constructing the code snippet, and the DIFkeeppage is a transcription error I made in doing this. I see in your answer you guessed correctly what I meant, and I have edited the question now.
    – frederik
    Mar 12, 2015 at 8:27

1 Answer 1

4

Page references are the only thing that are influenced by this delayed writing to the .aux - it's a requirement in order to obtain the correct reference. However, if you're not using any page reference, you can avoid this delayed .aux-writing by using an "immediate writing wrapper" (zref provides this via \zref@immediate@wrapper):

enter image description here

\documentclass{article}

\usepackage{lipsum,zref}
\usepackage{atbegshi,etoolbox}

\newbool{keeppage}
\boolfalse{keeppage}
\AtBeginShipout{%
  \ifbool{keeppage}
      {\global\boolfalse{keeppage}}% Keep this page
      {\global\boolfalse{keeppage}\AtBeginShipoutDiscard}}% Discard this page
\newcommand{\keepthispage}{\global\booltrue{keeppage}}

\makeatletter
\let\oldlabel\label% Store \label
\renewcommand{\label}[1]{% Update \label to write to the .aux immediately
  \zref@wrapper@immediate{\oldlabel{#1}}}
\makeatother

\begin{document}

See Section~\ref{sec:second}.\keepthispage% Keep this page

\section{First section}\label{sec:first}\lipsum[1-5]
\subsection{First subsection}\label{subsec:first.first}\lipsum[1-5]
\subsection{Second subsection}\label{subsec:first.second}\lipsum[1-5]
\subsection{Last subsection}\label{subsec:first.last}\lipsum[1-5]

\section{Second section}\label{sec:second}\lipsum[1-5]
\subsection{First subsection}\label{subsec:second.first}\lipsum[1-5]
\subsection{Second subsection}\label{subsec:second.second}\lipsum[1-5]
\subsection{Last subsection}\label{subsec:second.last}\lipsum[1-5]

\end{document}

The .aux file will now contain all the correct counter references, but an incorrect page reference:

\relax 
\providecommand\zref@newlabel[2]{}
\newlabel{sec:first}{{1}{\thepage }}
\@writefile{toc}{\contentsline {section}{\numberline {1}First section}{1}}
\newlabel{subsec:first.first}{{1.1}{\thepage }}
\newlabel{subsec:first.second}{{1.2}{\thepage }}
\newlabel{subsec:first.last}{{1.3}{\thepage }}
\newlabel{sec:second}{{2}{\thepage }}
\newlabel{subsec:second.first}{{2.1}{\thepage }}
\newlabel{subsec:second.second}{{2.2}{\thepage }}
\newlabel{subsec:second.last}{{2.3}{\thepage }}

Note that the ToC-writing still occurs at page shipout (and is therefore lost for pages not kept).

2
  • If you know the pages to be shipped out, a two-stage compilation with pagesel is also an option.
    – Werner
    Mar 12, 2015 at 0:58
  • Works well and this should deal with nearly all use cases (ultimately this is to become a highlighting style in latexdiff script, so it depends ultimately on the users of that script)
    – frederik
    Mar 12, 2015 at 8:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.