@@ -2,6 +2,7 @@
22 FlexibleContexts
33, GeneralizedNewtypeDeriving
44, TypeSynonymInstances
5+, MultiParamTypeClasses
56, FlexibleInstances #-}
67{-
78Copyright (C) 2006-2014 John MacFarlane <jgm@berkeley.edu>
@@ -80,6 +81,7 @@ module Text.Pandoc.Parsing ( anyLine,
8081 HeaderType (..),
8182 ParserContext (..),
8283 QuoteContext (..),
84+ HasQuoteContext (..),
8385 NoteTable,
8486 NoteTable',
8587 KeyTable,
@@ -88,7 +90,6 @@ module Text.Pandoc.Parsing ( anyLine,
8890 toKey,
8991 registerHeader,
9092 smartPunctuation,
91− withQuoteContext,
9293 singleQuoteStart,
9394 singleQuoteEnd,
9495 doubleQuoteStart,
@@ -106,6 +107,7 @@ module Text.Pandoc.Parsing ( anyLine,
106107 runF,
107108 askF,
108109 asksF,
110+ token,
109111 -- * Re-exports from Text.Pandoc.Parsec
110112 Stream,
111113 runParser,
@@ -160,7 +162,6 @@ module Text.Pandoc.Parsing ( anyLine,
160162 setSourceColumn,
161163 setSourceLine,
162164 newPos,
163− token
164165 )
165166where
166167
@@ -170,7 +171,7 @@ import Text.Pandoc.Builder (Blocks, Inlines, rawBlock, HasMeta(..))
170171import qualified Text.Pandoc.Builder as B
171172import Text.Pandoc.XML (fromEntities)
172173import qualified Text.Pandoc.UTF8 as UTF8 (putStrLn)
173−import Text.Parsec
174+import Text.Parsec hiding (token)
174175import Text.Parsec.Pos (newPos)
175176import Data.Char ( toLower, toUpper, ord, chr, isAscii, isAlphaNum,
176177 isHexDigit, isSpace )
@@ -484,7 +485,8 @@ mathDisplayWith op cl = try $ do
484485 string op
485486 many1Till (noneOf "\n" <|> (newline <* notFollowedBy' blankline)) (try $ string cl)
486487
487−mathDisplay :: Stream s m Char => ParserT s ParserState m String
488+mathDisplay :: (HasReaderOptions st, Stream s m Char)
489+ => ParserT s st m String
488490mathDisplay =
489491 (guardEnabled Ext_tex_math_dollars >> mathDisplayWith "$$" "$$")
490492 <|> (guardEnabled Ext_tex_math_single_backslash >>
@@ -492,7 +494,8 @@ mathDisplay =
492494 <|> (guardEnabled Ext_tex_math_double_backslash >>
493495 mathDisplayWith "\\\\[" "\\\\]")
494496
495−mathInline :: Stream s m Char => ParserT s ParserState m String
497+mathInline :: (HasReaderOptions st , Stream s m Char)
498+ => ParserT s st m String
496499mathInline =
497500 (guardEnabled Ext_tex_math_dollars >> mathInlineWith "$" "$")
498501 <|> (guardEnabled Ext_tex_math_single_backslash >>
@@ -909,6 +912,21 @@ class HasReaderOptions st where
909912 -- default
910913 getOption f = (f . extractReaderOptions) <$> getState
911914
915+class HasQuoteContext st m where
916+ getQuoteContext :: (Stream s m t) => ParsecT s st m QuoteContext
917+ withQuoteContext :: QuoteContext -> ParsecT s st m a -> ParsecT s st m a
918+
919+instance Monad m => HasQuoteContext ParserState m where
920+ getQuoteContext = stateQuoteContext <$> getState
921+ withQuoteContext context parser = do
922+ oldState <- getState
923+ let oldQuoteContext = stateQuoteContext oldState
924+ setState oldState { stateQuoteContext = context }
925+ result <- parser
926+ newState <- getState
927+ setState newState { stateQuoteContext = oldQuoteContext }
928+ return result
929+
912930instance HasReaderOptions ParserState where
913931 extractReaderOptions = stateOptions
914932
@@ -1051,9 +1069,9 @@ registerHeader (ident,classes,kvs) header' = do
10511069failUnlessSmart :: (Stream s m a, HasReaderOptions st) => ParserT s st m ()
10521070failUnlessSmart = getOption readerSmart >>= guard
10531071
1054−smartPunctuation :: Stream s m Char
1055− => ParserT s ParserState m Inlines
1056− -> ParserT s ParserState m Inlines
1072+smartPunctuation :: (HasReaderOptions st, HasLastStrPosition st, HasQuoteContext st m, Stream s m Char)
1073+ => ParserT s st m Inlines
1074+ -> ParserT s st m Inlines
10571075smartPunctuation inlineParser = do
10581076 failUnlessSmart
10591077 choice [ quoted inlineParser, apostrophe, dash, ellipses ]
@@ -1061,46 +1079,33 @@ smartPunctuation inlineParser = do
10611079apostrophe :: Stream s m Char => ParserT s st m Inlines
10621080apostrophe = (char '\'' <|> char '\8217') >> return (B.str "\x2019")
10631081
1064−quoted :: Stream s m Char
1065− => ParserT s ParserState m Inlines
1066− -> ParserT s ParserState m Inlines
1082+quoted :: (HasLastStrPosition st, HasQuoteContext st m, Stream s m Char)
1083+ => ParserT s st m Inlines
1084+ -> ParserT s st m Inlines
10671085quoted inlineParser = doubleQuoted inlineParser <|> singleQuoted inlineParser
10681086
1069−withQuoteContext :: Stream s m t
1070− => QuoteContext
1071− -> ParserT s ParserState m a
1072− -> ParserT s ParserState m a
1073−withQuoteContext context parser = do
1074− oldState <- getState
1075− let oldQuoteContext = stateQuoteContext oldState
1076− setState oldState { stateQuoteContext = context }
1077− result <- parser
1078− newState <- getState
1079− setState newState { stateQuoteContext = oldQuoteContext }
1080− return result
1081−
1082−singleQuoted :: Stream s m Char
1083− => ParserT s ParserState m Inlines
1084− -> ParserT s ParserState m Inlines
1087+singleQuoted :: (HasLastStrPosition st, HasQuoteContext st m, Stream s m Char)
1088+ => ParserT s st m Inlines
1089+ -> ParserT s st m Inlines
10851090singleQuoted inlineParser = try $ do
10861091 singleQuoteStart
10871092 withQuoteContext InSingleQuote $ many1Till inlineParser singleQuoteEnd >>=
10881093 return . B.singleQuoted . mconcat
10891094
1090−doubleQuoted :: Stream s m Char
1091− => ParserT s ParserState m Inlines
1092− -> ParserT s ParserState m Inlines
1095+doubleQuoted :: (HasQuoteContext st m, Stream s m Char)
1096+ => ParserT s st m Inlines
1097+ -> ParserT s st m Inlines
10931098doubleQuoted inlineParser = try $ do
10941099 doubleQuoteStart
10951100 withQuoteContext InDoubleQuote $ manyTill inlineParser doubleQuoteEnd >>=
10961101 return . B.doubleQuoted . mconcat
10971102
1098−failIfInQuoteContext :: Stream s m t
1103+failIfInQuoteContext :: (HasQuoteContext st m, Stream s m t)
10991104 => QuoteContext
1100− -> ParserT s ParserState m ()
1105+ -> ParserT s st m ()
11011106failIfInQuoteContext context = do
1102− st <- getState
1103− if stateQuoteContext st == context
1107+ context' <- getQuoteContext
1108+ if context' == context
11041109 then fail "already inside quotes"
11051110 else return ()
11061111
@@ -1110,8 +1115,8 @@ charOrRef cs =
11101115 guard (c `elem` cs)
11111116 return c)
11121117
1113−singleQuoteStart :: Stream s m Char
1114− => ParserT s ParserState m ()
1118+singleQuoteStart :: (HasLastStrPosition st, HasQuoteContext st m, Stream s m Char)
1119+ => ParserT s st m ()
11151120singleQuoteStart = do
11161121 failIfInQuoteContext InSingleQuote
11171122 -- single quote start can't be right after str
@@ -1124,8 +1129,8 @@ singleQuoteEnd = try $ do
11241129 charOrRef "'\8217\146"
11251130 notFollowedBy alphaNum
11261131
1127−doubleQuoteStart :: Stream s m Char
1128− => ParserT s ParserState m ()
1132+doubleQuoteStart :: (HasQuoteContext st m, Stream s m Char)
1133+ => ParserT s st m ()
11291134doubleQuoteStart = do
11301135 failIfInQuoteContext InDoubleQuote
11311136 try $ do charOrRef "\"\8220\147"
@@ -1179,6 +1184,14 @@ citeKey = try $ do
11791184 let key = firstChar:rest
11801185 return (suppress_author, key)
11811186
1187+
1188+token :: (Stream s m t)
1189+ => (t -> String)
1190+ -> (t -> SourcePos)
1191+ -> (t -> Maybe a)
1192+ -> ParsecT s st m a
1193+token pp pos match = tokenPrim pp (\_ t _ -> pos t) match
1194+
11821195--
11831196-- Macros
11841197--
@@ -1200,9 +1213,9 @@ macro = do
12001213 else return $ rawBlock "latex" def'
12011214
12021215-- | Apply current macros to string.
1203−applyMacros' :: Stream [Char] m Char
1216+applyMacros' :: (HasReaderOptions st, HasMacros st, Stream [Char] m Char)
12041217 => String
1205− -> ParserT [Char] ParserState m String
1218+ -> ParserT [Char] st m String
12061219applyMacros' target = do
12071220 apply <- getOption readerApplyMacros
12081221 if apply