git.iko.soy/typeable/pandoc
on master help sign in
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.

commitd43c3e81017734170fb25460c4b9ab9cccb1e0db authorAlbert Krewinkel <tarleb@moltkeplatz.de> dateFri 4 Apr 2014, 17:20 (13 years ago) parent7cf7e45
1 file changed+41−7
src/Text/Pandoc/Readers/Org.hs+41−7
src/Text/Pandoc/Readers/Org.hs+41−7
@@ -29,15 +29,16 @@ Conversion of Org-Mode to 'Pandoc' document.
2929module Text.Pandoc.Readers.Org ( readOrg ) where
3030
3131import qualified Text.Pandoc.Builder as B
32−import Text.Pandoc.Builder (Inlines, Blocks, trimInlines, (<>))
32+import Text.Pandoc.Builder (Inlines, Blocks, trimInlines, (<>), HasMeta(..))
3333import Text.Pandoc.Definition
3434import Text.Pandoc.Options
35−import Text.Pandoc.Parsing hiding (orderedListMarker)
35+import Text.Pandoc.Parsing hiding (orderedListMarker, updateLastStrPos)
3636import Text.Pandoc.Shared (compactify')
3737
3838import Control.Applicative (pure, (<$>), (<$), (<*>), (<*), (*>), (<**>))
3939import Control.Monad (guard, mzero)
4040import Data.Char (toLower)
41+import Data.Default
4142import Data.List (foldl')
4243import Data.Maybe (listToMaybe, fromMaybe)
4344import Data.Monoid (mconcat, mempty, mappend)
@@ -46,15 +47,48 @@ import Data.Monoid (mconcat, mempty, mappend)
4647readOrg :: ReaderOptions -- ^ Reader options
4748 -> String -- ^ String to parse (assuming @'\n'@ line endings)
4849 -> Pandoc
49−readOrg opts s = (readWith parseOrg) def{ stateOptions = opts } (s ++ "\n\n")
50+readOrg opts s = (readWith parseOrg) def{ orgOptions = opts } (s ++ "\n\n")
51+
52+type OrgParser = Parser [Char] OrgParserState
53+
54+-- | Org-mode parser state
55+data OrgParserState = OrgParserState
56+ { orgOptions :: ReaderOptions
57+ , orgInlineCharStack :: [Char]
58+ , orgLastStrPos :: Maybe SourcePos
59+ , orgMeta :: Meta
60+ } deriving (Show)
61+
62+instance HasReaderOptions OrgParserState where
63+ extractReaderOptions = orgOptions
64+
65+instance HasMeta OrgParserState where
66+ setMeta field val st =
67+ st{ orgMeta = setMeta field val $ orgMeta st }
68+ deleteMeta field st =
69+ st{ orgMeta = deleteMeta field $ orgMeta st }
70+
71+instance Default OrgParserState where
72+ def = defaultOrgParserState
73+
74+defaultOrgParserState :: OrgParserState
75+defaultOrgParserState = OrgParserState
76+ { orgOptions = def
77+ , orgInlineCharStack = []
78+ , orgLastStrPos = Nothing
79+ , orgMeta = nullMeta
80+ }
81+
82+updateLastStrPos :: OrgParser ()
83+updateLastStrPos = getPosition >>= \p ->
84+ updateState $ \s -> s{ orgLastStrPos = Just p }
5085
51−type OrgParser = Parser [Char] ParserState
5286
5387parseOrg:: OrgParser Pandoc
5488parseOrg = do
5589 blocks' <- B.toList <$> parseBlocks
5690 st <- getState
57− let meta = stateMeta st
91+ let meta = orgMeta st
5892 return $ Pandoc meta $ filter (/= Null) blocks'
5993
6094--
@@ -177,7 +211,7 @@ commentLineStart = try $ mappend <$> many spaceChar <*> string "# "
177211declarationLine :: OrgParser Blocks
178212declarationLine = try $ do
179213 meta' <- B.setMeta <$> metaKey <*> metaValue <*> pure nullMeta
180− updateState $ \st -> st { stateMeta = stateMeta st <> meta' }
214+ updateState $ \st -> st { orgMeta = orgMeta st <> meta' }
181215 return mempty
182216
183217metaValue :: OrgParser MetaValue
@@ -522,7 +556,7 @@ atStart :: OrgParser a -> OrgParser a
522556atStart p = do
523557 pos <- getPosition
524558 st <- getState
525− guard $ stateLastStrPos st /= Just pos
559+ guard $ orgLastStrPos st /= Just pos
526560 p
527561
528562-- | succeeds only if we're at the end of a word