Include multi-page PDF

Posted on August 19, 2020

As an academic, I often have to write letters and grant applications where I need to need to prepare a single PDF which includes the letter or the grant application with one of more research papers “attached” at the end. In principle, I could generate the letter/grant separately and use a tool such as qpdf to merge multiple files into a single file. But I find it much easier to generate everything from a single tex file.

To do so, I need a macro to include all the pages of the PDF. ConTeXt provides three commands to include multipage external PDFs:

but none of them really fit my needs. First, they place the content as a layer on the current page (so the headers and footer of the current document are still shown). Second, I need to know the number of pages in the PDF. In principle, I could circumvent these limitation, but in the end it was much simpler to just define a new macro \includePDF which simply includes all the pages of the PDF:

\startluacode
  includePDF = function(file)
  local document = lpdf.epdf.load(file)
  local pages = #document.pages
    for i=1,pages do
      context.startTEXpage()
      context.externalfigure({file}, {page=i})
      context.incrementcounter{"userpage"}
      context.stopTEXpage()
    end
  end


  interfaces.implement {
      name      = "includePDF",
      arguments = { "string" },
      actions   = includePDF,
  }
\stopluacode

\unprotect
\unexpanded\def\includePDF%
    {\dosingleempty\include_PDF}

\def\include_PDF[#1]%
    {\clf_includePDF{#1}}
\protect

The code is almost self explanatory. We load the PDF file with the specified name, check how many pages it has, and then manually include it page-by-page.

Now I can include a multipage PDF using:

\includePDF[filename]

That was simple!

Henri Menke explained in the comment below that the same macro could have been written at the TeX end as well:

\unexpanded\def\includePDF%
    {\dosingleempty\doincludePDF}

\def\doincludePDF[#1]%
    {\getfiguredimensions[#1]%
     \dorecurse{\noffigurepages}
        {\startTEXpage
            \externalfigure[#1][page=\recurselevel]
         \stopTEXpage}}

This entry was posted in Luatex and tagged externalfigure, include.