org-parser-0.1.0.0: src/Org/Parser/Definitions.hs
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Org.Parser.Definitions
( module Org.Parser.Definitions
, module Org.Types
, module Org.Builder
, module Org.Parser.State
, module Text.Megaparsec
, module Text.Megaparsec.Char
, module Text.Megaparsec.Debug
, module Data.Char
)
where
import Data.Char (isAlphaNum, isAscii, isDigit, isLetter, isPunctuation, isSpace)
import Org.Builder (OrgElements, OrgObjects)
import Org.Parser.State
import Org.Types
import Text.Megaparsec
import Text.Megaparsec.Char
import Text.Megaparsec.Debug
import Prelude hiding (State)
type Parser = Parsec Void Text
type MonadParser m = MonadParsec Void Text m
newtype OrgParser a = OrgParser (ReaderT OrgParserEnv (StateT OrgParserState Parser) a)
deriving newtype
( Functor
, Applicative
, Monad
, Alternative
, MonadState OrgParserState
, MonadReader OrgParserEnv
, MonadPlus
, MonadFail
, MonadParsec Void Text
)
type OrgParseError = ParseErrorBundle Text Void
-- * Last char
setLastChar :: Maybe Char -> OrgParser ()
setLastChar lchar =
modify (\c -> c {orgStateLastChar = lchar <|> orgStateLastChar c})
clearLastChar :: OrgParser ()
clearLastChar = modify (\c -> c {orgStateLastChar = Nothing})
putLastChar :: Char -> OrgParser ()
putLastChar lchar = modify (\c -> c {orgStateLastChar = Just lchar})
withIndentLevel :: Int -> OrgParser a -> OrgParser a
withIndentLevel i = local \s -> s {orgEnvIndentLevel = i}
-- * State and Environment convenience functions
type FullState = (State Text Void, OrgParserState)
getFullState :: OrgParser FullState
getFullState = liftA2 (,) getParserState get
setFullState :: FullState -> OrgParser ()
setFullState (pS, oS) = setParserState pS >> put oS
getsO :: (OrgOptions -> a) -> OrgParser a
getsO f = asks (f . orgEnvOptions)
-- * Marked parsers
data Marked m a = Marked
{ getMarks :: String
, getParser :: m a
}
instance Functor m => Functor (Marked m) where
fmap f x@(Marked _ p) = x {getParser = fmap f p}
instance Alternative m => Semigroup (Marked m a) where
Marked s1 p1 <> Marked s2 p2 =
Marked (s1 ++ s2) (p1 <|> p2)
instance Alternative m => Monoid (Marked m a) where
mempty = Marked [] empty
mconcat ms =
Marked
(foldMap getMarks ms)
(choice $ map getParser ms)
{-# INLINE mconcat #-}