emanote-0.8.0.0: src/Emanote/Pandoc/Renderer.hs
{-# LANGUAGE RecordWildCards #-}
-- | Types for custom render extensions to Pandoc AST nodes.
--
-- Note that unlike Pandoc *filters* (which operate on entire document), these
-- are modeled based on Text.Pandoc.Walk, ie. fine-grained on individual inline
-- and block processing. We do this only so as to render a specific node during
-- recursion (cf. `rpBlock` and `rpInline` in Render.hs).
--
-- So we expect the extensions to be in Haskell, however external script may be
-- supported using a traditional whole-AST extension API.
module Emanote.Pandoc.Renderer
( PandocRenderers (PandocRenderers),
PandocInlineRenderer,
PandocBlockRenderer,
mkRenderCtxWithPandocRenderers,
EmanotePandocRenderers (..),
)
where
import Heist (HeistT)
import Heist.Extra.Splices.Pandoc qualified as Splices
import Heist.Extra.Splices.Pandoc.Ctx qualified as Splices
import Heist.Interpreted qualified as HI
import Relude
import Text.Pandoc.Definition qualified as B
-- | Custom Heist renderer function for specific Pandoc AST nodes
type PandocRenderF model route astNode =
model ->
PandocRenderers model route ->
Splices.RenderCtx ->
route ->
astNode ->
Maybe (HI.Splice Identity)
type PandocInlineRenderer model route = PandocRenderF model route B.Inline
type PandocBlockRenderer model route = PandocRenderF model route B.Block
data PandocRenderers model route = PandocRenderers
{ pandocInlineRenderers :: [PandocInlineRenderer model route],
pandocBlockRenderers :: [PandocBlockRenderer model route]
}
mkRenderCtxWithPandocRenderers ::
forall model route m.
(Monad m) =>
PandocRenderers model route ->
Map Text Text ->
model ->
route ->
HeistT Identity m Splices.RenderCtx
mkRenderCtxWithPandocRenderers nr@PandocRenderers {..} classRules model x =
Splices.mkRenderCtx
classRules
( \ctx blk ->
asum $
pandocBlockRenderers <&> \f ->
f model nr ctx x blk
)
( \ctx blk ->
asum $
pandocInlineRenderers <&> \f ->
f model nr ctx x blk
)
data EmanotePandocRenderers a r = EmanotePandocRenderers
{ blockRenderers :: PandocRenderers a r,
-- | Like `blockRenderers` but for use in inline contexts.
--
-- Backlinks and titles constitute an example of inline context, where we don't
-- care about block elements.
inlineRenderers :: PandocRenderers a r,
-- | Like `inlineRenderers` but suitable for use inside links (<a> tags).
linkInlineRenderers :: PandocRenderers a r
}