「メモ帳並みに軽く」と頼んだら、メモ帳より速くなった。Markdownビューアを1日で作った話

AIに仕事を頼むようになってから、手元に「.md」という拡張子のファイルが増えた。仕様書、台帳、検証の記録、反省文。Claudeが書くものはだいたいこの形式で、数えてみたら作業フォルダだけで187個あった。

中身はただの文章だ。ただ、見出しは「#」、表は「|」、チェックリストは「- [ ]」という記号で書いてある。そのまま開くと記号だらけで、表はとくに読めない。

それで、ダブルクリックしたらメモ帳と同じくらい軽く開いて、記号が整形された状態で読める道具がほしくなった。この記事は、それを作ってもらうまでの話。

最初に試したのはメモ帳だった

Windows 11のメモ帳には、いつの間にかMarkdownを整形表示する機能が付いていた(11.2606版)。これで済むなら何も作らなくていい。

試したら、済まなかった。表示を切り替えただけで、元のファイルの中身が書き換わる- [x]* \[x] になる、という具合に。そのまま保存すると、他の道具で読めない形になる。閲覧のつもりで開いたファイルが、黙って別物になっている。

これは実際にファイルを開いて確かめた。以後、.mdを読む目的でメモ帳を使うのはやめた。

ついでに測っておいたのだけれど、メモ帳自体の起動は、すでに一度立ち上げてある状態でも1.0〜1.7秒かかっていた。「メモ帳並みに軽く」という自分の注文は、思ったより低い壁だった。

4つの作り方を、別々に設計させて比べた

作り方はいくつかある。専用のアプリを書く、Chromeの拡張を入れる、メモ帳で我慢する、それとも別の何か。どれがいいか自分では判断できないので、Claudeに4つの方式を別々に設計させて、それを3つの視点(軽さ・保守・安全)で採点させた。設計4人と審査3人、計7体のエージェントで回した。

結果はこうだった(10点満点)。

方式軽さ保守安全
小さな起動役がHTMLに変換→Chromeで開く78.56→821.5
専用アプリ(C#+WebView2)56718
Chromeの拡張(既製)7.58419.5
メモ帳のMarkdown表示2439

採用したのは1番目。.mdをダブルクリックすると、窓を出さない小さなPythonが走って、中身をスタイル付きの1枚のHTMLに変換し、いつも開いているChromeの新しいタブで表示する。変換に使う部品はHTMLの中に焼き込んであって、開いたあとに外と通信することは一切ない。

専用アプリ案は、読み心地はいちばん良かった。ただ実測で、立ち上げ済みでも本文が出るまで1.6〜2.1秒、初回は3.7〜6.0秒かかった。ブラウザの部品を起動する1秒が構造的に消せない。「軽さ」が最優先の注文だったので落とした。動く試作品は残してある。

Chrome拡張の案は速かったけれど、ファイルを読む権限を個人開発の拡張に常時与えることになる。そこで落ちた。

実際の数字

作ってもらって、測った。

  • ダブルクリックから本文が読めるまで: 0.7〜1.0秒(メモ帳の1.0〜1.7秒より速い)
  • 手元でいちばん大きい204KBのファイル: 0.97秒、固まらない
  • 見出し・表・コードの枠・チェックリスト・リンク・ダークモード、全部表示された

自分のファイルを40個抜き出して中身を調べてもらったら、表を使っているのが9個、コードの枠が21個。図を描く記法や生のHTMLは0個だった。だから対応する範囲もそこで切った。足りない機能を先回りして作らない。

予定していた「クリック1回」が、いらなくなった

計画では、最後に自分で「.mdを開くときは常にこのアプリを使う」を1回クリックする手はずだった。

ところが実装の途中で、Windows 11はレジストリに登録しただけでは既定のアプリを変えてくれないことが分かった。候補が複数あると、ダブルクリックのたびに「アプリの選択」という画面が出る。

原因になっている設定の場所を突き止めて、そこを退避してから消す処理を入れたら、画面は出ずに直接開くようになった。退避したものは、元に戻すときに復元する。私の作業はゼロになった。

渡される前に見つかった不具合が2つ

どちらも検証で見つかった。動かさずに渡されていたら、私が最初に踏んでいた。

1つは、セットアップのスクリプトが、直前に作ったばかりの設定を自分で消していた。登録の命令に「強制」の指定を付けていたせいで、既にある項目を作り直してしまう。この状態だとダブルクリックしても何も起きない。

もう1つは見た目。ダークモードの指定が通常の指定より前に書かれていたため、後の指定に上書きされていた。暗い画面の上で、文中のコードの部分だけ明るい背景のまま残って読めない。ダークモードの指定はCSSの末尾に置く、という一行を手順書に残してもらった。

安全のほうは、読む人が気にしないところ

.mdの中に、たちの悪いHTMLが混ざっていることはありうる。AIが書いたファイルや、ネットから拾ったファイルなら、なおさら。

そこは設計の段階から必須にしてあった。危ないHTMLは変換時に除去し、万一残ってもブラウザ側の仕組み(CSP)でスクリプトは実行されない。これは実際に仕込んで、止まることを確かめている。外への画像の読み込みや送信も遮断。2MBを超えるファイルは整形せず原文のまま出す(固まらせないため)。開けなかったときは必ずダイアログを出す(黙って終わらない)。そして、元のファイルには絶対に書き込まない。メモ帳の件があったので、ここだけは譲らなかった。

弱いところ

  • Chromeを閉じた状態(再起動直後の1回目)は、Chrome自体の起動で3〜6秒かかるはず。これは再起動が要るので、まだ測っていない
  • 開くたびにタブが1つ増える
  • .mdの中で相対パスで指した画像は出ない
  • コードの色分けはない

どれも今のところ困っていない。困ったら直す。

道具を作る、というほどの話ではなかった

できたものは、Pythonが80行ほどとHTMLの雛形が1枚。構築は1日で終わって、私がしたのは「Notionとの関連付けを変えてもいいか」と「表示用の部品を初回だけネットから取ってきていいか」の2つにYesと言っただけだ。

それでも、読めなかった187個のファイルが、ダブルクリックで読めるようになった。小さな不便は、小さな道具でちょうど消える。大きく作らないことのほうが、たぶん難しい。

元に戻すスクリプトも付いていて、動かすとNotionに戻る。これも実際に戻して確かめた。戻せることを先に確かめてから使い始める、というのは、AIに何かを入れさせるときの癖にしておいていいと思う。