Skip to content
This repository
Browse code

Basics now working with text.

Still need to rewrite macro code, html stuff.
See TODOs in source.
  • Loading branch information...
commit 451d7c38690f2c939d25d2a40fc01492cba7b391 1 parent 0468425
John MacFarlane authored September 25, 2012
15  src/Text/Pandoc/Parsing.hs
... ...
@@ -1,4 +1,5 @@
1  
-{-# LANGUAGE GeneralizedNewtypeDeriving, FlexibleContexts #-}
  1
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
  2
+{-# LANGUAGE FlexibleContexts #-}
2 3
 {-
3 4
 Copyright (C) 2006-2010 John MacFarlane <jgm@berkeley.edu>
4 5
 
@@ -87,6 +88,7 @@ module Text.Pandoc.Parsing ( (>>~),
87 88
                              -- macro,
88 89
                              -- applyMacros',
89 90
                              Parser,
  91
+                             Stream (..),
90 92
                              F(..),
91 93
                              runF,
92 94
                              askF,
@@ -260,12 +262,12 @@ stringAnyCase (x:xs) = do
260 262
   return (firstChar:rest)
261 263
 
262 264
 -- | Parse contents of 'str' using 'parser' and return result.
263  
-parseFromString :: Stream s Identity tok
264  
-                => Parser s st a -> s -> Parser s st a
  265
+parseFromString :: (IsString s, Stream s Identity tok)
  266
+                => Parser s st a -> String -> Parser s st a
265 267
 parseFromString parser str = do
266 268
   oldPos <- getPosition
267 269
   oldInput <- getInput
268  
-  setInput str
  270
+  setInput $ fromString str
269 271
   result <- parser
270 272
   setInput oldInput
271 273
   setPosition oldPos
@@ -672,8 +674,7 @@ gridTableHeader headless blocks = try $ do
672 674
                     then replicate (length dashes) ""
673 675
                     else map (intercalate " ") $ transpose
674 676
                        $ map (gridTableSplitLine indices) rawContent
675  
-  heads <- mapM (parseFromString blocks . fromString .
676  
-                 removeLeadingTrailingSpace) rawHeads
  677
+  heads <- mapM (parseFromString blocks . removeLeadingTrailingSpace) rawHeads
677 678
   return (heads, aligns, indices)
678 679
 
679 680
 gridTableRawLine :: Stream s Identity Char
@@ -692,7 +693,7 @@ gridTableRow blocks indices = do
692 693
   colLines <- many1 (gridTableRawLine indices)
693 694
   let cols = map ((++ "\n") . unlines . removeOneLeadingSpace) $
694 695
                transpose colLines
695  
-  mapM (liftM compactifyCell . parseFromString blocks . fromString) cols
  696
+  mapM (liftM compactifyCell . parseFromString blocks) cols
696 697
 
697 698
 removeOneLeadingSpace :: [String] -> [String]
698 699
 removeOneLeadingSpace xs =
418  src/Text/Pandoc/Readers/Markdown.hs
... ...
@@ -1,4 +1,5 @@
1 1
 {-# LANGUAGE RelaxedPolyRec #-} -- needed for inlinesBetween on GHC < 7
  2
+{-# LANGUAGE FlexibleContexts #-}
2 3
 {-
3 4
 Copyright (C) 2006-2010 John MacFarlane <jgm@berkeley.edu>
4 5
 
@@ -42,7 +43,7 @@ import Text.Pandoc.Options
42 43
 import Text.Pandoc.Shared hiding (compactify)
43 44
 import Text.Pandoc.Parsing hiding (tableWith)
44 45
 import Text.Pandoc.Readers.LaTeX ( rawLaTeXInline, rawLaTeXBlock )
45  
-import Text.Pandoc.Readers.HTML ( htmlTag, htmlInBalanced, isInlineTag, isBlockTag,
  46
+import Text.Pandoc.Readers.HTML ( {- htmlTag, htmlInBalanced, -} isInlineTag, isBlockTag,
46 47
                                   isTextTag, isCommentTag )
47 48
 import Text.Pandoc.XML ( fromEntities )
48 49
 import Data.Monoid (mconcat, mempty)
@@ -53,22 +54,32 @@ import Text.HTML.TagSoup.Match (tagOpen)
53 54
 import qualified Data.Set as Set
54 55
 import Data.Text (Text)
55 56
 import qualified Data.Text as T
  57
+import Data.String (IsString)
  58
+import Control.Monad.Identity
  59
+import Text.Parsec.Text ()
56 60
 
57 61
 -- TODO temporary til restored in Parsing
  62
+applyMacros' :: (Stream s Identity Char, IsString s) => String -> Parser s ParserState String
58 63
 applyMacros' = return
  64
+macro :: (Stream s Identity Char, IsString s) => Parser s ParserState Blocks
59 65
 macro = mzero
  66
+-- TODO temporary til e fix HTML
  67
+htmlTag :: (Stream s Identity Char, IsString s) => (Tag String -> Bool) -> Parser s st (Tag String, String)
  68
+htmlTag _ = mzero
  69
+htmlInBalanced :: (Stream s Identity Char, IsString s) => (Tag String -> Bool) -> Parser s ParserState String
  70
+htmlInBalanced _ = mzero
60 71
 
61 72
 -- | Read markdown from an input string and return a Pandoc document.
62 73
 readMarkdown :: ReaderOptions -- ^ Reader options
63 74
              -> String        -- ^ String to parse (assuming @'\n'@ line endings)
64 75
              -> Pandoc
65 76
 readMarkdown opts s =
66  
-  case runParser parseMarkdown def { stateOptions = opts }
67  
-    (T.pack $ s ++ "\n\n") of
  77
+  case runParser parseMarkdown def { stateOptions = opts } "input"
  78
+        (T.pack $ s ++ "\n\n") of
68 79
           Left err'    -> error $ "\nError:\n" ++ show err'
69 80
           Right result -> result
70 81
 
71  
-type MarkdownParser = Parser Text ParserState
  82
+type MarkdownParser s = Parser s ParserState
72 83
 
73 84
 trimInlinesF :: F Inlines -> F Inlines
74 85
 trimInlinesF = liftM trimInlines
@@ -105,20 +116,20 @@ isBlank _    = False
105 116
 isNull :: F Inlines -> Bool
106 117
 isNull ils = B.isNull $ runF ils def
107 118
 
108  
-spnl :: Parser [Char] st ()
  119
+spnl :: (Stream s Identity Char, IsString s) => Parser s st ()
109 120
 spnl = try $ do
110 121
   skipSpaces
111 122
   optional newline
112 123
   skipSpaces
113 124
   notFollowedBy (char '\n')
114 125
 
115  
-indentSpaces :: MarkdownParser String
  126
+indentSpaces :: (Stream s Identity Char, IsString s) => MarkdownParser s String
116 127
 indentSpaces = try $ do
117 128
   tabStop <- getOption readerTabStop
118 129
   count tabStop (char ' ') <|>
119 130
     string "\t" <?> "indentation"
120 131
 
121  
-nonindentSpaces :: MarkdownParser String
  132
+nonindentSpaces :: (Stream s Identity Char, IsString s) => MarkdownParser s String
122 133
 nonindentSpaces = do
123 134
   tabStop <- getOption readerTabStop
124 135
   sps <- many (char ' ')
@@ -126,27 +137,28 @@ nonindentSpaces = do
126 137
      then return sps
127 138
      else unexpected "indented line"
128 139
 
129  
-skipNonindentSpaces :: MarkdownParser ()
  140
+skipNonindentSpaces :: (Stream s Identity Char, IsString s) => MarkdownParser s ()
130 141
 skipNonindentSpaces = do
131 142
   tabStop <- getOption readerTabStop
132 143
   atMostSpaces (tabStop - 1)
133 144
 
134  
-atMostSpaces :: Int -> MarkdownParser ()
  145
+atMostSpaces :: (Stream s Identity Char, IsString s) => Int -> MarkdownParser s ()
135 146
 atMostSpaces 0 = notFollowedBy (char ' ')
136 147
 atMostSpaces n = (char ' ' >> atMostSpaces (n-1)) <|> return ()
137 148
 
138  
-litChar :: MarkdownParser Char
  149
+litChar :: (Stream s Identity Char, IsString s) => MarkdownParser s Char
139 150
 litChar = escapedChar'
140 151
        <|> noneOf "\n"
141 152
        <|> (newline >> notFollowedBy blankline >> return ' ')
142 153
 
143 154
 -- | Parse a sequence of inline elements between square brackets,
144 155
 -- including inlines between balanced pairs of square brackets.
145  
-inlinesInBalancedBrackets :: MarkdownParser (F Inlines)
  156
+inlinesInBalancedBrackets :: (Stream s Identity Char, IsString s)
  157
+                          => MarkdownParser s (F Inlines)
146 158
 inlinesInBalancedBrackets = charsInBalancedBrackets >>=
147 159
   parseFromString (trimInlinesF . mconcat <$> many inline)
148 160
 
149  
-charsInBalancedBrackets :: MarkdownParser [Char]
  161
+charsInBalancedBrackets :: (Stream s Identity Char, IsString s) => MarkdownParser s [Char]
150 162
 charsInBalancedBrackets = do
151 163
   char '['
152 164
   result <- manyTill (  many1 (noneOf "`[]\n")
@@ -161,7 +173,7 @@ charsInBalancedBrackets = do
161 173
 -- document structure
162 174
 --
163 175
 
164  
-titleLine :: MarkdownParser (F Inlines)
  176
+titleLine :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Inlines)
165 177
 titleLine = try $ do
166 178
   char '%'
167 179
   skipSpaces
@@ -170,7 +182,7 @@ titleLine = try $ do
170 182
   newline
171 183
   return $ trimInlinesF $ mconcat res
172 184
 
173  
-authorsLine :: MarkdownParser (F [Inlines])
  185
+authorsLine :: (Stream s Identity Char, IsString s) => MarkdownParser s (F [Inlines])
174 186
 authorsLine = try $ do
175 187
   char '%'
176 188
   skipSpaces
@@ -181,16 +193,18 @@ authorsLine = try $ do
181 193
   newline
182 194
   return $ sequence $ filter (not . isNull) $ map (trimInlinesF . mconcat) authors
183 195
 
184  
-dateLine :: MarkdownParser (F Inlines)
  196
+dateLine :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Inlines)
185 197
 dateLine = try $ do
186 198
   char '%'
187 199
   skipSpaces
188 200
   trimInlinesF . mconcat <$> manyTill inline newline
189 201
 
190  
-titleBlock :: MarkdownParser (F Inlines, F [Inlines], F Inlines)
  202
+titleBlock :: (Stream s Identity Char, IsString s)
  203
+           => MarkdownParser s (F Inlines, F [Inlines], F Inlines)
191 204
 titleBlock = pandocTitleBlock <|> mmdTitleBlock
192 205
 
193  
-pandocTitleBlock :: MarkdownParser (F Inlines, F [Inlines], F Inlines)
  206
+pandocTitleBlock :: (Stream s Identity Char, IsString s)
  207
+                 => MarkdownParser s (F Inlines, F [Inlines], F Inlines)
194 208
 pandocTitleBlock = try $ do
195 209
   guardEnabled Ext_pandoc_title_block
196 210
   title <- option mempty titleLine
@@ -199,7 +213,8 @@ pandocTitleBlock = try $ do
199 213
   optional blanklines
200 214
   return (title, author, date)
201 215
 
202  
-mmdTitleBlock :: MarkdownParser (F Inlines, F [Inlines], F Inlines)
  216
+mmdTitleBlock :: (Stream s Identity Char, IsString s)
  217
+              => MarkdownParser s (F Inlines, F [Inlines], F Inlines)
203 218
 mmdTitleBlock = try $ do
204 219
   guardEnabled Ext_mmd_title_block
205 220
   kvPairs <- many1 kvPair
@@ -209,7 +224,7 @@ mmdTitleBlock = try $ do
209 224
   let date = maybe mempty return $ lookup "date" kvPairs
210 225
   return (title, author, date)
211 226
 
212  
-kvPair :: MarkdownParser (String, Inlines)
  227
+kvPair :: (Stream s Identity Char, IsString s) => MarkdownParser s (String, Inlines)
213 228
 kvPair = try $ do
214 229
   key <- many1Till (alphaNum <|> oneOf "_- ") (char ':')
215 230
   val <- manyTill anyChar
@@ -218,7 +233,7 @@ kvPair = try $ do
218 233
   let val' = trimInlines $ B.text val
219 234
   return (key',val')
220 235
 
221  
-parseMarkdown :: MarkdownParser Pandoc
  236
+parseMarkdown :: (Stream s Identity Char, IsString s) => MarkdownParser s Pandoc
222 237
 parseMarkdown = do
223 238
   -- markdown allows raw HTML
224 239
   updateState $ \state -> state { stateOptions =
@@ -232,7 +247,7 @@ parseMarkdown = do
232 247
          $ B.setDate (runF date st)
233 248
          $ B.doc $ runF blocks st
234 249
 
235  
-referenceKey :: MarkdownParser (F Blocks)
  250
+referenceKey :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Blocks)
236 251
 referenceKey = try $ do
237 252
   skipNonindentSpaces
238 253
   (_,raw) <- reference
@@ -256,7 +271,7 @@ referenceKey = try $ do
256 271
   updateState $ \s -> s { stateKeys = M.insert (toKey raw) target oldkeys }
257 272
   return $ return mempty
258 273
 
259  
-referenceTitle :: MarkdownParser String
  274
+referenceTitle :: (Stream s Identity Char, IsString s) => MarkdownParser s String
260 275
 referenceTitle = try $ do
261 276
   skipSpaces >> optional newline >> skipSpaces
262 277
   tit <-    (charsInBalanced '(' ')' litChar >>= return . unwords . words)
@@ -268,7 +283,7 @@ referenceTitle = try $ do
268 283
 -- | PHP Markdown Extra style abbreviation key.  Currently
269 284
 -- we just skip them, since Pandoc doesn't have an element for
270 285
 -- an abbreviation.
271  
-abbrevKey :: MarkdownParser (F Blocks)
  286
+abbrevKey :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Blocks)
272 287
 abbrevKey = do
273 288
   guardEnabled Ext_abbreviations
274 289
   try $ do
@@ -279,23 +294,23 @@ abbrevKey = do
279 294
     blanklines
280 295
     return $ return mempty
281 296
 
282  
-noteMarker :: MarkdownParser String
  297
+noteMarker :: (Stream s Identity Char, IsString s) => MarkdownParser s String
283 298
 noteMarker = string "[^" >> many1Till (satisfy $ not . isBlank) (char ']')
284 299
 
285  
-rawLine :: MarkdownParser String
  300
+rawLine :: (Stream s Identity Char, IsString s) => MarkdownParser s String
286 301
 rawLine = try $ do
287 302
   notFollowedBy blankline
288 303
   notFollowedBy' $ try $ skipNonindentSpaces >> noteMarker
289 304
   optional indentSpaces
290 305
   anyLine
291 306
 
292  
-rawLines :: MarkdownParser String
  307
+rawLines :: (Stream s Identity Char, IsString s) => MarkdownParser s String
293 308
 rawLines = do
294 309
   first <- anyLine
295 310
   rest <- many rawLine
296 311
   return $ unlines (first:rest)
297 312
 
298  
-noteBlock :: MarkdownParser (F Blocks)
  313
+noteBlock :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Blocks)
299 314
 noteBlock = try $ do
300 315
   skipNonindentSpaces
301 316
   ref <- noteMarker
@@ -315,10 +330,10 @@ noteBlock = try $ do
315 330
 -- parsing blocks
316 331
 --
317 332
 
318  
-parseBlocks :: MarkdownParser (F Blocks)
  333
+parseBlocks :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Blocks)
319 334
 parseBlocks = mconcat <$> manyTill block eof
320 335
 
321  
-block :: MarkdownParser (F Blocks)
  336
+block :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Blocks)
322 337
 block = choice [ codeBlockFenced
323 338
                , codeBlockBackticks
324 339
                , guardEnabled Ext_latex_macros *> (mempty <$ macro)
@@ -344,10 +359,10 @@ block = choice [ codeBlockFenced
344 359
 -- header blocks
345 360
 --
346 361
 
347  
-header :: MarkdownParser (F Blocks)
  362
+header :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Blocks)
348 363
 header = setextHeader <|> atxHeader <?> "header"
349 364
 
350  
-atxHeader :: MarkdownParser (F Blocks)
  365
+atxHeader :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Blocks)
351 366
 atxHeader = try $ do
352 367
   level <- many1 (char '#') >>= return . length
353 368
   notFollowedBy (char '.' <|> char ')') -- this would be a list
@@ -355,10 +370,10 @@ atxHeader = try $ do
355 370
   text <- trimInlinesF . mconcat <$> manyTill inline atxClosing
356 371
   return $ B.header level <$> text
357 372
 
358  
-atxClosing :: Parser [Char] st String
  373
+atxClosing :: (Stream s Identity Char, IsString s) => Parser s st String
359 374
 atxClosing = try $ skipMany (char '#') >> blanklines
360 375
 
361  
-setextHeader :: MarkdownParser (F Blocks)
  376
+setextHeader :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Blocks)
362 377
 setextHeader = try $ do
363 378
   -- This lookahead prevents us from wasting time parsing Inlines
364 379
   -- unless necessary -- it gives a significant performance boost.
@@ -374,7 +389,7 @@ setextHeader = try $ do
374 389
 -- hrule block
375 390
 --
376 391
 
377  
-hrule :: Parser [Char] st (F Blocks)
  392
+hrule :: (Stream s Identity Char, IsString s) => Parser s st (F Blocks)
378 393
 hrule = try $ do
379 394
   skipSpaces
380 395
   start <- satisfy isHruleChar
@@ -388,12 +403,13 @@ hrule = try $ do
388 403
 -- code blocks
389 404
 --
390 405
 
391  
-indentedLine :: MarkdownParser String
  406
+indentedLine :: (Stream s Identity Char, IsString s) => MarkdownParser s String
392 407
 indentedLine = indentSpaces >> manyTill anyChar newline >>= return . (++ "\n")
393 408
 
394  
-blockDelimiter :: (Char -> Bool)
  409
+blockDelimiter :: (Stream s Identity Char, IsString s)
  410
+               => (Char -> Bool)
395 411
                -> Maybe Int
396  
-               -> Parser [Char] st Int
  412
+               -> Parser s st Int
397 413
 blockDelimiter f len = try $ do
398 414
   c <- lookAhead (satisfy f)
399 415
   case len of
@@ -401,7 +417,8 @@ blockDelimiter f len = try $ do
401 417
       Nothing -> count 3 (char c) >> many (char c) >>=
402 418
                  return . (+ 3) . length
403 419
 
404  
-attributes :: Parser [Char] st (String, [String], [(String, String)])
  420
+attributes :: (Stream s Identity Char, IsString s)
  421
+           => Parser s st (String, [String], [(String, String)])
405 422
 attributes = try $ do
406 423
   char '{'
407 424
   spnl
@@ -413,28 +430,30 @@ attributes = try $ do
413 430
                           | otherwise    = firstNonNull xs
414 431
   return (firstNonNull $ reverse ids, concat classes, concat keyvals)
415 432
 
416  
-attribute :: Parser [Char] st (String, [String], [(String, String)])
  433
+attribute :: (Stream s Identity Char, IsString s)
  434
+          => Parser s st (String, [String], [(String, String)])
417 435
 attribute = identifierAttr <|> classAttr <|> keyValAttr
418 436
 
419  
-identifier :: Parser [Char] st String
  437
+identifier :: (Stream s Identity Char, IsString s) => Parser s st String
420 438
 identifier = do
421 439
   first <- letter
422 440
   rest <- many $ alphaNum <|> oneOf "-_:."
423 441
   return (first:rest)
424 442
 
425  
-identifierAttr :: Parser [Char] st (String, [a], [a1])
  443
+identifierAttr :: (Stream s Identity Char, IsString s) => Parser s st (String, [a], [a1])
426 444
 identifierAttr = try $ do
427 445
   char '#'
428 446
   result <- identifier
429 447
   return (result,[],[])
430 448
 
431  
-classAttr :: Parser [Char] st (String, [String], [a])
  449
+classAttr :: (Stream s Identity Char, IsString s) => Parser s st (String, [String], [a])
432 450
 classAttr = try $ do
433 451
   char '.'
434 452
   result <- identifier
435 453
   return ("",[result],[])
436 454
 
437  
-keyValAttr :: Parser [Char] st (String, [a], [(String, String)])
  455
+keyValAttr :: (Stream s Identity Char, IsString s)
  456
+           => Parser s st (String, [a], [(String, String)])
438 457
 keyValAttr = try $ do
439 458
   key <- identifier
440 459
   char '='
@@ -443,7 +462,7 @@ keyValAttr = try $ do
443 462
      <|> many nonspaceChar
444 463
   return ("",[],[(key,val)])
445 464
 
446  
-codeBlockFenced :: MarkdownParser (F Blocks)
  465
+codeBlockFenced :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Blocks)
447 466
 codeBlockFenced = try $ do
448 467
   guardEnabled Ext_fenced_code_blocks
449 468
   size <- blockDelimiter (=='~') Nothing
@@ -455,7 +474,7 @@ codeBlockFenced = try $ do
455 474
   blanklines
456 475
   return $ return $ B.codeBlockWith attr $ intercalate "\n" contents
457 476
 
458  
-codeBlockBackticks :: MarkdownParser (F Blocks)
  477
+codeBlockBackticks :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Blocks)
459 478
 codeBlockBackticks = try $ do
460 479
   guardEnabled Ext_backtick_code_blocks
461 480
   blockDelimiter (=='`') (Just 3)
@@ -466,7 +485,7 @@ codeBlockBackticks = try $ do
466 485
   blanklines
467 486
   return $ return $ B.codeBlockWith ("",[cls],[]) $ intercalate "\n" contents
468 487
 
469  
-codeBlockIndented :: MarkdownParser (F Blocks)
  488
+codeBlockIndented :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Blocks)
470 489
 codeBlockIndented = do
471 490
   contents <- many1 (indentedLine <|>
472 491
                      try (do b <- blanklines
@@ -477,7 +496,7 @@ codeBlockIndented = do
477 496
   return $ return $ B.codeBlockWith ("", classes, []) $
478 497
            stripTrailingNewlines $ concat contents
479 498
 
480  
-lhsCodeBlock :: MarkdownParser (F Blocks)
  499
+lhsCodeBlock :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Blocks)
481 500
 lhsCodeBlock = do
482 501
   guardEnabled Ext_literate_haskell
483 502
   (return . B.codeBlockWith ("",["sourceCode","literate","haskell"],[]) <$>
@@ -485,7 +504,7 @@ lhsCodeBlock = do
485 504
     <|> (return . B.codeBlockWith ("",["sourceCode","haskell"],[]) <$>
486 505
           lhsCodeBlockInverseBird)
487 506
 
488  
-lhsCodeBlockLaTeX :: MarkdownParser String
  507
+lhsCodeBlockLaTeX :: (Stream s Identity Char, IsString s) => MarkdownParser s String
489 508
 lhsCodeBlockLaTeX = try $ do
490 509
   string "\\begin{code}"
491 510
   manyTill spaceChar newline
@@ -493,13 +512,14 @@ lhsCodeBlockLaTeX = try $ do
493 512
   blanklines
494 513
   return $ stripTrailingNewlines contents
495 514
 
496  
-lhsCodeBlockBird :: MarkdownParser String
  515
+lhsCodeBlockBird :: (Stream s Identity Char, IsString s) => MarkdownParser s String
497 516
 lhsCodeBlockBird = lhsCodeBlockBirdWith '>'
498 517
 
499  
-lhsCodeBlockInverseBird :: MarkdownParser String
  518
+lhsCodeBlockInverseBird :: (Stream s Identity Char, IsString s) => MarkdownParser s String
500 519
 lhsCodeBlockInverseBird = lhsCodeBlockBirdWith '<'
501 520
 
502  
-lhsCodeBlockBirdWith :: Char -> MarkdownParser String
  521
+lhsCodeBlockBirdWith :: Char -> (Stream s Identity Char, IsString s)
  522
+                     => MarkdownParser s String
503 523
 lhsCodeBlockBirdWith c = try $ do
504 524
   pos <- getPosition
505 525
   when (sourceColumn pos /= 1) $ fail "Not in first column"
@@ -511,7 +531,7 @@ lhsCodeBlockBirdWith c = try $ do
511 531
   blanklines
512 532
   return $ intercalate "\n" lns'
513 533
 
514  
-birdTrackLine :: Char -> Parser [Char] st String
  534
+birdTrackLine :: (Stream s Identity Char, IsString s) => Char -> Parser s st String
515 535
 birdTrackLine c = try $ do
516 536
   char c
517 537
   -- allow html tags on left margin:
@@ -522,10 +542,10 @@ birdTrackLine c = try $ do
522 542
 -- block quotes
523 543
 --
524 544
 
525  
-emailBlockQuoteStart :: MarkdownParser Char
  545
+emailBlockQuoteStart :: (Stream s Identity Char, IsString s) => MarkdownParser s Char
526 546
 emailBlockQuoteStart = try $ skipNonindentSpaces >> char '>' >>~ optional (char ' ')
527 547
 
528  
-emailBlockQuote :: MarkdownParser [String]
  548
+emailBlockQuote :: (Stream s Identity Char, IsString s) => MarkdownParser s [String]
529 549
 emailBlockQuote = try $ do
530 550
   emailBlockQuoteStart
531 551
   raw <- sepBy (many (nonEndline <|>
@@ -536,7 +556,7 @@ emailBlockQuote = try $ do
536 556
   optional blanklines
537 557
   return raw
538 558
 
539  
-blockQuote :: MarkdownParser (F Blocks)
  559
+blockQuote :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Blocks)
540 560
 blockQuote = do
541 561
   raw <- emailBlockQuote
542 562
   -- parse the extracted block, which may contain various block elements:
@@ -547,7 +567,7 @@ blockQuote = do
547 567
 -- list blocks
548 568
 --
549 569
 
550  
-bulletListStart :: MarkdownParser ()
  570
+bulletListStart :: (Stream s Identity Char, IsString s) => MarkdownParser s ()
551 571
 bulletListStart = try $ do
552 572
   optional newline -- if preceded by a Plain block in a list context
553 573
   skipNonindentSpaces
@@ -556,7 +576,8 @@ bulletListStart = try $ do
556 576
   spaceChar
557 577
   skipSpaces
558 578
 
559  
-anyOrderedListStart :: MarkdownParser (Int, ListNumberStyle, ListNumberDelim)
  579
+anyOrderedListStart :: (Stream s Identity Char, IsString s)
  580
+                    => MarkdownParser s (Int, ListNumberStyle, ListNumberDelim)
560 581
 anyOrderedListStart = try $ do
561 582
   optional newline -- if preceded by a Plain block in a list context
562 583
   skipNonindentSpaces
@@ -575,11 +596,11 @@ anyOrderedListStart = try $ do
575 596
           skipSpaces
576 597
           return (num, style, delim)
577 598
 
578  
-listStart :: MarkdownParser ()
  599
+listStart :: (Stream s Identity Char, IsString s) => MarkdownParser s ()
579 600
 listStart = bulletListStart <|> (anyOrderedListStart >> return ())
580 601
 
581 602
 -- parse a line of a list item (start = parser for beginning of list item)
582  
-listLine :: MarkdownParser String
  603
+listLine :: (Stream s Identity Char, IsString s) => MarkdownParser s String
583 604
 listLine = try $ do
584 605
   notFollowedBy blankline
585 606
   notFollowedBy' (do indentSpaces
@@ -589,8 +610,9 @@ listLine = try $ do
589 610
   return $ concat chunks ++ "\n"
590 611
 
591 612
 -- parse raw text for one list item, excluding start marker and continuations
592  
-rawListItem :: MarkdownParser a
593  
-            -> MarkdownParser String
  613
+rawListItem :: (Stream s Identity Char, IsString s)
  614
+            => MarkdownParser s a
  615
+            -> MarkdownParser s String
594 616
 rawListItem start = try $ do
595 617
   start
596 618
   first <- listLine
@@ -601,23 +623,24 @@ rawListItem start = try $ do
601 623
 -- continuation of a list item - indented and separated by blankline
602 624
 -- or (in compact lists) endline.
603 625
 -- note: nested lists are parsed as continuations
604  
-listContinuation :: MarkdownParser String
  626
+listContinuation :: (Stream s Identity Char, IsString s) => MarkdownParser s String
605 627
 listContinuation = try $ do
606 628
   lookAhead indentSpaces
607 629
   result <- many1 listContinuationLine
608 630
   blanks <- many blankline
609 631
   return $ concat result ++ blanks
610 632
 
611  
-listContinuationLine :: MarkdownParser String
  633
+listContinuationLine :: (Stream s Identity Char, IsString s) => MarkdownParser s String
612 634
 listContinuationLine = try $ do
613 635
   notFollowedBy blankline
614  
-  notFollowedBy' listStart
  636
+  notFollowedBy listStart
615 637
   optional indentSpaces
616 638
   result <- manyTill anyChar newline
617 639
   return $ result ++ "\n"
618 640
 
619  
-listItem :: MarkdownParser a
620  
-         -> MarkdownParser (F Blocks)
  641
+listItem :: (Stream s Identity Char, IsString s)
  642
+         => MarkdownParser s a
  643
+         -> MarkdownParser s (F Blocks)
621 644
 listItem start = try $ do
622 645
   first <- rawListItem start
623 646
   continuations <- many listContinuation
@@ -633,7 +656,7 @@ listItem start = try $ do
633 656
   updateState (\st -> st {stateParserContext = oldContext})
634 657
   return contents
635 658
 
636  
-orderedList :: MarkdownParser (F Blocks)
  659
+orderedList :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Blocks)
637 660
 orderedList = try $ do
638 661
   (start, style, delim) <- lookAhead anyOrderedListStart
639 662
   unless ((style == DefaultStyle || style == Decimal || style == Example) &&
@@ -662,14 +685,14 @@ compactify items =
662 685
                             _   -> items
663 686
            _      -> items
664 687
 
665  
-bulletList :: MarkdownParser (F Blocks)
  688
+bulletList :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Blocks)
666 689
 bulletList = do
667 690
   items <- fmap sequence $ many1 $ listItem  bulletListStart
668 691
   return $ B.bulletList <$> fmap compactify items
669 692
 
670 693
 -- definition lists
671 694
 
672  
-defListMarker :: MarkdownParser ()
  695
+defListMarker :: (Stream s Identity Char, IsString s) => MarkdownParser s ()
673 696
 defListMarker = do
674 697
   sps <- nonindentSpaces
675 698
   char ':' <|> char '~'
@@ -680,7 +703,8 @@ defListMarker = do
680 703
      else mzero
681 704
   return ()
682 705
 
683  
-definitionListItem :: MarkdownParser (F (Inlines, [Blocks]))
  706
+definitionListItem :: (Stream s Identity Char, IsString s)
  707
+                   => MarkdownParser s (F (Inlines, [Blocks]))
684 708
 definitionListItem = try $ do
685 709
   guardEnabled Ext_definition_lists
686 710
   -- first, see if this has any chance of being a definition list:
@@ -695,7 +719,7 @@ definitionListItem = try $ do
695 719
   updateState (\st -> st {stateParserContext = oldContext})
696 720
   return $ liftM2 (,) term (sequence contents)
697 721
 
698  
-defRawBlock :: MarkdownParser String
  722
+defRawBlock :: (Stream s Identity Char, IsString s) => MarkdownParser s String
699 723
 defRawBlock = try $ do
700 724
   defListMarker
701 725
   firstline <- anyLine
@@ -707,7 +731,7 @@ defRawBlock = try $ do
707 731
             return $ unlines lns ++ trl
708 732
   return $ firstline ++ "\n" ++ unlines rawlines ++ trailing ++ cont
709 733
 
710  
-definitionList :: MarkdownParser (F Blocks)
  734
+definitionList :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Blocks)
711 735
 definitionList = do
712 736
   items <- fmap sequence $ many1 definitionListItem
713 737
   return $ B.definitionList <$> fmap compactifyDL items
@@ -740,7 +764,7 @@ isHtmlOrBlank (LineBreak)     = True
740 764
 isHtmlOrBlank _               = False
741 765
 -}
742 766
 
743  
-para :: MarkdownParser (F Blocks)
  767
+para :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Blocks)
744 768
 para = try $ do
745 769
   result <- trimInlinesF . mconcat <$> many1 inline
746 770
   -- TODO remove this if not really needed?  and remove isHtmlOrBlank
@@ -752,34 +776,34 @@ para = try $ do
752 776
                 <|> (guardDisabled Ext_blank_before_header >> lookAhead header)
753 777
               return $ B.para <$> result
754 778
 
755  
-plain :: MarkdownParser (F Blocks)
  779
+plain :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Blocks)
756 780
 plain = fmap B.plain . trimInlinesF . mconcat <$> many1 inline <* spaces
757 781
 
758 782
 --
759 783
 -- raw html
760 784
 --
761 785
 
762  
-htmlElement :: MarkdownParser String
  786
+htmlElement :: (Stream s Identity Char, IsString s) => MarkdownParser s String
763 787
 htmlElement = strictHtmlBlock <|> liftM snd (htmlTag isBlockTag)
764 788
 
765  
-htmlBlock :: MarkdownParser (F Blocks)
  789
+htmlBlock :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Blocks)
766 790
 htmlBlock = do
767 791
   guardEnabled Ext_raw_html
768 792
   res <- (guardEnabled Ext_markdown_in_html_blocks >> rawHtmlBlocks)
769 793
           <|> htmlBlock'
770 794
   return $ return $ B.rawBlock "html" res
771 795
 
772  
-htmlBlock' :: MarkdownParser String
  796
+htmlBlock' :: (Stream s Identity Char, IsString s) => MarkdownParser s String
773 797
 htmlBlock' = try $ do
774 798
     first <- htmlElement
775 799
     finalSpace <- many spaceChar
776 800
     finalNewlines <- many newline
777 801
     return $ first ++ finalSpace ++ finalNewlines
778 802
 
779  
-strictHtmlBlock :: MarkdownParser String
  803
+strictHtmlBlock :: (Stream s Identity Char, IsString s) => MarkdownParser s String
780 804
 strictHtmlBlock = htmlInBalanced (not . isInlineTag)
781 805
 
782  
-rawVerbatimBlock :: MarkdownParser String
  806
+rawVerbatimBlock :: (Stream s Identity Char, IsString s) => MarkdownParser s String
783 807
 rawVerbatimBlock = try $ do
784 808
   (TagOpen tag _, open) <- htmlTag (tagOpen (\t ->
785 809
                               t == "pre" || t == "style" || t == "script")
@@ -787,15 +811,15 @@ rawVerbatimBlock = try $ do
787 811
   contents <- manyTill anyChar (htmlTag (~== TagClose tag))
788 812
   return $ open ++ contents ++ renderTags [TagClose tag]
789 813
 
790  
-rawTeXBlock :: MarkdownParser (F Blocks)
  814
+rawTeXBlock :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Blocks)
791 815
 rawTeXBlock = do
792 816
   guardEnabled Ext_raw_tex
793  
-  result <- (B.rawBlock "latex" <$> rawLaTeXBlock)
794  
-        <|> (B.rawBlock "context" <$> rawConTeXtEnvironment)
  817
+  result <- (B.rawBlock "latex" <$> mzero {- TODO rawLaTeXBlock -})
  818
+        <|> (B.rawBlock "context" <$> mzero {- TODO rawConTeXtEnvironment -})
795 819
   spaces
796 820
   return $ return result
797 821
 
798  
-rawHtmlBlocks :: MarkdownParser String
  822
+rawHtmlBlocks :: (Stream s Identity Char, IsString s) => MarkdownParser s String
799 823
 rawHtmlBlocks = do
800 824
   htmlBlocks <- many1 $ try $ do
801 825
                           s <- rawVerbatimBlock <|> try (
@@ -839,8 +863,9 @@ stripMarkdownAttribute s = renderTags' $ map filterAttrib $ parseTags s
839 863
 
840 864
 -- Parse a dashed line with optional trailing spaces; return its length
841 865
 -- and the length including trailing space.
842  
-dashedLine :: Char
843  
-           -> Parser [Char] st (Int, Int)
  866
+dashedLine :: (Stream s Identity Char, IsString s)
  867
+           => Char
  868
+           -> Parser s st (Int, Int)
844 869
 dashedLine ch = do
845 870
   dashes <- many1 (char ch)
846 871
   sp     <- many spaceChar
@@ -849,7 +874,8 @@ dashedLine ch = do
849 874
 -- Parse a table header with dashed lines of '-' preceded by
850 875
 -- one (or zero) line of text.
851 876
 simpleTableHeader :: Bool  -- ^ Headerless table
852  
-                  -> MarkdownParser (F [Blocks], [Alignment], [Int])
  877
+                  -> (Stream s Identity Char, IsString s)
  878
+                  => MarkdownParser s (F [Blocks], [Alignment], [Int])
853 879
 simpleTableHeader headless = try $ do
854 880
   rawContent  <- if headless
855 881
                     then return ""
@@ -893,16 +919,17 @@ alignType strLst len =
893 919
         (False, False)   -> AlignDefault
894 920
 
895 921
 -- Parse a table footer - dashed lines followed by blank line.
896  
-tableFooter :: MarkdownParser String
  922
+tableFooter :: (Stream s Identity Char, IsString s) => MarkdownParser s String
897 923
 tableFooter = try $ skipNonindentSpaces >> many1 (dashedLine '-') >> blanklines
898 924
 
899 925
 -- Parse a table separator - dashed line.
900  
-tableSep :: MarkdownParser Char
  926
+tableSep :: (Stream s Identity Char, IsString s) => MarkdownParser s Char
901 927
 tableSep = try $ skipNonindentSpaces >> many1 (dashedLine '-') >> char '\n'
902 928
 
903 929
 -- Parse a raw line and split it into chunks by indices.
904  
-rawTableLine :: [Int]
905  
-             -> MarkdownParser [String]
  930
+rawTableLine :: (Stream s Identity Char, IsString s)
  931
+             => [Int]
  932
+             -> MarkdownParser s [String]
906 933
 rawTableLine indices = do
907 934
   notFollowedBy' (blanklines <|> tableFooter)
908 935
   line <- many1Till anyChar newline
@@ -910,14 +937,16 @@ rawTableLine indices = do
910 937
            splitStringByIndices (init indices) line
911 938
 
912 939
 -- Parse a table line and return a list of lists of blocks (columns).
913  
-tableLine :: [Int]
914  
-          -> MarkdownParser (F [Blocks])
  940
+tableLine :: (Stream s Identity Char, IsString s)
  941
+          => [Int]
  942
+          -> MarkdownParser s (F [Blocks])
915 943
 tableLine indices = rawTableLine indices >>=
916 944
   fmap sequence . mapM (parseFromString (mconcat <$> many plain))
917 945
 
918 946
 -- Parse a multiline table row and return a list of blocks (columns).
919  
-multilineRow :: [Int]
920  
-             -> MarkdownParser (F [Blocks])
  947
+multilineRow :: (Stream s Identity Char, IsString s)
  948
+             => [Int]
  949
+             -> MarkdownParser s (F [Blocks])
921 950
 multilineRow indices = do
922 951
   colLines <- many1 (rawTableLine indices)
923 952
   let cols = map unlines $ transpose colLines
@@ -925,7 +954,7 @@ multilineRow indices = do
925 954
 
926 955
 -- Parses a table caption:  inlines beginning with 'Table:'
927 956
 -- and followed by blank lines.
928  
-tableCaption :: MarkdownParser (F Inlines)
  957
+tableCaption :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Inlines)
929 958
 tableCaption = try $ do
930 959
   guardEnabled Ext_table_captions
931 960
   skipNonindentSpaces
@@ -933,8 +962,9 @@ tableCaption = try $ do
933 962
   trimInlinesF . mconcat <$> many1 inline <* blanklines
934 963
 
935 964
 -- Parse a simple table with '---' header and one line per row.
936  
-simpleTable :: Bool  -- ^ Headerless table
937  
-            -> MarkdownParser ([Alignment], [Double], F [Blocks], F [[Blocks]])
  965
+simpleTable :: (Stream s Identity Char, IsString s)
  966
+            => Bool  -- ^ Headerless table
  967
+            -> MarkdownParser s ([Alignment], [Double], F [Blocks], F [[Blocks]])
938 968
 simpleTable headless = do
939 969
   (aligns, _widths, heads', lines') <-
940 970
        tableWith (simpleTableHeader headless) tableLine
@@ -947,13 +977,15 @@ simpleTable headless = do
947 977
 -- (which may be multiline), then the rows,
948 978
 -- which may be multiline, separated by blank lines, and
949 979
 -- ending with a footer (dashed line followed by blank line).
950  
-multilineTable :: Bool -- ^ Headerless table
951  
-               -> MarkdownParser ([Alignment], [Double], F [Blocks], F [[Blocks]])
  980
+multilineTable :: (Stream s Identity Char, IsString s)
  981
+               => Bool -- ^ Headerless table
  982
+               -> MarkdownParser s ([Alignment], [Double], F [Blocks], F [[Blocks]])
952 983
 multilineTable headless =
953 984
   tableWith (multilineTableHeader headless) multilineRow blanklines tableFooter
954 985
 
955  
-multilineTableHeader :: Bool -- ^ Headerless table
956  
-                     -> MarkdownParser (F [Blocks], [Alignment], [Int])
  986
+multilineTableHeader :: (Stream s Identity Char, IsString s)
  987
+                     => Bool -- ^ Headerless table
  988
+                     -> MarkdownParser s (F [Blocks], [Alignment], [Int])
957 989
 multilineTableHeader headless = try $ do
958 990
   if headless
959 991
      then return '\n'
@@ -986,8 +1018,9 @@ multilineTableHeader headless = try $ do
986 1018
 -- (which may be grid), then the rows,
987 1019
 -- which may be grid, separated by blank lines, and
988 1020
 -- ending with a footer (dashed line followed by blank line).
989  
-gridTable :: Bool -- ^ Headerless table
990  
-          -> MarkdownParser ([Alignment], [Double], F [Blocks], F [[Blocks]])
  1021
+gridTable :: (Stream s Identity Char, IsString s)
  1022
+          => Bool -- ^ Headerless table
  1023
+          -> MarkdownParser s ([Alignment], [Double], F [Blocks], F [[Blocks]])
991 1024
 gridTable headless =
992 1025
   tableWith (gridTableHeader headless) gridTableRow
993 1026
             (gridTableSep '-') gridTableFooter
@@ -996,13 +1029,13 @@ gridTableSplitLine :: [Int] -> String -> [String]
996 1029
 gridTableSplitLine indices line = map removeFinalBar $ tail $
997 1030
   splitStringByIndices (init indices) $ removeTrailingSpace line
998 1031
 
999  
-gridPart :: Char -> Parser [Char] st (Int, Int)
  1032
+gridPart :: (Stream s Identity Char, IsString s) => Char -> Parser s st (Int, Int)
1000 1033
 gridPart ch = do
1001 1034
   dashes <- many1 (char ch)
1002 1035
   char '+'
1003 1036
   return (length dashes, length dashes + 1)
1004 1037
 
1005  
-gridDashedLines :: Char -> Parser [Char] st [(Int,Int)]
  1038
+gridDashedLines :: (Stream s Identity Char, IsString s) => Char -> Parser s st [(Int,Int)]
1006 1039
 gridDashedLines ch = try $ char '+' >> many1 (gridPart ch) >>~ blankline
1007 1040
 
1008 1041
 removeFinalBar :: String -> String
@@ -1010,12 +1043,13 @@ removeFinalBar =
1010 1043
   reverse . dropWhile (`elem` " \t") . dropWhile (=='|') . reverse
1011 1044
 
1012 1045
 -- | Separator between rows of grid table.
1013  
-gridTableSep :: Char -> MarkdownParser Char
  1046
+gridTableSep :: (Stream s Identity Char, IsString s) => Char -> MarkdownParser s Char
1014 1047
 gridTableSep ch = try $ gridDashedLines ch >> return '\n'
1015 1048
 
1016 1049
 -- | Parse header for a grid table.
1017  
-gridTableHeader :: Bool -- ^ Headerless table
1018  
-                -> MarkdownParser (F [Blocks], [Alignment], [Int])
  1050
+gridTableHeader :: (Stream s Identity Char, IsString s)
  1051
+                => Bool -- ^ Headerless table
  1052
+                -> MarkdownParser s (F [Blocks], [Alignment], [Int])
1019 1053
 gridTableHeader headless = try $ do
1020 1054
   optional blanklines
1021 1055
   dashes <- gridDashedLines '-'
@@ -1039,15 +1073,16 @@ gridTableHeader headless = try $ do
1039 1073
                map removeLeadingTrailingSpace rawHeads
1040 1074
   return (heads, aligns, indices)
1041 1075
 
1042  
-gridTableRawLine :: [Int] -> MarkdownParser [String]
  1076
+gridTableRawLine :: (Stream s Identity Char, IsString s) => [Int] -> MarkdownParser s [String]
1043 1077
 gridTableRawLine indices = do
1044 1078
   char '|'
1045 1079
   line <- many1Till anyChar newline
1046 1080
   return (gridTableSplitLine indices line)
1047 1081
 
1048 1082
 -- | Parse row of grid table.
1049  
-gridTableRow :: [Int]
1050  
-             -> MarkdownParser (F [Blocks])
  1083
+gridTableRow :: (Stream s Identity Char, IsString s)
  1084
+             => [Int]
  1085
+             -> MarkdownParser s (F [Blocks])
1051 1086
 gridTableRow indices = do
1052 1087
   colLines <- many1 (gridTableRawLine indices)
1053 1088
   let cols = map ((++ "\n") . unlines . removeOneLeadingSpace) $
@@ -1063,10 +1098,11 @@ removeOneLeadingSpace xs =
1063 1098
          startsWithSpace (y:_) = y == ' '
1064 1099
 
1065 1100
 -- | Parse footer for a grid table.
1066  
-gridTableFooter :: MarkdownParser [Char]
  1101
+gridTableFooter :: (Stream s Identity Char, IsString s) => MarkdownParser s [Char]
1067 1102
 gridTableFooter = blanklines
1068 1103
 
1069  
-pipeTable :: MarkdownParser ([Alignment], [Double], F [Blocks], F [[Blocks]])
  1104
+pipeTable :: (Stream s Identity Char, IsString s)
  1105
+          => MarkdownParser s ([Alignment], [Double], F [Blocks], F [[Blocks]])
1070 1106
 pipeTable = try $ do
1071 1107
   let pipeBreak = nonindentSpaces *> optional (char '|') *>
1072 1108
                       pipeTableHeaderPart `sepBy1` sepPipe <*
@@ -1081,13 +1117,13 @@ pipeTable = try $ do
1081 1117
   let widths = replicate (length aligns) 0.0
1082 1118
   return $ (aligns, widths, heads, lines')
1083 1119
 
1084  
-sepPipe :: MarkdownParser ()
  1120
+sepPipe :: (Stream s Identity Char, IsString s) => MarkdownParser s ()
1085 1121
 sepPipe = try $ do
1086 1122
   char '|' <|> char '+'
1087 1123
   notFollowedBy blankline
1088 1124
 
1089 1125
 -- parse a row, also returning probable alignments for org-table cells
1090  
-pipeTableRow :: MarkdownParser (F [Blocks])
  1126
+pipeTableRow :: (Stream s Identity Char, IsString s) => MarkdownParser s (F [Blocks])
1091 1127
 pipeTableRow = do
1092 1128
   nonindentSpaces
1093 1129
   optional (char '|')
@@ -1107,7 +1143,7 @@ pipeTableRow = do
1107 1143
                  ils' | B.isNull ils' -> mempty
1108 1144
                       | otherwise   -> B.plain $ ils') cells'
1109 1145
 
1110  
-pipeTableHeaderPart :: Parser [Char] st Alignment
  1146
+pipeTableHeaderPart :: (Stream s Identity Char, IsString s) => Parser s st Alignment
1111 1147
 pipeTableHeaderPart = do
1112 1148
   left <- optionMaybe (char ':')
1113 1149
   many1 (char '-')
@@ -1120,17 +1156,18 @@ pipeTableHeaderPart = do
1120 1156
       (Just _,Just _)   -> AlignCenter
1121 1157
 
1122 1158
 -- Succeed only if current line contains a pipe.
1123  
-scanForPipe :: Parser [Char] st ()
  1159
+scanForPipe :: (Stream s Identity Char, IsString s) => Parser s st ()
1124 1160
 scanForPipe = lookAhead (manyTill (satisfy (/='\n')) (char '|')) >> return ()
1125 1161
 
1126 1162
 -- | Parse a table using 'headerParser', 'rowParser',
1127 1163
 -- 'lineParser', and 'footerParser'.  Variant of the version in
1128 1164
 -- Text.Pandoc.Parsing.
1129  
-tableWith :: MarkdownParser (F [Blocks], [Alignment], [Int])
1130  
-          -> ([Int] -> MarkdownParser (F [Blocks]))
1131  
-          -> MarkdownParser sep
1132  
-          -> MarkdownParser end
1133  
-          -> MarkdownParser ([Alignment], [Double], F [Blocks], F [[Blocks]])
  1165
+tableWith :: (Stream s Identity Char, IsString s)
  1166
+          => MarkdownParser s (F [Blocks], [Alignment], [Int])
  1167
+          -> ([Int] -> MarkdownParser s (F [Blocks]))
  1168
+          -> MarkdownParser s sep
  1169
+          -> MarkdownParser s end
  1170
+          -> MarkdownParser s ([Alignment], [Double], F [Blocks], F [[Blocks]])
1134 1171
 tableWith headerParser rowParser lineParser footerParser = try $ do
1135 1172
     (heads, aligns, indices) <- headerParser
1136 1173
     lines' <- fmap sequence $ rowParser indices `sepEndBy1` lineParser
@@ -1141,7 +1178,7 @@ tableWith headerParser rowParser lineParser footerParser = try $ do
1141 1178
                     else widthsFromIndices numColumns indices
1142 1179
     return $ (aligns, widths, heads, lines')
1143 1180
 
1144  
-table :: MarkdownParser (F Blocks)
  1181
+table :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Blocks)
1145 1182
 table = try $ do
1146 1183
   frontCaption <- option Nothing (Just <$> tableCaption)
1147 1184
   (aligns, widths, heads, lns) <-
@@ -1168,7 +1205,7 @@ table = try $ do
1168 1205
 -- inline
1169 1206
 --
1170 1207
 
1171  
-inline :: MarkdownParser (F Inlines)
  1208
+inline :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Inlines)
1172 1209
 inline = choice [ whitespace
1173 1210
                 , str
1174 1211
                 , endline
@@ -1196,13 +1233,13 @@ inline = choice [ whitespace
1196 1233
                 , ltSign
1197 1234
                 ] <?> "inline"
1198 1235
 
1199  
-escapedChar' :: MarkdownParser Char
  1236
+escapedChar' :: (Stream s Identity Char, IsString s) => MarkdownParser s Char
1200 1237
 escapedChar' = try $ do
1201 1238
   char '\\'
1202 1239
   (guardEnabled Ext_all_symbols_escapable >> satisfy (not . isAlphaNum))
1203 1240
      <|> oneOf "\\`*_{}[]()>#+-.!~"
1204 1241
 
1205  
-escapedChar :: MarkdownParser (F Inlines)
  1242
+escapedChar :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Inlines)
1206 1243
 escapedChar = do
1207 1244
   result <- escapedChar'
1208 1245
   case result of
@@ -1211,7 +1248,7 @@ escapedChar = do
1211 1248
                 return (return B.linebreak)  -- "\[newline]" is a linebreak
1212 1249
        _     -> return $ return $ B.str [result]
1213 1250
 
1214  
-ltSign :: MarkdownParser (F Inlines)
  1251
+ltSign :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Inlines)
1215 1252
 ltSign = do
1216 1253
   guardDisabled Ext_raw_html
1217 1254
     <|> guardDisabled Ext_markdown_in_html_blocks
@@ -1219,7 +1256,7 @@ ltSign = do
1219 1256
   char '<'
1220 1257
   return $ return $ B.str "<"
1221 1258
 
1222  
-exampleRef :: MarkdownParser (F Inlines)
  1259
+exampleRef :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Inlines)
1223 1260
 exampleRef = try $ do
1224 1261
   guardEnabled Ext_example_lists
1225 1262
   char '@'
@@ -1230,7 +1267,7 @@ exampleRef = try $ do
1230 1267
                   Just n    -> B.str (show n)
1231 1268
                   Nothing   -> B.str ('@':lab)
1232 1269
 
1233  
-symbol :: MarkdownParser (F Inlines)
  1270
+symbol :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Inlines)
1234 1271
 symbol = do
1235 1272
   result <- noneOf "<\\\n\t "
1236 1273
          <|> try (do lookAhead $ char '\\'
@@ -1239,7 +1276,7 @@ symbol = do
1239 1276
   return $ return $ B.str [result]
1240 1277
 
1241 1278
 -- parses inline code, between n `s and n `s
1242  
-code :: MarkdownParser (F Inlines)
  1279
+code :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Inlines)
1243 1280
 code = try $ do
1244 1281
   starts <- many1 (char '`')
1245 1282
   skipSpaces
@@ -1251,11 +1288,11 @@ code = try $ do
1251 1288
                                    optional whitespace >> attributes)
1252 1289
   return $ return $ B.codeWith attr $ removeLeadingTrailingSpace $ concat result
1253 1290
 
1254  
-math :: MarkdownParser (F Inlines)
  1291
+math :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Inlines)
1255 1292
 math =  (return . B.displayMath <$> (mathDisplay >>= applyMacros'))
1256 1293
      <|> (return . B.math <$> (mathInline >>= applyMacros'))
1257 1294
 
1258  
-mathDisplay :: MarkdownParser String
  1295
+mathDisplay :: (Stream s Identity Char, IsString s) => MarkdownParser s String
1259 1296
 mathDisplay =
1260 1297
       (guardEnabled Ext_tex_math_dollars >> mathDisplayWith "$$" "$$")
1261 1298
   <|> (guardEnabled Ext_tex_math_single_backslash >>
@@ -1263,12 +1300,13 @@ mathDisplay =
1263 1300
   <|> (guardEnabled Ext_tex_math_double_backslash >>
1264 1301
        mathDisplayWith "\\\\[" "\\\\]")
1265 1302
 
1266  
-mathDisplayWith :: String -> String -> MarkdownParser String
  1303
+mathDisplayWith :: (Stream s Identity Char, IsString s)
  1304
+                => String -> String -> MarkdownParser s String
1267 1305
 mathDisplayWith op cl = try $ do
1268 1306
   string op
1269 1307
   many1Till (noneOf "\n" <|> (newline >>~ notFollowedBy' blankline)) (try $ string cl)
1270 1308
 
1271  
-mathInline :: MarkdownParser String
  1309
+mathInline :: (Stream s Identity Char, IsString s) => MarkdownParser s String
1272 1310
 mathInline =
1273 1311
       (guardEnabled Ext_tex_math_dollars >> mathInlineWith "$" "$")
1274 1312
   <|> (guardEnabled Ext_tex_math_single_backslash >>
@@ -1276,7 +1314,8 @@ mathInline =
1276 1314
   <|> (guardEnabled Ext_tex_math_double_backslash >>
1277 1315
        mathInlineWith "\\\\(" "\\\\)")
1278 1316
 
1279  
-mathInlineWith :: String -> String -> MarkdownParser String
  1317
+mathInlineWith :: (Stream s Identity Char, IsString s)
  1318
+               => String -> String -> MarkdownParser s String
1280 1319
 mathInlineWith op cl = try $ do
1281 1320
   string op
1282 1321
   notFollowedBy space
@@ -1290,7 +1329,7 @@ mathInlineWith op cl = try $ do
1290 1329
 
1291 1330
 -- to avoid performance problems, treat 4 or more _ or * or ~ or ^ in a row
1292 1331
 -- as a literal rather than attempting to parse for emph/strong/strikeout/super/sub
1293  
-fours :: Parser [Char] st (F Inlines)
  1332
+fours :: (Stream s Identity Char, IsString s) => Parser s st (F Inlines)
1294 1333
 fours = try $ do
1295 1334
   x <- char '*' <|> char '_' <|> char '~' <|> char '^'
1296 1335
   count 2 $ satisfy (==x)
@@ -1298,59 +1337,59 @@ fours = try $ do
1298 1337
   return $ return $ B.str (x:x:x:rest)
1299 1338
 
1300 1339
 -- | Parses a list of inlines between start and end delimiters.
1301  
-inlinesBetween :: (Show b)
1302  
-               => MarkdownParser a
1303  
-               -> MarkdownParser b
1304  
-               -> MarkdownParser (F Inlines)
  1340
+inlinesBetween :: (Stream s Identity Char, IsString s)
  1341
+               => MarkdownParser s ()
  1342
+               -> MarkdownParser s ()
  1343
+               -> MarkdownParser s (F Inlines)
1305 1344
 inlinesBetween start end =
1306 1345
   (trimInlinesF . mconcat) <$> try (start >> many1Till inner end)
1307 1346
     where inner      = innerSpace <|> (notFollowedBy' (() <$ whitespace) >> inline)
1308 1347
           innerSpace = try $ whitespace >>~ notFollowedBy' end
1309 1348
 
1310  
-emph :: MarkdownParser (F Inlines)
  1349
+emph :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Inlines)
1311 1350
 emph = fmap B.emph <$> nested
1312 1351
   (inlinesBetween starStart starEnd <|> inlinesBetween ulStart ulEnd)
1313  
-    where starStart = char '*' >> lookAhead nonspaceChar
1314  
-          starEnd   = notFollowedBy' (() <$ strong) >> char '*'
1315  
-          ulStart   = char '_' >> lookAhead nonspaceChar
1316  
-          ulEnd     = notFollowedBy' (() <$ strong) >> char '_'
  1352
+    where starStart = char '*' >> lookAhead nonspaceChar >> return ()
  1353
+          starEnd   = notFollowedBy' (() <$ strong) <* char '*'
  1354
+          ulStart   = char '_' >> lookAhead nonspaceChar >> return ()
  1355
+          ulEnd     = notFollowedBy' (() <$ strong) <* char '_'
1317 1356
 
1318  
-strong :: MarkdownParser (F Inlines)
  1357
+strong :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Inlines)
1319 1358
 strong = fmap B.strong <$> nested
1320 1359
   (inlinesBetween starStart starEnd <|> inlinesBetween ulStart ulEnd)
1321  
-    where starStart = string "**" >> lookAhead nonspaceChar
1322  
-          starEnd   = try $ string "**"
1323  
-          ulStart   = string "__" >> lookAhead nonspaceChar
1324  
-          ulEnd     = try $ string "__"
  1360
+    where starStart = string "**" >> lookAhead nonspaceChar >> return ()
  1361
+          starEnd   = () <$ try (string "**")
  1362
+          ulStart   = string "__" >> lookAhead nonspaceChar >> return ()
  1363
+          ulEnd     = () <$ try (string "__")
1325 1364
 
1326  
-strikeout :: MarkdownParser (F Inlines)
  1365
+strikeout :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Inlines)
1327 1366
 strikeout = fmap B.strikeout <$>
1328 1367
  (guardEnabled Ext_strikeout >> inlinesBetween strikeStart strikeEnd)
1329 1368
     where strikeStart = string "~~" >> lookAhead nonspaceChar
1330 1369
                         >> notFollowedBy (char '~')
1331  
-          strikeEnd   = try $ string "~~"
  1370
+          strikeEnd   = () <$ try (string "~~")
1332 1371
 
1333  
-superscript :: MarkdownParser (F Inlines)
  1372
+superscript :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Inlines)
1334 1373
 superscript = fmap B.superscript <$> try (do
1335 1374
   guardEnabled Ext_superscript
1336 1375
   char '^'
1337 1376
   mconcat <$> many1Till (notFollowedBy spaceChar >> inline) (char '^'))
1338 1377
 
1339  
-subscript :: MarkdownParser (F Inlines)
  1378
+subscript :: (Stream s Identity Char, IsString s) => MarkdownParser s (F Inlines)