# 機能設計書 7-HTML/Vue/Angular パース

## 概要

本ドキュメントは、PrettierのHTML/Vue/Angularパース機能の設計について記述する。

### 本機能の処理概要

HTML、Vue、Angular、LWC、MJMLテンプレートをパースし、AST（抽象構文木）を生成する機能である。angular-html-parserライブラリを基盤として、各テンプレート言語の特性に応じたパース処理を行う。

**業務上の目的・背景**：HTMLとテンプレートベースのフレームワーク（Vue、Angular）は、モダンなウェブ開発において広く使用されている。これらのテンプレートをサポートすることで、フロントエンド開発者のコードスタイル統一を支援する。

**機能の利用シーン**：
- HTMLファイルのフォーマット
- Vue Single File Component（SFC）のフォーマット
- Angularテンプレートのフォーマット
- Lightning Web Components（LWC）のフォーマット
- MJMLメールテンプレートのフォーマット

**主要な処理内容**：
1. Front Matterの解析（YAML/TOMLヘッダー）
2. angular-html-parserによるメインパース
3. Vue SFC判定とHTML切り替え
4. rawテキストタグの処理（script、style等）
5. サブテンプレートの再帰パース
6. ポストプロセス（AST正規化）

**関連システム・外部連携**：
- angular-html-parser（HTMLパーサー）
- Prettier内部の埋め込み言語フォーマット（script、style）

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | Playground | API連携 | HTML、Vue、Angularテンプレートをパース |
| 5 | About - Prettier概要 | 補助機能 | 対応言語としてHTML/Vue/Angularパースを説明 |

## 機能種別

計算処理 / パース処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| text | string | Yes | パース対象のテンプレートコード | - |
| options | object | No | パースオプション | - |
| options.parser | string | No | パーサー名（html, vue, angular, lwc, mjml） | 有効なパーサー名 |
| options.filepath | string | No | ファイルパス（パーサー推論用） | - |

### 入力データソース

- HTMLテンプレートコードテキスト
- ファイルパス情報（パーサー推論用）

### サポートパーサー

| パーサー名 | 説明 | 特徴 |
|-----------|------|------|
| html | 標準HTMLパーサー | タグ名/属性名の正規化 |
| vue | Vue SFCパーサー | タグ名大文字小文字を維持、rawテキストタグ対応 |
| angular | Angularテンプレートパーサー | @ブロック構文、let宣言対応 |
| lwc | Lightning Web Componentsパーサー | 自己終了タグ禁止 |
| mjml | MJMLメールテンプレートパーサー | mj-style、mj-rawをrawテキストとして処理 |

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ast | object | パースされたHTML AST（kind: "root"） |
| ast.children | array | 子ノード配列 |
| ast.frontMatter | object | Front Matter情報（存在する場合） |

### 出力先

- パース関数の戻り値として返却
- プリンターで使用

## 処理フロー

### 処理シーケンス

```
1. Front Matterの解析
   └─ YAML/TOMLヘッダーを検出・分離

2. パーサーオプション正規化
   └─ normalizeParseOptionsで設定を統一

3. 初回パース
   ├─ Vue: parseVue関数
   └─ その他: parseHtml関数

4. Vue SFC判定（Vueパーサー時）
   ├─ DOCTYPE htmlまたはhtml要素あり → HTMLとして再パース
   └─ template/script/styleルート要素 → Vue SFCとして処理

5. rawテキストタグ処理
   └─ script、style、template[lang]等のコンテンツを保持

6. ポストプロセス
   └─ AST正規化、位置情報調整

7. サブテンプレート再帰パース（必要な場合）
   └─ Vue template等の埋め込みHTMLをパース
```

### フローチャート

```mermaid
flowchart TD
    A[パース開始] --> B[Front Matter解析]
    B --> C[パーサーオプション正規化]
    C --> D{パーサー種類}
    D -->|vue| E[parseVue]
    D -->|その他| F[parseHtml]
    E --> G{Vue SFC?}
    G -->|Yes| H[Vue SFCとして処理]
    G -->|No| I[HTMLとして再パース]
    F --> J[angular-html-parser呼び出し]
    H --> J
    I --> J
    J --> K{パースエラー?}
    K -->|Yes| L[エラースロー]
    K -->|No| M[ポストプロセス]
    M --> N{サブテンプレートあり?}
    N -->|Yes| O[サブテンプレート再帰パース]
    N -->|No| P[AST返却]
    O --> P
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | Vue SFC判定 | DOCTYPE htmlまたはhtml要素がある場合はHTMLとして処理 | parser=vue時 |
| BR-02 | タグ名正規化 | HTMLパーサーではタグ名を小文字に正規化 | parser=html時 |
| BR-03 | タグ名維持 | Vueパーサーではタグ名の大文字小文字を維持 | parser=vue時 |
| BR-04 | rawテキストタグ | script、style、template[lang!="html"]はパースせず保持 | Vue時 |
| BR-05 | Angularブロック | @if、@for等のAngular 17+ブロック構文をサポート | parser=angular時 |
| BR-06 | Angular let宣言 | @let宣言をサポート | parser=angular時 |
| BR-07 | 自己終了タグ | LWCでは自己終了タグ（<br/>）を禁止 | parser=lwc時 |
| BR-08 | MJMLrawタグ | mj-style、mj-rawをrawテキストとして処理 | parser=mjml時 |

### 計算ロジック

**Vue SFC判定**：
```javascript
const isHtml = rootNodes.some(
  (node) =>
    (node.kind === "docType" && node.value === "html") ||
    (node.kind === "element" && node.name.toLowerCase() === "html")
);
```

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | パースエラー | HTMLの構文エラー | テンプレートを修正 |
| ConfigError | 設定エラー | パーサーが見つからない | パーサー名を確認 |

### リトライ仕様

リトライは行わない。エラー発生時は即座に例外をスロー。

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

トランザクション管理は不要（ステートレスな処理）。

## パフォーマンス要件

- 一般的なHTMLファイル（500行程度）のパースは30ms以内
- Vue SFCの複合パース（HTML + script + style）も安定した処理時間

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

- 入力コードの実行は行わない（静的解析のみ）
- scriptタグのコンテンツは別途JSパーサーで処理

## 備考

- angular-html-parserはAngular公式のHTMLパーサーを拡張したもの
- Vue SFCでは複数のrootノードが許可される
- 埋め込み言語（script、style）は別途フォーマット処理される

---

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

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

### 推奨読解順序

#### Step 1: パーサープラグインの構成を理解する

HTMLパーサーがプラグインとしてどのように構成されているかを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | html.js | `src/plugins/html.js` | HTMLパーサープラグインのエクスポート |
| 1-2 | index.js | `src/language-html/index.js` | 言語モジュールの構成 |

#### Step 2: パーサー定義を理解する

各パーサー（html、vue、angular等）の定義を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | parsers.js | `src/language-html/parse/parsers.js` | パーサー定義 |

**主要処理フロー**:
- **13-24行目**: createParser関数
- **27行目**: htmlParser定義
- **31-35行目**: mjmlParser定義
- **38-42行目**: angularParser定義
- **45-62行目**: vueParser定義
- **65行目**: lwcParser定義

#### Step 3: パース処理の実装を理解する

パース処理の本体を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | parse.js | `src/language-html/parse/parse.js` | パース実装本体 |

**主要処理フロー**:
- **28-39行目**: parseHtml関数
- **45-109行目**: parseVue関数
  - **53-57行目**: Vue SFC判定
  - **60-62行目**: HTMLとしての再パース
- **137-174行目**: parseSubHtml関数（サブテンプレート再帰パース）
- **182-238行目**: parse関数（メインエントリー）
- **241-247行目**: HTML_PARSE_OPTIONS

#### Step 4: ポストプロセスを理解する

ASTの後処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | postprocess.js | `src/language-html/parse/postprocess.js` | ポストプロセス |

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

```
parsers.js (src/language-html/parse/parsers.js)
    │
    ├─ htmlParser / vueParser / angularParser / lwcParser / mjmlParser
    │      │
    │      └─ createParser
    │             │
    │             └─ parse (src/language-html/parse/parse.js)
    │                    │
    │                    ├─ parseFrontMatter
    │                    │
    │                    ├─ parseVue (Vue時)
    │                    │      │
    │                    │      ├─ angularHtmlParserParse
    │                    │      │
    │                    │      └─ Vue SFC判定
    │                    │             └─ parseHtml (HTML再パース)
    │                    │
    │                    ├─ parseHtml (その他)
    │                    │      └─ angularHtmlParserParse
    │                    │
    │                    ├─ postprocess
    │                    │
    │                    └─ parseSubHtml (サブテンプレート再帰)
    │
    └─ hasPragma / hasIgnorePragma
```

### データフロー図

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

テンプレート ───────────▶ Front Matter解析 ─────────────▶ コンテンツ分離
    │                                                         │
    │                                                         ▼
    │                    パーサー選択 ──────────────────▶ パーサー設定
    │                         │
    │                         ▼
    │               angular-html-parser ────────────────▶ 生AST
    │                         │
    │                         ▼
    │                    ポストプロセス ────────────────▶ 正規化AST
    │                         │
    │                         ▼
    └─────────────────▶ サブテンプレート再帰パース ─────▶ 完全AST
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| html.js | `src/plugins/html.js` | ソース | HTMLパーサープラグイン |
| index.js | `src/language-html/index.js` | ソース | 言語モジュールエクスポート |
| parsers.js | `src/language-html/parse/parsers.js` | ソース | パーサー定義 |
| parse.js | `src/language-html/parse/parse.js` | ソース | パース実装本体 |
| parse-options.js | `src/language-html/parse/parse-options.js` | ソース | パースオプション正規化 |
| postprocess.js | `src/language-html/parse/postprocess.js` | ソース | ポストプロセス |
| loc.js | `src/language-html/loc.js` | ソース | 位置情報関数 |
| pragma.js | `src/language-html/pragma.js` | ソース | プラグマ処理 |
| printer-html.js | `src/language-html/printer-html.js` | ソース | HTMLプリンター |
| angular.js | `src/plugins/angular.js` | ソース | Angularパーサープラグイン |
