module Commonmark.Parser
    ( commonmark
    , commonmarkWith
    , parseCommonmarkWith
    -- * Exported from "Text.Parsec.Error"
    , ParseError
    ) where

import           Commonmark.Blocks
import           Commonmark.Inlines
import           Commonmark.Tokens
import           Commonmark.Types
import           Commonmark.Syntax (SyntaxSpec(..), defaultSyntaxSpec)
import           Text.Parsec.Error (ParseError)
import           Data.Functor.Identity   (runIdentity)
import           Data.Text (Text)

-- | Parse a commonmark document using the core syntax
-- elements.
-- To produce HTML, instantiate 'bl' with @'Html' ()@ (see
-- 'Commonmark.Html'.
-- If you want to add syntax extensions or run the parser in a
-- monadic context, use 'commonmarkWith'.
-- If you want to operate on tokenized input, use 'parseCommonmarkWith'.
commonmark :: IsBlock il bl
           => String      -- ^ Name or path of input
           -> Text        -- ^ Commonmark text input
           -> Either ParseError bl -- ^ Result or error
commonmark :: forall il bl.
IsBlock il bl =>
String -> Text -> Either ParseError bl
commonmark String
sourcename =
 Identity (Either ParseError bl) -> Either ParseError bl
forall a. Identity a -> a
runIdentity (Identity (Either ParseError bl) -> Either ParseError bl)
-> (Text -> Identity (Either ParseError bl))
-> Text
-> Either ParseError bl
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
 SyntaxSpec Identity il bl
-> [Tok] -> Identity (Either ParseError bl)
forall (m :: * -> *) il bl.
(Monad m, IsBlock il bl, IsInline il) =>
SyntaxSpec m il bl -> [Tok] -> m (Either ParseError bl)
parseCommonmarkWith SyntaxSpec Identity il bl
forall (m :: * -> *) il bl.
(Monad m, IsBlock il bl, IsInline il) =>
SyntaxSpec m il bl
defaultSyntaxSpec ([Tok] -> Identity (Either ParseError bl))
-> (Text -> [Tok]) -> Text -> Identity (Either ParseError bl)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
 String -> Text -> [Tok]
tokenize String
sourcename

-- | Like 'commonmark', but allows specifying a custom syntax
-- and a monadic context (since some syntax extensions may
-- only be defined in certain monads, e.g. an extension for
-- include files may require IO).
commonmarkWith :: (Monad m, IsBlock il bl, IsInline il)
               => SyntaxSpec m il bl       -- ^ Defines syntax
               -> String                   -- ^ Name or path of input
               -> Text                     -- ^ Commonmark text input
               -> m (Either ParseError bl) -- ^ Result or error
commonmarkWith :: forall (m :: * -> *) il bl.
(Monad m, IsBlock il bl, IsInline il) =>
SyntaxSpec m il bl -> String -> Text -> m (Either ParseError bl)
commonmarkWith SyntaxSpec m il bl
syntax String
sourcename =
 SyntaxSpec m il bl -> [Tok] -> m (Either ParseError bl)
forall (m :: * -> *) il bl.
(Monad m, IsBlock il bl, IsInline il) =>
SyntaxSpec m il bl -> [Tok] -> m (Either ParseError bl)
parseCommonmarkWith SyntaxSpec m il bl
syntax ([Tok] -> m (Either ParseError bl))
-> (Text -> [Tok]) -> Text -> m (Either ParseError bl)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
 String -> Text -> [Tok]
tokenize String
sourcename

-- | Parse a tokenized commonmark document using specified
-- syntax elements.  Use 'tokenize' to convert 'Text' into ['Tok'].
parseCommonmarkWith :: (Monad m, IsBlock il bl, IsInline il)
                    => SyntaxSpec m il bl -- ^ Defines syntax
                    -> [Tok] -- ^ Tokenized commonmark input
                    -> m (Either ParseError bl)  -- ^ Result or error
parseCommonmarkWith :: forall (m :: * -> *) il bl.
(Monad m, IsBlock il bl, IsInline il) =>
SyntaxSpec m il bl -> [Tok] -> m (Either ParseError bl)
parseCommonmarkWith SyntaxSpec m il bl
syntax =
    [BlockSpec m il bl]
-> [BlockParser m il bl bl]
-> (ReferenceMap -> [Tok] -> m (Either ParseError il))
-> [BlockParser m il bl Attributes]
-> [Tok]
-> m (Either ParseError bl)
forall (m :: * -> *) il bl.
(Monad m, IsBlock il bl) =>
[BlockSpec m il bl]
-> [BlockParser m il bl bl]
-> (ReferenceMap -> [Tok] -> m (Either ParseError il))
-> [BlockParser m il bl Attributes]
-> [Tok]
-> m (Either ParseError bl)
mkBlockParser (SyntaxSpec m il bl -> [BlockSpec m il bl]
forall (m :: * -> *) il bl.
SyntaxSpec m il bl -> [BlockSpec m il bl]
syntaxBlockSpecs SyntaxSpec m il bl
syntax)
      (SyntaxSpec m il bl -> [BlockParser m il bl bl]
forall (m :: * -> *) il bl.
SyntaxSpec m il bl -> [BlockParser m il bl bl]
syntaxFinalParsers SyntaxSpec m il bl
syntax)
      ([BracketedSpec il]
-> [FormattingSpec il]
-> [InlineParser m il]
-> [InlineParser m Attributes]
-> ReferenceMap
-> [Tok]
-> m (Either ParseError il)
forall (m :: * -> *) a.
(Monad m, IsInline a) =>
[BracketedSpec a]
-> [FormattingSpec a]
-> [InlineParser m a]
-> [InlineParser m Attributes]
-> ReferenceMap
-> [Tok]
-> m (Either ParseError a)
mkInlineParser (SyntaxSpec m il bl -> [BracketedSpec il]
forall (m :: * -> *) il bl.
SyntaxSpec m il bl -> [BracketedSpec il]
syntaxBracketedSpecs SyntaxSpec m il bl
syntax)
                      (SyntaxSpec m il bl -> [FormattingSpec il]
forall (m :: * -> *) il bl.
SyntaxSpec m il bl -> [FormattingSpec il]
syntaxFormattingSpecs SyntaxSpec m il bl
syntax)
                      (SyntaxSpec m il bl -> [InlineParser m il]
forall (m :: * -> *) il bl.
SyntaxSpec m il bl -> [InlineParser m il]
syntaxInlineParsers SyntaxSpec m il bl
syntax)
                      (SyntaxSpec m il bl
-> forall u (m1 :: * -> *).
   Monad m1 =>
   [ParsecT [Tok] u m1 Attributes]
forall (m :: * -> *) il bl.
SyntaxSpec m il bl
-> forall u (m1 :: * -> *).
   Monad m1 =>
   [ParsecT [Tok] u m1 Attributes]
syntaxAttributeParsers SyntaxSpec m il bl
syntax))
      (SyntaxSpec m il bl
-> forall u (m1 :: * -> *).
   Monad m1 =>
   [ParsecT [Tok] u m1 Attributes]
forall (m :: * -> *) il bl.
SyntaxSpec m il bl
-> forall u (m1 :: * -> *).
   Monad m1 =>
   [ParsecT [Tok] u m1 Attributes]
syntaxAttributeParsers SyntaxSpec m il bl
syntax)