liveBook · Manning

Pretty printing

As explained in Fabulous Adventures in Data Structures and Algorithms

Pretty printing is the automated formatting of source code to produce a readable layout under spacing and indentation constraints.

Pretty printing automatically formats source code into a readable layout. It balances horizontal space, vertical space, and indentation: keep lines within a typical width, reveal structure through indentation, and insert as few line breaks as possible. These goals conflict, so formatting policy becomes an algorithmic design problem. section 9.0 section 9.1

A simplified formatter makes the problem precise and separates its main transformations:

  • Parse source text into a parse tree; parsing itself is outside the formatter’s core treatment. section 9.4
  • Transform the tree into an immutable doc describing grouping, indentation, and possible line breaks. section 9.4
  • Render the doc into source code that fits the desired page width, using an iterative greedy algorithm. section 9.5
  • Use an explicit stack when the doc graph becomes deeper than the parse tree, avoiding call-stack overflow from deep recursion. section 9.5
  • Keep formatting rules separate from parse-tree classes with the visitor pattern, allowing multiple analyses or formatting policies. section 9.4

A formatting choice with competing goals

Given `if (outdated) Update(); CreateReport();`, a formatter might keep everything on one line, or break after the condition and indent `Update()`. The latter uses more vertical space but makes the control-flow structure clearer. The simplified problem excludes comments, tabs, required statement breaks, and language-specific quirks; it permits only spaces and line breaks with four-space indentation. section 9.1

double Frob(int x){int y = Qux(x); return Rezrov(y+1);}

Compare compact and irregularly spaced source with the same expression structure, motivating normalization by a pretty printer. section 9.0

How Fabulous Adventures in Data Structures and Algorithms covers it

How deep it goes
Descends from layout goals to parse-tree transformation, doc graphs, greedy rendering, explicit stacks, and visitor-based organization.
Examples
Uses irregularly spaced expressions, conditional statements, comments, delimited comments, and immutable C# expression-tree records.
What it assumes
Assumes parsing knowledge but teaches the formatting representation, rendering strategy, greedy trade-offs, and visitor-based separation.
What you can do after
Build it from scratch as a simplified, nonrecursive formatter with separate parse-tree, doc, rendering, and visitor layers.
How it connects
Connects greedy algorithms, parse trees, directed acyclic graphs, explicit stacks, visitor pattern, compilers, and code editors.

Also explained in

Compare how 3 books explain pretty printing →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Fabulous Adventures in Data Structures and Algorithms. The section links point to the parts of the book it draws on.