{-# LANGUAGE CPP #-}
{-# LANGUAGE RankNTypes #-}
module Commonmark.Syntax
( SyntaxSpec(..)
, defaultSyntaxSpec
)
where
import Text.Parsec (ParsecT)
import Commonmark.Tokens (Tok)
import Commonmark.Types
import Commonmark.Blocks
import Commonmark.Inlines
#if !MIN_VERSION_base(4,11,0)
import Data.Semigroup
#endif
data SyntaxSpec m il bl = SyntaxSpec
{ syntaxBlockSpecs :: [BlockSpec m il bl]
, syntaxBracketedSpecs :: [BracketedSpec il]
, syntaxFormattingSpecs :: [FormattingSpec il]
, syntaxInlineParsers :: [InlineParser m il]
, syntaxFinalParsers :: [BlockParser m il bl bl]
, syntaxAttributeParsers
:: forall u m1 . Monad m1 => [ParsecT [Tok] u m1 Attributes]
}
instance Semigroup (SyntaxSpec m il bl) where
SyntaxSpec bl1 br1 fo1 il1 fp1 ap1 <> SyntaxSpec bl2 br2 fo2 il2 fp2 ap2
= SyntaxSpec (removeDuplicateBlockSpecs $ bl1 <> bl2)
(br1 <> br2) (fo1 <> fo2) (il1 <> il2)
(fp1 <> fp2) (ap1 <> ap2)
instance Monoid (SyntaxSpec m il bl) where
mempty = SyntaxSpec mempty mempty mempty mempty mempty mempty
mappend = (<>)
removeDuplicateBlockSpecs :: [BlockSpec m il bl] -> [BlockSpec m il bl]
removeDuplicateBlockSpecs [] = []
removeDuplicateBlockSpecs (b:bs) =
b : removeDuplicateBlockSpecs (filter ((/= blockType b) . blockType) bs)
defaultSyntaxSpec :: (Monad m, IsBlock il bl, IsInline il)
=> SyntaxSpec m il bl
defaultSyntaxSpec = SyntaxSpec
{ syntaxBlockSpecs = defaultBlockSpecs
, syntaxBracketedSpecs = defaultBracketedSpecs
, syntaxFormattingSpecs = defaultFormattingSpecs
, syntaxInlineParsers = [defaultInlineParser]
, syntaxFinalParsers = []
, syntaxAttributeParsers = []
}