2

My question is related to and in continuation to Compiling only a page range or page selection

I would like to output only the last page (or last two/three pages) without knowing the total number of pages in advance. As in the above referred question, compilation should happen for the entire document with all the counters, page number on footers intact.

Is it possible to say something like \keeppages{-1} (from the accepted answer to the above question - https://tex.stackexchange.com/a/96258/26682) and that should do for the last page? I toyed with pageslts package but I dont see any way to achieve what I want.

Any ideas?

PS: the question is self explanatory ... a MWE is not really needed here.

  • I have a solution that provides the means to use \keeppages{-3,-1} to keep only the third-to-last and final page (say), but any references to content on the discarded pages will be lost. Is this a sufficient solution? – Werner Jan 19 '18 at 19:57
  • @Werner sure that is acceptable. in fact, the original question and solution also have the same conditions – magguu Jan 20 '18 at 1:27
  • @Werner could you please post your solution of enabling \keeppages{-3,-1}? – magguu Jan 21 '18 at 17:32
  • Sorry, done. – Werner Jan 21 '18 at 17:43
1

Here is a modification to Compiling only a page range or page selection that allows you to use negative numbers that counts from the last page. So, for example, you could use

\discardpages{-2,-1}

to remove the last two pages, or

\keeppages{-3,-1}

to only keep the third-to-last and final page. The adaptation relies of lastpage to place a \label{LastPage} on the last page and use the page number in calculations (thanks to refcount).

\documentclass{article}

\usepackage{lipsum,atbegshi,etoolbox}
\usepackage{lastpage,refcount}

\makeatletter
\newcommand{\discardpages}[1]{% \discardpages{<csv list>}
  \xdef\discard@pages{#1}% Store pages to discard
  \AtBeginShipout{% At shipout, decide whether to discard page/not
    \renewcommand*{\do}[1]{% How to handle each page entry in csv list
      \ifnum##1<0
        \ifnum\value{page}=\numexpr\getpagerefnumber{LastPage}+##1+1\relax
          \AtBeginShipoutDiscard% Discard page/not
          \gdef\do####1{}% Do nothing further
        \fi
      \else% ##1 >= 0
        \ifnum\value{page}=##1\relax%
          \AtBeginShipoutDiscard% Discard page/not
          \gdef\do####1{}% Do nothing further
        \fi
      \fi
    }%
    \expandafter\docsvlist\expandafter{\discard@pages}% Process list of pages to discard
  }%
}

\newif\ifkeeppage
\newcommand{\keeppages}[1]{% \keeppages{<csv list>}
  \xdef\keep@pages{#1}% Store pages to keep
  \AtBeginShipout{% At shipout, decide whether to discard page/not
    \keeppagefalse%
    \renewcommand*{\do}[1]{% How to handle each page entry in csv list
      \ifnum##1<0
        \ifnum\value{page}=\numexpr\getpagerefnumber{LastPage}+##1+1\relax
          \keeppagetrue% Page should be kept
          \gdef\do####1{}% Do nothing further
        \fi
      \else% ##1 >= 0
        \ifnum\value{page}=##1\relax%
          \keeppagetrue% Page should be kept
          \gdef\do####1{}% Do nothing further
        \fi
      \fi
    }%
    \expandafter\docsvlist\expandafter{\keep@pages}% Process list of pages to keep
    \ifkeeppage\else\AtBeginShipoutDiscard\fi% Discard page/not
  }%
}
\makeatother

%\discardpages{-2,-1}
\keeppages{-3,-1}% Keep these pages.

\begin{document}

\sloppy\lipsum[1-50]\lipsum[1-50]\lipsum[1-50]\lipsum[1-50]\lipsum[1-50]

\end{document}

The LastPage reference will have to settle in order to be effective. So, you'll have to compile at least twice with every change in this \label location (or at the first go).

No further testing was done to see whether atveryend might be required.

  • ...as in the previous solution, this does not preserve cross-references for pages that are removed. – Werner Jan 21 '18 at 17:43
  • perfect! However in my real document, I had reassigned LastPage counter to one (or more, dynamically determined) lesser and the actual last page (or pages) are ununmbered and unreferenced. I tried setting a new temporary counter to keep track of these extra pages and then do this \ifnum\value{page}=\numexpr\getpagerefnumber{LastPage}+\value{unnumberedpages}+##1+1 in \keeppages. However \value{unnumberedpages} seems to only be set at the initialized value of 0. Maybe because \keeppages{1,-1} is called before \begin{document}. Is there a way out? – magguu Jan 22 '18 at 11:59
1

The problem with this approach is that TeX's model is built sequentially out of "boxes" and "glue." To figure out what's on the 17th page, the TeX system needs to layout the previous 16 pages. The question you linked defines some macros that remove pages after pdf generation, but those pages are still generated.

The simplest manual way is to open your generated pdf in a viewer and use the "Print to PDF" option, specifying a page range. If you want to do this in an automated way, that would be more platform-dependent.

  • In fact, fully generating the pages and then discarding them is the goal ... so that one doesn't have to go through the rigmarole of post-processing the PDF file with some other software or subject to pdfpages type hack of recompiling. – magguu Jan 20 '18 at 1:33
  • @magguu Ah, I see. Werner's solution is probably the best though. You'd think there would be a package that would solve this kind of thing; it doesn't seem like an uncommon thing to want. – Walter Mays Jan 20 '18 at 4:26
  • @WalterMays: You can try this code. It uses an alternative method to establish a LastPage "reference" (thanks to atveryend). You can change all references to LastPage to something that suits you better. It's just another option. – Werner Jan 23 '18 at 5:27
  • @Werner I presume you were replying to this tex.stackexchange.com/questions/411180/… .. I followed your excellent suggestion with one change ... I defined a new token called EndPage to do the shovel work for \keeppages, while LastPage is left undisturbed. And it does work very well. Thanks a lot! – magguu Jan 23 '18 at 8:09
  • @magguu: Indeed. Glad you found it. – Werner Jan 23 '18 at 17:07

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.