MS謹製のanything to Markdownライブラリ: markitdownを試す&PRを出してみた件

こんにちは！逆瀬川 ( https://x.com/gyakuse ) です！

このアドベントカレンダーでは生成AIのアプリケーションを実際に作り、どのように作ればいいのか、ということをわかりやすく書いていければと思います。アプリケーションだけではなく、プロダクト開発に必要なモデルの調査方法、training方法、基礎知識等にも触れていければと思います。

## 今回の記事について

今回の記事では以下の内容に触れます

- MarkItDownの紹介
- Pull-Requestを出してみる

## **MarkItDownの紹介**

https://github.com/microsoft/markitdown

さまざまなタイプのファイルをMarkdownに変換するためのライブラリです。非常に人気で、数日前に公開されたのですが記事公開時点で16.5Kスターもついています。内部を見るとパース処理のために python-pptx, pandas, pdfminer, mammoth等のライブラリを呼び出して実行しています。

このライブラリは以下のreplit appで簡単に試すことが可能です。

https://msftmd.replit.app/

### 何が嬉しいか

任意のファイルをMarkdown化できると以下の嬉しみが発生します

- LLMに供給しやすい (RAG等の場面で活用できる)
- git actionsとかに組み込んでdiffを見やすくできる

実際、類似のライブラリを自作していた方も非常に多いと思います (私も作成していました)

### 対応ファイル

- PDF (.pdf)
- PowerPoint (.pptx)
- Word (.docx)
- Excel (.xlsx)
- 画像（EXIFメタデータおよびOCR）
- 音声（EXIFメタデータおよび音声文字起こし）
- HTML（Wikipediaなどの特別な処理）
- その他のさまざまなテキストベースの形式（csv、json、xmlなど）
- ZIP（内容を展開し、各ファイルを変換）

### 利用法

インストール:

```bash
pip install markitdown
```

使い方:

```bash
from markitdown import MarkItDown

markitdown = MarkItDown()
result = markitdown.convert("test.xlsx")
print(result.text_content)
```

## Pull-Requestを出してみる

MarkItdownについては当初MS謹製というのもあって高速なパーサ等のシステムを期待していたので、ちょっとすかされた感がありました。

https://x.com/gyakuse/status/1868103839322448337

気軽にpostしたつもりが、想定以上に伸びてしまいました。エンジニアであれば揶揄している暇があったら手を動すべきです。というわけでPRを出してみることにしました。

### まず実装を見る

実装本体を見てみると、シンプルな1ファイルにまとまっていることがわかります。

https://github.com/microsoft/markitdown/blob/main/src/markitdown/_markitdown.py

これはそのうちリファクタリングされファイル分割されるので、ちょっと手を入れるならタイミングが非常に重要なライブラリであることがわかります。

### 何をするか

実装を見ていくと、ファイルごとにパーサ実装があります。

自分は特にpptxのreader / editorとかを作ってきたので、その強みを活かして何かやれればと考えました。

### pptxについて

pptxはMicrosoft Officeのパワーポイントです。仕様はOpen XMLで公開されています。これは非常にシンプルで、zipファイルなのでunzipして内部のxmlを編集してもう一度zipにすると編集が容易にできてしまいます。

ただ闇もあり、pptxのグラフ表現は **Excelへの参照を持ちます**

入れ子となっているわけです。なので、簡単に操作する場合は、cacheされた部分をupdateするのが良い戦略となります。

### やってないことを見つけ、実行する

現在の実装ではpptxのチャートのmarkdown化がされていませんでした。

よってここを実装することにします。python-pptxライブラリが使えるので、闇について考えずに容易に実装できます。

### Pull-Requestを出す

基本的にはforkしてpushしてPRを作成するだけですが、リポジトリごとのお作法に従う必要があります。だいたい `CONTRIBUTING.md` とか [`README.md`](http://README.md) に書いてあります。

```markdown
### Running Tests

To run tests, install `hatch` using `pip` or other methods as described [here](https://hatch.pypa.io/dev/install).

    ```sh
    pip install hatch
    hatch shell
    hatch test
    ```

### Running Pre-commit Checks

Please run the pre-commit checks before submitting a PR.

    ```sh
    pre-commit run --all-files
    ```
```

上記を実行して、PRを投げます。

https://github.com/microsoft/markitdown/pull/33

### できたもの

以下のようなチャート入りスライドが入力されても適切にMarkdownになります。

input:

![395859599-e01703aa-bed9-4f6b-ae08-5d62976b3ada.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958603/99e6b663-04ea-b04c-09f4-3b0263dc78f4.png)

output:

```markdown
<!-- Slide number: 4 -->
# A chart to test parsing:

### Chart: a3f6004b-6f4f-4ea8-bee3-3741f4dc385f

| Category | Series 1 |
|---|---|
| 2000 | 2000.0 |
| 2001 | 2001.0 |
| 2002 | 2002.0 |
| 2003 | 2003.0 |
```

なお、scatter plot (散布図) や複雑なグラフには対応していないので今後の修正余地として残っています。

## まとめ

- MarkItDownはこれからに期待なライブラリ！
- 気軽にみんなPRしよう
- 特にリポジトリ初期は気軽さMaxなのでサクッとやろう
- 英語が微妙だったらChatGPTに翻訳してもらおう