| Safe Haskell | Safe |
|---|---|
| Language | Haskell2010 |
Data.Text.Prettyprint.Doc.Render.Tutorials.StackMachineTutorial
Description
This module shows how to write a custom prettyprinter backend, based on
directly converting a SimpleDoc to an output format using a stack machine.
For a tree serialization approach, which may be more suitable for certain
output formats, see
Data.Text.Prettyprint.Doc.Render.Tutorials.TreeRenderingTutorial.
Rendering to ANSI terminal with colors is an important use case for stack machine based rendering.
The module is written to be readable top-to-bottom in both Haddock and raw source form.
- data SimpleHtml
- data Color
- bold :: Doc SimpleHtml -> Doc SimpleHtml
- italics :: Doc SimpleHtml -> Doc SimpleHtml
- paragraph :: Doc SimpleHtml -> Doc SimpleHtml
- headline :: Doc SimpleHtml -> Doc SimpleHtml
- color :: Color -> Doc SimpleHtml -> Doc SimpleHtml
- renderStackMachine :: SimpleDoc SimpleHtml -> StackMachine Builder SimpleHtml ()
- htmlTag :: SimpleHtml -> (Builder, Builder)
- render :: SimpleDoc SimpleHtml -> Text
Documentation
The type of available markup
First, we define a set of valid annotations must be defined, with the goal of
defining a . We will later define how to convert this to
the output format (Doc SimpleHtmlText).
Conveinence definitions
bold :: Doc SimpleHtml -> Doc SimpleHtml Source #
italics :: Doc SimpleHtml -> Doc SimpleHtml Source #
paragraph :: Doc SimpleHtml -> Doc SimpleHtml Source #
headline :: Doc SimpleHtml -> Doc SimpleHtml Source #
color :: Color -> Doc SimpleHtml -> Doc SimpleHtml Source #
The rendering algorithm
With the annotation definitions out of the way, we can now define a
conversion function from SimpleDoc annotated with our SimpleHtml to the
final Text representation.
renderStackMachine :: SimpleDoc SimpleHtml -> StackMachine Builder SimpleHtml () Source #
The StackMachine type defines a stack machine suitable for many rendering
needs. It has two auxiliary parameters: the type of the end result, and the
type of the document’s annotations.
Most StackMachine creations will look like this definition: a recursive walk
through the SimpleDoc, pushing styles on the stack and popping them off
again, and writing raw output.
The equivalent to this in the tree based rendering approach is
renderTree.
htmlTag :: SimpleHtml -> (Builder, Builder) Source #
Convert a SimpleHtml annotation to a pair of opening and closing tags.
This is where the translation of style to raw output happens.
render :: SimpleDoc SimpleHtml -> Text Source #
We can now wrap our stack machine definition from renderStackMachine in a
nicer interface; on successful conversion, we run the builder to give us the
final Text, and before we do that we check that the style stack is empty
(i.e. there are no unmatched style applications) after the machine is run.
This function does only a bit of plumbing around renderStackMachine, and is
the main API function of a stack machine renderer. The tree renderer
equivalent to this is
render.
Example invocation
We can now render an example document using our definitions:
>>>:set -XOverloadedStrings>>>import qualified Data.Text.Lazy.IO as TL>>>:{>>>let go = TL.putStrLn . render . layoutPretty defaultLayoutOptions>>>in 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>