Rust 2024 · hand-rolled FSM

Write for humans. Feed agents less.

xmlsquish recursively processes XML prompts, collapsing layout whitespace while keeping exactly one space between tag/tag, tag/word, and word/tag boundaries.

Inputs stay untouched; results are written beside them as .o.xml files.

This is not a semantics-preserving XML minifier. It rewrites ordinary character-data whitespace, may change mixed-content meaning, and does not honor xml:space="preserve". Use it only where that whitespace is known layout noise.

INPUT
<role>
  You are a careful agent.
</role>
<task>
  Summarize this.
</task>
OUTPUT
<role> You are a careful agent. </role> <task> Summarize this. </task>
Carriage returns, newlines, tabs, and spaces collapse to one separator at lexical-unit boundaries.

Do less, precisely

Made for prompt pipelines

This is a prompt-oriented lexical canonicalizer, not an XML Infoset minifier: it normalizes XML whitespace in ordinary character data without building a DOM.

Deterministic

One-pass scanning

A finite-state machine advances character by character. Equal inputs produce equal outputs, without formatter preferences.

Batch-ready

Paths, folders, and globs

Pass many paths at once. Directories discover *.xml recursively; globs fit into existing workflows.

Traceable

Inputs are never replaced

Each result lands in a matching *.o.xml file, leaving readable source prompts as the reviewable source of truth.

Mechanism, not magic

Form atoms, then emit once

The scanner forms Word atoms from ordinary character data and complete Markup atoms from structures. It defers whitespace runs, then one emitter joins adjacent atoms.

Boundary rule: TAG ↔ TAG, TAG ↔ WORD, and WORD ↔ TAG all emit exactly one space.
  1. DATACharacter data

    Form Word atoms and defer XML S whitespace runs.

  2. TAGTag

    A > inside a quoted attribute does not end the tag.

  3. COMMENT / CDATA / PIDelimited structures

    Recognize each terminator and preserve interior bytes verbatim.

  4. DOCTYPEDocument type

    Track quotes, comments, PIs, and internal-subset bracket depth.

Zero-ceremony batching

Give it paths

Pass any number of files, directories, or globs. With no arguments, xmlsquish prints its help.

Directories are searched recursively for *.xml; every input creates a matching *.o.xml beside it.

xmlsquish — zsh
$ cargo install --path crates/xmlsquish-cli --locked

$ xmlsquish ./prompts "templates/*.xml"
✓ 12 files processed

Account for every run

See what you actually saved

A summary covers files, tokens, characters, and whitespace, so compression stays measurable rather than anecdotal.

Tokenizer encodingo200k_base
Files processed1
Input tokens12
Output tokens9
Input characters18
Output characters15
Recognized whitespace6
Inserted whitespace1
Token compression rate25.00%

Illustrative values only; actual results depend on your files.

Friendly to authors. Frugal for agents.

View source