Org-modeのインライン画像をQiitaにアップロードする拡張機能を作ってみました

:::note warn
注意
この記事で紹介する拡張機能は、Qiitaの非公開APIを使用しています。公式サポートから、当該APIの使用は禁止ではないことを伺っておりますが、API仕様の変更に伴って、本機能は予告なく動作をしなくなる可能性があります。ご使用の際は、上記ご了承願います。
:::

Org-modeからQiita用Markdownをexportする[拙作パッケージ](https://qiita.com/0x60df/items/3cde67967e3db30d9afe)（ `ox-qmd` ）の機能調整を行っていたところ、インライン画像の扱いが不便であることに気が付きました。インライン画像機能は、Qiitaとorg-mode両方でサポートされていますが、`ox-qmd` ではこれらの連携がうまく取れていませんでした。具体的には、org-modeのインライン画像をQiitaに持ち込む場合、ローカルファイルを手動でアップロードする必要がありました。また、一度アップロードを行った後、org-mode側のリンクをローカルのままにしておきたい場合、アップロードされたURLを別途控えておいて、exportのたびに手動で置き換える必要がありました。この手間をなんとかできないかと思い、拡張機能 ( `ox-qmd-upload-inline-image` ) を作ってみました。


# インストール


## package.el

本拡張機能は、パッケージの本体に付随して公開しておりますので、[MELPA](https://melpa.org/) から `ox-qmd` をインストールいただければ、ox-qmd-upload-inline-image.elも共にインストールされます。


## 手動

[Github](https://github.com/0x60df/ox-qmd/)から、ox-qmd-upload-inline-imagel.elをダウンロードするか、`git clone` するなどして、ロードパスの通った場所に置きます。

外部パッケージの [request](https://github.com/tkf/emacs-request/) と [mimetypes](https://github.com/cniles/emacs-mimetypes) に依存しているので、これらも別途インストールしてください。


# セットアップ


## アクセストークンの取得

QiitaのAPI用のアクセストークンを取得します。設定画面の「アプリケーション」から取得できます。

![Application menu](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65195/6b97ae07-2d7e-87fa-7fcc-45398d265df3.png)

下段の「新しくトークンを発行する」を押すと、発行画面に移行するので、適当な説明を書き入れ、read/write両方のスコープを有効にしてトークンを発行します。（Qiita Teamを使う場合は、末尾teamのスコープを有効にしてください。）

![Issuing access token](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65195/2032a166-2a4f-77cf-dfb5-b7b9d7863bdd.png)

発行直後にだけ、アクセストークンが表示されるので（下図の墨塗り部分）、忘れずにコピーしておきます。

![Issued access token](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65195/084681be-0d50-d12a-1d11-d6f0c4feba34.png)


## 初期設定

initファイルに以下のコードを追加します。`access-token` には、前節でコピーしておいたアクセストークンを貼り付けます。アクセストークンを書き入れたファイルの扱いには十分ご注意ください。

```el:init.el
(require 'ox-qmd)
(require 'ox-qmd-upload-inline-image)
(custom-set-variables
 '(ox-qmd--upload-inline-image-access-token "access-token"))
```


# 使用方法

アップロード用のコマンド `ox-qmd--upload-inline-image` を呼び出して案内に従えば、インライン画像がアップロードされます。このコマンドは、org-mode標準のexport用メニュー（ `C-c C-e` ）からも呼び出すことができます。

アップロードされたファイルのURLは、対象のバッファの末尾にコメントとして記録されます。このコメントがある場合、 `ox-qmd` は、markdownへのexport時、インライン画像のリンクをURLに置換します。


# 注意事項


## 現時点での機能制限

現時点では、 `ox-qmd-upload-inline-image` は、`request` を通じて `curl` に依存しています。`curl` がない環境では動きませんのでご注意ください。

また、サブツリーごとのアップロードにも現時点では対応しておりません。バッファにあるインライン画像は全てアップロードが試行されますのでご注意ください。

Qiita Teamへのアップロードは、 `ox-qmd--upload-inline-image-team-id` にチームidを設定いただければ動作するはずですが、私がQiita Teamを利用していないため、動作確認ができておりません。動作不良がありましたら、お知らせいただけますと幸いです。


## Qiitaに画像をアップロードする際の注意点

[アップロードの容量には上限があります](https://help.qiita.com/ja/articles/qiita-image-upload)。1ファイルの上限は10MB、1ヶ月あたりの上限は100MBです。また、一度アップロードした画像は自分では削除ができません。[削除したい場合は、サポートに依頼を行う必要があります](https://twitter.com/qiita/status/472319710420140032?lang=ja)のでご注意ください。なお、余談ですが、「Qiitaに画像をアップロードする」と言いつつ、実際にはQiitaを経由して、ファイルはAmazon S3にアップロードされます。URLもamazonドメインですが、誤動作ではないのでご安心ください。


## 使用可能なコマンドとカスタム変数

冒頭の注意書きの通り、 `ox-qmd-upload-inline-image` は、Qiitaの非公開APIを使用しているため、将来APIが公開されない限り、恒久的に実験的機能となります。これに伴って、ユーザー側からお使いいただけるコマンドとカスタム変数についても、`ox-qmd--` をプレフィックスとしてつけ、プライベート扱いをしています。`ox-qmd-upload-inline-image` の内部変数と内部関数は、上記に加えて、 `ox-qmd--upload-inline-image--`との形でプレフィックスとして設定しているので、`--` が2つある変数や関数を扱われるときは特にご注意ください。


# 参考文献

-   <https://qiita.com/yuku_t/items/40b7daf018d3dab48974>
-   <https://github.com/increments/kobito-oss>