summaryrefslogtreecommitdiff
path: root/src/Text/Pandoc/Readers/Org.hs
diff options
context:
space:
mode:
authorAlbert Krewinkel <tarleb@moltkeplatz.de>2014-04-04 17:20:36 +0200
committerAlbert Krewinkel <tarleb@moltkeplatz.de>2014-04-05 16:14:09 +0200
commitd43c3e81017734170fb25460c4b9ab9cccb1e0db (patch)
tree9e8f32ccdc8ae9525832fac0fa0894ea490c1ad5 /src/Text/Pandoc/Readers/Org.hs
parent7cf7e45e4cbb99b320a92b4bd31e433f535d3ef7 (diff)
Org reader: Use specialized org parser state
The default pandoc ParserState is replaced with `OrgParserState`. This is done to simplify the introduction of new state fields required for efficient Org parsing.
Diffstat (limited to 'src/Text/Pandoc/Readers/Org.hs')
-rw-r--r--src/Text/Pandoc/Readers/Org.hs48
1 files changed, 41 insertions, 7 deletions
diff --git a/src/Text/Pandoc/Readers/Org.hs b/src/Text/Pandoc/Readers/Org.hs
index 8b155194b..0ae4d231c 100644
--- a/src/Text/Pandoc/Readers/Org.hs
+++ b/src/Text/Pandoc/Readers/Org.hs
@@ -29,15 +29,16 @@ Conversion of Org-Mode to 'Pandoc' document.
module Text.Pandoc.Readers.Org ( readOrg ) where
import qualified Text.Pandoc.Builder as B
-import Text.Pandoc.Builder (Inlines, Blocks, trimInlines, (<>))
+import Text.Pandoc.Builder (Inlines, Blocks, trimInlines, (<>), HasMeta(..))
import Text.Pandoc.Definition
import Text.Pandoc.Options
-import Text.Pandoc.Parsing hiding (orderedListMarker)
+import Text.Pandoc.Parsing hiding (orderedListMarker, updateLastStrPos)
import Text.Pandoc.Shared (compactify')
import Control.Applicative (pure, (<$>), (<$), (<*>), (<*), (*>), (<**>))
import Control.Monad (guard, mzero)
import Data.Char (toLower)
+import Data.Default
import Data.List (foldl')
import Data.Maybe (listToMaybe, fromMaybe)
import Data.Monoid (mconcat, mempty, mappend)
@@ -46,15 +47,48 @@ import Data.Monoid (mconcat, mempty, mappend)
readOrg :: ReaderOptions -- ^ Reader options
-> String -- ^ String to parse (assuming @'\n'@ line endings)
-> Pandoc
-readOrg opts s = (readWith parseOrg) def{ stateOptions = opts } (s ++ "\n\n")
+readOrg opts s = (readWith parseOrg) def{ orgOptions = opts } (s ++ "\n\n")
+
+type OrgParser = Parser [Char] OrgParserState
+
+-- | Org-mode parser state
+data OrgParserState = OrgParserState
+ { orgOptions :: ReaderOptions
+ , orgInlineCharStack :: [Char]
+ , orgLastStrPos :: Maybe SourcePos
+ , orgMeta :: Meta
+ } deriving (Show)
+
+instance HasReaderOptions OrgParserState where
+ extractReaderOptions = orgOptions
+
+instance HasMeta OrgParserState where
+ setMeta field val st =
+ st{ orgMeta = setMeta field val $ orgMeta st }
+ deleteMeta field st =
+ st{ orgMeta = deleteMeta field $ orgMeta st }
+
+instance Default OrgParserState where
+ def = defaultOrgParserState
+
+defaultOrgParserState :: OrgParserState
+defaultOrgParserState = OrgParserState
+ { orgOptions = def
+ , orgInlineCharStack = []
+ , orgLastStrPos = Nothing
+ , orgMeta = nullMeta
+ }
+
+updateLastStrPos :: OrgParser ()
+updateLastStrPos = getPosition >>= \p ->
+ updateState $ \s -> s{ orgLastStrPos = Just p }
-type OrgParser = Parser [Char] ParserState
parseOrg:: OrgParser Pandoc
parseOrg = do
blocks' <- B.toList <$> parseBlocks
st <- getState
- let meta = stateMeta st
+ let meta = orgMeta st
return $ Pandoc meta $ filter (/= Null) blocks'
--
@@ -177,7 +211,7 @@ commentLineStart = try $ mappend <$> many spaceChar <*> string "# "
declarationLine :: OrgParser Blocks
declarationLine = try $ do
meta' <- B.setMeta <$> metaKey <*> metaValue <*> pure nullMeta
- updateState $ \st -> st { stateMeta = stateMeta st <> meta' }
+ updateState $ \st -> st { orgMeta = orgMeta st <> meta' }
return mempty
metaValue :: OrgParser MetaValue
@@ -522,7 +556,7 @@ atStart :: OrgParser a -> OrgParser a
atStart p = do
pos <- getPosition
st <- getState
- guard $ stateLastStrPos st /= Just pos
+ guard $ orgLastStrPos st /= Just pos
p
-- | succeeds only if we're at the end of a word