Crate pretty

source ·
Expand description

This crate defines a Wadler-style pretty-printing API.

Start with with the static functions of Doc.

Quick start

Let’s pretty-print simple sexps! We want to pretty print sexps like

(1 2 3)

or, if the line would be too long, like

 (2 3)
 (4 5 6))

A simple symbolic expression consists of a numeric atom or a nested ordered list of symbolic expression children.

enum SExp {
use SExp::*;

We define a simple conversion to a Doc. Atoms are rendered as strings; lists are recursively rendered, with spaces between children where appropriate. Children are nested and grouped, allowing them to be laid out in a single line as appropriate.

impl SExp {
    /// Return a pretty printed format of self.
    pub fn to_doc(&self) -> Doc<BoxDoc<()>> {
        match *self {
            Atom(ref x) => Doc::as_string(x),
            List(ref xs) =>
                    .append(Doc::intersperse(xs.into_iter().map(|x| x.to_doc()), Doc::space()).nest(1).group())

Next, we convert the Doc to a plain old string.

impl SExp {
    pub fn to_pretty(&self, width: usize) -> String {
        let mut w = Vec::new();
        self.to_doc().render(width, &mut w).unwrap();

And finally we can test that the nesting and grouping behaves as we expected.

let atom = SExp::Atom(5);
assert_eq!("5", atom.to_pretty(10));
let list = SExp::List(vec![SExp::Atom(1), SExp::Atom(2), SExp::Atom(3)]);
assert_eq!("(1 2 3)", list.to_pretty(10));
 3)", list.to_pretty(5));

Advanced usage

There’s a more efficient pattern that uses the DocAllocator trait, as implemented by BoxAllocator, to allocate DocBuilder instances. See examples/ for this approach.


  • The DocBuilder type allows for convenient appending of documents even for arena allocated documents by storing the arena inline.
  • Writes to something implementing std::fmt::Write
  • Writes to something implementing std::io::Write
  • Newtype wrapper for &Doc


  • The concrete document type. This type is not meant to be used directly. Instead use the static functions on Doc or the methods on an DocAllocator.


  • The DocAllocator trait abstracts over a type which can allocate (pointers to) Doc.
  • Trait representing the operations necessary to render a document
  • Trait representing the operations necessary to write an annotated document.

Type Aliases

  • An arena which can be used to allocate Doc values.