cmark-sections-0.2.0.0: Represent cmark-parsed Markdown as a tree of sections

Safe HaskellNone
LanguageHaskell2010

CMark.Sections

Contents

Description

This library lets you parse Markdown into a hierarchical structure (delimited by headings). For instance, let's say your document looks like this:

This is the preface.

First chapter
========================================

This chapter doesn't have sections.

Second chapter
========================================

First section
--------------------

Here's some text.

Second section
--------------------

And more text.

It can be represented as a tree:

preface: "This is the preface."

sections:
    * heading: "First chapter"
      content: "This chapter doesn't have sections."
      sections: []

    * heading: "Second chapter"
      sections:
          * heading: "First section"
            content: "Here's some text."
            sections: []

          * heading: "Second section"
            content: "And more text."
            sections: []

That's what this library does. Moreover, it lets you access the Markdown source of every node of the tree.

In most cases the only thing you need to do is something like this:

nodesToDocument . commonmarkToNodesWithSource [optSafe, optNormalize]

You can preprocess parsed Markdown after doing commonmarkToNodesWithSource as long as you don't add or remove any top-level nodes.

Synopsis

Parse Markdown to trees

commonmarkToNodesWithSource :: [CMarkOption] -> Text -> WithSource [Node] Source #

commonmarkToNodesWithSource parses Markdown with the given options and extracts nodes from the initial DOCUMENT node.

nodesToDocument :: WithSource [Node] -> Document () () Source #

Turn a list of Markdown nodes into a tree.

data WithSource a Source #

A data type for annotating things with their source. In this library we only use WithSource [Node], which stands for “some Markdown nodes + source”.

Constructors

WithSource Text a 

Instances

Functor WithSource Source # 

Methods

fmap :: (a -> b) -> WithSource a -> WithSource b #

(<$) :: a -> WithSource b -> WithSource a #

Foldable WithSource Source # 

Methods

fold :: Monoid m => WithSource m -> m #

foldMap :: Monoid m => (a -> m) -> WithSource a -> m #

foldr :: (a -> b -> b) -> b -> WithSource a -> b #

foldr' :: (a -> b -> b) -> b -> WithSource a -> b #

foldl :: (b -> a -> b) -> b -> WithSource a -> b #

foldl' :: (b -> a -> b) -> b -> WithSource a -> b #

foldr1 :: (a -> a -> a) -> WithSource a -> a #

foldl1 :: (a -> a -> a) -> WithSource a -> a #

toList :: WithSource a -> [a] #

null :: WithSource a -> Bool #

length :: WithSource a -> Int #

elem :: Eq a => a -> WithSource a -> Bool #

maximum :: Ord a => WithSource a -> a #

minimum :: Ord a => WithSource a -> a #

sum :: Num a => WithSource a -> a #

product :: Num a => WithSource a -> a #

Traversable WithSource Source # 

Methods

traverse :: Applicative f => (a -> f b) -> WithSource a -> f (WithSource b) #

sequenceA :: Applicative f => WithSource (f a) -> f (WithSource a) #

mapM :: Monad m => (a -> m b) -> WithSource a -> m (WithSource b) #

sequence :: Monad m => WithSource (m a) -> m (WithSource a) #

Eq a => Eq (WithSource a) Source # 

Methods

(==) :: WithSource a -> WithSource a -> Bool #

(/=) :: WithSource a -> WithSource a -> Bool #

Show a => Show (WithSource a) Source # 
Monoid a => Monoid (WithSource a) Source # 

getSource :: WithSource a -> Text Source #

Extract source from WithSource (it's stored there in a field).

stripSource :: WithSource a -> a Source #

Extract data from WithSource.

data Section a b Source #

A section in the Markdown tree.

Sections do not contain subsections; i.e. Section isn't recursive and the tree structure is provided by Data.Tree.

In a Section a b, the heading is coupled with a value of type a, and content – with a value of type b. This is occasionally useful.

Constructors

Section 

Fields

Instances

(Eq b, Eq a) => Eq (Section a b) Source # 

Methods

(==) :: Section a b -> Section a b -> Bool #

(/=) :: Section a b -> Section a b -> Bool #

(Show b, Show a) => Show (Section a b) Source # 

Methods

showsPrec :: Int -> Section a b -> ShowS #

show :: Section a b -> String #

showList :: [Section a b] -> ShowS #

data Document a b Source #

The whole parsed Markdown tree. In a Document a b, headings are annotated with a and content blocks – with b.

Constructors

Document 

Fields

Instances

(Eq a, Eq b) => Eq (Document a b) Source # 

Methods

(==) :: Document a b -> Document a b -> Bool #

(/=) :: Document a b -> Document a b -> Bool #

(Show a, Show b) => Show (Document a b) Source # 

Methods

showsPrec :: Int -> Document a b -> ShowS #

show :: Document a b -> String #

showList :: [Document a b] -> ShowS #

Work with parsed trees

Note that you can use (<>) to combine WithSource nodes together. It will concatenate sources and parsed Markdown.

I'm not sure how valid this operation is for Markdown, but probably more-or-less valid (when you exclude corner cases like missing newlines at the end and duplicate links). Maybe cmark doesn't even allow duplicate links, I don't know.

flattenDocument :: Document a b -> WithSource [Node] Source #

Turn the whole parsed-and-broken-down Document into a list of nodes.

flattenSection :: Section a b -> WithSource [Node] Source #

Turn a section into a list of nodes.

flattenTree :: Tree (Section a b) -> WithSource [Node] Source #

Turn a Data.Tree Tree into a list of nodes.

flattenForest :: Forest (Section a b) -> WithSource [Node] Source #

Turn a Data.Tree Forest into a list of nodes.