# base/small-spacer-merge-to-enspace

Merge exact half-em small-spacer chunks into enspace in one pass.

https://texform.dev/rules/base/small-spacer-merge-to-enspace

## Metadata

| Field | Value |
| --- | --- |
| Key | base/small-spacer-merge-to-enspace |
| Level | authoring |
| Fidelity | render |
| Enabled by packages | base |
| Profiles | Authoring, Faithful, Corpus, Equiv |

## Rewrite patterns

### thin-triple

From:

```latex
\,\,\,
```

To:

```latex
\enspace
```

### colon-semicolon

From:

```latex
\:\;
```

To:

```latex
\enspace
```

### semicolon-colon

From:

```latex
\;\:
```

To:

```latex
\enspace
```

## Examples

Examples show the rule in isolation, not a complete normalization profile.

### Thin triple

Before:

```latex
A\,\,\,B
```

After this rule:

```latex
A\enspace B
```

Packages: base.

Rendering verified with the declared packages.

### Colon semicolon

Before:

```latex
A\:\;B
```

After this rule:

```latex
A\enspace B
```

Packages: base.

Rendering verified with the declared packages.

### Semicolon colon

Before:

```latex
A\;\:B
```

After this rule:

```latex
A\enspace B
```

Packages: base.

Rendering verified with the declared packages.

### Thin multiple one pass

Before:

```latex
A\,\,\,\,\,\,\,B
```

After this rule:

```latex
A\enspace\enspace\,B
```

Packages: base.

The rendered result has pixel differences from the input.

### Mixed pair multiple one pass

Before:

```latex
A\:\;\;\:B
```

After this rule:

```latex
A\enspace\enspace B
```

Packages: base.

Rendering verified with the declared packages.

### Text run preserved

Before:

```latex
\text{A\,\,\,B}
```

After this rule:

```latex
\text{A\,\,\,B}
```

Packages: base, textmacros.

Rendering verified with the declared packages.

## Triggers

- [\\,](https://texform.dev/latex/commands/-2c-)
- [\\:](https://texform.dev/latex/commands/-3a-)
- [\\;](https://texform.dev/latex/commands/-3b-)

## Produces

- [\\enspace](https://texform.dev/latex/commands/enspace)

## Touches

- [\\,](https://texform.dev/latex/commands/-2c-)
- [\\:](https://texform.dev/latex/commands/-3a-)
- [\\;](https://texform.dev/latex/commands/-3b-)

## Upstream

- [ams/impliedby-to-Longleftarrow](https://texform.dev/rules/ams/impliedby-to-Longleftarrow): Collapse impliedby to the explicit AMS long-left-arrow spelling with source-backed spacing.
- [ams/implies-to-Longrightarrow](https://texform.dev/rules/ams/implies-to-Longrightarrow): Collapse implies to the explicit AMS long-right-arrow spelling with source-backed spacing.
- [ams/idotsint-expand](https://texform.dev/rules/ams/idotsint-expand): Expand idotsint to explicit repeated integral surfaces.
- [base/gt-space-to-colon-space](https://texform.dev/rules/base/gt-space-to-colon-space): Collapse \> to the canonical medium math space command \:
- [base/thinspace-to-comma-space](https://texform.dev/rules/base/thinspace-to-comma-space): Collapse thinspace to the explicit thin math space command.

## Downstream

- [base/double-enspace-to-quad](https://texform.dev/rules/base/double-enspace-to-quad): Rewrite two adjacent enspaces to one exact-width quad.
- [base/enspace-drop](https://texform.dev/rules/base/enspace-drop): Drop enspace in math mode and collapse each text-mode enspace run to one ordinary space.

## Same family

- [ams/nobreakspace-to-tilde](https://texform.dev/rules/ams/nobreakspace-to-tilde): Collapse nobreakspace to the canonical nonbreaking space token.
- [base/break-to-linebreak](https://texform.dev/rules/base/break-to-linebreak): Collapse break to the explicit linebreak command.
- [base/newline-to-linebreak](https://texform.dev/rules/base/newline-to-linebreak): Collapse newline to the explicit linebreak command.
- [base/control-space-to-tilde](https://texform.dev/rules/base/control-space-to-tilde): Rewrite math-mode control space to the canonical active space token.
- [base/gt-space-to-colon-space](https://texform.dev/rules/base/gt-space-to-colon-space): Collapse \> to the canonical medium math space command \:
- [base/hfil-to-hfill](https://texform.dev/rules/base/hfil-to-hfill): Collapse hfil to the canonical hfill command under MathJax spacing semantics.
- [base/hfilll-to-hfill](https://texform.dev/rules/base/hfilll-to-hfill): Collapse hfilll to the canonical hfill command.
- [base/hskip-to-hspace](https://texform.dev/rules/base/hskip-to-hspace): Collapse hskip to the explicit hspace command.
- [base/negthinspace-to-neg-comma-space](https://texform.dev/rules/base/negthinspace-to-neg-comma-space): Collapse negthinspace to the explicit negative thin math space command.
- [base/space-to-tilde](https://texform.dev/rules/base/space-to-tilde): Collapse space to the explicit nonbreaking space token.
- [base/thinspace-to-comma-space](https://texform.dev/rules/base/thinspace-to-comma-space): Collapse thinspace to the explicit thin math space command.
- [base/double-enspace-to-quad](https://texform.dev/rules/base/double-enspace-to-quad): Rewrite two adjacent enspaces to one exact-width quad.
- [base/double-quad-to-qquad](https://texform.dev/rules/base/double-quad-to-qquad): Merge two adjacent quads into one qquad for authoring normalization.
- [base/allowbreak-drop](https://texform.dev/rules/base/allowbreak-drop): Drop allowbreak as a pure linebreak hint during cleanup-oriented normalization.
- [base/badbreak-drop](https://texform.dev/rules/base/badbreak-drop): Drop badbreak as a pure linebreak hint during cleanup-oriented normalization.
- [base/goodbreak-drop](https://texform.dev/rules/base/goodbreak-drop): Drop goodbreak as a pure linebreak hint during cleanup-oriented normalization.
- [base/mathstrut-drop](https://texform.dev/rules/base/mathstrut-drop): Drop the invisible mathstrut layout helper in cleanup-oriented normalization.
- [base/nobreak-drop](https://texform.dev/rules/base/nobreak-drop): Drop nobreak as a pure linebreak hint during cleanup-oriented normalization.
- [base/strut-drop](https://texform.dev/rules/base/strut-drop): Drop the fixed empty strut node in cleanup-oriented normalization.
- [base/enspace-drop](https://texform.dev/rules/base/enspace-drop): Drop enspace in math mode and collapse each text-mode enspace run to one ordinary space.
- [base/qquad-drop](https://texform.dev/rules/base/qquad-drop): Drop qquad in math mode and collapse each text-mode qquad run to one ordinary space.
- [base/quad-drop](https://texform.dev/rules/base/quad-drop): Drop quad in math mode and collapse each text-mode quad run to one ordinary space.
- [base/mkern-to-mspace](https://texform.dev/rules/base/mkern-to-mspace): Collapse mkern to the explicit mspace command.
- [base/mskip-to-mspace](https://texform.dev/rules/base/mskip-to-mspace): Collapse mskip to the explicit mspace command.

## Notes

Authoring-level exact-width canonicalization for math-mode sibling runs. Starting at the first matching Spacer in a maximal run, scan left to right and replace every non-overlapping declared chunk in one rule application: each three consecutive \, commands become one \enspace, and each \:\; or \;\: pair becomes one \enspace. Process all available multiples at once instead of relying on later fixed-point iterations; for example, seven consecutive \, commands become \enspace\enspace\,, and \:\;\;\: becomes \enspace\enspace. Preserve unmatched remainder commands in their original order. MathJax defines \, as exactly 3/18 em and \enspace as exactly 0.5 em, so the declared width algebra is exact. The reviewed inline mismatch for repeated thin-space chunks is an accepted browser layout quantization exception: separately positioned mspace elements can accumulate to a one-pixel raster size difference even though their MathJax lengths are equal. Do not generalize this exception beyond these declared chunks or relax the global rendering threshold. Do not generalize this rule into arbitrary width decomposition or reorder other equal-width runs. Text-mode records, groups, scripts, cells, other slots, negative spacing, ActiveSpace, control space, hspace, and mspace remain unchanged. Every Applied result consumes at least one complete source chunk and produces no touched small-spacer target, so the total count of touched source spacer nodes strictly decreases.

## Disable this rule

```python
TransformEngine(profile="corpus", disable_rules=["base/small-spacer-merge-to-enspace"])
```

```javascript
new TransformEngine({ profile: 'corpus', disableRules: ['base/small-spacer-merge-to-enspace'] })
```

[Open in Playground](https://play.texform.dev/?input=A%5C%2C%5C%2C%5C%2CB)
