Hatena::ブログ(Diary)

アセトアミノフェンの気ままな日常

2015-07-25

いろいろな PDF ページ数カウント(続き)

かなり前の記事で「PDF ページ数カウントを種々のプログラムのバッチ処理で実装」という実験を行った。今回は、そんなことをせずに PDF のページ数をコマンドライン一発で取得する方法を考える。

Ghostscript によるカウント

 $ gs -q -dNODISPLAY -c "(hoge.pdf) (r) file runpdfbegin pdfpagecount = quit"

これは以前の記事と本質的には変わらない。hoge.pdf は /path/to/hoge.pdf のように絶対パスでも構わないが、その区切りは必ず / でなければならない(Windows でよく見る \ は不可)。もちろん「gs」というコマンド名は Windows では gswin32c や gswin64 かもしれないし rungs かもしれないが、どの環境でも使える。

QPDF によるカウント

 $ qpdf --show-npages hoge.pdf

QPDF は PDF ファイルの構造変換を行うコマンドラインプログラムで、PDF の中身を覗いてみたい人向けのツールである。これを使うとページ数がわかる。こちらは絶対パスの区切りは / でも \ でも良いようだ。

pdfiumdraw によるカウント

 $ pdfiumdraw --output-page input.pdf

最近あべのりさんに作っていただいてブログでも紹介した、おなじみ PDFium ベースの PDF 操作ツール。これも、ヘルプメッセージに出ていないが実は PDF のページ数を取得できる(実際、TeX2img for Windows は複数ページ処理対応でかつて pdfinfo を使っていたが、pdfiumdraw の同梱で pdfiumdraw を使ったページ数取得に切り替えている)。絶対パスでも問題なし。

おまけ:pdfTeX によるカウント「pdftexpdfpages.bat」

pdfTeX を使っている場合、\pdfximage で読み込んだ(=画像オブジェクトを生成した)PDF ファイルのページ数を \pdflastximagepages で表示することができる。このことを応用して無理やり pdfTeX による PDF ページ数カウントをバッチファイルで実行できるようになる。

@echo off
echo pdftexpdfpages v0.1 (2015-07-25)
setlocal
set FROMDIR=%~dp1
set FROM=%~n1
set COUNTTEMP=counttemp
if "%FROM%"=="" echo Usage: pdftexpdfpages in.pdf
if not exist "%FROMDIR%%FROM%.pdf" exit /B
if not "%TEMP%"=="" cd "%TEMP%"
copy "%FROMDIR%%FROM%.pdf" "%COUNTTEMP%.pdf" 1>nul
echo \pdfoutput=1 >%COUNTTEMP%-pages.tex
echo \pdfximage{%COUNTTEMP%.pdf} >>%COUNTTEMP%-pages.tex
echo \newwrite\counttemp >>%COUNTTEMP%-pages.tex
echo \immediate\openout\counttemp=%COUNTTEMP%-pages.txt\relax >>%COUNTTEMP%-pages.tex
echo \immediate\write\counttemp{\the\pdflastximagepages} >>%COUNTTEMP%-pages.tex
echo \immediate\closeout\counttemp >>%COUNTTEMP%-pages.tex
echo \shipout\vbox{}\end >>%COUNTTEMP%-pages.tex
pdftex -no-shell-escape -interaction=batchmode %COUNTTEMP%-pages.tex 1>nul
del %COUNTTEMP%-pages.tex %COUNTTEMP%-pages.log %COUNTTEMP%-pages.pdf
set /P NUM=<"%COUNTTEMP%-pages.txt"
del "%COUNTTEMP%.pdf" "%COUNTTEMP%-pages.txt"
echo Number of pages: %NUM%

この場合、以下に示す内容の counttemp-pages.tex というファイルを pdftex でタイプセットすることで「真っ白な PDF ファイルを出力する間に、\immediate\write で counttemp-pages.txt というテキストに元の PDF ファイルのページ数を吐き出す」という仕組みである。

\pdfoutput=1 
\pdfximage{counttemp.pdf} 
\newwrite\counttemp 
\immediate\openout\counttemp=counttemp-pages.txt\relax 
\immediate\write\counttemp{\the\pdflastximagepages} 
\immediate\closeout\counttemp 
\shipout\vbox{}\end 

誰得感ハンパないが、pdfTeX の文書中にページ数を表示したければ \pdflastximagepages が便利かもしれない。