# 機能設計書 52-単一属性ごとの改行（singleAttributePerLine）

## 概要

本ドキュメントは、Prettierの`singleAttributePerLine`オプションに関する機能設計書である。このオプションは、HTML、Vue、JSXにおいて、要素に複数の属性がある場合に各属性を個別の行に配置するかどうかを制御する。

### 本機能の処理概要

**業務上の目的・背景**：コードレビューやバージョン管理において、属性ごとに改行されていると差分が見やすくなる。また、長い属性リストを持つ要素の可読性が向上する。このオプションにより、チームのコーディング規約に合わせた一貫したフォーマットが可能になる。

**機能の利用シーン**：多くの属性を持つHTML要素やReact/Vueコンポーネントをフォーマットする際に使用される。特に、propsが多いコンポーネントや、属性値が長い要素に対して効果的である。

**主要な処理内容**：
1. オプション値（true/false）の読み込み
2. HTML/Vue/JSX要素の属性数を確認
3. 属性が2つ以上かつオプションがtrueの場合、各属性を個別の行に配置
4. VueSFCブロックの場合は例外としてこの設定を適用しない

**関連システム・外部連携**：HTMLパーサー、Vueパーサー、JavaScriptパーサー（JSX）と連携して動作する。

**権限による制御**：権限による制御は存在しない。設定ファイルまたはCLIオプションで指定する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | Playground | 補助機能 | サイドバーから単一属性改行オプションを設定 |
| 19 | Configuration - Options | 主機能 | singleAttributePerLineオプションの詳細説明 |

## 機能種別

設定オプション / フォーマット制御

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| singleAttributePerLine | boolean | No | 属性ごとに改行するかどうか | true/falseのブール値のみ許可 |

### 入力データソース

- 設定ファイル（.prettierrc、prettier.config.js等）
- CLIオプション（--single-attribute-per-line）
- プログラマティックAPI呼び出し時のオプションオブジェクト

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| formattedCode | string | 属性配置設定が適用されたフォーマット済みコード |

### 出力先

フォーマット結果は呼び出し元に返却される（標準出力、ファイル、API戻り値）。

## 処理フロー

### 処理シーケンス

```
1. オプション解析
   └─ singleAttributePerLineオプションの値を取得（デフォルト: false）
2. 要素のパース
   └─ HTML/Vue/JSX要素を解析
3. 属性数の確認
   └─ 要素の属性数をカウント
4. 改行判定
   └─ オプションがtrue かつ 属性数 > 1 かつ VueSFCブロックでない場合、改行を適用
5. 属性出力
   └─ 判定結果に基づいて属性を出力（line または hardline で区切る）
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[要素をパース]
    B --> C{属性数 > 1?}
    C -->|No| D[通常の属性出力]
    C -->|Yes| E{singleAttributePerLine = true?}
    E -->|No| D
    E -->|Yes| F{VueSFCブロックか?}
    F -->|Yes| D
    F -->|No| G[hardlineで各属性を区切り]
    D --> H[出力]
    G --> H
    H --> I[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-52-1 | デフォルト動作 | 属性はlineで区切られる（折り返し可能） | singleAttributePerLine = false（デフォルト） |
| BR-52-2 | 強制改行 | 各属性をhardlineで区切る | singleAttributePerLine = true かつ 属性数 > 1 |
| BR-52-3 | VueSFC例外 | VueSFCブロックには適用しない | isVueSfcBlock() = true |
| BR-52-4 | HTML適用 | HTML要素の属性に適用 | language-html/print/tag.js |
| BR-52-5 | JSX適用 | JSX要素の属性に適用 | language-js/print/jsx.js |

### 計算ロジック

特別な計算ロジックは存在しない。

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

データベース操作は発生しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 型エラー | boolean以外の値が指定された場合 | Prettierのオプション検証でエラーが発生 |

### リトライ仕様

リトライは不要（同期的な設定適用処理）。

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

トランザクション管理は不要。

## パフォーマンス要件

オプション参照のみの軽量な処理であり、特別なパフォーマンス要件は存在しない。

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

セキュリティに関する特別な考慮事項は存在しない。

## 備考

- HTML、Vue、JSXで共通して使用される。
- 属性が1つの場合はこのオプションの影響を受けない。
- VueSFCの`<template>`、`<script>`、`<style>`タグには適用されない。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | common-options.evaluate.js | `src/common/common-options.evaluate.js` | singleAttributePerLineオプションの定義 |

**読解のコツ**: このファイルでは、Common（共通）カテゴリのオプション定義が行われている。singleAttributePerLineはboolean型でデフォルトがfalseであることを確認する。

#### Step 2: HTML実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | tag.js | `src/language-html/print/tag.js` | printAttributes関数でのオプション参照 |

**主要処理フロー**:
1. **262-265行目**: shouldPrintAttributePerLineの判定
2. **263行目**: options.singleAttributePerLineの参照
3. **264行目**: 属性数 > 1の条件チェック
4. **265行目**: isVueSfcBlockの除外条件
5. **266行目**: attributeLineの決定（hardline または line）

#### Step 3: JSX実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | jsx.js | `src/language-js/print/jsx.js` | printJsxOpeningElement関数でのオプション参照 |

**主要処理フロー**:
- **645-648行目**: attributeLineの決定ロジック
- **646行目**: options.singleAttributePerLineの参照
- 属性数 > 1の条件でhardlineを使用

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

```
HTML処理:
printOpeningTag (tag.js)
    │
    └─ printAttributes
           ├─ options.singleAttributePerLine 参照
           ├─ node.attrs.length > 1 判定
           ├─ isVueSfcBlock 判定
           └─ attributeLine の決定 (hardline / line)

JSX処理:
printJsxOpeningElement (jsx.js)
    │
    └─ options.singleAttributePerLine 参照
           ├─ node.attributes.length > 1 判定
           └─ attributeLine の決定 (hardline / line)
```

### データフロー図

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

オプション設定 ───▶ printAttributes関数 ───▶ 属性間の区切り文字
(singleAttributePerLine)   (tag.js:262-266)      (hardline / line)
        │
        ▼
HTML/JSX要素 ───▶ 属性数カウント ───▶ 条件判定結果
                    VueSFC判定
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| common-options.evaluate.js | `src/common/common-options.evaluate.js` | ソース | オプション定義（62-67行目） |
| options.js | `src/language-html/options.js` | ソース | HTMLオプションへの参照（28行目） |
| options.js | `src/language-js/options.js` | ソース | JSオプションへの参照（112行目） |
| tag.js | `src/language-html/print/tag.js` | ソース | HTML属性出力ロジック |
| jsx.js | `src/language-js/print/jsx.js` | ソース | JSX属性出力ロジック |
| index.d.ts | `src/index.d.ts` | 型定義 | TypeScript型定義（437行目） |
