{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}

-- |
-- Module      :  Text.MMark.Render
-- Copyright   :  © 2017–present Mark Karpov
-- License     :  BSD 3 clause
--
-- Maintainer  :  Mark Karpov <markkarpov92@gmail.com>
-- Stability   :  experimental
-- Portability :  portable
--
-- MMark rendering machinery.
module Text.MMark.Render
  ( render,
  )
where

import Control.Arrow
import Control.Monad
import Data.Char (isSpace)
import Data.Function (fix)
import Data.List.NonEmpty (NonEmpty (..))
import qualified Data.List.NonEmpty as NE
import qualified Data.Text as T
import Lucid
import Text.MMark.Trans
import Text.MMark.Type
import Text.MMark.Util
import qualified Text.URI as URI

-- | Render a 'MMark' markdown document. You can then render @'Html' ()@ to
-- various things:
--
--     * to lazy 'Data.Taxt.Lazy.Text' with 'renderText'
--     * to lazy 'Data.ByteString.Lazy.ByteString' with 'renderBS'
--     * directly to file with 'renderToFile'
render :: MMark -> Html ()
render :: MMark -> Html ()
render MMark {[Bni]
Maybe Value
Extension
mmarkExtension :: MMark -> Extension
mmarkBlocks :: MMark -> [Bni]
mmarkYaml :: MMark -> Maybe Value
mmarkExtension :: Extension
mmarkBlocks :: [Bni]
mmarkYaml :: Maybe Value
..} =
  (Bni -> Html ()) -> [Bni] -> Html ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ Bni -> Html ()
rBlock [Bni]
mmarkBlocks
  where
    Extension {Endo Inline
Endo Bni
Render Inline
Render (Block (Ois, Html ()))
extInlineRender :: Extension -> Render Inline
extInlineTrans :: Extension -> Endo Inline
extBlockRender :: Extension -> Render (Block (Ois, Html ()))
extBlockTrans :: Extension -> Endo Bni
extInlineRender :: Render Inline
extInlineTrans :: Endo Inline
extBlockRender :: Render (Block (Ois, Html ()))
extBlockTrans :: Endo Bni
..} = Extension
mmarkExtension
    rBlock :: Bni -> Html ()
rBlock =
      Render (Block (Ois, Html ())) -> Block (Ois, Html ()) -> Html ()
applyBlockRender Render (Block (Ois, Html ()))
extBlockRender
        (Block (Ois, Html ()) -> Html ())
-> (Bni -> Block (Ois, Html ())) -> Bni -> Html ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (NonEmpty Inline -> (Ois, Html ())) -> Bni -> Block (Ois, Html ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap NonEmpty Inline -> (Ois, Html ())
rInlines
        (Bni -> Block (Ois, Html ()))
-> (Bni -> Bni) -> Bni -> Block (Ois, Html ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Endo Bni -> Bni -> Bni
applyBlockTrans Endo Bni
extBlockTrans
    rInlines :: NonEmpty Inline -> (Ois, Html ())
rInlines =
      (NonEmpty Inline -> Ois
mkOisInternal (NonEmpty Inline -> Ois)
-> (NonEmpty Inline -> Html ())
-> NonEmpty Inline
-> (Ois, Html ())
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& (Inline -> Html ()) -> NonEmpty Inline -> Html ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (Render Inline -> Inline -> Html ()
applyInlineRender Render Inline
extInlineRender))
        (NonEmpty Inline -> (Ois, Html ()))
-> (NonEmpty Inline -> NonEmpty Inline)
-> NonEmpty Inline
-> (Ois, Html ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Inline -> Inline) -> NonEmpty Inline -> NonEmpty Inline
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Endo Inline -> Inline -> Inline
applyInlineTrans Endo Inline
extInlineTrans)

-- | Apply a 'Render' to a given @'Block' 'Html' ()@.
applyBlockRender ::
  Render (Block (Ois, Html ())) ->
  Block (Ois, Html ()) ->
  Html ()
applyBlockRender :: Render (Block (Ois, Html ())) -> Block (Ois, Html ()) -> Html ()
applyBlockRender Render (Block (Ois, Html ()))
r = ((Block (Ois, Html ()) -> Html ())
 -> Block (Ois, Html ()) -> Html ())
-> Block (Ois, Html ()) -> Html ()
forall a. (a -> a) -> a
fix (Render (Block (Ois, Html ()))
-> (Block (Ois, Html ()) -> Html ())
-> Block (Ois, Html ())
-> Html ()
forall a. Render a -> (a -> Html ()) -> a -> Html ()
runRender Render (Block (Ois, Html ()))
r ((Block (Ois, Html ()) -> Html ())
 -> Block (Ois, Html ()) -> Html ())
-> ((Block (Ois, Html ()) -> Html ())
    -> Block (Ois, Html ()) -> Html ())
-> (Block (Ois, Html ()) -> Html ())
-> Block (Ois, Html ())
-> Html ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Block (Ois, Html ()) -> Html ())
-> Block (Ois, Html ()) -> Html ()
defaultBlockRender)

-- | The default 'Block' render.
defaultBlockRender ::
  -- | Rendering function to use to render sub-blocks
  (Block (Ois, Html ()) -> Html ()) ->
  Block (Ois, Html ()) ->
  Html ()
defaultBlockRender :: (Block (Ois, Html ()) -> Html ())
-> Block (Ois, Html ()) -> Html ()
defaultBlockRender Block (Ois, Html ()) -> Html ()
blockRender = \case
  Block (Ois, Html ())
ThematicBreak ->
    [Attribute] -> Html ()
forall (m :: * -> *). Applicative m => [Attribute] -> HtmlT m ()
hr_ [] Html () -> Html () -> Html ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Html ()
newline
  Heading1 (Ois
h, Html ()
html) ->
    [Attribute] -> Html () -> Html ()
forall arg result. Term arg result => arg -> result
h1_ (Ois -> [Attribute]
mkId Ois
h) Html ()
html Html () -> Html () -> Html ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Html ()
newline
  Heading2 (Ois
h, Html ()
html) ->
    [Attribute] -> Html () -> Html ()
forall arg result. Term arg result => arg -> result
h2_ (Ois -> [Attribute]
mkId Ois
h) Html ()
html Html () -> Html () -> Html ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Html ()
newline
  Heading3 (Ois
h, Html ()
html) ->
    [Attribute] -> Html () -> Html ()
forall arg result. Term arg result => arg -> result
h3_ (Ois -> [Attribute]
mkId Ois
h) Html ()
html Html () -> Html () -> Html ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Html ()
newline
  Heading4 (Ois
h, Html ()
html) ->
    [Attribute] -> Html () -> Html ()
forall arg result. Term arg result => arg -> result
h4_ (Ois -> [Attribute]
mkId Ois
h) Html ()
html Html () -> Html () -> Html ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Html ()
newline
  Heading5 (Ois
h, Html ()
html) ->
    [Attribute] -> Html () -> Html ()
forall arg result. Term arg result => arg -> result
h5_ (Ois -> [Attribute]
mkId Ois
h) Html ()
html Html () -> Html () -> Html ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Html ()
newline
  Heading6 (Ois
h, Html ()
html) ->
    [Attribute] -> Html () -> Html ()
forall arg result. Term arg result => arg -> result
h6_ (Ois -> [Attribute]
mkId Ois
h) Html ()
html Html () -> Html () -> Html ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Html ()
newline
  CodeBlock Maybe Text
infoString Text
txt -> do
    let f :: Text -> Attribute
f Text
x = Text -> Attribute
class_ (Text -> Attribute) -> Text -> Attribute
forall a b. (a -> b) -> a -> b
$ Text
"language-" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> (Char -> Bool) -> Text -> Text
T.takeWhile (Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isSpace) Text
x
    Html () -> Html ()
forall arg result. Term arg result => arg -> result
pre_ (Html () -> Html ()) -> Html () -> Html ()
forall a b. (a -> b) -> a -> b
$ [Attribute] -> Html () -> Html ()
forall arg result. Term arg result => arg -> result
code_ ([Attribute] -> (Text -> [Attribute]) -> Maybe Text -> [Attribute]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (Attribute -> [Attribute]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Attribute -> [Attribute])
-> (Text -> Attribute) -> Text -> [Attribute]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Attribute
f) Maybe Text
infoString) (Text -> Html ()
forall a (m :: * -> *). (ToHtml a, Monad m) => a -> HtmlT m ()
toHtml Text
txt)
    Html ()
newline
  Naked (Ois
_, Html ()
html) ->
    Html ()
html Html () -> Html () -> Html ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Html ()
newline
  Paragraph (Ois
_, Html ()
html) ->
    Html () -> Html ()
forall arg result. Term arg result => arg -> result
p_ Html ()
html Html () -> Html () -> Html ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Html ()
newline
  Blockquote [Block (Ois, Html ())]
blocks -> do
    Html () -> Html ()
forall arg result. Term arg result => arg -> result
blockquote_ (Html ()
newline Html () -> Html () -> Html ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* (Block (Ois, Html ()) -> Html ())
-> [Block (Ois, Html ())] -> Html ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ Block (Ois, Html ()) -> Html ()
blockRender [Block (Ois, Html ())]
blocks)
    Html ()
newline
  OrderedList Word
i NonEmpty [Block (Ois, Html ())]
items -> do
    let startIndex :: [Attribute]
startIndex = [Text -> Attribute
start_ (String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ Word -> String
forall a. Show a => a -> String
show Word
i) | Word
i Word -> Word -> Bool
forall a. Eq a => a -> a -> Bool
/= Word
1]
    [Attribute] -> Html () -> Html ()
forall arg result. Term arg result => arg -> result
ol_ [Attribute]
startIndex (Html () -> Html ()) -> Html () -> Html ()
forall a b. (a -> b) -> a -> b
$ do
      Html ()
newline
      NonEmpty [Block (Ois, Html ())]
-> ([Block (Ois, Html ())] -> Html ()) -> Html ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ NonEmpty [Block (Ois, Html ())]
items (([Block (Ois, Html ())] -> Html ()) -> Html ())
-> ([Block (Ois, Html ())] -> Html ()) -> Html ()
forall a b. (a -> b) -> a -> b
$ \[Block (Ois, Html ())]
x -> do
        Html () -> Html ()
forall arg result. Term arg result => arg -> result
li_ (Html ()
newline Html () -> Html () -> Html ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* (Block (Ois, Html ()) -> Html ())
-> [Block (Ois, Html ())] -> Html ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ Block (Ois, Html ()) -> Html ()
blockRender [Block (Ois, Html ())]
x)
        Html ()
newline
    Html ()
newline
  UnorderedList NonEmpty [Block (Ois, Html ())]
items -> do
    Html () -> Html ()
forall arg result. Term arg result => arg -> result
ul_ (Html () -> Html ()) -> Html () -> Html ()
forall a b. (a -> b) -> a -> b
$ do
      Html ()
newline
      NonEmpty [Block (Ois, Html ())]
-> ([Block (Ois, Html ())] -> Html ()) -> Html ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ NonEmpty [Block (Ois, Html ())]
items (([Block (Ois, Html ())] -> Html ()) -> Html ())
-> ([Block (Ois, Html ())] -> Html ()) -> Html ()
forall a b. (a -> b) -> a -> b
$ \[Block (Ois, Html ())]
x -> do
        Html () -> Html ()
forall arg result. Term arg result => arg -> result
li_ (Html ()
newline Html () -> Html () -> Html ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* (Block (Ois, Html ()) -> Html ())
-> [Block (Ois, Html ())] -> Html ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ Block (Ois, Html ()) -> Html ()
blockRender [Block (Ois, Html ())]
x)
        Html ()
newline
    Html ()
newline
  Table NonEmpty CellAlign
calign (NonEmpty (Ois, Html ())
hs :| [NonEmpty (Ois, Html ())]
rows) -> do
    Html () -> Html ()
forall arg result. Term arg result => arg -> result
table_ (Html () -> Html ()) -> Html () -> Html ()
forall a b. (a -> b) -> a -> b
$ do
      Html ()
newline
      Html () -> Html ()
forall arg result. Term arg result => arg -> result
thead_ (Html () -> Html ()) -> Html () -> Html ()
forall a b. (a -> b) -> a -> b
$ do
        Html ()
newline
        Html () -> Html ()
forall arg result. Term arg result => arg -> result
tr_ (Html () -> Html ()) -> Html () -> Html ()
forall a b. (a -> b) -> a -> b
$
          NonEmpty (CellAlign, (Ois, Html ()))
-> ((CellAlign, (Ois, Html ())) -> Html ()) -> Html ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ (NonEmpty CellAlign
-> NonEmpty (Ois, Html ()) -> NonEmpty (CellAlign, (Ois, Html ()))
forall a b. NonEmpty a -> NonEmpty b -> NonEmpty (a, b)
NE.zip NonEmpty CellAlign
calign NonEmpty (Ois, Html ())
hs) (((CellAlign, (Ois, Html ())) -> Html ()) -> Html ())
-> ((CellAlign, (Ois, Html ())) -> Html ()) -> Html ()
forall a b. (a -> b) -> a -> b
$ \(CellAlign
a, (Ois, Html ())
h) ->
            [Attribute] -> Html () -> Html ()
forall arg result. Term arg result => arg -> result
th_ (CellAlign -> [Attribute]
alignStyle CellAlign
a) ((Ois, Html ()) -> Html ()
forall a b. (a, b) -> b
snd (Ois, Html ())
h)
        Html ()
newline
      Html ()
newline
      Html () -> Html ()
forall arg result. Term arg result => arg -> result
tbody_ (Html () -> Html ()) -> Html () -> Html ()
forall a b. (a -> b) -> a -> b
$ do
        Html ()
newline
        [NonEmpty (Ois, Html ())]
-> (NonEmpty (Ois, Html ()) -> Html ()) -> Html ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [NonEmpty (Ois, Html ())]
rows ((NonEmpty (Ois, Html ()) -> Html ()) -> Html ())
-> (NonEmpty (Ois, Html ()) -> Html ()) -> Html ()
forall a b. (a -> b) -> a -> b
$ \NonEmpty (Ois, Html ())
row -> do
          Html () -> Html ()
forall arg result. Term arg result => arg -> result
tr_ (Html () -> Html ()) -> Html () -> Html ()
forall a b. (a -> b) -> a -> b
$
            NonEmpty (CellAlign, (Ois, Html ()))
-> ((CellAlign, (Ois, Html ())) -> Html ()) -> Html ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ (NonEmpty CellAlign
-> NonEmpty (Ois, Html ()) -> NonEmpty (CellAlign, (Ois, Html ()))
forall a b. NonEmpty a -> NonEmpty b -> NonEmpty (a, b)
NE.zip NonEmpty CellAlign
calign NonEmpty (Ois, Html ())
row) (((CellAlign, (Ois, Html ())) -> Html ()) -> Html ())
-> ((CellAlign, (Ois, Html ())) -> Html ()) -> Html ()
forall a b. (a -> b) -> a -> b
$ \(CellAlign
a, (Ois, Html ())
h) ->
              [Attribute] -> Html () -> Html ()
forall arg result. Term arg result => arg -> result
td_ (CellAlign -> [Attribute]
alignStyle CellAlign
a) ((Ois, Html ()) -> Html ()
forall a b. (a, b) -> b
snd (Ois, Html ())
h)
          Html ()
newline
      Html ()
newline
    Html ()
newline
  where
    mkId :: Ois -> [Attribute]
mkId Ois
ois = [(Text -> Attribute
id_ (Text -> Attribute) -> (Ois -> Text) -> Ois -> Attribute
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty Inline -> Text
headerId (NonEmpty Inline -> Text)
-> (Ois -> NonEmpty Inline) -> Ois -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ois -> NonEmpty Inline
getOis) Ois
ois]
    alignStyle :: CellAlign -> [Attribute]
alignStyle = \case
      CellAlign
CellAlignDefault -> []
      CellAlign
CellAlignLeft -> [Text -> Attribute
forall arg result. TermRaw arg result => arg -> result
style_ Text
"text-align:left"]
      CellAlign
CellAlignRight -> [Text -> Attribute
forall arg result. TermRaw arg result => arg -> result
style_ Text
"text-align:right"]
      CellAlign
CellAlignCenter -> [Text -> Attribute
forall arg result. TermRaw arg result => arg -> result
style_ Text
"text-align:center"]

-- | Apply a render to a given 'Inline'.
applyInlineRender :: Render Inline -> Inline -> Html ()
applyInlineRender :: Render Inline -> Inline -> Html ()
applyInlineRender Render Inline
r = ((Inline -> Html ()) -> Inline -> Html ()) -> Inline -> Html ()
forall a. (a -> a) -> a
fix (Render Inline -> (Inline -> Html ()) -> Inline -> Html ()
forall a. Render a -> (a -> Html ()) -> a -> Html ()
runRender Render Inline
r ((Inline -> Html ()) -> Inline -> Html ())
-> ((Inline -> Html ()) -> Inline -> Html ())
-> (Inline -> Html ())
-> Inline
-> Html ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Inline -> Html ()) -> Inline -> Html ()
defaultInlineRender)

-- | The default render for 'Inline' elements.
defaultInlineRender ::
  -- | Rendering function to use to render sub-inlines
  (Inline -> Html ()) ->
  Inline ->
  Html ()
defaultInlineRender :: (Inline -> Html ()) -> Inline -> Html ()
defaultInlineRender Inline -> Html ()
inlineRender = \case
  Plain Text
txt ->
    Text -> Html ()
forall a (m :: * -> *). (ToHtml a, Monad m) => a -> HtmlT m ()
toHtml Text
txt
  Inline
LineBreak ->
    [Attribute] -> Html ()
forall (m :: * -> *). Applicative m => [Attribute] -> HtmlT m ()
br_ [] Html () -> Html () -> Html ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Html ()
newline
  Emphasis NonEmpty Inline
inner ->
    Html () -> Html ()
forall arg result. Term arg result => arg -> result
em_ ((Inline -> Html ()) -> NonEmpty Inline -> Html ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ Inline -> Html ()
inlineRender NonEmpty Inline
inner)
  Strong NonEmpty Inline
inner ->
    Html () -> Html ()
forall arg result. Term arg result => arg -> result
strong_ ((Inline -> Html ()) -> NonEmpty Inline -> Html ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ Inline -> Html ()
inlineRender NonEmpty Inline
inner)
  Strikeout NonEmpty Inline
inner ->
    Html () -> Html ()
forall arg result. Term arg result => arg -> result
del_ ((Inline -> Html ()) -> NonEmpty Inline -> Html ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ Inline -> Html ()
inlineRender NonEmpty Inline
inner)
  Subscript NonEmpty Inline
inner ->
    Html () -> Html ()
forall arg result. Term arg result => arg -> result
sub_ ((Inline -> Html ()) -> NonEmpty Inline -> Html ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ Inline -> Html ()
inlineRender NonEmpty Inline
inner)
  Superscript NonEmpty Inline
inner ->
    Html () -> Html ()
forall arg result. Term arg result => arg -> result
sup_ ((Inline -> Html ()) -> NonEmpty Inline -> Html ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ Inline -> Html ()
inlineRender NonEmpty Inline
inner)
  CodeSpan Text
txt ->
    Html () -> Html ()
forall arg result. Term arg result => arg -> result
code_ (Text -> Html ()
forall a (m :: * -> *). (ToHtml a, Monad m) => a -> HtmlT m ()
toHtml Text
txt)
  Link NonEmpty Inline
inner URI
dest Maybe Text
mtitle ->
    let title :: [Attribute]
title = [Attribute] -> (Text -> [Attribute]) -> Maybe Text -> [Attribute]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (Attribute -> [Attribute]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Attribute -> [Attribute])
-> (Text -> Attribute) -> Text -> [Attribute]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Attribute
forall arg result. Term arg result => arg -> result
title_) Maybe Text
mtitle
     in [Attribute] -> Html () -> Html ()
forall arg result. Term arg result => arg -> result
a_ (Text -> Attribute
href_ (URI -> Text
URI.render URI
dest) Attribute -> [Attribute] -> [Attribute]
forall a. a -> [a] -> [a]
: [Attribute]
title) ((Inline -> Html ()) -> NonEmpty Inline -> Html ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ Inline -> Html ()
inlineRender NonEmpty Inline
inner)
  Image NonEmpty Inline
desc URI
src Maybe Text
mtitle ->
    let title :: [Attribute]
title = [Attribute] -> (Text -> [Attribute]) -> Maybe Text -> [Attribute]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (Attribute -> [Attribute]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Attribute -> [Attribute])
-> (Text -> Attribute) -> Text -> [Attribute]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Attribute
forall arg result. Term arg result => arg -> result
title_) Maybe Text
mtitle
     in [Attribute] -> Html ()
forall (m :: * -> *). Applicative m => [Attribute] -> HtmlT m ()
img_ (Text -> Attribute
alt_ (NonEmpty Inline -> Text
asPlainText NonEmpty Inline
desc) Attribute -> [Attribute] -> [Attribute]
forall a. a -> [a] -> [a]
: Text -> Attribute
src_ (URI -> Text
URI.render URI
src) Attribute -> [Attribute] -> [Attribute]
forall a. a -> [a] -> [a]
: [Attribute]
title)

-- | HTML containing a newline.
newline :: Html ()
newline :: Html ()
newline = Html ()
"\n"