markdown-0.1.17.4/Text/0000755000000000000000000000000013252405552012701 5ustar0000000000000000markdown-0.1.17.4/Text/Markdown/0000755000000000000000000000000013256413103014456 5ustar0000000000000000markdown-0.1.17.4/test/0000755000000000000000000000000013350661306012734 5ustar0000000000000000markdown-0.1.17.4/test/Tests/0000755000000000000000000000000012677401324014041 5ustar0000000000000000markdown-0.1.17.4/test/examples/0000755000000000000000000000000013350660574014560 5ustar0000000000000000markdown-0.1.17.4/Text/Markdown.hs0000644000000000000000000001511313252405552015020 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE RankNTypes #-} module Text.Markdown ( -- * Functions markdown -- * Settings , MarkdownSettings , defaultMarkdownSettings , msXssProtect , msStandaloneHtml , msFencedHandlers , msBlockCodeRenderer , msLinkNewTab , msBlankBeforeBlockquote , msBlockFilter , msAddHeadingId , setNoFollowExternal -- * Newtype , Markdown (..) -- * Fenced handlers , FencedHandler (..) , codeFencedHandler , htmlFencedHandler -- * Convenience re-exports , def ) where import Control.Arrow ((&&&)) import Text.Markdown.Inline import Text.Markdown.Block import Text.Markdown.Types import Prelude hiding (sequence, takeWhile) import Data.Char (isAlphaNum) import Data.Default (Default (..)) import Data.List (intercalate, isInfixOf) import Data.Maybe (isJust) import Data.Text (Text) import qualified Data.Text as T import qualified Data.Text.Lazy as TL import Text.Blaze (toValue) import Text.Blaze.Html (ToMarkup (..), Html) import Text.Blaze.Html.Renderer.Text (renderHtml) import Data.Conduit import qualified Data.Conduit.List as CL import Data.Monoid (Monoid (mappend, mempty, mconcat), (<>)) import qualified Text.Blaze.Html5 as H import qualified Text.Blaze.Html5.Attributes as HA import Text.HTML.SanitizeXSS (sanitizeBalance) import qualified Data.Map as Map import Data.String (IsString) import Data.Semigroup (Semigroup) -- | A newtype wrapper providing a @ToHtml@ instance. newtype Markdown = Markdown TL.Text deriving(Eq, Ord, Monoid, Semigroup, IsString, Show) instance ToMarkup Markdown where toMarkup (Markdown t) = markdown def t -- | Convert the given textual markdown content to HTML. -- -- >>> :set -XOverloadedStrings -- >>> import Text.Blaze.Html.Renderer.Text -- >>> renderHtml $ markdown def "# Hello World!" -- "

Hello World!

" -- -- >>> renderHtml $ markdown def { msXssProtect = False } "" -- "" markdown :: MarkdownSettings -> TL.Text -> Html markdown ms tl = sanitize $ runConduitPure $ CL.sourceList blocksH .| toHtmlB ms .| CL.fold mappend mempty where sanitize | msXssProtect ms = preEscapedToMarkup . sanitizeBalance . TL.toStrict . renderHtml | otherwise = id blocksH :: [Block Html] blocksH = processBlocks blocks blocks :: [Block Text] blocks = runConduitPure $ CL.sourceList (TL.toChunks tl) .| toBlocks ms .| CL.consume processBlocks :: [Block Text] -> [Block Html] processBlocks = map (fmap $ toHtmlI ms) . msBlockFilter ms . map (fmap $ intercalate [InlineHtml "
"]) . map (fmap $ map $ toInline refs) . map toBlockLines refs = Map.unions $ map toRef blocks where toRef (BlockReference x y) = Map.singleton x y toRef _ = Map.empty data MState = NoState | InList ListType toHtmlB :: Monad m => MarkdownSettings -> ConduitM (Block Html) Html m () toHtmlB ms = loop NoState where loop state = await >>= maybe (closeState state) (\x -> do state' <- getState state x yield $ go x loop state') closeState NoState = return () closeState (InList Unordered) = yield $ escape "" closeState (InList Ordered) = yield $ escape "" getState NoState (BlockList ltype _) = do yield $ escape $ case ltype of Unordered -> "