sundown-0.6: src/Text/Sundown/Html/ByteString.hs
{-# Language ForeignFunctionInterface #-}
{-|
Warning: you should not need to use this module, if you're storing your text
sanely. Use "Text.Sundown.Html.String" or "Text.Sundown.Html.Text" so that you
won't have to worry about text encoding.
If you really want to use 'ByteString's directly, make sure that they are UTF-8.
-}
module Text.Sundown.Html.ByteString
( renderHtml
, smartypants
-- * Markdown extensions
, Extensions (..)
, allExtensions
, noExtensions
-- * Html render modes
, HtmlRenderMode (..)
, noHtmlModes
, allHtmlModes
) where
import Data.Maybe (fromMaybe)
import Foreign.Marshal
import Foreign.Ptr
import Foreign.Storable
import System.IO.Unsafe
import Data.ByteString (ByteString)
import qualified Data.ByteString.Unsafe as BS
import Text.Sundown.Buffer.Foreign
import Text.Sundown.Foreign
import Text.Sundown.Html.Foreign
defaultMaxNesting :: Int
defaultMaxNesting = 16
-- | Parses a 'ByteString' containing the markdown, returns the Html code.
renderHtml :: Extensions
-> HtmlRenderMode
-> Bool -- ^ If true, smartypant the output
-> Maybe Int
-- ^ The maximum nesting of the HTML. If Nothing, a default value
-- (16) will be used.
-> ByteString
-> ByteString
{-# NOINLINE renderHtml #-}
renderHtml exts mode sp maxNestingM input =
unsafePerformIO $
alloca $ \callbacks ->
alloca $ \options ->
BS.unsafeUseAsCStringLen input $ \(ptr, len) -> do
ob <- bufnew 64
sdhtml_renderer callbacks options mode
let maxNesting = fromIntegral $ fromMaybe defaultMaxNesting maxNestingM
markdown <- sd_markdown_new exts maxNesting callbacks (castPtr options)
sd_markdown_render ob ptr (fromIntegral len) markdown
sd_markdown_free markdown
res <- if sp then
do ob' <- bufnew 64
Buffer {buf_data = optr, buf_size = olen} <- peek ob
sdhtml_smartypants ob' optr olen
bufrelease ob
return ob'
else return ob
output <- peek res >>= getBufferData
bufrelease res
return output
-- | All the 'HtmlRenderMode' disabled
noHtmlModes :: HtmlRenderMode
noHtmlModes = HtmlRenderMode False False False False False False False False
False False
-- | All the 'HtmlRenderMode' enabled
allHtmlModes :: HtmlRenderMode
allHtmlModes = HtmlRenderMode True True True True True True True True True True
-- | Converts punctuation in Html entities,
-- <http://daringfireball.net/projects/smartypants/>
smartypants :: ByteString -> ByteString
{-# NOINLINE smartypants #-}
smartypants input =
unsafePerformIO $
BS.unsafeUseAsCStringLen input $ \(ptr, len) -> do
ob <- bufnew 64
sdhtml_smartypants ob ptr (fromIntegral len)
output <- peek ob >>= getBufferData
bufrelease ob
return output