最終更新:2017-04-11 (火) 19:16:18 (555d)

チュートリアル

チュートリアル/PDFの操作と編集

デファクトスタンダードの PDF

PDF ファイルを扱う機会が増えました。
政府や自治体、企業や団体の配布する資料の形式では、 もともと Word で作成ファイル等を PDF へ変換したものなどが多く見受けられます。
別のコンピュータユーザから文書をやりとりするという時にも PDF が頻繁に使われています。

PDF は一度作成するとそれを編集するための術が減少します。
文書作成ソフトで作成した、そのソフト独自の形式を一度 PDF に変換してしまうと、 もとの形式が失われて、文書構成要素の位置情報しか残らないために再編集性がなくなります。

しかし、ある程度は PDF 文書を編集したい物です。
そこで、コンソールから使える PDF 操作・編集ツールを紹介します。
GUI による編集ツールも沢山登場してきましたが, プラットフォームに依存しない,一般的な話をします.

Xpdf Utilities

Glyph & Cog, LLC. による PDF ビューアー。
次のツール (Xpdf Utilities) が 含まれています。

pdffonts
PDFのフォント情報を表示する
pdfinfo
PDF のPDF文書情報を表示する
pdftops
PDFを Postscript に変換する
pdftotext
PDF を ASCII テキストに変換する。 Unicode エンコーディングされていないと正常に変換される保証はない。
pdftoppm
PDF を PPM 形式の画像に変換する。
pdfimages
PDF 文書中の画像をすでに存在するディレクトリに抽出する。
xpdf
PDFファイルを閲覧する

pdffonts

Xpdf Utilities に含まれる PDF のフォント情報を表示する プログラム。
Xpdf の設定ファイルを 適切に設定することにより日本語等の TrueType フォントなどの 情報も表示させることが出来る。
Xpdf で日本語が表示できるように ~/.xpdfrc を編集する。

vi ~/.xpdfrc
cidToUnicode Adobe-Japan1 /usr/local/share/xpdf/japanese/Adobe-Japan1.cidToUnicode
unicodeMap ISO-2022-JP /usr/local/share/xpdf/japanese/ISO-2022-JP.unicodeMap
unicodeMap EUC-JP /usr/local/share/xpdf/japanese/EUC-JP.unicodeMap
unicodeMap Shift-JIS /usr/local/share/xpdf/japanese/Shift-JIS.unicodeMap
cMapDir Adobe-Japan1 /usr/local/share/xpdf/japanese/CMap
toUnicodeDir /usr/local/share/xpdf/japanese/CMap
fontFile Ryumin-Light-Identity-H /usr/share/texmf-dist/fonts/truetype/public/ipaex/ipaexm.ttf
fontFile GothicBBB-Medium-Identity-H /usr/share/texmf-dist/fonts/truetype/public/ipaex/ipaexg.ttf
pdffonts hoge.pdf 

とするとターミナルに

name                                 type         emb sub uni object ID
------------------------------------ ------------ --- --- --- ---------
NHLNPZ+SFSX2488                      Type 1C      yes yes yes    193  0
VKUTAD+SFSX2074                      Type 1C      yes yes yes    194  0
GothicBBB-Medium-Identity-H          CID Type 0   no  no  no     196  0
GVFLCG+SFRM1200                      Type 1C      yes yes yes    197  0
Ryumin-Light-Identity-H              CID Type 0   no  no  no     199  0
KSLVDN+SFSS1200                      Type 1C      yes yes yes    209  0
UPZGAX+CMTT12                        Type 1C      yes yes no     203  0
HTTQFE+SFRM1000                      Type 1C      yes yes yes    213  0

などと表示される。

name
PDF でのフォント名。
type
フォントの種類(Type1, CID, TrueType, Type0 Type1 Collection など)。
emb
埋め込まれているかどうか。
sub
サブセット化されているかどうか。
uni
unicode マッピングされているかどうか(これにより文字列の抽出や テキストのコピー等に影響が出てくるが些細なもんだい)。
object ID
PDF ファイルにおけるフォントのオブジェクト ID。

pdfimages

Xpdf utilities 付属の PDF ファイル中に含まれているビットマップ画像 を PPM 形式で抽出するプログラム。

mkdir img
pdfimages hoge.pdf img/hoge

とすることにより hoge.pdf に含まれる 画像 *.ppm が img/hoge-%d.pdf に 抽出される。ディレクトリは別に作らなくても良い.filename prefix だけは 指定しておかないとハイフン - からファイル名が始まるので,頂けない.

pdfimages hoge.pdf hoge

とすると hoge-%03d.pdf が生成される.

pdfinfo

Xpdf utilities 付属の PDF の文書情報 (Doc info) を表示するための プログラム。

pdfinfo hoge.pdf

とすると

Title:          How to write your own thesis tutorial with LaTeX2e 
Subject:        For thesis writers
Keywords:       TeX, LaTeX, LaTeX2e, pTeX, pLaTeX, pLaTeX2e, FUNNIST, thesis
Author:         FUNNIST
Creator:        LaTeX with hyperref packages
Producer:       dvipdfmx (20170318)
CreationDate:   05/30/17 14:02:46 東京 (標準時)
Tagged:         no
UserProperties: no
Suspects:       no
Form:           none
JavaScript:     no
Pages:          176
Encrypted:      no
Page size:      595.28 x 841.89 pts (A4)
Page rot:       0
File size:      1733518 bytes
Optimized:      no
PDF version:    1.5

などの情報が表示されることとなる。

Title
主題。
Subject
副題。
Keywords
キーワード、関連用語。
Author
PDF の執筆者。
Creator
元々のファイルを作成したプログラム。
Producer
実際に何らかのファイル形式から PDF へと変換したプログラム。
CreationDate?
PDF の作成日時。PDF はこれ以外に編集日時なども追加できる。
Tagged
文書構造を持っているかどうか。通常 ○○ から作成された PDF では 「ここからここまでが段落の固まりだよ」とか「ここが章の固まりだよ」といった情報 を PDF 自身には含めない。あくまで識別子 (Object ID) を持った字形や画像 と行ったモノが xy 座標系のどこに配置すべきかという情報だけである。 そのため、XML と同様に PDF にタグ付けするという機能がある。これはアクセシビリティ の向上のため(主に読み上げ機能の順序を保持するため)に設けられた機能。
Pages
ページ数。
Encrypted
暗号化されているか否か。暗号化されているときは暗号かの内訳。
Page size
用紙のサイズ [pt]。
Page rot
/Rotate の値。
File size
ファイルの容量 [byte]。
Optimized
モニター用に最適化されているか否か。
PDF version
PDF のバージョン。それぞれ 1.4 = Acrobat 5, 1.5 = Acrobat 6, 1.6 = Acrobat 7, 1.7 = Acrobat 8, ということになる。PDF のバージョンをあげればそれだけ多機能になるが、 PDF を閲覧する人物が古いバージョンの Adobe Acrobat Reader を使っている可能性もありえるので、まぁだいたい 1.4 にでもしておけば大丈夫。 TeX の古いバージョンでは 1.5 以上で圧縮された PDF ファイルを処理できないことがある。 それぞれどのような仕様になっているかは Adobe 社のサイト で入手する事ができる。

pdftoppm

Xpdf utilities 付属の PDF を PPM 画像に変換するための プログラム。

mkdir img
pdftoppm -r 36 hoge.pdf img/

とすることにより 36 dpi で img 以下に PPM 画像を出力することができるので PDF ファイルのサムネイル一覧を作成することもできる。または、めちゃくちゃ 解像度をあげてごにょごにょすることも可能。

例えばあるディレクトリに たくさんの PDF *.pdf が存在したとします。 ウェブから適当にダウンロードした PDF なのでファイル名から何の PDF かを判別する事もできません。そのため、 PDF をすべて Xpdf などから プレビューしては面倒です。そこで、 pdftoppm を使ってサムネイルの 一覧を作成します(Ghostscript を使ってもできますが、フォントのラスタライズ や処理速度で満足のいく結果とならないことが多いようです)。

zsh などを使っているのであれば、次のようにできます。

こいつは pdf --(pdftoppm)--> ppm --(magick)--> png という ことをやるのですが、ついでに HTML で出力してウェブブラウザ からアクセスできるようにしましょう。そうするとクリック一つで 該当する PDF にアクセスできるようになりますので。

html='index.html';
pngdir=`pwd`;

echo "<html><boody bgcolor=\"black\"><p>">${html};

mkdir -p ${pngdir}/img;

for f in *.pdf; do
  g=`basename ${f} .pdf`;
  if [ -f img/$g.png ] ; then
      echo "Already $g.png exists.";
  else
      echo "creating $g.png from $f";
      pdftoppm -l 1 -r 30 $f ${pngdir}/img/;
      magick img/-000001.ppm img/$g.png;   
  fi
  echo "<a href=\"$f\"><img border=1 src=\"img/$g.png\"></a> ">>${html};
done 

echo "</p></boody></html>">>${html};

exit;

このようなスクリプト thumb.sh をあるディレクトリ ~/public_html/work などにおき、ここの PDF が有るとします。すると work ディレクトリに index.html と img ディレクトリが作成され、img ディレクトリに生成された png 画像がおさめられます。

別のアプローチとして ImageMagick + Ghostscript という方法があると 思います。

for f in *.pdf; do
  g=`basename $f .pdf`;
  width=300;
  magick -thumbnail ${width} "${f}[0]" $g.png;
done

とかやると良いのでしょうか。

pdftops

Xpdf utilities 付属の PDF を Postscript ファイルに変換するスクリプト。 /etc/xpdfrc などのファイルで日本語に関する設定が適切になされていないと 日本語がごっそりと抜けるという悲惨な事態になり得る。

pdftops version 3.00
Copyright 1996-2004 Glyph & Cog, LLC
用法: pdftops [オプション] <入力>.pdf [<出力>.ps]
 -f <数値>           : 出力する最初のページ
 -l <数値>           : 出力する最後のページ
 -level1             : PostScript Level 1 にする
 -level1sep          : ページ別 PostScript Level 1 にする
 -level2             : PostScript Level 2 にする
 -level2sep          : ページ別 PostScript Level 2 にする
 -level3             : PostScript Level 3 にする
 -level3sep          : ページ別 PostScript Level 3 にする
 -eps                : Encapsulated PostScript (EPS) 形式にする
 -form               : PostScript form
 -opi                : OPI comments
 -noembt1            : Type 1 フォントを埋め込まない
 -noembtt            : TrueType フォントを埋め込まない
 -noembcidps         : CID PostScript フォントを埋め込まない
 -noembcidtt         : CID TrueType フォントを埋め込まない
 -paper <文字列>     : 用紙サイズ (letter, legal, A4, A3, match)
 -paperw <数値>      : 用紙の幅 [pt]
 -paperh <数値>      : 用紙の高さ [pt]
 -nocrop             : CropBox を使って切り抜きしない
 -expand             : 用紙サイズより小さければ拡大する
 -noshrink           : 用紙サイズより大きくても縮小しない
 -nocenter           : 用紙サイズより小さくても中央に配置しない
 -duplex             : 両面印刷を可能にする
 -opw <文字列>       : 暗号化された PDF における所有者パスワード
 -upw <文字列>       : 暗号化された PDF における閲覧者パスワード
 -q                  : 黙って処理をする
 -cfg <文字列>       : 設定ファイルを使用する(一般的には /usr/local/etc/xpdfrc
 -v                  : このソフトの著作権情報とバージョン情報を表示する
 -h                  : このソフトの用法を表示する
 -help               : このソフトの用法を表示する
 --help              : このソフトの用法を表示する
 -?                  : このソフトの用法を表示する

典型的なエラーとしては次のような感じだろう。

Error: Couldn't find a font to substitute for 
  'GothicBBB-Medium-Identity-H' ('Adobe-Japan1' character collection)
Error: Couldn't find a font to substitute for 
  'Ryumin-Light-Identity-H' ('Adobe-Japan1' character collection)

pdftotext

Xpdf utilities 付属の PDF の文字列を抽出して ASCII テキストファイルに 保存するためのプログラム。xpdfrc にて適切な設定をしておけば、いちおう 日本語も大丈夫。fi, fl, ffi, ffl oe, ae 等のように合字などは正常に抽出する ことができないので、わざと合字を殺したフォントを使うのもあり。

pdftotext hoge.pdf hoge.txt

とすることで hoge.pdf からテキストを抽出して hoge.txt が生成される。

Namazu 等の全文検索エンジンはこの pdftotext を使用して PDF ファイル中 のインデックスを生成している場合もある。

PDFtk

使用法

      pdftk <入力PDFファイル| - | コンソール>
           [input_pw <所有者パスワード | コンソール>]
           [<操作> <操作の引数>]
           [output <出力ファイル名 | - | コンソール>]
           [encrypt_40bit | encrypt_128bit]
           [allow <パーミッション>]
           [owner_pw <所有者パスワード | コンソール>]
           [user_pw <ユーザパスワード | コンソール>]
           [flatten] [compress | uncompress]
           [verbose] [dont_ask | do_ask]
      Where:
           <操作> 何も記述しないか、または:
           [cat | attach_files | unpack_files | burst |
            fill_form | background |
            dump_data | dump_data_fields | update_info]
      For Complete Help: pdftk --help

TeXExec

pdfTeX をバックエンドに PDF ファイルを操作するためのツール。 ConTeXt に付属するプログラムで Ruby で書かれている。

用法: texexec [<オプション>] [<入力>.<拡張子>]

重要なオプション

--pdfarrange

PDF ファイルを編集するためには --pdfarrange というオプションを つけるようにする。

普通に複数の PDF ファイルを一つの PDF に結合したければ

texexec --pdfarrange --result=out.pdf file1.pdf file2.pdf ... filex.pdf

lette とか A4 とかが混ざっている場合は、標準で A4 になっちゃうかな。

主なオプション

--result=<output>
出力ファイル名
--input=<input>
入力ファイル名
--pdfcombine
面付けに近いオプション
--pdfcopy
ほげ。
--pdfselect
ページの選択
--pages=<選択>
odd, even によって奇数・偶数の選択、 1,5--9 としたりもできる。
--paper=<版面>
a4 とか a4a3 とか色々指定する。
--silent
もの静か
--verbose
口うるさい
--print=<down
up> | 両面

ページの集約・面付け

集約(面付け)のような事は次のようにすればできます。

texexec --pdfcombine --result=output.pdf foo.pdf bar.pdf hoge.pdf

集約が標準では 2*4 (8 ページが 1 枚に集約)、さらにページのオフセットが 1 cm 入るので、標準的には次のように処理をする事になると思われ。

texexec --silent --pdfcombine --combination="2*1" --nobanner \
   --result=<output>.pdf --paperoffset=0cm <input>.pdf <input2>.pdf

以下のファイルを適当に pdf2up 等とファイル名で保存すれば便利かなと。

#!/bin/sh
texexec --silent --pdfcombine \
   --combination="2*1"\
   --paper=a4,landscape \
   --nobanner \
   --result=$2.pdf \
   --paperoffset=0cm \
   $1.pdf

使い方は

pdf2up input.pdf output.pdf

とか。

ページ数の選択

ページ選択の選択をしたければ次のようにすると奇数ページだけ抜き出す。

texexec --pdfselect --pages=odd --result=output.pdf file1.pdf file2.pdf

複数の入力ファイルを指定した場合は file1.pdf の該当ページ、file2.pdf の 該当ページがそれぞれ選択されるので、結合になる。

Ghostscript

一応 Ghostscript にも単体で PDF を操作するための機能が盛り込まれて いるため、色々と操作する事ができます。 例えば input.pdf があるとすれば

gs -q -dNOPAUSE -dBATCH -sDEVICE=<出力デバイス> -sOutputFile=<出力ファイル名> \
-f input.pdf

とすれば、PDF ファイルを任意の形式に変換できます。 フォントのアンチエイリアシングが鈍いかもしれないので、 ちょっと気に入らない人は気に入らないかもしれませんが。 複数ページからなる PDF の場合は

-sOutputFile=output%03d.png

などとして書式を指定すれば output001.png, output002.png, ..., outoutnnn.png のように出力してくれます。

dvips などで適当に作成した Postscript ファイル input.ps を PDF に変換する時に、詳細に変換したければ、つぎのようなオプションを 付けると印刷用に最適化できるかもしれません。

ps2pdf \
   -dAutoFilterColorImages=false \
   -dAutoFilterGrayImages=false \
   -sColorImageFilter=FlateEncode \
   -sGrayImageFilter=FlateEncode \
   -dPDFSETTINGS=/prepress \
   -dUseFlateCompression=true \
   input.ps

dvips などで適当に作成した Postscript ファイル input.ps を何らかの 画像に変換したければ -sDEVICE=pbm 等として、次のように変換する 事も可能でしょう。

rungs -q -dBATCH -dSAFER -dNOPAUSE -sPAPERSIZE=a4 \
   -sDEVICE=pbm \
   -r72 \
   -sOutputFile=output.pbm  input.ps