# 機能設計書 78-DDoc処理

## 概要

本ドキュメントは、serve-dにおけるDDoc処理ユーティリティの設計を記述する。D言語のDDocコメントのパース、Markdown変換、パラメータドキュメント抽出を行うユーティリティモジュールである。

### 本機能の処理概要

**業務上の目的・背景**：D言語のソースコードにはDDoc形式のドキュメンテーションコメントが記述される。LSPのホバー情報やコード補完の詳細表示では、これらのDDocコメントをMarkdown形式に変換してエディタに表示する必要がある。本ユーティリティはDDocからMarkdownへの変換、DDocマクロの解決、パラメータドキュメントの抽出を提供する。

**機能の利用シーン**：ホバー情報（textDocument/hover）、コード補完アイテム解決（completionItem/resolve）、シグネチャヘルプ（textDocument/signatureHelp）等の機能が、シンボルのドキュメントを表示する際に本ユーティリティを呼び出す。

**主要な処理内容**：
1. DDocパース（parseDdoc）：DDoc文字列をComment構造体に変換
2. Markdown変換（ddocToMarkdown）：DDocコメントをMarkdown文字列に変換（マクロ解決含む）
3. MarkedString変換（ddocToMarked）：DDocをMarkedString配列（D言語コードブロック対応）に変換
4. パラメータ抽出（getParams、getParamDocumentation）：DDocからパラメータドキュメントを抽出
5. DDocマクロ定義（markdownMacros）：DDocマクロからMarkdownへの変換テーブル
6. 特殊マクロ処理（TABLE2、P等）：テーブルや段落のマクロを特別処理

**関連システム・外部連携**：ddocライブラリ（parseComment、Lexer）に依存。code-d VSCode拡張のナビゲーションコマンド（command:code-d.navigateLocal/navigateGlobal）へのリンク生成。

**権限による制御**：なし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 30 | ホバー（textDocument/hover） | 補助機能 | ホバー表示用にDDocコメントをMarkdownに変換 |

## 機能種別

ユーティリティ / データ変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ddoc (parseDdoc) | string | Yes | DDoc文字列（コメントマーカー除去済み） | 空文字列の場合Comment.initを返す |
| throwError (parseDdoc) | bool | No | trueの場合パースエラーで例外を発生 | デフォルトfalse |
| ddoc (ddocToMarkdown) | string | Yes | DDoc文字列 | パース失敗時は元の文字列を返す |
| comment (ddocToMarkdown) | Comment | Yes | パース済みCommentオブジェクト | Comment.initの場合空配列を返す |
| searchParam | string | Yes | 検索するパラメータ名 | - |

### 入力データソース

- DCDから取得したシンボルのドキュメント文字列
- ソースコード中のDDocコメント

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Comment | Comment | DDocのパース結果（セクション、パラメータマッピング等） |
| Markdown文字列 | string | DDocから変換されたMarkdown形式の文字列 |
| MarkedString[] | MarkedString[] | D言語コードブロック対応のMarkdown分割配列 |
| パラメータドキュメント | string | 指定パラメータのドキュメント文字列 |

### 出力先

serve-dの各LSP機能モジュール（definition.d、complete.d、calltips.d等）

## 処理フロー

### 処理シーケンス

```
1. DDoc文字列受け取り
   └─ コメントマーカー除去済みの文字列を受け取る
2. 前処理（preProcessContent）
   └─ 先頭の*/+文字をセクション単位で除去
3. DDocマクロ解決（prepareDDoc）
   └─ コードブロックをマクロに変換、特殊マクロ（TABLE2, P等）を処理
4. DDocパース
   └─ ddocライブラリのparseCommentでComment構造体に変換
5. Markdown変換（ddocToMarkdown）
   └─ セクションごとにMarkdown形式に変換（summary, params, returns等）
6. 後処理（postProcessContent）
   └─ code-d固有のインラインリファレンスプレースホルダーを処理
```

### フローチャート

```mermaid
flowchart TD
    A[DDoc文字列] --> B[preProcessContent]
    B --> C[prepareDDoc]
    C --> D[parseComment]
    D --> E{パース成功?}
    E -->|Yes| F[ddocToMarkdown]
    E -->|No| G{throwError?}
    G -->|Yes| H[Exception発生]
    G -->|No| I[Comment.init返却]
    F --> J[postProcessContent]
    J --> K[Markdown文字列]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-78-01 | コメントマーカー除去 | 先頭の`*`や`+`文字をセクション単位で除去（`---`で区切られたセクション内） | preProcessContent |
| BR-78-02 | マクロ変換テーブル | DDocマクロ（B, I, U, LINK, LINK2, REF, LREF等）をMarkdown等価表現に変換 | ddocToMarkdown |
| BR-78-03 | コードブロック変換 | DDocの埋め込みコード（`---`で囲まれた部分）を```dコードブロックに変換 | prepareDDoc |
| BR-78-04 | パラメータセクション | Paramsセクションのkey=valueマッピングを"`param` description"形式に変換 | ddocToMarkdown |
| BR-78-05 | インラインリファレンス | REFマクロは`command:code-d.navigateGlobal`リンク、LREFマクロは`command:code-d.navigateLocal`リンクに変換 | マクロ解決時 |
| BR-78-06 | TABLE2マクロ | THEAD/TROWマクロをMarkdownテーブルに変換 | 特殊マクロ処理 |

### 計算ロジック

特になし。

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

本機能ではデータベース操作は行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Exception | throwError=trueでDDocにシンタックスエラーがある場合 | 例外を上位に伝播 |
| - | Exception | throwError=falseでDDocにシンタックスエラーがある場合 | Comment.initを返却 |
| - | Exception | ddocToMarkdownのパースエラー | 元のDDoc文字列をそのまま返却 |

### リトライ仕様

リトライは行わない。パースエラー時はフォールバック（元文字列またはComment.init）を返す。

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

不要（ステートレスな変換処理）。

## パフォーマンス要件

DDocパースは即時完了することが期待される。マクロ解決テーブル（markdownMacros）はshared static thisで一度だけ初期化され、以降は読み取り専用。

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

DDocマクロ展開で`&#36;`（ドル記号のHTMLエンティティ）を`$`に置換する処理がある。マクロ展開による意図しないコード実行のリスクはない（Markdownに変換するのみ）。

## 備考

- `inlineRefPrefix`定数（`__CODED_INLINE_REF__:`）はcode-d固有のプレースホルダーで、REFマクロの展開結果に含まれる
- DDocのTABLE2マクロは標準DDocには存在しないPhobos拡張マクロ
- ユニットテストが多数含まれており、各変換パターンの動作検証が可能

---

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

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

### 推奨読解順序

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

DDocのComment型と変換先のMarkedString型を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ddoc.d | `source/served/utils/ddoc.d` | `public import ddoc : Comment;`（14行目）でComment型をre-export |

**読解のコツ**: Comment型はddocライブラリの型で、sections（セクション配列）とmapping（パラメータキー・バリューペア）を持つ。MarkedString型はprotocol.dで定義されたLSP型で、value（テキスト内容）とlanguage（言語ID）を持つ。

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

主要なパブリック関数を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ddoc.d | `source/served/utils/ddoc.d` | `parseDdoc`関数（49-67行目）: DDoc文字列のパース |
| 2-2 | ddoc.d | `source/served/utils/ddoc.d` | `ddocToMarkdown`関数（75-137行目）: Markdown変換のメインロジック |
| 2-3 | ddoc.d | `source/served/utils/ddoc.d` | `ddocToMarked`関数（262-277行目）: MarkedString配列への変換 |

**主要処理フロー**:
1. **49-67行目**: `parseDdoc`でprepareDDocを経由してddocライブラリのparseCommentを呼び出し
2. **91-137行目**: `ddocToMarkdown(Comment)`でセクションごとにMarkdown変換（summary, params, default）
3. **106-111行目**: paramsセクションのkey=valueマッピングを"`key` value"形式に変換
4. **136行目**: `&#36;`を`$`に置換する後処理

#### Step 3: マクロ定義テーブルを理解する

DDocマクロからMarkdownへの変換テーブルを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ddoc.d | `source/served/utils/ddoc.d` | `markdownMacros`連想配列（637-742行目）: 全マクロ定義 |

**主要処理フロー**:
- **641行目**: `B` → `**$0**`（太字）
- **642行目**: `I` → `*$0*`（イタリック）
- **663行目**: `LINK` → `[$0]($0)`（リンク）
- **664行目**: `LINK2` → `[$+]($1)`（テキスト付きリンク）
- **671行目**: `LREF` → ローカルナビゲーションリンク
- **672行目**: `REF` → グローバルナビゲーションリンク

#### Step 4: 前処理・後処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ddoc.d | `source/served/utils/ddoc.d` | `preProcessContent`関数（140-203行目）: コメントマーカー除去 |
| 4-2 | ddoc.d | `source/served/utils/ddoc.d` | `prepareDDoc`関数（333-393行目）: DDocマクロ前処理 |
| 4-3 | ddoc.d | `source/served/utils/ddoc.d` | `postProcessContent`関数（230-249行目）: インラインリファレンス後処理 |

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

```
serve-d LSP機能 (definition.d, complete.d 等)
    │
    ├─ parseDdoc (49行目)
    │      ├─ preProcessContent (140行目)
    │      ├─ prepareDDoc (333行目)
    │      │      ├─ Lexer (ddocライブラリ)
    │      │      └─ matchSpecialMacro (527行目)
    │      │             └─ processSpecialMacro (401行目)
    │      └─ parseComment (ddocライブラリ, markdownMacros使用)
    │
    ├─ ddocToMarkdown (75/91行目)
    │      └─ postProcessContent (230行目)
    │             └─ postProcessInlineRefPrefix (251行目)
    │
    ├─ ddocToMarked (262行目)
    │      ├─ ddocToMarkdown
    │      └─ markdownToMarked (282行目)
    │
    └─ getParamDocumentation (320行目)
           └─ getParams (309行目)
```

### データフロー図

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

DDoc文字列 ──────▶ preProcessContent ──────▶ クリーン文字列
                  ──────▶ prepareDDoc ─────────▶ マクロ変換済み文字列
                  ──────▶ parseComment ────────▶ Comment構造体
                  ──────▶ ddocToMarkdown ──────▶ Markdown文字列
                  ──────▶ postProcessContent ──▶ 最終Markdown文字列
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ddoc.d | `source/served/utils/ddoc.d` | ソース | DDoc処理の全実装（パース、変換、マクロ定義） |
| protocol.d | `protocol/source/served/lsp/protocol.d` | ソース | MarkedString型の定義 |
| definition.d | `source/served/commands/definition.d` | ソース | ホバー情報表示（ddocToMarkedの呼び出し元） |
| complete.d | `source/served/commands/complete.d` | ソース | コード補完（ddocToMarkdownの呼び出し元） |
