    -- | A renderer that produces a native Haskell 'String', mostly meant for
    -- debugging purposes.
    --
    {-# LANGUAGE OverloadedStrings #-}
    module Text.Blaze.Renderer.String
        ( fromChoiceString
        , renderMarkup
        , renderHtml
        ) where

    import Data.List (isInfixOf)

    import qualified Data.ByteString.Char8 as SBC
    import qualified Data.Text as T
    import qualified Data.ByteString as S

    import Text.Blaze.Internal

    -- | Escape predefined XML entities in a string
    --
    escapeMarkupEntities :: String  -- ^ String to escape
                       -> String  -- ^ String to append
                       -> String  -- ^ Resulting string
    escapeMarkupEntities :: [Char] -> [Char] -> [Char]
    escapeMarkupEntities []     [Char]
    k = [Char]
    k
    escapeMarkupEntities (Char
    c:[Char]
    cs) [Char]
    k = case Char
    c of
        Char
    '<'  -> Char
    '&' Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    : Char
    'l' Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    : Char
    't' Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    : Char
    ';'             Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    : [Char] -> [Char] -> [Char]
    escapeMarkupEntities [Char]
    cs [Char]
    k
        Char
    '>'  -> Char
    '&' Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    : Char
    'g' Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    : Char
    't' Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    : Char
    ';'             Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    : [Char] -> [Char] -> [Char]
    escapeMarkupEntities [Char]
    cs [Char]
    k
        Char
    '&'  -> Char
    '&' Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    : Char
    'a' Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    : Char
    'm' Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    : Char
    'p' Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    : Char
    ';'       Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    : [Char] -> [Char] -> [Char]
    escapeMarkupEntities [Char]
    cs [Char]
    k
        Char
    '"'  -> Char
    '&' Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    : Char
    'q' Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    : Char
    'u' Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    : Char
    'o' Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    : Char
    't' Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    : Char
    ';' Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    : [Char] -> [Char] -> [Char]
    escapeMarkupEntities [Char]
    cs [Char]
    k
        Char
    '\'' -> Char
    '&' Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    : Char
    '#' Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    : Char
    '3' Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    : Char
    '9' Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    : Char
    ';'       Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    : [Char] -> [Char] -> [Char]
    escapeMarkupEntities [Char]
    cs [Char]
    k
        Char
    x    -> Char
    x                                 Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    : [Char] -> [Char] -> [Char]
    escapeMarkupEntities [Char]
    cs [Char]
    k

    -- | Render a 'ChoiceString'.
    --
    fromChoiceString :: ChoiceString  -- ^ String to render
                     -> String        -- ^ String to append
                     -> String        -- ^ Resulting string
    fromChoiceString :: ChoiceString -> [Char] -> [Char]
    fromChoiceString (Static StaticString
    s)     = StaticString -> [Char] -> [Char]
    getString StaticString
    s
    fromChoiceString (String [Char]
    s)     = [Char] -> [Char] -> [Char]
    escapeMarkupEntities [Char]
    s
    fromChoiceString (Text Text
    s)       = [Char] -> [Char] -> [Char]
    escapeMarkupEntities ([Char] -> [Char] -> [Char]) -> [Char] -> [Char] -> [Char]
    forall a b. (a -> b) -> a -> b
    $ Text -> [Char]
    T.unpack Text
    s
    fromChoiceString (ByteString ByteString
    s) = (ByteString -> [Char]
    SBC.unpack ByteString
    s [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++)
    fromChoiceString (PreEscaped ChoiceString
    x) = case ChoiceString
    x of
        String [Char]
    s -> ([Char]
    s [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++)
        Text   Text
    s -> (\[Char]
    k -> (Char -> [Char] -> [Char]) -> [Char] -> Text -> [Char]
    forall a. (Char -> a -> a) -> a -> Text -> a
    T.foldr (:) [Char]
    k Text
    s)
        ChoiceString
    s        -> ChoiceString -> [Char] -> [Char]
    fromChoiceString ChoiceString
    s
    fromChoiceString (External ChoiceString
    x) = case ChoiceString
    x of
        -- Check that the sequence "</" is *not* in the external data.
        String [Char]
    s     -> if [Char]
    "</" [Char] -> [Char] -> Bool
    forall a. Eq a => [a] -> [a] -> Bool
    `isInfixOf` [Char]
    s then [Char] -> [Char]
    forall a. a -> a
    id else ([Char]
    s [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++)
        Text   Text
    s     -> if Text
    "</" Text -> Text -> Bool
    `T.isInfixOf` Text
    s then [Char] -> [Char]
    forall a. a -> a
    id else (\[Char]
    k -> (Char -> [Char] -> [Char]) -> [Char] -> Text -> [Char]
    forall a. (Char -> a -> a) -> a -> Text -> a
    T.foldr (:) [Char]
    k Text
    s)
        ByteString ByteString
    s -> if ByteString
    "</" ByteString -> ByteString -> Bool
    `S.isInfixOf` ByteString
    s then [Char] -> [Char]
    forall a. a -> a
    id else (ByteString -> [Char]
    SBC.unpack ByteString
    s [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++)
        ChoiceString
    s            -> ChoiceString -> [Char] -> [Char]
    fromChoiceString ChoiceString
    s
    fromChoiceString (AppendChoiceString ChoiceString
    x ChoiceString
    y) =
        ChoiceString -> [Char] -> [Char]
    fromChoiceString ChoiceString
    x ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ChoiceString -> [Char] -> [Char]
    fromChoiceString ChoiceString
    y
    fromChoiceString ChoiceString
    EmptyChoiceString = [Char] -> [Char]
    forall a. a -> a
    id
    {-# INLINE fromChoiceString #-}

    -- | Render some 'Markup' to an appending 'String'.
    --
    renderString :: Markup    -- ^ Markup to render
                 -> String  -- ^ String to append
                 -> String  -- ^ Resulting String
    renderString :: Markup -> [Char] -> [Char]
    renderString = ([Char] -> [Char]) -> Markup -> [Char] -> [Char]
    forall b. ([Char] -> [Char]) -> MarkupM b -> [Char] -> [Char]
    go [Char] -> [Char]
    forall a. a -> a
    id
      where
        go :: (String -> String) -> MarkupM b -> String -> String
        go :: forall b. ([Char] -> [Char]) -> MarkupM b -> [Char] -> [Char]
    go [Char] -> [Char]
    attrs (Parent StaticString
    _ StaticString
    open StaticString
    close MarkupM b
    content) =
            StaticString -> [Char] -> [Char]
    getString StaticString
    open ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> [Char]
    attrs ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Char
    '>' Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    :) ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ([Char] -> [Char]) -> MarkupM b -> [Char] -> [Char]
    forall b. ([Char] -> [Char]) -> MarkupM b -> [Char] -> [Char]
    go [Char] -> [Char]
    forall a. a -> a
    id MarkupM b
    content ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . StaticString -> [Char] -> [Char]
    getString StaticString
    close
        go [Char] -> [Char]
    attrs (CustomParent ChoiceString
    tag MarkupM b
    content) =
            (Char
    '<' Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    :) ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ChoiceString -> [Char] -> [Char]
    fromChoiceString ChoiceString
    tag ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> [Char]
    attrs ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Char
    '>' Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    :) ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .  ([Char] -> [Char]) -> MarkupM b -> [Char] -> [Char]
    forall b. ([Char] -> [Char]) -> MarkupM b -> [Char] -> [Char]
    go [Char] -> [Char]
    forall a. a -> a
    id MarkupM b
    content ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
            ([Char]
    "</" [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++) ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ChoiceString -> [Char] -> [Char]
    fromChoiceString ChoiceString
    tag ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Char
    '>' Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    :)
        go [Char] -> [Char]
    attrs (Leaf StaticString
    _ StaticString
    begin StaticString
    end b
    _) = StaticString -> [Char] -> [Char]
    getString StaticString
    begin ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> [Char]
    attrs ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . StaticString -> [Char] -> [Char]
    getString StaticString
    end
        go [Char] -> [Char]
    attrs (CustomLeaf ChoiceString
    tag Bool
    close b
    _) =
            (Char
    '<' Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    :) ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ChoiceString -> [Char] -> [Char]
    fromChoiceString ChoiceString
    tag ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> [Char]
    attrs ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
            (if Bool
    close then ([Char]
    " />" [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++) else (Char
    '>' Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    :))
        go [Char] -> [Char]
    attrs (AddAttribute StaticString
    _ StaticString
    key ChoiceString
    value MarkupM b
    h) = (([Char] -> [Char]) -> MarkupM b -> [Char] -> [Char])
    -> MarkupM b -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip ([Char] -> [Char]) -> MarkupM b -> [Char] -> [Char]
    forall b. ([Char] -> [Char]) -> MarkupM b -> [Char] -> [Char]
    go MarkupM b
    h (([Char] -> [Char]) -> [Char] -> [Char])
    -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall a b. (a -> b) -> a -> b
    $
            StaticString -> [Char] -> [Char]
    getString StaticString
    key ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ChoiceString -> [Char] -> [Char]
    fromChoiceString ChoiceString
    value ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Char
    '"' Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    :) ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> [Char]
    attrs
        go [Char] -> [Char]
    attrs (AddCustomAttribute ChoiceString
    key ChoiceString
    value MarkupM b
    h) = (([Char] -> [Char]) -> MarkupM b -> [Char] -> [Char])
    -> MarkupM b -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip ([Char] -> [Char]) -> MarkupM b -> [Char] -> [Char]
    forall b. ([Char] -> [Char]) -> MarkupM b -> [Char] -> [Char]
    go MarkupM b
    h (([Char] -> [Char]) -> [Char] -> [Char])
    -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall a b. (a -> b) -> a -> b
    $
            (Char
    ' ' Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    :) ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ChoiceString -> [Char] -> [Char]
    fromChoiceString ChoiceString
    key ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ([Char]
    "=\"" [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++) ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ChoiceString -> [Char] -> [Char]
    fromChoiceString ChoiceString
    value ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
            (Char
    '"' Char -> [Char] -> [Char]
    forall a. a -> [a] -> [a]
    :) ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .  [Char] -> [Char]
    attrs
        go [Char] -> [Char]
    _ (Content ChoiceString
    content b
    _) = ChoiceString -> [Char] -> [Char]
    fromChoiceString ChoiceString
    content
        go [Char] -> [Char]
    _ (Comment ChoiceString
    comment b
    _) =
            ([Char]
    "<!-- " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++) ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ChoiceString -> [Char] -> [Char]
    fromChoiceString ChoiceString
    comment ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ([Char]
    " -->" [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++)
        go [Char] -> [Char]
    attrs (Append MarkupM b
    h1 MarkupM b
    h2) = ([Char] -> [Char]) -> MarkupM b -> [Char] -> [Char]
    forall b. ([Char] -> [Char]) -> MarkupM b -> [Char] -> [Char]
    go [Char] -> [Char]
    attrs MarkupM b
    h1 ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ([Char] -> [Char]) -> MarkupM b -> [Char] -> [Char]
    forall b. ([Char] -> [Char]) -> MarkupM b -> [Char] -> [Char]
    go [Char] -> [Char]
    attrs MarkupM b
    h2
        go [Char] -> [Char]
    _ (Empty b
    _) = [Char] -> [Char]
    forall a. a -> a
    id
        {-# NOINLINE go #-}
    {-# INLINE renderString #-}

    -- | Render markup to a lazy 'String'.
    --
    renderMarkup :: Markup -> String
    renderMarkup :: Markup -> [Char]
    renderMarkup Markup
    html = Markup -> [Char] -> [Char]
    renderString Markup
    html [Char]
    ""
    {-# INLINE renderMarkup #-}

    renderHtml :: Markup -> String
    renderHtml :: Markup -> [Char]
    renderHtml = Markup -> [Char]
    renderMarkup
    {-# INLINE renderHtml #-}
    {-# DEPRECATED renderHtml
        "Use renderHtml from Text.Blaze.Html.Renderer.String instead" #-}