小ネタ: Google Docsの文書をmarkdownに変換して手元に持ってくる

色々試してみたので、ログとして残しておきます。

背景: 俺はmarkdownのテキストが欲しいんだ!

Google Docsは同時編集ができるし、特別な記法を覚えなくても使えるので、議事録を取るときなどによく使われる。一方で、Google Docsはplain textではないので、ログをissueとかにコピペするときに、markdownのテキストとして欲しくなるときが結構ある(plain text教徒です)。同様のことを考える人は世の中にやっぱりいる。

Docs to Markdownで大体済みそうなものだが、使ってみると案外足りないところが出てくる。

そんなわけで、どんぴしゃで自分の用途に合うものがない。とはいえ、GASでツールを作りたくもない。

適当にスクリプトを書く

Google Docsからdocxファイルをダウンロードしてpandocで変換すればどうとでもできるだろう、というのが基本的な方針。メニューバーからぽちぽちダウンロードすることもできるが面倒だし、そこからファイル名を選んでpandocに食わせて(ryとやるのはさらに面倒。

適当に調べてみると、フォーマットを指定した上でダウンロードするためのURLが存在するらしい。残念ながらダウンロードするファイル名を指定するためのパラメータは存在しないようだ。

あとは適当にダウンロードして変換するスクリプトを書く。フォーマットはdocx以外にも色々あったけど、何だかんだでこれが一番いい見た目になった。

#!/bin/bash
set -eu -o pipefail

DOC_ID=$1
FORMAT="docx"

open "https://docs.google.com/document/d/${DOC_ID}/export?format=${FORMAT}"

sleep 1
osascript -e 'tell application "System Events" to tell process "iTerm2" to keystroke "i" using control down'

FILENAME=""
while [ "${FILENAME}" == "" ]
do
  FILENAME=$(find ~/Downloads -name "*.${FORMAT}" -ctime -1m | head -n 1)
  sleep 1
done

pandoc --from "${FORMAT}" \
  --to markdown_strict-bracketed_spans-raw_html-native_spans-escaped_line_breaks-four_space_rule \
  --wrap=preserve \
  --tab-stop=2 \
  "${FILENAME}" | \
  sed -e '/^$/d' | \
  vim -
rm "${FILENAME}"

いくつか工夫している点。

  • Chromeのフォーカスを取られるので、AppleScriptでiTermにフォーカスを合わせ直す
    • open -g https:// でバックグラウンドで実行しようとしてもなぜかforegroundになってしまうので、これでしのいでる...
  • ファイルがダウンロードされるまで、適当にpollingして待つ
    • 大きいドキュメントだと多少待つ必要があるので。選択範囲だけ、とか考えだすと面倒なので思考停止してる
    • 同時刻に何か他のファイルをダウンロードするとうまく動かないことがあるかもしれないけど、自分のPCの中だけで動くやつなので、厳密さは排除してる
  • 出力されるmarkdownのフォーマットで気に食わないものがあるので、適当にオプションを渡したり、sedで加工してる
  • 大体どこかに貼り付けるのが目的なので、STDINからvimに渡してる
  • コピペが終わったらファイルは削除する
    • 忘れずにやっておかないとDownloadsがゴミ屋敷になるので...

欲しいものに対して、それなりにローカロリーでできたので満足した。