# 機能設計書 50-Markdown

## 概要

本ドキュメントは、NushellにおけるMarkdown形式への変換機能（`to md`コマンド）の詳細設計を記載する。このコマンドはNushellのテーブルやリストをMarkdown形式のテキストに変換する。

### 本機能の処理概要

Markdown変換機能は、Nushellの構造化データ（テーブル、リスト、レコード）をMarkdown形式のテキストに変換する。テーブル、見出し（H1/H2/H3）、ブロッククォート、順序付きリスト、順序なしリストなどの出力に対応している。

**業務上の目的・背景**：Markdownはドキュメント作成やREADME、GitHub上の表示などで広く使用されている。コマンドライン出力やデータをMarkdown形式で出力することで、ドキュメント作成の効率化やWebサービスとの連携が容易になる。

**機能の利用シーン**：
- READMEやドキュメントの自動生成
- GitHub Issue/PRへのテーブル出力
- 報告書の作成
- ブログ記事の素材生成

**主要な処理内容**：
1. `to md`: テーブル/リストをMarkdownに変換
2. `to md --pretty`: 整形済みテーブル出力
3. `to md --per-element`: 各要素を個別に処理
4. `to md --center`: カラムの中央揃え
5. `to md --escape-md`: Markdown特殊文字エスケープ
6. `to md --escape-html`: HTML特殊文字エスケープ
7. `to md --list`: リストスタイル指定

**関連システム・外部連携**：v_htmlescapeクレート（HTMLエスケープ）を使用。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | CLI専用機能のため画面なし |

## 機能種別

データ変換 / フォーマット変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| input | Any | Yes | 変換対象データ（パイプライン入力） | - |
| --pretty / -p | Switch | No | 垂直整列したテーブル出力 | - |
| --per-element / -e | Switch | No | 各行を個別のMarkdown要素として処理 | - |
| --center / -c | list\<cell-path\> | No | 中央揃えするカラム指定 | - |
| --escape-md / -m | Switch | No | Markdown特殊文字をエスケープ | - |
| --escape-html / -t | Switch | No | HTML特殊文字をエスケープ | - |
| --escape-all / -a | Switch | No | Markdown/HTML両方をエスケープ | - |
| --list / -l | String | No | リストスタイル (ordered/unordered/none) | ordered/unordered/none |

### 入力データソース

パイプライン入力（Any型）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | String | Markdown形式の文字列 |

### 出力先

標準出力（パイプライン出力）。content_type: "text/markdown"メタデータを付与。

## 処理フロー

### 処理シーケンス

```
to md:
1. パイプライン入力を受け取る
   └─ Any型を期待
2. フラグを取得
   └─ pretty, per-element, center, escape-md/html, list
3. 入力タイプを判定
   └─ 単純リスト/テーブル/レコードを識別
4. 単純リストの場合
   └─ format_list_item関数でリスト形式出力
5. テーブル/レコードの場合
   └─ group_by関数でグルーピング
6. per-element/single_listの場合
   └─ 各要素を個別処理
7. 通常の場合
   └─ table関数でテーブル出力
8. メタデータを付与
   └─ content_type: text/markdown
```

### フローチャート

```mermaid
flowchart TD
    A1[入力: Any] --> B1[フラグ取得]
    B1 --> C1{単純リスト?}
    C1 -->|Yes| D1[format_list_item]
    C1 -->|No| E1[group_by]
    D1 --> F1[リスト形式出力]
    E1 --> G1{per-element or single_list?}
    G1 -->|Yes| H1[各要素を個別処理]
    G1 -->|No| I1[table関数]
    H1 --> J1{要素タイプ?}
    J1 -->|List| K1[table関数]
    J1 -->|Record h1/h2/h3/blockquote| L1[fragment関数]
    J1 -->|Record other| M1[table関数]
    J1 -->|Other| N1[format_list_item]
    K1 --> O1[String出力 + metadata]
    L1 --> O1
    M1 --> O1
    N1 --> O1
    I1 --> O1
    F1 --> O1
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-50-01 | テーブル出力 | レコードのリストはMarkdownテーブルに変換 | to md |
| BR-50-02 | 見出し変換 | {H1: text}は「# text」に変換 | --per-element |
| BR-50-03 | ブロッククォート | {BLOCKQUOTE: text}は「> text」に変換 | --per-element |
| BR-50-04 | リストスタイル | ordered=「1. 2. 3.」、unordered=「* * *」、none=行のみ | --list |
| BR-50-05 | 整形出力 | --prettyでカラム幅を揃える | --pretty |
| BR-50-06 | 中央揃え | --centerで指定カラムを「:---:」形式 | --center |
| BR-50-07 | パイプエスケープ | テーブル内の「\|」は「\\|」にエスケープ | to md |
| BR-50-08 | 最小カラム幅 | カラム幅は最小3（「---」） | to md |

### 計算ロジック

**特殊Markdownヘッダー**:
- h1, h2, h3, blockquote
- 単一フィールドのレコードで判定

**リストスタイル出力**:
| スタイル | 出力 |
|---------|------|
| ordered | 1. item1\n2. item2\n3. item3 |
| unordered | * item1\n* item2\n* item3 |
| none | item1\nitem2\nitem3 |

**エスケープ対象文字**:
- Markdown: `\ | * _ { } [ ] ( ) < > # + - . !`
- HTML: `< > & " '` (v_htmlescape使用)

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| InvalidValue | 不正なlistオプション | ordered/unordered/none以外 | 有効な値を指定 |

### リトライ仕様

リトライは不要。

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

本機能はトランザクション処理を行わない。

## パフォーマンス要件

- 入力全体をメモリに読み込んで処理
- 大きなテーブルではカラム幅計算のオーバーヘッドあり

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

- --escape-htmlでXSS対策（HTMLタグをエスケープ）
- --escape-mdでMarkdownインジェクション対策

## 備考

- RFC7763に基づくMIMEタイプ「text/markdown」を使用
- 空のカラムヘッダーにも対応
- 複数カラムの中央揃えが可能

---

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

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

### 推奨読解順序

#### Step 1: コマンドインターフェースを理解する

コマンドの定義とパラメータを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | md.rs | `crates/nu-command/src/formats/to/md.rs` | ToMd構造体（7-216行目） |
| 1-2 | md.rs | `crates/nu-command/src/formats/to/md.rs` | ToMdOptions構造体（35-42行目） |
| 1-3 | md.rs | `crates/nu-command/src/formats/to/md.rs` | ListStyle列挙型（10-33行目） |

**読解のコツ**: 6つのフラグ（pretty, per-element, center, escape-md, escape-html, escape-all）と--listオプションの役割を理解する。

#### Step 2: メイン変換処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | md.rs | `crates/nu-command/src/formats/to/md.rs` | to_md関数（218-343行目） |
| 2-2 | md.rs | `crates/nu-command/src/formats/to/md.rs` | group_by関数（562-593行目） |

**主要処理フロー**:
- **224-228行目**: content_type設定（text/markdown）
- **235-237行目**: 単純リスト判定
- **240-259行目**: 単純リストの処理
- **263行目**: group_by関数でグルーピング
- **264-330行目**: per-element/single_listの処理
- **331-343行目**: 通常のテーブル処理

#### Step 3: テーブル生成処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | md.rs | `crates/nu-command/src/formats/to/md.rs` | table関数（467-560行目） |
| 3-2 | md.rs | `crates/nu-command/src/formats/to/md.rs` | get_output_string関数（595-705行目） |

**主要処理フロー**:
- **482行目**: merge_descriptorsでヘッダー取得
- **498行目**: collect_headersでヘッダーエスケープ
- **502-543行目**: 各行の処理とカラム幅計算
- **550-559行目**: get_output_stringで最終出力生成

#### Step 4: 補助関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | md.rs | `crates/nu-command/src/formats/to/md.rs` | fragment関数（400-444行目） |
| 4-2 | md.rs | `crates/nu-command/src/formats/to/md.rs` | format_list_item関数（346-362行目） |
| 4-3 | md.rs | `crates/nu-command/src/formats/to/md.rs` | escape_markdown_characters関数（364-385行目） |
| 4-4 | md.rs | `crates/nu-command/src/formats/to/md.rs` | escape_value関数（388-398行目） |

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

```
to md
    │
    ├─ ToMd::run (172-215行目)
    │      ├─ フラグ取得
    │      │      ├─ pretty, per-element, center
    │      │      ├─ escape-md, escape-html, escape-all
    │      │      └─ list (ListStyle::from_str)
    │      └─ to_md (218-343行目)
    │             ├─ [単純リスト]
    │             │      └─ format_list_item (346-362行目)
    │             │             └─ escape_value
    │             ├─ [テーブル/レコード]
    │             │      └─ group_by (562-593行目)
    │             └─ [出力生成]
    │                    ├─ [per-element/single_list]
    │                    │      ├─ [List] table関数
    │                    │      ├─ [Record h1/h2/h3/blockquote]
    │                    │      │      └─ fragment (400-444行目)
    │                    │      │             └─ escape_value
    │                    │      ├─ [Record other] fragment → table
    │                    │      └─ [Other] format_list_item
    │                    └─ [default]
    │                           └─ table (467-560行目)
    │                                  ├─ merge_descriptors
    │                                  ├─ collect_headers (446-465行目)
    │                                  │      └─ escape_markdown_characters
    │                                  └─ get_output_string (595-705行目)
    │                                         ├─ get_padded_string (725-737行目)
    │                                         └─ get_centered_string (707-723行目)
```

### データフロー図

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

Any ───▶ 入力タイプ判定 ───▶ 処理選択 ───▶ String
              │                   │              │
              ├── 単純リスト ─────┤              └── content_type:
              ├── テーブル ───────┤                  text/markdown
              └── レコード ───────┘
                       │
                       ├── h1/h2/h3/blockquote → fragment
                       └── その他 → table

table関数:
Values ───▶ merge_descriptors ───▶ headers ───▶ get_output_string
                    │                               │
                    └── カラム幅計算 ───────────────┤
                                                    └── 整形出力
                                                         (--pretty時)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| md.rs | `crates/nu-command/src/formats/to/md.rs` | ソース | to mdコマンド実装 |
