golden-luckyの日記

ツイッターより長くなるやつ

PDFから「使える」テキストを取り出す(第6回)

今日まで延々と「PDFからテキストデータを取り出すのは大変」という話を続けてきましたが、その構造を見るにあたっては、 hpdft という自作のツールを使ってきました。 大変とはいっても、まあ実現困難な話ではなく、この程度のPDFパーザであれば趣味プログラミングで自作できる範囲です。

しかし、べつにわざわざ自作しなくても、「PDFからテキストデータを取り出す」ためのツールなら世の中にはすでにいくつもあります。 特に有名で昔からよく使われているのは、Xpdf由来のpdftotextでしょう。

XpdfからはPopplerが分派しているので、Poppler版のpdftotextもあります。

また、pdfminerというツールもあります。

pdfminerが面白いのは、行間などを細かく指定して読み方をユーザがある程度まで制御できるところです。ちなみにhpdftはpdfminerにちょっとだけ影響を受けています。

有償の製品まで幅を広げるともっといろいろな選択肢があります。 いずれも使ったことはないですが、個人的にいちばん気になるのは、アンテナハウスのPDFXMLです。 これ、たぶん同社のPDF編集アプリの応用で、あのアプリを実現するためにPDFのテキストを認識する部分だけを切り出した製品であるような気がするんですが、だとするとかなり構造化されたデータが取れたりしそう。

Acrobatのようなビューワーからテキストを範囲選択してコピペすることもできます。「テキストとして書き出し」みたいなオプションがある場合もあるでしょう。

PDFからHTMLを作る

hpdftを作り始めたのは、もともとは「PDFの中身を直接読みたい」という単純な好奇心からでした。 しかしながら、既存のツールに頼らず自作したことで実際に仕事に役立った事例があるので、最終回はそれを紹介だけして締めたいと思います(その後でちょっとだけエモい話もするよ)。

さて、ここに当社で発行している『定理証明手習い』という本があります。

『定理証明手習い』www.lambdanote.com f:id:golden-lucky:20191205214620p:plain

この本、翻訳書なんですが、使える原書のデータがPDFしかありませんでした。 翻訳の版権を購入すると、原書のDTPデータやTeXソースを原書出版社から提供してもらえることが多いんですが、どういうわけか本書については印刷所に入稿されたPDFしかもらえず、それをベースに翻訳作業を開始することになりました。

しかしこの本、そこそこ特殊で微妙な色分けなどが施されていて、既存のPDFテキスト抽出ツールでは翻訳に使えるようなデータが得られません。 というか、膨大な目視による手作業が必要になる有様でした。 そんなのはいやだ。

そこでどうしたかというと、hpdftを本書専用に改造し、それでテキストだけでなくグラフィックスに関する情報をなんとなく読み取ってHTMLを吐き出すようにしました。 たとえばPDFのコンテンツストリームにはCSSCというオペレータがあるのですが、これらでPDF上の色が決まります。 /PANTONE285PC CSとか/PANTONE153PC CSで色空間を決めて、数値 SCでその強度を設定するという感じです。 ここから取得した値を使って、<font color="">...</font> を組み立てるようにします。

また、PDFを生成したツールが一冊の書籍中でまちまちということはないので、テキストに関するオペレータからインデントの分量もある程度までは読み取れます。 もちろん人間による確認と細かい調整は必要ですが、それは自分で原書を見つつ一次翻訳をするので、その過程でついでにやりました。

最終的に、こんな感じのオリジナルのPDFから…

f:id:golden-lucky:20191205214122p:plain

こんな感じにレンダリングされるようにCSSをあてがったHTMLを半自動で出力しています。 (ちなみに、このHTMLでは英日を対訳で表示できるようになっていますが、これはhpdftの出力とは別に後処理でやりました。)

f:id:golden-lucky:20191205214325p:plain

このHTMLの状態で監訳の中野さんにみっちり直してもらい、そのHTMLを最終原稿としてそこからLaTeXを介してPDFにすることで、翻訳版の書籍が次のようなページとして完成しています。

f:id:golden-lucky:20191205214344p:plain

つらいのはPDFではなく人間

今日まで6回に分けて、「PDFファイルからのテキスト抜き出しは単純な作業ではないけれど、条件さえ合えば、PDFからうまくテキストを取り出して再利用できないこともない」という話をしてきました。 結局、「PDFファイルからのテキスト抜き出しは単純な作業ではない」の部分だけが強調されてしまった気もしますが、これはPDFの出自にさかのぼった第1回の記事のことを考えると、ある意味では「予想された結末」だったような気もします。

そもそもPDFは、紙に印刷された状態を再現するためのデータ形式であり、そこに埋め込まれたテキストを再利用できる条件は限られています。 本文では紹介しませんでしたが、/ActualTextというエントリに「実際の文字列」を含めるようなこともPDFの仕様上は可能です。 さらに進むと、タグ付きPDFといって、ページ上のテキストに対する構造を伴ったPDFも仕様化されています。 そういったPDFであれば、データの再利用を目的とした用途にも有効でしょう。 最終回の記事で紹介した事例のように、書籍のような「それなりに同じパターンの見た目のページが数百ページくらい繰り返す」ドキュメントであれば、そのパターンに合わせてコンテンツストリームからテキストを取り出す処理を書くこともまったくのおとぎ話というわけでもありませんでした。

ようするにPDFのつらさとは、その仕様からくるテキスト抜き出しの煩雑さではなく、「ドキュメントの見た目」と「データとしてのドキュメント」をごっちゃにしている人間の残念さだといえます。

ドキュメントの見た目という観点では、人間向けにプラットフォームをまたいだ見た目の再現に関してPDFは本当に考え抜かれたフォーマットなので、当社の商品である書籍のようなメディアにはうってつけです。 一方で、データの再利用を前提としたドキュメント、たとえば行政機関による統計データの配布などにはまったく不向きです。 後者にPDFを使うのはやめましょう。

さて、PDF編はこれでおしまい。 明日からは「HTMLからLaTeXを介してPDFにする」部分を何回かに分けてお話する予定です。

(そう考えると、『定理証明手習い』の事例は、PDF→HTML→LaTeX→PDFという円環を閉じる物語だったとも言えそうですね。)