pdfTeX, LuaTeX
\pdflastximageages, see the answer of Symbol 1.
Remarks:
\pdfximage cannot be used in DVI mode.
LuaTeX
Unhappily, LuaTeX is constantly changing its interfaces.
\luatexluaescapestring was renamed to \luaescapestring and
the library epdf was replaced by the library pdfe.
The following example was developed and tested with 1.15.0.
The number of pages can also be retrieved via the pdfe Lua library:
\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}
Remarks:
- If the document does not exists, the macro
\pdfnumberofpages returns zero.
\pdfnumberofpages is full expandable. Therefore it can be used in
counter assignments, it can be written to a file, ...
- It also works in DVI mode.
Older LuaTeX
The number of pages can also be retrieved via the epdf Lua library:
\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}
Remarks:
- If the document does not exists, the macro
\pdfnumberofpages returns zero.
\pdfnumberofpages is full expandable. Therefore it can be used in
counter assignments, it can be written to a file, ...
- It also works in DVI mode.
XeTeX
XeTeX provides \XeTeXpdfpagecount:
\documentclass{article}
\newcommand*{\numberofpages}[1]{%
\the\XeTeXpdfpagecount"#1" %
}
\begin{document}
Number of pages: \numberofpages{test.pdf}
\end{document}
Remarks:
- If the file does not exists, the result is zero.
- Also this version if full expandable.
Summary
The following example puts the different versions together:
\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}
Remarks:
- If the
\newcommand and \renewcommand are replaced by \def constructs, then the definition also works in plain TeX. (\luatexluaescapestring might be available as \luaescapestring or has to be enabled via tex.enableprimitives.)
- If the retrieval of the number of pages is not supported, an error message
is thrown.