git.iko.soy/typeable/pandoc
on master help sign in
MediaWiki reader: Use MWState instead of ParserState.
8cc5625John MacFarlane
src/Text/Pandoc/Readers/HTML.hs+1−1
@@ -597,7 +597,7 @@ htmlInBalanced f = try $ do
597 return $ tag ++ concat contents ++ endtag
597 return $ tag ++ concat contents ++ endtag
598
598
599-- | Matches a tag meeting a certain condition.
599-- | Matches a tag meeting a certain condition.
600−htmlTag :: (Tag String -> Bool) -> Parser [Char] ParserState (Tag String, String)
600+htmlTag :: (Tag String -> Bool) -> Parser [Char] st (Tag String, String)
601htmlTag f = try $ do
601htmlTag f = try $ do
602 lookAhead (char '<')
602 lookAhead (char '<')
603 (next : _) <- getInput >>= return . canonicalizeTags . parseTags
603 (next : _) <- getInput >>= return . canonicalizeTags . parseTags
src/Text/Pandoc/Readers/MediaWiki.hs+24−5
@@ -34,6 +34,7 @@ _ support internal links http://www.mediawiki.org/wiki/Help:Links
34_ support external links (partially implemented)
34_ support external links (partially implemented)
35_ support images http://www.mediawiki.org/wiki/Help:Images
35_ support images http://www.mediawiki.org/wiki/Help:Images
36_ support tables http://www.mediawiki.org/wiki/Help:Tables
36_ support tables http://www.mediawiki.org/wiki/Help:Tables
37+- footnotes?
37-}
38-}
38module Text.Pandoc.Readers.MediaWiki ( readMediaWiki ) where
39module Text.Pandoc.Readers.MediaWiki ( readMediaWiki ) where
39
40
@@ -44,7 +45,7 @@ import Text.Pandoc.Options
44import Text.Pandoc.Readers.HTML ( htmlTag, isInlineTag,
45import Text.Pandoc.Readers.HTML ( htmlTag, isInlineTag,
45 isBlockTag, isCommentTag )
46 isBlockTag, isCommentTag )
46import Text.Pandoc.XML ( fromEntities )
47import Text.Pandoc.XML ( fromEntities )
47−import Text.Pandoc.Parsing
48+import Text.Pandoc.Parsing hiding ( nested )
48import Text.Pandoc.Generic ( bottomUp )
49import Text.Pandoc.Generic ( bottomUp )
49import Text.Pandoc.Shared ( stripTrailingNewlines, safeRead )
50import Text.Pandoc.Shared ( stripTrailingNewlines, safeRead )
50import Data.Monoid (mconcat, mempty)
51import Data.Monoid (mconcat, mempty)
@@ -56,17 +57,35 @@ import Data.Sequence (viewl, ViewL(..), (<|))
56
57
57-- | Read mediawiki from an input string and return a Pandoc document.
58-- | Read mediawiki from an input string and return a Pandoc document.
58readMediaWiki :: ReaderOptions -- ^ Reader options
59readMediaWiki :: ReaderOptions -- ^ Reader options
59− -> String -- ^ String to parse (assuming @'\n'@ line endings)
60+ -> String -- ^ String to parse (assuming @'\n'@ line endings)
60− -> Pandoc
61+ -> Pandoc
61readMediaWiki opts s =
62readMediaWiki opts s =
62− (readWith parseMediaWiki) def{ stateOptions = opts } (s ++ "\n\n")
63+ case runParser parseMediaWiki MWState{ mwOptions = opts, mwMaxNestingLevel = 4 }
64+ "source" (s ++ "\n") of
65+ Left err' -> error $ "\nError:\n" ++ show err'
66+ Right result -> result
63
67
68+data MWState = MWState { mwOptions :: ReaderOptions
69+ , mwMaxNestingLevel :: Int
70+ }
71+
64−type MWParser = Parser [Char] ParserState
72+type MWParser = Parser [Char] MWState
65
73
66--
74--
67-- auxiliary functions
75-- auxiliary functions
68--
76--
69
77
78+-- This is used to prevent exponential blowups for things like:
79+-- ''a'''a''a'''a''a'''a''a'''a
80+nested :: MWParser a -> MWParser a
81+nested p = do
82+ nestlevel <- mwMaxNestingLevel `fmap` getState
83+ guard $ nestlevel > 0
84+ updateState $ \st -> st{ mwMaxNestingLevel = mwMaxNestingLevel st - 1 }
85+ res <- p
86+ updateState $ \st -> st{ mwMaxNestingLevel = nestlevel }
87+ return res
88+
70specialChars :: [Char]
89specialChars :: [Char]
71specialChars = "'[]<=&*{}"
90specialChars = "'[]<=&*{}"
72
91