    module Text.Lazy.Builder.ANSI
      ( -- $intro

        -- * Foreground color
        black,
        red,
        green,
        yellow,
        blue,
        magenta,
        cyan,
        white,
        brightBlack,
        brightRed,
        brightGreen,
        brightYellow,
        brightBlue,
        brightMagenta,
        brightCyan,
        brightWhite,
        rgb,

        -- * Background color
        blackBg,
        redBg,
        greenBg,
        yellowBg,
        blueBg,
        magentaBg,
        cyanBg,
        whiteBg,
        brightBlackBg,
        brightRedBg,
        brightGreenBg,
        brightYellowBg,
        brightBlueBg,
        brightMagentaBg,
        brightCyanBg,
        brightWhiteBg,
        rgbBg,

        -- * Style
        bold,
        faint,
        italic,
        underline,
        doubleUnderline,
        strikethrough,
        frame,
        encircle,
        overline,
      )
    where

    import Data.Text.Lazy.Builder (Builder)
    import qualified Data.Text.Lazy.Builder as Builder
    import qualified Data.Text.Lazy.Builder.Int as Builder
    import Data.Word (Word8)
    import System.IO.Unsafe (unsafePerformIO)
    import System.Posix.Internals (c_isatty)

    -- $intro
    --
    -- Text styling for ANSI terminals using SGR codes, as defined by the
    -- <https://www.ecma-international.org/publications-and-standards/standards/ecma-48 ECMA-48>
    -- standard.
    --
    -- Supports foreground\/background color, bold\/faint intensity, italic,
    -- single\/double underline, strikethrough, frame, encircle, and overline escape
    -- sequences. Some styles may not work on your terminal.
    --
    -- Also features terminal detection, so redirecting styled output to a file will
    -- automatically strip the ANSI escape sequences.

    -- | Black foreground.
    black :: Builder -> Builder
    black :: Builder -> Builder
    black =
      Builder -> Builder -> Builder
    foreground (String -> Builder
    Builder.fromString String
    "30")
    {-# INLINE black #-}

    -- | Red foreground.
    red :: Builder -> Builder
    red :: Builder -> Builder
    red =
      Builder -> Builder -> Builder
    foreground (String -> Builder
    Builder.fromString String
    "31")
    {-# INLINE red #-}

    -- | Green foreground.
    green :: Builder -> Builder
    green :: Builder -> Builder
    green =
      Builder -> Builder -> Builder
    foreground (String -> Builder
    Builder.fromString String
    "32")
    {-# INLINE green #-}

    -- | Yellow foreground.
    yellow :: Builder -> Builder
    yellow :: Builder -> Builder
    yellow =
      Builder -> Builder -> Builder
    foreground (String -> Builder
    Builder.fromString String
    "33")
    {-# INLINE yellow #-}

    -- | Blue foreground.
    blue :: Builder -> Builder
    blue :: Builder -> Builder
    blue =
      Builder -> Builder -> Builder
    foreground (String -> Builder
    Builder.fromString String
    "34")
    {-# INLINE blue #-}

    -- | Magenta foreground.
    magenta :: Builder -> Builder
    magenta :: Builder -> Builder
    magenta =
      Builder -> Builder -> Builder
    foreground (String -> Builder
    Builder.fromString String
    "35")
    {-# INLINE magenta #-}

    -- | Cyan foreground.
    cyan :: Builder -> Builder
    cyan :: Builder -> Builder
    cyan =
      Builder -> Builder -> Builder
    foreground (String -> Builder
    Builder.fromString String
    "36")
    {-# INLINE cyan #-}

    -- | White foreground.
    white :: Builder -> Builder
    white :: Builder -> Builder
    white =
      Builder -> Builder -> Builder
    foreground (String -> Builder
    Builder.fromString String
    "37")
    {-# INLINE white #-}

    -- | Bright black foreground.
    brightBlack :: Builder -> Builder
    brightBlack :: Builder -> Builder
    brightBlack =
      Builder -> Builder -> Builder
    foreground (String -> Builder
    Builder.fromString String
    "90")
    {-# INLINE brightBlack #-}

    -- | Bright red foreground.
    brightRed :: Builder -> Builder
    brightRed :: Builder -> Builder
    brightRed =
      Builder -> Builder -> Builder
    foreground (String -> Builder
    Builder.fromString String
    "91")
    {-# INLINE brightRed #-}

    -- | Bright green foreground.
    brightGreen :: Builder -> Builder
    brightGreen :: Builder -> Builder
    brightGreen =
      Builder -> Builder -> Builder
    foreground (String -> Builder
    Builder.fromString String
    "92")
    {-# INLINE brightGreen #-}

    -- | Bright yellow foreground.
    brightYellow :: Builder -> Builder
    brightYellow :: Builder -> Builder
    brightYellow =
      Builder -> Builder -> Builder
    foreground (String -> Builder
    Builder.fromString String
    "93")
    {-# INLINE brightYellow #-}

    -- | Bright blue foreground.
    brightBlue :: Builder -> Builder
    brightBlue :: Builder -> Builder
    brightBlue =
      Builder -> Builder -> Builder
    foreground (String -> Builder
    Builder.fromString String
    "94")
    {-# INLINE brightBlue #-}

    -- | Bright magenta foreground.
    brightMagenta :: Builder -> Builder
    brightMagenta :: Builder -> Builder
    brightMagenta =
      Builder -> Builder -> Builder
    foreground (String -> Builder
    Builder.fromString String
    "95")
    {-# INLINE brightMagenta #-}

    -- | Bright cyan foreground.
    brightCyan :: Builder -> Builder
    brightCyan :: Builder -> Builder
    brightCyan =
      Builder -> Builder -> Builder
    foreground (String -> Builder
    Builder.fromString String
    "96")
    {-# INLINE brightCyan #-}

    -- | Bright white foreground.
    brightWhite :: Builder -> Builder
    brightWhite :: Builder -> Builder
    brightWhite =
      Builder -> Builder -> Builder
    foreground (String -> Builder
    Builder.fromString String
    "97")
    {-# INLINE brightWhite #-}

    -- | RGB foreground.
    rgb :: Word8 -> Word8 -> Word8 -> Builder -> Builder
    rgb :: Word8 -> Word8 -> Word8 -> Builder -> Builder
    rgb Word8
    r Word8
    g Word8
    b =
      Builder -> Builder -> Builder
    foreground (String -> Builder
    Builder.fromString String
    "38;2;" Builder -> Builder -> Builder
    forall a. Semigroup a => a -> a -> a
    <> Word8 -> Builder
    forall a. Integral a => a -> Builder
    Builder.decimal Word8
    r Builder -> Builder -> Builder
    forall a. Semigroup a => a -> a -> a
    <> Builder
    semi Builder -> Builder -> Builder
    forall a. Semigroup a => a -> a -> a
    <> Word8 -> Builder
    forall a. Integral a => a -> Builder
    Builder.decimal Word8
    g Builder -> Builder -> Builder
    forall a. Semigroup a => a -> a -> a
    <> Builder
    semi Builder -> Builder -> Builder
    forall a. Semigroup a => a -> a -> a
    <> Word8 -> Builder
    forall a. Integral a => a -> Builder
    Builder.decimal Word8
    b)
    {-# INLINE rgb #-}

    foreground :: Builder -> Builder -> Builder
    foreground :: Builder -> Builder -> Builder
    foreground Builder
    s =
      Builder -> Builder -> Builder -> Builder
    surround Builder
    s (String -> Builder
    Builder.fromString String
    "39")
    {-# INLINE foreground #-}

    -- | Black background.
    blackBg :: Builder -> Builder
    blackBg :: Builder -> Builder
    blackBg =
      Builder -> Builder -> Builder
    background (String -> Builder
    Builder.fromString String
    "40")
    {-# INLINE blackBg #-}

    -- | Red background.
    redBg :: Builder -> Builder
    redBg :: Builder -> Builder
    redBg =
      Builder -> Builder -> Builder
    background (String -> Builder
    Builder.fromString String
    "41")
    {-# INLINE redBg #-}

    -- | Green background.
    greenBg :: Builder -> Builder
    greenBg :: Builder -> Builder
    greenBg =
      Builder -> Builder -> Builder
    background (String -> Builder
    Builder.fromString String
    "42")
    {-# INLINE greenBg #-}

    -- | Yellow background.
    yellowBg :: Builder -> Builder
    yellowBg :: Builder -> Builder
    yellowBg =
      Builder -> Builder -> Builder
    background (String -> Builder
    Builder.fromString String
    "43")
    {-# INLINE yellowBg #-}

    -- | Blue background.
    blueBg :: Builder -> Builder
    blueBg :: Builder -> Builder
    blueBg =
      Builder -> Builder -> Builder
    background (String -> Builder
    Builder.fromString String
    "44")
    {-# INLINE blueBg #-}

    -- | Magenta background.
    magentaBg :: Builder -> Builder
    magentaBg :: Builder -> Builder
    magentaBg =
      Builder -> Builder -> Builder
    background (String -> Builder
    Builder.fromString String
    "45")
    {-# INLINE magentaBg #-}

    -- | Cyan background.
    cyanBg :: Builder -> Builder
    cyanBg :: Builder -> Builder
    cyanBg =
      Builder -> Builder -> Builder
    background (String -> Builder
    Builder.fromString String
    "46")
    {-# INLINE cyanBg #-}

    -- | White background.
    whiteBg :: Builder -> Builder
    whiteBg :: Builder -> Builder
    whiteBg =
      Builder -> Builder -> Builder
    background (String -> Builder
    Builder.fromString String
    "47")
    {-# INLINE whiteBg #-}

    -- | Bright black background.
    brightBlackBg :: Builder -> Builder
    brightBlackBg :: Builder -> Builder
    brightBlackBg =
      Builder -> Builder -> Builder
    background (String -> Builder
    Builder.fromString String
    "100")
    {-# INLINE brightBlackBg #-}

    -- | Bright red background.
    brightRedBg :: Builder -> Builder
    brightRedBg :: Builder -> Builder
    brightRedBg =
      Builder -> Builder -> Builder
    background (String -> Builder
    Builder.fromString String
    "101")
    {-# INLINE brightRedBg #-}

    -- | Bright green background.
    brightGreenBg :: Builder -> Builder
    brightGreenBg :: Builder -> Builder
    brightGreenBg =
      Builder -> Builder -> Builder
    background (String -> Builder
    Builder.fromString String
    "102")
    {-# INLINE brightGreenBg #-}

    -- | Bright yellow background.
    brightYellowBg :: Builder -> Builder
    brightYellowBg :: Builder -> Builder
    brightYellowBg =
      Builder -> Builder -> Builder
    background (String -> Builder
    Builder.fromString String
    "103")
    {-# INLINE brightYellowBg #-}

    -- | Bright blue background.
    brightBlueBg :: Builder -> Builder
    brightBlueBg :: Builder -> Builder
    brightBlueBg =
      Builder -> Builder -> Builder
    background (String -> Builder
    Builder.fromString String
    "104")
    {-# INLINE brightBlueBg #-}

    -- | Bright magenta background.
    brightMagentaBg :: Builder -> Builder
    brightMagentaBg :: Builder -> Builder
    brightMagentaBg =
      Builder -> Builder -> Builder
    background (String -> Builder
    Builder.fromString String
    "105")
    {-# INLINE brightMagentaBg #-}

    -- | Bright cyan background.
    brightCyanBg :: Builder -> Builder
    brightCyanBg :: Builder -> Builder
    brightCyanBg =
      Builder -> Builder -> Builder
    background (String -> Builder
    Builder.fromString String
    "106")
    {-# INLINE brightCyanBg #-}

    -- | Bright white background.
    brightWhiteBg :: Builder -> Builder
    brightWhiteBg :: Builder -> Builder
    brightWhiteBg =
      Builder -> Builder -> Builder
    background (String -> Builder
    Builder.fromString String
    "107")
    {-# INLINE brightWhiteBg #-}

    background :: Builder -> Builder -> Builder
    background :: Builder -> Builder -> Builder
    background Builder
    s =
      Builder -> Builder -> Builder -> Builder
    surround Builder
    s (String -> Builder
    Builder.fromString String
    "49")
    {-# INLINE background #-}

    -- | RGB background.
    rgbBg :: Word8 -> Word8 -> Word8 -> Builder -> Builder
    rgbBg :: Word8 -> Word8 -> Word8 -> Builder -> Builder
    rgbBg Word8
    r Word8
    g Word8
    b =
      Builder -> Builder -> Builder
    background (String -> Builder
    Builder.fromString String
    "48;2;" Builder -> Builder -> Builder
    forall a. Semigroup a => a -> a -> a
    <> Word8 -> Builder
    forall a. Integral a => a -> Builder
    Builder.decimal Word8
    r Builder -> Builder -> Builder
    forall a. Semigroup a => a -> a -> a
    <> Builder
    semi Builder -> Builder -> Builder
    forall a. Semigroup a => a -> a -> a
    <> Word8 -> Builder
    forall a. Integral a => a -> Builder
    Builder.decimal Word8
    g Builder -> Builder -> Builder
    forall a. Semigroup a => a -> a -> a
    <> Builder
    semi Builder -> Builder -> Builder
    forall a. Semigroup a => a -> a -> a
    <> Word8 -> Builder
    forall a. Integral a => a -> Builder
    Builder.decimal Word8
    b)
    {-# INLINE rgbBg #-}

    -- | __Bold__ style (high intensity).
    bold :: Builder -> Builder
    bold :: Builder -> Builder
    bold =
      Builder -> Builder -> Builder -> Builder
    surround (String -> Builder
    Builder.fromString String
    "1") (String -> Builder
    Builder.fromString String
    "22")
    {-# INLINE bold #-}

    -- | Faint style (low intensity).
    faint :: Builder -> Builder
    faint :: Builder -> Builder
    faint =
      Builder -> Builder -> Builder -> Builder
    surround (String -> Builder
    Builder.fromString String
    "2") (String -> Builder
    Builder.fromString String
    "22")
    {-# INLINE faint #-}

    -- | /Italic/ style.
    italic :: Builder -> Builder
    italic :: Builder -> Builder
    italic =
      Builder -> Builder -> Builder -> Builder
    surround (String -> Builder
    Builder.fromString String
    "3") (String -> Builder
    Builder.fromString String
    "23")
    {-# INLINE italic #-}

    -- | U̲n̲d̲e̲r̲l̲i̲n̲e̲ style.
    underline :: Builder -> Builder
    underline :: Builder -> Builder
    underline =
      Builder -> Builder -> Builder -> Builder
    surround (String -> Builder
    Builder.fromString String
    "4") (String -> Builder
    Builder.fromString String
    "24")
    {-# INLINE underline #-}

    -- | D̳o̳u̳b̳l̳e̳ ̳u̳n̳d̳e̳r̳l̳i̳n̳e̳ style.
    doubleUnderline :: Builder -> Builder
    doubleUnderline :: Builder -> Builder
    doubleUnderline =
      Builder -> Builder -> Builder -> Builder
    surround (String -> Builder
    Builder.fromString String
    "21") (String -> Builder
    Builder.fromString String
    "24")
    {-# INLINE doubleUnderline #-}

    -- | S̶t̶r̶i̶k̶e̶t̶h̶r̶o̶u̶g̶h̶ style.
    strikethrough :: Builder -> Builder
    strikethrough :: Builder -> Builder
    strikethrough =
      Builder -> Builder -> Builder -> Builder
    surround (String -> Builder
    Builder.fromString String
    "9") (String -> Builder
    Builder.fromString String
    "29")
    {-# INLINE strikethrough #-}

    -- | Frame style.
    frame :: Builder -> Builder
    frame :: Builder -> Builder
    frame =
      Builder -> Builder -> Builder -> Builder
    surround (String -> Builder
    Builder.fromString String
    "51") (String -> Builder
    Builder.fromString String
    "54")
    {-# INLINE frame #-}

    -- | Encircle style.
    encircle :: Builder -> Builder
    encircle :: Builder -> Builder
    encircle =
      Builder -> Builder -> Builder -> Builder
    surround (String -> Builder
    Builder.fromString String
    "52") (String -> Builder
    Builder.fromString String
    "54")
    {-# INLINE encircle #-}

    -- | O̅v̅e̅r̅l̅i̅n̅e̅ style.
    overline :: Builder -> Builder
    overline :: Builder -> Builder
    overline =
      Builder -> Builder -> Builder -> Builder
    surround (String -> Builder
    Builder.fromString String
    "53") (String -> Builder
    Builder.fromString String
    "55")
    {-# INLINE overline #-}

    --------------------------------------------------------------------------------

    surround :: Builder -> Builder -> Builder -> Builder
    surround :: Builder -> Builder -> Builder -> Builder
    surround Builder
    open Builder
    close Builder
    text
      | Bool
    isatty = Builder
    esc Builder -> Builder -> Builder
    forall a. Semigroup a => a -> a -> a
    <> Builder
    open Builder -> Builder -> Builder
    forall a. Semigroup a => a -> a -> a
    <> Builder
    m Builder -> Builder -> Builder
    forall a. Semigroup a => a -> a -> a
    <> Builder
    text Builder -> Builder -> Builder
    forall a. Semigroup a => a -> a -> a
    <> Builder
    esc Builder -> Builder -> Builder
    forall a. Semigroup a => a -> a -> a
    <> Builder
    close Builder -> Builder -> Builder
    forall a. Semigroup a => a -> a -> a
    <> Builder
    m
      | Bool
    otherwise = Builder
    text
    -- Don't inline before phase 1
    {-# NOINLINE [1] surround #-}

    esc :: Builder
    esc :: Builder
    esc =
      String -> Builder
    Builder.fromString String
    "\ESC["

    m :: Builder
    m :: Builder
    m =
      Char -> Builder
    Builder.singleton Char
    'm'

    semi :: Builder
    semi :: Builder
    semi =
      Char -> Builder
    Builder.singleton Char
    ';'

    isatty :: Bool
    isatty :: Bool
    isatty =
      IO CInt -> CInt
    forall a. IO a -> a
    unsafePerformIO (CInt -> IO CInt
    c_isatty CInt
    1) CInt -> CInt -> Bool
    forall a. Eq a => a -> a -> Bool
    == CInt
    1
    {-# NOINLINE isatty #-}

    -- Collapse surround/surround to a single surround before phase 1
    {-# RULES
    "surround/surround" [~1] forall a b c d s.
      surround a b (surround c d s) =
        surround (a <> semi <> c) (b <> semi <> d) s
      #-}