Skip to content

feat: マークダウンレンダリングの改善 (#54)#58

Merged
ktmage merged 2 commits into
developmentfrom
feature/54/markdown-rendering
Mar 1, 2026
Merged

feat: マークダウンレンダリングの改善 (#54)#58
ktmage merged 2 commits into
developmentfrom
feature/54/markdown-rendering

Conversation

@ktmage
Copy link
Copy Markdown
Owner

@ktmage ktmage commented Mar 1, 2026

概要

Issue #54 に対応し、マークダウンレンダリングを改善しました。

変更内容

1. シンタックスハイライト

  • highlight.js/lib/common を使用し、コードブロックにシンタックスハイライトを適用
  • VSCode テーマ CSS 変数 (--vscode-*) に連動したカラースキーム

2. コピーボタン

  • コードブロックヘッダーにコピーボタンを追加
  • イベント委譲パターンで dangerouslySetInnerHTML と共存
  • VS Code webview の制約により postMessage("copyToClipboard") 経由で Extension Host の vscode.env.clipboard.writeText() を使用
  • コピー後にチェックアイコン(緑色)で視覚フィードバック

3. スペーシング改善

  • リスト (ul/ol/li) のコンパクトなマージン
  • 見出し h1h6 のサイズ階層とマージン
  • 段落 (p) の適切な余白

4. ネストされたコードブロック

  • preprocessNestedCodeBlocks() ユーティリティで、内側にコードフェンスを含むブロックの外側フェンスを自動拡張
  • 9件のユニットテスト付き

設計判断

判断 理由
highlight.js/lib/common (37言語) フルバンドル比で 60% サイズ削減 (1,345KB → 538KB)
new Marked() インスタンス marked.use() のグローバル副作用を回避
イベント委譲 (onClick on container) dangerouslySetInnerHTML が DOM を置換するため addEventListener は不可
Extension Host 経由クリップボード webview iframe サンドボックスで navigator.clipboard が使用不可
Plain HTML + SVG (not React components) createRoot + dangerouslySetInnerHTML の併用は detached DOM を生む

テスト

  • 全 66 ファイル、1,441 テスト合格
  • markdown.test.ts: ネストコードブロック前処理の 9 テスト追加

Closes #54

ktmage added 2 commits March 2, 2026 01:29
- highlight.js (common) によるコードブロックのシンタックスハイライト
- コピーボタン(イベント委譲 + Extension Host 経由のクリップボード操作)
- リスト・見出し・段落の適切なスペーシング
- ネストされたコードブロックの前処理ユーティリティ
- marked を Marked インスタンスに変更(グローバル状態汚染の回避)
- DOMPurify で SVG 要素を許可する設定
- highlight.js テーマを VSCode CSS 変数に連動
@ktmage ktmage changed the base branch from master to development March 1, 2026 16:35
@ktmage ktmage merged commit 11a4436 into development Mar 1, 2026
1 check passed
@ktmage ktmage mentioned this pull request Mar 1, 2026
@ktmage ktmage deleted the feature/54/markdown-rendering branch March 1, 2026 17:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant