Rule order
The fixed order in which the nine polytypo rules run, why each sits where it does, why ranges is off by default, and how options never reorder them.
transform runs nine rules in one fixed order. The order is part of the specification, not an implementation detail, and it is identical in all five runtimes.
The order #
| Order | Rule | Default | Role |
|---|---|---|---|
| 10 | spaces | on | collapse repeated spaces, strip spaces before punctuation and inside brackets |
| 20 | ellipsis | on | three dots to the ellipsis character |
| 25 | ranges | off | numeric and date range dash |
| 30 | dashes | on | parenthetical dash |
| 35 | hyphen | on | non-breaking hyphen in listed forms |
| 40 | quotes | on | straight quotes to the locale's pairs |
| 50 | apostrophe | on | remaining straight apostrophes |
| 60 | symbols | on | (c), (r), (tm) and the multiplication sign |
| 70 | nbsp | on | no-break and narrow no-break spaces |
Why the order matters #
Each rule reads the output of the ones before it, so some orderings are required rather than chosen:
spacesis first so every later rule sees clean spacing.rangesruns beforedashes. A digit-hyphen-digit shape belongs torangesalone, whether or notrangesis enabled;dashesnever reinterprets it as a parenthetical dash.dashesruns beforehyphen. By the timehyphenruns,dasheshas already declined every hyphen that sits between letters.quotesruns beforeapostrophe. A straight apostrophe can be evidence that a single quote is part of a quotation.quotesuses that evidence first;apostrophethen converts whatever is left.nbspis last so every other rule has settled the characters around the spaces it binds.
The order also underpins idempotency: a rule may create work for a later rule but never for an earlier one.
Examples #
The input holds a digit range and a parenthetical dash. ranges is off, so the range keeps its hyphen while dashes converts the --:
Input
Output
Turning ranges on also converts the range, bound with word joiners, and dashes still handles the rest:
Input
Output
Options and order #
ranges is the only rule that is off by default. A range and a compound label such as Figure 5-10 have the same shape, and telling them apart would need the preceding word, which the rules never read. It is an explicit opt-in.
The rules option switches rules on or off by id. It never reorders them. A disabled rule is removed from the sequence and the rest keep their positions, and the order in which you list ids does not matter. Here dashes is off, so the spaced -- stays while ranges still runs:
Input
Output
Edge cases #
- Rule ids are public API. They appear in the
rulesoption. An unknown id raisesPOLYTYPO_UNKNOWN_RULE. - Which rules a locale affects varies.
spaces,apostropheandsymbolsread no locale data; the others read the fields listed on their pages.
Related #
Normative text: spec/rules/order.json.