Spintax構文リファレンス

spintaxテンプレートマークアップの完全なリファレンス。

列挙 { }

リストからランダムに1つのオプションを選択します。

{option1|option2|option3}

{blue|grey|clear}
{|free|paid} plan                 ← empty option = sometimes nothing
{Acme {Pro|Lite}}                ← nested enumerations
{order {|#42-A} confirmed}       ← nesting with empty option

ルール

  • 区切り文字:{}
  • セパレータ:|
  • 任意の深さまでネストをサポート
  • 空のオプションは有効(空文字列を生成)
  • 最も内側の式から外側に向かって解決

順列 [ ]

N個の要素を選択し、シャッフルし、セパレータで結合します。

シンプルな順列

すべての要素を含み、スペースで区切り:

[1|2|3|4]

出力例:1 4 3 22 3 4 13 2 4 1

セパレータ付き

先頭の < > で統一セパレータを指定:

[<, > 1|2|3|4]

出力例:2, 1, 4, 34, 3, 2, 1

重要:[<セパレータ> の間にスペースを入れないでください。

要素ごとのセパレータ

各オプションは、前の | の前に <sep> で独自のセパレータを定義できます。セパレータはシャッフル時に要素と一緒に移動します。

[<, > 1|2|3 < and >|4]

出力例:1, 3, 2 and 43, 1, 2 and 4

自動スペース:<and><or> のような単語セパレータは自動的にスペースが追加され、<and> and  になります。句読点セパレータ(<,>)は追加されません。

組み合わせ付き順列

最小/最大要素数とセパレータの設定が可能:

[<minsize=1;maxsize=3;sep=", ";lastsep=" and "> apple|plum|orange|apricot]

出力例:apple, plum and orangeapple and apricotorange

設定パラメータ

パラメータデフォルト説明
minsize全件数選択する最小要素数
maxsize全件数選択する最大要素数
sep" "(スペース)最後以外の要素間のセパレータ
lastsepsepと同じ最後の要素の前のセパレータ

順列のルール

  • 区切り文字:[]
  • 設定ブロック <...>[ の直後に続く必要があります
  • 設定パラメータはセミコロンで区切ります
  • 設定内の文字列値は引用符で囲みます:sep=", "
  • 列挙と順列はオプション内にネストできます
  • HTML要素をオプションにできます
  • sep は最後の一組より前をつなぎ、lastsep はその一組をつなぎます。二つ選ばれた場合は lastsep だけが現れ、一つの場合はどちらも現れません

変数 %var%

出現するすべての箇所で置換される、再利用可能な変数を定義します。宣言できる指令は二つあり、その選択は見た目だけの違いではありません。#set はマクロで、参照のたびに値が再展開され、その中の spintax も引き直されます。#def はレンダリングごとに一度だけ値を引き、その一つの結果をすべての参照に渡します(1 回のレンダリングは 1 つの出力で、同じ seed が再現します)。値がただの文字列である限り両者は同一で、違いは値に選択が入った瞬間に現れます。

#set %VARIABLE_NAME% = value or spintax structure

#def %VARIABLE_NAME% = value or spintax structure

#set %name% = John
#set %greeting% = {Hello|Hi|Hey}
#set %items% = [<minsize=2;maxsize=3;sep=", ";lastsep=" and "> apples|oranges|bananas]
Some text with %name% and %greeting%, also %items%.
And once more, %greeting% — a second reference.

/# %greeting% above may differ between the two references — #set re-rolls.
   #def picks once and keeps it: #/
#def %tone% = {friendly|warm|upbeat}
A %tone% intro, and a %tone% outro — always the same word.

変数のルール

  • #set#def は行頭から始める必要があります
  • 変数名は % で囲みます: %name%
  • 変数名は英数字とアンダースコアで、参照は大文字小文字を区別しません: %Tone%%tone% は同じ変数です
  • 値には任意の spintax 構文を含められます(列挙、順列、ほかの変数)
  • #set はマクロです。定義時ではなく参照時に展開され、その値は — 中の spintax も含めて — 参照のたびに再展開され引き直されます
  • #def はレンダリングごとに一度だけ値を解決し、その結果をすべての参照で保持します。繰り返し現れる語の一致を保つのはこれです。名詞とそこから作る各形、{plural} に渡す数、一字一句そろえたい語句
  • #def は一つの変数を自分自身と一致させますが、二つの変数を連動させません#def %Noun%#def %NounGen% は独立した二回の抽選で、別々の語になり得ます — 一致が必要な形は一回の抽選から取る必要があります。すべての形が参照する #def の語幹を一つ置くか、同じ変化をする同義語を選び語尾を定義の外に書きます
  • 名前の定義は一度だけです。同じ名前の二つ目の定義は definition.duplicate-name として報告されますが、レンダリングはそのまま進みます。同じ指令どうしなら後のほうが有効になり、#set#def が名前を共有した場合はどちらが先でも #def が勝ちます
  • 定義のない参照は自分自身を出力します。%missing% は消えずにそのまま残ります
  • どちらの指令も #include を越えません。取り込まれたテンプレートは親のローカル変数を見られず、自分のものも親へ漏れません。引き当てた形が子に届くのはランタイム変数としてだけです
  • #set#def の行は出力から取り除かれます
  • 詳細: 変数ガイド(スコープと引き直しの落とし穴)と 文法的に安全な同義語化(格の family)

変数のスコープ

ホストは複数の場所から変数を供給できます。同じ名前が複数にある場合は、最も強いものが勝ちます。

  1. ランタイム変数(最強)— ホストがレンダリング呼び出しに渡す値。@spintax/corecontext、WordPress プラグインのショートコード属性: [spintax slug="greeting" name="Alice"]
  2. ローカル変数 — テンプレート内で #set または #def により定義
  3. グローバル変数(最弱)— プラグインの設定ページのような、ホスト全体の既定値

条件 {?VAR?then|else}

条件は この言語独自の構文 です。原型である GTW には同様のものはありませんでした。{a|b} が変数を見ない一様ランダム選択であるのに対し、{?VAR?then|else}%VAR% に値があるかどうかで選択します。

値駆動の選択に使います:無料プランがあるときだけ無料プラン行を表示する、ユーザーが有料プランの場合だけプロ機能ブロックをレンダリングする、適用されない CTA を隠す。

プリパスは %var% 展開とランダム分岐選択器より前に走るので、falsy 分岐は完全に破棄されます — その中身は評価されません。

形式

{?VAR?then}                ← truthy ⇒ then; falsy ⇒ empty
{?VAR?then|else}           ← truthy ⇒ then; falsy ⇒ else
{?!VAR?then|else}          ← inverted
{?HasFreeTier? — free tier available since %founded%|, trusted since %founded%}

Truthy と falsy

ルールは JavaScript より意図的にシンプル — truthy = 少なくとも 1 つの非空白文字:

%VAR% の値Truthy?
未宣言falsy
空文字列falsy
空白のみfalsy
"0""false"truthy(非空)
その他のテキストや HTMLtruthy

条件のルール

  • 変数名は %var% と同じ regex(大文字小文字非区別)
  • ! プレフィックスはチェックを反転:{?!VAR?なし}
  • 深さ 0 の最初の |thenelse を分け、それ以降は else 内でリテラル
  • ネストされた条件は外側から評価 — falsy 分岐はショートサーキット
  • 複合論理(&&||、比較)は非対応 — アセンブラでガード変数を事前計算
  • 不正な形式({??yes}{?VAR})は決してスローしない — プレイグラウンドで警告として表示
  • 詳細: 条件 spintax ガイド に例とアンチパターン

複数形 {plural %n%: language|languages}

数値に応じて文法的に正しい語形を選びます。カウントはコロンの前、語形はコロンの後に | 区切りで置きます。

語形を決めるのはテンプレートではなくレンダリング時のロケールです。したがって必要な語形の数はロケール次第で、英語は2つ、ロシア語は3つを要求します。

{plural %n%: form1|form2}          ← 2-form locale (en, de, es…)

{plural %n%: form1|form2|form3}    ← 3-form locale (ru, uk, sr…)
#def %LangCount% = 5
supports %LangCount% {plural %LangCount%: language|languages}
← supports 5 languages

ロケール別の語形数

ロケールは言語サブタグで判定されるため、ru-RUru は同じ挙動になります。

ロケール語形数選択基準
ruukbesrhrbs31 · 2–4 · 5 以上
その他すべて(en を含む)2ちょうど 1 · それ以外

語形の数が合わない場合、エンジンは plural.arity を報告し、全角波括弧でブロックを可視化したまま残します。誤った複数形が黙って公開されることはありません。

複数形のルール

  • 開始部分はスペースを含めてリテラルです: {plural {plural: x}{pluralN: x} は複数形ブロックではありません
  • コロンは必須で、カウントと語形を分けます
  • カウントは %Var% 参照か整数リテラル。カウント内の変数は語形選択より前に置換されます
  • 負の数は絶対値で扱い、0 は「それ以外」の語形になります
  • カウント変数は #set ではなく #def にしてください#set はマクロなので、{1|4|9} のような値は複数形を決める時点でまだ未解決の spintax であり、ブロックは空になります。プレイグラウンドは plural.count-macro として表示します
  • 数値でない、または未定義のカウントは、推測せずブロックを消去します
  • 詳細: 複数形 spintax ガイド にロシア語の3語形ルールと実例

インクルード #include

指令の位置に別のテンプレートを埋め込みます。#include はエンジンが単独では応えられない唯一の構文です。エンジンはテンプレートを保持しないため、参照をテンプレート本文に変換するリゾルバはホストが提供します。リゾルバが入っていない場所 — 本サイトのプレイグラウンドと MCP サーバー、いずれも意図的です — では指令は働かず、そのまま文字列として出力に残ります。

#include "hero-text"

/# wrong: text before the directive on the same line leaves it literal #/
Intro: #include "hero-text"

インクルードのルール

  • 指令は行全体を占める必要があります。行頭の空白は問題ありませんが、参照の後ろに文字があると成立しません — テキスト #include "hero" はそのまま残ります
  • 参照は二重引用符で囲みます。単引用符や引用符なしでは指令になりません
  • 解決はホストの仕事です。WordPress プラグインはスラッグまたは数値 ID で解決し、JavaScript ホストは includeResolver を渡します
  • リゾルバがなければ行は文字列として出力に残ります。リゾルバにそのテンプレートがない場合は、逆に行が削除されます — 未知の参照先は黙ってブロックごと失わせます
  • 取り込まれたテンプレートは自分の変数や spintax を持てますし、自分の #include も持てます
  • 取り込みは親の列挙・順列が引かれた後に解決されます。勝った枝の中の取り込みは埋め込まれ、捨てられた枝の中のものは起こりません
  • 連鎖は機能します(テンプレートが別のテンプレートを取り込み、それがさらに別を取り込む)。自分自身を直接または循環で取り込むテンプレートは最初の繰り返しで打ち切られます — エラーも診断も出ません
  • 子テンプレートはグローバル変数とランタイム変数を継承しますが、親のローカルな #set / #def継承しません。自分のものも親へ漏れません
  • 取り込みを定義の値にはできません。#def %x% = #include "y"def.include-in-value として拒否されます
  • レンダリング前、validate() が未知の参照先を指摘するのはホストが既知参照の一覧を渡したときだけです。extract() はテンプレートが必要とする参照を返し、ホストはこれで事前取得します
  • 詳細: テンプレート合成ガイド — 多くのパイプラインが代わりに使うアセンブラ方式

コメント /#...#/

コメントマーカー間のテキストは、他の処理の前に出力から除去されます。

/#
  This is a comment section.
  It can span multiple lines.
  It won't appear in output.
#/

コメントのルール

  • 開始区切り文字:/#
  • 終了区切り文字:#/
  • 複数行にまたがることができます
  • ネストはできません
  • 他の処理の前に除去されます

ネスト

すべての構文要素は任意の深さで相互にネストできます:

{option1|[<, > sub1|sub2|sub3]|option3}

[<minsize=2;maxsize=3;sep=", ";lastsep=" and "> {red|blue} apples|{big|small} oranges|bananas]

#set %var% = {a|[b|c]}

後処理

エンジンは生成後に自動テキスト補正を適用します:

  1. URL、メール、ドメイン、小数、略語を大文字化から保護
  2. 重複するスペースとタブを除去
  3. 句読点の前のスペースを除去(, . ! ?
  4. 句読点の後にスペースがない場合追加
  5. 出力の最初の文字を大文字に(HTMLタグをスキップ)
  6. 文末の句読点の後を大文字に
  7. ブロックレベルHTMLタグの後を大文字に
  8. 改行の後を大文字に
  9. 保護されたプレースホルダーを復元

構文サマリー

機能構文動作
列挙{a|b|c}ランダムに1つ選択
順列[a|b|c]N個選択、シャッフル、結合
セパレータ[<sep> a|b|c]統一セパレータ付き順列
要素別セパレータ[<, > a|b <x>|c]カスタムセパレータ付き順列
組み合わせ[<config> a|b|c]最小/最大数付き順列
変数#set %var% = {a|b}参照のたびに再展開され、中の spintax も引き直される
変数(1回のみ)#def %var% = {a|b}レンダリングごとに一度だけ引き、全参照で保持 — 語形と語尾がこれで一致する
条件{?VAR?then|else}truthy なら then、falsy なら else
複数形{plural %n%: language|languages}ロケールに従って語形を数値に一致させる
インクルード#include "slug"別のテンプレートを埋め込み — 参照はホストが解決
コメント/#...#/出力から除去

この言語は原型である Generating The Web (GTW) を超えて成長しました。GTW 向けに書かれたテンプレートは今でもそのまま動作します。