1日で自作Markdownノートシステムを構築した話

本家サイト(reiko-kagura.ink)の重厚な空気とは別に、技術メモとか進捗をラフに書き殴れる「自分だけのノート」が欲しくなったので、思い切って休日の1日でVSCodeを使って、結果的に「マークダウンファイルを自分のサイトのフォルダに投げるだけで勝手にメニューが生成される、最強のノート環境」が爆誕しました!

🛠️ 構築の軌跡(タイムライン)

1. 午前〜昼:インフラと名前解決の迷宮

まずは自サーバー(Synology NAS)へのアクセスルートの確保から。 NTTルーター(PR-400MI)のIPv4ヘアピンNAT仕様に阻まれちゃって、LAN内から nuns-hanne.com が見えない問題が発生したのよね(IPv6の本家は見えていたのに!)

最終的に、Geminiに聞いて、作業PCの hosts ファイルを書き換えて強制的にローカルIPへ向けることで、無事に専用の地下トンネルを開通させましたー。

:: hosts ファイル
192.168.x.x nuns-hanne.com <= これを記入

2. 13時〜14時:UI設計と「シスター風」魔改造

ノートとしての探しやすさを重視して、「左に目次、右に本文」の王道2カラムレイアウトをCSS Gridで構築。スマホで見ると綺麗に1カラムにスタックする感じにしてます。

さらに「シスター † アンネの図書室」感を出すために、ちょっとCSSスパイスを投入。

  • 全体のフォントを優しくて可愛い「丸ゴシック」に統一
  • 枠線を上品な紫色の「二重線(double)」に変更
  • リストの黒丸(・)を、疑似要素を使って紫色の「十字架(†)」に上書きしました!

3. 15時〜夕方:フラットファイルCMSの構築

ここが今回の一番の目玉かしら。データベースは一切使わずに、PHPでディレクトリ階層を読み込んで、.md ファイルを置くだけで自動的にサイドバーの目次が生成されるシステムを組み上げました!

  1. fragmentsscience などのカテゴリフォルダを作る
  2. その中に .md ファイルを保存する
  3. 勝手にサイトが更新される!

圧倒的なメンテナンスフリー環境の完成です!文字を書くときは多少楽したいしね。

4. 夕方〜夜間:VSCode と Copilot による細部のブラッシュアップ

実装の大枠ができたところで、いよいよ細かいこだわり部分の調整に入ったんですよね。ここからは VSCode の GitHub Copilot に力を借りて、さらに磨き上げることにしました。

土台となるコード生成の段階

最初の骨組みづくりでは、本家サイト(reiko-kagura.ink)の Journal システムをお手本にしながら、VSCode に「こういう感じのノートシステムを作りたい」とお願いしました。具体的には:

  • 本家の journal-template/ ディレクトリ構造を参考に
  • Markdown パーサーのロジック(journal_Wordreplace.php)から必要な部分を抽出
  • フラットファイル CMS の仕組み(ディレクトリ走査 → 自動メニュー生成)を移植

本家では Webhook 連携や閲覧数カウンター、自動アーカイブといった重厚な機能がてんこ盛りなんですけど、今回はあくまで「自分用のシンプルなノート」がコンセプトなので、必要最小限に絞り込みました。VSCode がサクサクとファイルを生成してくれたおかげで、作業がかなり捗りましたね。

Markdown パーサーの段階的進化

最初に動いたのは、見出し(#)、段落、コードブロック( ` )、箇条書きリスト(-)くらいのシンプルな構成だったんです。でも、使っているうちに「あれ? これも欲しいな」というのが次々と出てきちゃって⋯。

そこで Copilot と相談しながら、段階的に機能を追加していきました。

  1. 太字 記法の対応
  2. 最初は 太字(スペース無し)のつもりだったんですけど、執筆中にスペースを入れちゃうことが多くて。正規表現を /\*\*\s*(.+?)\s*\*\*/u に調整して、前後のスペースを許容するようにしました。

  1. Gemini API 連携の Webhook システム
  2. 「記事の中でちょっと疑問に思ったことを、その場で AI に質問できたら便利かも?」と思いついて、[質問文]@(チャンネル名) という独自記法を実装。Copilot が GeminiDescription.phpwebhook.php の実装パターンを提案してくれたので、本家の Webhook 構造を流用しつつ、キャッシュ機構まで含めて一気に組み上げることができました。

  1. 番号付きリスト(1. 2. 3.)の追加
  2. 箇条書きリスト(-)だけだと、手順を示すときにちょっと物足りなくて。数字始まりの行を検出して <ol> に変換するロジックを追加しました。Copilot が既存の ul 処理を参考にしながら、$inOL という状態変数を提案してくれたおかげで、リストの切り替えもスムーズに実装できちゃいました。

  1. テーブル記法の実装
  2. これが一番手応えがあったかも。Markdown のテーブルって、「パイプ記号 | で区切られたヘッダー行 → 区切り行(|---|---|)→ データ行」という3段階構造になっているんですよね。

Copilot に「どうやって実装する?」と投げかけたら、こんな流れを提案してくれました: - ヘッダー行 + セパレータ行のペアを検出 - $inTable フラグで状態管理 - $tableBuffer 配列にテーブル行を蓄積 - テーブルが終わったら renderTable() で HTML に一括変換

「セパレータ行の検出パターン /^\|[\s\-:|]+\|$/」とか「列数をヘッダーに統一する処理」なんかは、自力で考えたら結構時間がかかっていたと思います。Copilot のアシストがあったおかげで、サクッと動くものが完成しちゃいました。

CSS / SCSS の同期管理

あと地味に助かったのが、VSCode の複数ファイル編集機能ですね。このサイトは SCSS でスタイルを書いてから、それを CSS にコンパイルして両方を同期させるという運用をしているんです。

テーブルのスタイルを追加するときなんかも:

  • note.scss.article-table のスタイルを追加
  • 同時に note.css にも同じ内容を追記
  • 両方のファイルをタブで開いておいて、見比べながら編集

これ、手作業で毎回同期させるのって、結構心が折れそうになるんですよね。でも VSCode だと、分割表示しながらコピペで対応できるし、Copilot が片方のファイルを見ながらもう片方の編集を提案してくれたりもするので、かなり捗りました。

エラー修正とデバッグの繰り返し

もちろん、すべてが一発で動いたわけではありません。途中で「あれ、テーブルの終端判定がおかしい?」とか「リストの切り替え時に </ul> が閉じられていない!」みたいなバグが出たりもしました。

そんなときも、Copilot が「この部分に if ($inList) { $html .= '</ul>'; } を追加してみてください」と提案してくれたり、PHP の構文チェック(php -l)を走らせてエラーを潰していったりと、地道なデバッグ作業の連続でしたね。

でも、そういう試行錯誤も含めて、「自分でコードを理解しながら組み上げていく感覚」が楽しかったんです。AI にすべてを丸投げするのではなく、「こうしたい」という要望を伝えて、一緒に考えながら実装していく⋯そんな協奏関係が心地よかったです。

📝 Markdownの装飾もバッチリ

今後の執筆が楽しくなるように、Markdown特有のタグにも専用のスタイルを当ててみました。

引用(Blockquote)は、背景を少し暗くして上品な二重線で囲み、手記のような雰囲気に。
項目こだわりポイント
テーブル(表)縦線を消して、シンプルな「引き算の美学」を追求
インラインコード`code` のように紫色のハイライトで美しく

🎉 おわりに

朝の11時に思い立ってから約6時間。インフラのトラブルシューティングから始まって、フロントエンドのレイアウト、バックエンドの自動パース機構まで、VSCodeに、[ 本家のJournal ]を参照にしながら「コード生成お願い⋯!」と頼んだっ結果、怒涛の勢いで組み上がっちゃいました。

ところで、この fragments フォルダには、日々の開発録やキャラクターの設定資料なんかを、とりあえずストックしていこうと思います!