Référence de syntaxe Spintax
Référence complète du balisage de modèles spintax.
Énumérations { }
Sélectionne aléatoirement une option dans la liste.
{option1|option2|option3}
Exemples
{blue|grey|clear}
{|free|paid} plan ← empty option = sometimes nothing
{Acme {Pro|Lite}} ← nested enumerations
{order {|#42-A} confirmed} ← nesting with empty option
Règles
- Délimiteurs :
{et} - Séparateur :
| - Prend en charge l'imbrication à profondeur arbitraire
- Les options vides sont valides (produisent une chaîne vide)
- La résolution va de l'expression la plus interne vers l'extérieur
Permutations [ ]
Sélectionne N éléments, les mélange et les joint avec des séparateurs.
Permutations simples
Tous les éléments inclus, séparés par des espaces :
[1|2|3|4]
Exemples de sortie : 1 4 3 2, 2 3 4 1, 3 2 4 1
Avec séparateur
Séparateur uniforme spécifié dans < > au début :
[<, > 1|2|3|4]
Exemples de sortie : 2, 1, 4, 3 · 4, 3, 2, 1
Important : Pas d'espace entre [ et <séparateur>.
Séparateurs par élément
Chaque option peut avoir son propre séparateur défini avec <sep> avant le | précédent. Le séparateur voyage avec son élément lors du mélange.
[<, > 1|2|3 < and >|4]
Exemples de sortie : 1, 3, 2 and 4 · 3, 1, 2 and 4
Espacement automatique : Les séparateurs textuels comme <and> ou <or> sont automatiquement entourés d'espaces : <and> produit and . Les séparateurs de ponctuation (<,>) ne sont pas complétés.
Permutations avec combinaisons
Nombre minimum/maximum d'éléments et séparateurs configurables :
[<minsize=1;maxsize=3;sep=", ";lastsep=" and "> apple|plum|orange|apricot]
Exemples de sortie : apple, plum and orange · apple and apricot · orange
Paramètres de configuration
| Paramètre | Par défaut | Description |
|---|---|---|
minsize | total de tous | Nombre minimum d'éléments à sélectionner |
maxsize | total de tous | Nombre maximum d'éléments à sélectionner |
sep | " " (espace) | Séparateur entre les éléments non finaux |
lastsep | identique à sep | Séparateur avant le dernier élément |
Règles de permutation
- Délimiteurs :
[et] - Le bloc de configuration
<...>doit suivre immédiatement[ - Les paramètres de configuration sont séparés par des points-virgules
- Les valeurs de chaîne dans la configuration sont entre guillemets :
sep=", " - Les énumérations et permutations peuvent être imbriquées dans les options
- Les éléments HTML peuvent être des options
sepjoint tout ce qui précède la dernière paire,lastsepjoint cette paire : avec deux éléments seullastsepapparaît, avec un seul aucun des deux
Variables %var%
Définit une variable réutilisable, substituée partout où elle apparaît. Deux directives la déclarent, et le choix n’est pas cosmétique : #set est une macro — sa valeur est resubstituée à chaque référence, donc le spintax qu’elle contient est rejoué ; #def tire la valeur une seule fois par rendu et remet ce résultat unique à toutes les références. (Un rendu est une sortie ; la même graine la reproduit.) Tant que la valeur est un texte simple, les deux sont identiques ; la différence apparaît dès que la valeur contient un choix.
#set %VARIABLE_NAME% = value or spintax structure
#def %VARIABLE_NAME% = value or spintax structure
Exemples
#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.
Règles des variables
#setet#defdoivent commencer en début de ligne- Les noms de variables sont entourés de
%:%name% - Les noms sont alphanumériques + tiret bas, et les références sont insensibles à la casse :
%Tone%et%tone%sont une seule variable - Les valeurs peuvent contenir n’importe quelle syntaxe spintax (énumérations, permutations, autres variables)
#setest une macro : elle est développée à la référence, pas à la définition, et sa valeur — y compris le spintax qu’elle contient — est resubstituée et rejouée à chaque référence#defrésout sa valeur une seule fois par rendu et conserve ce résultat partout. C’est ce qui garde les répétitions accordées : un nom et les formes qui en dérivent, un compte alimentant un bloc{plural}, toute phrase dont les répétitions doivent correspondre mot pour mot#defrend une variable cohérente avec elle-même ; il ne corrèle pas deux variables.#def %Noun%et#def %NounGen%sont deux tirages indépendants et peuvent tomber sur des mots différents — les formes qui doivent s’accorder doivent venir d’un seul tirage : un radical en#defréférencé par chaque forme, ou des synonymes qui se déclinent pareil avec la terminaison écrite hors de la définition- Un nom se définit une fois. Une seconde définition du même nom est signalée comme
definition.duplicate-nameet le rendu se poursuit malgré tout : entre deux directives identiques, la dernière l’emporte ; et quand un#setet un#defpartagent un nom, c’est le#defqui l’emporte, quel que soit celui qui vient en premier - Une référence sans définition s’imprime elle-même :
%missing%reste dans la sortie au lieu de disparaître - Aucune des deux directives ne franchit un
#include: le modèle inclus ne voit pas les locales du parent, et les siennes ne remontent pas. Une forme déjà tirée n’atteint l’enfant que comme variable d’exécution - Les lignes
#setet#defsont retirées de la sortie - Approfondir : voir le guide des variables (portées et piège du re-tirage) et la synonymisation grammaticalement sûre (familles de cas)
Portées des variables
Un hôte peut fournir des variables depuis plusieurs endroits. Quand le même nom existe dans plusieurs, le plus fort l’emporte :
- Variables d’exécution (les plus fortes) — ce que l’hôte passe à l’appel de rendu :
contextdans@spintax/core, attributs du shortcode dans l’extension WordPress :[spintax slug="greeting" name="Alice"] - Variables locales — définies avec
#setou#defdans le modèle - Variables globales (les plus faibles) — valeurs par défaut à l’échelle de l’hôte, comme la page de réglages de l’extension
Conditionnels {?VAR?then|else}
Les conditionnels sont une construction propre au langage : rien de tel n'existait dans le prototype GTW. Là où {a|b} est un tirage aléatoire uniforme qui ignore les variables, {?VAR?then|else} choisit selon que %VAR% ait une valeur ou non.
Utilisez-le pour des choix dictés par la valeur : afficher une ligne sur l'offre gratuite uniquement si elle existe, rendre un bloc fonctionnalités pro uniquement lorsque l'utilisateur a un forfait payant, masquer un CTA qui ne s'applique pas.
Le pré-traitement s'exécute avant l'expansion de %var% et avant le sélecteur de branche aléatoire, donc une branche fausse est entièrement écartée — rien à l'intérieur n'est évalué.
Formes
{?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 et falsy
La règle est volontairement plus simple qu'en JavaScript — truthy = au moins un caractère non-espace :
Valeur de %VAR% | Truthy ? |
|---|---|
| non déclarée | falsy |
| chaîne vide | falsy |
| uniquement des espaces | falsy |
"0", "false" | truthy (non vides) |
| tout autre texte ou HTML | truthy |
Règles des conditionnels
- Les noms de variables suivent la même regex que
%var%(insensibles à la casse) - Le préfixe
!inverse la vérification :{?!VAR?absent} - Le premier
|de profondeur 0 séparethenetelse; les suivants restent littéraux danselse - Les conditionnels imbriqués s'évaluent de l'extérieur — les branches fausses court-circuitent
- La logique composée (
&&,||, comparaisons) n'est pas supportée — pré-calculez une variable garde dans l'assembleur - Les formes malformées (
{??yes},{?VAR}) ne lèvent jamais d'exception — le playground les signale comme avertissements - Approfondir : voir le guide spintax conditionnel avec exemples et anti-patterns
Pluriels {plural %n%: langue|langues}
Choisit la forme grammaticalement correcte d'un mot en fonction d'un nombre. Le compteur précède les deux-points, les formes suivent, séparées par |.
La forme est choisie par la locale du rendu, pas par le modèle : le nombre de formes à fournir dépend donc de cette locale. L'anglais en demande deux, le russe trois.
{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
Formes par locale
La locale est comparée sur sa sous-balise de langue : ru-RU et ru se comportent donc à l'identique.
| Locale | Formes | Choisie selon |
|---|---|---|
ru, uk, be, sr, hr, bs | 3 | 1 · 2–4 · 5 et plus |
toutes les autres, dont en | 2 | exactement 1 · tout le reste |
Si le nombre de formes ne correspond pas, le moteur signale plural.arity et laisse le bloc visible avec des accolades pleine chasse : un pluriel faux ne part jamais en silence.
Règles des pluriels
- L'ouverture est littérale, espace compris :
{plural.{plural: x}et{pluralN: x}ne sont pas des blocs pluriels - Les deux-points sont obligatoires : ils séparent le compteur des formes
- Le compteur est une référence
%Var%ou un entier littéral ; les variables du compteur sont substituées avant le choix de la forme - Les nombres négatifs sont pris en valeur absolue ;
0reçoit la forme « tout le reste » - Une variable compteur doit être
#def, pas#set:#setest une macro, donc une valeur comme{1|4|9}est encore du spintax non résolu au moment du choix, et le bloc se rend vide. Le playground le signale parplural.count-macro - Un compteur non numérique ou indéfini efface le bloc au lieu de deviner
- Approfondir : voir le guide des pluriels pour les règles russes à trois formes et des exemples détaillés
Includes #include
Insère un autre modèle à la position de la directive. #include est la seule construction que le moteur ne peut pas assurer seul : il ne stocke aucun modèle, c’est donc l’hôte qui fournit un resolver transformant une référence en texte de modèle. Là où aucun resolver n’est installé — le playground et le serveur MCP de ce site, les deux volontairement — la directive est inerte et reste dans la sortie comme du texte littéral.
#include "hero-text"
/# wrong: text before the directive on the same line leaves it literal #/
Intro: #include "hero-text"
Règles d'inclusion
- La directive doit occuper toute la ligne. Une indentation ne gêne pas ; du texte après la référence, si —
Texte #include "hero"reste littéral - La référence est entre guillemets doubles ; avec des apostrophes ou sans guillemets, ce n’est plus la directive
- La résolution appartient à l’hôte : l’extension WordPress résout par slug ou ID numérique, un hôte JavaScript passe un
includeResolver - Sans resolver, la ligne reste littérale dans la sortie ; si le resolver n’a pas ce modèle, la ligne est supprimée — une cible inconnue vous coûte le bloc en silence
- Les modèles inclus peuvent contenir leurs propres variables et spintax, et leurs propres
#include - Les inclusions sont résolues après le tirage des énumérations et permutations du parent : une inclusion dans la branche gagnante est intégrée — une inclusion dans une branche écartée n’a jamais lieu
- Les chaînes fonctionnent (un modèle en inclut un autre qui en inclut un troisième) ; un modèle qui s’inclut lui-même, directement ou en cycle, est coupé à la première répétition — sans erreur ni diagnostic
- Les modèles enfants héritent des variables globales et d’exécution mais pas des locales
#set/#defdu parent, et les leurs ne remontent pas - Une inclusion ne peut pas être la valeur d’une définition :
#def %x% = #include "y"est rejeté commedef.include-in-value - Avant le rendu,
validate()ne signale une cible inconnue que si l’hôte fournit la liste des références connues ;extract()renvoie les références dont le modèle a besoin, ce qui permet à l’hôte de les précharger - Approfondir : voir le guide de composition de modèles, le motif d’assembleur qu’utilisent la plupart des pipelines
Commentaires /#...#/
Le texte entre les marqueurs de commentaire est supprimé de la sortie avant tout autre traitement.
/#
This is a comment section.
It can span multiple lines.
It won't appear in output.
#/
Règles des commentaires
- Délimiteur de début :
/# - Délimiteur de fin :
#/ - Peuvent s'étendre sur plusieurs lignes
- Ne peuvent pas être imbriqués
- Supprimés avant tout autre traitement
Imbrication
Tous les éléments de syntaxe peuvent être imbriqués les uns dans les autres à profondeur arbitraire :
{option1|[<, > sub1|sub2|sub3]|option3}
[<minsize=2;maxsize=3;sep=", ";lastsep=" and "> {red|blue} apples|{big|small} oranges|bananas]
#set %var% = {a|[b|c]}
Post-traitement
Le moteur applique une correction automatique du texte après la génération :
- Protège les URLs, e-mails, domaines, décimales et abréviations de la capitalisation
- Supprime les espaces et tabulations en double
- Supprime les espaces avant la ponctuation (
,.!?) - Ajoute un espace après la ponctuation si manquant
- Met en majuscule la première lettre de la sortie (en ignorant les balises HTML)
- Met en majuscule après la ponctuation de fin de phrase
- Met en majuscule après les balises HTML de niveau bloc
- Met en majuscule après les sauts de ligne
- Restaure les marqueurs protégés
Résumé de la syntaxe
| Fonctionnalité | Syntaxe | Comportement |
|---|---|---|
| Énumération | {a|b|c} | Choisit une option aléatoire |
| Permutation | [a|b|c] | Choisit N, mélange, joint |
| Séparateur | [<sep> a|b|c] | Permutation avec séparateur uniforme |
| Sep par élément | [<, > a|b <x>|c] | Permutation avec séparateurs personnalisés |
| Combinaisons | [<config> a|b|c] | Permutation avec nombre min/max |
| Variable | #set %var% = {a|b} | Resubstituée à chaque référence — le spintax qu’elle contient est rejoué |
| Variable (une fois) | #def %var% = {a|b} | Un seul tirage par rendu, conservé partout — c’est ainsi que formes et terminaisons s’accordent |
| Conditionnel | {?VAR?then|else} | then si vrai ; else si faux |
| Pluriel | {plural %n%: langue|langues} | Accorde la forme du mot avec le nombre, selon la locale |
| Include | #include "slug" | Intègre un autre modèle — la référence est résolue par l’hôte |
| Commentaire | /#...#/ | Supprimé de la sortie |
Le langage a dépassé son prototype, Generating The Web (GTW) : les modèles écrits pour GTW fonctionnent toujours sans modification.