    {-# LANGUAGE CPP #-}
    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Text.PrettyPrint.ANSI.Leijen
    -- Copyright   :  Daan Leijen (c) 2000, http://www.cs.uu.nl/~daan
    --                Max Bolingbroke (c) 2008, http://blog.omega-prime.co.uk
    -- License     :  BSD-style (see the file LICENSE)
    --
    -- Maintainer  :  Edward Kmett <ekmett@gmail.com>
    -- Stability   :  provisional
    -- Portability :  portable
    --
    --
    -- This module is an extended implementation of the functional pretty printer
    -- given by Philip Wadler (1997):
    --
    -- @
    --      \"A prettier printer\"
    --      Draft paper, April 1997, revised March 1998.
    --      <https://homepages.inf.ed.ac.uk/wadler/papers/prettier/prettier.pdf>
    -- @
    --
    -- In their bare essence, the combinators given by Wadler are
    -- not expressive enough to describe some commonly occurring layouts.
    -- This library adds new primitives to describe these layouts and
    -- works well in practice.
    --
    -- The library is based on a single way to concatenate documents,
    -- which is associative and has both a left and right unit.  This
    -- simple design leads to an efficient and short implementation. The
    -- simplicity is reflected in the predictable behaviour of the
    -- combinators which make them easy to use in practice.
    --
    -- A thorough description of the primitive combinators and their
    -- implementation can be found in Philip Wadler's paper.
    -- The main differences with his original paper are:
    --
    -- * The nil document is called 'empty'.
    --
    -- * The above combinator is called '<$>'. The operator '</>' is used
    -- for soft line breaks.
    --
    -- * There are three new primitives: 'align', 'fill' and
    -- 'fillBreak'. These are very useful in practice.
    --
    -- * There are many additional useful combinators, like 'fillSep' and 'list'.
    --
    -- * There are two renderers: 'renderPretty' for pretty printing, and
    -- 'renderCompact' for quickly rendered, compact output more suitable
    -- for generating input to other programs.
    --
    -- * The pretty printing algorithm used by 'renderPretty' extends the algorithm
    -- given by Wadler to take into account a \"ribbon width\", i.e., a desired
    -- maximum number of non-indentation characters to output on any one line.
    --
    -- * There are two displayers, 'displayS' for strings and 'displayIO' for
    -- file-based output.
    --
    -- * There is a 'Pretty' class.
    --
    -- * The implementation uses optimised representations and strictness
    -- annotations.
    --
    -- * The library has been extended to allow formatting text for output
    -- to ANSI style consoles. New combinators allow control of foreground and
    -- background color and the ability to make parts of the text bold or
    -- underlined.
    -----------------------------------------------------------
    module Text.PrettyPrint.ANSI.Leijen (
       -- * The algebra of pretty-printing
       -- $DocumentAlgebra

       -- * Documents
       Doc,

       -- * Basic combinators
       empty, char, text, string, int, integer, float, double, rational, bool,
       (<>), nest, line, linebreak,
       group, softline, softbreak, hardline, flatAlt,

       -- * Alignment combinators
       --
       -- | The combinators in this section cannot be described by Wadler's
       -- original combinators. They align their output relative to the
       -- current output position — in contrast to @nest@ which always
       -- aligns to the current nesting level. This deprives these
       -- combinators from being \`optimal\'. In practice however they
       -- prove to be very useful. The combinators in this section should
       -- be used with care, since they are more expensive than the other
       -- combinators. For example, @align@ shouldn't be used to pretty
       -- print all top-level declarations of a language, but using @hang@
       -- for let expressions is fine.
       align, hang, indent, encloseSep, list, tupled, semiBraces,

       -- * Operators
       (<+>), (Text.PrettyPrint.ANSI.Leijen.Internal.<$>), (</>), (<$$>), (<//>),

       -- * List combinators
       hsep, vsep, fillSep, sep, hcat, vcat, fillCat, cat, punctuate,

       -- * Filler combinators
       fill, fillBreak,

       -- * Bracketing combinators
       enclose, squotes, dquotes, parens, angles, braces, brackets,

       -- * Named character combinators
       lparen, rparen, langle, rangle, lbrace, rbrace, lbracket, rbracket,
       squote, dquote, semi, colon, comma, space, dot, backslash, equals,

       -- * ANSI formatting combinators
       --
       -- | This terminal formatting functionality is, as far as possible,
       -- portable across platforms with their varying terminals. However,
       -- note that to display ANSI colors and formatting will only be displayed
       -- on Windows consoles if the 'Doc' value is output using the 'putDoc'
       -- function or one of its friends.  Rendering the 'Doc' to a 'String'
       -- and then outputing /that/ will only work on Unix-style operating systems.

       -- ** Forecolor combinators
       black, red, green, yellow, blue, magenta, cyan, white,
       dullblack, dullred, dullgreen, dullyellow, dullblue, dullmagenta,
       dullcyan, dullwhite,

       -- ** Backcolor combinators
       onblack, onred, ongreen, onyellow, onblue, onmagenta, oncyan, onwhite,
       ondullblack, ondullred, ondullgreen, ondullyellow, ondullblue, ondullmagenta,
       ondullcyan, ondullwhite,

       -- ** Emboldening combinators
       bold, debold,

       -- ** Underlining combinators
       underline, deunderline,

       -- ** Formatting elimination combinators
       plain,

       -- * Pretty class
       Pretty(..),

       -- * Rendering and displaying documents

       -- ** Simple (i.e., rendered) documents
       SimpleDoc(..),
       renderPretty, renderCompact, renderSmart,
       displayS,
       displayIO,

       -- ** Simultaneous rendering and displaying of documents
       putDoc, hPutDoc,

       -- * Undocumented
       column, columns, nesting, width
       ) where

    import Text.PrettyPrint.ANSI.Leijen.Internal

    #if __GLASGOW_HASKELL__ >= 710
    import Data.Monoid ((<>))
    #elif __GLASGOW_HASKELL__ >= 704
    import Data.Monoid (Monoid, mappend, mconcat, mempty, (<>))
    #else
    import Data.Monoid (Monoid, mappend, mconcat, mempty)
    infixr 6 <>
    #endif

    -- $DocumentAlgebra
    -- The combinators in this library satisfy many algebraic laws.
    --
    -- The concatenation operator '<>' is associative and has 'empty' as a left
    -- and right unit:
    --
    --     > x <> (y <> z)           = (x <> y) <> z
    --     > x <> empty              = x
    --     > empty <> x              = x
    --
    -- The 'text' combinator is a homomorphism from string concatenation to
    -- document concatenation:
    --
    --     > text (s ++ t)           = text s <> text t
    --     > text ""                 = empty
    --
    -- The 'char' combinator behaves like one-element text:
    --
    --     > char c                  = text [c]
    --
    -- The 'nest' combinator is a homomorphism from addition to document
    -- composition.  'nest' also distributes through document concatenation and is
    -- absorbed by 'text' and 'align':
    --
    --     > nest (i + j) x          = nest i (nest j x)
    --     > nest 0 x                = x
    --     > nest i (x <> y)         = nest i x <> nest i y
    --     > nest i empty            = empty
    --     > nest i (text s)         = text s
    --     > nest i (align x)        = align x
    --
    -- The 'group' combinator is absorbed by 'empty'.  'group' is commutative with
    -- 'nest' and 'align':
    --
    --     > group empty             = empty
    --     > group (text s <> x)     = text s <> group x
    --     > group (nest i x)        = nest i (group x)
    --     > group (align x)         = align (group x)
    --
    -- The 'align' combinator is absorbed by 'empty' and 'text'.
    -- 'align' is idempotent:
    --
    --     > align empty             = empty
    --     > align (text s)          = text s
    --     > align (align x)         = align x
    --
    -- From the laws of the primitive combinators, we can derive many other laws
    -- for the derived combinators.  For example, the /above/ operator '<$>' is
    -- defined as:
    --
    --     > x <$> y                 = x <> line <> y
    --
    -- It follows that '<$>' is associative and that '<$>' and '<>' associate
    -- with each other:
    --
    --     > x <$> (y <$> z)         = (x <$> y) <$> z
    --     > x <> (y <$> z)          = (x <> y) <$> z
    --     > x <$> (y <> z)          = (x <$> y) <> z
    --
    -- Similar laws also hold for the other line break operators '</>', '<$$>',
    -- and '<//>'.