Works / Tool Profile
timeline-dsl
Wikidata を起点に年表を構造化し、CLI・WebUI・エディタ拡張・Obsidian までつなぐ Timeline DSL の紹介枠です。

制作経緯
最初の思いつきは、もっと身近な年表でした。自分や両親、兄弟、知人といった近しい人たちの人生を一つの時間軸に並べ、視覚的に見比べられるツールが欲しい——そんな素朴な動機が出発点です。想定に合う既存ツールが見当たらず、「ないなら作る」と構想だけは温めていたものの、長らく手付かずのままになっていました。
着手のきっかけは AI コーディング支援の発達です。これなら形にできそうだと開発に踏み切りました。実在の人物データの取得元として Wikidata を使うというアイデアは、開発を進める中で AI から提案されたもので、そこから「QID を指定して歴史データを取り込む」という現在の中心機能へと広がっていきました。
概要
.tdsl ファイルに C 風の宣言的構文で年表を記述します。Wikidata から QID を指定して歴史データを自動取得でき、HTML(インタラクティブ / 静的)・SVG・PDF・PNG の 4 形式で出力できます。
現在は CLI だけでなく、ブラウザ上の WebUI で編集・プレビューできる体験も整えています。https://keroway.github.io/timeline-dsl/ の Playground では、サンプルを編集しながら即座に SVG / HTML の出力を確認できます。VS Code 拡張と LSP サーバーも整備しており、エディタ上でシンタックスエラーや補完を受けながら書けます。
関連プロダクトとして、Obsidian プラグイン obsidian-tdsl も公開しています。tdsl コードブロックをプレビュー時に SVG 年表として描画でき、ノート内の調査メモと年表を同じ Vault に置けるようにしています。
技術選定
- Rust 2024 + マルチクレートワークスペース — コンパイラ本体にパフォーマンスと型安全性が必要で、Rust を選んだ。機能ごとにクレートを分離(
tdsl-parser/tdsl-core/tdsl-wikidata/tdsl-render/tdsl-wasm)し、テスト対象・WASM ターゲットを切り替えやすくしている。 - pest PEG パーサー — DSL の文法を
.pestファイルで宣言的に管理できる。文法変更の影響範囲が明確になり、ブラウザ向け WASM ビルドにも素直に乗せられる。 - wasm-bindgen —
tdsl-wasmをブラウザ向け WASM facade として npm 公開(@keroway/tdsl-wasm)。WebUI と Obsidian プラグインがこの薄いラッパー越しにコンパイラを呼び出す。 - Wikidata REST/SPARQL + ローカルキャッシュ — QID 指定で歴史データを自動取得。24 時間 TTL のディスクキャッシュでオフライン利用と CI の安定性を両立させた。
- Astro LP / GitHub Pages Demo — LP と Playground を分け、プロダクト説明と実操作の導線を整理している。
学び
- WebUI が入ると DSL の粗さが見える。 CLI では許容できていたエラーメッセージやサンプルの不足が、ブラウザ編集ではすぐ UX の問題として表面化しました。
- WASM facade は共通基盤として効く。 WebUI と Obsidian プラグインが同じ
@keroway/tdsl-wasmを使うことで、コンパイラの修正を複数の入口へ波及させやすくなりました。 - 各種レジストリへの公開も初挑戦でした。 npm(
@keroway/tdsl-wasm)・VS Code 拡張・Homebrew といった配布チャネルへの登録はどれも未経験で、それぞれの公開フローや必要なメタデータ・設定の仕組みを通すこと自体が大きな収穫でした。
今後の方向性
LSP の完成度を上げることが直近の関心事です。Completion(キーワード補完)・Hover(hover 情報)は実装済みで、Goto Definition や Code Action を次のターゲットとして検討しています。
WebUI 側では共有 URL コピー、履歴スナップショット、エディタ⇄プレビュー双方向ジャンプを順次追加しており、ブラウザ完結での年表制作体験をさらに上げていきます。Obsidian 連携は、調査メモの中に年表を自然に埋め込む導線として継続して育てる予定です。
External Links
プロダクト本体や LP に移動
このページでは背景と設計判断をまとめ、詳細な導線は外部 LP / リポジトリ側に集約しています。