# 機能設計書 36-テキスト出力

## 概要

本ドキュメントは、Julia Base ライブラリにおけるテキスト出力機能の設計を記述する。`print` / `println` / `printstyled` / `sprint` / `show` / `dump` / `@show` などのテキスト出力関数を提供する。

### 本機能の処理概要

本機能は、Julia オブジェクトのテキスト表現を生成・出力するための関数群を提供する。ユーザー向けの読みやすい出力（`print`/`show`）からプログラム的な表現（`repr`）、デバッグ支援（`dump`/`@show`）まで、多様な出力形式をサポートする。

**業務上の目的・背景**：プログラムの出力表示、デバッグ、ログ出力、REPL における対話的な値表示など、あらゆる場面でオブジェクトのテキスト表現が必要とされる。Julia の多重ディスパッチにより、ユーザー定義型に対してカスタム表示を容易に追加できる。

**機能の利用シーン**：REPL での値表示、ファイルへのテキスト出力、デバッグ時の変数検査、ログメッセージの構築、テスト出力の検証。

**主要な処理内容**：
1. `print(io, x...)` による基本テキスト出力（人間可読形式）
2. `println(io, x...)` による改行付きテキスト出力
3. `show(io, x)` による Julia 構文的表現の出力（2引数形式）
4. `show(io, mime, x)` による MIME タイプ指定表示（3引数形式）
5. `sprint(f, args...)` による文字列キャプチャ
6. `printstyled(io, x...; color, bold, ...)` によるスタイル付き出力
7. `dump(io, x; maxdepth)` による構造的ダンプ
8. `@show expr` マクロによるデバッグ表示
9. ANSI エスケープシーケンス対応のテキスト幅計算
10. `print_range` / `print_matrix` による配列・範囲の整形出力

**関連システム・外部連携**：ANSI ターミナルエスケープシーケンス。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | REPL | 主画面 | show(MIME"text/plain") による値表示 |

## 機能種別

テキスト表現・出力ユーティリティ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| io | IO | No | 出力先ストリーム | 省略時は stdout |
| x | Any | Yes | 出力対象のオブジェクト | - |
| mime | MIME | No | 出力形式指定（3引数 show） | - |
| color | Symbol | No | printstyled のテキスト色 | :red, :green, :blue 等 |
| bold | Bool | No | 太字フラグ | デフォルト: false |
| maxdepth | Int | No | dump の最大深度 | デフォルト: 8 |

### 入力データソース

関数の引数として直接受け取る。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| print/println/show | Nothing | IO ストリームへの出力（戻り値は nothing） |
| sprint結果 | String | 関数出力をキャプチャした文字列 |
| repr結果 | String | Julia 構文表現の文字列 |

### 出力先

指定された IO ストリーム（デフォルトは stdout）に出力する。`sprint`/`repr` は内部 IOBuffer に出力し文字列として返却する。

## 処理フロー

### 処理シーケンス

```
1. show(io, x) - 2引数形式
   └─ 各型に対する show メソッドをディスパッチ
   └─ デフォルトは型名とフィールド値を表示
2. show(io, ::MIME"text/plain", x) - 3引数形式
   └─ REPL 等での pretty-print 用
   └─ フォールバックは show(io, x) を呼び出し
3. print(io, x...)
   └─ 各引数に対して show(io, x) を呼び出し（文字列は直接書き込み）
4. println(io, x...)
   └─ print(io, x...) + print(io, '\n')
5. sprint(f, args...; context, sizehint)
   └─ IOBuffer を作成
   └─ f(IOBuffer, args...) を実行
   └─ takestring!(IOBuffer) で文字列を返却
6. printstyled(io, x...; color, bold, ...)
   └─ ANSI エスケープコード出力
   └─ print(io, x...)
   └─ ANSI リセットコード出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始: show io, x] --> B{型に対する show メソッドが定義済み?}
    B -->|Yes| C[特殊化された show を呼び出し]
    B -->|No| D[デフォルト show: 型名 + フィールド表示]
    C --> E[IO ストリームに書き込み]
    D --> E
    E --> F[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-36-01 | show vs print | show は Julia 構文的表現、print は人間可読表現 | show/print |
| BR-36-02 | 2引数 vs 3引数 show | 2引数は構文表現、3引数は MIME 指定表示 | show |
| BR-36-03 | text/plain フォールバック | show(io, MIME"text/plain", x) は show(io, x) にフォールバック | MIME 未定義時 |
| BR-36-04 | IOContext :compact | :compact => true で短縮表示（配列要素等） | IOContext 内 |
| BR-36-05 | IOContext :limit | :limit => true で表示行数制限 | REPL表示 |
| BR-36-06 | displaysize | IOContext の displaysize でターミナルサイズを取得 | 配列表示 |
| BR-36-07 | ANSI 幅計算 | ANSIIterator で ANSI エスケープシーケンスの幅を 0 として計算 | 文字列幅計算 |

### 計算ロジック

- `_truncate_at_width_or_chars`: textwidth ベースで文字列を切り詰め、ANSI デリミタの幅を 0 として処理
- `print_range` / `print_matrix`: displaysize に基づく行列の整形出力

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

該当なし。

### テーブル別操作詳細

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | MethodError | 対象型に show メソッドが未定義 | show メソッドを定義 |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

- `sprint` は `sizehint` パラメータで IOBuffer の初期サイズを指定可能
- `_truncate_at_width_or_chars` は ANSI 対応モードと非対応モードを切り替え可能
- `ANSIIterator` は正規表現ベースで ANSI デリミタを解析

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

該当なし。

## 備考

- `show` メソッドをカスタム型に定義する際は、2引数形式（構文表現）と3引数形式（pretty-print）の両方を定義することが推奨される
- `@show` マクロは式と値の両方を表示するため、デバッグに便利
- ANSI エスケープシーケンスの正規表現パターンは `ansi_regex = r"(?s)(?:\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~]))|."` で定義

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | show.jl | `base/show.jl` | ANSIDelimiter 構造体（78-80行目）: ANSI デリミタの表現 |
| 1-2 | show.jl | `base/show.jl` | ANSIIterator 構造体（85-88行目）: ANSI 対応文字列イテレータ |
| 1-3 | show.jl | `base/show.jl` | ansi_regex 定数（75行目）: ANSI エスケープパターン |

**読解のコツ**: show.jl は非常に大きなファイル（数千行）であるため、目的の show メソッドを見つけるには型名で検索するのが効率的。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | show.jl | `base/show.jl` | show(io, ::MIME"text/plain", ...) の各型メソッド |
| 2-2 | show.jl | `base/show.jl` | show(io, ::Function) の text/plain 表示（51-69行目） |

**主要処理フロー**:
1. **51行目**: `show(io, ::MIME"text/plain", f::Function)` - 関数名とメソッド数を表示
2. **75行目**: `ansi_regex` - ANSI エスケープシーケンスの正規表現パターン
3. **100行目**: `_truncate_at_width_or_chars` - ANSI対応の文字列切り詰め

#### Step 3: 主要出力関数群を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | show.jl | `base/show.jl` | Dict / KeySet / ValueIterator の text/plain 表示（133-200行目） |

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

```
REPL 表示
    |
    +-- display(x)                          [multimedia.jl]
            +-- display(TextDisplay, MIME"text/plain", x)
                    +-- show(io, MIME"text/plain"(), x)  [show.jl]
                            |
                            +-- [Function] "name (generic function with N methods)"
                            +-- [Dict] summary + key=>value ペア
                            +-- [Array] summary + print_matrix
                            +-- [その他] フォールバック: show(io, x)

print(io, x...)
    |
    +-- show(io, x) [各引数]               [show.jl]
    +-- print(io, s::String) = write(io, s) [直接書き込み]

sprint(f, args...)
    |
    +-- IOBuffer(sizehint=sizehint)
    +-- f(IOBuffer, args...)
    +-- takestring!(IOBuffer) -> String

printstyled(io, x...; color, bold)
    |
    +-- with_output_color(color, io) do
    |       +-- "\033[...]m" [ANSI開始]
    |       +-- print(io, x...)
    |       +-- "\033[0m" [ANSIリセット]

@show expr
    |
    +-- print(stderr, "expr = ")
    +-- show(stderr, val)
    +-- println(stderr)
```

### データフロー図

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

Any オブジェクト -------> show(io, MIME"text/plain", x) --> IO ストリーム
                              |                              (テキスト表現)
                              +-> 型に応じた show メソッドをディスパッチ
                              +-> IOContext からプロパティ取得
                              +-> displaysize でサイズ制限

Any オブジェクト -------> sprint(show, x) --------------> String
                              |
                              +-> IOBuffer に書き込み
                              +-> takestring! で文字列化

色指定 + テキスト -------> printstyled(io, x; color) ----> IO ストリーム
                              |                              (ANSI色付きテキスト)
                              +-> ANSI エスケープコード付加
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| show.jl | `base/show.jl` | ソース | show メソッド群の主要実装（数千行の大規模ファイル） |
| io.jl | `base/io.jl` | ソース | print/println の基本実装、IOContext |
| strings/io.jl | `base/strings/io.jl` | ソース | string/sprint の実装 |
| multimedia.jl | `base/multimedia.jl` | ソース | display 関数（show を呼び出す） |
| methodshow.jl | `base/methodshow.jl` | ソース | メソッドリストの表示 |
| arrayshow.jl | `base/arrayshow.jl` | ソース | 配列の整形表示（print_matrix等） |
