HORIZON HASKELLDocslts/ghc-9.10.xc74966e2026-09-27Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · c74966e · 2026-09-27

Moduleprettyprinter-1.7.1Haskell2010

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.

  • 2 types
  • 8 values
  • Packageprettyprinter-1.7.1
  • Exports10
  • LanguageHaskell2010
  • LicenceBSD-2-Clause
  • SourceTreeRenderingTutorial.hs

The type of available markup

2 declarations

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

3 declarations

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

0 declarations

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>