PDFファイルの注釈(Annotation)を列挙する

最近炎上プロジェクトへの支援に行き、そのコードのレビューしてため息が出ています。

さて、PDFには注釈(Annotation)という機能があります。 こんな感じでマーカー引いたり、コメントとか入れられます(図中の赤枠の部分)。 いわゆる赤入れとかに使う感じの機能ですね。

f:id:e8l:20190416220846p:plain

で、この注釈としてつけられたテキストを列挙したい要件があったのですが、 残念ながらAdobe Readerとかだと単純なテキストとして吐けないんですよね。 まあ、実際そういう用途ってほとんどないと思いますが。

じゃあPDF扱う系のライブラリ使ったらできるんじゃねえかなって 探したらPoppler使うとできるよ的なものに行き着いたので、 本記事はこんなニッチな要件を満たしたい人のために残しておきます。

今回、たまたま調査しているときに見つけた参考ブログ記事で扱ってたのがRubyだったので、 Rubyコードで書いていますが、PythonとかPerlとかでもいけるみたい。 そのあたりは自身で調べて。

実行環境

WSL(Windows Subsystem for Linux)上にインストールしたUbuntu 16.04
Rubyはrbenvで入れたv2.6.2

準備

gempopplerパッケージを入れます。 macだと面倒なような記述がありましたが(WSL上の)Ubuntuだと特に問題なく 以下のコマンド一発で導入できました。

$ gem install poppler

コード

先に結論。エラー処理とかは皆無です。

require "poppler"

ARGV.each do |filename|
  Poppler::Document.new(filename).each do |page|
    page.annot_mapping.each do |annotation|
      entity = annotation.annot
      annotationText = entity.contents
      if !annotationText.nil? then
        puts "#{annotationText.gsub(/(\r\n|\r|\n)/, "\n")}"
      end
    end
  end
end
  • Poppler::Document.newでパスを指定すると、PDFドキュメントのインスタンスが作られる
  • 注釈はページごとに設定されるのでページごとに走査する
  • annot_mappingメソッドを実行すると注釈を全部取り出すことができる
  • ただし、一段ラッピングされているので具象的な注釈の実体を得るためにannotプロパティにアクセスする
  • テキストはcontentsにアクセスするととれる
    • テキストを含められない注釈とか、テキストが入力されていない注釈はnilが設定される
  • 改行が\rだけだったりして、コンソールに普通に出力すると悲しいことになったりするので置換してる

制限とか

注釈には「返信」って機能があって、コメントにコメントを付けていくことができます。 上のコードでその返信内容も取れるんだけど、どのコメントに対応するのかが分からない。 APIドキュメントとか読んでみたけど、結局分からなかった

ちなみに

あとでツールねーかなって調べたら、 cpdfというツールがありました。 商用では使えないっぽいけど、それでもよければこっち使うのが楽そう。

参考にしたところとか