# 機能設計書 71-Markdown

## 概要

本ドキュメントは、VS Codeの組み込み拡張機能「markdown-language-features」が提供するMarkdown言語機能の設計を記述する。

### 本機能の処理概要

Markdownファイルの編集、プレビュー表示、言語サーバー連携を提供し、ドキュメント作成の生産性を向上させる機能である。

**業務上の目的・背景**：開発者がREADME、ドキュメント、技術文書などのMarkdownファイルを効率的に作成・編集できる環境を提供する。リアルタイムプレビューにより、最終的な見た目を確認しながら編集できることで、文書作成の品質と効率を向上させる。

**機能の利用シーン**：
- プロジェクトのREADME.mdファイルを作成・編集する場面
- 技術ドキュメントやAPI仕様書をMarkdownで記述する場面
- ブログ記事やWikiページをMarkdownで作成する場面
- コードレビューコメントやPRの説明文を作成する場面

**主要な処理内容**：
1. Markdownファイルのシンタックスハイライト表示
2. リアルタイムプレビュー（サイドパネル/同一パネル）の提供
3. コードブロック内のシンタックスハイライト（highlight.js使用）
4. 見出しへのID自動付与（GitHub互換slugify）
5. リンクの検証と自動補完
6. 画像のプレビュー表示とリソース解決
7. ファイルリネーム時のリンク自動更新
8. 言語サーバーによる診断機能（壊れたリンク検出等）

**関連システム・外部連携**：
- vscode-markdown-languageserver（言語サーバープロトコル）
- markdown-itライブラリ（パース・レンダリング）
- highlight.jsライブラリ（コードハイライト）
- vscode-textmate（トークナイズ）

**権限による制御**：特になし。すべてのユーザーが利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 11 | テキストエディタ | 主画面 | Markdownファイルの編集 |
| 13 | ノートブックエディタ | 参照画面 | ノートブック内Markdownセルの編集 |

## 機能種別

ドキュメントプレビュー / 言語サービス / テキスト処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| document | TextDocument | Yes | 編集中のMarkdownドキュメント | .md/.markdown拡張子またはmarkdown言語ID |
| previewSettings | DynamicPreviewSettings | No | プレビューの表示設定 | - |

### 入力データソース

- エディタで開いているMarkdownファイル
- ワークスペース内の.mdファイル
- 拡張機能が提供するMarkdown-itプラグイン

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| html | string | レンダリングされたHTMLコンテンツ |
| containingImages | Set<string> | ドキュメント内の画像URI一覧 |
| diagnostics | Diagnostic[] | リンク検証結果などの診断情報 |

### 出力先

- Webviewパネル（プレビュー表示）
- 問題パネル（診断結果）
- エディタ（補完候補、ホバー情報）

## 処理フロー

### 処理シーケンス

```
1. 拡張機能のアクティベーション
   └─ MarkdownItEngineの初期化、言語サーバーの起動
2. ドキュメントのトークナイズ
   └─ markdown-itによるパース、トークンキャッシュへの保存
3. HTMLレンダリング
   └─ トークンからHTMLへの変換、画像URI解決、コードハイライト適用
4. プレビュー表示
   └─ Webviewへの出力、スクロール同期
5. 言語機能の提供
   └─ 補完、ホバー、定義へ移動、リンク検証
```

### フローチャート

```mermaid
flowchart TD
    A[Markdownファイルを開く] --> B[MarkdownItEngine初期化]
    B --> C[markdown-itでトークナイズ]
    C --> D{プレビュー要求?}
    D -->|Yes| E[HTMLレンダリング]
    E --> F[Webviewに表示]
    D -->|No| G[言語機能提供]
    G --> H[補完/ホバー/診断]
    F --> I[スクロール同期]
    H --> J[エディタに反映]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-71-01 | GitHub互換Slugify | 見出しのIDはGitHub形式でslugifyする | 見出し要素生成時 |
| BR-71-02 | 相対パス解決 | 画像・リンクの相対パスはドキュメント位置基準で解決 | リソース参照時 |
| BR-71-03 | セキュリティレベル | プレビューのCSPはユーザー設定で制御可能 | プレビュー表示時 |

### 計算ロジック

- トークンキャッシュ: ドキュメントURI + バージョン + 設定をキーとしてキャッシュ
- Slugify: タイトルテキストを小文字化、空白をハイフンに変換、特殊文字を除去

## データベース操作仕様

### 操作別データベース影響一覧

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | RenderError | プレビューレンダリング失敗 | エラーメッセージをWebviewに表示 |
| - | LinkValidationError | 無効なリンク検出 | 診断情報として問題パネルに表示 |
| - | PluginLoadError | Markdown-itプラグイン読み込み失敗 | コンソールにエラー出力、処理継続 |

### リトライ仕様

特になし。エラー発生時は次回の編集操作で再試行される。

## トランザクション仕様

該当なし。

## パフォーマンス要件

- トークンキャッシュにより同一ドキュメントの再パース回避
- プレビュー更新はdebounce処理で頻繁な更新を抑制
- 大規模ドキュメントでも1秒以内にプレビュー表示

## セキュリティ考慮事項

- プレビューWebviewはContent Security Policy(CSP)で制御
- 外部リソースの読み込みはセキュリティレベル設定に従う
- スクリプト実行は既定で無効

## 備考

- Jupyter NotebookのMarkdownセルもサポート
- 拡張機能によるカスタムMarkdown-itプラグインの追加が可能

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、Markdownパーサーとレンダリングの中核となるデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | markdownEngine.ts | `extensions/markdown-language-features/src/markdownEngine.ts` | IMdParser、RenderOutput、RenderEnvインターフェースの定義 |
| 1-2 | previewConfig.ts | `extensions/markdown-language-features/src/preview/previewConfig.ts` | プレビュー設定の構造 |

**読解のコツ**: TypeScriptのインターフェース定義に注目し、markdown-itライブラリとの連携部分を確認する。

#### Step 2: エントリーポイントを理解する

処理の起点となる拡張機能のアクティベーション処理を特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | extension.ts | `extensions/markdown-language-features/src/extension.ts` | activate関数がエントリーポイント |

**主要処理フロー**:
1. **15-27行目**: activate関数でMarkdownItEngine、言語サーバー、共有機能を初期化
2. **29-56行目**: startServer関数で言語サーバーを起動

#### Step 3: Markdownエンジンを理解する

markdown-itを使用したパース・レンダリング処理の詳細を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | markdownEngine.ts | `extensions/markdown-language-features/src/markdownEngine.ts` | MarkdownItEngineクラスの実装 |

**主要処理フロー**:
- **100-120行目**: MarkdownItEngineクラスのコンストラクタ、プラグイン貢献の監視
- **128-173行目**: _getEngineメソッドでmarkdown-itエンジンを初期化、プラグイン適用
- **205-229行目**: renderメソッドでHTMLレンダリング
- **250-270行目**: _addImageRendererで画像URLの解決処理

#### Step 4: プレビュー管理を理解する

プレビューパネルの管理と表示処理を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | previewManager.ts | `extensions/markdown-language-features/src/preview/previewManager.ts` | MarkdownPreviewManagerクラス |

**主要処理フロー**:
- **72-105行目**: MarkdownPreviewManagerクラスのコンストラクタ、イベントリスナー登録
- **125-140行目**: openDynamicPreviewメソッドでプレビューを開く
- **178-234行目**: deserializeWebviewPanelでプレビュー状態の復元

#### Step 5: 言語サーバークライアントを理解する

言語サーバーとの通信処理を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | client.ts | `extensions/markdown-language-features/src/client/client.ts` | MdLanguageClientクラス |

**主要処理フロー**:
- **18-56行目**: MdLanguageClientクラスでLSPリクエストをラップ
- **58-174行目**: startClient関数で言語サーバーを初期化、リクエストハンドラ登録

### プログラム呼び出し階層図

```
activate (extension.ts)
    │
    ├─ MarkdownItEngine (markdownEngine.ts)
    │      ├─ _getEngine → markdown-it初期化
    │      ├─ tokenize → ドキュメントをトークナイズ
    │      └─ render → HTMLにレンダリング
    │
    ├─ startServer → MdLanguageClient (client.ts)
    │      └─ 言語サーバーとの通信
    │
    └─ activateShared (extension.shared.ts)
           └─ MarkdownPreviewManager (previewManager.ts)
                  ├─ openDynamicPreview
                  └─ DynamicMarkdownPreview/StaticMarkdownPreview
```

### データフロー図

```
[入力]                    [処理]                         [出力]

Markdownテキスト ──────▶ MarkdownItEngine ──────────▶ HTMLコンテンツ
                              │
                              ├─▶ tokenize ─▶ Token[]
                              │
                              └─▶ render ─▶ RenderOutput
                                              │
                                              ├─▶ Webview (プレビュー)
                                              │
                                              └─▶ 診断情報 (問題パネル)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| extension.ts | `extensions/markdown-language-features/src/extension.ts` | ソース | 拡張機能エントリーポイント |
| markdownEngine.ts | `extensions/markdown-language-features/src/markdownEngine.ts` | ソース | Markdownパース・レンダリングエンジン |
| previewManager.ts | `extensions/markdown-language-features/src/preview/previewManager.ts` | ソース | プレビュー管理 |
| preview.ts | `extensions/markdown-language-features/src/preview/preview.ts` | ソース | プレビューパネル実装 |
| documentRenderer.ts | `extensions/markdown-language-features/src/preview/documentRenderer.ts` | ソース | ドキュメントレンダラー |
| client.ts | `extensions/markdown-language-features/src/client/client.ts` | ソース | 言語サーバークライアント |
| slugify.ts | `extensions/markdown-language-features/src/slugify.ts` | ソース | 見出しID生成（slugify） |
| markdownExtensions.ts | `extensions/markdown-language-features/src/markdownExtensions.ts` | ソース | 拡張機能貢献管理 |
| package.json | `extensions/markdown-language-features/package.json` | 設定 | 拡張機能マニフェスト |
