8
(pdfpages) How to write code that only affects some select pages of a PDF document
(linkage.ds8.zone)
submitted
4 days ago* (last edited 4 days ago)
by
LibreMonk@linkage.ds8.zone
to
c/tex_typesetting@lemmy.sdf.org
Suppose you feed a multi-page PDF into \includepdf
. If you only want pagecommand
or picturecommand
to take effect on some pages, you normally must split the construct up into multiple invocations. E.g.
\includepdf[pages=1], pagecommand={\doStuffOnPageOne}]{file.pdf}
\includepdf[pages=2-], pagecommand={\doStuffOnPagesAfterOne}]{file.pdf}
It gets ugly fast when there are some commands you want performed on every page, and some on select pages, because then you must write and maintain redundant code.
Fuck that. So here’s a demonstration of how to write code inside pagecommand
and picturecommand
that is page-specific:
\documentclass{article}
% Demonstrates use of the pdfpages package with page-by-page actions that are specific to select pages.
\usepackage{mwe} % furnishes example-image-a4-numbered.pdf
\usepackage{pdfpages}
\usepackage{pdfcomment}
\usepackage{ocgx2} % furnishes the ocg environment (PDF layers, but not really needed for this demo)
\usepackage{fancybox} % furnishes oval box
\usepackage{fontawesome} % furnishes \faWarning
\begin{document}
\makeatletter
\includepdf[pages=1-,pagecommand={%
% \makeatletter ← ⚠ does not work in this scope; must wrap the whole includepdf construct
\pdfcomment[icon=Note, hoffset=0.5\textwidth, voffset=5em]{%
(inside pagecommand, executing on every page)\textLF\textLF
\texttt{\textbackslash AM@page} variable: \AM@page\textLF\textLF
Side-note: the voffset option has no effect when the value is positive (5em in this case)%
}%
\ifthenelse{\AM@page = 1 \OR \AM@page = 2 \OR \AM@page = 12}{%
\pdfcomment[icon=Insert, hoffset=0.5\textwidth, voffset=-6em]{%
(inside pagecommand, affecting only pages 1, 2, and 12)\textLF\textLF
\texttt{\textbackslash AM@page} variable: \AM@page\textLF\textLF
Strangely, the voffset option only works if it is negative.%
}%
}{}
% \makeatother
}, picturecommand={%
\put(50,715){Inside the picture environment:}
\put(50,700){%
\begin{tabular}[t]{llp{0.6\textwidth}}
internal \texttt{\textbackslash @tempcnta} variable (useless): &\the\@tempcnta&\\
internal \texttt{\textbackslash @tempcntb} variable (useless): &\the\@tempcntb&\\
internal \texttt{\textbackslash AM@pagecnt} variable (useless): &\the\AM@pagecnt&\\
internal \texttt{\textbackslash AM@abs@page} variable (useless): &\AM@abs@page&\\
internal \texttt{\textbackslash AM@page} variable (interesting): &\AM@page & \faWarning Inside picturecommand, this number is 1 higher than the actual page number! But it’s correct inside pagecommand (see the annotation note to check).\\
internal \texttt{\textbackslash AM@pagecount} variable (interesting): &\AM@pagecount&\\%
\end{tabular}
% lastpage: \AM@lastpage% broken
\ifAM@firstpage
We might expect this to trigger on the 1st page, but it never does. Likely because the page counter is incremented before picturecommand is invoked. It would perhaps work in the pagecommand construct.
\fi
}
\put(500,770){% The ocg environment is irrelevant and unnecessary.. just here to demo PDF layers.
\begin{ocg}{section labels}{sl1}{on}\color{blue}
\Large\rotatebox{-45}{\setlength{\fboxsep}{6pt}\Ovalbox{Section~A}}
\end{ocg}}}]%
{example-image-a4-numbered.pdf}
\makeatother
\end{document}
One annoying limitation is that the last page and a penultimate page cannot have different behavior in the
picturecommand
option. I thought I was fucked for ½ a day. But hacked around that by using thepagecommand
and nesting\ifthenelse{\AM@page = (penultimate page №)}{\begin{picture}(0,0)\put(50,-50){…}…
inside the pagecommand. Makes me wonder what’s the point of having thepicturecommand
. There is apicturecommand*
which only executes on the 1st page, and apparently no equivalent forpagecommand
-- but we can test the internal variable anyway.