# 機能設計書 29-Markdownレンダラー

## 概要

本ドキュメントは、Laravel FrameworkのMarkdownレンダラー機能（Markdown）の設計仕様を記載する。Markdownクラスは、MarkdownテンプレートをHTMLメールにレンダリングする機能を提供する。

### 本機能の処理概要

Markdownクラスは、Markdownで記述されたメールテンプレートをHTMLに変換し、CSSをインライン化してメールクライアントで正しく表示されるようにする。League\CommonMarkライブラリを使用してMarkdownを解析する。

**業務上の目的・背景**：HTMLメールの作成は、複雑なHTML構造やインラインスタイルが必要なため手間がかかる。Markdownを使用することで、シンプルな記法でリッチなメールを作成でき、開発効率が大幅に向上する。また、テーマ機能により、ブランドに合わせたデザインの統一が容易になる。

**機能の利用シーン**：パスワードリセットメール、ウェルカムメール、通知メール、ニュースレターなど、HTMLメールの作成・送信時に利用される。

**主要な処理内容**：
1. render()でMarkdownテンプレートをHTMLにレンダリング
2. renderText()でプレーンテキスト版をレンダリング
3. CssToInlineStylesでCSSをインライン化
4. テーマに基づいたスタイル適用
5. セキュアエンコーディングによるXSS対策

**関連システム・外部連携**：League\CommonMark（Markdown解析）、TijsVerkoyen\CssToInlineStyles（CSS インライン化）、Bladeテンプレートエンジンとの連携。

**権限による制御**：本機能自体には権限制御はない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | 内部機能 | メールテンプレートレンダリング |

## 機能種別

メール / テンプレートレンダリング

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| view | string | Yes | ビュー名 | 有効なビューパス |
| data | array | No | ビューに渡すデータ | 配列 |
| theme | string | No | 使用するテーマ（デフォルト: 'default'） | 有効なテーマ名 |

### 入力データソース

- Markdownテンプレートファイル（resources/views）
- テーマCSSファイル
- Mailableクラスからのデータ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| html | HtmlString | インラインスタイル適用済みHTML |
| text | HtmlString | プレーンテキスト版 |

### 出力先

- Mailerに返却され、メール本文として使用

## 処理フロー

### 処理シーケンス

```
1. render()でレンダリング開始
   └─ ViewFactoryのキャッシュをフラッシュ

2. Bladeテンプレートをレンダリング
   └─ EncodedHtmlStringでセキュアエンコーディング
   └─ htmlComponentPaths()でHTMLコンポーネント取得

3. テーマCSSを取得
   └─ カスタムテーマまたはデフォルトテーマ

4. CSSをインライン化
   └─ CssToInlineStyles::convert()

5. HtmlStringとして返却

テキスト版:
1. renderText()でレンダリング開始
2. textComponentPaths()でテキストコンポーネント取得
3. HTML エンティティをデコード
4. 連続改行を正規化
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{HTML/Text?}
    B -->|HTML| C[render]
    B -->|Text| D[renderText]

    C --> E[flushFinderCache]
    E --> F[BladeCompiler取得]
    F --> G[EncodedHtmlStringモード設定]
    G --> H[htmlComponentPaths]
    H --> I[ビューレンダリング]
    I --> J[テーマCSS取得]
    J --> K{カスタムテーマ?}
    K -->|Yes| L[カスタムテーマ読み込み]
    K -->|No| M[mail::themes.default]
    L --> N[CssToInlineStyles]
    M --> N
    N --> O[HtmlString返却]

    D --> P[flushFinderCache]
    P --> Q[textComponentPaths]
    Q --> R[ビューレンダリング]
    R --> S[html_entity_decode]
    S --> T[改行正規化]
    T --> U[HtmlString返却]

    O --> V[終了]
    U --> V
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | テーマ適用 | テーマCSSをHTMLにインライン化 | render()実行時 |
| BR-02 | セキュアエンコーディング | XSS対策のためのエスケープ処理 | withSecuredEncoding有効時 |
| BR-03 | コンポーネントパス | カスタムパス優先、デフォルトパスを補完 | 常時 |
| BR-04 | マルチパートメール | HTML版とテキスト版を両方生成 | Mailableでの利用時 |

### 計算ロジック

- コンポーネントパス: array_unique(array_merge($customPaths, [__DIR__.'/resources/views']))
- HTMLパス: $path.'/html'
- テキストパス: $path.'/text'

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ViewNotFoundException | ビューエラー | テンプレート不存在 | ビューパスを確認 |
| RuntimeException | レンダリングエラー | Blade構文エラー | テンプレートを確認 |

### リトライ仕様

リトライ機能なし。

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

本機能はトランザクションを使用しない。

## パフォーマンス要件

- Markdownパースは軽量
- CSSインライン化は中規模のHTML文書で十分高速
- ビューキャッシュを活用

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

- **セキュアエンコーディング**: withSecuredEncoding()でXSS対策
- **HTMLエスケープ**: 特殊文字（<, >, [）をエスケープ
- **安全でないリンク無効化**: allow_unsafe_links: false

## 備考

- MailServiceProviderで自動登録
- 'markdown'エイリアスでコンテナから解決可能
- MarkdownコンポーネントはLaravelのメール用に最適化

---

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

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

### 推奨読解順序

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

まず、Markdownクラスの全体構造を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Markdown.php | `src/Illuminate/Mail/Markdown.php` | Markdownレンダリングの実装 |

**主要処理フロー**:
- **51-56行目**: コンストラクタでViewFactory、テーマ、コンポーネントパスを設定
- **66-113行目**: render()でHTMLレンダリング
- **122-133行目**: renderText()でテキストレンダリング
- **142-172行目**: parse()で静的Markdown解析
- **182-192行目**: converter()でMarkdownConverterを生成

#### Step 2: レンダリング処理を理解する

render()メソッドの詳細を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Markdown.php | `src/Illuminate/Mail/Markdown.php` | render()の処理フロー |

**主要処理フロー**:
- **68行目**: ViewFactoryのキャッシュをフラッシュ
- **70-73行目**: BladeCompilerを取得
- **75-100行目**: usingEchoFormat()でセキュアエンコーディング
- **102-108行目**: テーマビューを決定
- **110-112行目**: CssToInlineStylesでインライン化

#### Step 3: テーマとコンポーネントを理解する

テーマとコンポーネントの管理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Markdown.php | `src/Illuminate/Mail/Markdown.php` | componentPaths(), theme() |

**主要処理フロー**:
- **199-203行目**: htmlComponentPaths()でHTMLコンポーネントパス
- **210-215行目**: textComponentPaths()でテキストコンポーネントパス
- **223-228行目**: componentPaths()でベースパス取得
- **247-252行目**: theme()でテーマを設定

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

```
Mailable::render()
    │
    └─ Markdown::render()
           │
           ├─ ViewFactory::flushFinderCache()
           │
           ├─ BladeCompiler::usingEchoFormat()
           │      │
           │      └─ EncodedHtmlString (XSS対策)
           │
           ├─ htmlComponentPaths()
           │      └─ replaceNamespace('mail')
           │
           ├─ View::make()->render()
           │
           ├─ テーマCSS取得
           │      └─ mail::themes.{theme}
           │
           └─ CssToInlineStyles::convert()
                  │
                  └─ HtmlString

Markdown::parse()
    │
    └─ converter()
           │
           ├─ Environment
           │      ├─ CommonMarkCoreExtension
           │      └─ TableExtension
           │
           └─ MarkdownConverter::convert()
```

### データフロー図

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

Markdownテンプレート
resources/views/
emails/welcome.blade.php
    │
    ├─ @component('mail::message')
    │
    ▼
Markdown::render()
    │
    ├─ Blade変数展開
    │      └─ {{ $user->name }}
    │
    ├─ Markdownコンポーネント
    │      └─ mail::button
    │      └─ mail::panel
    │
    ├─ CommonMark解析
    │      └─ # → <h1>
    │      └─ ** → <strong>
    │
    └─ テーマCSS
           │
           ▼
    CssToInlineStyles
           │
           └─ <div style="...">
                  │
                  ▼
           HtmlString ───▶ メール本文
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Markdown.php | `src/Illuminate/Mail/Markdown.php` | ソース | Markdownレンダリング |
| MailServiceProvider.php | `src/Illuminate/Mail/MailServiceProvider.php` | ソース | サービス登録 |
| EncodedHtmlString.php | `src/Illuminate/Support/EncodedHtmlString.php` | ソース | セキュアエンコーディング |
| message.blade.php | `src/Illuminate/Mail/resources/views/html/message.blade.php` | テンプレート | HTMLメッセージ基底 |
| button.blade.php | `src/Illuminate/Mail/resources/views/html/button.blade.php` | テンプレート | ボタンコンポーネント |
| panel.blade.php | `src/Illuminate/Mail/resources/views/html/panel.blade.php` | テンプレート | パネルコンポーネント |
| default.css | `src/Illuminate/Mail/resources/views/html/themes/default.css` | スタイル | デフォルトテーマ |
