# Candidate language specification ## 対象ノード | ノード | `#` | `!` | 入れ子 | |---|---|---|---| | Prompt Random Choice | コメント | 通常文字 | なし | | Prompt Random Choice Ex | 各階層でコメント | 通常文字 | あり | | Runtime Prompt Random Choice | コメント | 強制選択 | なし | | Runtime Prompt Random Choice Ex | 各階層でコメント | 各階層で強制選択 | あり | ## 共通候補分割 - 候補区切りは実改行または `|`。 - CRLFとCRはLFへ正規化する。 - 候補前後の空白、タブ、改行、カンマを除去する。 - 空候補は無視する。 - `()` は明示的な空文字候補。 - 制御記号はtrim後の先頭1文字だけを判定する。 ## `#` コメント - 先頭が `#` の候補全体を除外する。 - `#` 自体を除去して通常候補へ戻す処理ではない。 - `#!candidate` はコメント。 - Exでは各階層に同じ規則を再帰適用する。 ## Runtime限定の `!` 強制選択 - 同じ階層に `!` 候補があれば、上から最初の1件だけを残す。 - 通常候補と2件目以降の `!` 候補は、その階層では選択しない。 - 出力から制御用の先頭 `!` を1文字だけ除去する。 - `!()` は空文字を強制選択する。 - 単独の `!` はHard Error。 - `!!candidate` は `!candidate` を強制出力する。 - 従来版2ノードでは `!` を通常文字として出力する。 `!` は現在の`change_every`保持期間へ割り込まず、次回再選択時に評価する。 ## Exの階層と確率 - 1候補は直接の子グループを最大1個持てる。 - 子候補はさらに子グループを持てるため、縦方向の入れ子は許可する。 - 子を持つ親候補を同じ階層へ複数並べることも許可する。 - 各階層で `#` と、Runtimeの場合は最初の `!` を適用する。 - 絞り込み後の最終葉候補は、すべて等しい確率で選択する。 - 実装は各枝の葉数を重みとして1経路だけを選び、完成文字列を全列挙しない。 - 同じ文字列へ至る経路が複数あれば、それぞれ独立した葉として重みになる。 例: ```text A{x|y|z} B{!p|q} ``` Runtime Exでの最終葉は `A, x`、`A, y`、`A, z`、`B, p` の4件で、 各確率は `1/4`。 ## 禁止する直積構文 同じ候補へ直接子グループを複数並べる構文は禁止する。 ```text A{B|C}{D|E} ``` - 2個目の直接子グループを構文解析中に検出する。 - 候補展開や葉選択を開始する前にHard Errorとする。 - 自動的な `|` 補完や式の書き換えはしない。 - エラーには対象候補、位置、理由、String Joinを使う代替方法を含める。 許可例: ```text black hair{straight long hair|short cut} blonde hair{long hair{side braid|black ribbon}|wavy long hair} ``` ## 出力 - 親子の非空文字列を `, ` で結合する。 - 独立したランダム軸は別ノードへ分け、String Joinで結合する。 - 空の`selected_text`に対する`selected_text_safe`は `empty`。 - `selected_text_safe`はファイル名禁止記号、Windows予約名、過大な長さを回避する。