git.iko.soy/typeable/pandoc
on master help sign in
RST reader: Refactored directive parser.
3a589b7John MacFarlane
src/Text/Pandoc/Readers/RST.hs+105−83
@@ -52,6 +52,8 @@ readRST :: ReaderOptions -- ^ Reader options
52 -> Pandoc
52 -> Pandoc
53readRST opts s = (readWith parseRST) def{ stateOptions = opts } (s ++ "\n\n")
53readRST opts s = (readWith parseRST) def{ stateOptions = opts } (s ++ "\n\n")
54
54
55+type RSTParser = Parser [Char] ParserState
56+
55--
57--
56-- Constants and data structure definitions
58-- Constants and data structure definitions
57---
59---
@@ -95,7 +97,7 @@ titleTransform ((Header 1 head1):rest) |
95 (promoteHeaders 1 rest, head1)
97 (promoteHeaders 1 rest, head1)
96titleTransform blocks = (blocks, [])
98titleTransform blocks = (blocks, [])
97
99
98−parseRST :: Parser [Char] ParserState Pandoc
100+parseRST :: RSTParser Pandoc
99parseRST = do
101parseRST = do
100 optional blanklines -- skip blank lines at beginning of file
102 optional blanklines -- skip blank lines at beginning of file
101 startPos <- getPosition
103 startPos <- getPosition
@@ -124,10 +126,10 @@ parseRST = do
124-- parsing blocks
126-- parsing blocks
125--
127--
126
128
127−parseBlocks :: Parser [Char] ParserState Blocks
129+parseBlocks :: RSTParser Blocks
128parseBlocks = mconcat <$> manyTill block eof
130parseBlocks = mconcat <$> manyTill block eof
129
131
130−block :: Parser [Char] ParserState Blocks
132+block :: RSTParser Blocks
131block = choice [ codeBlock
133block = choice [ codeBlock
132 , rawBlock
134 , rawBlock
133 , blockQuote
135 , blockQuote
@@ -137,7 +139,7 @@ block = choice [ codeBlock
137 , customCodeBlock
139 , customCodeBlock
138 , mathBlock
140 , mathBlock
139 , defaultRoleBlock
141 , defaultRoleBlock
140− , unknownDirective
142+ , directive
141 , header
143 , header
142 , hrule
144 , hrule
143 , lineBlock -- must go before definitionList
145 , lineBlock -- must go before definitionList
@@ -152,7 +154,7 @@ block = choice [ codeBlock
152-- field list
154-- field list
153--
155--
154
156
155−rawFieldListItem :: String -> Parser [Char] ParserState (String, String)
157+rawFieldListItem :: String -> RSTParser (String, String)
156rawFieldListItem indent = try $ do
158rawFieldListItem indent = try $ do
157 string indent
159 string indent
158 char ':'
160 char ':'
@@ -165,7 +167,7 @@ rawFieldListItem indent = try $ do
165 return (name, raw)
167 return (name, raw)
166
168
167fieldListItem :: String
169fieldListItem :: String
168− -> Parser [Char] ParserState (Maybe (Inlines, [Blocks]))
170+ -> RSTParser (Maybe (Inlines, [Blocks]))
169fieldListItem indent = try $ do
171fieldListItem indent = try $ do
170 (name, raw) <- rawFieldListItem indent
172 (name, raw) <- rawFieldListItem indent
171 let term = B.str name
173 let term = B.str name
@@ -192,7 +194,7 @@ extractContents [Plain auth] = auth
192extractContents [Para auth] = auth
194extractContents [Para auth] = auth
193extractContents _ = []
195extractContents _ = []
194
196
195−fieldList :: Parser [Char] ParserState Blocks
197+fieldList :: RSTParser Blocks
196fieldList = try $ do
198fieldList = try $ do
197 indent <- lookAhead $ many spaceChar
199 indent <- lookAhead $ many spaceChar
198 items <- many1 $ fieldListItem indent
200 items <- many1 $ fieldListItem indent
@@ -204,7 +206,7 @@ fieldList = try $ do
204-- line block
206-- line block
205--
207--
206
208
207−lineBlockLine :: Parser [Char] ParserState Inlines
209+lineBlockLine :: RSTParser Inlines
208lineBlockLine = try $ do
210lineBlockLine = try $ do
209 char '|'
211 char '|'
210 char ' ' <|> lookAhead (char '\n')
212 char ' ' <|> lookAhead (char '\n')
@@ -215,7 +217,7 @@ lineBlockLine = try $ do
215 then mconcat line
217 then mconcat line
216 else B.str white <> mconcat line
218 else B.str white <> mconcat line
217
219
218−lineBlock :: Parser [Char] ParserState Blocks
220+lineBlock :: RSTParser Blocks
219lineBlock = try $ do
221lineBlock = try $ do
220 lines' <- many1 lineBlockLine
222 lines' <- many1 lineBlockLine
221 blanklines
223 blanklines
@@ -226,7 +228,7 @@ lineBlock = try $ do
226--
228--
227
229
228-- note: paragraph can end in a :: starting a code block
230-- note: paragraph can end in a :: starting a code block
229−para :: Parser [Char] ParserState Blocks
231+para :: RSTParser Blocks
230para = try $ do
232para = try $ do
231 result <- trimInlines . mconcat <$> many1 inline
233 result <- trimInlines . mconcat <$> many1 inline
232 option (B.plain result) $ try $ do
234 option (B.plain result) $ try $ do
@@ -239,20 +241,20 @@ para = try $ do
239 <> codeblock
241 <> codeblock
240 _ -> return (B.para result)
242 _ -> return (B.para result)
241
243
242−plain :: Parser [Char] ParserState Blocks
244+plain :: RSTParser Blocks
243plain = B.plain . trimInlines . mconcat <$> many1 inline
245plain = B.plain . trimInlines . mconcat <$> many1 inline
244
246
245--
247--
246-- image block
248-- image block
247--
249--
248
250
249−imageBlock :: Parser [Char] ParserState Blocks
251+imageBlock :: RSTParser Blocks
250imageBlock = try $ do
252imageBlock = try $ do
251 string ".. "
253 string ".. "
252 res <- imageDef (B.str "image")
254 res <- imageDef (B.str "image")
253 return $ B.para res
255 return $ B.para res
254
256
255−imageDef :: Inlines -> Parser [Char] ParserState Inlines
257+imageDef :: Inlines -> RSTParser Inlines
256imageDef defaultAlt = try $ do
258imageDef defaultAlt = try $ do
257 string "image:: "
259 string "image:: "
258 src <- escapeURI . removeLeadingTrailingSpace <$> manyTill anyChar newline
260 src <- escapeURI . removeLeadingTrailingSpace <$> manyTill anyChar newline
@@ -271,11 +273,11 @@ imageDef defaultAlt = try $ do
271-- header blocks
273-- header blocks
272--
274--
273
275
274−header :: Parser [Char] ParserState Blocks
276+header :: RSTParser Blocks
275header = doubleHeader <|> singleHeader <?> "header"
277header = doubleHeader <|> singleHeader <?> "header"
276
278
277-- a header with lines on top and bottom
279-- a header with lines on top and bottom
278−doubleHeader :: Parser [Char] ParserState Blocks
280+doubleHeader :: RSTParser Blocks
279doubleHeader = try $ do
281doubleHeader = try $ do
280 c <- oneOf underlineChars
282 c <- oneOf underlineChars
281 rest <- many (char c) -- the top line
283 rest <- many (char c) -- the top line
@@ -300,7 +302,7 @@ doubleHeader = try $ do
300 return $ B.header level txt
302 return $ B.header level txt
301
303
302-- a header with line on the bottom only
304-- a header with line on the bottom only
303−singleHeader :: Parser [Char] ParserState Blocks
305+singleHeader :: RSTParser Blocks
304singleHeader = try $ do
306singleHeader = try $ do
305 notFollowedBy' whitespace
307 notFollowedBy' whitespace
306 txt <- trimInlines . mconcat <$> many1 (do {notFollowedBy blankline; inline})
308 txt <- trimInlines . mconcat <$> many1 (do {notFollowedBy blankline; inline})
@@ -377,7 +379,7 @@ customCodeBlock = try $ do
377 return $ B.codeBlockWith ("", ["sourceCode", language], [])
379 return $ B.codeBlockWith ("", ["sourceCode", language], [])
378 $ stripTrailingNewlines result
380 $ stripTrailingNewlines result
379
381
380−figureBlock :: Parser [Char] ParserState Blocks
382+figureBlock :: RSTParser Blocks
381figureBlock = try $ do
383figureBlock = try $ do
382 string ".. figure::"
384 string ".. figure::"
383 src <- escapeURI . removeLeadingTrailingSpace <$> manyTill anyChar newline
385 src <- escapeURI . removeLeadingTrailingSpace <$> manyTill anyChar newline
@@ -385,7 +387,7 @@ figureBlock = try $ do
385 caption <- parseFromString extractCaption body
387 caption <- parseFromString extractCaption body
386 return $ B.para $ B.image src "" caption
388 return $ B.para $ B.image src "" caption
387
389
388−extractCaption :: Parser [Char] ParserState Inlines
390+extractCaption :: RSTParser Inlines
389extractCaption = try $ do
391extractCaption = try $ do
390 manyTill anyLine blanklines
392 manyTill anyLine blanklines
391 trimInlines . mconcat <$> many inline
393 trimInlines . mconcat <$> many inline
@@ -417,7 +419,7 @@ mathBlockMultiline = try $ do
417 $ filter (not . null) $ splitBy null lns'
419 $ filter (not . null) $ splitBy null lns'
418 return $ B.para $ mconcat $ map B.displayMath eqs
420 return $ B.para $ mconcat $ map B.displayMath eqs
419
421
420−lhsCodeBlock :: Parser [Char] ParserState Blocks
422+lhsCodeBlock :: RSTParser Blocks
421lhsCodeBlock = try $ do
423lhsCodeBlock = try $ do
422 guardEnabled Ext_literate_haskell
424 guardEnabled Ext_literate_haskell
423 optional codeBlockStart
425 optional codeBlockStart
@@ -451,7 +453,7 @@ rawBlock = try $ do
451-- block quotes
453-- block quotes
452--
454--
453
455
454−blockQuote :: Parser [Char] ParserState Blocks
456+blockQuote :: RSTParser Blocks
455blockQuote = do
457blockQuote = do
456 raw <- indentedBlock
458 raw <- indentedBlock
457 -- parse the extracted block, which may contain various block elements:
459 -- parse the extracted block, which may contain various block elements:
@@ -462,10 +464,10 @@ blockQuote = do
462-- list blocks
464-- list blocks
463--
465--
464
466
465−list :: Parser [Char] ParserState Blocks
467+list :: RSTParser Blocks
466list = choice [ bulletList, orderedList, definitionList ] <?> "list"
468list = choice [ bulletList, orderedList, definitionList ] <?> "list"
467
469
468−definitionListItem :: Parser [Char] ParserState (Inlines, [Blocks])
470+definitionListItem :: RSTParser (Inlines, [Blocks])
469definitionListItem = try $ do
471definitionListItem = try $ do
470 -- avoid capturing a directive or comment
472 -- avoid capturing a directive or comment
471 notFollowedBy (try $ char '.' >> char '.')
473 notFollowedBy (try $ char '.' >> char '.')
@@ -475,7 +477,7 @@ definitionListItem = try $ do
475 contents <- parseFromString parseBlocks $ raw ++ "\n"
477 contents <- parseFromString parseBlocks $ raw ++ "\n"
476 return (term, [contents])
478 return (term, [contents])
477
479
478−definitionList :: Parser [Char] ParserState Blocks
480+definitionList :: RSTParser Blocks
479definitionList = B.definitionList <$> many1 definitionListItem
481definitionList = B.definitionList <$> many1 definitionListItem
480
482
481-- parses bullet list start and returns its length (inc. following whitespace)
483-- parses bullet list start and returns its length (inc. following whitespace)
@@ -489,14 +491,14 @@ bulletListStart = try $ do
489-- parses ordered list start and returns its length (inc following whitespace)
491-- parses ordered list start and returns its length (inc following whitespace)
490orderedListStart :: ListNumberStyle
492orderedListStart :: ListNumberStyle
491 -> ListNumberDelim
493 -> ListNumberDelim
492− -> Parser [Char] ParserState Int
494+ -> RSTParser Int
493orderedListStart style delim = try $ do
495orderedListStart style delim = try $ do
494 (_, markerLen) <- withHorizDisplacement (orderedListMarker style delim)
496 (_, markerLen) <- withHorizDisplacement (orderedListMarker style delim)
495 white <- many1 spaceChar
497 white <- many1 spaceChar
496 return $ markerLen + length white
498 return $ markerLen + length white
497
499
498-- parse a line of a list item
500-- parse a line of a list item
499−listLine :: Int -> Parser [Char] ParserState [Char]
501+listLine :: Int -> RSTParser [Char]
500listLine markerLength = try $ do
502listLine markerLength = try $ do
501 notFollowedBy blankline
503 notFollowedBy blankline
502 indentWith markerLength
504 indentWith markerLength
@@ -504,7 +506,7 @@ listLine markerLength = try $ do
504 return $ line ++ "\n"
506 return $ line ++ "\n"
505
507
506-- indent by specified number of spaces (or equiv. tabs)
508-- indent by specified number of spaces (or equiv. tabs)
507−indentWith :: Int -> Parser [Char] ParserState [Char]
509+indentWith :: Int -> RSTParser [Char]
508indentWith num = do
510indentWith num = do
509 tabStop <- getOption readerTabStop
511 tabStop <- getOption readerTabStop
510 if (num < tabStop)
512 if (num < tabStop)
@@ -513,8 +515,8 @@ indentWith num = do
513 (try (char '\t' >> count (num - tabStop) (char ' '))) ]
515 (try (char '\t' >> count (num - tabStop) (char ' '))) ]
514
516
515-- parse raw text for one list item, excluding start marker and continuations
517-- parse raw text for one list item, excluding start marker and continuations
516−rawListItem :: Parser [Char] ParserState Int
518+rawListItem :: RSTParser Int
517− -> Parser [Char] ParserState (Int, [Char])
519+ -> RSTParser (Int, [Char])
518rawListItem start = try $ do
520rawListItem start = try $ do
519 markerLength <- start
521 markerLength <- start
520 firstLine <- manyTill anyChar newline
522 firstLine <- manyTill anyChar newline
@@ -524,14 +526,14 @@ rawListItem start = try $ do
524-- continuation of a list item - indented and separated by blankline or
526-- continuation of a list item - indented and separated by blankline or
525-- (in compact lists) endline.
527-- (in compact lists) endline.
526-- Note: nested lists are parsed as continuations.
528-- Note: nested lists are parsed as continuations.
527−listContinuation :: Int -> Parser [Char] ParserState [Char]
529+listContinuation :: Int -> RSTParser [Char]
528listContinuation markerLength = try $ do
530listContinuation markerLength = try $ do
529 blanks <- many1 blankline
531 blanks <- many1 blankline
530 result <- many1 (listLine markerLength)
532 result <- many1 (listLine markerLength)
531 return $ blanks ++ concat result
533 return $ blanks ++ concat result
532
534
533−listItem :: Parser [Char] ParserState Int
535+listItem :: RSTParser Int
534− -> Parser [Char] ParserState Blocks
536+ -> RSTParser Blocks
535listItem start = try $ do
537listItem start = try $ do
536 (markerLength, first) <- rawListItem start
538 (markerLength, first) <- rawListItem start
537 rest <- many (listContinuation markerLength)
539 rest <- many (listContinuation markerLength)
@@ -548,21 +550,21 @@ listItem start = try $ do
548 updateState (\st -> st {stateParserContext = oldContext})
550 updateState (\st -> st {stateParserContext = oldContext})
549 return parsed
551 return parsed
550
552
551−orderedList :: Parser [Char] ParserState Blocks
553+orderedList :: RSTParser Blocks
552orderedList = try $ do
554orderedList = try $ do
553 (start, style, delim) <- lookAhead (anyOrderedListMarker >>~ spaceChar)
555 (start, style, delim) <- lookAhead (anyOrderedListMarker >>~ spaceChar)
554 items <- many1 (listItem (orderedListStart style delim))
556 items <- many1 (listItem (orderedListStart style delim))
555 let items' = compactify' items
557 let items' = compactify' items
556 return $ B.orderedListWith (start, style, delim) items'
558 return $ B.orderedListWith (start, style, delim) items'
557
559
558−bulletList :: Parser [Char] ParserState Blocks
560+bulletList :: RSTParser Blocks
559bulletList = B.bulletList . compactify' <$> many1 (listItem bulletListStart)
561bulletList = B.bulletList . compactify' <$> many1 (listItem bulletListStart)
560
562
561--
563--
562-- default-role block
564-- default-role block
563--
565--
564
566
565−defaultRoleBlock :: Parser [Char] ParserState Blocks
567+defaultRoleBlock :: RSTParser Blocks
566defaultRoleBlock = try $ do
568defaultRoleBlock = try $ do
567 string ".. default-role::"
569 string ".. default-role::"
568 -- doesn't enforce any restrictions on the role name; embedded spaces shouldn't be allowed, for one
570 -- doesn't enforce any restrictions on the role name; embedded spaces shouldn't be allowed, for one
@@ -577,22 +579,42 @@ defaultRoleBlock = try $ do
577 return mempty
579 return mempty
578
580
579--
581--
580−-- unknown directive (e.g. comment)
582+-- unknown directive (e.g. comment, container, compound-paragraph)
581--
583--
582
584
583−unknownDirective :: Parser [Char] st Blocks
585+directive :: RSTParser Blocks
584−unknownDirective = try $ do
586+directive = try $ do
585 string ".."
587 string ".."
586− notFollowedBy (noneOf " \t\n")
588+ lookAhead (char '\n') <|> spaceChar
587− manyTill anyChar newline
589+ skipMany spaceChar
588− many $ blanklines <|> (spaceChar >> manyTill anyChar newline)
590+ label <- option "" $ try $ many1Till letter (try $ string "::")
591+ skipMany spaceChar
592+ top <- many $ satisfy (/='\n')
593+ <|> try (char '\n' <* notFollowedBy blankline <*
594+ notFollowedBy' (lookAhead (many spaceChar)
595+ >>= rawFieldListItem))
596+ newline
597+ indent <- lookAhead $ many spaceChar
598+ fields <- many $ rawFieldListItem indent
599+ blanklines
600+ body <- option "" indentedBlock
601+ let body' = body ++ "\n\n"
602+ case label of
603+ "" -> return mempty
604+ "container" -> parseFromString parseBlocks body'
605+ "compound" -> parseFromString parseBlocks body'
606+ "pull-quote" -> B.blockQuote <$> parseFromString parseBlocks body'
607+ "epigraph" -> B.blockQuote <$> parseFromString parseBlocks body'
608+ "highlights" -> B.blockQuote <$> parseFromString parseBlocks body'
609+ "rubric" -> B.para . B.strong <$> parseFromString
610+ (trimInlines . mconcat <$> many inline) top
589− return mempty
611+ _ -> return mempty
590
612
591---
613---
592--- note block
614--- note block
593---
615---
594
616
595−noteBlock :: Parser [Char] ParserState [Char]
617+noteBlock :: RSTParser [Char]
596noteBlock = try $ do
618noteBlock = try $ do
597 startPos <- getPosition
619 startPos <- getPosition
598 string ".."
620 string ".."
@@ -611,7 +633,7 @@ noteBlock = try $ do
611 -- return blanks so line count isn't affected
633 -- return blanks so line count isn't affected
612 return $ replicate (sourceLine endPos - sourceLine startPos) '\n'
634 return $ replicate (sourceLine endPos - sourceLine startPos) '\n'
613
635
614−noteMarker :: Parser [Char] ParserState [Char]
636+noteMarker :: RSTParser [Char]
615noteMarker = do
637noteMarker = do
616 char '['
638 char '['
617 res <- many1 digit
639 res <- many1 digit
@@ -624,13 +646,13 @@ noteMarker = do
624-- reference key
646-- reference key
625--
647--
626
648
627−quotedReferenceName :: Parser [Char] ParserState Inlines
649+quotedReferenceName :: RSTParser Inlines
628quotedReferenceName = try $ do
650quotedReferenceName = try $ do
629 char '`' >> notFollowedBy (char '`') -- `` means inline code!
651 char '`' >> notFollowedBy (char '`') -- `` means inline code!
630 label' <- trimInlines . mconcat <$> many1Till inline (char '`')
652 label' <- trimInlines . mconcat <$> many1Till inline (char '`')
631 return label'
653 return label'
632
654
633−unquotedReferenceName :: Parser [Char] ParserState Inlines
655+unquotedReferenceName :: RSTParser Inlines
634unquotedReferenceName = try $ do
656unquotedReferenceName = try $ do
635 label' <- trimInlines . mconcat <$> many1Till inline (lookAhead $ char ':')
657 label' <- trimInlines . mconcat <$> many1Till inline (lookAhead $ char ':')
636 return label'
658 return label'
@@ -651,12 +673,12 @@ simpleReferenceName = do
651 raw <- simpleReferenceName'
673 raw <- simpleReferenceName'
652 return $ B.str raw
674 return $ B.str raw
653
675
654−referenceName :: Parser [Char] ParserState Inlines
676+referenceName :: RSTParser Inlines
655referenceName = quotedReferenceName <|>
677referenceName = quotedReferenceName <|>
656 (try $ simpleReferenceName >>~ lookAhead (char ':')) <|>
678 (try $ simpleReferenceName >>~ lookAhead (char ':')) <|>
657 unquotedReferenceName
679 unquotedReferenceName
658
680
659−referenceKey :: Parser [Char] ParserState [Char]
681+referenceKey :: RSTParser [Char]
660referenceKey = do
682referenceKey = do
661 startPos <- getPosition
683 startPos <- getPosition
662 choice [imageKey, anonymousKey, regularKey]
684 choice [imageKey, anonymousKey, regularKey]
@@ -674,7 +696,7 @@ targetURI = do
674 blanklines
696 blanklines
675 return $ escapeURI $ removeLeadingTrailingSpace $ contents
697 return $ escapeURI $ removeLeadingTrailingSpace $ contents
676
698
677−imageKey :: Parser [Char] ParserState ()
699+imageKey :: RSTParser ()
678imageKey = try $ do
700imageKey = try $ do
679 string ".. |"
701 string ".. |"
680 (alt,ref) <- withRaw (trimInlines . mconcat <$> manyTill inline (char '|'))
702 (alt,ref) <- withRaw (trimInlines . mconcat <$> manyTill inline (char '|'))
@@ -683,7 +705,7 @@ imageKey = try $ do
683 let key = toKey $ init ref
705 let key = toKey $ init ref
684 updateState $ \s -> s{ stateSubstitutions = M.insert key img $ stateSubstitutions s }
706 updateState $ \s -> s{ stateSubstitutions = M.insert key img $ stateSubstitutions s }
685
707
686−anonymousKey :: Parser [Char] ParserState ()
708+anonymousKey :: RSTParser ()
687anonymousKey = try $ do
709anonymousKey = try $ do
688 oneOfStrings [".. __:", "__"]
710 oneOfStrings [".. __:", "__"]
689 src <- targetURI
711 src <- targetURI
@@ -696,7 +718,7 @@ stripTicks = reverse . stripTick . reverse . stripTick
696 where stripTick ('`':xs) = xs
718 where stripTick ('`':xs) = xs
697 stripTick xs = xs
719 stripTick xs = xs
698
720
699−regularKey :: Parser [Char] ParserState ()
721+regularKey :: RSTParser ()
700regularKey = try $ do
722regularKey = try $ do
701 string ".. _"
723 string ".. _"
702 (_,ref) <- withRaw referenceName
724 (_,ref) <- withRaw referenceName
@@ -732,21 +754,21 @@ simpleDashedLines :: Char -> Parser [Char] st [(Int,Int)]
732simpleDashedLines ch = try $ many1 (dashedLine ch)
754simpleDashedLines ch = try $ many1 (dashedLine ch)
733
755
734-- Parse a table row separator
756-- Parse a table row separator
735−simpleTableSep :: Char -> Parser [Char] ParserState Char
757+simpleTableSep :: Char -> RSTParser Char
736simpleTableSep ch = try $ simpleDashedLines ch >> newline
758simpleTableSep ch = try $ simpleDashedLines ch >> newline
737
759
738-- Parse a table footer
760-- Parse a table footer
739−simpleTableFooter :: Parser [Char] ParserState [Char]
761+simpleTableFooter :: RSTParser [Char]
740simpleTableFooter = try $ simpleTableSep '=' >> blanklines
762simpleTableFooter = try $ simpleTableSep '=' >> blanklines
741
763
742-- Parse a raw line and split it into chunks by indices.
764-- Parse a raw line and split it into chunks by indices.
743−simpleTableRawLine :: [Int] -> Parser [Char] ParserState [String]
765+simpleTableRawLine :: [Int] -> RSTParser [String]
744simpleTableRawLine indices = do
766simpleTableRawLine indices = do
745 line <- many1Till anyChar newline
767 line <- many1Till anyChar newline
746 return (simpleTableSplitLine indices line)
768 return (simpleTableSplitLine indices line)
747
769
748-- Parse a table row and return a list of blocks (columns).
770-- Parse a table row and return a list of blocks (columns).
749−simpleTableRow :: [Int] -> Parser [Char] ParserState [[Block]]
771+simpleTableRow :: [Int] -> RSTParser [[Block]]
750simpleTableRow indices = do
772simpleTableRow indices = do
751 notFollowedBy' simpleTableFooter
773 notFollowedBy' simpleTableFooter
752 firstLine <- simpleTableRawLine indices
774 firstLine <- simpleTableRawLine indices
@@ -760,7 +782,7 @@ simpleTableSplitLine indices line =
760 $ tail $ splitByIndices (init indices) line
782 $ tail $ splitByIndices (init indices) line
761
783
762simpleTableHeader :: Bool -- ^ Headerless table
784simpleTableHeader :: Bool -- ^ Headerless table
763− -> Parser [Char] ParserState ([[Block]], [Alignment], [Int])
785+ -> RSTParser ([[Block]], [Alignment], [Int])
764simpleTableHeader headless = try $ do
786simpleTableHeader headless = try $ do
765 optional blanklines
787 optional blanklines
766 rawContent <- if headless
788 rawContent <- if headless
@@ -780,7 +802,7 @@ simpleTableHeader headless = try $ do
780
802
781-- Parse a simple table.
803-- Parse a simple table.
782simpleTable :: Bool -- ^ Headerless table
804simpleTable :: Bool -- ^ Headerless table
783− -> Parser [Char] ParserState Blocks
805+ -> RSTParser Blocks
784simpleTable headless = do
806simpleTable headless = do
785 Table c a _w h l <- tableWith (simpleTableHeader headless) simpleTableRow sep simpleTableFooter
807 Table c a _w h l <- tableWith (simpleTableHeader headless) simpleTableRow sep simpleTableFooter
786 -- Simple tables get 0s for relative column widths (i.e., use default)
808 -- Simple tables get 0s for relative column widths (i.e., use default)
@@ -789,11 +811,11 @@ simpleTable headless = do
789 sep = return () -- optional (simpleTableSep '-')
811 sep = return () -- optional (simpleTableSep '-')
790
812
791gridTable :: Bool -- ^ Headerless table
813gridTable :: Bool -- ^ Headerless table
792− -> Parser [Char] ParserState Blocks
814+ -> RSTParser Blocks
793gridTable headerless = B.singleton
815gridTable headerless = B.singleton
794 <$> gridTableWith (B.toList <$> parseBlocks) headerless
816 <$> gridTableWith (B.toList <$> parseBlocks) headerless
795
817
796−table :: Parser [Char] ParserState Blocks
818+table :: RSTParser Blocks
797table = gridTable False <|> simpleTable False <|>
819table = gridTable False <|> simpleTable False <|>
798 gridTable True <|> simpleTable True <?> "table"
820 gridTable True <|> simpleTable True <?> "table"
799
821
@@ -801,7 +823,7 @@ table = gridTable False <|> simpleTable False <|>
801-- inline
823-- inline
802--
824--
803
825
804−inline :: Parser [Char] ParserState Inlines
826+inline :: RSTParser Inlines
805inline = choice [ whitespace
827inline = choice [ whitespace
806 , link
828 , link
807 , str
829 , str
@@ -819,7 +841,7 @@ inline = choice [ whitespace
819 , escapedChar
841 , escapedChar
820 , symbol ] <?> "inline"
842 , symbol ] <?> "inline"
821
843
822−hyphens :: Parser [Char] ParserState Inlines
844+hyphens :: RSTParser Inlines
823hyphens = do
845hyphens = do
824 result <- many1 (char '-')
846 result <- many1 (char '-')
825 optional endline
847 optional endline
@@ -832,13 +854,13 @@ escapedChar = do c <- escaped anyChar
832 then mempty
854 then mempty
833 else B.str [c]
855 else B.str [c]
834
856
835−symbol :: Parser [Char] ParserState Inlines
857+symbol :: RSTParser Inlines
836symbol = do
858symbol = do
837 result <- oneOf specialChars
859 result <- oneOf specialChars
838 return $ B.str [result]
860 return $ B.str [result]
839
861
840-- parses inline code, between codeStart and codeEnd
862-- parses inline code, between codeStart and codeEnd
841−code :: Parser [Char] ParserState Inlines
863+code :: RSTParser Inlines
842code = try $ do
864code = try $ do
843 string "``"
865 string "``"
844 result <- manyTill anyChar (try (string "``"))
866 result <- manyTill anyChar (try (string "``"))
@@ -846,7 +868,7 @@ code = try $ do
846 $ removeLeadingTrailingSpace $ unwords $ lines result
868 $ removeLeadingTrailingSpace $ unwords $ lines result
847
869
848-- succeeds only if we're not right after a str (ie. in middle of word)
870-- succeeds only if we're not right after a str (ie. in middle of word)
849−atStart :: Parser [Char] ParserState a -> Parser [Char] ParserState a
871+atStart :: RSTParser a -> RSTParser a
850atStart p = do
872atStart p = do
851 pos <- getPosition
873 pos <- getPosition
852 st <- getState
874 st <- getState
@@ -854,18 +876,18 @@ atStart p = do
854 guard $ stateLastStrPos st /= Just pos
876 guard $ stateLastStrPos st /= Just pos
855 p
877 p
856
878
857−emph :: Parser [Char] ParserState Inlines
879+emph :: RSTParser Inlines
858emph = B.emph . trimInlines . mconcat <$>
880emph = B.emph . trimInlines . mconcat <$>
859 enclosed (atStart $ char '*') (char '*') inline
881 enclosed (atStart $ char '*') (char '*') inline
860
882
861−strong :: Parser [Char] ParserState Inlines
883+strong :: RSTParser Inlines
862strong = B.strong . trimInlines . mconcat <$>
884strong = B.strong . trimInlines . mconcat <$>
863 enclosed (atStart $ string "**") (try $ string "**") inline
885 enclosed (atStart $ string "**") (try $ string "**") inline
864
886
865-- Parses inline interpreted text which is required to have the given role.
887-- Parses inline interpreted text which is required to have the given role.
866-- This decision is based on the role marker (if present),
888-- This decision is based on the role marker (if present),
867-- and the current default interpreted text role.
889-- and the current default interpreted text role.
868−interpreted :: [Char] -> Parser [Char] ParserState [Char]
890+interpreted :: [Char] -> RSTParser [Char]
869interpreted role = try $ do
891interpreted role = try $ do
870 state <- getState
892 state <- getState
871 if role == stateRstDefaultRole state
893 if role == stateRstDefaultRole state
@@ -882,19 +904,19 @@ interpreted role = try $ do
882 result <- enclosed (atStart $ char '`') (char '`') anyChar
904 result <- enclosed (atStart $ char '`') (char '`') anyChar
883 return result
905 return result
884
906
885−superscript :: Parser [Char] ParserState Inlines
907+superscript :: RSTParser Inlines
886superscript = B.superscript . B.str <$> interpreted "sup"
908superscript = B.superscript . B.str <$> interpreted "sup"
887
909
888−subscript :: Parser [Char] ParserState Inlines
910+subscript :: RSTParser Inlines
889subscript = B.subscript . B.str <$> interpreted "sub"
911subscript = B.subscript . B.str <$> interpreted "sub"
890
912
891−math :: Parser [Char] ParserState Inlines
913+math :: RSTParser Inlines
892math = B.math <$> interpreted "math"
914math = B.math <$> interpreted "math"
893
915
894−whitespace :: Parser [Char] ParserState Inlines
916+whitespace :: RSTParser Inlines
895whitespace = B.space <$ skipMany1 spaceChar <?> "whitespace"
917whitespace = B.space <$ skipMany1 spaceChar <?> "whitespace"
896
918
897−str :: Parser [Char] ParserState Inlines
919+str :: RSTParser Inlines
898str = do
920str = do
899 let strChar = noneOf ("\t\n " ++ specialChars)
921 let strChar = noneOf ("\t\n " ++ specialChars)
900 result <- many1 strChar
922 result <- many1 strChar
@@ -902,7 +924,7 @@ str = do
902 return $ B.str result
924 return $ B.str result
903
925
904-- an endline character that can be treated as a space, not a structural break
926-- an endline character that can be treated as a space, not a structural break
905−endline :: Parser [Char] ParserState Inlines
927+endline :: RSTParser Inlines
906endline = try $ do
928endline = try $ do
907 newline
929 newline
908 notFollowedBy blankline
930 notFollowedBy blankline
@@ -918,10 +940,10 @@ endline = try $ do
918-- links
940-- links
919--
941--
920
942
921−link :: Parser [Char] ParserState Inlines
943+link :: RSTParser Inlines
922link = choice [explicitLink, referenceLink, autoLink] <?> "link"
944link = choice [explicitLink, referenceLink, autoLink] <?> "link"
923
945
924−explicitLink :: Parser [Char] ParserState Inlines
946+explicitLink :: RSTParser Inlines
925explicitLink = try $ do
947explicitLink = try $ do
926 char '`'
948 char '`'
927 notFollowedBy (char '`') -- `` marks start of inline code
949 notFollowedBy (char '`') -- `` marks start of inline code
@@ -932,7 +954,7 @@ explicitLink = try $ do
932 string "`_"
954 string "`_"
933 return $ B.link (escapeURI $ removeLeadingTrailingSpace src) "" label'
955 return $ B.link (escapeURI $ removeLeadingTrailingSpace src) "" label'
934
956
935−referenceLink :: Parser [Char] ParserState Inlines
957+referenceLink :: RSTParser Inlines
936referenceLink = try $ do
958referenceLink = try $ do
937 (label',ref) <- withRaw (quotedReferenceName <|> simpleReferenceName) >>~
959 (label',ref) <- withRaw (quotedReferenceName <|> simpleReferenceName) >>~
938 char '_'
960 char '_'
@@ -953,21 +975,21 @@ referenceLink = try $ do
953 when (isAnonKey key) $ updateState $ \s -> s{ stateKeys = M.delete key keyTable }
975 when (isAnonKey key) $ updateState $ \s -> s{ stateKeys = M.delete key keyTable }
954 return $ B.link src tit label'
976 return $ B.link src tit label'
955
977
956−autoURI :: Parser [Char] ParserState Inlines
978+autoURI :: RSTParser Inlines
957autoURI = do
979autoURI = do
958 (orig, src) <- uri
980 (orig, src) <- uri
959 return $ B.link src "" $ B.str orig
981 return $ B.link src "" $ B.str orig
960
982
961−autoEmail :: Parser [Char] ParserState Inlines
983+autoEmail :: RSTParser Inlines
962autoEmail = do
984autoEmail = do
963 (orig, src) <- emailAddress
985 (orig, src) <- emailAddress
964 return $ B.link src "" $ B.str orig
986 return $ B.link src "" $ B.str orig
965
987
966−autoLink :: Parser [Char] ParserState Inlines
988+autoLink :: RSTParser Inlines
967autoLink = autoURI <|> autoEmail
989autoLink = autoURI <|> autoEmail
968
990
969-- For now, we assume that all substitution references are for images.
991-- For now, we assume that all substitution references are for images.
970−image :: Parser [Char] ParserState Inlines
992+image :: RSTParser Inlines
971image = try $ do
993image = try $ do
972 char '|'
994 char '|'
973 (_,ref) <- withRaw (manyTill inline (char '|'))
995 (_,ref) <- withRaw (manyTill inline (char '|'))
@@ -977,7 +999,7 @@ image = try $ do
977 Nothing -> fail "no corresponding key"
999 Nothing -> fail "no corresponding key"
978 Just target -> return target
1000 Just target -> return target
979
1001
980−note :: Parser [Char] ParserState Inlines
1002+note :: RSTParser Inlines
981note = try $ do
1003note = try $ do
982 ref <- noteMarker
1004 ref <- noteMarker
983 char '_'
1005 char '_'
@@ -1000,20 +1022,20 @@ note = try $ do
1000 updateState $ \st -> st{ stateNotes = newnotes }
1022 updateState $ \st -> st{ stateNotes = newnotes }
1001 return $ B.note contents
1023 return $ B.note contents
1002
1024
1003−smart :: Parser [Char] ParserState Inlines
1025+smart :: RSTParser Inlines
1004smart = do
1026smart = do
1005 getOption readerSmart >>= guard
1027 getOption readerSmart >>= guard
1006 doubleQuoted <|> singleQuoted <|>
1028 doubleQuoted <|> singleQuoted <|>
1007 choice (map (B.singleton <$>) [apostrophe, dash, ellipses])
1029 choice (map (B.singleton <$>) [apostrophe, dash, ellipses])
1008
1030
1009−singleQuoted :: Parser [Char] ParserState Inlines
1031+singleQuoted :: RSTParser Inlines
1010singleQuoted = try $ do
1032singleQuoted = try $ do
1011 singleQuoteStart
1033 singleQuoteStart
1012 withQuoteContext InSingleQuote $
1034 withQuoteContext InSingleQuote $
1013 B.singleQuoted . trimInlines . mconcat <$>
1035 B.singleQuoted . trimInlines . mconcat <$>
1014 many1Till inline singleQuoteEnd
1036 many1Till inline singleQuoteEnd
1015
1037
1016−doubleQuoted :: Parser [Char] ParserState Inlines
1038+doubleQuoted :: RSTParser Inlines
1017doubleQuoted = try $ do
1039doubleQuoted = try $ do
1018 doubleQuoteStart
1040 doubleQuoteStart
1019 withQuoteContext InDoubleQuote $
1041 withQuoteContext InDoubleQuote $