nbparts-0.1.0.0: src/Nbparts/Types/Sources/Markdown.hs
module Nbparts.Types.Sources.Markdown where
import Commonmark
( Format,
HasAttributes,
IsBlock
( blockQuote,
codeBlock,
heading,
list,
paragraph,
plain,
rawBlock,
referenceLinkDefinition,
thematicBreak
),
IsInline
( code,
emph,
entity,
escapedChar,
image,
lineBreak,
link,
rawInline,
softBreak,
str,
strong
),
ListSpacing,
ListType,
Rangeable (ranged),
SourceRange,
)
import Commonmark.Types (HasAttributes (addAttributes))
import Data.Data (Data, Typeable)
import Data.Map (Map)
import Data.Map qualified as Map
import Data.Sequence (Seq)
import Data.Sequence qualified as Seq
import Data.Text (Text)
newtype Inlines = Inlines (Seq Inline)
deriving (Show, Semigroup, Monoid, Data, Typeable)
data Inline
= Inline
{ inlineType :: InlineType,
sourceRange :: SourceRange,
attributes :: Map Text Text
}
deriving (Show, Data, Typeable)
data InlineType
= Code Text
| Emph Inlines
| Entity Text
| EscapedChar Char
| Image Text Text Inlines
| LineBreak
| Link Text Text Inlines
| RawInline Format Text
| SoftBreak
| Str Text
| Strong Inlines
deriving (Show, Data, Typeable)
singletonInlines :: InlineType -> Inlines
singletonInlines = Inlines . Seq.singleton . mkInline
mkInline :: InlineType -> Inline
mkInline ilType = Inline ilType mempty mempty
instance Rangeable Inlines where
ranged srcRange' (Inlines ils) =
Inlines $
fmap
(\(Inline ilType srcRange attrs) -> Inline ilType (srcRange <> srcRange') attrs)
ils
instance HasAttributes Inlines where
addAttributes attrs (Inlines ils) =
Inlines $
fmap
(\(Inline ilType srcRange ilAttrs) -> Inline ilType srcRange $ ilAttrs <> Map.fromList attrs)
ils
instance IsInline Inlines where
lineBreak = singletonInlines LineBreak
softBreak = singletonInlines SoftBreak
str = singletonInlines . Str
entity = singletonInlines . Entity
escapedChar = singletonInlines . EscapedChar
emph = singletonInlines . Emph
strong = singletonInlines . Strong
link target title ils = singletonInlines $ Link target title ils
image target title ils = singletonInlines $ Image target title ils
code = singletonInlines . Code
rawInline format txt = singletonInlines $ RawInline format txt
newtype Blocks = Blocks (Seq Block)
deriving (Show, Semigroup, Monoid, Data, Typeable)
data Block = Block
{ blockType :: BlockType,
sourceRange :: SourceRange,
attributes :: Map Text Text
}
deriving (Show, Data, Typeable)
data BlockType
= Paragraph Inlines
| Plain Inlines
| ThematicBreak
| BlockQuote Blocks
| CodeBlock Text Text
| Heading Int Inlines
| RawBlock Format Text
| ReferenceLinkDefinition Text (Text, Text)
| List ListType ListSpacing Blocks
deriving (Show, Data, Typeable)
singletonBlocks :: BlockType -> Blocks
singletonBlocks = Blocks . Seq.singleton . mkBlock
mkBlock :: BlockType -> Block
mkBlock blockType = Block blockType mempty mempty
instance Rangeable Blocks where
ranged srcRange' (Blocks blks) =
Blocks $
fmap
(\(Block blkType srcRange attrs) -> Block blkType (srcRange <> srcRange') attrs)
blks
instance HasAttributes Blocks where
addAttributes attrs (Blocks blks) =
Blocks $
fmap
(\(Block blkType srcRange blkAttrs) -> Block blkType srcRange $ blkAttrs <> Map.fromList attrs)
blks
instance IsBlock Inlines Blocks where
paragraph = singletonBlocks . Paragraph
plain = singletonBlocks . Plain
thematicBreak = singletonBlocks ThematicBreak
blockQuote = singletonBlocks . BlockQuote
codeBlock info txt = singletonBlocks $ CodeBlock info txt
heading level ils = singletonBlocks $ Heading level ils
rawBlock format txt = singletonBlocks $ RawBlock format txt
referenceLinkDefinition label (dest, title) = singletonBlocks $ ReferenceLinkDefinition label (dest, title)
list listType listSpacing blks = singletonBlocks $ List listType listSpacing (mconcat blks)