是否有可能获取 LaTeX 文档中的外部 PDF 文件的总页数?
假设在保存我的 LaTeX 文件的同一目录中存在一个test.pdf
包含 8 页的 PDF 文件。这是我的基本方法:
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{xparse}
\DeclareDocumentCommand \pdfnumberofpages { m } {
% Do some magic
}
\begin{document}
\texttt{test.pdf}: \pdfnumberofpages{test.pdf} pages
\end{document}
生成的文档应该包含
test.pdf:8页
我知道这应该是可能的(pdfpages
必须做这样的事情),但我不知道如何实现它。
答案1
\tracingmacros1
使用选项之后pages=last-1
,好像pdfpages
使用了功能来pdf(la)tex
获取数字。
\documentclass{minimal}
\begin{document}
\pdfximage{test-29.pdf}
\the\pdflastximagepages\ pages
\end{document}
答案2
pdfTeX、LuaTeX
\pdflastximageages
,参见回答符号 1。
评论:
\pdfximage
不能在 DVI 模式下使用。
LuaTeX
不幸的是,LuaTeX 一直在不断更改其接口。
\luatexluaescapestring
已重命名为\luaescapestring
,并且库epdf
已被库 取代pdfe
。 以下示例是使用 1.15.0 开发和测试的。
也可以通过 Lua 库检索页面数量pdfe
:
\documentclass{article}
\newcommand*{\pdfnumberofpages}[1]{%
\directlua{%
local doc = pdfe.open("\luaescapestring{#1}")
local pages
if (doc) then
pages = pdfe.getnofpages(doc)
else
pages = 0
end
tex.write(pages)
}%
}
\begin{document}
Number of pages: \pdfnumberofpages{test.pdf}
\end{document}
评论:
- 如果该文档不存在,宏
\pdfnumberofpages
将返回零。 \pdfnumberofpages
是完全可扩展的。因此,它可以用于计数器分配,可以写入文件,...- 它也可以在 DVI 模式下工作。
较旧的 LuaTeX
也可以通过 Lua 库检索页面数量epdf
:
\documentclass{article}
\newcommand*{\pdfnumberofpages}[1]{%
\directlua{%
local doc = epdf.open("\luatexluaescapestring{#1}")
local pages
if (doc) then
pages = doc:getCatalog():getNumPages()
else
pages = 0
end
tex.write(pages)
}%
}
\begin{document}
Number of pages: \pdfnumberofpages{test.pdf}
\end{document}
评论:
- 如果该文档不存在,宏
\pdfnumberofpages
将返回零。 \pdfnumberofpages
是完全可扩展的。因此,它可以用于计数器分配,可以写入文件,...- 它也可以在 DVI 模式下工作。
特克斯
XeTeX 提供\XeTeXpdfpagecount
:
\documentclass{article}
\newcommand*{\numberofpages}[1]{%
\the\XeTeXpdfpagecount"#1" %
}
\begin{document}
Number of pages: \numberofpages{test.pdf}
\end{document}
评论:
- 如果该文件不存在,结果为零。
- 此版本也可完全扩展。
概括
以下示例将不同的版本放在一起:
\documentclass{article}
\usepackage{ifpdf}
% XeTeX check
\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname XeTeXpdfpagecount\endcsname\relax
% pdfTeX check
\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname pdflastximagepages\endcsname\relax
\newcommand*{\numberofpages}[1]{%
0%
\errmessage{\noexpand\numberofpages is unsupported for this driver}%
}%
\else
% Definition for pdfTeX
\ifpdf
\newcommand*{\numberofpages}[1]{%
\pdfximage{#1}%
\the\pdflastximagepages
}%
\else
\newcommand*{\numberofpages}[1]{%
0%
\errmessage{\noexpand\numberofpages is unsupported in DVI mode}%
}%
\fi
\fi
% LuaTeX check
\typeout{LuaTeX check}
\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname directlua\endcsname\relax
\else
\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname luaescapestring\endcsname\relax
\typeout{luaescapestring is undefined}%
\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname luatexluaescapestring\endcsname\relax
\typeout{luatexluaescapestring is undefined}%
\else
\newcommand*{\LuaEscapeString}{}%
\let\LuaEscapeString\luatexluaescapestring
\fi
\else
\newcommand*{\LuaEscapeString}{}%
\let\LuaEscapeString\luaescapestring
\fi
\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname LuaEscapeString\endcsname\relax
\else
% Definition for newer LuaTeX
\ifnum0\directlua{if pdfe then tex.write(1)end}=1 %
\renewcommand*{\numberofpages}[1]{%
\directlua{%
local doc = pdfe.open("\LuaEscapeString{#1}")
local pages
if (doc) then
pages = pdfe.getnofpages(doc)
else
pages = 0
end
tex.write(pages)
}%
}%
\else
% Definition for older LuaTeX
\ifnum0\directlua{if epdf then tex.write(1)end}=1 %
\renewcommand*{\numberofpages}[1]{%
\directlua{%
local doc = epdf.open("\LuaEscapeString{#1}")
local pages
if (doc) then
pages = doc:getCatalog():getNumPages()
else
pages = 0
end
tex.write(pages)
}%
}%
\fi
\fi
\fi
\fi
\else
% Definition for XeTeX
\newcommand*{\numberofpages}[1]{%
\the\XeTeXpdfpagecount"#1" % space ends the file name scanning
}%
\fi
\begin{document}
Number of pages: \numberofpages{test.pdf}% Should be different from \jobname.pdf
\end{document}
评论:
- 如果将
\newcommand
和\renewcommand
替换为\def
构造,则定义在纯 TeX 中也能起作用。(\luatexluaescapestring
可能可用\luaescapestring
或必须通过启用tex.enableprimitives
。) - 如果不支持检索页数,则会抛出错误消息。
答案3
使用当前的 l3graphics(当前处于 l3experimental 中),您可以用来\graphics_get_pagecount:nN
检索页数,然后打印它或在命令中将其用作页码\includegraphics
。\graphics_get_pagecount:nN
适用于所有引擎,也适用于 dvi 模式下的 LaTeX。
\documentclass{article}
\usepackage{l3graphics}
\usepackage{graphicx}
\begin{document}
\ExplSyntaxOn
\graphics_get_pagecount:nN {example-image-a4-numbered.pdf}\l_tmpa_tl
\l_tmpa_tl
\includegraphics[scale=0.5,page=\l_tmpa_tl]{example-image-a4-numbered.pdf}
\ExplSyntaxOff
\end{document}
答案4
如果有人对将页数写入文件的单行命令感兴趣test.pdf.pages
(如果test.pdf
是所讨论的 PDF 文件),则以下内容(基于接受的答案) 正在命令提示符在 Windows 10 上使用 MikTeX:
pdflatex "\documentclass{minimal}\nofiles\def\pdffile{test.pdf}\begin{document}\pdfximage{\pdffile}\newwrite\myfile\immediate\openout\myfile=\pdffile.pages\makeatletter\immediate\write\myfile{\the\pdflastximagepages}\makeatother\immediate\closeout\myfile\end{document}"
连同一起test.pdf.pages
,会生成2个不需要的文件:minimal.pdf
和minimal.log
,编译后可以删除它们。