git.iko.soy/typeable/pandoc
on master help sign in
Better smart quote parsing.
925a4c5John MacFarlane
src/Text/Pandoc/Parsing.hs+7−1
@@ -603,6 +603,7 @@ data ParserState = ParserState
603 { stateParseRaw :: Bool, -- ^ Parse raw HTML and LaTeX?
603 { stateParseRaw :: Bool, -- ^ Parse raw HTML and LaTeX?
604 stateParserContext :: ParserContext, -- ^ Inside list?
604 stateParserContext :: ParserContext, -- ^ Inside list?
605 stateQuoteContext :: QuoteContext, -- ^ Inside quoted environment?
605 stateQuoteContext :: QuoteContext, -- ^ Inside quoted environment?
606+ stateLastStrPos :: Maybe SourcePos, -- ^ Position after last str parsed
606 stateKeys :: KeyTable, -- ^ List of reference keys
607 stateKeys :: KeyTable, -- ^ List of reference keys
607 stateCitations :: [String], -- ^ List of available citations
608 stateCitations :: [String], -- ^ List of available citations
608 stateNotes :: NoteTable, -- ^ List of notes
609 stateNotes :: NoteTable, -- ^ List of notes
@@ -630,6 +631,7 @@ defaultParserState =
630 ParserState { stateParseRaw = False,
631 ParserState { stateParseRaw = False,
631 stateParserContext = NullState,
632 stateParserContext = NullState,
632 stateQuoteContext = NoQuote,
633 stateQuoteContext = NoQuote,
634+ stateLastStrPos = Nothing,
633 stateKeys = M.empty,
635 stateKeys = M.empty,
634 stateCitations = [],
636 stateCitations = [],
635 stateNotes = [],
637 stateNotes = [],
@@ -751,8 +753,12 @@ charOrRef cs =
751 return c)
753 return c)
752
754
753singleQuoteStart :: GenParser Char ParserState ()
755singleQuoteStart :: GenParser Char ParserState ()
754−singleQuoteStart = do
756+singleQuoteStart = do
755 failIfInQuoteContext InSingleQuote
757 failIfInQuoteContext InSingleQuote
758+ pos <- getPosition
759+ st <- getState
760+ -- single quote start can't be right after str
761+ guard $ stateLastStrPos st /= Just pos
756 try $ do charOrRef "'\8216\145"
762 try $ do charOrRef "'\8216\145"
757 notFollowedBy (oneOf ")!],;:-? \t\n")
763 notFollowedBy (oneOf ")!],;:-? \t\n")
758 notFollowedBy (char '.') <|> lookAhead (string "..." >> return ())
764 notFollowedBy (char '.') <|> lookAhead (string "..." >> return ())
src/Text/Pandoc/Readers/HTML.hs+6−2
@@ -421,8 +421,12 @@ pTagContents =
421 pStr <|> pSpace <|> smartPunctuation pTagContents <|> pSymbol <|> pBad
421 pStr <|> pSpace <|> smartPunctuation pTagContents <|> pSymbol <|> pBad
422
422
423pStr :: GenParser Char ParserState Inline
423pStr :: GenParser Char ParserState Inline
424+pStr = do
424−pStr = liftM Str $ many1 $ satisfy $ \c ->
425+ result <- many1 $ satisfy $ \c ->
425− not (isSpace c) && not (isSpecial c) && not (isBad c)
426+ not (isSpace c) && not (isSpecial c) && not (isBad c)
427+ pos <- getPosition
428+ updateState $ \s -> s{ stateLastStrPos = Just pos }
429+ return $ Str result
426
430
427isSpecial :: Char -> Bool
431isSpecial :: Char -> Bool
428isSpecial '"' = True
432isSpecial '"' = True
src/Text/Pandoc/Readers/Markdown.hs+2
@@ -1096,6 +1096,8 @@ str = do
1096 lookAhead alphaNum >> return '\x2019')
1096 lookAhead alphaNum >> return '\x2019')
1097 -- for things like l'aide
1097 -- for things like l'aide
1098 else mzero
1098 else mzero
1099+ pos <- getPosition
1100+ updateState $ \s -> s{ stateLastStrPos = Just pos }
1099 let result = a:as
1101 let result = a:as
1100 let spacesToNbr = map (\c -> if c == ' ' then '\160' else c)
1102 let spacesToNbr = map (\c -> if c == ' ' then '\160' else c)
1101 if smart
1103 if smart
src/Text/Pandoc/Readers/RST.hs+5−1
@@ -791,7 +791,11 @@ whitespace :: GenParser Char ParserState Inline
791whitespace = many1 spaceChar >> return Space <?> "whitespace"
791whitespace = many1 spaceChar >> return Space <?> "whitespace"
792
792
793str :: GenParser Char ParserState Inline
793str :: GenParser Char ParserState Inline
794+str = do
794−str = many1 (noneOf (specialChars ++ "\t\n ")) >>= return . Str
795+ result <- many1 (noneOf (specialChars ++ "\t\n "))
796+ pos <- getPosition
797+ updateState $ \s -> s{ stateLastStrPos = Just pos }
798+ return $ Str result
795
799
796-- an endline character that can be treated as a space, not a structural break
800-- an endline character that can be treated as a space, not a structural break
797endline :: GenParser Char ParserState Inline
801endline :: GenParser Char ParserState Inline
src/Text/Pandoc/Readers/Textile.hs+2
@@ -436,6 +436,8 @@ str = do
436 next <- lookAhead letter
436 next <- lookAhead letter
437 guard $ isLetter (last xs) || isLetter next
437 guard $ isLetter (last xs) || isLetter next
438 return $ xs ++ "-"
438 return $ xs ++ "-"
439+ pos <- getPosition
440+ updateState $ \s -> s{ stateLastStrPos = Just pos }
439 return $ Str result
441 return $ Str result
440
442
441-- | Textile allows HTML span infos, we discard them
443-- | Textile allows HTML span infos, we discard them