Expand description
§pretty_lang
A language-agnostic pretty-printer: turn any syntax tree into laid-out source
text that reflows to a target line width. It is the rendering half of a
formatter — a gofmt-style tool for any language, nearly free — and knows
nothing about grammars. You describe the layout with a handful of combinators
and pretty_lang decides where the lines break.
§The idea
You do not print strings directly. Instead you build a Doc: a lazy
description that says these pieces belong together, put a break here that
becomes a space or a newline, indent the inside by four, keep this on one
line if it fits. Rendering a Doc against a width then chooses concrete
line breaks. The same document renders compactly at width 100 and stacked at
width 20, with no branching in your code.
The engine is Wadler’s A Prettier Printer in Lindig’s linear-time
imperative form: rendering is O(document size), look-ahead is bounded by
the target width, and neither pass recurses on the tree, so deeply nested
documents cannot overflow the stack.
§Quick start
use pretty_lang::Doc;
// Build `f(a, b, c)` as a document that can break into one-argument-per-line.
let call = Doc::text("f(")
.append(
Doc::softline()
.append(Doc::join(
Doc::text(",").append(Doc::line()),
["a", "b", "c"].map(Doc::text),
))
.nest(4),
)
.append(Doc::softline())
.append(Doc::text(")"))
.group();
// Wide: it all fits on one line.
assert_eq!(call.render(80), "f(a, b, c)");
// Narrow: the group breaks and the arguments stack, indented.
assert_eq!(call.render(6), "f(\n a,\n b,\n c\n)");§The combinators
| Build with | Meaning |
|---|---|
Doc::text | literal, unbreakable text |
Doc::line | space when flat, newline when broken |
Doc::softline | nothing when flat, newline when broken |
Doc::hardline | always a newline; forces enclosing groups to break |
Doc::append | put one document after another |
Doc::concat / Doc::join | fold / intersperse a sequence |
Doc::nest | indent the line breaks inside a document |
Doc::group | lay flat if it fits, otherwise break every flexible line |
Render with Doc::render (to a String), Doc::render_into (into any
core::fmt::Write), or Doc::render_writer (into a std::io::Write,
behind the std feature).
§no_std
The crate is no_std and needs only alloc. The default std feature adds
the Doc::render_writer I/O sink. There is no unsafe anywhere
(#![forbid(unsafe_code)]).
§Stability
As of 1.0.0 the public surface — the Doc type, its constructors,
combinators, render methods, and trait implementations, together with the
std feature flag — is stable and frozen under Semantic Versioning. It
will not change in a breaking way within the 1.x series; 1.x releases may
only add. See docs/API.md for the full promise.
Structs§
- Doc
- An immutable, cheaply-clonable description of a document’s layout.