HORIZON HASKELLDocslts/ghc-10.0.x2b276322026-10-31Search packagesCtrl K
Theme: |

GHC 10.0.0.20260917 · lts/ghc-10.0.x · 2b27632 · 2026-10-31

Moduleprettyprinter-1.7.2Haskell2010

Prettyprinter.Render.Tutorials.TreeRenderingTutorial

This module shows how to write a custom prettyprinter backend, based on a tree representation of a SimpleDocStream. For a stack machine approach, which may be more suitable for certain output formats, see Prettyprinter.Render.Tutorials.StackMachineTutorial.

Rendering to HTML, particularly using libraries such as blaze-html or lucid, is one important use case of tree-based rendering.

The module is written to be readable top-to-bottom in both Haddock and raw source form.

Contents
  1. The type of available markup
  2. Convenience definitions
  3. The rendering algorithm
  4. Example invocation
Synopsis
  • Packageprettyprinter-1.7.2
  • Exports10
  • LanguageHaskell2010
  • LicenceBSD-2-Clause
  • SourceTreeRenderingTutorial.hs

The type of available markup

First, we define a set of valid annotations must be defined, with the goal of defining a Doc SimpleHtml. We will later define how to convert this to the output format (Text).

Convenience definitions

The rendering algorithm

With the annotation definitions out of the way, we can now define a conversion function from SimpleDocStream (annotated with our SimpleHtml) to the tree-shaped SimpleDocTree, which is easily convertible to a HTML/Text representation.

There are two ways to render this; the simpler one is just using renderSimplyDecorated. However, some output formats require more complicated functionality, so we explore this explicitly with a simple example below. An example for something more complicated is e.g. an XHTML renderer, where a newline may not simply be a newline character followed by a certain number of spaces, but e.g. involve adding a br/ tag.

To render the HTML, we first convert the SimpleDocStream to the SimpleDocTree format, which makes enveloping sub-documents in markup easier.

This function is the entry main API function of the renderer; as such, it is only glue for the internal functions. This is similar to render from the stack machine tutorial in its purpose.

Example invocation

We can now render an example document using our definitions:

Example10 expressions
:set -XOverloadedStringsimport qualified Data.Text.Lazy.IO as TL:{let go = TL.putStrLn . render . layoutPretty defaultLayoutOptionsin go (vsep    [ headline "Example document"    , paragraph ("This is a" <+> color Red "paragraph" <> comma)    , paragraph ("and" <+> bold "this text is bold.")    ]):}<h1>Example document</h1><p>This is a <span style="color: #f00">paragraph</span>,</p><p>and <strong>this text is bold.</strong></p>