@@ -105,8 +105,9 @@ module Text.Pandoc.Parsing ( take1WhileP,
105105 singleQuoteEnd,
106106 doubleQuoteStart,
107107 doubleQuoteEnd,
108− ellipses,
109108 apostrophe,
109+ doubleCloseQuote,
110+ ellipses,
110111 dash,
111112 nested,
112113 citeKey,
@@ -1398,10 +1399,7 @@ smartPunctuation :: (HasReaderOptions st, HasLastStrPosition st, HasQuoteContext
13981399 -> ParserT s st m Inlines
13991400smartPunctuation inlineParser = do
14001401 guardEnabled Ext_smart
1401− choice [ quoted inlineParser, apostrophe, dash, ellipses ]
1402−
1403−apostrophe :: Stream s m Char => ParserT s st m Inlines
1404−apostrophe = (char '\'' <|> char '\8217') >> return (B.str "\x2019")
1402+ choice [ quoted inlineParser, apostrophe, doubleCloseQuote, dash, ellipses ]
14051403
14061404quoted :: (HasLastStrPosition st, HasQuoteContext st m, Stream s m Char)
14071405 => ParserT s st m Inlines
@@ -1411,16 +1409,22 @@ quoted inlineParser = doubleQuoted inlineParser <|> singleQuoted inlineParser
14111409singleQuoted :: (HasLastStrPosition st, HasQuoteContext st m, Stream s m Char)
14121410 => ParserT s st m Inlines
14131411 -> ParserT s st m Inlines
1414−singleQuoted inlineParser = try $ B.singleQuoted . mconcat
1415− <$ singleQuoteStart
1416− <*> withQuoteContext InSingleQuote (many1Till inlineParser singleQuoteEnd)
1417−
1418−doubleQuoted :: (HasQuoteContext st m, Stream s m Char)
1412+singleQuoted inlineParser = do
1413+ singleQuoteStart
1414+ (B.singleQuoted . mconcat <$>
1415+ try
1416+ (withQuoteContext InSingleQuote (many1Till inlineParser singleQuoteEnd)))
1417+ <|> pure "\8217"
1418+
1419+doubleQuoted :: (HasQuoteContext st m, HasLastStrPosition st, Stream s m Char)
14191420 => ParserT s st m Inlines
14201421 -> ParserT s st m Inlines
1421−doubleQuoted inlineParser = try $ B.doubleQuoted . mconcat
1422− <$ doubleQuoteStart
1423− <*> withQuoteContext InDoubleQuote (manyTill inlineParser doubleQuoteEnd)
1422+doubleQuoted inlineParser = do
1423+ doubleQuoteStart
1424+ (B.doubleQuoted . mconcat <$>
1425+ try
1426+ (withQuoteContext InDoubleQuote (manyTill inlineParser doubleQuoteEnd)))
1427+ <|> pure (B.str "\8220")
14241428
14251429failIfInQuoteContext :: (HasQuoteContext st m, Stream s m t)
14261430 => QuoteContext
@@ -1443,7 +1447,7 @@ singleQuoteStart = do
14431447 guard =<< notAfterString
14441448 try $ do
14451449 charOrRef "'\8216\145"
1446− notFollowedBy (oneOf [' ', '\t', '\n'])
1450+ notFollowedBy (satisfy isSpaceChar)
14471451
14481452singleQuoteEnd :: Stream s m Char
14491453 => ParserT s st m ()
@@ -1451,17 +1455,26 @@ singleQuoteEnd = try $ do
14511455 charOrRef "'\8217\146"
14521456 notFollowedBy alphaNum
14531457
1454−doubleQuoteStart :: (HasQuoteContext st m, Stream s m Char)
1458+doubleQuoteStart :: (HasLastStrPosition st,
1459+ HasQuoteContext st m,
1460+ Stream s m Char)
14551461 => ParserT s st m ()
14561462doubleQuoteStart = do
14571463 failIfInQuoteContext InDoubleQuote
1464+ guard =<< notAfterString
14581465 try $ do charOrRef "\"\8220\147"
1459− notFollowedBy (oneOf [' ', '\t', '\n'])
1466+ notFollowedBy (satisfy isSpaceChar)
14601467
14611468doubleQuoteEnd :: Stream s m Char
14621469 => ParserT s st m ()
14631470doubleQuoteEnd = void (charOrRef "\"\8221\148")
14641471
1472+apostrophe :: Stream s m Char => ParserT s st m Inlines
1473+apostrophe = (char '\'' <|> char '\8217') >> return (B.str "\8217")
1474+
1475+doubleCloseQuote :: Stream s m Char => ParserT s st m Inlines
1476+doubleCloseQuote = B.str "\8221" <$ char '"'
1477+
14651478ellipses :: Stream s m Char
14661479 => ParserT s st m Inlines
14671480ellipses = try (string "..." >> return (B.str "\8230"))