5

I need to use a command of a 3rd-party package, which inserts multiple pages of content into my document. Is there a way to tell LaTeX to ignore the last of these pages? E.g. the command inserts 3 pages, but I only want the first two.

Equivalently, can I tell LaTeX to simply drop the current page, i.e. to go back to the last hard page break (\newpage) and forget all the content that has been added since then?

Obviously I can easily remove the page from the resulting PDF using external postprocessing, but I'd rather do it directly in the document if that's possible.

Note that I cannot modify the 3rd-party package and that not using the command from that package is not an acceptable solution.

  • What kind of content are you inserting? PDF, by any chance? – Masroor Oct 31 '13 at 13:14
  • @MMA: The content inserted by the 3rd-party command is dynamically generated LaTeX. – Florian Brucker Oct 31 '13 at 13:45
  • If there is not \newpage at the end you can use atbegshi to discard the last page before it is shipout. – Ulrike Fischer Oct 31 '13 at 16:02
  • Do you always know how many pages it will be that will be inserted? Does the 3rd-party command always insert full pages, or just content amounting to a number of pages? – Werner Oct 31 '13 at 16:58
  • @Werner: Yes, I know the number of pages beforehand. – Florian Brucker Nov 2 '13 at 12:07
3

If you know the number of pages will be included with the 3rd-party package/command, then you can issue a number of nested commands using atbegshi to discard a specific page. The following MWE provides \removepage{<num>} that will remove a page <num> from the current page:

enter image description here

\documentclass{article}
\usepackage{atbegshi,multido,graphicx}% http://ctan.org/pkg/{atbegshi,multido,graphicx}
\makeatletter
\newcommand{\removepage}[1]{%
  \def\@drop@this@page{\AtBeginShipoutDiscard}%
  \multido{\iA=1+1}{#1}{%
    \expandafter\gdef\expandafter\@drop@this@page\expandafter%
      {\expandafter\AtBeginShipoutNext\expandafter{\@drop@this@page}}%
    }%
  \@drop@this@page%
}
\newcommand{\magiccommand}{% Inserts 9 pages
  \multido{\iA=1+1}{9}{\clearpage\centering\scalebox{40}{\iA}}}

\makeatother
\begin{document}
\removepage{3}%
\magiccommand% 3rd-party command for including a bunch of pages
\end{document}

Note that using this method will discard the page completely (including the header/footer), which could contain an incremented page number. One should correct for this if needed, perhaps as part of \removepage.

If \magiccommand only inserts text that is formatted together with your current document (rather than including stand-alone full pages), then you can just issue \AtBeginShipoutNext{\AtBeginShipoutDiscard} after the command, which should remove the final page.

  • Thank you, Werner, that is exactly what I was looking for. – Florian Brucker Nov 2 '13 at 12:08
3

Without much information about your third party application (I understand that there might be some official secrecy involved, no problem), I assume that you have some control over the names of the (LaTeX) files generated. (If you do not have control over the names of generated files, please let me know. We can put them in some predecided LaTeX files during runtime.)

The solution below is Linux based. Should you use any other OS, I can not be of much help. For the system to work, you need pdflatex, pdftk, awk and pdfinfo (part of package xpdf), to be installed. Please refer to your specific distribution of Linux on how to install them. We need to use these, since I failed to find a way to exclude the last page without actual page rendering.

I understand that you had some aversion to external preprocessing. But whatever processing is done in the solution provided are very transparent to the end user and called from inside LaTeX.


Anyway, this is how the solution works.

  1. The defined macro \insertfromthirdpartyapplicationwithoutlastpage needs only one argument. Name of the LaTeX (input, third party generated) file, without the .tex extension, to be inserted. All the operations mentioned below are contained inside this macro.
  2. When the main file is compiled using latex (or pdflatex), it compiles your input file three times using pdflatex to get an all-references-resolved .pdf file. Should there be any BibTeX or any other LaTeX frield involoved, we need to insert those commands as well. Please do not forget to use the -shell-escape option for the main file. Otherwise the internal \write18 will not be executed for security purpose. Please see here for details.
  3. Then the macro generates a shell script (\jobname.bash) to save all but the last page from the generated pdf file. Again, I found that there is no command line utility to readily exclude the last page. So, this script actually counts the number of pages and then excludes the last one.
  4. The macro makes the above shell script executable.
  5. The macro executes the script. Once executed, this script will generate a .pdf file with a name <input file>minuslastpage.pdf.
  6. The macro uses pdfpages to insert all the pages from the above <input file>minuslastpage.pdf file.

I have provide below three .tex files for your immediate testing. The first one can be saved with any name you like. The last two should be saved with the names as indicated.


Main file

Compile this using the (pdf)latex -shell-escape command. You should get a five page output (1 page from main file, 2 minus 1 from inserted file, 1 page from main file, 2 minus 1 from inserted file, 1 page from main file).

\documentclass{article}

\usepackage{pdfpages}

\def\insertfromthirdpartyapplicationwithoutlastpage#1{%
  % Compile your generated third party LaTeX file three times to get the pdf output
  \immediate\write18{pdflatex #1.tex}
  \immediate\write18{pdflatex #1.tex}
  \immediate\write18{pdflatex #1.tex}
  % Generate a shell script (\jobname.bash) to save all but last page from generated pdf file
  \newwrite\shellscript
  \immediate\openout\shellscript=\jobname.bash
  \immediate\write\shellscript{pagecount=`pdfinfo #1.pdf | grep 'Pages:' | awk '{print $2}'`}
  \immediate\write\shellscript{pagecount=$(( $pagecount - 1 ))}
  \immediate\write\shellscript{pdftk A=#1.pdf cat A1-$pagecount output #1minuslastpage.pdf}
  \immediate\closeout\shellscript
  % Make the generated shell script executable
  \immediate\write18{chmod +x ./\jobname.bash}
  % Execute the shell script to remove the last page from pdf file
  \immediate\write18{. ./\jobname.bash}
  % Include the pdf file with last page removed
  \includepdf[pages=-]{#1minuslastpage.pdf}
}

\begin{document}

Some opening text.

\insertfromthirdpartyapplicationwithoutlastpage{insertfileone}

Middle text

\insertfromthirdpartyapplicationwithoutlastpage{insertfiletwo}

Closing text.

\end{document}

Input LaTeX files for testing (in lieu of your third party generated file)

insertfileone.tex

\documentclass{article}

\usepackage{lipsum}

\begin{document}

\lipsum[1-10]

\end{document}

insertfiletwo.tex

\documentclass{article}

\usepackage{lipsum}

\begin{document}

\lipsum[11-20]

\end{document}

Very different from the above solution, we can think of a solution based on Makefile in a completely different way.

  • Thanks! I'll go with Werner's suggestion as it seems more simple in my case, but your's has some nice ideas that might come in handy at a later time. – Florian Brucker Nov 2 '13 at 12:09
  • @FlorianBrucker I was also impressed by the simplicity of Werner's solution. But how did you get number of pages that will be included with the 3rd-party package? This is where I got stuck when I tried to mentally picture the implementation. Perhaps you know the number of pages in your case. Or may be I am missing something. – Masroor Nov 2 '13 at 15:28
  • The number of inserted pages is fixed for every document. So I just run the command once, count the pages and remove the ones I don't need. – Florian Brucker Nov 3 '13 at 18:01
  • @FlorianBrucker If you know the number of pages beforehand, and do not have many documents to insert, then that solution is best for you. – Masroor Nov 4 '13 at 0:17

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.