git.iko.soy/typeable/pandoc
on master help sign in
Fixed serious performance problems with new Markdown reader:

Instead of using lookahead to determine whether a single quote is an apostrophe, we now use state. Inside single quotes, a ' character won't be recognized as the beginning of a single quote. 'stateQuoteContext' has been added to keep track of this. git-svn-id: https://pandoc.googlecode.com/svn/trunk@437 788f1e2b-df1e-0410-8736-df70ead52e1b

commit1645fb65e4a486de95f5375bcc029a139d4d8c45 authorfiddlosopher <fiddlosopher@788f1e2b-df1e-0410-8736-df70ead52e1b> dateSat 6 Jan 2007, 18:41 (20 years ago) parentbb8478e
2 files changed+44−13
src/Text/Pandoc/Readers/Markdown.hs+35−13 src/Text/Pandoc/Shared.hs+9
src/Text/Pandoc/Readers/Markdown.hs+35−13
@@ -594,24 +594,46 @@ apostrophe = do
594594quoted = do
595595 doubleQuoted <|> singleQuoted
596596
597−singleQuoted = try (do
598− result <- enclosed singleQuoteStart singleQuoteEnd
599− (do{notFollowedBy' singleQuoted; inline} <|> apostrophe)
600− return $ Quoted SingleQuote $ normalizeSpaces result)
601−
602−doubleQuoted = try (do
603− result <- enclosed doubleQuoteStart doubleQuoteEnd inline
604− return $ Quoted DoubleQuote $ normalizeSpaces result)
597+withQuoteContext context parser = do
598+ oldState <- getState
599+ let oldQuoteContext = stateQuoteContext oldState
600+ setState oldState { stateQuoteContext = context }
601+ result <- parser
602+ newState <- getState
603+ setState newState { stateQuoteContext = oldQuoteContext }
604+ return result
605+
606+singleQuoted = try $ do
607+ singleQuoteStart
608+ withQuoteContext InSingleQuote $ do
609+ notFollowedBy space
610+ result <- many1Till inline singleQuoteEnd
611+ return $ Quoted SingleQuote $ normalizeSpaces result
612+
613+doubleQuoted = try $ do
614+ doubleQuoteStart
615+ withQuoteContext InDoubleQuote $ do
616+ notFollowedBy space
617+ result <- many1Till inline doubleQuoteEnd
618+ return $ Quoted DoubleQuote $ normalizeSpaces result
619+
620+failIfInQuoteContext context = do
621+ st <- getState
622+ if (stateQuoteContext st == context)
623+ then fail "already inside quotes"
624+ else return ()
605625
606−singleQuoteStart = try (do
626+singleQuoteStart = do
627+ failIfInQuoteContext InSingleQuote
607628 char '\'' <|> char '\8216'
608− notFollowedBy' whitespace)
609629
610630singleQuoteEnd = try (do
611− oneOfStrings ["'", "\8217"]
631+ char '\'' <|> char '\8217'
612632 notFollowedBy alphaNum)
613633
614−doubleQuoteStart = char '"' <|> char '\8220'
634+doubleQuoteStart = do
635+ failIfInQuoteContext InDoubleQuote
636+ char '"' <|> char '\8220'
615637
616638doubleQuoteEnd = char '"' <|> char '\8221'
617639
@@ -623,7 +645,7 @@ dash = enDash <|> emDash
623645
624646enDash = try (do
625647 char '-'
626− followedBy' (many1 digit)
648+ notFollowedBy (noneOf "0123456789")
627649 return EnDash)
628650
629651emDash = try (do
src/Text/Pandoc/Shared.hs+9
@@ -47,6 +47,7 @@ module Text.Pandoc.Shared (
4747 testStringWith,
4848 HeaderType (..),
4949 ParserContext (..),
50+ QuoteContext (..),
5051 ParserState (..),
5152 defaultParserState,
5253 -- * Native format prettyprinting
@@ -108,10 +109,17 @@ data ParserContext
108109 | NullState -- ^ Default state
109110 deriving (Eq, Show)
110111
112+data QuoteContext
113+ = InSingleQuote -- ^ Used when we're parsing inside single quotes
114+ | InDoubleQuote -- ^ Used when we're parsing inside double quotes
115+ | NoQuote -- ^ Used when we're not parsing inside quotes
116+ deriving (Eq, Show)
117+
111118data ParserState = ParserState
112119 { stateParseRaw :: Bool, -- ^ Parse untranslatable HTML
113120 -- and LaTeX?
114121 stateParserContext :: ParserContext, -- ^ What are we parsing?
122+ stateQuoteContext :: QuoteContext, -- ^ Inside quoted environment?
115123 stateKeyBlocks :: [Block], -- ^ List of reference key blocks
116124 stateKeysUsed :: [[Inline]], -- ^ List of references used
117125 stateNoteBlocks :: [Block], -- ^ List of note blocks
@@ -134,6 +142,7 @@ defaultParserState :: ParserState
134142defaultParserState =
135143 ParserState { stateParseRaw = False,
136144 stateParserContext = NullState,
145+ stateQuoteContext = NoQuote,
137146 stateKeyBlocks = [],
138147 stateKeysUsed = [],
139148 stateNoteBlocks = [],