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
Synopsis
- data SimpleHtml
- data Color
- value bold
- value italics
- value paragraph
- value headline
- value color
- value render
- value renderTree
- value encloseInTagFor
- 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.
Render a SimpleDocTree to a Builder; this is the workhorse of the tree-based rendering approach, and equivalent to renderStackMachine in the stack machine rendering tutorial.
Convert a SimpleHtml to a function that encloses a Builder in HTML tags. This is where the translation of style to raw output happens.
Example invocation
We can now render an example document using our definitions:
: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>