prettyprinter

repository·master·Indexed 43 days ago

https://github.com/haskell-prettyprinter/prettyprinter

A modern, high-performance Wadler/Leijen prettyprinter for Haskell that uses Text instead of String. It features a three-step model of compose, layout, and render, with extensible backends for formats like ANSI terminals and HTML. The ecosystem includes the core library, the prettyprinter-ansi-terminal renderer, and various compatibility and conversion packages for migrating from legacy wl-pprint, ansi-wl-pprint, and annotated-wl-pprint libraries.

Tokens
1.8K
Snippets
4
Records
9
Agent score
55%

What's inside prettyprinter

  1. Overview of the prettyprinter library

    master

    The prettyprinter library is a modern Wadler/Leijen-style text rendering engine designed for flexible and efficient document formatting. It follows a three-step mental model:

    1. Compose: Build a complex document out of many small components.
    2. Layout: Use a layouter to convert the document into a simplified, renderable format.
    3. Render: Convert the layout into a specific target format, such as plain Text, Markdown, or ANSI terminal output.

    Key features include Text-based internals (avoiding String), support for unobtrusive annotations (for styling or metadata), and extensible backends.

    let prettyType = align . sep . zipWith (<+>) ("::" : repeat "->")
        prettySig name ty = pretty name <+> prettyType ty
    in  prettySig "example" ["Int", "Bool", "Char", "IO ()"]
  2. Use the ANSI terminal renderer for prettyprinter

    master

    The prettyprinter-ansi-terminal package provides a renderer for documents created with the core prettyprinter library. It allows you to display these documents in ANSI-compatible terminals with support for text styling, including:

    • Colors
    • Bold text
    • Underlining
    • Italics

    To use this, you must have documents generated by the main prettyprinter package.

  3. The prettyprinter package family

    master

    The ecosystem is split into several packages depending on your needs:

    • prettyprinter: The core package defining the document language and layout logic.
    • prettyprinter-ansi-terminal: A renderer for ANSI terminal output, including color support (requires additional dependencies).
    • prettyprinter-compat-wl-pprint: A drop-in compatibility layer for users migrating from the legacy wl-pprint package.
    • prettyprinter-compat-ansi-wl-pprint: Compatibility layer for ansi-wl-pprint users.
    • prettyprinter-compat-annotated-wl-pprint: Compatibility layer for annotated-wl-pprint users.
    • prettyprinter-convert-ansi-wl-pprint: A converter (not a drop-in replacement) for documents generated by ansi-wl-pprint, useful for interfacing with libraries like Trifecta or Optparse-Applicative.
  4. Convert between ansi-wl-pprint and prettyprinter Doc types

    master

    The ansi-wl-pprint conversion package provides bidirectional conversion between the legacy ansi-wl-pprint Doc type and the modern prettyprinter Doc AnsiStyle type.

    Use this package when you have existing data generated by packages that only output ansi-wl-pprint and you want to bring that data into the prettyprinter ecosystem for rendering or further manipulation.

    Important Distinction:

    • This package performs actual data conversion between the two types.
    • This is different from prettyprinter-compat-ansi-wl-pprint, which only provides a compatibility API that mimics the ansi-wl-pprint interface while using prettyprinter internally without converting the underlying data structures.
    -- Conceptual mapping:
    -- ansi-wl-pprint Doc  <-->  prettyprinter Doc AnsiStyle
    
    -- Conversion functions:
    -- fromAnsiWlPprint :: Doc (ansi-wl-pprint) -> Doc AnsiStyle (prettyprinter)
    -- toAnsiWlPprint   :: Doc AnsiStyle (prettyprinter) -> Doc (ansi-wl-pprint)
  5. Key differences from legacy Wadler/Leijen printers

    master

    If you are moving from older wl-pprint based libraries, note these significant changes:

    • No Name Clashes: The (<$>) operator has been removed because it clashes with the standard fmap synonym.
    • Simplified API: Most operators have been removed or replaced by ordinary names, leaving only essential ones like <> and <+>.
    • Text-based: Uses Text instead of String for better performance.
    • Optimization: Includes a fuse function to optimize frequently used documents before rendering.
    • Renamed Types: SimpleDoc is now SimpleDocStream to distinguish it from the new SimpleDocTree.
    • ANSI Styling: In the ANSI backend, colorization is handled via color, colorDull, bgColor, and bgColorDull functions found in the prettyprinter-ansi-terminal package.
  6. Transition from wl-pprint to prettyprinter using the compatibility package

    master

    If you have a project that depends on the old wl-pprint package, you can transition to the new prettyprinter package by using the prettyprinter-compat-wl-pprint compatibility layer.

    To perform the transition, replace wl-pprint with prettyprinter-compat-wl-pprint in your project's .cabal file.

    Warning: This package is intended only for transitional purposes. It is deprecated and undocumented. For all new development, you should use the current version of prettyprinter directly instead of using this compatibility layer.

    -- Replace this:
    build-depends: wl-pprint
    
    -- With this:
    build-depends: prettyprinter-compat-wl-pprint
  7. Transition from ansi-wl-pprint to prettyprinter

    master

    If you are migrating a project from the old ansi-wl-pprint package to the new prettyprinter ecosystem, you can use prettyprinter-compat-ansi-wl-pprint as a compatibility layer.

    To begin the transition:

    1. Replace ansi-wl-pprint with prettyprinter-compat-ansi-wl-pprint in your .cabal file.
    2. For third-party plugins that output ansi-wl-pprint data, use the converters provided in the prettyprinter-convert-ansi-wl-pprint module to adapt the data to the new format.

    Warning: This package is intended only for transitional purposes. It is deprecated and undocumented. For all new development, use the standard prettyprinter package and the prettyprinter-ansi-terminal package for ANSI terminal output.

  8. Use the annotated-wl-pprint compatibility package for migration

    master

    The prettyprinter-compat-annotated-wl-pprint package provides a compatibility layer designed to help developers transition existing projects from the legacy annotated-wl-pprint package to the modern prettyprinter package.

    To migrate a dependent package, replace annotated-wl-pprint with prettyprinter in your .cabal file.

    Warning: This package is intended only for transitional purposes. It is considered deprecated and is undocumented. For all new development, you should use the current version of prettyprinter directly instead of using this compatibility layer.

  9. How to compose and render documents

    master

    You can compose documents using combinators like align, sep, and <+>. The library handles line wrapping automatically based on the available width. For example, a signature can be rendered on a single line if the width is sufficient, or broken into multiple lines if the format is narrow.

    Note: The library uses Text instead of String for all internal operations and output to ensure high performance.

    -- Output for wide enough formats:
    example :: Int -> Bool -> Char -> IO ()
    
    -- Output for narrow formats:
    example :: Int
            -> Bool
            -> Char
            -> IO ()