{- |
   Module      : Text.Pandoc.Readers.Org
   Copyright   : Copyright (C) 2014-2024 Albert Krewinkel
   License     : GNU GPL, version 2 or above

   Maintainer  : Albert Krewinkel <albert+pandoc@tarleb.com>

Conversion of org-mode formatted plain text to 'Pandoc' document.
-}
module Text.Pandoc.Readers.Org ( readOrg ) where

import Text.Pandoc.Readers.Org.Blocks (blockList, meta)
import Text.Pandoc.Readers.Org.ParserState (optionsToParserState)
import Text.Pandoc.Readers.Org.Parsing (OrgParser, readWithM)

import Text.Pandoc.Class.PandocMonad (PandocMonad)
import Text.Pandoc.Definition
import Text.Pandoc.Options
import Text.Pandoc.Parsing (reportLogMessages)
import Text.Pandoc.Sources (ToSources(..), ensureFinalNewlines)
import Control.Monad.Except (throwError)
import Control.Monad.Reader (runReaderT)

-- | Parse org-mode string and return a Pandoc document.
readOrg :: (PandocMonad m, ToSources a)
        => ReaderOptions -- ^ Reader options
        -> a
        -> m Pandoc
readOrg :: forall (m :: * -> *) a.
(PandocMonad m, ToSources a) =>
ReaderOptions -> a -> m Pandoc
readOrg ReaderOptions
opts a
s = do
  parsed <- (ReaderT OrgParserLocal m (Either PandocError Pandoc)
 -> OrgParserLocal -> m (Either PandocError Pandoc))
-> OrgParserLocal
-> ReaderT OrgParserLocal m (Either PandocError Pandoc)
-> m (Either PandocError Pandoc)
forall a b c. (a -> b -> c) -> b -> a -> c
flip ReaderT OrgParserLocal m (Either PandocError Pandoc)
-> OrgParserLocal -> m (Either PandocError Pandoc)
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT OrgParserLocal
forall a. Default a => a
def (ReaderT OrgParserLocal m (Either PandocError Pandoc)
 -> m (Either PandocError Pandoc))
-> ReaderT OrgParserLocal m (Either PandocError Pandoc)
-> m (Either PandocError Pandoc)
forall a b. (a -> b) -> a -> b
$
            ParsecT Sources OrgParserState (ReaderT OrgParserLocal m) Pandoc
-> OrgParserState
-> Sources
-> ReaderT OrgParserLocal m (Either PandocError Pandoc)
forall (m :: * -> *) t st a.
(Monad m, ToSources t) =>
ParsecT Sources st m a -> st -> t -> m (Either PandocError a)
readWithM ParsecT Sources OrgParserState (ReaderT OrgParserLocal m) Pandoc
forall (m :: * -> *). PandocMonad m => OrgParser m Pandoc
parseOrg (ReaderOptions -> OrgParserState
optionsToParserState ReaderOptions
opts)
            (Int -> Sources -> Sources
ensureFinalNewlines Int
2 (a -> Sources
forall a. ToSources a => a -> Sources
toSources a
s))
  case parsed of
    Right Pandoc
result -> Pandoc -> m Pandoc
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Pandoc
result
    Left  PandocError
e      -> PandocError -> m Pandoc
forall a. PandocError -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError PandocError
e

--
-- Parser
--
parseOrg :: PandocMonad m => OrgParser m Pandoc
parseOrg :: forall (m :: * -> *). PandocMonad m => OrgParser m Pandoc
parseOrg = do
  blocks' <- OrgParser m [Block]
forall (m :: * -> *). PandocMonad m => OrgParser m [Block]
blockList
  meta'   <- meta
  reportLogMessages
  return $ Pandoc meta' blocks'