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:

[<minsize=2;maxsize=4;sep=", ";lastsep=" and ">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:

[<and>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].

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:

{|[<minsize=2;maxsize=3;sep=", ";lastsep=" and ">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:

[<minsize=3;maxsize=3;sep=", ";lastsep=", and ">Benefits|Integrations|How to Get Started]

Good inside a heading frame with a brand slot:

%product_name%: [<minsize=3;maxsize=3;sep=", ";lastsep=", and ">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:

[<minsize=3;maxsize=3;sep=", ";lastsep=", and ">Benefits|Integrations|How to Get Started]

not:

[<minsize=3;maxsize=3;sep=", ";lastsep=", and ">benefits|integrations|how to get started]

Post-processing will not convert a comma-separated headline list into title case for you.

Common mistakes with permutations

Don'tWhyDo instead
Hardcode a fixed 4+ item listFixed 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 stringLoses the separator pattern; shrinks variant space dramatically.Emit as a permutation with sep and lastsep.
Use minsize=0Engine 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 padsRenders 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 caseRendered 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 subjectSerial 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.


Continue the series