    {-# LANGUAGE OverloadedStrings #-}
    {-# LANGUAGE LambdaCase #-}
    {-|
    Module      : Formatting.Combinators
    Copyright   : (c) 2020 Alex Chapman
    License     : BSD3
    Maintainer  : alex@farfromthere.net
    Stability   : experimental
    Portability : GHC
    Description : Formatting combinators for building new formatters, with some useful pre-defined formatters.

    A formatting combinator takes a Format and returns another Format.
    Generally we want to change what the original format takes as its *input*,
    leaving the output polymorphic.
    Many of these combinators can be chained together to form a single 'Format'.

    Implementation detail: in order to be able to chain multiple combinators to make a single 'Format' we need them all to use the same intermediate string type, and we have chosen 'Builder'.
    This does not tie you to using 'Builder's, because the final output string type 'r' is still polymorphic.
    -}
    module Formatting.Combinators
      (
      -- * Formatting common containers
        maybed
      , optioned
      , eithered
      , lefted
      , righted

      -- * Formatting lists of data
      , concatenated
      , joinedWith
      , intercalated
      , unworded
      , unlined
      , spaced
      , commaSep
      , commaSpaceSep
      , list
      , qlist
      , took
      , dropped

      -- * Splitting strings to pass to other formatters
      , splat
      , splatWith
      , splatOn
      , worded
      , lined

      -- * Altering formatted strings
      , alteredWith
      , charsKeptIf
      , charsRemovedIf
      , replaced
      , uppercased
      , lowercased
      , titlecased
      , ltruncated
      , ctruncated
      , rtruncated
      , lpadded
      , rpadded
      , cpadded
      , lfixed
      , rfixed
      , cfixed

      -- * Wrapping formatted strings
      , prefixed
      , suffixed
      , surrounded
      , enclosed
      , squoted
      , dquoted
      , parenthesised
      , squared
      , braced
      , angled
      , backticked

      -- * Changing indentation
      , indented
      , indentedLines
      , reindented

      -- * Numerical adapters
      , roundedTo
      , truncatedTo
      , ceilingedTo
      , flooredTo

      -- * Structure formatting
      , viewed
      , accessed

      -- * Fixed-width number formatting
      , binPrefix
      , octPrefix
      , hexPrefix
      ) where

    import Control.Applicative (Const(..), getConst)
    import Control.Category ((>>>))
    import Data.Foldable (toList)
    import Data.Function ((&))
    import Data.Int (Int64)
    import Data.Text.Lazy (Text)
    import qualified Data.Text.Lazy as TL
    import Data.Text.Lazy.Builder (Builder)
    import qualified Data.Text.Lazy.Builder as TLB
    import Formatting.Internal
    import Formatting.Formatters

    -- $setup
    -- >>> import Formatting.Internal
    -- >>> import Formatting.Formatters
    -- >>> import qualified Data.Text.Lazy as TL
    -- >>> _1 g (a, x) = fmap (\b -> (b, x)) $ g a
    --
    -- We define a simplistic implementation of the lens _1, Not polymorphic in
    -- tuple length, but it works for our example without requiring the lens
    -- package.

    -- | Render a Maybe value either as a default (if Nothing) or using the given formatter:
    --
    -- >>> format (maybed "Goodbye" text) Nothing
    -- "Goodbye"
    --
    -- >>> format (maybed "Goodbye" text) (Just "Hello")
    -- "Hello"
    maybed
      :: Builder -- ^ The value to use when the input is Nothing
      -> Format Builder (a -> Builder) -- ^ The formatter to use on the value in a Just
      -> Format r (Maybe a -> r)
    maybed :: forall a r.
    Builder -> Format Builder (a -> Builder) -> Format r (Maybe a -> r)
    maybed Builder
    whenNothing Format Builder (a -> Builder)
    f = (Maybe a -> Builder) -> Format r (Maybe a -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later ((Maybe a -> Builder) -> Format r (Maybe a -> r))
    -> (Maybe a -> Builder) -> Format r (Maybe a -> r)
    forall a b. (a -> b) -> a -> b
    $ \case
      Maybe a
    Nothing -> Builder
    whenNothing
      Just a
    x -> Format Builder (a -> Builder) -> a -> Builder
    forall a. Format Builder a -> a
    bformat Format Builder (a -> Builder)
    f a
    x
    {-# INLINE maybed #-}

    -- | Render the value in a Maybe using the given formatter, or produce an empty string:
    --
    -- >>> format (optioned text) Nothing
    -- ""
    --
    -- >>> format (optioned text) (Just "Hello")
    -- "Hello"
    optioned :: Format Builder (a -> Builder) -> Format r (Maybe a -> r)
    optioned :: forall a r.
    Format Builder (a -> Builder) -> Format r (Maybe a -> r)
    optioned = Builder -> Format Builder (a -> Builder) -> Format r (Maybe a -> r)
    forall a r.
    Builder -> Format Builder (a -> Builder) -> Format r (Maybe a -> r)
    maybed Builder
    ""
    {-# INLINE optioned #-}

    -- | Render the value in an Either:
    --
    -- >>> format (eithered text int) (Left "Error!")
    -- "Error!"
    --
    -- >>> format (eithered text int) (Right 69)
    -- "69"
    eithered
      :: Format Builder (a -> Builder) -- ^ The formatter to use on a value in a Left
      -> Format Builder (b -> Builder) -- ^ The formatter to use on a value in a Right
      -> Format r (Either a b -> r)
    eithered :: forall a b r.
    Format Builder (a -> Builder)
    -> Format Builder (b -> Builder) -> Format r (Either a b -> r)
    eithered Format Builder (a -> Builder)
    l Format Builder (b -> Builder)
    r = (Either a b -> Builder) -> Format r (Either a b -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later ((Either a b -> Builder) -> Format r (Either a b -> r))
    -> (Either a b -> Builder) -> Format r (Either a b -> r)
    forall a b. (a -> b) -> a -> b
    $ \case
      Left a
    x -> Format Builder (a -> Builder) -> a -> Builder
    forall a. Format Builder a -> a
    bformat Format Builder (a -> Builder)
    l a
    x
      Right b
    x -> Format Builder (b -> Builder) -> b -> Builder
    forall a. Format Builder a -> a
    bformat Format Builder (b -> Builder)
    r b
    x
    {-# INLINE eithered #-}

    -- | Render the value in a Left with the given formatter, rendering a Right as an empty string:
    --
    -- >>> format (lefted text) (Left "bingo")
    -- "bingo"
    --
    -- >>> format (lefted text) (Right 16)
    -- ""
    lefted :: Format Builder (a -> Builder) -> Format r (Either a x -> r)
    lefted :: forall a r x.
    Format Builder (a -> Builder) -> Format r (Either a x -> r)
    lefted Format Builder (a -> Builder)
    f = Format Builder (a -> Builder)
    -> Format Builder (x -> Builder) -> Format r (Either a x -> r)
    forall a b r.
    Format Builder (a -> Builder)
    -> Format Builder (b -> Builder) -> Format r (Either a b -> r)
    eithered Format Builder (a -> Builder)
    f (Builder -> Format Builder (x -> Builder)
    forall r a. Builder -> Format r (a -> r)
    fconst Builder
    "")
    {-# INLINE lefted #-}

    -- | Render the value in a Right with the given formatter, rendering a Left as an empty string:
    --
    -- >>> format (righted text) (Left 16)
    -- ""
    --
    -- >>> format (righted text) (Right "bingo")
    -- "bingo"
    righted :: Format Builder (a -> Builder) -> Format r (Either x a -> r)
    righted :: forall a r x.
    Format Builder (a -> Builder) -> Format r (Either x a -> r)
    righted = Format Builder (x -> Builder)
    -> Format Builder (a -> Builder) -> Format r (Either x a -> r)
    forall a b r.
    Format Builder (a -> Builder)
    -> Format Builder (b -> Builder) -> Format r (Either a b -> r)
    eithered (Builder -> Format Builder (x -> Builder)
    forall r a. Builder -> Format r (a -> r)
    fconst Builder
    "")
    {-# INLINE righted #-}

    -- | Format each value in a list and concatenate them all:
    --
    -- >>> format (concatenated text) ["one", "two", "three"]
    -- "onetwothree"
    --
    -- >>> format (took 15 (concatenated bin)) [1..]
    -- "1101110010111011110001001101010111100110111101111"
    concatenated :: Foldable t => Format Builder (a -> Builder) -> Format r (t a -> r)
    concatenated :: forall (t :: * -> *) a r.
    Foldable t =>
    Format Builder (a -> Builder) -> Format r (t a -> r)
    concatenated Format Builder (a -> Builder)
    f = (t a -> Builder) -> Format r (t a -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later ((t a -> Builder) -> Format r (t a -> r))
    -> (t a -> Builder) -> Format r (t a -> r)
    forall a b. (a -> b) -> a -> b
    $ (a -> Builder) -> t a -> Builder
    forall m a. Monoid m => (a -> m) -> t a -> m
    forall (t :: * -> *) m a.
    (Foldable t, Monoid m) =>
    (a -> m) -> t a -> m
    foldMap (Format Builder (a -> Builder) -> a -> Builder
    forall a. Format Builder a -> a
    bformat Format Builder (a -> Builder)
    f)
    {-# INLINE concatenated #-}

    -- | Use the given text-joining function to join together the individually rendered items of a list.
    --
    -- >>> format (joinedWith (mconcat . reverse) int) [123, 456, 789]
    -- "789456123"
    joinedWith :: Foldable t => ([Text] -> Text) -> Format Builder (a -> Builder) -> Format r (t a -> r)
    joinedWith :: forall (t :: * -> *) a r.
    Foldable t =>
    ([Text] -> Text)
    -> Format Builder (a -> Builder) -> Format r (t a -> r)
    joinedWith [Text] -> Text
    joiner Format Builder (a -> Builder)
    f = (t a -> Builder) -> Format r (t a -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later ((t a -> Builder) -> Format r (t a -> r))
    -> (t a -> Builder) -> Format r (t a -> r)
    forall a b. (a -> b) -> a -> b
    $ t a -> [a]
    forall a. t a -> [a]
    forall (t :: * -> *) a. Foldable t => t a -> [a]
    toList
      (t a -> [a]) -> ([a] -> Builder) -> t a -> Builder
    forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
    Category cat =>
    cat a b -> cat b c -> cat a c
    >>> (a -> Text) -> [a] -> [Text]
    forall a b. (a -> b) -> [a] -> [b]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (Format Builder (a -> Builder) -> a -> Builder
    forall a. Format Builder a -> a
    bformat Format Builder (a -> Builder)
    f (a -> Builder) -> (Builder -> Text) -> a -> Text
    forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
    Category cat =>
    cat a b -> cat b c -> cat a c
    >>> Builder -> Text
    TLB.toLazyText)
      ([a] -> [Text]) -> ([Text] -> Builder) -> [a] -> Builder
    forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
    Category cat =>
    cat a b -> cat b c -> cat a c
    >>> [Text] -> Text
    joiner
      ([Text] -> Text) -> (Text -> Builder) -> [Text] -> Builder
    forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
    Category cat =>
    cat a b -> cat b c -> cat a c
    >>> Text -> Builder
    TLB.fromLazyText
    {-# INLINABLE joinedWith #-}

    -- | Format each value in a list and place the given string between each:
    --
    -- >>> fprintLn (intercalated "||" int) [1, 2, 3]
    -- 1||2||3
    intercalated :: Foldable t => Text -> Format Builder (a -> Builder) -> Format r (t a -> r)
    intercalated :: forall (t :: * -> *) a r.
    Foldable t =>
    Text -> Format Builder (a -> Builder) -> Format r (t a -> r)
    intercalated Text
    s = ([Text] -> Text)
    -> Format Builder (a -> Builder) -> Format r (t a -> r)
    forall (t :: * -> *) a r.
    Foldable t =>
    ([Text] -> Text)
    -> Format Builder (a -> Builder) -> Format r (t a -> r)
    joinedWith (Text -> [Text] -> Text
    TL.intercalate Text
    s)
    {-# INLINE intercalated #-}

    -- | Format each value in a list with spaces in between:
    --
    -- >>> format (unworded int) [1, 2, 3]
    -- "1 2 3"
    unworded :: Foldable t => Format Builder (a -> Builder) -> Format r (t a -> r)
    unworded :: forall (t :: * -> *) a r.
    Foldable t =>
    Format Builder (a -> Builder) -> Format r (t a -> r)
    unworded = ([Text] -> Text)
    -> Format Builder (a -> Builder) -> Format r (t a -> r)
    forall (t :: * -> *) a r.
    Foldable t =>
    ([Text] -> Text)
    -> Format Builder (a -> Builder) -> Format r (t a -> r)
    joinedWith [Text] -> Text
    TL.unwords
    {-# INLINE unworded #-}

    -- | Format each value in a list, placing each on its own line:
    --
    -- >>> fprint (unlined char) ['a'..'c']
    -- a
    -- b
    -- c
    unlined :: Foldable t => Format Builder (a -> Builder) -> Format r (t a -> r)
    unlined :: forall (t :: * -> *) a r.
    Foldable t =>
    Format Builder (a -> Builder) -> Format r (t a -> r)
    unlined = ([Text] -> Text)
    -> Format Builder (a -> Builder) -> Format r (t a -> r)
    forall (t :: * -> *) a r.
    Foldable t =>
    ([Text] -> Text)
    -> Format Builder (a -> Builder) -> Format r (t a -> r)
    joinedWith [Text] -> Text
    TL.unlines
    {-# INLINE unlined #-}

    -- | Separate the formatted items of the Foldable (e.g. list) with spaces:
    --
    -- >>> format (spaced int) [1, 2, 3]
    -- "1 2 3"
    --
    -- Note that this behaviour is identical to 'unworded', it's just a different way of thinking about it.
    spaced :: Foldable t => Format Builder (a -> Builder) -> Format r (t a -> r)
    spaced :: forall (t :: * -> *) a r.
    Foldable t =>
    Format Builder (a -> Builder) -> Format r (t a -> r)
    spaced = Text -> Format Builder (a -> Builder) -> Format r (t a -> r)
    forall (t :: * -> *) a r.
    Foldable t =>
    Text -> Format Builder (a -> Builder) -> Format r (t a -> r)
    intercalated Text
    " "
    {-# INLINE spaced #-}

    -- | Separate the formatted items of the Foldable (e.g. list) with commas:
    --
    -- >>> format (commaSep stext) ["one", "two", "three", "four", "five"]
    -- "one,two,three,four,five"
    --
    -- >>> format (took 5 (commaSep int)) [1..]
    -- "1,2,3,4,5"
    commaSep :: Foldable t => Format Builder (a -> Builder) -> Format r (t a -> r)
    commaSep :: forall (t :: * -> *) a r.
    Foldable t =>
    Format Builder (a -> Builder) -> Format r (t a -> r)
    commaSep = Text -> Format Builder (a -> Builder) -> Format r (t a -> r)
    forall (t :: * -> *) a r.
    Foldable t =>
    Text -> Format Builder (a -> Builder) -> Format r (t a -> r)
    intercalated Text
    ","
    {-# INLINE commaSep #-}

    -- | Separate the formatted items of the Foldable (e.g. list) with commas and spaces:
    --
    -- >>> format (took 3 (commaSpaceSep ords)) [1..]
    -- "1st, 2nd, 3rd"
    commaSpaceSep :: Foldable t => Format Builder (a -> Builder) -> Format r (t a -> r)
    commaSpaceSep :: forall (t :: * -> *) a r.
    Foldable t =>
    Format Builder (a -> Builder) -> Format r (t a -> r)
    commaSpaceSep = Text -> Format Builder (a -> Builder) -> Format r (t a -> r)
    forall (t :: * -> *) a r.
    Foldable t =>
    Text -> Format Builder (a -> Builder) -> Format r (t a -> r)
    intercalated Text
    ", "
    {-# INLINE commaSpaceSep #-}

    -- | Add square brackets around the Foldable (e.g. a list), and separate each formatted item with a comma and space.
    --
    -- >>> format (list stext) ["one", "two", "three"]
    -- "[one, two, three]"
    --
    -- >>> format (list shown) ["one", "two", "three"]
    -- "[\"one\", \"two\", \"three\"]"
    list :: Foldable t => Format Builder (a -> Builder) -> Format r (t a -> r)
    list :: forall (t :: * -> *) a r.
    Foldable t =>
    Format Builder (a -> Builder) -> Format r (t a -> r)
    list = Format Builder (a -> Builder) -> Format r (t a -> r)
    forall (t :: * -> *) a r.
    Foldable t =>
    Format Builder (a -> Builder) -> Format r (t a -> r)
    commaSpaceSep (Format Builder (a -> Builder) -> Format r (t a -> r))
    -> (Format r (t a -> r) -> Format r (t a -> r))
    -> Format Builder (a -> Builder)
    -> Format r (t a -> r)
    forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
    Category cat =>
    cat a b -> cat b c -> cat a c
    >>> Format r (t a -> r) -> Format r (t a -> r)
    forall r a. Format r a -> Format r a
    squared
    {-# INLINE list #-}

    -- | Like 'list', but also put double quotes around each rendered item:
    --
    -- >>> fprintLn (qlist stext) ["one", "two", "three"]
    -- ["one", "two", "three"]
    qlist :: Foldable t => Format Builder (a -> Builder) -> Format r (t a -> r)
    qlist :: forall (t :: * -> *) a r.
    Foldable t =>
    Format Builder (a -> Builder) -> Format r (t a -> r)
    qlist = Format Builder (a -> Builder) -> Format Builder (a -> Builder)
    forall r a. Format r a -> Format r a
    dquoted (Format Builder (a -> Builder) -> Format Builder (a -> Builder))
    -> (Format Builder (a -> Builder) -> Format r (t a -> r))
    -> Format Builder (a -> Builder)
    -> Format r (t a -> r)
    forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
    Category cat =>
    cat a b -> cat b c -> cat a c
    >>> Format Builder (a -> Builder) -> Format r (t a -> r)
    forall (t :: * -> *) a r.
    Foldable t =>
    Format Builder (a -> Builder) -> Format r (t a -> r)
    commaSpaceSep (Format Builder (a -> Builder) -> Format r (t a -> r))
    -> (Format r (t a -> r) -> Format r (t a -> r))
    -> Format Builder (a -> Builder)
    -> Format r (t a -> r)
    forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
    Category cat =>
    cat a b -> cat b c -> cat a c
    >>> Format r (t a -> r) -> Format r (t a -> r)
    forall r a. Format r a -> Format r a
    squared
    {-# INLINE qlist #-}

    -- | Take only the first n items from the list of items.
    --
    -- >>> format (took 7 (list bin)) [1..]
    -- "[1, 10, 11, 100, 101, 110, 111]"
    --
    -- >>> format (list bin) (take 7 [1..])
    -- "[1, 10, 11, 100, 101, 110, 111]"
    took :: Int -> Format r ([a] -> r) -> Format r ([a] -> r)
    took :: forall r a. Int -> Format r ([a] -> r) -> Format r ([a] -> r)
    took Int
    n = (([a] -> r) -> [a] -> r)
    -> Format r ([a] -> r) -> Format r ([a] -> r)
    forall a b. (a -> b) -> Format r a -> Format r b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (([a] -> r) -> ([a] -> [a]) -> [a] -> r
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> [a] -> [a]
    forall a. Int -> [a] -> [a]
    take Int
    n)
    {-# INLINE took #-}

    -- | Drop the first n items from the list of items.
    --
    -- >>> format (dropped 3 (list int)) [1..6]
    -- "[4, 5, 6]"
    dropped :: Int -> Format r ([a] -> r) -> Format r ([a] -> r)
    dropped :: forall r a. Int -> Format r ([a] -> r) -> Format r ([a] -> r)
    dropped Int
    n = (([a] -> r) -> [a] -> r)
    -> Format r ([a] -> r) -> Format r ([a] -> r)
    forall a b. (a -> b) -> Format r a -> Format r b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (([a] -> r) -> ([a] -> [a]) -> [a] -> r
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> [a] -> [a]
    forall a. Int -> [a] -> [a]
    drop Int
    n)
    {-# INLINE dropped #-}

    -- | Utility for taking a text-splitting function and turning it into a formatting combinator.
    --
    -- >>> format (splatWith (TL.chunksOf 3) list int) 1234567890
    -- "[123, 456, 789, 0]"
    splatWith
      :: (Text -> [Text]) -- ^ The text splitter
      -> (Format r' (Builder -> r') -> Format Builder ([Builder] -> Builder)) -- ^ A list-formatting combinator, e.g. 'unworded', 'list', 'concatenated', etc.
      -> Format r a -- ^ The base formatter, whose rendered text will be split
      -> Format r a
    splatWith :: forall r' r a.
    (Text -> [Text])
    -> (Format r' (Builder -> r')
        -> Format Builder ([Builder] -> Builder))
    -> Format r a
    -> Format r a
    splatWith Text -> [Text]
    splitter Format r' (Builder -> r') -> Format Builder ([Builder] -> Builder)
    lf Format r a
    f = (Builder -> Builder) -> Format r (Builder -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later (Builder -> Text
    TLB.toLazyText
      (Builder -> Text) -> (Text -> Builder) -> Builder -> Builder
    forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
    Category cat =>
    cat a b -> cat b c -> cat a c
    >>> Text -> [Text]
    splitter
      (Text -> [Text]) -> ([Text] -> Builder) -> Text -> Builder
    forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
    Category cat =>
    cat a b -> cat b c -> cat a c
    >>> (Text -> Builder) -> [Text] -> [Builder]
    forall a b. (a -> b) -> [a] -> [b]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Text -> Builder
    TLB.fromLazyText
      ([Text] -> [Builder])
    -> ([Builder] -> Builder) -> [Text] -> Builder
    forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
    Category cat =>
    cat a b -> cat b c -> cat a c
    >>> Format Builder ([Builder] -> Builder) -> [Builder] -> Builder
    forall a. Format Builder a -> a
    bformat (Format r' (Builder -> r') -> Format Builder ([Builder] -> Builder)
    lf Format r' (Builder -> r')
    forall r. Format r (Builder -> r)
    builder))
      Format r (Builder -> r) -> Format r a -> Format r a
    forall r r' a.
    Format r (Builder -> r') -> Format r' a -> Format r a
    %. Format r a
    f
    {-# INLINABLE splatWith #-}

    -- | Split the formatted item in places the given predicated matches, and use the given list combinator to render the resultant list of strings
    -- (this function was sent to us from a parallel universe in which splat is the past participle of split, e.g. "whoops, I splat my pants").
    --
    -- >>> format (splat Data.Char.isSpace commaSpaceSep stext) "This\t  is\n\t\t  poorly formatted   "
    -- "This, , , is, , , , , poorly, formatted, , , "
    splat
      :: (Char -> Bool) -- ^ Whether to split the string at this character
      -> (Format r' (Builder -> r') -> Format Builder ([Builder] -> Builder)) -- ^ A list-formatting combinator, e.g. 'unworded', 'list', 'concatenated', etc.
      -> Format r a -- ^ The base formatter, whose rendered text will be split
      -> Format r a
    splat :: forall r' r a.
    (Char -> Bool)
    -> (Format r' (Builder -> r')
        -> Format Builder ([Builder] -> Builder))
    -> Format r a
    -> Format r a
    splat Char -> Bool
    p = (Text -> [Text])
    -> (Format r' (Builder -> r')
        -> Format Builder ([Builder] -> Builder))
    -> Format r a
    -> Format r a
    forall r' r a.
    (Text -> [Text])
    -> (Format r' (Builder -> r')
        -> Format Builder ([Builder] -> Builder))
    -> Format r a
    -> Format r a
    splatWith ((Char -> Bool) -> Text -> [Text]
    TL.split Char -> Bool
    p)
    {-# INLINE splat #-}

    -- | Split the formatted item at instances of the given string, and use the given list combinator to render the resultant list of strings.
    --
    -- >>> fprint (splatOn "," unlined text) "one,two,three"
    -- one
    -- two
    -- three
    --
    -- >>> fprint (splatOn "," (indentedLines 4) text) "one,two,three"
    --     one
    --     two
    --     three
    splatOn
      :: Text -- ^ The text to split on
      -> (Format r' (Builder -> r') -> Format Builder ([Builder] -> Builder)) -- ^ A list-formatting combinator, e.g. 'unworded', 'list', 'concatenated', etc.
      -> Format r a -- ^ The base formatter, whose rendered text will be split
      -> Format r a
    splatOn :: forall r' r a.
    Text
    -> (Format r' (Builder -> r')
        -> Format Builder ([Builder] -> Builder))
    -> Format r a
    -> Format r a
    splatOn Text
    t = (Text -> [Text])
    -> (Format r' (Builder -> r')
        -> Format Builder ([Builder] -> Builder))
    -> Format r a
    -> Format r a
    forall r' r a.
    (Text -> [Text])
    -> (Format r' (Builder -> r')
        -> Format Builder ([Builder] -> Builder))
    -> Format r a
    -> Format r a
    splatWith (HasCallStack => Text -> Text -> [Text]
    Text -> Text -> [Text]
    TL.splitOn Text
    t)
    {-# INLINE splatOn #-}

    -- | Split the formatted item into words and use the given list combinator to render the resultant list of strings.
    --
    -- >>> format (worded list text) "one  two three  "
    -- "[one, two, three]"
    worded
      :: (Format r' (Builder -> r') -> Format Builder ([Builder] -> Builder)) -- ^ A list-formatting combinator, e.g. 'unworded', 'list', 'concatenated', etc.
      -> Format r a -- ^ The base formatter, whose rendered text will be split
      -> Format r a
    worded :: forall r' r a.
    (Format r' (Builder -> r')
     -> Format Builder ([Builder] -> Builder))
    -> Format r a -> Format r a
    worded = (Text -> [Text])
    -> (Format r' (Builder -> r')
        -> Format Builder ([Builder] -> Builder))
    -> Format r a
    -> Format r a
    forall r' r a.
    (Text -> [Text])
    -> (Format r' (Builder -> r')
        -> Format Builder ([Builder] -> Builder))
    -> Format r a
    -> Format r a
    splatWith Text -> [Text]
    TL.words
    {-# INLINE worded #-}

    -- | Split the formatted item into lines and use the given list combinator to render the resultant list of strings.
    --
    -- >>> fprintLn (lined qlist text) "one two three\n\nfour five six\nseven eight nine\n\n"
    -- ["one two three", "", "four five six", "seven eight nine", ""]
    lined
      :: (Format Builder (Builder -> Builder) -> Format Builder ([Builder] -> Builder)) -- ^ A list-formatting combinator, e.g. 'unworded', 'list', 'concatenated', etc.
      -> Format r a -- ^ The base formatter, whose rendered text will be split
      -> Format r a
    lined :: forall r a.
    (Format Builder (Builder -> Builder)
     -> Format Builder ([Builder] -> Builder))
    -> Format r a -> Format r a
    lined = (Text -> [Text])
    -> (Format Builder (Builder -> Builder)
        -> Format Builder ([Builder] -> Builder))
    -> Format r a
    -> Format r a
    forall r' r a.
    (Text -> [Text])
    -> (Format r' (Builder -> r')
        -> Format Builder ([Builder] -> Builder))
    -> Format r a
    -> Format r a
    splatWith Text -> [Text]
    TL.lines
    {-# INLINE lined #-}

    -- | Alter the formatted string with the given function.
    --
    -- >>> format (alteredWith Data.Text.Lazy.reverse int) 123456
    -- "654321"
    alteredWith :: (Text -> Text) -> Format r a -> Format r a
    alteredWith :: forall r a. (Text -> Text) -> Format r a -> Format r a
    alteredWith Text -> Text
    alterer Format r a
    f =
      (Builder -> Builder) -> Format r (Builder -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later (Builder -> Text
    TLB.toLazyText (Builder -> Text) -> (Text -> Builder) -> Builder -> Builder
    forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
    Category cat =>
    cat a b -> cat b c -> cat a c
    >>> Text -> Text
    alterer (Text -> Text) -> (Text -> Builder) -> Text -> Builder
    forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
    Category cat =>
    cat a b -> cat b c -> cat a c
    >>> Text -> Builder
    TLB.fromLazyText) Format r (Builder -> r) -> Format r a -> Format r a
    forall r r' a.
    Format r (Builder -> r') -> Format r' a -> Format r a
    %. Format r a
    f
    {-# INLINABLE alteredWith #-}

    -- | Filter the formatted string to contain only characters which pass the given predicate:
    --
    -- >>> format (charsKeptIf Data.Char.isUpper text) "Data.Char.isUpper"
    -- "DCU"
    charsKeptIf :: (Char -> Bool) -> Format r a -> Format r a
    charsKeptIf :: forall r a. (Char -> Bool) -> Format r a -> Format r a
    charsKeptIf Char -> Bool
    p = (Text -> Text) -> Format r a -> Format r a
    forall r a. (Text -> Text) -> Format r a -> Format r a
    alteredWith ((Char -> Bool) -> Text -> Text
    TL.filter Char -> Bool
    p)
    {-# INLINE charsKeptIf #-}

    -- | Filter the formatted string to not contain characters which pass the given predicate:
    --
    -- >>> format (charsRemovedIf Data.Char.isUpper text) "Data.Char.isUpper"
    -- "ata.har.ispper"
    charsRemovedIf :: (Char -> Bool) -> Format r a -> Format r a
    charsRemovedIf :: forall r a. (Char -> Bool) -> Format r a -> Format r a
    charsRemovedIf Char -> Bool
    p = (Text -> Text) -> Format r a -> Format r a
    forall r a. (Text -> Text) -> Format r a -> Format r a
    alteredWith ((Char -> Bool) -> Text -> Text
    TL.filter (Bool -> Bool
    not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Char -> Bool
    p))
    {-# INLINE charsRemovedIf #-}

    -- | Take a formatter and replace the given needle with the given replacement in its output.
    --
    -- >>> format (replaced "Bruce" "<redacted>" stext) "Bruce replied that Bruce's name was, in fact, '<redacted>'."
    -- "<redacted> replied that <redacted>'s name was, in fact, '<redacted>'."
    replaced :: Text -> Text -> Format r a -> Format r a
    replaced :: forall r a. Text -> Text -> Format r a -> Format r a
    replaced Text
    needle Text
    replacement = (Text -> Text) -> Format r a -> Format r a
    forall r a. (Text -> Text) -> Format r a -> Format r a
    alteredWith (HasCallStack => Text -> Text -> Text -> Text
    Text -> Text -> Text -> Text
    TL.replace Text
    needle Text
    replacement)
    {-# INLINE replaced #-}

    -- | Convert any letters in the output of the given formatter to upper-case.
    --
    -- >>> format (uppercased text) "I'm not shouting, you're shouting."
    -- "I'M NOT SHOUTING, YOU'RE SHOUTING."
    uppercased :: Format r a -> Format r a
    uppercased :: forall r a. Format r a -> Format r a
    uppercased = (Text -> Text) -> Format r a -> Format r a
    forall r a. (Text -> Text) -> Format r a -> Format r a
    alteredWith Text -> Text
    TL.toUpper
    {-# INLINE uppercased #-}

    -- | Convert any letters in the output of the given formatter to lower-case.
    --
    -- >>> format (lowercased text) "Cd SrC/; Rm -Rf *"
    -- "cd src/; rm -rf *"
    lowercased :: Format r a -> Format r a
    lowercased :: forall r a. Format r a -> Format r a
    lowercased = (Text -> Text) -> Format r a -> Format r a
    forall r a. (Text -> Text) -> Format r a -> Format r a
    alteredWith Text -> Text
    TL.toLower
    {-# INLINE lowercased #-}

    -- | Convert the formatted string to title case, or something like it:
    --
    -- >>> format (titlecased string) "the life of brian"
    -- "The Life Of Brian"
    titlecased :: Format r a -> Format r a
    titlecased :: forall r a. Format r a -> Format r a
    titlecased = (Text -> Text) -> Format r a -> Format r a
    forall r a. (Text -> Text) -> Format r a -> Format r a
    alteredWith Text -> Text
    TL.toTitle
    {-# INLINE titlecased #-}

    -- | Truncate the formatted string at the end so that it is no more than the given number of characters in length, placing an ellipsis at the end such that it does not exceed this length.
    --
    -- >>> format (ltruncated 5 text) "hello"
    -- "hello"
    --
    -- >>> format (ltruncated 5 text) "hellos"
    -- "he..."
    ltruncated :: Int64 -> Format r a -> Format r a
    ltruncated :: forall r a. Int64 -> Format r a -> Format r a
    ltruncated Int64
    n = Int64 -> Int64 -> Format r a -> Format r a
    forall r a. Int64 -> Int64 -> Format r a -> Format r a
    ctruncated (Int64
    n Int64 -> Int64 -> Int64
    forall a. Num a => a -> a -> a
    - Int64
    3) Int64
    0
    {-# INLINE ltruncated #-}

    -- | Truncate the formatted string at the start so that it is no more than the given number of characters in length, placing an ellipsis at the start such that it does not exceed this length.
    --
    -- >>> format (rtruncated 5 text) "hello"
    -- "hello"
    --
    -- >>> format (rtruncated 5 text) "hellos"
    -- "...os"
    rtruncated :: Int64 -> Format r a -> Format r a
    rtruncated :: forall r a. Int64 -> Format r a -> Format r a
    rtruncated Int64
    n = Int64 -> Int64 -> Format r a -> Format r a
    forall r a. Int64 -> Int64 -> Format r a -> Format r a
    ctruncated Int64
    0 (Int64
    n Int64 -> Int64 -> Int64
    forall a. Num a => a -> a -> a
    - Int64
    3)
    {-# INLINE rtruncated #-}

    -- | Truncate the formatted string in the center, leaving the given number of characters at the start and end, and placing an ellipsis in between.
    -- The length will be no longer than `start + end + 3` characters long.
    --
    -- >>> format (ctruncated 15 4 text) "The quick brown fox jumps over the lazy dog."
    -- "The quick brown...dog."
    --
    -- >>> format (ctruncated 15 4 text) "The quick brown fox"
    -- "The quick brown fox"
    ctruncated :: Int64 -> Int64 -> Format r a -> Format r a
    ctruncated :: forall r a. Int64 -> Int64 -> Format r a -> Format r a
    ctruncated Int64
    start Int64
    end = (Text -> Text) -> Format r a -> Format r a
    forall r a. (Text -> Text) -> Format r a -> Format r a
    alteredWith Text -> Text
    shorten
      where
        shorten :: Text -> Text
        shorten :: Text -> Text
    shorten Text
    txt =
          let n :: Int64
    n = Int64
    start Int64 -> Int64 -> Int64
    forall a. Num a => a -> a -> a
    + Int64
    end Int64 -> Int64 -> Int64
    forall a. Num a => a -> a -> a
    + Int64
    3
          in if Text -> Int64
    TL.length Text
    txt Int64 -> Int64 -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Int64
    n
            then Text
    txt
            else Int64 -> Text -> Text
    TL.take Int64
    start Text
    txt Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "..." Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int64 -> Text -> Text
    TL.takeEnd Int64
    end Text
    txt
    {-# INLINABLE ctruncated #-}

    -- | Pad the formatted string on the left with the given character to give it the given minimum width:
    --
    -- >>> format (lpadded 7 ' ' int) 1
    -- "      1"
    --
    -- >>> format (lpadded 7 ' ' int) 123456789
    -- "123456789"
    lpadded :: Int64 -> Char -> Format r (a -> r) -> Format r (a -> r)
    lpadded :: forall r a. Int64 -> Char -> Format r (a -> r) -> Format r (a -> r)
    lpadded Int64
    i Char
    c = (Text -> Text) -> Format r (a -> r) -> Format r (a -> r)
    forall r a. (Text -> Text) -> Format r a -> Format r a
    alteredWith (Int64 -> Char -> Text -> Text
    TL.justifyRight Int64
    i Char
    c)
    {-# INLINE lpadded #-}

    -- | Pad the formatted string on the right with the given character to give it the given minimum width:
    --
    -- >>> format (rpadded 7 ' ' int) 1
    -- "1      "
    rpadded :: Int64 -> Char -> Format r (a -> r) -> Format r (a -> r)
    rpadded :: forall r a. Int64 -> Char -> Format r (a -> r) -> Format r (a -> r)
    rpadded Int64
    i Char
    c = (Text -> Text) -> Format r (a -> r) -> Format r (a -> r)
    forall r a. (Text -> Text) -> Format r a -> Format r a
    alteredWith (Int64 -> Char -> Text -> Text
    TL.justifyLeft Int64
    i Char
    c)
    {-# INLINE rpadded #-}

    -- | Pad the formatted string on the left and right with the given character to center it, giving it the given minimum width:
    --
    -- >>> format (cpadded 7 ' ' int) 1
    -- "   1   "
    cpadded :: Int64 -> Char -> Format r (a -> r) -> Format r (a -> r)
    cpadded :: forall r a. Int64 -> Char -> Format r (a -> r) -> Format r (a -> r)
    cpadded Int64
    i Char
    c = (Text -> Text) -> Format r (a -> r) -> Format r (a -> r)
    forall r a. (Text -> Text) -> Format r a -> Format r a
    alteredWith (Int64 -> Char -> Text -> Text
    TL.center Int64
    i Char
    c)
    {-# INLINE cpadded #-}

    -- | Format the item with a fixed width, padding with the given character on the left to extend, adding an ellipsis on the right to shorten:
    --
    -- >>> format (lfixed 10 ' ' int) 123
    -- "123       "
    --
    -- >>> format (lfixed 10 ' ' int) 1234567890
    -- "1234567890"
    --
    -- >>> format (lfixed 10 ' ' int) 123456789012345
    -- "1234567..."
    lfixed :: Int64 -> Char -> Format r (a -> r) -> Format r (a -> r)
    lfixed :: forall r a. Int64 -> Char -> Format r (a -> r) -> Format r (a -> r)
    lfixed Int64
    n Char
    c = Int64 -> Format r (a -> r) -> Format r (a -> r)
    forall r a. Int64 -> Format r a -> Format r a
    ltruncated Int64
    n (Format r (a -> r) -> Format r (a -> r))
    -> (Format r (a -> r) -> Format r (a -> r))
    -> Format r (a -> r)
    -> Format r (a -> r)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int64 -> Char -> Format r (a -> r) -> Format r (a -> r)
    forall r a. Int64 -> Char -> Format r (a -> r) -> Format r (a -> r)
    rpadded Int64
    n Char
    c
    {-# INLINE lfixed #-}

    -- | Format the item with a fixed width, padding with the given character on the right to extend, adding an ellipsis on the right to shorten:
    --
    -- >>> format (rfixed 10 ' ' int) 123
    -- "       123"
    --
    -- >>> format (rfixed 10 ' ' int) 1234567890
    -- "1234567890"
    --
    -- >>> format (rfixed 10 ' ' int) 123456789012345
    -- "...9012345"
    rfixed :: Int64 -> Char -> Format r (a -> r) -> Format r (a -> r)
    rfixed :: forall r a. Int64 -> Char -> Format r (a -> r) -> Format r (a -> r)
    rfixed Int64
    n Char
    c = Int64 -> Format r (a -> r) -> Format r (a -> r)
    forall r a. Int64 -> Format r a -> Format r a
    rtruncated Int64
    n (Format r (a -> r) -> Format r (a -> r))
    -> (Format r (a -> r) -> Format r (a -> r))
    -> Format r (a -> r)
    -> Format r (a -> r)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int64 -> Char -> Format r (a -> r) -> Format r (a -> r)
    forall r a. Int64 -> Char -> Format r (a -> r) -> Format r (a -> r)
    lpadded Int64
    n Char
    c
    {-# INLINE rfixed #-}

    -- | Format the item with a fixed width, padding with the given character on either side to extend, adding an ellipsis in the center to shorten.
    --
    -- The total length will be `l + r + 3` characters.
    --
    -- >>> format (cfixed 4 3 ' ' int) 123
    -- "    123   "
    --
    -- >>> format (cfixed 4 3 ' ' int) 1234567890
    -- "1234567890"
    --
    -- >>> format (cfixed 4 3 ' ' int) 123456789012345
    -- "1234...345"
    cfixed :: Int64 -> Int64 -> Char -> Format r (a -> r) -> Format r (a -> r)
    cfixed :: forall r a.
    Int64 -> Int64 -> Char -> Format r (a -> r) -> Format r (a -> r)
    cfixed Int64
    l Int64
    r Char
    c = Int64 -> Int64 -> Format r (a -> r) -> Format r (a -> r)
    forall r a. Int64 -> Int64 -> Format r a -> Format r a
    ctruncated Int64
    l Int64
    r (Format r (a -> r) -> Format r (a -> r))
    -> (Format r (a -> r) -> Format r (a -> r))
    -> Format r (a -> r)
    -> Format r (a -> r)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int64 -> Char -> Format r (a -> r) -> Format r (a -> r)
    forall r a. Int64 -> Char -> Format r (a -> r) -> Format r (a -> r)
    cpadded (Int64
    l Int64 -> Int64 -> Int64
    forall a. Num a => a -> a -> a
    + Int64
    r Int64 -> Int64 -> Int64
    forall a. Num a => a -> a -> a
    + Int64
    3) Char
    c
    {-# INLINE cfixed #-}

    -- | Add the given prefix to the formatted item:
    --
    -- >>> format ("The answer is: " % prefixed "wait for it... " int) 42
    -- "The answer is: wait for it... 42"
    --
    -- >>> fprint (unlined (indented 4 (prefixed "- " int))) [1, 2, 3]
    --     - 1
    --     - 2
    --     - 3
    prefixed :: Builder -> Format r a -> Format r a
    prefixed :: forall r a. Builder -> Format r a -> Format r a
    prefixed Builder
    s Format r a
    f = Builder -> Format a a
    forall r. Builder -> Format r r
    now Builder
    s Format a a -> Format r a -> Format r a
    forall r a r'. Format r a -> Format r' r -> Format r' a
    % Format r a
    f
    {-# INLINE prefixed #-}

    -- | Add the given suffix to the formatted item.
    suffixed :: Builder -> Format r a -> Format r a
    suffixed :: forall r a. Builder -> Format r a -> Format r a
    suffixed Builder
    s Format r a
    f = Format r a
    f Format r a -> Format r r -> Format r a
    forall r a r'. Format r a -> Format r' r -> Format r' a
    % Builder -> Format r r
    forall r. Builder -> Format r r
    now Builder
    s
    {-# INLINE suffixed #-}

    -- | Surround the output string with the given string:
    --
    -- >>> format (surrounded "***" string) "glue"
    -- "***glue***"
    surrounded :: Builder -> Format r a -> Format r a
    surrounded :: forall r a. Builder -> Format r a -> Format r a
    surrounded Builder
    s Format r a
    f = Builder -> Format a a
    forall r. Builder -> Format r r
    now Builder
    s Format a a -> Format r a -> Format r a
    forall r a r'. Format r a -> Format r' r -> Format r' a
    % Format r a
    f Format r a -> Format r r -> Format r a
    forall r a r'. Format r a -> Format r' r -> Format r' a
    % Builder -> Format r r
    forall r. Builder -> Format r r
    now Builder
    s
    {-# INLINE surrounded #-}

    -- | Enclose the output string with the given strings:
    --
    -- >>> format (enclosed "<!--" "-->" text) "an html comment"
    -- "<!--an html comment-->"
    enclosed :: Builder -> Builder -> Format r a -> Format r a
    enclosed :: forall r a. Builder -> Builder -> Format r a -> Format r a
    enclosed Builder
    pre Builder
    suf Format r a
    f = Builder -> Format a a
    forall r. Builder -> Format r r
    now Builder
    pre Format a a -> Format r a -> Format r a
    forall r a r'. Format r a -> Format r' r -> Format r' a
    % Format r a
    f Format r a -> Format r r -> Format r a
    forall r a r'. Format r a -> Format r' r -> Format r' a
    % Builder -> Format r r
    forall r. Builder -> Format r r
    now Builder
    suf
    {-# INLINE enclosed #-}

    -- | Add single quotes around the formatted item:
    --
    -- >>> let obj = Just Nothing in format ("The object is: " % squoted shown % ".") obj
    -- "The object is: 'Just Nothing'."
    squoted :: Format r a -> Format r a
    squoted :: forall r a. Format r a -> Format r a
    squoted = Builder -> Format r a -> Format r a
    forall r a. Builder -> Format r a -> Format r a
    surrounded Builder
    "'"
    {-# INLINE squoted #-}

    -- | Add double quotes around the formatted item:
    --
    -- >>> fprintLn ("He said it was based on " % dquoted stext % ".") "science"
    -- He said it was based on "science".
    dquoted :: Format r a -> Format r a
    dquoted :: forall r a. Format r a -> Format r a
    dquoted = Builder -> Format r a -> Format r a
    forall r a. Builder -> Format r a -> Format r a
    surrounded Builder
    "\""
    {-# INLINE dquoted #-}

    -- | Add parentheses around the formatted item:
    --
    -- >>> format ("We found " % parenthesised int % " discrepancies.") 17
    -- "We found (17) discrepancies."
    --
    -- >>> fprintLn (took 5 (list (parenthesised int))) [1..]
    -- [(1), (2), (3), (4), (5)]
    parenthesised :: Format r a -> Format r a
    parenthesised :: forall r a. Format r a -> Format r a
    parenthesised = Builder -> Builder -> Format r a -> Format r a
    forall r a. Builder -> Builder -> Format r a -> Format r a
    enclosed Builder
    "(" Builder
    ")"
    {-# INLINE parenthesised #-}

    -- | Add square brackets around the formatted item:
    --
    -- >>> format (squared int) 7
    -- "[7]"
    squared :: Format r a -> Format r a
    squared :: forall r a. Format r a -> Format r a
    squared = Builder -> Builder -> Format r a -> Format r a
    forall r a. Builder -> Builder -> Format r a -> Format r a
    enclosed Builder
    "[" Builder
    "]"
    {-# INLINE squared #-}

    -- | Add curly brackets around the formatted item:
    --
    -- >>> format ("\\begin" % braced text) "section"
    -- "\\begin{section}"
    braced :: Format r a -> Format r a
    braced :: forall r a. Format r a -> Format r a
    braced = Builder -> Builder -> Format r a -> Format r a
    forall r a. Builder -> Builder -> Format r a -> Format r a
    enclosed Builder
    "{" Builder
    "}"
    {-# INLINE braced #-}

    -- | Add angle brackets around the formatted item:
    --
    -- >>> format (angled int) 7
    -- "<7>"
    --
    -- >>> format (list (angled text)) ["html", "head", "title", "body", "div", "span"]
    -- "[<html>, <head>, <title>, <body>, <div>, <span>]"
    angled :: Format r a -> Format r a
    angled :: forall r a. Format r a -> Format r a
    angled = Builder -> Builder -> Format r a -> Format r a
    forall r a. Builder -> Builder -> Format r a -> Format r a
    enclosed Builder
    "<" Builder
    ">"
    {-# INLINE angled #-}

    -- | Add backticks around the formatted item:
    --
    -- >>> format ("Be sure to run " % backticked builder % " as root.") ":(){:|:&};:"
    -- "Be sure to run `:(){:|:&};:` as root."
    backticked :: Format r a -> Format r a
    backticked :: forall r a. Format r a -> Format r a
    backticked = Builder -> Format r a -> Format r a
    forall r a. Builder -> Format r a -> Format r a
    surrounded Builder
    "`"
    {-# INLINE backticked #-}

    -- | Insert the given number of spaces at the start of the rendered text:
    --
    -- >>> format (indented 4 int) 7
    -- "    7"
    --
    -- Note that this only indents the first line of a multi-line string.
    -- To indent all lines see 'reindented'.
    indented :: Int -> Format r a -> Format r a
    indented :: forall r a. Int -> Format r a -> Format r a
    indented Int
    n = Builder -> Format r a -> Format r a
    forall r a. Builder -> Format r a -> Format r a
    prefixed Builder
    spaces
      where
        spaces :: Builder
    spaces = Int64 -> Text -> Text
    TL.replicate (Int -> Int64
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    n) (Char -> Text
    TL.singleton Char
    ' ') Text -> (Text -> Builder) -> Builder
    forall a b. a -> (a -> b) -> b
    & Text -> Builder
    TLB.fromLazyText
    {-# INLINABLE indented #-}

    -- | Format a list of items, placing one per line, indented by the given number of spaces.
    --
    -- >>> fprint ("The lucky numbers are:\n" % indentedLines 4 int) [7, 13, 1, 42]
    -- The lucky numbers are:
    --     7
    --     13
    --     1
    --     42
    indentedLines :: Foldable t => Int -> Format Builder (a -> Builder) -> Format r (t a -> r)
    indentedLines :: forall (t :: * -> *) a r.
    Foldable t =>
    Int -> Format Builder (a -> Builder) -> Format r (t a -> r)
    indentedLines Int
    n = Format Builder (a -> Builder) -> Format r (t a -> r)
    forall (t :: * -> *) a r.
    Foldable t =>
    Format Builder (a -> Builder) -> Format r (t a -> r)
    unlined (Format Builder (a -> Builder) -> Format r (t a -> r))
    -> (Format Builder (a -> Builder) -> Format Builder (a -> Builder))
    -> Format Builder (a -> Builder)
    -> Format r (t a -> r)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int
    -> Format Builder (a -> Builder) -> Format Builder (a -> Builder)
    forall r a. Int -> Format r a -> Format r a
    indented Int
    n
    {-# INLINE indentedLines #-}

    -- | Indent each line of the formatted string by the given number of spaces:
    --
    -- >>> fprint (reindented 2 text) "one\ntwo\nthree"
    --   one
    --   two
    --   three
    reindented :: Int -> Format r a -> Format r a
    reindented :: forall r a. Int -> Format r a -> Format r a
    reindented Int
    n = (Format Builder (Builder -> Builder)
     -> Format Builder ([Builder] -> Builder))
    -> Format r a -> Format r a
    forall r a.
    (Format Builder (Builder -> Builder)
     -> Format Builder ([Builder] -> Builder))
    -> Format r a -> Format r a
    lined (Int
    -> Format Builder (Builder -> Builder)
    -> Format Builder ([Builder] -> Builder)
    forall (t :: * -> *) a r.
    Foldable t =>
    Int -> Format Builder (a -> Builder) -> Format r (t a -> r)
    indentedLines Int
    n)
    {-# INLINE reindented #-}

    -- | Take a fractional number and round it before formatting it as the given Format:
    --
    -- >>> format (roundedTo int) 6.66
    -- "7"
    -- >>> format (list (roundedTo int)) [10.66, 6.66, 1.0, 3.4]
    -- "[11, 7, 1, 3]"
    --
    -- Note: the type variable 'f' will almost always be 'Format r', so the type of this function can be thought of as:
    --
    -- @
    -- roundedTo :: (Integral i, RealFrac d) => Format r (i -> r) -> Format r (d -> r)
    -- @
    roundedTo :: (Integral i, RealFrac d, Functor f) => f (i -> r) -> f (d -> r)
    roundedTo :: forall i d (f :: * -> *) r.
    (Integral i, RealFrac d, Functor f) =>
    f (i -> r) -> f (d -> r)
    roundedTo = ((i -> r) -> d -> r) -> f (i -> r) -> f (d -> r)
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((i -> r) -> (d -> i) -> d -> r
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . d -> i
    forall b. Integral b => d -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    round)
    {-# INLINE roundedTo #-}

    -- | Take a fractional number and truncate it before formatting it as the given Format:
    --
    -- >>> format (truncatedTo int) 6.66
    -- "6"
    -- >>> format (list (truncatedTo int)) [10.66, 6.66, 1.0, 3.4]
    -- "[10, 6, 1, 3]"
    --
    -- Note: the type variable 'f' will almost always be 'Format r', so the type of this function can be thought of as:
    --
    -- @
    -- truncatedTo :: (Integral i, RealFrac d) => Format r (i -> r) -> Format r (d -> r)
    -- @
    truncatedTo :: (Integral i, RealFrac d, Functor f) => f (i -> r) -> f (d -> r)
    truncatedTo :: forall i d (f :: * -> *) r.
    (Integral i, RealFrac d, Functor f) =>
    f (i -> r) -> f (d -> r)
    truncatedTo = ((i -> r) -> d -> r) -> f (i -> r) -> f (d -> r)
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((i -> r) -> (d -> i) -> d -> r
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . d -> i
    forall b. Integral b => d -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    truncate)
    {-# INLINE truncatedTo #-}

    -- | Take a fractional number and ceiling it before formatting it as the given Format:
    --
    -- >>> format (ceilingedTo int) 6.66
    -- "7"
    -- >>> format (list (ceilingedTo int)) [10.66, 6.66, 1.0, 3.4]
    -- "[11, 7, 1, 4]"
    --
    -- Note: the type variable 'f' will almost always be 'Format r', so the type of this function can be thought of as:
    --
    -- @
    -- ceilingedTo :: (Integral i, RealFrac d) => Format r (i -> r) -> Format r (d -> r)
    -- @
    ceilingedTo :: (Integral i, RealFrac d, Functor f) => f (i -> r) -> f (d -> r)
    ceilingedTo :: forall i d (f :: * -> *) r.
    (Integral i, RealFrac d, Functor f) =>
    f (i -> r) -> f (d -> r)
    ceilingedTo = ((i -> r) -> d -> r) -> f (i -> r) -> f (d -> r)
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((i -> r) -> (d -> i) -> d -> r
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . d -> i
    forall b. Integral b => d -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    ceiling)
    {-# INLINE ceilingedTo #-}

    -- | Take a fractional number and floor it before formatting it as the given Format:
    --
    -- >>> format (flooredTo int) 6.66
    -- "6"
    -- >>> format (list (flooredTo int)) [10.66, 6.66, 1.0, 3.4]
    -- "[10, 6, 1, 3]"
    --
    -- Note: the type variable 'f' will almost always be 'Format r', so the type of this function can be thought of as:
    --
    -- @
    -- flooredTo :: (Integral i, RealFrac d) => Format r (i -> r) -> Format r (d -> r)
    -- @
    flooredTo :: (Integral i, RealFrac d, Functor f) => f (i -> r) -> f (d -> r)
    flooredTo :: forall i d (f :: * -> *) r.
    (Integral i, RealFrac d, Functor f) =>
    f (i -> r) -> f (d -> r)
    flooredTo = ((i -> r) -> d -> r) -> f (i -> r) -> f (d -> r)
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((i -> r) -> (d -> i) -> d -> r
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . d -> i
    forall b. Integral b => d -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    floor)
    {-# INLINE flooredTo #-}

    -- | Use the given lens to view an item, formatting it with the given formatter.
    --
    -- You can think of this as having the type:
    --
    -- @
    -- 'viewed' :: 'Lens'' s a -> Format r (a -> r) -> Format r (s -> r)
    -- @
    --
    -- >>> format (viewed _1 int) (1, "hello")
    -- "1"
    --
    -- This is useful when combined with the Monoid instance for Format, because it allows us to give a data structure as an argument only once, and deconstruct it with the formatters:
    --
    -- @
    -- data Person = Person
    --   { _personName :: Text
    --   , _personAge :: Int
    --   }
    -- makeLenses ''Person
    --
    -- me :: Person
    -- me = Person "Alex" 38
    --
    -- format ("The person's name is " % squoted (viewed personName text) % ", and their age is " <> viewed personAge int) me
    -- "The person's name is 'Alex', and their age is 38"
    -- @
    viewed :: ((a -> Const a b) -> s -> Const a t) -> Format r (a -> r) -> Format r (s -> r)
    viewed :: forall a b s t r.
    ((a -> Const a b) -> s -> Const a t)
    -> Format r (a -> r) -> Format r (s -> r)
    viewed (a -> Const a b) -> s -> Const a t
    l = ((a -> r) -> s -> r) -> Format r (a -> r) -> Format r (s -> r)
    forall a b. (a -> b) -> Format r a -> Format r b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((a -> r) -> (s -> a) -> s -> r
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Const a t -> a
    forall {k} a (b :: k). Const a b -> a
    getConst (Const a t -> a) -> (s -> Const a t) -> s -> a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a -> Const a b) -> s -> Const a t
    l a -> Const a b
    forall {k} a (b :: k). a -> Const a b
    Const))
    {-# INLINE viewed #-}

    -- | Access an element of the structure and format it with the given formatter.
    --
    -- >>> format (accessed fst int) (1, "hello")
    -- "1"
    --
    -- Repeating the example from 'viewed':
    --
    -- format ("The person's name is " % squoted (accessed _personName text) % ", and their age is " <> accessed _personAge int) me
    -- "The person's name is 'Alex', and their age is 38"
    accessed :: (s -> a) -> Format r (a -> r) -> Format r (s -> r)
    accessed :: forall s a r. (s -> a) -> Format r (a -> r) -> Format r (s -> r)
    accessed s -> a
    accessor = ((a -> r) -> s -> r) -> Format r (a -> r) -> Format r (s -> r)
    forall a b. (a -> b) -> Format r a -> Format r b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((a -> r) -> (s -> a) -> s -> r
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . s -> a
    accessor)
    {-# INLINE accessed #-}

    -- | Render an integer using binary notation with a leading 0b, padding with zeroes to the given width:
    --
    -- >>> format (binPrefix 16) 4097
    -- "0b0001000000000001"
    binPrefix :: Integral a => Int64 -> Format r (a -> r)
    binPrefix :: forall a r. Integral a => Int64 -> Format r (a -> r)
    binPrefix Int64
    n = Format (a -> r) (a -> r)
    "0b" Format (a -> r) (a -> r) -> Format r (a -> r) -> Format r (a -> r)
    forall r a r'. Format r a -> Format r' r -> Format r' a
    % Int64 -> Char -> Format r (a -> r) -> Format r (a -> r)
    forall r a. Int64 -> Char -> Format r (a -> r) -> Format r (a -> r)
    lpadded Int64
    n Char
    '0' Format r (a -> r)
    forall a r. Integral a => Format r (a -> r)
    bin
    {-# INLINE binPrefix #-}

    -- | Render an integer using octal notation with a leading 0o, padding with zeroes to the given width:
    --
    -- >>> format (octPrefix 16) 4097
    -- "0o0000000000010001"
    octPrefix :: Integral a => Int64 -> Format r (a -> r)
    octPrefix :: forall a r. Integral a => Int64 -> Format r (a -> r)
    octPrefix Int64
    n = Format (a -> r) (a -> r)
    "0o" Format (a -> r) (a -> r) -> Format r (a -> r) -> Format r (a -> r)
    forall r a r'. Format r a -> Format r' r -> Format r' a
    % Int64 -> Char -> Format r (a -> r) -> Format r (a -> r)
    forall r a. Int64 -> Char -> Format r (a -> r) -> Format r (a -> r)
    lpadded Int64
    n Char
    '0' Format r (a -> r)
    forall a r. Integral a => Format r (a -> r)
    oct
    {-# INLINE octPrefix #-}

    -- | Render an integer using octal notation with a leading 0x, padding with zeroes to the given width:
    --
    -- >>> format (hexPrefix 16) 4097
    -- "0x0000000000001001"
    hexPrefix :: Integral a => Int64 -> Format r (a -> r)
    hexPrefix :: forall a r. Integral a => Int64 -> Format r (a -> r)
    hexPrefix Int64
    n = Format (a -> r) (a -> r)
    "0x" Format (a -> r) (a -> r) -> Format r (a -> r) -> Format r (a -> r)
    forall r a r'. Format r a -> Format r' r -> Format r' a
    % Int64 -> Char -> Format r (a -> r) -> Format r (a -> r)
    forall r a. Int64 -> Char -> Format r (a -> r) -> Format r (a -> r)
    lpadded Int64
    n Char
    '0' Format r (a -> r)
    forall a r. Integral a => Format r (a -> r)
    hex
    {-# INLINE hexPrefix #-}