BSD-3-Clause licensed by Dennis Gosnell
Maintained by [email protected]
This version can be pinned in stack with:pretty-simple-4.1.3.0@sha256:560989fdbbff12aa1c93d4c2b03bed06ee9b364088015c0ecd609106c71df109,3588

Text.Pretty.Simple

Build Status Hackage Stackage LTS Stackage Nightly BSD3 license

pretty-simple is a pretty printer for Haskell data types that have a Show instance.

For example, imagine the following Haskell data types and values:

data Foo = Foo { foo1 :: Integer , foo2 :: [String] } deriving Show

foo :: Foo
foo = Foo 3 ["hello", "goodbye"]

data Bar = Bar { bar1 :: Double , bar2 :: [Foo] } deriving Show

bar :: Bar
bar = Bar 10.55 [foo, foo]

If you run this in ghci and type print bar, you’ll get output like this:

> print bar
Bar {bar1 = 10.55, bar2 = [Foo {foo1 = 3, foo2 = ["hello","goodbye"]},Foo {foo1 = 3, foo2 = ["hello","goodbye"]}]}

This is pretty hard to read. Imagine if there were more fields or it were even more deeply nested. It would be even more difficult to read.

pretty-simple can be used to print bar in an easy-to-read format:

example screenshot

Usage

pretty-simple can be easily used from ghci when debugging.

When using stack to run ghci, just append the --package flag to the command line to load pretty-simple:

$ stack ghci --package pretty-simple

Or, with cabal:

$ cabal repl --build-depends pretty-simple

Once you get a prompt in ghci, you can use import to get pretty-simple’s pPrint function in scope.

> import Text.Pretty.Simple (pPrint)

You can test out pPrint with simple data types like Maybe or tuples.

> pPrint $ Just ("hello", "goodbye")
Just
    ( "hello"
    , "goodbye"
    )

If for whatever reason you’re not able to incur a dependency on the pretty-simple library, you can simulate its behaviour by using process to call out to the command line executable (see below for installation):

pPrint :: Show a => a -> IO ()
pPrint = putStrLn <=< readProcess "pretty-simple" [] . show

There’s also a web app, compiled with GHCJS, where you can play around with pretty-simple in your browser.

Features

  • Easy-to-read
    • Complex data types are simple to understand.
  • Color
    • Prints in color using ANSI escape codes.
    • It is possible to print without color by using the pPrintNoColor function.
  • Rainbow Parentheses
    • Easy to understand deeply nested data types.
  • Configurable
    • Indentation, compactness, colors and more are configurable with the pPrintOpt function.
  • Fast
    • No problem pretty-printing data types thousands of lines long.
  • Works with any data type with a Show instance
    • Some common Haskell data types have a Show instance that produces non-valid Haskell code. pretty-simple will pretty-print even these data types.

Why not (some other package)?

Other pretty-printing packages have some combination of these defects:

  • No options for printing in color.
  • No options for changing the amount of indentation
  • Requires every data type to be an instance of some special typeclass (instead of just Show).
  • Requires all Show instances to output valid Haskell code.

Other Uses

Pretty-print all GHCi output

The pPrint function can be used as the default output function in GHCi.

All you need to do is run GHCi with a command like one of these:

$ stack ghci --ghci-options "-interactive-print=Text.Pretty.Simple.pPrint" --package pretty-simple
$ cabal repl --repl-options "-interactive-print=Text.Pretty.Simple.pPrint" --build-depends pretty-simple

Now, whenever you make GHCi evaluate an expression, GHCi will pretty-print the result using pPrint! See here for more info on this neat feature in GHCi.

Pretty-printing JSON

pretty-simple can be used to pretty-print any String that is similar to Haskell data types. The only requirement is that the String must correctly use brackets, parenthese, and braces to indicate nesting.

For example, the pString function can be used to pretty-print JSON.

Recall our example from before.

data Foo = Foo { foo1 :: Integer , foo2 :: [String] } deriving Show

foo :: Foo
foo = Foo 3 ["hello", "goodbye"]

data Bar = Bar { bar1 :: Double , bar2 :: [Foo] } deriving Show

bar :: Bar
bar = Bar 10.55 [foo, foo]

You can use aeson to turn these data types into JSON. First, you must derive ToJSON instances for the data types. It is easiest to do this with Template Haskell:

{-# LANGUAGE TemplateHaskell #-}

$(deriveJSON defaultOptions ''Foo)
$(deriveJSON defaultOptions ''Bar)

If you run this in ghci and type encode bar, you’ll get output like this:

> import Data.Aeson (encode)
> putLazyByteStringLn $ encode bar
{"bar1":10.55,"bar2":[{"foo1":3,"foo2":["hello","goodbye"]},{"foo1":3,"foo2":["hello","goodbye"]}]}

Just like Haskell’s normal print output, this is pretty hard to read.

pretty-simple can be used to pretty-print the JSON-encoded bar in an easy-to-read format:

json example screenshot

(You can find the lazyByteStringToString, putLazyByteStringLn, and putLazyTextLn in the ExampleJSON.hs file.)

Pretty-printing from the command line

pretty-simple includes a command line executable that can be used to pretty-print anything passed in on stdin.

It can be installed to ~/.local/bin/ with the following command.

$ stack install pretty-simple

When run on the command line, you can paste in the Haskell datatype you want to be formatted, then hit Ctrl-D:

cli example screenshot

This is very useful if you accidentally print out a Haskell data type with print instead of pPrint.

Contributions

Feel free to open an issue or PR for any bugs/problems/suggestions/improvements.

Testing

To run the test suite locally, one must install the executables doctest and cabal-doctest, e.g. with cabal install --ignore-project doctest --flag cabal-doctest.

Then run the command cabal doctest.

Maintainers

Changes

4.1.3.0

  • Remove custom setup. This makes cross-compiling pretty-simple a lot more straightforward. No functionality has been lost from the library, since the custom setup was only used for generating tests. #107

4.1.2.0

  • Fix a problem with the pHPrint function incorrectly outputting a trailing newline to stdout, instead of the handle you pass it. #118
  • Add a web app where you can play around with pretty-simple in your browser. #116. This took a lot of hard work by @georgefst!

4.1.1.0

  • Make the pretty-printed output with outputOptionsCompact enabled a little more compact. #110. Thanks @juhp!
  • Add a --compact / -C flag to the pretty-simple executable that enables outputOptionsCompact. #111. Thanks again @juhp!
  • Add pTraceWith and pTraceShowWith to Debug.Pretty.Simple. #104. Thanks @LeviButcher!

4.1.0.0

  • Fix a regression which arose in 4.0, whereby excess spaces would be inserted for unusual strings like dates and IP addresses. #105
  • Attach warnings to debugging functions, so that they’re easy to find and remove. #103
  • Some minor improvements to the CLI tool:
    • Add a --version/-v flag. #83
    • Add a trailing newline. #87
    • Install by default, without requiring a flag. #94

4.0.0.0

  • Expand OutputOptions:
    • Compactness, including grouping of parentheses. #72
    • Page width, affecting when lines are grouped if compact output is enabled. #72
    • Indent whole expression. Useful when using pretty-simple for one part of a larger output. #71
    • Use Style type for easier configuration of colour, boldness etc. #73
  • Significant internal rewrite of printing code, to make use of the prettyprinter library. The internal function layoutString can be used to integrate with other prettyprinter backends, such as prettyprinter-lucid for HTML output. #67

3.3.0.0

  • Add an output option to print escaped and non-printable characters literally when outputting strings. #68 and #69 Thanks Joe Hermaszewski (@expipiplus1)!

3.2.3.0

  • Fix a bug that messes up printing identifiers with ' in the name. Now identifiers like data Don't = Don't show up properly. #65 Thanks George Thomas (@georgefst)!

3.2.2.0

  • Remove whitespace from the ends of lines. #62 Thanks Gaith Hallak (@ghallak)!

3.2.1.0

  • Added pTraceOpt functions to Debug.Pretty.Simple. #58 Thanks again sureyeaah!

3.2.0.0

  • Add support for pretty-printing Haskell character literals. #57 Thanks again sjakobi!

3.1.1.0

  • Added a pPrintString function for pretty-printing a String that is the output of show. Implemented in #54. Thanks sureyeaah!
  • Fix build on GHC-7.10.3. #55. Thanks sjakobi.

3.1.0.0

  • Numbers are now highlighted in green by default. Implemented in #51. Thanks lawrencebell!

3.0.0.0

  • pretty-simple now escapes non-printable characters by default. A field called outputOptionsEscapeNonPrintable has been added to OutputOptions to control this behavior. Implemented in #44. Thanks dminuoso!
  • pretty-simple now checks the output Handle to determine whether to print in color when using functions like pPrint. This makes it so that you can redirect output to a file on disk and still be able to read the output from pPrint! Implemented in #47. Thanks metiulekm!
  • Add functions like pHPrint for specifying the Handle to output to. Added in #47.

2.2.0.1

  • Fixed a bug where the parser failed to parse escaped quotation marks in string literals. Thanks Andreas!

2.2.0.0

  • Fixed a bug with a missing space after strings. Thanks again Andrew!
  • Add a command line flag --color to be able to set whether to use colors for a dark background (--color dark-bg), a light background (--color light-bg), or no color (--color no-color). This is from great work by Andrew!
  • Made parsing/printing lazy - pretty-printing will now output strings continuously as they’re read, handling potentially infinite input.

2.1.0.1

  • Fix a bug where printing deeply nested data structures would take exponential time. Thanks Andrew!

2.1.0.0

  • Make strings have indentation by default when pretty-printed. See #26. Thanks Milan!

2.0.2.1

  • Add a small command-line program that will pretty print anything from stdin called pretty-print. It can be installed to ~/.local/bin if you enable the flag buildexe like so:

    $ stack install pretty-simple-2.0.2.1 --flag pretty-simple:buildexe
    

    When you run it, you can paste something you want formatted on stdin, then press Ctrl-D. It will print the formatted version on stdout:

    $ pretty-simple
    [(Just 3, Just 4)]
    
    ^D
    
    [
        ( Just 3
        , Just 4
        )
    ]
    

2.0.2.0

  • Fix a problem with the pTraceShow functions not working correctly.

2.0.1.0

  • Added the Debug.Pretty.Simple that exports functions that work like Debug.Trace.