heist-extra 0.3.0.0 → 0.4.0.0
raw patch · 4 files changed
+55/−13 lines, 4 filesdep ~basePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base
API changes (from Hackage documentation)
- Heist.Extra.TemplateState: instance Data.Default.Class.Default Heist.Extra.TemplateState.TemplateState
+ Heist.Extra.TemplateState: instance Data.Default.Internal.Default Heist.Extra.TemplateState.TemplateState
- Heist.Extra: availableTemplates :: HeistState n -> [Text]
+ Heist.Extra: availableTemplates :: forall (n :: Type -> Type). HeistState n -> [Text]
- Heist.Extra: lookupHtmlTemplate :: Monad n => ByteString -> HeistT m n (Maybe Template)
+ Heist.Extra: lookupHtmlTemplate :: forall (n :: Type -> Type) (m :: Type -> Type). Monad n => ByteString -> HeistT m n (Maybe Template)
- Heist.Extra: lookupHtmlTemplateMust :: forall m n. Monad n => ByteString -> HeistT m n Template
+ Heist.Extra: lookupHtmlTemplateMust :: forall (m :: Type -> Type) (n :: Type -> Type). Monad n => ByteString -> HeistT m n Template
- Heist.Extra.Splices.Pandoc.Ctx: mkRenderCtx :: Monad m => Map Text Text -> (RenderCtx -> Block -> Maybe (Splice Identity)) -> (RenderCtx -> Inline -> Maybe (Splice Identity)) -> HeistT Identity m RenderCtx
+ Heist.Extra.Splices.Pandoc.Ctx: mkRenderCtx :: forall (m :: Type -> Type). Monad m => Map Text Text -> (RenderCtx -> Block -> Maybe (Splice Identity)) -> (RenderCtx -> Inline -> Maybe (Splice Identity)) -> HeistT Identity m RenderCtx
Files
- CHANGELOG.md +6/−0
- heist-extra.cabal +2/−2
- src/Heist/Extra/Splices/Pandoc/Ctx.hs +0/−4
- src/Heist/Extra/Splices/Pandoc/Render.hs +47/−7
CHANGELOG.md view
@@ -1,5 +1,11 @@ # Revision history for heist-extra +## 0.4.0.0 (2025-08-19)++- **Backwards incompatible** changes+ - Improved Header renderer to included heading ID (#6)+- Handle simple inline raw html such as for `<kbd>` (#8)+ ## 0.3.0.0 (2023-08-09) - `treeSplice`: pass children to sortKey function (#2)
heist-extra.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: heist-extra-version: 0.3.0.0+version: 0.4.0.0 license: MIT copyright: 2022 Sridhar Ratnakumar maintainer: srid@srid.ca@@ -69,7 +69,7 @@ ViewPatterns build-depends:- , base >=4.13.0.0 && <4.18.0.0.0+ , base >=4.13.0.0 && <5 , data-default , filepath , heist >=1.1.1.0
src/Heist/Extra/Splices/Pandoc/Ctx.hs view
@@ -103,10 +103,6 @@ B.OrderedList {} -> childTagAttr node "OrderedList" B.CodeBlock {} -> childTagAttr node "CodeBlock" B.BlockQuote {} -> childTagAttr node "BlockQuote"- B.Header level _ _ ->- fromMaybe B.nullAttr $ do- header <- X.childElementTag "Header" node- pure $ childTagAttr header ("h" <> show level) _ -> B.nullAttr inlineLookupAttr :: X.Node -> B.Inline -> B.Attr
src/Heist/Extra/Splices/Pandoc/Render.hs view
@@ -43,14 +43,14 @@ rpBlock' :: RenderCtx -> B.Block -> HI.Splice Identity rpBlock' ctx@RenderCtx {..} b = case b of B.Plain is ->- rpInlineWithTasks ctx is+ rpInlineWithTasks ctx (convertRawInline [] is) B.Para is -> do- let innerSplice = rpInlineWithTasks ctx is+ let innerSplice = rpInlineWithTasks ctx (convertRawInline [] is) withTplTag ctx "Para" ("inlines" ## innerSplice) $ one . X.Element "p" mempty <$> innerSplice B.LineBlock iss -> flip foldMapM iss $ \is ->- foldMapM (rpInline ctx) is >> pure [X.TextNode "\n"]+ foldMapM (rpInline ctx) (convertRawInline [] is) >> pure [X.TextNode "\n"] B.CodeBlock (id', mkLangClass -> classes, attrs) s -> do pure $ one . X.Element "div" (rpAttr $ bAttr b) $@@ -81,14 +81,16 @@ withTplTag ctx "DefinitionList" (definitionListSplices defs) $ fmap (one . X.Element "dl" mempty) $ flip foldMapM defs $ \(term, descList) -> do- a <- foldMapM (rpInline ctx) term+ a <- foldMapM (rpInline ctx) (convertRawInline [] term) as <- flip foldMapM descList $ fmap (one . X.Element "dd" mempty) . foldMapM (rpBlock ctx) pure $ a <> as- B.Header level attr is ->- one . X.Element (headerTag level) (rpAttr $ concatAttr attr $ bAttr b)- <$> foldMapM (rpInline ctx) is+ B.Header level attr@(headerId, _, _) is -> do+ let innerSplice = foldMapM (rpInline ctx) (convertRawInline [] is)+ withTplTag ctx ("Header:" <> show level) (headerSplices headerId innerSplice) $+ one . X.Element (headerTag level) (rpAttr $ concatAttr attr $ bAttr b)+ <$> innerSplice B.HorizontalRule -> withTplTag ctx "HorizontalRule" mempty (pure $ one $ X.Element "hr" mempty mempty) B.Table attr _captions _colSpec (B.TableHead _ hrows) tbodys _tfoot -> do@@ -136,6 +138,10 @@ let lang = head classes pure $ lang : ("language-" <> lang) : tail classes + headerSplices headerId innerSplice = do+ "header:id" ## HI.textSplice headerId+ "inlines" ## innerSplice+ definitionListSplices :: [([B.Inline], [[B.Block]])] -> H.Splices (HI.Splice Identity) definitionListSplices defs = do "DefinitionList:Items" ## (HI.runChildrenWith . uncurry itemsSplices) `foldMapM` defs@@ -246,6 +252,40 @@ B.DoubleQuote -> w <&> \nodes -> [X.TextNode "“"] <> nodes <> [X.TextNode "”"]++{- | Convert raw html attribute sequence into span++ For example, this markdown: `<kbd>ctrl</kbd>`, which is in native pandoc:+ RawInline (Format "html") "<kbd>" : Str "ctrl" : RawInline (Format "html") "</kbd>"+ … is converted as:+ <span xmlhtmlraw=""><kbd>ctrl</kbd></span>+ … instead of the default behavior which is:+ <span xmlhtmlraw=""><kbd></kbd></span>ctrl<span xmlhtmlraw=""></span>+-}+convertRawInline :: [B.Inline] -> [B.Inline] -> [B.Inline]+convertRawInline acc = \case+ [] -> reverse acc+ (B.RawInline (B.Format "html") oTag : rest)+ | -- This is a new raw tag, let's find a matching closing tag+ Just (newElem, is) <- mkHtmlInline oTag rest ->+ convertRawInline (newElem : acc) is+ i : is -> convertRawInline (i : acc) is+ where+ mkHtmlInline :: Text -> [B.Inline] -> Maybe (B.Inline, [B.Inline])+ mkHtmlInline oTag rest = case span (not . isClosingTag oTag) rest of+ -- Collect the inner element until a closing tag+ (inner, (closing : is))+ | -- Verify we did find a matching tag+ isClosingTag oTag closing ->+ let inner' = oTag <> plainify inner <> "</" <> T.drop 1 oTag+ in Just (B.RawInline (B.Format "html") inner', is)+ _ -> Nothing++ isClosingTag :: Text -> B.Inline -> Bool+ isClosingTag oTag = \case+ B.RawInline (B.Format "html") eTag ->+ "<" `T.isPrefixOf` oTag && "</" `T.isPrefixOf` eTag && T.drop 1 oTag == T.drop 2 eTag+ _ -> False -- | Like rpInline', but supports task checkbox in the given inlines. rpInlineWithTasks :: RenderCtx -> [B.Inline] -> HI.Splice Identity