git.iko.soy/typeable/pandoc
on master help sign in
Parsing: introduce `HasIncludeFiles` type class
5ff6108Albert Krewinkel
src/Text/Pandoc/Parsing.hs+22−9
@@ -83,6 +83,7 @@ module Text.Pandoc.Parsing ( anyLine,
83 HasMacros (..),
83 HasMacros (..),
84 HasLogMessages (..),
84 HasLogMessages (..),
85 HasLastStrPosition (..),
85 HasLastStrPosition (..),
86+ HasIncludeFiles (..),
86 defaultParserState,
87 defaultParserState,
87 HeaderType (..),
88 HeaderType (..),
88 ParserContext (..),
89 ParserContext (..),
@@ -1008,6 +1009,9 @@ class HasReaderOptions st where
1008 -- default
1009 -- default
1009 getOption f = (f . extractReaderOptions) <$> getState
1010 getOption f = (f . extractReaderOptions) <$> getState
1010
1011
1012+instance HasReaderOptions ParserState where
1013+ extractReaderOptions = stateOptions
1014+
1011class HasQuoteContext st m where
1015class HasQuoteContext st m where
1012 getQuoteContext :: (Stream s m t) => ParsecT s st m QuoteContext
1016 getQuoteContext :: (Stream s m t) => ParsecT s st m QuoteContext
1013 withQuoteContext :: QuoteContext -> ParsecT s st m a -> ParsecT s st m a
1017 withQuoteContext :: QuoteContext -> ParsecT s st m a -> ParsecT s st m a
@@ -1023,9 +1027,6 @@ instance Monad m => HasQuoteContext ParserState m where
1023 setState newState { stateQuoteContext = oldQuoteContext }
1027 setState newState { stateQuoteContext = oldQuoteContext }
1024 return result
1028 return result
1025
1029
1026−instance HasReaderOptions ParserState where
1027− extractReaderOptions = stateOptions
1028−
1029class HasHeaderMap st where
1030class HasHeaderMap st where
1030 extractHeaderMap :: st -> M.Map Inlines String
1031 extractHeaderMap :: st -> M.Map Inlines String
1031 updateHeaderMap :: (M.Map Inlines String -> M.Map Inlines String) ->
1032 updateHeaderMap :: (M.Map Inlines String -> M.Map Inlines String) ->
@@ -1067,6 +1068,16 @@ instance HasLogMessages ParserState where
1067 addLogMessage msg st = st{ stateLogMessages = msg : stateLogMessages st }
1068 addLogMessage msg st = st{ stateLogMessages = msg : stateLogMessages st }
1068 getLogMessages st = reverse $ stateLogMessages st
1069 getLogMessages st = reverse $ stateLogMessages st
1069
1070
1071+class HasIncludeFiles st where
1072+ getIncludeFiles :: st -> [String]
1073+ addIncludeFile :: String -> st -> st
1074+ dropLatestIncludeFile :: st -> st
1075+
1076+instance HasIncludeFiles ParserState where
1077+ getIncludeFiles = stateContainers
1078+ addIncludeFile f s = s{ stateContainers = f : stateContainers s }
1079+ dropLatestIncludeFile s = s { stateContainers = drop 1 $ stateContainers s }
1080+
1070defaultParserState :: ParserState
1081defaultParserState :: ParserState
1071defaultParserState =
1082defaultParserState =
1072 ParserState { stateOptions = def,
1083 ParserState { stateOptions = def,
@@ -1358,17 +1369,19 @@ extractIdClass (ident, cls, kvs) = (ident', cls', kvs')
1358 Nothing -> cls
1369 Nothing -> cls
1359 kvs' = filter (\(k,_) -> k /= "id" || k /= "class") kvs
1370 kvs' = filter (\(k,_) -> k /= "id" || k /= "class") kvs
1360
1371
1372+-- | Parse content of include file as blocks. Circular includes result in an
1373+-- @PandocParseError@.
1361−insertIncludedFile :: PandocMonad m
1374+insertIncludedFile :: (PandocMonad m, HasIncludeFiles st)
1362− => ParserT String ParserState m Blocks
1375+ => ParserT String st m Blocks
1363 -> [FilePath] -> FilePath
1376 -> [FilePath] -> FilePath
1364− -> ParserT String ParserState m Blocks
1377+ -> ParserT String st m Blocks
1365insertIncludedFile blocks dirs f = do
1378insertIncludedFile blocks dirs f = do
1366 oldPos <- getPosition
1379 oldPos <- getPosition
1367 oldInput <- getInput
1380 oldInput <- getInput
1368− containers <- stateContainers <$> getState
1381+ containers <- getIncludeFiles <$> getState
1369 when (f `elem` containers) $
1382 when (f `elem` containers) $
1370 throwError $ PandocParseError $ "Include file loop at " ++ show oldPos
1383 throwError $ PandocParseError $ "Include file loop at " ++ show oldPos
1371− updateState $ \s -> s{ stateContainers = f : stateContainers s }
1384+ updateState $ addIncludeFile f
1372 mbcontents <- readFileFromDirs dirs f
1385 mbcontents <- readFileFromDirs dirs f
1373 contents <- case mbcontents of
1386 contents <- case mbcontents of
1374 Just s -> return s
1387 Just s -> return s
@@ -1380,5 +1393,5 @@ insertIncludedFile blocks dirs f = do
1380 bs <- blocks
1393 bs <- blocks
1381 setInput oldInput
1394 setInput oldInput
1382 setPosition oldPos
1395 setPosition oldPos
1383− updateState $ \s -> s{ stateContainers = drop 1 $ stateContainers s }
1396+ updateState dropLatestIncludeFile
1384 return bs
1397 return bs