YC.PrettyPrinter


Getting started

YC.PrettyPrinters contains two sets of printer combinators: the first consists of 5 basic combinators described in the paper and the second is the same as FSharp.Text.StructuredFormat library provides. You can either use the set of basic combinators or the set of more high-level StructuredFormat-like combinators.

The best way to understand how to create pretty printers using our library is to take a look at our implementation of FSharp.Text.StructuredFormat.

The following example demonstrates how to use this library.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
43: 
44: 
45: 
46: 
47: 
48: 
#r @"..\..\bin\YC.PrettyPrinter\YC.PrettyPrinter.dll"

open YC.PrettyPrinter.Pretty
open YC.PrettyPrinter.StructuredFormat

let stmt i = wordL <| "stmt_" + string i

let stmtBlock k =
    [for i in 0 .. k - 1 -> stmt i]
    |> List.reduce (@@)

let layout =
   let condBlock = wordL "if" ^^ bracketL (wordL "cond")
   let thenBlock = wordL "then" -- (stmtBlock 2)
   let elseBlock = wordL "else" -- (stmtBlock 3)
   condBlock
   @@ thenBlock
   @@ elseBlock

/// Method print chooses the best layout for your code.
/// First argument specializes a maximum possible width.
let str = print 10 layout
printfn "Narrow box:\n%s" str

let str2 = print 30 layout
printfn "\nWide box:\n%s" str2

(*
Expected result:

Narrow box:
if (cond)
then
 stmt_0
 stmt_1
else
 stmt_0
 stmt_1
 stmt_2

Wide box:
if (cond)
then stmt_0
     stmt_1
else stmt_0
     stmt_1
     stmt_2
*)
namespace YC
namespace YC.PrettyPrinter
module Pretty

from YC.PrettyPrinter
module StructuredFormat

from YC.PrettyPrinter
val stmt : i:int -> YC.PrettyPrinter.Doc.Doc

Full name: Tutorial.stmt
val i : int
val wordL : s:string -> YC.PrettyPrinter.Doc.Doc

Full name: YC.PrettyPrinter.StructuredFormat.wordL
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = System.String

Full name: Microsoft.FSharp.Core.string
val stmtBlock : k:int -> YC.PrettyPrinter.Doc.Doc

Full name: Tutorial.stmtBlock
val k : int
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
  | ( [] )
  | ( :: ) of Head: 'T * Tail: 'T list
  interface IEnumerable
  interface IEnumerable<'T>
  member GetSlice : startIndex:int option * endIndex:int option -> 'T list
  member Head : 'T
  member IsEmpty : bool
  member Item : index:int -> 'T with get
  member Length : int
  member Tail : 'T list
  static member Cons : head:'T * tail:'T list -> 'T list
  static member Empty : 'T list

Full name: Microsoft.FSharp.Collections.List<_>
val reduce : reduction:('T -> 'T -> 'T) -> list:'T list -> 'T

Full name: Microsoft.FSharp.Collections.List.reduce
val layout : YC.PrettyPrinter.Doc.Doc

Full name: Tutorial.layout
val condBlock : YC.PrettyPrinter.Doc.Doc
val bracketL : l:YC.PrettyPrinter.Doc.Doc -> YC.PrettyPrinter.Doc.Doc

Full name: YC.PrettyPrinter.StructuredFormat.bracketL
val thenBlock : YC.PrettyPrinter.Doc.Doc
val elseBlock : YC.PrettyPrinter.Doc.Doc
val str : string

Full name: Tutorial.str


 Method print chooses the best layout for your code.
 First argument specializes a maximum possible width.
val print : resultWidth:int -> d:YC.PrettyPrinter.Doc.Doc -> string

Full name: YC.PrettyPrinter.Pretty.print
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
val str2 : string

Full name: Tutorial.str2
Fork me on GitHub