@@ -1,5 +1,8 @@
1−{-# LANGUAGE GeneralizedNewtypeDeriving, TypeSynonymInstances,
2− FlexibleInstances#-}
1+{-# LANGUAGE
2+ FlexibleContexts
3+, GeneralizedNewtypeDeriving
4+, TypeSynonymInstances
5+, FlexibleInstances #-}
36{-
47Copyright (C) 2006-2014 John MacFarlane <jgm@berkeley.edu>
58
@@ -177,12 +180,15 @@ import Text.Pandoc.Asciify (toAsciiChar)
177180import Data.Default
178181import qualified Data.Set as Set
179182import Control.Monad.Reader
180−import Control.Applicative ((*>), (<*), (<$), liftA2, Applicative)
183+import Control.Monad.Identity
184+import Control.Applicative ((<$>), (<*>), (*>), (<*), (<$), Applicative)
181185import Data.Monoid
182186import Data.Maybe (catMaybes)
183187
184188type Parser t s = Parsec t s
185189
190+type ParserT = ParsecT
191+
186192newtype F a = F { unF :: Reader ParserState a } deriving (Monad, Applicative, Functor)
187193
188194runF :: F a -> ParserState -> a
@@ -201,11 +207,11 @@ instance Monoid a => Monoid (F a) where
201207
202208-- | Like >>, but returns the operation on the left.
203209-- (Suggested by Tillmann Rendel on Haskell-cafe list.)
204−(>>~) :: (Monad m) => m a -> m b -> m a
205−a >>~ b = a >>= \x -> b >> return x
210+(>>~) :: (Applicative m) => m a -> m b -> m a
211+a >>~ b = a <* b
206212
207213-- | Parse any line of text
208−anyLine :: Parser [Char] st [Char]
214+anyLine :: Stream [Char] m Char => ParserT [Char] st m [Char]
209215anyLine = do
210216 -- This is much faster than:
211217 -- manyTill anyChar newline
@@ -221,9 +227,10 @@ anyLine = do
221227 _ -> mzero
222228
223229-- | Like @manyTill@, but reads at least one item.
224−many1Till :: Parser [tok] st a
225− -> Parser [tok] st end
226− -> Parser [tok] st [a]
230+many1Till :: Stream s m t
231+ => ParserT s st m a
232+ -> ParserT s st m end
233+ -> ParserT s st m [a]
227234many1Till p end = do
228235 first <- p
229236 rest <- manyTill p end
@@ -232,14 +239,14 @@ many1Till p end = do
232239-- | A more general form of @notFollowedBy@. This one allows any
233240-- type of parser to be specified, and succeeds only if that parser fails.
234241-- It does not consume any input.
235−notFollowedBy' :: Show b => Parser [a] st b -> Parser [a] st ()
242+notFollowedBy' :: (Show b, Stream s m a) => ParserT s st m b -> ParserT s st m ()
236243notFollowedBy' p = try $ join $ do a <- try p
237244 return (unexpected (show a))
238245 <|>
239246 return (return ())
240247-- (This version due to Andrew Pimlott on the Haskell mailing list.)
241248
242−oneOfStrings' :: (Char -> Char -> Bool) -> [String] -> Parser [Char] st String
249+oneOfStrings' :: Stream s m Char => (Char -> Char -> Bool) -> [String] -> ParserT s st m String
243250oneOfStrings' _ [] = fail "no strings"
244251oneOfStrings' matches strs = try $ do
245252 c <- anyChar
@@ -254,11 +261,11 @@ oneOfStrings' matches strs = try $ do
254261-- | Parses one of a list of strings. If the list contains
255262-- two strings one of which is a prefix of the other, the longer
256263-- string will be matched if possible.
257−oneOfStrings :: [String] -> Parser [Char] st String
264+oneOfStrings :: Stream s m Char => [String] -> ParserT s st m String
258265oneOfStrings = oneOfStrings' (==)
259266
260267-- | Parses one of a list of strings (tried in order), case insensitive.
261−oneOfStringsCI :: [String] -> Parser [Char] st String
268+oneOfStringsCI :: Stream s m Char => [String] -> ParserT s st m String
262269oneOfStringsCI = oneOfStrings' ciMatch
263270 where ciMatch x y = toLower' x == toLower' y
264271 -- this optimizes toLower by checking common ASCII case
@@ -269,35 +276,35 @@ oneOfStringsCI = oneOfStrings' ciMatch
269276 | otherwise = toLower c
270277
271278-- | Parses a space or tab.
272−spaceChar :: Parser [Char] st Char
279+spaceChar :: Stream s m Char => ParserT s st m Char
273280spaceChar = satisfy $ \c -> c == ' ' || c == '\t'
274281
275282-- | Parses a nonspace, nonnewline character.
276−nonspaceChar :: Parser [Char] st Char
283+nonspaceChar :: Stream s m Char => ParserT s st m Char
277284nonspaceChar = satisfy $ flip notElem ['\t', '\n', ' ', '\r']
278285
279286-- | Skips zero or more spaces or tabs.
280−skipSpaces :: Parser [Char] st ()
287+skipSpaces :: Stream s m Char => ParserT s st m ()
281288skipSpaces = skipMany spaceChar
282289
283290-- | Skips zero or more spaces or tabs, then reads a newline.
284−blankline :: Parser [Char] st Char
291+blankline :: Stream s m Char => ParserT s st m Char
285292blankline = try $ skipSpaces >> newline
286293
287294-- | Parses one or more blank lines and returns a string of newlines.
288−blanklines :: Parser [Char] st [Char]
295+blanklines :: Stream s m Char => ParserT s st m [Char]
289296blanklines = many1 blankline
290297
291298-- | Parses material enclosed between start and end parsers.
292−enclosed :: Parser [Char] st t -- ^ start parser
293− -> Parser [Char] st end -- ^ end parser
294− -> Parser [Char] st a -- ^ content parser (to be used repeatedly)
295− -> Parser [Char] st [a]
299+enclosed :: Stream s m Char => ParserT s st m t -- ^ start parser
300+ -> ParserT s st m end -- ^ end parser
301+ -> ParserT s st m a -- ^ content parser (to be used repeatedly)
302+ -> ParserT s st m [a]
296303enclosed start end parser = try $
297304 start >> notFollowedBy space >> many1Till parser end
298305
299306-- | Parse string, case insensitive.
300−stringAnyCase :: [Char] -> Parser [Char] st String
307+stringAnyCase :: Stream s m Char => [Char] -> ParserT s st m String
301308stringAnyCase [] = string ""
302309stringAnyCase (x:xs) = do
303310 firstChar <- char (toUpper x) <|> char (toLower x)
@@ -305,7 +312,7 @@ stringAnyCase (x:xs) = do
305312 return (firstChar:rest)
306313
307314-- | Parse contents of 'str' using 'parser' and return result.
308−parseFromString :: Parser [tok] st a -> [tok] -> Parser [tok] st a
315+parseFromString :: Stream s m t => ParserT s st m a -> s -> ParserT s st m a
309316parseFromString parser str = do
310317 oldPos <- getPosition
311318 oldInput <- getInput
@@ -316,7 +323,7 @@ parseFromString parser str = do
316323 return result
317324
318325-- | Parse raw line block up to and including blank lines.
319−lineClump :: Parser [Char] st String
326+lineClump :: Stream [Char] m Char => ParserT [Char] st m String
320327lineClump = blanklines
321328 <|> (many1 (notFollowedBy blankline >> anyLine) >>= return . unlines)
322329
@@ -325,8 +332,8 @@ lineClump = blanklines
325332-- pairs of open and close, which must be different. For example,
326333-- @charsInBalanced '(' ')' anyChar@ will parse "(hello (there))"
327334-- and return "hello (there)".
328−charsInBalanced :: Char -> Char -> Parser [Char] st Char
329− -> Parser [Char] st String
335+charsInBalanced :: Stream s m Char => Char -> Char -> ParserT s st m Char
336+ -> ParserT s st m String
330337charsInBalanced open close parser = try $ do
331338 char open
332339 let isDelim c = c == open || c == close
@@ -350,8 +357,8 @@ uppercaseRomanDigits :: [Char]
350357uppercaseRomanDigits = map toUpper lowercaseRomanDigits
351358
352359-- | Parses a roman numeral (uppercase or lowercase), returns number.
353−romanNumeral :: Bool -- ^ Uppercase if true
354− -> Parser [Char] st Int
360+romanNumeral :: Stream s m Char => Bool -- ^ Uppercase if true
361+ -> ParserT s st m Int
355362romanNumeral upperCase = do
356363 let romanDigits = if upperCase
357364 then uppercaseRomanDigits
@@ -383,8 +390,8 @@ romanNumeral upperCase = do
383390
384391-- | Parses an email address; returns original and corresponding
385392-- escaped mailto: URI.
386−emailAddress :: Parser [Char] st (String, String)
387−emailAddress = try $ liftA2 toResult mailbox (char '@' *> domain)
393+emailAddress :: Stream s m Char => ParserT s st m (String, String)
394+emailAddress = try $ toResult <$> mailbox <*> (char '@' *> domain)
388395 where toResult mbox dom = let full = fromEntities $ mbox ++ '@':dom
389396 in (full, escapeURI $ "mailto:" ++ full)
390397 mailbox = intercalate "." `fmap` (emailWord `sepby1` dot)
@@ -398,7 +405,7 @@ emailAddress = try $ liftA2 toResult mailbox (char '@' *> domain)
398405 isEmailPunct c = c `elem` "!\"#$%&'*+-/=?^_{|}~;"
399406 -- note: sepBy1 from parsec consumes input when sep
400407 -- succeeds and p fails, so we use this variant here.
401− sepby1 p sep = liftA2 (:) p (many (try $ sep >> p))
408+ sepby1 p sep = (:) <$> p <*> (many (try $ sep >> p))
402409
403410
404411-- Schemes from http://www.iana.org/assignments/uri-schemes.html plus
@@ -426,11 +433,11 @@ schemes = ["coap","doi","javascript","aaa","aaas","about","acap","cap","cid",
426433 "ventrilo","view-source","webcal","wtai","wyciwyg","xfire","xri",
427434 "ymsgr"]
428435
429−uriScheme :: Parser [Char] st String
436+uriScheme :: Stream s m Char => ParserT s st m String
430437uriScheme = oneOfStringsCI schemes
431438
432439-- | Parses a URI. Returns pair of original and URI-escaped version.
433−uri :: Parser [Char] st (String, String)
440+uri :: Stream [Char] m Char => ParserT [Char] st m (String, String)
434441uri = try $ do
435442 scheme <- uriScheme
436443 char ':'
@@ -460,7 +467,7 @@ uri = try $ do
460467 let uri' = scheme ++ ":" ++ fromEntities str'
461468 return (uri', escapeURI uri')
462469
463−mathInlineWith :: String -> String -> Parser [Char] st String
470+mathInlineWith :: Stream s m Char => String -> String -> ParserT s st m String
464471mathInlineWith op cl = try $ do
465472 string op
466473 notFollowedBy space
@@ -474,12 +481,12 @@ mathInlineWith op cl = try $ do
474481 notFollowedBy digit -- to prevent capture of $5
475482 return $ concat words'
476483
477−mathDisplayWith :: String -> String -> Parser [Char] st String
484+mathDisplayWith :: Stream s m Char => String -> String -> ParserT s st m String
478485mathDisplayWith op cl = try $ do
479486 string op
480487 many1Till (noneOf "\n" <|> (newline >>~ notFollowedBy' blankline)) (try $ string cl)
481488
482−mathDisplay :: Parser [Char] ParserState String
489+mathDisplay :: Stream s m Char => ParserT s ParserState m String
483490mathDisplay =
484491 (guardEnabled Ext_tex_math_dollars >> mathDisplayWith "$$" "$$")
485492 <|> (guardEnabled Ext_tex_math_single_backslash >>
@@ -487,7 +494,7 @@ mathDisplay =
487494 <|> (guardEnabled Ext_tex_math_double_backslash >>
488495 mathDisplayWith "\\\\[" "\\\\]")
489496
490−mathInline :: Parser [Char] ParserState String
497+mathInline :: Stream s m Char => ParserT s ParserState m String
491498mathInline =
492499 (guardEnabled Ext_tex_math_dollars >> mathInlineWith "$" "$")
493500 <|> (guardEnabled Ext_tex_math_single_backslash >>
@@ -499,8 +506,9 @@ mathInline =
499506-- displacement (the difference between the source column at the end
500507-- and the source column at the beginning). Vertical displacement
501508-- (source row) is ignored.
502−withHorizDisplacement :: Parser [Char] st a -- ^ Parser to apply
503− -> Parser [Char] st (a, Int) -- ^ (result, displacement)
509+withHorizDisplacement :: Stream s m Char
510+ => ParserT s st m a -- ^ Parser to apply
511+ -> ParserT s st m (a, Int) -- ^ (result, displacement)
504512withHorizDisplacement parser = do
505513 pos1 <- getPosition
506514 result <- parser
@@ -509,7 +517,7 @@ withHorizDisplacement parser = do
509517
510518-- | Applies a parser and returns the raw string that was parsed,
511519-- along with the value produced by the parser.
512−withRaw :: Monad m => ParsecT [Char] st m a -> ParsecT [Char] st m (a, [Char])
520+withRaw :: Stream [Char] m Char => ParsecT [Char] st m a -> ParsecT [Char] st m (a, [Char])
513521withRaw parser = do
514522 pos1 <- getPosition
515523 inp <- getInput
@@ -525,12 +533,13 @@ withRaw parser = do
525533 return (result, raw)
526534
527535-- | Parses backslash, then applies character parser.
528−escaped :: Parser [Char] st Char -- ^ Parser for character to escape
529− -> Parser [Char] st Char
536+escaped :: Stream s m Char
537+ => ParserT s st m Char -- ^ Parser for character to escape
538+ -> ParserT s st m Char
530539escaped parser = try $ char '\\' >> parser
531540
532541-- | Parse character entity.
533−characterReference :: Parser [Char] st Char
542+characterReference :: Stream s m Char => ParserT s st m Char
534543characterReference = try $ do
535544 char '&'
536545 ent <- many1Till nonspaceChar (char ';')
@@ -539,19 +548,19 @@ characterReference = try $ do
539548 Nothing -> fail "entity not found"
540549
541550-- | Parses an uppercase roman numeral and returns (UpperRoman, number).
542−upperRoman :: Parser [Char] st (ListNumberStyle, Int)
551+upperRoman :: Stream s m Char => ParserT s st m (ListNumberStyle, Int)
543552upperRoman = do
544553 num <- romanNumeral True
545554 return (UpperRoman, num)
546555
547556-- | Parses a lowercase roman numeral and returns (LowerRoman, number).
548−lowerRoman :: Parser [Char] st (ListNumberStyle, Int)
557+lowerRoman :: Stream s m Char => ParserT s st m (ListNumberStyle, Int)
549558lowerRoman = do
550559 num <- romanNumeral False
551560 return (LowerRoman, num)
552561
553562-- | Parses a decimal numeral and returns (Decimal, number).
554−decimal :: Parser [Char] st (ListNumberStyle, Int)
563+decimal :: Stream s m Char => ParserT s st m (ListNumberStyle, Int)
555564decimal = do
556565 num <- many1 digit
557566 return (Decimal, read num)
@@ -560,7 +569,8 @@ decimal = do
560569-- returns (DefaultStyle, [next example number]). The next
561570-- example number is incremented in parser state, and the label
562571-- (if present) is added to the label table.
563−exampleNum :: Parser [Char] ParserState (ListNumberStyle, Int)
572+exampleNum :: Stream s m Char
573+ => ParserT s ParserState m (ListNumberStyle, Int)
564574exampleNum = do
565575 char '@'
566576 lab <- many (alphaNum <|> satisfy (\c -> c == '_' || c == '-'))
@@ -574,38 +584,39 @@ exampleNum = do
574584 return (Example, num)
575585
576586-- | Parses a '#' returns (DefaultStyle, 1).
577−defaultNum :: Parser [Char] st (ListNumberStyle, Int)
587+defaultNum :: Stream s m Char => ParserT s st m (ListNumberStyle, Int)
578588defaultNum = do
579589 char '#'
580590 return (DefaultStyle, 1)
581591
582592-- | Parses a lowercase letter and returns (LowerAlpha, number).
583−lowerAlpha :: Parser [Char] st (ListNumberStyle, Int)
593+lowerAlpha :: Stream s m Char => ParserT s st m (ListNumberStyle, Int)
584594lowerAlpha = do
585595 ch <- oneOf ['a'..'z']
586596 return (LowerAlpha, ord ch - ord 'a' + 1)
587597
588598-- | Parses an uppercase letter and returns (UpperAlpha, number).
589−upperAlpha :: Parser [Char] st (ListNumberStyle, Int)
599+upperAlpha :: Stream s m Char => ParserT s st m (ListNumberStyle, Int)
590600upperAlpha = do
591601 ch <- oneOf ['A'..'Z']
592602 return (UpperAlpha, ord ch - ord 'A' + 1)
593603
594604-- | Parses a roman numeral i or I
595−romanOne :: Parser [Char] st (ListNumberStyle, Int)
605+romanOne :: Stream s m Char => ParserT s st m (ListNumberStyle, Int)
596606romanOne = (char 'i' >> return (LowerRoman, 1)) <|>
597607 (char 'I' >> return (UpperRoman, 1))
598608
599609-- | Parses an ordered list marker and returns list attributes.
600−anyOrderedListMarker :: Parser [Char] ParserState ListAttributes
610+anyOrderedListMarker :: Stream s m Char => ParserT s ParserState m ListAttributes
601611anyOrderedListMarker = choice $
602612 [delimParser numParser | delimParser <- [inPeriod, inOneParen, inTwoParens],
603613 numParser <- [decimal, exampleNum, defaultNum, romanOne,
604614 lowerAlpha, lowerRoman, upperAlpha, upperRoman]]
605615
606616-- | Parses a list number (num) followed by a period, returns list attributes.
607−inPeriod :: Parser [Char] st (ListNumberStyle, Int)
608− -> Parser [Char] st ListAttributes
617+inPeriod :: Stream s m Char
618+ => ParserT s st m (ListNumberStyle, Int)
619+ -> ParserT s st m ListAttributes
609620inPeriod num = try $ do
610621 (style, start) <- num
611622 char '.'
@@ -615,16 +626,18 @@ inPeriod num = try $ do
615626 return (start, style, delim)
616627
617628-- | Parses a list number (num) followed by a paren, returns list attributes.
618−inOneParen :: Parser [Char] st (ListNumberStyle, Int)
619− -> Parser [Char] st ListAttributes
629+inOneParen :: Stream s m Char
630+ => ParserT s st m (ListNumberStyle, Int)
631+ -> ParserT s st m ListAttributes
620632inOneParen num = try $ do
621633 (style, start) <- num
622634 char ')'
623635 return (start, style, OneParen)
624636
625637-- | Parses a list number (num) enclosed in parens, returns list attributes.
626−inTwoParens :: Parser [Char] st (ListNumberStyle, Int)
627− -> Parser [Char] st ListAttributes
638+inTwoParens :: Stream s m Char
639+ => ParserT s st m (ListNumberStyle, Int)
640+ -> ParserT s st m ListAttributes
628641inTwoParens num = try $ do
629642 char '('
630643 (style, start) <- num
@@ -633,9 +646,10 @@ inTwoParens num = try $ do
633646
634647-- | Parses an ordered list marker with a given style and delimiter,
635648-- returns number.
636−orderedListMarker :: ListNumberStyle
649+orderedListMarker :: Stream s m Char
650+ => ListNumberStyle
637651 -> ListNumberDelim
638− -> Parser [Char] ParserState Int
652+ -> ParserT s ParserState m Int
639653orderedListMarker style delim = do
640654 let num = defaultNum <|> -- # can continue any kind of list
641655 case style of
@@ -655,12 +669,12 @@ orderedListMarker style delim = do
655669 return start
656670
657671-- | Parses a character reference and returns a Str element.
658−charRef :: Parser [Char] st Inline
672+charRef :: Stream s m Char => ParserT s st m Inline
659673charRef = do
660674 c <- characterReference
661675 return $ Str [c]
662676
663−lineBlockLine :: Parser [Char] st String
677+lineBlockLine :: Stream [Char] m Char => ParserT [Char] st m String
664678lineBlockLine = try $ do
665679 char '|'
666680 char ' '
@@ -671,7 +685,7 @@ lineBlockLine = try $ do
671685 return $ white ++ unwords (line : continuations)
672686
673687-- | Parses an RST-style line block and returns a list of strings.
674−lineBlockLines :: Parser [Char] st [String]
688+lineBlockLines :: Stream [Char] m Char => ParserT [Char] st m [String]
675689lineBlockLines = try $ do
676690 lines' <- many1 lineBlockLine
677691 skipMany1 $ blankline <|> try (char '|' >> blankline)
@@ -679,11 +693,12 @@ lineBlockLines = try $ do
679693
680694-- | Parse a table using 'headerParser', 'rowParser',
681695-- 'lineParser', and 'footerParser'.
682−tableWith :: Parser [Char] ParserState ([[Block]], [Alignment], [Int])
683− -> ([Int] -> Parser [Char] ParserState [[Block]])
684− -> Parser [Char] ParserState sep
685− -> Parser [Char] ParserState end
686− -> Parser [Char] ParserState Block
696+tableWith :: Stream s m Char
697+ => ParserT s ParserState m ([[Block]], [Alignment], [Int])
698+ -> ([Int] -> ParserT s ParserState m [[Block]])
699+ -> ParserT s ParserState m sep
700+ -> ParserT s ParserState m end
701+ -> ParserT s ParserState m Block
687702tableWith headerParser rowParser lineParser footerParser = try $ do
688703 (heads, aligns, indices) <- headerParser
689704 lines' <- rowParser indices `sepEndBy1` lineParser
@@ -725,9 +740,10 @@ widthsFromIndices numColumns' indices =
725740-- (which may be grid), then the rows,
726741-- which may be grid, separated by blank lines, and
727742-- ending with a footer (dashed line followed by blank line).
728−gridTableWith :: Parser [Char] ParserState [Block] -- ^ Block list parser
743+gridTableWith :: Stream [Char] m Char
744+ => ParserT [Char] ParserState m [Block] -- ^ Block list parser
729745 -> Bool -- ^ Headerless table
730− -> Parser [Char] ParserState Block
746+ -> ParserT [Char] ParserState m Block
731747gridTableWith blocks headless =
732748 tableWith (gridTableHeader headless blocks) (gridTableRow blocks)
733749 (gridTableSep '-') gridTableFooter
@@ -736,13 +752,13 @@ gridTableSplitLine :: [Int] -> String -> [String]
736752gridTableSplitLine indices line = map removeFinalBar $ tail $
737753 splitStringByIndices (init indices) $ trimr line
738754
739−gridPart :: Char -> Parser [Char] st (Int, Int)
755+gridPart :: Stream s m Char => Char -> ParserT s st m (Int, Int)
740756gridPart ch = do
741757 dashes <- many1 (char ch)
742758 char '+'
743759 return (length dashes, length dashes + 1)
744760
745−gridDashedLines :: Char -> Parser [Char] st [(Int,Int)]
761+gridDashedLines :: Stream s m Char => Char -> ParserT s st m [(Int,Int)]
746762gridDashedLines ch = try $ char '+' >> many1 (gridPart ch) >>~ blankline
747763
748764removeFinalBar :: String -> String
@@ -750,13 +766,14 @@ removeFinalBar =
750766 reverse . dropWhile (`elem` " \t") . dropWhile (=='|') . reverse
751767
752768-- | Separator between rows of grid table.
753−gridTableSep :: Char -> Parser [Char] ParserState Char
769+gridTableSep :: Stream s m Char => Char -> ParserT s ParserState m Char
754770gridTableSep ch = try $ gridDashedLines ch >> return '\n'
755771
756772-- | Parse header for a grid table.
757−gridTableHeader :: Bool -- ^ Headerless table
758− -> Parser [Char] ParserState [Block]
759− -> Parser [Char] ParserState ([[Block]], [Alignment], [Int])
773+gridTableHeader :: Stream [Char] m Char
774+ => Bool -- ^ Headerless table
775+ -> ParserT [Char] ParserState m [Block]
776+ -> ParserT [Char] ParserState m ([[Block]], [Alignment], [Int])
760777gridTableHeader headless blocks = try $ do
761778 optional blanklines
762779 dashes <- gridDashedLines '-'
@@ -779,16 +796,17 @@ gridTableHeader headless blocks = try $ do
779796 heads <- mapM (parseFromString blocks) $ map trim rawHeads
780797 return (heads, aligns, indices)
781798
782−gridTableRawLine :: [Int] -> Parser [Char] ParserState [String]
799+gridTableRawLine :: Stream s m Char => [Int] -> ParserT s ParserState m [String]
783800gridTableRawLine indices = do
784801 char '|'
785802 line <- many1Till anyChar newline
786803 return (gridTableSplitLine indices line)
787804
788805-- | Parse row of grid table.
789−gridTableRow :: Parser [Char] ParserState [Block]
806+gridTableRow :: Stream [Char] m Char
807+ => ParserT [Char] ParserState m [Block]
790808 -> [Int]
791− -> Parser [Char] ParserState [[Block]]
809+ -> ParserT [Char] ParserState m [[Block]]
792810gridTableRow blocks indices = do
793811 colLines <- many1 (gridTableRawLine indices)
794812 let cols = map ((++ "\n") . unlines . removeOneLeadingSpace) $
@@ -807,15 +825,16 @@ compactifyCell :: [Block] -> [Block]
807825compactifyCell bs = head $ compactify [bs]
808826
809827-- | Parse footer for a grid table.
810−gridTableFooter :: Parser [Char] ParserState [Char]
828+gridTableFooter :: Stream s m Char => ParserT s ParserState m [Char]
811829gridTableFooter = blanklines
812830
813831---
814832
815833-- | Parse a string with a given parser and state.
816−readWith :: Parser [Char] st a -- ^ parser
834+readWith :: (Show s, Stream s Identity Char)
835+ => ParserT s st Identity a -- ^ parser
817836 -> st -- ^ initial state
818− -> [Char] -- ^ input
837+ -> s -- ^ input
819838 -> a
820839readWith parser state input =
821840 case runParser parser state "source" input of
@@ -823,15 +842,16 @@ readWith parser state input =
823842 let errPos = errorPos err'
824843 errLine = sourceLine errPos
825844 errColumn = sourceColumn errPos
826− theline = (lines input ++ [""]) !! (errLine - 1)
845+ theline = (lines (show input) ++ [""]) !! (errLine - 1)
827846 in error $ "\nError at " ++ show err' ++ "\n" ++
828847 theline ++ "\n" ++ replicate (errColumn - 1) ' ' ++
829848 "^"
830849 Right result -> result
831850
832851-- | Parse a string with @parser@ (for testing).
833−testStringWith :: (Show a) => Parser [Char] ParserState a
834− -> String
852+testStringWith :: (Show s, Show a, Stream s Identity Char)
853+ => ParserT s ParserState Identity a
854+ -> s
835855 -> IO ()
836856testStringWith parser str = UTF8.putStrLn $ show $
837857 readWith parser defaultParserState str
@@ -878,7 +898,7 @@ instance HasMeta ParserState where
878898
879899class HasReaderOptions st where
880900 extractReaderOptions :: st -> ReaderOptions
881− getOption :: (ReaderOptions -> b) -> Parser s st b
901+ getOption :: (Stream s m t) => (ReaderOptions -> b) -> ParserT s st m b
882902 -- default
883903 getOption f = (f . extractReaderOptions) `fmap` getState
884904
@@ -946,19 +966,19 @@ defaultParserState =
946966 stateWarnings = []}
947967
948968-- | Succeed only if the extension is enabled.
949−guardEnabled :: HasReaderOptions st => Extension -> Parser s st ()
969+guardEnabled :: (Stream s m a, HasReaderOptions st) => Extension -> ParserT s st m ()
950970guardEnabled ext = getOption readerExtensions >>= guard . Set.member ext
951971
952972-- | Succeed only if the extension is disabled.
953−guardDisabled :: HasReaderOptions st => Extension -> Parser s st ()
973+guardDisabled :: (Stream s m a, HasReaderOptions st) => Extension -> ParserT s st m ()
954974guardDisabled ext = getOption readerExtensions >>= guard . not . Set.member ext
955975
956976-- | Update the position on which the last string ended.
957−updateLastStrPos :: HasLastStrPosition st => Parser s st ()
977+updateLastStrPos :: (Stream s m a, HasLastStrPosition st) => ParserT s st m ()
958978updateLastStrPos = getPosition >>= updateState . setLastStrPos
959979
960980-- | Whether we are right after the end of a string.
961−notAfterString :: HasLastStrPosition st => Parser s st Bool
981+notAfterString :: (Stream s m a, HasLastStrPosition st) => ParserT s st m Bool
962982notAfterString = do
963983 pos <- getPosition
964984 st <- getState
@@ -998,8 +1018,8 @@ type SubstTable = M.Map Key Inlines
9981018-- and the auto_identifers extension is set, generate a new
9991019-- unique identifier, and update the list of identifiers
10001020-- in state.
1001−registerHeader :: (HasReaderOptions st, HasHeaderMap st, HasIdentifierList st)
1002− => Attr -> Inlines -> Parser s st Attr
1021+registerHeader :: (Stream s m a, HasReaderOptions st, HasHeaderMap st, HasIdentifierList st)
1022+ => Attr -> Inlines -> ParserT s st m Attr
10031023registerHeader (ident,classes,kvs) header' = do
10041024 ids <- extractIdentifierList `fmap` getState
10051025 exts <- getOption readerExtensions
@@ -1020,25 +1040,28 @@ registerHeader (ident,classes,kvs) header' = do
10201040 return (ident,classes,kvs)
10211041
10221042-- | Fail unless we're in "smart typography" mode.
1023−failUnlessSmart :: HasReaderOptions st => Parser s st ()
1043+failUnlessSmart :: (Stream s m a, HasReaderOptions st) => ParserT s st m ()
10241044failUnlessSmart = getOption readerSmart >>= guard
10251045
1026−smartPunctuation :: Parser [Char] ParserState Inlines
1027− -> Parser [Char] ParserState Inlines
1046+smartPunctuation :: Stream s m Char
1047+ => ParserT s ParserState m Inlines
1048+ -> ParserT s ParserState m Inlines
10281049smartPunctuation inlineParser = do
10291050 failUnlessSmart
10301051 choice [ quoted inlineParser, apostrophe, dash, ellipses ]
10311052
1032−apostrophe :: Parser [Char] ParserState Inlines
1053+apostrophe :: Stream s m Char => ParserT s st m Inlines
10331054apostrophe = (char '\'' <|> char '\8217') >> return (B.str "\x2019")
10341055
1035−quoted :: Parser [Char] ParserState Inlines
1036− -> Parser [Char] ParserState Inlines
1056+quoted :: Stream s m Char
1057+ => ParserT s ParserState m Inlines
1058+ -> ParserT s ParserState m Inlines
10371059quoted inlineParser = doubleQuoted inlineParser <|> singleQuoted inlineParser
10381060
1039−withQuoteContext :: QuoteContext
1040− -> Parser [tok] ParserState a
1041− -> Parser [tok] ParserState a
1061+withQuoteContext :: Stream s m t
1062+ => QuoteContext
1063+ -> ParserT s ParserState m a
1064+ -> ParserT s ParserState m a
10421065withQuoteContext context parser = do
10431066 oldState <- getState
10441067 let oldQuoteContext = stateQuoteContext oldState
@@ -1048,99 +1071,112 @@ withQuoteContext context parser = do
10481071 setState newState { stateQuoteContext = oldQuoteContext }
10491072 return result
10501073
1051−singleQuoted :: Parser [Char] ParserState Inlines
1052− -> Parser [Char] ParserState Inlines
1074+singleQuoted :: Stream s m Char
1075+ => ParserT s ParserState m Inlines
1076+ -> ParserT s ParserState m Inlines
10531077singleQuoted inlineParser = try $ do
10541078 singleQuoteStart
10551079 withQuoteContext InSingleQuote $ many1Till inlineParser singleQuoteEnd >>=
10561080 return . B.singleQuoted . mconcat
10571081
1058−doubleQuoted :: Parser [Char] ParserState Inlines
1059− -> Parser [Char] ParserState Inlines
1082+doubleQuoted :: Stream s m Char
1083+ => ParserT s ParserState m Inlines
1084+ -> ParserT s ParserState m Inlines
10601085doubleQuoted inlineParser = try $ do
10611086 doubleQuoteStart
10621087 withQuoteContext InDoubleQuote $ manyTill inlineParser doubleQuoteEnd >>=
10631088 return . B.doubleQuoted . mconcat
10641089
1065−failIfInQuoteContext :: QuoteContext -> Parser [tok] ParserState ()
1090+failIfInQuoteContext :: Stream s m t
1091+ => QuoteContext
1092+ -> ParserT s ParserState m ()
10661093failIfInQuoteContext context = do
10671094 st <- getState
10681095 if stateQuoteContext st == context
10691096 then fail "already inside quotes"
10701097 else return ()
10711098
1072−charOrRef :: [Char] -> Parser [Char] st Char
1099+charOrRef :: Stream s m Char => String -> ParserT s st m Char
10731100charOrRef cs =
10741101 oneOf cs <|> try (do c <- characterReference
10751102 guard (c `elem` cs)
10761103 return c)
10771104
1078−singleQuoteStart :: Parser [Char] ParserState ()
1105+singleQuoteStart :: Stream s m Char
1106+ => ParserT s ParserState m ()
10791107singleQuoteStart = do
10801108 failIfInQuoteContext InSingleQuote
10811109 -- single quote start can't be right after str
10821110 guard =<< notAfterString
10831111 () <$ charOrRef "'\8216\145"
10841112
1085−singleQuoteEnd :: Parser [Char] st ()
1113+singleQuoteEnd :: Stream s m Char
1114+ => ParserT s st m ()
10861115singleQuoteEnd = try $ do
10871116 charOrRef "'\8217\146"
10881117 notFollowedBy alphaNum
10891118
1090−doubleQuoteStart :: Parser [Char] ParserState ()
1119+doubleQuoteStart :: Stream s m Char
1120+ => ParserT s ParserState m ()
10911121doubleQuoteStart = do
10921122 failIfInQuoteContext InDoubleQuote
10931123 try $ do charOrRef "\"\8220\147"
10941124 notFollowedBy . satisfy $ flip elem [' ', '\t', '\n']
10951125
1096−doubleQuoteEnd :: Parser [Char] st ()
1097−doubleQuoteEnd = do
1098− charOrRef "\"\8221\148"
1099− return ()
1126+doubleQuoteEnd :: Stream s m Char
1127+ => ParserT s st m ()
1128+doubleQuoteEnd = void (charOrRef "\"\8221\148")
11001129
1101−ellipses :: Parser [Char] st Inlines
1130+ellipses :: Stream s m Char
1131+ => ParserT s st m Inlines
11021132ellipses = do
11031133 try (charOrRef "\8230\133") <|> try (string "..." >> return '…')
11041134 return (B.str "\8230")
11051135
1106−dash :: Parser [Char] ParserState Inlines
1136+dash :: Stream s m Char => ParserT s ParserState m Inlines
11071137dash = do
11081138 oldDashes <- getOption readerOldDashes
11091139 if oldDashes
11101140 then emDashOld <|> enDashOld
1111− else B.str `fmap` (hyphenDash <|> emDash <|> enDash)
1141+ else B.str <$> (hyphenDash <|> emDash <|> enDash)
11121142
11131143-- Two hyphens = en-dash, three = em-dash
1114−hyphenDash :: Parser [Char] st String
1144+hyphenDash :: Stream s m Char
1145+ => ParserT s st m String
11151146hyphenDash = do
11161147 try $ string "--"
11171148 option "\8211" (char '-' >> return "\8212")
11181149
1119−emDash :: Parser [Char] st String
1150+emDash :: Stream s m Char
1151+ => ParserT s st m String
11201152emDash = do
11211153 try (charOrRef "\8212\151")
11221154 return "\8212"
11231155
1124−enDash :: Parser [Char] st String
1156+enDash :: Stream s m Char
1157+ => ParserT s st m String
11251158enDash = do
11261159 try (charOrRef "\8212\151")
11271160 return "\8211"
11281161
1129−enDashOld :: Parser [Char] st Inlines
1162+enDashOld :: Stream s m Char
1163+ => ParserT s st m Inlines
11301164enDashOld = do
11311165 try (charOrRef "\8211\150") <|>
11321166 try (char '-' >> lookAhead (satisfy isDigit) >> return '–')
11331167 return (B.str "\8211")
11341168
1135−emDashOld :: Parser [Char] st Inlines
1169+emDashOld :: Stream s m Char
1170+ => ParserT s st m Inlines
11361171emDashOld = do
11371172 try (charOrRef "\8212\151") <|> (try $ string "--" >> optional (char '-') >> return '-')
11381173 return (B.str "\8212")
11391174
11401175-- This is used to prevent exponential blowups for things like:
11411176-- a**a*a**a*a**a*a**a*a**a*a**a*a**
1142−nested :: Parser s ParserState a
1143− -> Parser s ParserState a
1177+nested :: Stream s m a
1178+ => ParserT s ParserState m a
1179+ -> ParserT s ParserState m a
11441180nested p = do
11451181 nestlevel <- stateMaxNestingLevel `fmap` getState
11461182 guard $ nestlevel > 0
@@ -1149,7 +1185,8 @@ nested p = do
11491185 updateState $ \st -> st{ stateMaxNestingLevel = nestlevel }
11501186 return res
11511187
1152−citeKey :: HasLastStrPosition st => Parser [Char] st (Bool, String)
1188+citeKey :: (Stream s m Char, HasLastStrPosition st)
1189+ => ParserT s st m (Bool, String)
11531190citeKey = try $ do
11541191 guard =<< notAfterString
11551192 suppress_author <- option False (char '-' *> return True)
@@ -1166,7 +1203,8 @@ citeKey = try $ do
11661203--
11671204
11681205-- | Parse a \newcommand or \renewcommand macro definition.
1169−macro :: (HasMacros st, HasReaderOptions st) => Parser [Char] st Blocks
1206+macro :: (Stream [Char] m Char, HasMacros st, HasReaderOptions st)
1207+ => ParserT [Char] st m Blocks
11701208macro = do
11711209 apply <- getOption readerApplyMacros
11721210 inp <- getInput
@@ -1181,7 +1219,9 @@ macro = do
11811219 else return $ rawBlock "latex" def'
11821220
11831221-- | Apply current macros to string.
1184−applyMacros' :: String -> Parser [Char] ParserState String
1222+applyMacros' :: Stream [Char] m Char
1223+ => String
1224+ -> ParserT [Char] ParserState m String
11851225applyMacros' target = do
11861226 apply <- getOption readerApplyMacros
11871227 if apply