{-# Language ForeignFunctionInterface #-}
module Text.Sundown.Html.ByteString
( renderHtml
, smartypants
, Extensions (..)
, allExtensions
, noExtensions
, 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 :: Int
defaultMaxNesting = Int
16
renderHtml :: Extensions
-> HtmlRenderMode
-> Bool
-> Maybe Int
-> ByteString
-> ByteString
{-# NOINLINE renderHtml #-}
renderHtml :: Extensions
-> HtmlRenderMode -> Bool -> Maybe Int -> ByteString -> ByteString
renderHtml Extensions
exts HtmlRenderMode
mode Bool
sp Maybe Int
maxNestingM ByteString
input =
IO ByteString -> ByteString
forall a. IO a -> a
unsafePerformIO (IO ByteString -> ByteString) -> IO ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$
(Ptr Callbacks -> IO ByteString) -> IO ByteString
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr Callbacks -> IO ByteString) -> IO ByteString)
-> (Ptr Callbacks -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr Callbacks
callbacks ->
(Ptr HtmlRenderOptions -> IO ByteString) -> IO ByteString
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr HtmlRenderOptions -> IO ByteString) -> IO ByteString)
-> (Ptr HtmlRenderOptions -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr HtmlRenderOptions
options ->
ByteString -> (CStringLen -> IO ByteString) -> IO ByteString
forall a. ByteString -> (CStringLen -> IO a) -> IO a
BS.unsafeUseAsCStringLen ByteString
input ((CStringLen -> IO ByteString) -> IO ByteString)
-> (CStringLen -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
ptr, Int
len) -> do
Ptr Buffer
ob <- CSize -> IO (Ptr Buffer)
bufnew CSize
64
Ptr Callbacks -> Ptr HtmlRenderOptions -> HtmlRenderMode -> IO ()
sdhtml_renderer Ptr Callbacks
callbacks Ptr HtmlRenderOptions
options HtmlRenderMode
mode
let maxNesting :: CSize
maxNesting = Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> CSize) -> Int -> CSize
forall a b. (a -> b) -> a -> b
$ Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
defaultMaxNesting Maybe Int
maxNestingM
Ptr Markdown
markdown <- Extensions -> CSize -> Ptr Callbacks -> Ptr () -> IO (Ptr Markdown)
sd_markdown_new Extensions
exts CSize
maxNesting Ptr Callbacks
callbacks (Ptr HtmlRenderOptions -> Ptr ()
forall a b. Ptr a -> Ptr b
castPtr Ptr HtmlRenderOptions
options)
Ptr Buffer -> Ptr CChar -> CSize -> Ptr Markdown -> IO ()
sd_markdown_render Ptr Buffer
ob Ptr CChar
ptr (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len) Ptr Markdown
markdown
Ptr Markdown -> IO ()
sd_markdown_free Ptr Markdown
markdown
Ptr Buffer
res <- if Bool
sp then
do Ptr Buffer
ob' <- CSize -> IO (Ptr Buffer)
bufnew CSize
64
Buffer {buf_data :: Buffer -> Ptr CChar
buf_data = Ptr CChar
optr, buf_size :: Buffer -> CSize
buf_size = CSize
olen} <- Ptr Buffer -> IO Buffer
forall a. Storable a => Ptr a -> IO a
peek Ptr Buffer
ob
Ptr Buffer -> Ptr CChar -> CSize -> IO ()
sdhtml_smartypants Ptr Buffer
ob' Ptr CChar
optr CSize
olen
Ptr Buffer -> IO ()
bufrelease Ptr Buffer
ob
Ptr Buffer -> IO (Ptr Buffer)
forall (m :: * -> *) a. Monad m => a -> m a
return Ptr Buffer
ob'
else Ptr Buffer -> IO (Ptr Buffer)
forall (m :: * -> *) a. Monad m => a -> m a
return Ptr Buffer
ob
ByteString
output <- Ptr Buffer -> IO Buffer
forall a. Storable a => Ptr a -> IO a
peek Ptr Buffer
res IO Buffer -> (Buffer -> IO ByteString) -> IO ByteString
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Buffer -> IO ByteString
getBufferData
Ptr Buffer -> IO ()
bufrelease Ptr Buffer
res
ByteString -> IO ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
output
noHtmlModes :: HtmlRenderMode
noHtmlModes :: HtmlRenderMode
noHtmlModes = Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> HtmlRenderMode
HtmlRenderMode Bool
False Bool
False Bool
False Bool
False Bool
False Bool
False Bool
False Bool
False
Bool
False Bool
False
allHtmlModes :: HtmlRenderMode
allHtmlModes :: HtmlRenderMode
allHtmlModes = Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> Bool
-> HtmlRenderMode
HtmlRenderMode Bool
True Bool
True Bool
True Bool
True Bool
True Bool
True Bool
True Bool
True Bool
True Bool
True
smartypants :: ByteString -> ByteString
{-# NOINLINE smartypants #-}
smartypants :: ByteString -> ByteString
smartypants ByteString
input =
IO ByteString -> ByteString
forall a. IO a -> a
unsafePerformIO (IO ByteString -> ByteString) -> IO ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$
ByteString -> (CStringLen -> IO ByteString) -> IO ByteString
forall a. ByteString -> (CStringLen -> IO a) -> IO a
BS.unsafeUseAsCStringLen ByteString
input ((CStringLen -> IO ByteString) -> IO ByteString)
-> (CStringLen -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
ptr, Int
len) -> do
Ptr Buffer
ob <- CSize -> IO (Ptr Buffer)
bufnew CSize
64
Ptr Buffer -> Ptr CChar -> CSize -> IO ()
sdhtml_smartypants Ptr Buffer
ob Ptr CChar
ptr (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)
ByteString
output <- Ptr Buffer -> IO Buffer
forall a. Storable a => Ptr a -> IO a
peek Ptr Buffer
ob IO Buffer -> (Buffer -> IO ByteString) -> IO ByteString
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Buffer -> IO ByteString
getBufferData
Ptr Buffer -> IO ()
bufrelease Ptr Buffer
ob
ByteString -> IO ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
output