# バッチ設計書 39-Generate-CodepointWidthsFromUCD.ps1

## 概要

本ドキュメントは、OpenConsoleプロジェクトにおいてUnicode UCD（Unicode Character Database）のXMLデータからコードポイント幅テーブルのC++コードを自動生成するスクリプト `Generate-CodepointWidthsFromUCD.ps1` の設計仕様を記載する。

### 本バッチの処理概要

本スクリプトは、Unicode UCD XMLドキュメント（UAX#42準拠）を読み込み、各コードポイントのEast_Asian_Widthプロパティおよび絵文字プロパティに基づいて幅テーブル（Wide/Ambiguous）を構築し、`src/types/CodepointWidthDetector.cpp` の配列定義として使用可能なC++コードを標準出力に生成する。オーバーライドXMLによる幅情報の上書きにも対応する。

**業務上の目的・背景**：ターミナルエミュレータにおいて、文字の表示幅（半角=1セル、全角=2セル）を正確に判定することは表示品質の根幹に関わる。Unicode規格のEast_Asian_Widthプロパティに基づいて各コードポイントの幅を判定する必要があるが、Unicodeのバージョンアップに伴い幅情報も更新されるため、手動での管理は非現実的である。本スクリプトはUCDデータベースから自動的にC++のルックアップテーブルを生成し、Unicode更新時の対応を効率化する。

**バッチの実行タイミング**：Unicode UCDの更新時や、幅テーブルのオーバーライド変更時に手動実行される。通常のビルドでは実行されない。

**主要な処理内容**：
1. UCD XMLファイル（ucd.nounihan.flat.xml）を読み込む
2. 各コードポイントのEast_Asian_Width（N/Na/H/W/F/A）と絵文字プロパティを解析する
3. 隣接する同一幅のコードポイント範囲をマージして圧縮する
4. オーバーライドXMLを読み込み、指定範囲の幅情報を上書きする
5. Narrow幅のエントリを除外する（Wide/Ambiguousのみを保持）
6. C++の `std::array<UnicodeRange, N>` 形式の配列定義コードを生成する

**前後の処理との関連**：生成されたコードは `src/types/CodepointWidthDetector.cpp` にペーストされて使用される。本スクリプトは独立して実行され、他のバッチとの直接的な依存関係はない。

**影響範囲**：生成されたコードはコンソール/ターミナルの文字幅判定ロジックに直接影響し、全角/半角文字の表示に関わる。

## バッチ種別

コード生成

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | Unicode UCD更新時（不定期） |
| 実行時刻 | - |
| 実行曜日 | - |
| 実行日 | - |
| トリガー | 手動 |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| PowerShell 7.0以上 | `#Requires -Version 7`（null合体演算子を使用するため） |
| UCD XMLファイルが存在 | ucd.nounihan.flat.xmlをダウンロードしておくこと |
| オーバーライドXMLが存在（-NoOverrides未指定時） | unicode_width_overrides.xmlが存在すること |

### 実行可否判定

入力XMLファイルの存在チェックは暗黙的（Get-Contentが失敗する）。明示的なValidateScriptは設定されていない。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| InputObject | XmlDocument | No（Parsedセット） | なし | 事前に解析済みのUCD XMLオブジェクト |
| OverrideObject | XmlDocument | No（Parsedセット） | なし | 事前に解析済みのオーバーライドXMLオブジェクト |
| Path | string | No（Unparsedセット） | "ucd.nounihan.flat.xml" | UCD XMLファイルパス |
| OverridePath | string | No（Unparsedセット） | "overrides.xml" | オーバーライドXMLファイルパス |
| Pack | switch | No | $false | 幅のみで厳密にパッキングする（コメント等を省略） |
| NoOverrides | switch | No | $false | オーバーライドを適用しない |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| ucd.nounihan.flat.xml | XML（UCD） | Unicode Character Databaseのフラット形式XML |
| unicode_width_overrides.xml | XML | コードポイント幅のオーバーライド定義 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| 標準出力 | C++コード（テキスト） | `std::array<UnicodeRange, N>` の配列定義 |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | 標準出力のため該当なし（リダイレクトでファイル化） |
| 出力先 | 標準出力 |
| 文字コード | UTF-8 |
| 区切り文字 | - |

出力内容の構造:
```
    // Generated by Generate-CodepointWidthsFromUCD.ps1 -Pack:{bool} -Full:{bool} -NoOverrides:{bool}
    // on {UTC datetime} from {UCD description}.
    // {count} (0x{hex}) codepoints covered.
    // {override_count} (0x{hex}) codepoints overridden.
    // Override path: {path}
    static constexpr std::array<UnicodeRange, {N}> s_wideAndAmbiguousTable{
        UnicodeRange{ 0x{start}, 0x{end}, {isAmbiguous} }, // {comment}
        ...
    };
```

## 処理フロー

### 処理シーケンス

```
1. パラメータバインディング
   └─ ParsedまたはUnparsedパラメータセットの判定
2. UCD XMLの読み込み
   ├─ InputObjectが指定されている場合: そのまま使用
   └─ 未指定の場合: Pathからファイル読み込み
3. UCDレパートリーのソート
   └─ コードポイント値（cpまたはfirst-cp）でソート
4. UnicodeRangeリストの構築
   ├─ 各エントリからUnicodeRangeオブジェクトを生成
   ├─ East_Asian_Widthプロパティ（N/Na/H/W/F/A）から幅を判定
   ├─ 絵文字プロパティ（Emoji=Y, EPres=Y）からWide判定
   └─ 隣接する同一フラグの範囲をマージ
5. オーバーライドの適用（-NoOverrides未指定時）
   ├─ OverrideObject/OverridePathからXML読み込み
   └─ ReplaceUnicodeRangeメソッドで既存範囲を上書き
6. Narrow幅エントリの除外
   └─ RemoveAllでNarrow幅のエントリを削除
7. C++コード生成
   ├─ メタ情報コメントの生成
   ├─ static constexpr std::array宣言
   ├─ 各UnicodeRangeのコード生成
   └─ 配列終端の生成
```

### フローチャート

```mermaid
flowchart TD
    A[スクリプト開始] --> B[UCD XMLの読み込み]
    B --> C[UCDレパートリーのソート]
    C --> D[UnicodeRangeリスト構築・マージ]
    D --> E{NoOverrides?}
    E -->|Yes| F[オーバーライドスキップ]
    E -->|No| G[オーバーライドXML読み込み・適用]
    F --> H[Narrow幅エントリ除外]
    G --> H
    H --> I[C++コード生成・標準出力]
    I --> J[スクリプト終了]
```

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

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

データベース操作はない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ファイル読み込みエラー | UCD XMLファイルが存在しない | 正しいパスを指定するか、UCDファイルをダウンロード |
| - | XML解析エラー | XMLファイルが不正な形式 | XMLファイルの整合性を確認 |
| - | East_Asian_Widthエラー | 未知のEast_Asian_Widthプロパティ値 | "Unexpected East_Asian_Width property" 例外スロー |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | - |
| リトライ対象エラー | - |

### 障害時対応

入力XMLファイルの内容を確認し、再実行する。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | なし |
| コミットタイミング | - |
| ロールバック条件 | - |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | UCDのコードポイント数（約30,000エントリ） |
| 目標処理時間 | 特に定義なし（数十秒程度が想定される） |
| メモリ使用量上限 | 特に定義なし（XML全体をメモリに読み込む） |

## 排他制御

標準出力へのコード生成であり、排他制御は不要。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 標準出力 | 処理完了時 | 生成されたC++コード（コメントヘッダー含む） |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| - | - | - |

本スクリプトは手動実行ツールであり、監視・アラートの対象外。

## 備考

- PowerShell 7.0以上が必須（`#Requires -Version 7`）。null合体演算子（`??`）を使用するため。
- UCD XMLは「no han unification」のフラット形式（ucd.nounihan.flat.xml）のみサポート。グループ化形式はサポートしない。
- 推奨実行コマンド: `.\tools\Generate-CodepointWidthsFromUCD.ps1 -Path .\path\to\ucd.nounihan.flat.xml -OverridePath .\src\types\unicode_width_overrides.xml -Pack`
- CodepointWidth EnumはNarrow/Wide/Ambiguousの3値を定義。出力にはWideとAmbiguousのみが含まれる。
- UnicodeRangeListクラスはBinarySearchを使用した高速な範囲置換（ReplaceUnicodeRange）を実装している。
- East_Asian_Widthの「F」（Fullwidth）は「W」（Wide）に正規化される。
- 絵文字かつEmoji Presentation（EPres=Y）のコードポイントはEast_Asian_Widthの値に関わらずWide幅として扱われる。
- ソースファイル: `tools/Generate-CodepointWidthsFromUCD.ps1`
