我想在使用 插入 PDF 之前测试它是否包含指定页面\includegraphicx[page=?]{filename.pdf}
。(通常指定不存在的页面会产生致命错误。)我该如何对 、 和 执行pdflatex
此xelatex
操作lualatex
?
梅威瑟:
\documentclass{article}
\usepackage{graphicx}
\usepackage{filecontents}
\begin{filecontents*}{\jobname page.pdf}
%PDF-1.1
1 0 obj <</Type /Catalog /Pages 2 0 R>>
endobj
2 0 obj <</Type /Pages /Kids [3 0 R] /Count 1>>
endobj
3 0 obj<</Type /Page /Parent 2 0 R /Resources 4 0 R /MediaBox [0 0 70 50] /Contents 6 0 R>>
endobj
4 0 obj<</Font <</F1 5 0 R>>>>
endobj
5 0 obj<</Type /Font /Subtype /Type1 /BaseFont /Helvetica>>
endobj
6 0 obj
<</Length 36>>
stream
BT /F1 10 Tf 20 20 Td (Page 1)Tj ET
endstream
endobj
xref
0 9
0000000000 65535 f
0000000009 00000 n
0000000056 00000 n
0000000111 00000 n
0000000210 00000 n
0000000248 00000 n
0000000315 00000 n
trailer <</Size 7/Root 1 0 R>>
startxref
398
%%EOF
\end{filecontents*}
% \includepdfifhaspage{filename.pdf}{page}
\newcommand{\includepdfifhaspage}[2]{%
\iftrue % <- what test should go here?
\includegraphics[page=#2]{#1}%
\else
% do nothing
\fi
}
\begin{document}
% insert page one of pdf:
\includepdfifhaspage{\jobname page.pdf}{1}
% insert nothing, since there is no page 2:
\includepdfifhaspage{\jobname page.pdf}{2}
\end{document}
答案1
我从包 pdfpages 源代码中提取了方法,该方法本身似乎是从 graphicx/pdftex.def 获取的。
我最初查看了 pdfpages 文档,但没有找到用户级界面。以下是其源代码中的相关文档:
% Unfortunately, |\pdflastximagepages| is not updated if |\includegraphics|
% is used repeatedly on the same file. Heiko is aware of this and will provide
% a solution in pdftex.def. Until then we will use the original graphicx's filename
% from |\Gread@@pdftex|.
%
% \def\AM@getpagecount{%
% \setbox\@tempboxa=\hbox{\includegraphics{\AM@currentdocname}}%
% \edef\AM@pagecount{\the\AM@lastsavedimageresourcepages}%
% }
注意:pdfpages 可能应该在其 中使用draft
选项。这就是我在这里所做的。\includegraphics
\AM@getpagecount
编辑:在这个答案的第一个版本中,我太容易忽略了上述评论,并且修剪了太多的代码pdfpages.sty
。
\documentclass{article}
\usepackage{graphicx}
\usepackage{filecontents}
\begin{filecontents*}{\jobname page.pdf}
%PDF-1.1
1 0 obj <</Type /Catalog /Pages 2 0 R>>
endobj
2 0 obj <</Type /Pages /Kids [3 0 R] /Count 1>>
endobj
3 0 obj<</Type /Page /Parent 2 0 R /Resources 4 0 R /MediaBox [0 0 70 50] /Contents 6 0 R>>
endobj
4 0 obj<</Font <</F1 5 0 R>>>>
endobj
5 0 obj<</Type /Font /Subtype /Type1 /BaseFont /Helvetica>>
endobj
6 0 obj
<</Length 36>>
stream
BT /F1 10 Tf 20 20 Td (Page 1)Tj ET
endstream
endobj
xref
0 9
0000000000 65535 f
0000000009 00000 n
0000000056 00000 n
0000000111 00000 n
0000000210 00000 n
0000000248 00000 n
0000000315 00000 n
trailer <</Size 7/Root 1 0 R>>
startxref
398
%%EOF
\end{filecontents*}
\makeatletter
% FIX FROM pdfpages.sty TO FIX ISSUE WITH \pdflastximagepages
\let\AM@Gread@@pdftex\Gread@@pdftex
\renewcommand*{\Gread@@pdftex}[1]{%
\xdef\AM@currentdocname@fix{#1}%
\AM@Gread@@pdftex{#1}%
}
\makeatother
\makeatletter
\newcommand{\includepdfifhaspage}[2]{%
\setbox\@tempboxa=\hbox{\includegraphics[draft]{#1}}%
\pdfximage{\AM@currentdocname@fix}%
\ifnum #2>\z@
\unless\ifnum #2>\pdflastximagepages
\includegraphics[page=#2]{#1}%
\fi
\fi
}
\makeatother
\begin{document}
% insert page one of pdf:
\includepdfifhaspage{\jobname page.pdf}{1}
% insert nothing, since there is no page 2:
\includepdfifhaspage{\jobname page.pdf}{2}
\end{document}
在上面,我没有处理 luatex 上下文。最终,最好的办法是pdfpages
让包生成用户控制的\pdfhaspage
布尔切换。我没有从其文档中感觉到它已经存在。
编辑以实际使用包pdfpages
以便其驱动程序也能处理 xetex、luatex。
\documentclass{article}
\usepackage{graphicx}
\usepackage{pdfpages}
\usepackage{filecontents}
\begin{filecontents*}{\jobname page.pdf}
%PDF-1.1
1 0 obj <</Type /Catalog /Pages 2 0 R>>
endobj
2 0 obj <</Type /Pages /Kids [3 0 R] /Count 1>>
endobj
3 0 obj<</Type /Page /Parent 2 0 R /Resources 4 0 R /MediaBox [0 0 70 50] /Contents 6 0 R>>
endobj
4 0 obj<</Font <</F1 5 0 R>>>>
endobj
5 0 obj<</Type /Font /Subtype /Type1 /BaseFont /Helvetica>>
endobj
6 0 obj
<</Length 36>>
stream
BT /F1 10 Tf 20 20 Td (Page 1)Tj ET
endstream
endobj
xref
0 9
0000000000 65535 f
0000000009 00000 n
0000000056 00000 n
0000000111 00000 n
0000000210 00000 n
0000000248 00000 n
0000000315 00000 n
trailer <</Size 7/Root 1 0 R>>
startxref
398
%%EOF
\end{filecontents*}
\makeatletter
\newcommand{\includepdfifhaspage}[2]{%
\begingroup
\edef\AM@currentdocname{#1}%
\IfFileExists{\AM@currentdocname}{%
\AM@getpagecount
\global\let\David@temp\AM@pagecount
\endgroup
\ifnum #2>\z@
\ifnum #2>\David@temp\relax
% NO PAGE #2 IN FILE #1\par
\else
\includegraphics[page=#2]{#1}%
\fi
\else
% NO PAGE #2 IN FILE #1\par
\fi}%
{\endgroup}% file does not exist
}
\makeatother
\usepackage{xinttools}
\begin{document}
% insert page one of pdf:
1: \includepdfifhaspage{\jobname page.pdf}{1}XXXX\par
% insert nothing, since there is no page 2:
2: \includepdfifhaspage{\jobname page.pdf}{2}XXXX\par
% Test plus complet
\xintFor #1 in {-1, 0, 1, 2, 3}\do {%
#1: \includepdfifhaspage{\jobname page.pdf}{#1}XXXX\par
}
\end{document}
警告:使用 xetex,包含的 pdf 占用的空间是空白的。此外,在更广泛的测试中,我包含了一个十页的 pdf,xelatex 运行似乎正确结束,但日志以错误结束并且没有生成 pdf。这些示例使用来自 OP 的 pdf 数据filecontents*
,也许 xetex 不喜欢那里的某些东西。
无论如何,这只是一个.pdf
使用包的一些内部功能的 hack(需要在文件名中使用扩展名)pdfpages
。如果该包提供了它,那就最好了。
附注:简短的阅读给我留下的印象是,一些不受保护的行尾空格可能会潜入 pdfpages 代码中。没有调查,我可能在胡说八道。
编辑在上面使用包的代码pdfpages
中
\includegraphics[page=#2]{#1}%
应该读作
\includepdf[pages=#2]{#1}%
现在已pdfpages
实际使用。
最后说明在对其他一些文件进行额外测试时,我没有遇到任何问题xetex
。因此,这可能是xetex
OP 的明确 pdf 文件中存在一些令人不满意的地方。