{-# LANGUAGE OverloadedStrings #-}
module Text.Markdown.Types where
import Data.Text (Text)
import qualified Data.Text as T
import Data.Default (Default (def))
import Data.Set (Set, empty)
import Data.Map (Map, singleton)
import Data.Monoid (mappend)
import Text.Blaze.Html (Html)
import qualified Text.Blaze.Html5 as H
import qualified Text.Blaze.Html5.Attributes as HA
data MarkdownSettings = MarkdownSettings
{ msXssProtect :: Bool
, msStandaloneHtml :: Set Text
, msFencedHandlers :: Map Text (Text -> FencedHandler)
, msBlockCodeRenderer :: Maybe Text -> (Text,Html) -> Html
, msLinkNewTab :: Bool
, msBlankBeforeBlockquote :: Bool
, msBlockFilter :: [Block [Inline]] -> [Block [Inline]]
}
data FencedHandler = FHRaw (Text -> [Block Text])
| FHParsed ([Block Text] -> [Block Text])
instance Default MarkdownSettings where
def = MarkdownSettings
{ msXssProtect = True
, msStandaloneHtml = empty
, msFencedHandlers = codeFencedHandler "```" `mappend` codeFencedHandler "~~~"
, msBlockCodeRenderer =
\lang (_,rendered) -> case lang of
Just l -> H.pre $ H.code H.! HA.class_ (H.toValue l) $ rendered
Nothing -> H.pre $ H.code $ rendered
, msLinkNewTab = False
, msBlankBeforeBlockquote = True
, msBlockFilter = id
}
codeFencedHandler :: Text
-> Map Text (Text -> FencedHandler)
codeFencedHandler key = singleton key $ \lang -> FHRaw $
return . BlockCode (if T.null lang then Nothing else Just lang)
htmlFencedHandler :: Text
-> (Text -> Text)
-> (Text -> Text)
-> Map Text (Text -> FencedHandler)
htmlFencedHandler key start end = singleton key $ \lang -> FHParsed $ \blocks ->
BlockHtml (start lang)
: blocks
++ [BlockHtml $ end lang]
data ListType = Ordered | Unordered
deriving (Show, Eq)
data Block inline
= BlockPara inline
| BlockList ListType (Either inline [Block inline])
| BlockCode (Maybe Text) Text
| BlockQuote [Block inline]
| BlockHtml Text
| BlockRule
| BlockHeading Int inline
| BlockReference Text Text
| BlockPlainText inline
deriving (Show, Eq)
instance Functor Block where
fmap f (BlockPara i) = BlockPara (f i)
fmap f (BlockList lt (Left i)) = BlockList lt $ Left $ f i
fmap f (BlockList lt (Right bs)) = BlockList lt $ Right $ map (fmap f) bs
fmap _ (BlockCode a b) = BlockCode a b
fmap f (BlockQuote bs) = BlockQuote $ map (fmap f) bs
fmap _ (BlockHtml t) = BlockHtml t
fmap _ BlockRule = BlockRule
fmap f (BlockHeading level i) = BlockHeading level (f i)
fmap _ (BlockReference x y) = BlockReference x y
fmap f (BlockPlainText x) = BlockPlainText (f x)
data Inline = InlineText Text
| InlineItalic [Inline]
| InlineBold [Inline]
| InlineCode Text
| InlineHtml Text
| InlineLink Text (Maybe Text) [Inline]
| InlineImage Text (Maybe Text) Text
| InlineFootnoteRef Integer
| InlineFootnote Integer
deriving (Show, Eq)