Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

A typography pipeline’s output depends on the order in which its rules run: each transformation can change what the next one sees, and a later rule can even create a pattern that an earlier rule would have handled differently. To make the full pipeline stable, test the composed sequence—not just each rule on its own—and treat markup boundaries as a separate design question.

What an ordered typography pipeline does

A text-rewriting pipeline applies a sequence of transformations to input text. In the polytypo article’s description, the project defines nine rules in a fixed order in spec/rules/order.json. The article presents that order as part of the project’s behavior, not as a universal typography standard.

Position Rule
10 spaces
20 ellipsis
25 ranges (off by default, according to the article)
30 dashes
35 hyphen
40 quotes
50 apostrophe
60 symbols
70 nbsp

The article says this ordering reflects dependencies between rules: quote processing precedes apostrophe handling so a straight mark can still serve as quotation evidence; hyphen processing follows dash handling; and nonbreaking spaces are inserted after surrounding punctuation has been decided. It also describes the rules as public API. Those are claims about this project in the article, not independently verified implementation details.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

That explicit sequence matters because a pipeline is a composition. If rules are instead executed in whatever order happens to result from registration or map iteration, behavior may vary with implementation details rather than a deliberate contract.

#1 Best Overall

Why a full pass can fail to reach a fixed point

A pipeline is idempotent when applying it twice gives the same result as applying it once: transform(transform(x)) == transform(x). The polytypo article attributes this invariant to the project’s idempotency documentation. It is a property of the complete transformation, not something established merely because every rule is individually idempotent.

A later rule can undo earlier cleanup

The article gives .--. as an example. It says a pass promotes the hyphen pair to a spaced en dash, producing . – .. On a subsequent full pass, a spacing rule removes the space before the full stop, leaving . –.. This is an article-reported example, not a reproduced test here. It illustrates how a later transformation can leave behind input that an earlier transformation would have changed—after that earlier rule has already run.

The design principle is directional: a rule may create work for a later rule in the same pass, because that rule has not run yet. A rule should not create work for an earlier rule that the pipeline has already passed, unless the system deliberately repeats passes until the output stabilizes.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Context can belong to the wrong rule

A second example in the article involves French guillemets. Straight double quotes around a bare hyphen are reportedly converted into guillemets with nonbreaking spaces. A later dash rule may then treat the hyphen flanked by those spaces as a parenthetical dash on the next pass. The article says the correction belongs in dash recognition, where the relevant context can be considered, rather than in nonbreaking-space insertion.

This is a rule-ownership issue: spacing should not need to compensate for a dash rule misclassifying its input. Because the full article and implementation were not available for verification, treat both examples and the proposed fix as the article’s account rather than confirmed current behavior.

How to test the composed pipeline

Individual rule tests answer whether a rule behaves as expected in isolation. They do not prove that the ordered chain is stable, because one rule’s output becomes another rule’s input. A useful fixed-point check is to compare one full run with two:

once = transform(input)
twice = transform(once)
assert twice == once

Use representative inputs that exercise interactions between rules, including punctuation near spaces and quote marks. When a test fails, inspect the intermediate output after each rule in the declared order. That identifies which transformation introduced the pattern and which later pass changes it. The example test shape above is a general method, not a claim about polytypo’s test suite.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What spans and markup boundaries change

The title’s reference to spans raises a real implementation question: how should a text rewriter handle content divided by markup or inline elements? The available article excerpt does not establish polytypo’s span representation or edit-boundary algorithm, so details such as offset conventions, overlapping spans, or treatment of edits crossing boundaries cannot be stated reliably.

Browser text processing offers a related but distinct reference point. CSS Text Level 4 says inline box boundaries and out-of-flow elements are ignored when determining adjacency for many text-processing operations, while directing readers to a separate rule for shaping across element boundaries: CSS Text Module Level 4. That browser behavior does not establish how a library’s own spans or string edits work.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

How CSS text processing differs from rewriting stored text

CSS text processing concerns browser layout. CSS Text Level 3 lists operations such as whitespace processing, text transformation, line wrapping, bidirectional reordering, glyph selection and positioning, spacing, justification, and alignment. The specification says, “Implementations are not bound to this order as long as the resulting layout is the same.” See CSS Text Module Level 3, Appendix A. CSS Text Level 4 gives a more detailed sequence that includes whitespace trimming: CSS Text Module Level 4, order of modifying text.

Those browser sequences should not be confused with a library’s ordered mutation rules. CSS text-transform changes presentation rather than underlying content: CSS Text Level 4 says it does not alter the underlying text or plain-text copy and cautions against relying on it for semantics. See the CSS Text Level 4 text-transform section. A content-normalization pipeline, by contrast, may rewrite the text value itself.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.