module Org.Parser
  ( OrgParser
  , OrgParseError
  , OrgOptions (..)
  , TodoSequence
  , defaultOrgOptions
  , parseOrgMaybe
  , parseOrg
  , parseOrgDoc
  , parseOrgDocIO
  )
where

import Org.Parser.Definitions
import Org.Parser.Document

{- | Evaluate the Org Parser state with the desired options. Returns 'Nothing' in
   case of parse failure.
-}
parseOrgMaybe :: OrgOptions -> OrgParser a -> Text -> Maybe a
parseOrgMaybe :: forall a. OrgOptions -> OrgParser a -> Text -> Maybe a
parseOrgMaybe OrgOptions
opt OrgParser a
p = forall l r. Either l r -> Maybe r
rightToMaybe forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a.
OrgOptions
-> OrgParser a -> FilePath -> Text -> Either OrgParseError a
parseOrg OrgOptions
opt OrgParser a
p FilePath
""

{- | Wrapper around 'parse' that evaluates the Org Parser state with the desired
   options.
-}
parseOrg :: OrgOptions -> OrgParser a -> FilePath -> Text -> Either OrgParseError a
parseOrg :: forall a.
OrgOptions
-> OrgParser a -> FilePath -> Text -> Either OrgParseError a
parseOrg OrgOptions
opt (OrgParser ReaderT
  OrgParserEnv (StateT OrgParserState (ParsecT Void Text Identity)) a
x) =
  forall e s a.
Parsec e s a -> FilePath -> s -> Either (ParseErrorBundle s e) a
parse forall a b. (a -> b) -> a -> b
$
    ReaderT
  OrgParserEnv (StateT OrgParserState (ParsecT Void Text Identity)) a
x
      forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
`runReaderT` OrgParserEnv
defaultEnv {orgEnvOptions :: OrgOptions
orgEnvOptions = OrgOptions
opt}
      forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
`evalStateT` OrgParserState
defaultState

-- | Parse an Org document fully, with given options, and a filepath for error messages.
parseOrgDoc :: OrgOptions -> FilePath -> Text -> Either OrgParseError OrgDocument
parseOrgDoc :: OrgOptions -> FilePath -> Text -> Either OrgParseError OrgDocument
parseOrgDoc OrgOptions
opt = forall a.
OrgOptions
-> OrgParser a -> FilePath -> Text -> Either OrgParseError a
parseOrg OrgOptions
opt OrgParser OrgDocument
orgDocument

-- | Parse an Org document in a UTF8 file, with given options.
parseOrgDocIO :: MonadIO m => OrgOptions -> FilePath -> m OrgDocument
parseOrgDocIO :: forall (m :: * -> *).
MonadIO m =>
OrgOptions -> FilePath -> m OrgDocument
parseOrgDocIO OrgOptions
opt FilePath
fp = do
  ByteString
text <- forall (m :: * -> *). MonadIO m => FilePath -> m ByteString
readFileBS FilePath
fp
  case OrgOptions -> FilePath -> Text -> Either OrgParseError OrgDocument
parseOrgDoc OrgOptions
opt FilePath
fp forall a b. (a -> b) -> a -> b
$ forall a b. ConvertUtf8 a b => b -> a
decodeUtf8 ByteString
text of
    Left OrgParseError
e -> forall a t. (HasCallStack, IsText t) => t -> a
error forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. ToText a => a -> Text
toText forall a b. (a -> b) -> a -> b
$ forall s e.
(VisualStream s, TraversableStream s, ShowErrorComponent e) =>
ParseErrorBundle s e -> FilePath
errorBundlePretty OrgParseError
e
    Right OrgDocument
d -> forall (f :: * -> *) a. Applicative f => a -> f a
pure OrgDocument
d