(文献紹介で役立つ?)PDFファイルをGitでコミットする前にハイライトや脚注を抜き出してREADME.mdに出力して一緒にコミットしGitHubなどのホスティングサービスで確認しやすくする


PDFに線を引いた情報を抜き出してマークダウン化してそのままGitHubで見られる様にしたい

GitHub もプライベートレポジトリが無料になったことで、使ってみようという方が増えていると思います。

私はプライベートレポジトリを、研究で使っているプログラムや計算結果のデータの共有用に使っていますが、プライベートで読んだPDFの保存などもしています。

さて、私はPDFを読む時、積極的にハイライトや脚注をつけて行くタイプ(線を引くと記憶できると思ってる。現実はそう甘くない)なのですが、それらはPDFを開いて該当ページまで開かないと見ることができません。
デバイスによってはPDFリーダーの関係でハイライトを見ることができないこともあります。

こういったPDFのハイライトや脚注を抜き出してマークダウンとして出力してGitHubで見られるようにすると便利かもしれないのでやってみました。また、脚注抜き出しのコマンドを毎回やるのは面倒なので、pdfの変更をgitでコミットする時にREADME.mdを更新する様にしました。

流れ

PDFの脚注を抜き出してREADME.mdに出力するプログラムを整える。

このプログラムをgitでコミットする前に実行する様に設定する。

pdfminer.sixのインストール

まずはじめにPython3でpdfファイルを扱えるライブラリであるpdfminer.sixをインストールします。
これは普通にpipでインストールできます。

pip install pdfminer.six

pdfannotsのインストール

先のpdfminer.sixを使ってpdfのハイライトや脚注を取ることができるpythonファイルが公開されています。
今回はこれを用いて、pdfからアノテーションを抽出していきます。

から、ダウンロードして適切な位置に配置してください。

ダウンロード後、以下の様にパスが通ってる場所にリンクを貼って、どこからでも使える様にしてください。Windowsの場合は環境設定でPATHにpdfannotsフォルダの位置を追加してください。

ln ${path}/pdfannots.py /usr/local/bin

これができたら、適当なpdfファイルに脚注をつけていってください。

世界に挨拶しましょう。

これを保存した後、

pdfannots.py sample.pdf

と入力すると、以下の様に標準出力で

と出力されます。

出力形式はpdfannots.pyのprety_printのところを修正することで変更できます。
(現状日本語に対応していません。正確にはPDFのcontents部分のデコードをiso8859-15からUTF-16などに変えると日本語になりますが、今度は英語が文字化けします。だれか…)

今回はこれを使って

pdfannots.py sample.pdf > README.md

とすることでマークダウンファイルが作成されます。

名前をREADME.mdにしておくと、GitHubの該当フォルダでこのファイルが表示されます。

githookの作成

githookはgit commitやgit pushなど、あるgitのコマンドを行う時に任意のシェルスクリプトを実行する様に指定できる機能です。

今回はクライアントサイドフックを用いてpdfをコミットする直前にpdfの注釈などをREADME.mdに書き出して一緒にコミットするプログラムを書きます。

.git/hooks/pre-commitというファイルを作成して、以下の様に修正します。

pre-commit
#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git commit" with no arguments.  The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-commit".

if git rev-parse --verify HEAD >/dev/null 2>&1
then
    against=HEAD
else
    # Initial commit: diff against an empty tree object
    against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi

# If you want to allow non-ASCII filenames set this variable to true.
allownonascii=$(git config --bool hooks.allownonascii)

# Redirect output to stderr.
exec 1>&2

#拡張子がpdfのファイルがコミットされる時、pdfファイルと同じ位置のフォルダにREADME.mdを作成
for FILE in `git diff --staged --name-only | grep .pdf$`; do
  pdfannots.py $FILE > $(dirname $FILE)/README.md
  git add $(dirname $FILE)/README.md
done

その後、実行権限を付加します。

chmod +x .git/hooks/pre-commit

(参考)
http://www.macneko.com/entry/git-precommit-hook-for-test
http://neos21.hatenablog.com/entry/2018/05/29/080000
https://yoshinorin.net/2018/01/07/git-pre-commit-code-format/

git commitの実行

コミットを実行したのが以下になります。

ステージング時には無かったREADME.mdファイルが追加されているのが分かります。

これをGitHubにプッシュします。

そのごGitHubの該当フォルダのページに行くとREADME.mdの内容が表示されているのが分かります。
プライベートレポジトリでも問題なく表示されます。

メモ

今回はPoC的な形で本当に簡単に書きましたが、pretty_printやシェルスクリプトを作り込めば、色々使いやすくなると思います。

質問などを書いてプルリクしてGitHub上でコラボレーター(メンター)に添削してもらうといった運用ができるかもです。