# 帳票設計書 2-doc.md

## 概要

本ドキュメントは、Lua Language ServerのAPIドキュメント生成機能によって出力される`doc.md`ファイルの帳票設計を定義する。この帳票は、Luaソースコードから抽出されたグローバル変数、型定義、クラス、関数などのAPIドキュメント情報をMarkdown形式で人間が読みやすい形式で出力する。

### 本帳票の処理概要

本帳票は、Lua Language ServerのCLIコマンドによって生成されるAPIドキュメントであり、doc.jsonと同時に生成されるMarkdown形式のドキュメントファイルである。

**業務上の目的・背景**：Luaプロジェクトにおいて、開発者やユーザーが直接閲覧できるAPIリファレンスドキュメントを自動生成するために必要である。GitHubやドキュメントサイトでそのまま表示可能な形式で、コードと同期したドキュメント維持を可能にする。

**帳票の利用シーン**：ライブラリのREADMEやAPIリファレンスページとして公開する際、開発者がAPI仕様を確認する際、またコードレビュー時に仕様を参照する際に利用される。

**主要な出力内容**：
1. グローバル変数・クラスの見出し（# 形式）
2. 各要素の説明文（descフィールド）
3. 関数シグネチャ（Luaコードブロック）
4. フィールド一覧（## 形式のサブセクション）

**帳票の出力タイミング**：CLIから`--DOC`オプションを指定して実行した際、doc.jsonと同時に出力される。

**帳票の利用者**：ライブラリ開発者、ライブラリユーザー、技術ドキュメント担当者

## 帳票種別

ドキュメント（APIリファレンス）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| CLI | コマンドラインインターフェース | `lua-language-server --DOC=<path>` | --DOCオプション指定 |
| CLI | コマンドラインインターフェース | `lua-language-server --DOC_UPDATE=<path>` | --DOC_UPDATEオプション指定 |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | Markdown (.md) |
| 用紙サイズ | N/A（テキストファイル） |
| 向き | N/A |
| ファイル名 | `doc.md` |
| 出力方法 | ファイル出力 |
| 文字コード | UTF-8 |

### Markdown固有設定

| 項目 | 内容 |
|-----|------|
| 見出しレベル | # (クラス/グローバル), ## (フィールド) |
| コードブロック | \`\`\`lua ... \`\`\` |
| 区切り線 | --- (各クラス/グローバル間) |

## 帳票レイアウト

### レイアウト概要

Markdownファイルは各グローバル/クラスごとにセクションとして構成される。名前順でソートされ、セクション間は区切り線で分離される。

```
# {クラス名/グローバル名}

{説明文}

```lua
{関数シグネチャ/型定義}
```

## {フィールド名1}

```lua
{フィールドの型定義}
```

{フィールドの説明}

---

# {次のクラス名/グローバル名}
...
```

### ヘッダー部

各セクションのヘッダーは`#`見出しで構成される。

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | クラス名/グローバル名 | 対象の識別名 | class.name | # {name} |

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | 説明文 | クラス/グローバルの説明 | class.desc | プレーンテキスト |
| 2 | 型定義 | 関数シグネチャ等 | define.extends.view | \`\`\`lua ... \`\`\` |
| 3 | フィールド名 | フィールドの識別名 | field.name | ## {name} |
| 4 | フィールド型 | フィールドの型定義 | field.extends.view | \`\`\`lua ... \`\`\` |
| 5 | フィールド説明 | フィールドの説明 | field.desc | プレーンテキスト |

### フッター部

各セクションの最後に区切り線が挿入される。

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | 区切り線 | セクション区切り | 固定 | --- |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| DOCパス | ドキュメント対象ディレクトリ | Yes |
| エクスポート可能グローバル | vm.getExportableGlobals()が返すグローバル | Yes |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | name | 昇順 |
| 2 | file | 昇順 |
| 3 | start位置 | 昇順 |

### 改ページ条件

N/A（Markdownファイルのため改ページなし、セクション区切り線で分離）

## データベース参照仕様

### 参照テーブル一覧

本帳票はデータベースを使用せず、doc.json生成時に構築されたdocsデータ構造を参照する。

| データソース | 用途 | 取得方法 |
|-------------|------|---------|
| docs配列 | ドキュメント情報 | makeDocs()の戻り値 |
| class.defines | 定義情報 | docs[i].defines |
| class.fields | フィールド情報 | docs[i].fields |

### テーブル別参照項目詳細

#### docs配列の各要素

| 参照項目 | 帳票項目との対応 | 取得条件 | 備考 |
|---------|----------------|---------|------|
| name | # 見出し | なし | クラス/グローバル名 |
| desc | 説明文 | なし | コメントから抽出 |
| defines[].extends.view | コードブロック | defines存在時 | 型定義表示 |
| fields[].name | ## 見出し | fields存在時 | フィールド名 |
| fields[].extends.view | コードブロック | fields存在時 | フィールド型表示 |
| fields[].desc | 説明文 | fields存在時 | フィールド説明 |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| 重複フィールド排除 | mark[field.name]でチェック | N/A | 同名フィールドは最初の1つのみ出力 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[docs配列取得] --> B[markdown()インスタンス生成]
    B --> C{各classをループ}
    C --> D[# class.name追加]
    D --> E[空行追加]
    E --> F[class.desc追加]
    F --> G[空行追加]
    G --> H{definesが存在?}
    H -->|Yes| I[define.extends.viewをluaブロックで追加]
    I --> J[空行追加]
    H -->|No| K{fieldsが存在?}
    J --> K
    K -->|Yes| L{各fieldをループ}
    L --> M{field.nameが未処理?}
    M -->|Yes| N[## field.name追加]
    N --> O[空行追加]
    O --> P[field.extends.viewをluaブロックで追加]
    P --> Q[空行追加]
    Q --> R[field.desc追加]
    R --> S[空行追加]
    M -->|No| L
    S --> L
    L --> T[区切り線追加]
    K -->|No| T
    T --> C
    C -->|完了| U[md:string()でテキスト化]
    U --> V[util.saveFile()で書き込み]
    V --> W[終了]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| ファイル書き込み失敗 | util.saveFile失敗 | エラーメッセージ配列で返却 | ディスク容量・権限確認 |
| パス不正 | DOCが文字列でない | CLI_CHECK_ERROR_TYPE | 正しいパスを指定 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | プロジェクト規模依存（数十〜数千グローバル） |
| 目標出力時間 | doc.jsonと同時生成、追加オーバーヘッドは軽微 |
| 同時出力数上限 | 1（CLI実行単位） |

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

- 出力ファイルにはソースコード内のコメント情報が含まれるため、機密情報がコメントに記載されていないことを確認する
- Markdown内にHTMLタグが含まれる可能性があるが、XSS対策は閲覧側で実施

## 備考

- doc.jsonと同時に生成され、同じディレクトリに出力される
- Markdownはprovider.markdownモジュールを使用して生成
- フィールドの重複排除により、同名フィールドが複数定義されている場合でも1回のみ出力

---

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

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

### 推奨読解順序

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

doc.jsonと同じデータ構造（docs配列）を使用するため、まずdoc.jsonのデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | export.lua | `script/cli/doc/export.lua` | docUnion型定義（37-56行目）で入力データの構造を理解 |

**読解のコツ**: Markdown生成では主にname, desc, defines, fieldsフィールドを使用する。

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

処理の起点となるCLI処理からMarkdown生成部分を特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | export.lua | `script/cli/doc/export.lua` | serializeAndExport関数（310-360行目）内のMarkdown生成部分 |

**主要処理フロー**:
1. **311-312行目**: 出力パス生成（doc.md）
2. **322行目**: markdown()インスタンス生成
3. **323-351行目**: 各classに対するMarkdown生成ループ
4. **352行目**: util.saveFileで書き込み

#### Step 3: Markdown生成処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | export.lua | `script/cli/doc/export.lua` | Markdown生成ループ（323-351行目） |
| 3-2 | markdown.lua | `script/provider/markdown.lua` | markdownモジュールの実装 |

**主要処理フロー**:
- **324行目**: `md:add('md', '# ' .. class.name)` でクラス見出し追加
- **325行目**: `md:emptyLine()` で空行追加
- **326行目**: `md:add('md', class.desc)` で説明追加
- **328-335行目**: definesのextends.viewをluaコードブロックとして追加
- **336-349行目**: fieldsをサブセクションとして追加
- **350行目**: `md:splitLine()` で区切り線追加

#### Step 4: Markdownモジュールを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | markdown.lua | `script/provider/markdown.lua` | add(), emptyLine(), splitLine(), string()メソッド |

**主要処理フロー**:
- `add('md', text)`: Markdownテキストとして追加
- `add('lua', code)`: Luaコードブロックとして追加
- `emptyLine()`: 空行追加
- `splitLine()`: 区切り線追加
- `string()`: 最終的なMarkdown文字列を返却

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

```
script/cli/doc/export.lua:serializeAndExport()
    │
    ├─ markdown() インスタンス生成
    │      └─ script/provider/markdown.lua
    │
    ├─ for _, class in ipairs(docs) do
    │      │
    │      ├─ md:add('md', '# ' .. class.name)
    │      │
    │      ├─ md:emptyLine()
    │      │
    │      ├─ md:add('md', class.desc)
    │      │
    │      ├─ for _, define in ipairs(class.defines) do
    │      │      └─ md:add('lua', define.extends.view)
    │      │
    │      ├─ for _, field in ipairs(class.fields) do
    │      │      ├─ md:add('md', '## ' .. field.name)
    │      │      ├─ md:add('lua', field.extends.view)
    │      │      └─ md:add('md', field.desc)
    │      │
    │      └─ md:splitLine()
    │
    ├─ md:string() → Markdown文字列生成
    │
    └─ util.saveFile(mdPath, md:string())
```

### データフロー図

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

docs配列 ────────────▶ markdown()生成
(makeDocs()から)              │
                              ├─ 各classをループ
                              │      │
                              │      ├─ # 見出し追加
                              │      ├─ 説明追加
                              │      ├─ コードブロック追加
                              │      ├─ フィールド追加
                              │      └─ 区切り線追加
                              │
                              └─ md:string()
                                    │
                                    ▼
                          ─────────────────────▶ doc.md
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| export.lua | `script/cli/doc/export.lua` | ソース | Markdown生成ロジック（serializeAndExport内） |
| init.lua | `script/cli/doc/init.lua` | ソース | CLIエントリーポイント |
| markdown.lua | `script/provider/markdown.lua` | ソース | Markdown組み立てユーティリティ |
| utility.lua | `script/utility.lua` | ソース | ファイル保存（saveFile） |
