    {-# LANGUAGE OverloadedStrings #-}
    module Text.Blaze.Renderer.Utf8
        ( renderMarkupBuilder
        , renderMarkup
        , renderMarkupToByteStringIO
        , renderHtmlBuilder
        , renderHtml
        , renderHtmlToByteStringIO
        ) where

    import Data.Monoid (mappend, mempty)
    import Data.List (isInfixOf)

    import qualified Data.ByteString.Lazy as L
    import qualified Data.Text as T (isInfixOf)
    import qualified Data.ByteString as S (ByteString, isInfixOf)

    import Text.Blaze.Internal
    import Blaze.ByteString.Builder (Builder)
    import qualified Blaze.ByteString.Builder           as B
    import qualified Blaze.ByteString.Builder.Html.Utf8 as B

    -- | Render a 'ChoiceString'.
    --
    fromChoiceString :: ChoiceString  -- ^ String to render
                     -> Builder       -- ^ Resulting builder
    fromChoiceString :: ChoiceString -> Builder
    fromChoiceString (Static StaticString
    s)     = ByteString -> Builder
    B.copyByteString (ByteString -> Builder) -> ByteString -> Builder
    forall a b. (a -> b) -> a -> b
    $ StaticString -> ByteString
    getUtf8ByteString StaticString
    s
    fromChoiceString (String [Char]
    s)     = [Char] -> Builder
    B.fromHtmlEscapedString [Char]
    s
    fromChoiceString (Text Text
    s)       = Text -> Builder
    B.fromHtmlEscapedText Text
    s
    fromChoiceString (ByteString ByteString
    s) = ByteString -> Builder
    B.fromByteString ByteString
    s
    fromChoiceString (PreEscaped ChoiceString
    x) = case ChoiceString
    x of
        String [Char]
    s -> [Char] -> Builder
    B.fromString [Char]
    s
        Text   Text
    s -> Text -> Builder
    B.fromText Text
    s
        ChoiceString
    s        -> ChoiceString -> Builder
    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 Builder
    forall a. Monoid a => a
    mempty else [Char] -> Builder
    B.fromString [Char]
    s
        Text   Text
    s     -> if Text
    "</" Text -> Text -> Bool
    `T.isInfixOf` Text
    s then Builder
    forall a. Monoid a => a
    mempty else Text -> Builder
    B.fromText Text
    s
        ByteString ByteString
    s -> if ByteString
    "</" ByteString -> ByteString -> Bool
    `S.isInfixOf` ByteString
    s then Builder
    forall a. Monoid a => a
    mempty else ByteString -> Builder
    B.fromByteString ByteString
    s
        ChoiceString
    s            -> ChoiceString -> Builder
    fromChoiceString ChoiceString
    s
    fromChoiceString (AppendChoiceString ChoiceString
    x ChoiceString
    y) =
        ChoiceString -> Builder
    fromChoiceString ChoiceString
    x Builder -> Builder -> Builder
    forall a. Monoid a => a -> a -> a
    `mappend` ChoiceString -> Builder
    fromChoiceString ChoiceString
    y
    fromChoiceString ChoiceString
    EmptyChoiceString = Builder
    forall a. Monoid a => a
    mempty
    {-# INLINE fromChoiceString #-}

    -- | Render some 'Markup' to a 'Builder'.
    --
    renderMarkupBuilder, renderHtmlBuilder :: Markup     -- ^ Markup to render
                      -> Builder  -- ^ Resulting builder
    renderMarkupBuilder :: Markup -> Builder
    renderMarkupBuilder = Builder -> Markup -> Builder
    forall b. Builder -> MarkupM b -> Builder
    go Builder
    forall a. Monoid a => a
    mempty
      where
        go :: Builder -> MarkupM b -> Builder
        go :: forall b. Builder -> MarkupM b -> Builder
    go Builder
    attrs (Parent StaticString
    _ StaticString
    open StaticString
    close MarkupM b
    content) =
            ByteString -> Builder
    B.copyByteString (StaticString -> ByteString
    getUtf8ByteString StaticString
    open)
                Builder -> Builder -> Builder
    forall a. Monoid a => a -> a -> a
    `mappend` Builder
    attrs
                Builder -> Builder -> Builder
    forall a. Monoid a => a -> a -> a
    `mappend` Char -> Builder
    B.fromChar Char
    '>'
                Builder -> Builder -> Builder
    forall a. Monoid a => a -> a -> a
    `mappend` Builder -> MarkupM b -> Builder
    forall b. Builder -> MarkupM b -> Builder
    go Builder
    forall a. Monoid a => a
    mempty MarkupM b
    content
                Builder -> Builder -> Builder
    forall a. Monoid a => a -> a -> a
    `mappend` ByteString -> Builder
    B.copyByteString (StaticString -> ByteString
    getUtf8ByteString StaticString
    close)
        go Builder
    attrs (CustomParent ChoiceString
    tag MarkupM b
    content) =
            Char -> Builder
    B.fromChar Char
    '<'
                Builder -> Builder -> Builder
    forall a. Monoid a => a -> a -> a
    `mappend` ChoiceString -> Builder
    fromChoiceString ChoiceString
    tag
                Builder -> Builder -> Builder
    forall a. Monoid a => a -> a -> a
    `mappend` Builder
    attrs
                Builder -> Builder -> Builder
    forall a. Monoid a => a -> a -> a
    `mappend` Char -> Builder
    B.fromChar Char
    '>'
                Builder -> Builder -> Builder
    forall a. Monoid a => a -> a -> a
    `mappend` Builder -> MarkupM b -> Builder
    forall b. Builder -> MarkupM b -> Builder
    go Builder
    forall a. Monoid a => a
    mempty MarkupM b
    content
                Builder -> Builder -> Builder
    forall a. Monoid a => a -> a -> a
    `mappend` ByteString -> Builder
    B.fromByteString ByteString
    "</"
                Builder -> Builder -> Builder
    forall a. Monoid a => a -> a -> a
    `mappend` ChoiceString -> Builder
    fromChoiceString ChoiceString
    tag
                Builder -> Builder -> Builder
    forall a. Monoid a => a -> a -> a
    `mappend` Char -> Builder
    B.fromChar Char
    '>'
        go Builder
    attrs (Leaf StaticString
    _ StaticString
    begin StaticString
    end b
    _) =
            ByteString -> Builder
    B.copyByteString (StaticString -> ByteString
    getUtf8ByteString StaticString
    begin)
                Builder -> Builder -> Builder
    forall a. Monoid a => a -> a -> a
    `mappend` Builder
    attrs
                Builder -> Builder -> Builder
    forall a. Monoid a => a -> a -> a
    `mappend` ByteString -> Builder
    B.copyByteString (StaticString -> ByteString
    getUtf8ByteString StaticString
    end)
        go Builder
    attrs (CustomLeaf ChoiceString
    tag Bool
    close b
    _) =
            Char -> Builder
    B.fromChar Char
    '<'
                Builder -> Builder -> Builder
    forall a. Monoid a => a -> a -> a
    `mappend` ChoiceString -> Builder
    fromChoiceString ChoiceString
    tag
                Builder -> Builder -> Builder
    forall a. Monoid a => a -> a -> a
    `mappend` Builder
    attrs
                Builder -> Builder -> Builder
    forall a. Monoid a => a -> a -> a
    `mappend` (if Bool
    close then ByteString -> Builder
    B.fromByteString ByteString
    " />" else Char -> Builder
    B.fromChar Char
    '>')
        go Builder
    attrs (AddAttribute StaticString
    _ StaticString
    key ChoiceString
    value MarkupM b
    h) =
            Builder -> MarkupM b -> Builder
    forall b. Builder -> MarkupM b -> Builder
    go (ByteString -> Builder
    B.copyByteString (StaticString -> ByteString
    getUtf8ByteString StaticString
    key)
                Builder -> Builder -> Builder
    forall a. Monoid a => a -> a -> a
    `mappend` ChoiceString -> Builder
    fromChoiceString ChoiceString
    value
                Builder -> Builder -> Builder
    forall a. Monoid a => a -> a -> a
    `mappend` Char -> Builder
    B.fromChar Char
    '"'
                Builder -> Builder -> Builder
    forall a. Monoid a => a -> a -> a
    `mappend` Builder
    attrs) MarkupM b
    h
        go Builder
    attrs (AddCustomAttribute ChoiceString
    key ChoiceString
    value MarkupM b
    h) =
            Builder -> MarkupM b -> Builder
    forall b. Builder -> MarkupM b -> Builder
    go (Char -> Builder
    B.fromChar Char
    ' '
                Builder -> Builder -> Builder
    forall a. Monoid a => a -> a -> a
    `mappend` ChoiceString -> Builder
    fromChoiceString ChoiceString
    key
                Builder -> Builder -> Builder
    forall a. Monoid a => a -> a -> a
    `mappend` ByteString -> Builder
    B.fromByteString ByteString
    "=\""
                Builder -> Builder -> Builder
    forall a. Monoid a => a -> a -> a
    `mappend` ChoiceString -> Builder
    fromChoiceString ChoiceString
    value
                Builder -> Builder -> Builder
    forall a. Monoid a => a -> a -> a
    `mappend` Char -> Builder
    B.fromChar Char
    '"'
                Builder -> Builder -> Builder
    forall a. Monoid a => a -> a -> a
    `mappend` Builder
    attrs) MarkupM b
    h
        go Builder
    _ (Content ChoiceString
    content b
    _) = ChoiceString -> Builder
    fromChoiceString ChoiceString
    content
        go Builder
    _ (Comment ChoiceString
    comment b
    _) =
            ByteString -> Builder
    B.fromByteString ByteString
    "<!-- "
                Builder -> Builder -> Builder
    forall a. Monoid a => a -> a -> a
    `mappend` ChoiceString -> Builder
    fromChoiceString ChoiceString
    comment
                Builder -> Builder -> Builder
    forall a. Monoid a => a -> a -> a
    `mappend` ByteString -> Builder
    B.fromByteString ByteString
    " -->"
        go Builder
    attrs (Append MarkupM b
    h1 MarkupM b
    h2) = Builder -> MarkupM b -> Builder
    forall b. Builder -> MarkupM b -> Builder
    go Builder
    attrs MarkupM b
    h1 Builder -> Builder -> Builder
    forall a. Monoid a => a -> a -> a
    `mappend` Builder -> MarkupM b -> Builder
    forall b. Builder -> MarkupM b -> Builder
    go Builder
    attrs MarkupM b
    h2
        go Builder
    _ (Empty b
    _) = Builder
    forall a. Monoid a => a
    mempty
        {-# NOINLINE go #-}
    {-# INLINE renderMarkupBuilder #-}

    renderHtmlBuilder :: Markup -> Builder
    renderHtmlBuilder = Markup -> Builder
    renderMarkupBuilder
    {-# INLINE renderHtmlBuilder #-}
    {-# DEPRECATED renderHtmlBuilder
        "Use renderHtmlBuilder from Text.Blaze.Html.Renderer.Utf8 instead" #-}

    -- | Render HTML to a lazy UTF-8 encoded 'L.ByteString.'
    --
    renderMarkup, renderHtml :: Markup          -- ^ Markup to render
                             -> L.ByteString  -- ^ Resulting 'L.ByteString'
    renderMarkup :: Markup -> ByteString
    renderMarkup = Builder -> ByteString
    B.toLazyByteString (Builder -> ByteString)
    -> (Markup -> Builder) -> Markup -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Markup -> Builder
    renderMarkupBuilder
    {-# INLINE renderMarkup #-}

    renderHtml :: Markup -> ByteString
    renderHtml = Markup -> ByteString
    renderMarkup
    {-# INLINE renderHtml #-}
    {-# DEPRECATED renderHtml
        "Use renderHtml from Text.Blaze.Html.Renderer.Utf8 instead" #-}

    -- | Repeatedly render HTML to a buffer and process this buffer using the given
    -- IO action.
    --
    renderMarkupToByteStringIO, renderHtmlToByteStringIO :: (S.ByteString -> IO ())
                                                            -- ^ IO action to execute per rendered buffer
                                                         -> Markup          -- ^ Markup to render
                                                         -> IO ()         -- ^ Resulting IO action
    renderMarkupToByteStringIO :: (ByteString -> IO ()) -> Markup -> IO ()
    renderMarkupToByteStringIO ByteString -> IO ()
    io = (ByteString -> IO ()) -> Builder -> IO ()
    B.toByteStringIO ByteString -> IO ()
    io (Builder -> IO ()) -> (Markup -> Builder) -> Markup -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Markup -> Builder
    renderMarkupBuilder
    {-# INLINE renderMarkupToByteStringIO #-}

    renderHtmlToByteStringIO :: (ByteString -> IO ()) -> Markup -> IO ()
    renderHtmlToByteStringIO = (ByteString -> IO ()) -> Markup -> IO ()
    renderMarkupToByteStringIO
    {-# INLINE renderHtmlToByteStringIO #-}
    {-# DEPRECATED renderHtmlToByteStringIO
        "Use renderMarkupToByteStringIO from Text.Blaze.Html.Renderer.Utf8 instead" #-}