cmark-sections 0.2.0.0 → 0.3.0
raw patch · 4 files changed
+78/−43 lines, 4 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ CMark.Sections: [contentAnn] :: Section a b -> b
+ CMark.Sections: [headingAnn] :: Section a b -> a
+ CMark.Sections: [prefaceAnn] :: Document a b -> b
+ CMark.Sections: instance (Data.Data.Data b, Data.Data.Data a) => Data.Data.Data (CMark.Sections.Document a b)
+ CMark.Sections: instance (Data.Data.Data b, Data.Data.Data a) => Data.Data.Data (CMark.Sections.Section a b)
+ CMark.Sections: instance Data.Data.Data a => Data.Data.Data (CMark.Sections.WithSource a)
+ CMark.Sections: instance GHC.Generics.Generic (CMark.Sections.Document a b)
+ CMark.Sections: instance GHC.Generics.Generic (CMark.Sections.Section a b)
+ CMark.Sections: instance GHC.Generics.Generic (CMark.Sections.WithSource a)
- CMark.Sections: Document :: (b, WithSource [Node]) -> Forest (Section a b) -> Document a b
+ CMark.Sections: Document :: WithSource [Node] -> b -> Forest (Section a b) -> Document a b
- CMark.Sections: Section :: Int -> (a, WithSource [Node]) -> (b, WithSource [Node]) -> Section a b
+ CMark.Sections: Section :: Int -> WithSource [Node] -> a -> WithSource [Node] -> b -> Section a b
- CMark.Sections: [content] :: Section a b -> (b, WithSource [Node])
+ CMark.Sections: [content] :: Section a b -> WithSource [Node]
- CMark.Sections: [heading] :: Section a b -> (a, WithSource [Node])
+ CMark.Sections: [heading] :: Section a b -> WithSource [Node]
- CMark.Sections: [preface] :: Document a b -> (b, WithSource [Node])
+ CMark.Sections: [preface] :: Document a b -> WithSource [Node]
Files
- CHANGELOG.md +7/−1
- cmark-sections.cabal +1/−1
- lib/CMark/Sections.hs +49/−25
- tests/Main.hs +21/−16
CHANGELOG.md view
@@ -1,4 +1,10 @@-# 0.2+# 0.3.0++* Added `Generic` and `Data` instances.++* Split back `preface`, `header`, `content` from their annotations.++# 0.2.0.0 * Renamed `Annotated` to `WithSource`.
cmark-sections.cabal view
@@ -1,5 +1,5 @@ name: cmark-sections-version: 0.2.0.0+version: 0.3.0 synopsis: Represent cmark-parsed Markdown as a tree of sections description: Represent cmark-parsed Markdown as a tree of sections
lib/CMark/Sections.hs view
@@ -1,12 +1,16 @@-{-# LANGUAGE-RecordWildCards,-DeriveFunctor,-DeriveFoldable,-DeriveTraversable,-OverloadedStrings,-NoImplicitPrelude- #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveFoldable #-}+{-# LANGUAGE DeriveTraversable #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE NoImplicitPrelude #-} +#if __GLASGOW_HASKELL__ == 708+{-# LANGUAGE StandaloneDeriving #-}+#endif {- | This library lets you parse Markdown into a hierarchical structure (delimited by headings). For instance, let's say your document looks like@@ -106,7 +110,7 @@ only use @WithSource [Node]@, which stands for “some Markdown nodes + source”. -} data WithSource a = WithSource Text a- deriving (Eq, Show, Functor, Foldable, Traversable)+ deriving (Eq, Show, Functor, Foldable, Traversable, Generic, Data) -- | Extract source from 'WithSource' (it's stored there in a field). getSource :: WithSource a -> Text@@ -131,22 +135,29 @@ -} data Section a b = Section { -- | Level (from 1 to 6).- level :: Int,+ level :: Int, -- | Heading- heading :: (a, WithSource [Node]),+ heading :: WithSource [Node],+ -- | Annotation for the heading+ headingAnn :: a, -- | Text between the heading and the first subsection. Can be empty.- content :: (b, WithSource [Node])+ content :: WithSource [Node],+ -- | Annotation for the content+ contentAnn :: b }- deriving (Eq, Show)+ deriving (Eq, Show, Generic, Data) {- | The whole parsed Markdown tree. In a @Document a b@, headings are annotated with @a@ and content blocks – with @b@. -} data Document a b = Document { -- | Text before the first section. Can be empty.- preface :: (b, WithSource [Node]),- sections :: Tree.Forest (Section a b) }- deriving (Eq, Show)+ preface :: WithSource [Node],+ -- | Annotation for the preface+ prefaceAnn :: b,+ -- | A tree with the sections comprising the rest of the document+ sections :: Tree.Forest (Section a b) }+ deriving (Eq, Show, Generic, Data) {- | 'commonmarkToNodesWithSource' parses Markdown with the given options and extracts nodes from the initial 'DOCUMENT' node.@@ -249,15 +260,18 @@ makeTree (((level, heading), content) : xs) = let (nested, others) = span (\x -> x^._1._1 > level) xs section = Section {- level = level,- heading = ((), heading),- content = ((), content)+ level = level,+ heading = heading,+ headingAnn = (),+ content = content,+ contentAnn = () } in Tree.Node section (makeTree nested) : makeTree others -- Return the result Document {- preface = ((), prefaceAnnotated),- sections = makeTree blocks+ preface = prefaceAnnotated,+ prefaceAnn = (),+ sections = makeTree blocks } {- $monoid-note@@ -273,15 +287,15 @@ -- | Turn the whole parsed-and-broken-down 'Document' into a list of nodes. flattenDocument :: Document a b -> WithSource [Node]-flattenDocument Document{..} = snd preface <> flattenForest sections+flattenDocument Document{..} = preface <> flattenForest sections -- | Turn a section into a list of nodes. flattenSection :: Section a b -> WithSource [Node] flattenSection Section{..} =- WithSource (getSource (snd heading) <> getSource (snd content))- (headingNode : stripSource (snd content))+ WithSource (getSource heading <> getSource content)+ (headingNode : stripSource content) where- headingNode = Node Nothing (HEADING level) (stripSource (snd heading))+ headingNode = Node Nothing (HEADING level) (stripSource heading) -- | Turn a "Data.Tree" 'Tree.Tree' into a list of nodes. flattenTree :: Tree.Tree (Section a b) -> WithSource [Node]@@ -290,3 +304,13 @@ -- | Turn a "Data.Tree" 'Tree.Forest' into a list of nodes. flattenForest :: Tree.Forest (Section a b) -> WithSource [Node] flattenForest = mconcat . map flattenSection . concatMap Tree.flatten++----------------------------------------------------------------------------+-- Instances for GHC 7.8+----------------------------------------------------------------------------++#if __GLASGOW_HASKELL__ == 708+deriving instance Typeable WithSource+deriving instance Typeable Section+deriving instance Typeable Document+#endif
tests/Main.hs view
@@ -1,9 +1,7 @@-{-# LANGUAGE-OverloadedStrings,-RecordWildCards,-ViewPatterns,-NoImplicitPrelude- #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE NoImplicitPrelude #-} module Main where@@ -28,40 +26,45 @@ main = hspec $ do let mkSect level heading content ns = Tree.Node- (Section level ((), heading) ((), content))+ (Section level heading () content ()) ns describe "converting:" $ do it "empty document" $ do let src = ""- preface = ((), mempty)+ preface = mempty+ prefaceAnn = () sections = [] nodesToDocument (commonmarkToNodesWithSource [] src) `shouldBe` Document{..} it "spaces" $ do let src = " \n\n \n"- preface = ((), WithSource " \n\n \n" [])+ preface = WithSource " \n\n \n" []+ prefaceAnn = () sections = [] nodesToDocument (commonmarkToNodesWithSource [] src) `shouldBe` Document{..} it "paragraph" $ do let src = "x"- preface = ((), WithSource "x" [- Node (Just (PosInfo 1 1 1 1)) PARAGRAPH [text "x"] ])+ preface = WithSource "x" [+ Node (Just (PosInfo 1 1 1 1)) PARAGRAPH [text "x"] ]+ prefaceAnn = () sections = [] nodesToDocument (commonmarkToNodesWithSource [] src) `shouldBe` Document{..} it "3 paragraphs" $ do let src = T.unlines ["","x","","","y","","z",""]- preface = ((), WithSource "\nx\n\n\ny\n\nz\n\n" [+ preface = WithSource "\nx\n\n\ny\n\nz\n\n" [ Node (Just (PosInfo 2 1 2 1)) PARAGRAPH [text "x"], Node (Just (PosInfo 5 1 5 1)) PARAGRAPH [text "y"],- Node (Just (PosInfo 7 1 7 1)) PARAGRAPH [text "z"] ])+ Node (Just (PosInfo 7 1 7 1)) PARAGRAPH [text "z"] ]+ prefaceAnn = () sections = [] nodesToDocument (commonmarkToNodesWithSource [] src) `shouldBe` Document{..} it "headers" $ do let src = T.unlines ["# 1", "", "## 2", "", "## 3"]- preface = ((), mempty)+ preface = mempty+ prefaceAnn = () sections = [ mkSect 1 (WithSource "# 1\n\n" [text "1"]) mempty [ mkSect 2 (WithSource "## 2\n\n" [text "2"]) mempty [],@@ -70,7 +73,8 @@ `shouldBe` Document{..} it "headers+content" $ do let src = T.unlines ["# 1", "", "## 2", "test", "## 3"]- preface = ((), mempty)+ preface = mempty+ prefaceAnn = () sections = [ mkSect 1 (WithSource "# 1\n\n" [text "1"]) mempty [ mkSect 2 (WithSource "## 2\n" [text "2"])@@ -81,7 +85,8 @@ `shouldBe` Document{..} it "preface+headers" $ do let src = T.unlines ["blah", "# 1", "", "## 2", "", "## 3"]- preface = ((), commonmarkToNodesWithSource [] "blah\n")+ preface = commonmarkToNodesWithSource [] "blah\n"+ prefaceAnn = () sections = [ mkSect 1 (WithSource "# 1\n\n" [text "1"]) mempty [ mkSect 2 (WithSource "## 2\n\n" [text "2"]) mempty [],