# Permutations in practice Permutations shuffle. Enumerations pick. Most real variety in a well-authored template comes from permutations — not from stacking synonyms. This guide covers the syntax, the separator rules, and the one pattern most authors miss: serial lists in titles and headings. ## Simple permutation ``` [a|b|c] ``` Defaults: - all elements are included; - order is shuffled on every render; - separator is a single space. Output examples: `a b c`, `c a b`, `b c a`. ## Single-separator shorthand To set the separator (and `lastsep`) in one stroke: ``` [< and >a|b|c] ``` Possible outputs: `a and b and c`, `c and a and b`. The shorthand assigns the same string to both `sep` and `lastsep`, so all joins look alike. ## Full config The verbose form gives full control: ``` [a|b|c|d|e] ``` Rules: - `minsize` — smallest number of elements to emit; - `maxsize` — largest number of elements to emit; - `sep` — joins all elements except the last pair; - `lastsep` — joins the last two elements (for natural "A, B and C" output). Omit either size and the other fills in sensibly: - only `minsize` set → `maxsize` becomes "all available"; - only `maxsize` set → `minsize` becomes 1; - both larger than the element count → clamped to the total; - **the engine cannot pick zero items.** Use an empty-branch wrap for "maybe no list" (see below). ## Per-element separators If you need finer control than a global `sep`/`lastsep`, one element can carry its own separator: ``` [<, >Visa|Mastercard < and >|Skrill] ``` Here: - the global separator is `", "`; - the element after `Mastercard` carries its own local separator `" and "`. Per-element separators are rare but useful when a particular slot needs a different connector. ## Separator auto-spacing Plain word separators are auto-padded with spaces on both sides: ``` [a|b|c] ``` behaves like: ``` a and b and c ``` Punctuation separators are _not_ auto-padded: ``` [<,>a|b|c] ``` produces: ``` a,b,c ``` If you want a space after the comma, include it explicitly: `[<, >a|b|c]`. Two exceptions follow the way a language writes its lists. A separator written only in a script that puts no spaces between words — Han, Hiragana or Katakana, Thai, Lao, Khmer, Myanmar — joins bare: `[<和>a|b|c]` produces `a和b和c`. And under the `ar` locale the conjunctions `و` and `ف` keep the space before them and none after when the next item starts with an Arabic letter, because Arabic writes them attached: `الكازينو والبث`. Before a Latin word both spaces stay (`و Evolution`); `ו` under `he` works the same way. ## Optional lists Because a permutation cannot emit zero items, the way to make a list "maybe absent" is to wrap the whole permutation in an empty enumeration branch: ``` {|[Postgres|Redis|Kafka|MongoDB]} ``` Possible outputs: `Postgres and Redis`, `Kafka, Postgres and Redis`, or an empty string. Remember to handle the surrounding whitespace — keep the space inside the branch when the list may disappear. ## Serial lists in titles, descriptions, and headings This is the pattern most authors miss. Titles and H2/H3 headings often promise several parallel section themes: ``` Benefits, Integrations, and How to Get Started ``` That is _not_ a frozen string — it is a list of three parallel headline chunks. Recognize the pattern and author it as a permutation: ``` [Benefits|Integrations|How to Get Started] ``` Good inside a heading frame with a brand slot: ``` %product_name%: [Benefits|Integrations|How to Get Started] ``` Bad: ``` %product_name%: {Benefits, Integrations, and How to Get Started|A Complete Guide for Teams} ``` Why the second form is weaker: - it treats a structured list as one frozen string; - it loses the separator pattern the engine already supports; - it pushes the model toward whole-string alternation instead of reusable structure; - it produces only a handful of variants where a permutation would produce dozens. Use the serial-list pattern for: - titles that enumerate three or more promises; - meta descriptions naming several article blocks; - H1/H2/H3 headings listing parallel section themes. Do _not_ use it when the sequence is procedural and must stay in order: ``` Create an account, verify email, and make a deposit ``` That is a step sequence, not a freely permutable headline list. ## Heading casing is manual The usual body-text rule says permutation elements should start lowercase, because post-processing capitalizes sentence starts. That rule does **not** apply to title-style serial headings. Each element must already be authored in its display case: ``` [Benefits|Integrations|How to Get Started] ``` not: ``` [benefits|integrations|how to get started] ``` Post-processing will not convert a comma-separated headline list into title case for you. ### Prompt fragment — how to instruct the model When a model helps templatize an article, spell out the permutation rules explicitly: - _"For any list of 3+ parallel items, emit a permutation with `minsize`/`maxsize` and an explicit `sep`/`lastsep`. Never wrap a fixed list in an enumeration of whole-string alternatives."_ - _"Titles and headings that enumerate several themes are permutations, not frozen strings. Emit them with `minsize=N;maxsize=N` so all themes always appear but in shuffled order."_ - _"For headings, preserve title case in every element. For body text, start elements lowercase so sentence capitalization still works."_ - _"Never end a permutation element with `.`, `!`, or `?` if the separator already provides that punctuation."_ Working through an agent? The whole series is condensed into the machine-readable [spintax-authoring skill](https://spintax.net/.well-known/agent-skills/spintax-authoring/SKILL.md), and every English page has a clean Markdown mirror — append `.md` to its URL. ## Common mistakes with permutations | Don't | Why | Do instead | | --- | --- | --- | | Hardcode a fixed 4+ item list | Fixed order becomes a footprint across all renders. | Use a permutation, even with `minsize=maxsize` if the set is mandatory. | | Freeze a serial headline as one string | Loses the separator pattern; shrinks variant space dramatically. | Emit as a permutation with `sep` and `lastsep`. | | Use `minsize=0` | Engine clamps to 1 minimum; you get a silently-broken expectation. | Wrap the list in `{|[...]}` for "maybe no list at all". | | End permutation elements with a period while `sep=". "` | Double punctuation: `"fact. . next fact"`. | Let the separator add punctuation; keep elements bare. | | Forget spaces around word separators the engine already pads | Renders `aandb` when you tried to fix a non-existent problem. | Trust auto-padding for word separators; add spaces only for punctuation separators. | | Author permutation elements in mixed case | Rendered text has random-looking capitalization. | Use lowercase for body text, title case for headings. Consistent inside one permutation. | | Make every element a whole sentence with its own subject | Serial flow breaks — each element reads as a new paragraph. | Keep elements phrase-level; bind subject outside the permutation. | ## Permutation checklist - Every 3+ item list is a permutation, not a frozen string. - Serial lists in titles and headings use permutations with explicit `sep`/`lastsep`. - Optional lists are wrapped in `{|[...]}`, not attempted with `minsize=0`. - Permutation elements do not end with punctuation that the separator already supplies. - Heading permutations are authored in display case. - Body-text permutations start lowercase when post-processing will capitalize. - Every element in one permutation is grammatically parallel with the others. With structure in place, the final pass is grammar: [grammar-safe synonymization](https://spintax.net/docs/grammar-safe-spintax.md). --- ## Continue the series - [Reverse authoring mindset](https://spintax.net/docs/authoring-mindset.md): Write the text first. Add markup last. - [Variables & multi-site reuse](https://spintax.net/docs/variables.md): Precedence, reroll gotchas, separator collisions. - [Grammar-safe synonymization](https://spintax.net/docs/grammar-safe-spintax.md): Binding rules. English agreement. Russian cases: families, prepositions, gender. - [Template composition](https://spintax.net/docs/template-composition.md): Variables as rendered HTML chunks. Item → section → orchestrator pipeline. - [Conditional spintax](https://spintax.net/docs/conditional-spintax.md): Value-driven {?VAR?then|else} — the syntax-level alternative to random enum picks. - [Plural agreement](https://spintax.net/docs/plural-spintax.md): Pick the right noun form by count. RU/UK/BE and SR/HR/BS 3-form, EN-style 2-form. - [Repairing spintax templates](https://spintax.net/docs/repairing-spintax.md): Detect → one named recipe → re-check. Lint codes, the catalogue, the repair prompt. - [Spintax by example](https://spintax.net/examples.md): Every technique in the series, applied to one real paragraph, with real renders. [Open in playground](https://spintax.net/play/) [Back to all guides](https://spintax.net/docs.md) --- Source: https://spintax.net/docs/permutations/