{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ViewPatterns #-}
module Rib.Parser.MMark
(
parse,
parsePure,
render,
getFirstImg,
projectYaml,
MMark,
)
where
import Control.Foldl (Fold (..))
import Development.Shake (readFile')
import Lucid (Html)
import Path
import Relude
import Rib.Source (SourceReader)
import Text.MMark (MMark, projectYaml)
import qualified Text.MMark as MMark
import qualified Text.MMark.Extension as Ext
import qualified Text.MMark.Extension.Common as Ext
import qualified Text.Megaparsec as M
import Text.URI (URI)
render :: MMark -> Html ()
render = MMark.render
parsePure ::
FilePath ->
Text ->
Either Text MMark
parsePure k s = case MMark.parse k s of
Left e -> Left $ toText $ M.errorBundlePretty e
Right doc -> Right $ MMark.useExtensions exts $ useTocExt doc
parse :: SourceReader MMark
parse (toFilePath -> f) = do
s <- toText <$> readFile' f
pure $ parsePure f s
getFirstImg :: MMark -> Maybe URI
getFirstImg = flip MMark.runScanner $ Fold f Nothing id
where
f acc blk = acc <|> listToMaybe (mapMaybe getImgUri (inlinesContainingImg blk))
getImgUri = \case
Ext.Image _ uri _ -> Just uri
_ -> Nothing
inlinesContainingImg :: Ext.Bni -> [Ext.Inline]
inlinesContainingImg = \case
Ext.Naked xs -> toList xs
Ext.Paragraph xs -> toList xs
_ -> []
exts :: [MMark.Extension]
exts =
[ Ext.fontAwesome,
Ext.footnotes,
Ext.kbd,
Ext.linkTarget,
Ext.mathJax (Just '$'),
Ext.obfuscateEmail "protected-email",
Ext.punctuationPrettifier,
Ext.ghcSyntaxHighlighter,
Ext.skylighting
]
useTocExt :: MMark -> MMark
useTocExt doc = MMark.useExtension (Ext.toc "toc" toc) doc
where
toc = MMark.runScanner doc $ Ext.tocScanner (\x -> x > 1 && x < 5)