@@ -31,7 +31,7 @@ Conversion of markdown-formatted plain text to 'Pandoc' document.
31module Text.Pandoc.Readers.Markdown ( readMarkdown,
31module Text.Pandoc.Readers.Markdown ( readMarkdown,
32 readMarkdownWithWarnings ) where
32 readMarkdownWithWarnings ) where
34−import Data.List ( transpose, sortBy, findIndex, intersperse, intercalate )
34+import Data.List ( transpose, sortBy, intersperse, intercalate, elemIndex)
35import qualified Data.Map as M
35import qualified Data.Map as M
36import Data.Scientific (coefficient, base10Exponent)
36import Data.Scientific (coefficient, base10Exponent)
37import Data.Ord ( comparing )
37import Data.Ord ( comparing )
@@ -55,8 +55,9 @@ import Text.Pandoc.Readers.LaTeX ( rawLaTeXInline, rawLaTeXBlock )
55import Text.Pandoc.Readers.HTML ( htmlTag, htmlInBalanced, isInlineTag, isBlockTag,
55import Text.Pandoc.Readers.HTML ( htmlTag, htmlInBalanced, isInlineTag, isBlockTag,
56 isTextTag, isCommentTag )
56 isTextTag, isCommentTag )
57import Data.Monoid (mconcat, mempty)
57import Data.Monoid (mconcat, mempty)
58−import Control.Applicative ((<$>), (<*), (*>), (<$))
58+import Control.Applicative ((<$>), (<*), (*>), (<$), (<*>))
59import Control.Monad
59import Control.Monad
60+import Control.Monad.Reader
60import System.FilePath (takeExtension, addExtension)
61import System.FilePath (takeExtension, addExtension)
61import Text.HTML.TagSoup
62import Text.HTML.TagSoup
62import Text.HTML.TagSoup.Match (tagOpen)
63import Text.HTML.TagSoup.Match (tagOpen)
@@ -64,25 +65,29 @@ import qualified Data.Set as Set
64import Text.Printf (printf)
65import Text.Printf (printf)
65import Debug.Trace (trace)
66import Debug.Trace (trace)
67−type MarkdownParser = Parser [Char] ParserState
68+type MarkdownParser a = ParserT [Char] ParserState (Reader ParserState) a
69-- | Read markdown from an input string and return a Pandoc document.
70-- | Read markdown from an input string and return a Pandoc document.
70readMarkdown :: ReaderOptions -- ^ Reader options
71readMarkdown :: ReaderOptions -- ^ Reader options
71 -> String -- ^ String to parse (assuming @'\n'@ line endings)
72 -> String -- ^ String to parse (assuming @'\n'@ line endings)
73readMarkdown opts s =
74readMarkdown opts s =
74− (readWith parseMarkdown) def{ stateOptions = opts } (s ++ "\n\n")
75+ runMarkdown opts s parseMarkdown
76-- | Read markdown from an input string and return a pair of a Pandoc document
77-- | Read markdown from an input string and return a pair of a Pandoc document
77-- and a list of warnings.
78-- and a list of warnings.
78readMarkdownWithWarnings :: ReaderOptions -- ^ Reader options
79readMarkdownWithWarnings :: ReaderOptions -- ^ Reader options
79 -> String -- ^ String to parse (assuming @'\n'@ line endings)
80 -> String -- ^ String to parse (assuming @'\n'@ line endings)
80 -> (Pandoc, [String])
81 -> (Pandoc, [String])
81−readMarkdownWithWarnings opts s =
82+readMarkdownWithWarnings opts s = runMarkdown opts s (returnWarnings parseMarkdown)
82− (readWithWarnings parseMarkdown) def{ stateOptions = opts } (s ++ "\n\n")
84−trimInlinesF :: F Inlines -> F Inlines
84+runMarkdown :: ReaderOptions -> String -> MarkdownParser a -> a
85−trimInlinesF = liftM trimInlines
85+runMarkdown opts inp p = fst res
87+ imd = readWithM (returnState p) def{ stateOptions = opts } (inp ++ "\n\n")
88+ res = runReader imd s
90+ s = snd $ runReader imd s
88-- Constants and data structure definitions
93-- Constants and data structure definitions
@@ -119,10 +124,10 @@ inList = do
119 ctx <- stateParserContext <$> getState
124 ctx <- stateParserContext <$> getState
120 guard (ctx == ListItemState)
125 guard (ctx == ListItemState)
122−isNull :: F Inlines -> Bool
127+isNull :: Inlines -> Bool
123−isNull ils = B.isNull $ runF ils def
128+isNull = B.isNull
125−spnl :: Parser [Char] st ()
130+spnl :: Monad m => ParserT [Char] st m ()
126spnl = try $ do
131spnl = try $ do
127 skipSpaces
132 skipSpaces
128 optional newline
133 optional newline
@@ -162,9 +167,9 @@ litChar = escapedChar'
163-- | Parse a sequence of inline elements between square brackets,
168-- | Parse a sequence of inline elements between square brackets,
164-- including inlines between balanced pairs of square brackets.
169-- including inlines between balanced pairs of square brackets.
165−inlinesInBalancedBrackets :: MarkdownParser (F Inlines)
170+inlinesInBalancedBrackets :: MarkdownParser Inlines
166inlinesInBalancedBrackets = charsInBalancedBrackets >>=
171inlinesInBalancedBrackets = charsInBalancedBrackets >>=
167− parseFromString (trimInlinesF . mconcat <$> many inline)
172+ parseFromString (trimInlines . mconcat <$> many inline)
169charsInBalancedBrackets :: MarkdownParser [Char]
174charsInBalancedBrackets :: MarkdownParser [Char]
170charsInBalancedBrackets = do
175charsInBalancedBrackets = do
@@ -181,16 +186,16 @@ charsInBalancedBrackets = do
181-- document structure
186-- document structure
184−titleLine :: MarkdownParser (F Inlines)
189+titleLine :: MarkdownParser Inlines
185titleLine = try $ do
190titleLine = try $ do
187 skipSpaces
192 skipSpaces
188 res <- many $ (notFollowedBy newline >> inline)
193 res <- many $ (notFollowedBy newline >> inline)
189 <|> try (endline >> whitespace)
194 <|> try (endline >> whitespace)
191− return $ trimInlinesF $ mconcat res
196+ return $ trimInlines $ mconcat res
193−authorsLine :: MarkdownParser (F [Inlines])
198+authorsLine :: MarkdownParser [Inlines]
194authorsLine = try $ do
199authorsLine = try $ do
196 skipSpaces
201 skipSpaces
@@ -199,13 +204,13 @@ authorsLine = try $ do
199 (char ';' <|>
204 (char ';' <|>
200 try (newline >> notFollowedBy blankline >> spaceChar))
205 try (newline >> notFollowedBy blankline >> spaceChar))
202− return $ sequence $ filter (not . isNull) $ map (trimInlinesF . mconcat) authors
207+ return $ filter (not . isNull) $ map (trimInlines . mconcat) authors
204−dateLine :: MarkdownParser (F Inlines)
209+dateLine :: MarkdownParser Inlines
205dateLine = try $ do
210dateLine = try $ do
207 skipSpaces
212 skipSpaces
208− trimInlinesF . mconcat <$> manyTill inline newline
213+ trimInlines . mconcat <$> manyTill inline newline
210titleBlock :: MarkdownParser ()
215titleBlock :: MarkdownParser ()
211titleBlock = pandocTitleBlock <|> mmdTitleBlock
216titleBlock = pandocTitleBlock <|> mmdTitleBlock
@@ -215,20 +220,16 @@ pandocTitleBlock = try $ do
215 guardEnabled Ext_pandoc_title_block
220 guardEnabled Ext_pandoc_title_block
216 lookAhead (char '%')
221 lookAhead (char '%')
217 title <- option mempty titleLine
222 title <- option mempty titleLine
218− author <- option (return []) authorsLine
223+ author <- option [] authorsLine
219 date <- option mempty dateLine
224 date <- option mempty dateLine
220 optional blanklines
225 optional blanklines
221− let meta' = do title' <- title
225− (if B.isNull title' then id else B.setMeta "title" title')
226+ let meta' = (if B.isNull title then id else B.setMeta "title" title)
226− . (if null author' then id else B.setMeta "author" author')
227+ . (if null author then id else B.setMeta "author" author)
227− . (if B.isNull date' then id else B.setMeta "date" date')
228+ . (if B.isNull date then id else B.setMeta "date" date)
228− $ nullMeta
229+ $ nullMeta
229− updateState $ \st -> st{ stateMeta' = stateMeta' st <> meta' }
230+ updateState $ \st -> st{ stateMeta = stateMeta st <> meta' }
231−yamlMetaBlock :: MarkdownParser (F Blocks)
232+yamlMetaBlock :: MarkdownParser Blocks
232yamlMetaBlock = try $ do
233yamlMetaBlock = try $ do
233 guardEnabled Ext_yaml_metadata_block
234 guardEnabled Ext_yaml_metadata_block
234 pos <- getPosition
235 pos <- getPosition
@@ -241,17 +242,17 @@ yamlMetaBlock = try $ do
241 optional blanklines
242 optional blanklines
242 opts <- stateOptions <$> getState
243 opts <- stateOptions <$> getState
243 meta' <- case Yaml.decodeEither' $ UTF8.fromString rawYaml of
244 meta' <- case Yaml.decodeEither' $ UTF8.fromString rawYaml of
244− Right (Yaml.Object hashmap) -> return $ return $
245+ Right (Yaml.Object hashmap) -> return $
245 H.foldrWithKey (\k v m ->
246 H.foldrWithKey (\k v m ->
246 if ignorable k
247 if ignorable k
248 else B.setMeta (T.unpack k)
249 else B.setMeta (T.unpack k)
249 (yamlToMeta opts v) m)
250 (yamlToMeta opts v) m)
250 nullMeta hashmap
251 nullMeta hashmap
251− Right Yaml.Null -> return $ return nullMeta
252+ Right Yaml.Null -> return nullMeta
252 Right _ -> do
253 Right _ -> do
253 addWarning (Just pos) "YAML header is not an object"
254 addWarning (Just pos) "YAML header is not an object"
254− return $ return nullMeta
255+ return nullMeta
255 Left err' -> do
256 Left err' -> do
256 case err' of
257 case err' of
257 InvalidYaml (Just YamlParseException{
258 InvalidYaml (Just YamlParseException{
@@ -270,13 +271,13 @@ yamlMetaBlock = try $ do
270 _ -> addWarning (Just pos)
271 _ -> addWarning (Just pos)
271 $ "Could not parse YAML header: " ++
272 $ "Could not parse YAML header: " ++
272 show err'
273 show err'
273− return $ return nullMeta
274+ return nullMeta
274− updateState $ \st -> st{ stateMeta' = stateMeta' st <> meta' }
275+ updateState $ \st -> st{ stateMeta = stateMeta st <> meta' }
275 return mempty
276 return mempty
277-- ignore fields ending with _
278-- ignore fields ending with _
278ignorable :: Text -> Bool
279ignorable :: Text -> Bool
279−ignorable t = (T.pack "_") `T.isSuffixOf` t
280+ignorable t = T.pack "_" `T.isSuffixOf` t
281toMetaValue :: ReaderOptions -> Text -> MetaValue
282toMetaValue :: ReaderOptions -> Text -> MetaValue
282toMetaValue opts x =
283toMetaValue opts x =
@@ -286,7 +287,7 @@ toMetaValue opts x =
286 | endsWithNewline x -> MetaBlocks [Para xs]
287 | endsWithNewline x -> MetaBlocks [Para xs]
287 | otherwise -> MetaInlines xs
288 | otherwise -> MetaInlines xs
288 Pandoc _ bs -> MetaBlocks bs
289 Pandoc _ bs -> MetaBlocks bs
289− where endsWithNewline t = (T.pack "\n") `T.isSuffixOf` t
290+ where endsWithNewline t = T.pack "\n" `T.isSuffixOf` t
291yamlToMeta :: ReaderOptions -> Yaml.Value -> MetaValue
292yamlToMeta :: ReaderOptions -> Yaml.Value -> MetaValue
292yamlToMeta opts (Yaml.String t) = toMetaValue opts t
293yamlToMeta opts (Yaml.String t) = toMetaValue opts t
@@ -314,8 +315,8 @@ mmdTitleBlock = try $ do
314 guardEnabled Ext_mmd_title_block
315 guardEnabled Ext_mmd_title_block
315 kvPairs <- many1 kvPair
316 kvPairs <- many1 kvPair
316 blanklines
317 blanklines
317− updateState $ \st -> st{ stateMeta' = stateMeta' st <>
318+ updateState $ \st -> st{ stateMeta = stateMeta st <>
318− return (Meta $ M.fromList kvPairs) }
319+ (Meta $ M.fromList kvPairs) }
320kvPair :: MarkdownParser (String, MetaValue)
321kvPair :: MarkdownParser (String, MetaValue)
321kvPair = try $ do
322kvPair = try $ do
@@ -335,11 +336,11 @@ parseMarkdown = do
335 optional titleBlock
336 optional titleBlock
336 blocks <- parseBlocks
337 blocks <- parseBlocks
337 st <- getState
338 st <- getState
338− let meta = runF (stateMeta' st) st
339+ let meta = stateMeta st
339− let Pandoc _ bs = B.doc $ runF blocks st
340+ let Pandoc _ bs = B.doc blocks
340 return $ Pandoc meta bs
341 return $ Pandoc meta bs
342−referenceKey :: MarkdownParser (F Blocks)
343+referenceKey :: MarkdownParser Blocks
343referenceKey = try $ do
344referenceKey = try $ do
344 pos <- getPosition
345 pos <- getPosition
345 skipNonindentSpaces
346 skipNonindentSpaces
@@ -366,7 +367,7 @@ referenceKey = try $ do
366 Just _ -> addWarning (Just pos) $ "Duplicate link reference `" ++ raw ++ "'"
367 Just _ -> addWarning (Just pos) $ "Duplicate link reference `" ++ raw ++ "'"
367 Nothing -> return ()
368 Nothing -> return ()
368 updateState $ \s -> s { stateKeys = M.insert key target oldkeys }
369 updateState $ \s -> s { stateKeys = M.insert key target oldkeys }
369− return $ return mempty
370+ return mempty
371referenceTitle :: MarkdownParser String
372referenceTitle :: MarkdownParser String
372referenceTitle = try $ do
373referenceTitle = try $ do
@@ -386,7 +387,7 @@ quotedTitle c = try $ do
386-- | PHP Markdown Extra style abbreviation key. Currently
387-- | PHP Markdown Extra style abbreviation key. Currently
387-- we just skip them, since Pandoc doesn't have an element for
388-- we just skip them, since Pandoc doesn't have an element for
388-- an abbreviation.
389-- an abbreviation.
389−abbrevKey :: MarkdownParser (F Blocks)
390+abbrevKey :: MarkdownParser Blocks
390abbrevKey = do
391abbrevKey = do
391 guardEnabled Ext_abbreviations
392 guardEnabled Ext_abbreviations
@@ -395,7 +396,7 @@ abbrevKey = do
396 skipMany (satisfy (/= '\n'))
397 skipMany (satisfy (/= '\n'))
397 blanklines
398 blanklines
398− return $ return mempty
399+ return mempty
400noteMarker :: MarkdownParser String
401noteMarker :: MarkdownParser String
401noteMarker = string "[^" >> many1Till (satisfy $ not . isBlank) (char ']')
402noteMarker = string "[^" >> many1Till (satisfy $ not . isBlank) (char ']')
@@ -413,7 +414,7 @@ rawLines = do
413 rest <- many rawLine
414 rest <- many rawLine
414 return $ unlines (first:rest)
415 return $ unlines (first:rest)
416−noteBlock :: MarkdownParser (F Blocks)
417+noteBlock :: MarkdownParser Blocks
417noteBlock = try $ do
418noteBlock = try $ do
418 pos <- getPosition
419 pos <- getPosition
419 skipNonindentSpaces
420 skipNonindentSpaces
@@ -425,7 +426,7 @@ noteBlock = try $ do
425 rest <- many $ try $ blanklines >> indentSpaces >> rawLines
426 rest <- many $ try $ blanklines >> indentSpaces >> rawLines
426 let raw = unlines (first:rest) ++ "\n"
427 let raw = unlines (first:rest) ++ "\n"
427 optional blanklines
428 optional blanklines
428− parsed <- parseFromString parseBlocks raw
429+ parsed <- parseFromString (inFootnote parseBlocks) raw
429 let newnote = (ref, parsed)
430 let newnote = (ref, parsed)
430 oldnotes <- stateNotes' <$> getState
431 oldnotes <- stateNotes' <$> getState
431 case lookup ref oldnotes of
432 case lookup ref oldnotes of
@@ -434,14 +435,22 @@ noteBlock = try $ do
434 updateState $ \s -> s { stateNotes' = newnote : oldnotes }
435 updateState $ \s -> s { stateNotes' = newnote : oldnotes }
435 return mempty
436 return mempty
438+inFootnote :: MarkdownParser a -> MarkdownParser a
440+ st <- stateInFootnote <$> getState
441+ updateState (\s -> s { stateInFootnote = True } )
443+ updateState (\s -> s { stateInFootnote = st } )
438-- parsing blocks
447-- parsing blocks
441−parseBlocks :: MarkdownParser (F Blocks)
450+parseBlocks :: MarkdownParser Blocks
442parseBlocks = mconcat <$> manyTill block eof
451parseBlocks = mconcat <$> manyTill block eof
444−block :: MarkdownParser (F Blocks)
453+block :: MarkdownParser Blocks
445block = do
454block = do
446 tr <- getOption readerTrace
455 tr <- getOption readerTrace
447 pos <- getPosition
456 pos <- getPosition
@@ -457,7 +466,7 @@ block = do
457 , htmlBlock
466 , htmlBlock
459 , codeBlockIndented
468 , codeBlockIndented
460− , guardEnabled Ext_latex_macros *> (macro >>= return . return)
469+ , guardEnabled Ext_latex_macros *> macro
461 , rawTeXBlock
470 , rawTeXBlock
462 , lineBlock
471 , lineBlock
463 , blockQuote
472 , blockQuote
@@ -470,29 +479,28 @@ block = do
472 ] <?> "block"
481 ] <?> "block"
473− when tr $ do
482+ when tr $
475 trace (printf "line %d: %s" (sourceLine pos)
483 trace (printf "line %d: %s" (sourceLine pos)
476− (take 60 $ show $ B.toList $ runF res st)) (return ())
484+ (take 60 . show . B.toList $ res)) (return ())
477 return res
485 return res
480-- header blocks
488-- header blocks
483−header :: MarkdownParser (F Blocks)
491+header :: MarkdownParser Blocks
484header = setextHeader <|> atxHeader <?> "header"
492header = setextHeader <|> atxHeader <?> "header"
486−atxHeader :: MarkdownParser (F Blocks)
494+atxHeader :: MarkdownParser Blocks
487atxHeader = try $ do
495atxHeader = try $ do
488− level <- many1 (char '#') >>= return . length
496+ level <- length <$> many1 (char '#')
489 notFollowedBy $ guardEnabled Ext_fancy_lists >>
497 notFollowedBy $ guardEnabled Ext_fancy_lists >>
490 (char '.' <|> char ')') -- this would be a list
498 (char '.' <|> char ')') -- this would be a list
491 skipSpaces
499 skipSpaces
492− text <- trimInlinesF . mconcat <$> many (notFollowedBy atxClosing >> inline)
500+ text <- trimInlines . mconcat <$> many (notFollowedBy atxClosing >> inline)
493 attr <- atxClosing
501 attr <- atxClosing
494− attr' <- registerHeader attr (runF text defaultParserState)
502+ attr' <- registerHeader attr text
495− return $ B.headerWith attr' level <$> text
503+ return $ B.headerWith attr' level text
497atxClosing :: MarkdownParser Attr
505atxClosing :: MarkdownParser Attr
498atxClosing = try $ do
506atxClosing = try $ do
@@ -519,25 +527,25 @@ mmdHeaderIdentifier = do
519 skipSpaces
527 skipSpaces
520 return (ident,[],[])
528 return (ident,[],[])
522−setextHeader :: MarkdownParser (F Blocks)
530+setextHeader :: MarkdownParser Blocks
523setextHeader = try $ do
531setextHeader = try $ do
524 -- This lookahead prevents us from wasting time parsing Inlines
532 -- This lookahead prevents us from wasting time parsing Inlines
525 -- unless necessary -- it gives a significant performance boost.
533 -- unless necessary -- it gives a significant performance boost.
526 lookAhead $ anyLine >> many1 (oneOf setextHChars) >> blankline
534 lookAhead $ anyLine >> many1 (oneOf setextHChars) >> blankline
527− text <- trimInlinesF . mconcat <$> many1 (notFollowedBy setextHeaderEnd >> inline)
535+ text <- trimInlines . mconcat <$> many1 (notFollowedBy setextHeaderEnd >> inline)
528 attr <- setextHeaderEnd
536 attr <- setextHeaderEnd
529 underlineChar <- oneOf setextHChars
537 underlineChar <- oneOf setextHChars
530 many (char underlineChar)
538 many (char underlineChar)
531 blanklines
539 blanklines
532− let level = (fromMaybe 0 $ findIndex (== underlineChar) setextHChars) + 1
540+ let level = (fromMaybe 0 $ elemIndex underlineChar setextHChars) + 1
533− attr' <- registerHeader attr (runF text defaultParserState)
541+ attr' <- registerHeader attr text
534− return $ B.headerWith attr' level <$> text
542+ return $ B.headerWith attr' level text
537-- hrule block
545-- hrule block
540−hrule :: Parser [Char] st (F Blocks)
548+hrule :: Monad m => ParserT [Char] st m Blocks
541hrule = try $ do
549hrule = try $ do
542 skipSpaces
550 skipSpaces
543 start <- satisfy isHruleChar
551 start <- satisfy isHruleChar
@@ -545,24 +553,24 @@ hrule = try $ do
545 skipMany (spaceChar <|> char start)
553 skipMany (spaceChar <|> char start)
547 optional blanklines
555 optional blanklines
548− return $ return B.horizontalRule
556+ return B.horizontalRule
551-- code blocks
559-- code blocks
554indentedLine :: MarkdownParser String
562indentedLine :: MarkdownParser String
555−indentedLine = indentSpaces >> anyLine >>= return . (++ "\n")
563+indentedLine = indentSpaces >> ((++ "\n") <$> anyLine)
557−blockDelimiter :: (Char -> Bool)
565+blockDelimiter :: Monad m
558 -> Maybe Int
567 -> Maybe Int
559− -> Parser [Char] st Int
568+ -> ParserT [Char] st m Int
560blockDelimiter f len = try $ do
569blockDelimiter f len = try $ do
561 c <- lookAhead (satisfy f)
570 c <- lookAhead (satisfy f)
562 case len of
571 case len of
563 Just l -> count l (char c) >> many (char c) >> return l
572 Just l -> count l (char c) >> many (char c) >> return l
564− Nothing -> count 3 (char c) >> many (char c) >>=
573+ Nothing -> count 3 (char c) >> ((+ 3) . length <$> many (char c))
565− return . (+ 3) . length
567attributes :: MarkdownParser Attr
575attributes :: MarkdownParser Attr
568attributes = try $ do
576attributes = try $ do
@@ -607,7 +615,7 @@ specialAttr = do
608 return $ \(id',cs,kvs) -> (id',cs ++ ["unnumbered"],kvs)
616 return $ \(id',cs,kvs) -> (id',cs ++ ["unnumbered"],kvs)
610−codeBlockFenced :: MarkdownParser (F Blocks)
618+codeBlockFenced :: MarkdownParser Blocks
611codeBlockFenced = try $ do
619codeBlockFenced = try $ do
612 c <- try (guardEnabled Ext_fenced_code_blocks >> lookAhead (char '~'))
620 c <- try (guardEnabled Ext_fenced_code_blocks >> lookAhead (char '~'))
613 <|> (guardEnabled Ext_backtick_code_blocks >> lookAhead (char '`'))
621 <|> (guardEnabled Ext_backtick_code_blocks >> lookAhead (char '`'))
@@ -619,7 +627,7 @@ codeBlockFenced = try $ do
619 blankline
627 blankline
620 contents <- manyTill anyLine (blockDelimiter (== c) (Just size))
628 contents <- manyTill anyLine (blockDelimiter (== c) (Just size))
621 blanklines
629 blanklines
622− return $ return $ B.codeBlockWith attr $ intercalate "\n" contents
630+ return $ B.codeBlockWith attr $ intercalate "\n" contents
624-- correctly handle github language identifiers
632-- correctly handle github language identifiers
625toLanguageId :: String -> String
633toLanguageId :: String -> String
@@ -628,7 +636,7 @@ toLanguageId = map toLower . go
628 go "objective-c" = "objectivec"
636 go "objective-c" = "objectivec"
631−codeBlockIndented :: MarkdownParser (F Blocks)
639+codeBlockIndented :: MarkdownParser Blocks
632codeBlockIndented = do
640codeBlockIndented = do
633 contents <- many1 (indentedLine <|>
641 contents <- many1 (indentedLine <|>
634 try (do b <- blanklines
642 try (do b <- blanklines
@@ -636,15 +644,15 @@ codeBlockIndented = do
636 return $ b ++ l))
644 return $ b ++ l))
637 optional blanklines
645 optional blanklines
638 classes <- getOption readerIndentedCodeClasses
646 classes <- getOption readerIndentedCodeClasses
639− return $ return $ B.codeBlockWith ("", classes, []) $
647+ return $ B.codeBlockWith ("", classes, []) $
640 stripTrailingNewlines $ concat contents
648 stripTrailingNewlines $ concat contents
642−lhsCodeBlock :: MarkdownParser (F Blocks)
650+lhsCodeBlock :: MarkdownParser Blocks
643lhsCodeBlock = do
651lhsCodeBlock = do
644 guardEnabled Ext_literate_haskell
652 guardEnabled Ext_literate_haskell
645− (return . B.codeBlockWith ("",["sourceCode","literate","haskell"],[]) <$>
653+ (B.codeBlockWith ("",["sourceCode","literate","haskell"],[]) <$>
646 (lhsCodeBlockBird <|> lhsCodeBlockLaTeX))
654 (lhsCodeBlockBird <|> lhsCodeBlockLaTeX))
647− <|> (return . B.codeBlockWith ("",["sourceCode","haskell"],[]) <$>
655+ <|> (B.codeBlockWith ("",["sourceCode","haskell"],[]) <$>
648 lhsCodeBlockInverseBird)
656 lhsCodeBlockInverseBird)
650lhsCodeBlockLaTeX :: MarkdownParser String
658lhsCodeBlockLaTeX :: MarkdownParser String
@@ -673,7 +681,7 @@ lhsCodeBlockBirdWith c = try $ do
673 blanklines
681 blanklines
674 return $ intercalate "\n" lns'
682 return $ intercalate "\n" lns'
676−birdTrackLine :: Char -> Parser [Char] st String
684+birdTrackLine :: Monad m => Char -> ParserT [Char] st m String
677birdTrackLine c = try $ do
685birdTrackLine c = try $ do
679 -- allow html tags on left margin:
687 -- allow html tags on left margin:
@@ -701,12 +709,12 @@ emailBlockQuote = try $ do
701 optional blanklines
709 optional blanklines
702 return raw
710 return raw
704−blockQuote :: MarkdownParser (F Blocks)
712+blockQuote :: MarkdownParser Blocks
705blockQuote = do
713blockQuote = do
706 raw <- emailBlockQuote
714 raw <- emailBlockQuote
707 -- parse the extracted block, which may contain various block elements:
715 -- parse the extracted block, which may contain various block elements:
708− contents <- parseFromString parseBlocks $ (intercalate "\n" raw) ++ "\n\n"
716+ contents <- parseFromString parseBlocks $ intercalate "\n" raw ++ "\n\n"
709− return $ B.blockQuote <$> contents
717+ return $ B.blockQuote contents
712-- list blocks
720-- list blocks
@@ -749,7 +757,7 @@ anyOrderedListStart = try $ do
749 return res
757 return res
751listStart :: MarkdownParser ()
759listStart :: MarkdownParser ()
752−listStart = bulletListStart <|> (anyOrderedListStart >> return ())
760+listStart = bulletListStart <|> void anyOrderedListStart
754listLine :: MarkdownParser String
762listLine :: MarkdownParser String
755listLine = try $ do
763listLine = try $ do
@@ -804,7 +812,7 @@ listContinuationLine = try $ do
804 return $ result ++ "\n"
812 return $ result ++ "\n"
806listItem :: MarkdownParser a
814listItem :: MarkdownParser a
807− -> MarkdownParser (F Blocks)
815+ -> MarkdownParser Blocks
808listItem start = try $ do
816listItem start = try $ do
809 first <- rawListItem start
817 first <- rawListItem start
810 continuations <- many listContinuation
818 continuations <- many listContinuation
@@ -820,14 +828,14 @@ listItem start = try $ do
820 updateState (\st -> st {stateParserContext = oldContext})
828 updateState (\st -> st {stateParserContext = oldContext})
821 return contents
829 return contents
823−orderedList :: MarkdownParser (F Blocks)
831+orderedList :: MarkdownParser Blocks
824orderedList = try $ do
832orderedList = try $ do
825 (start, style, delim) <- lookAhead anyOrderedListStart
833 (start, style, delim) <- lookAhead anyOrderedListStart
826 unless (style `elem` [DefaultStyle, Decimal, Example] &&
834 unless (style `elem` [DefaultStyle, Decimal, Example] &&
827 delim `elem` [DefaultDelim, Period]) $
835 delim `elem` [DefaultDelim, Period]) $
828 guardEnabled Ext_fancy_lists
836 guardEnabled Ext_fancy_lists
829 when (style == Example) $ guardEnabled Ext_example_lists
837 when (style == Example) $ guardEnabled Ext_example_lists
830− items <- fmap sequence $ many1 $ listItem
838+ items <- many1 $ listItem
831 ( try $ do
839 ( try $ do
832 optional newline -- if preceded by Plain block in a list
840 optional newline -- if preceded by Plain block in a list
833 startpos <- sourceColumn <$> getPosition
841 startpos <- sourceColumn <$> getPosition
@@ -839,12 +847,12 @@ orderedList = try $ do
839 atMostSpaces (tabStop - (endpos - startpos))
847 atMostSpaces (tabStop - (endpos - startpos))
840 return res )
848 return res )
841 start' <- option 1 $ guardEnabled Ext_startnum >> return start
849 start' <- option 1 $ guardEnabled Ext_startnum >> return start
842− return $ B.orderedListWith (start', style, delim) <$> fmap compactify' items
850+ return $ B.orderedListWith (start', style, delim) (compactify' items)
844−bulletList :: MarkdownParser (F Blocks)
852+bulletList :: MarkdownParser Blocks
845bulletList = do
853bulletList = do
846− items <- fmap sequence $ many1 $ listItem bulletListStart
854+ items <- many1 $ listItem bulletListStart
847− return $ B.bulletList <$> fmap compactify' items
855+ return $ B.bulletList (compactify' items)
849-- definition lists
857-- definition lists
@@ -859,14 +867,14 @@ defListMarker = do
859 else mzero
867 else mzero
860 return ()
868 return ()
862−definitionListItem :: Bool -> MarkdownParser (F (Inlines, [Blocks]))
870+definitionListItem :: Bool -> MarkdownParser (Inlines, [Blocks])
863definitionListItem compact = try $ do
871definitionListItem compact = try $ do
864 rawLine' <- anyLine
872 rawLine' <- anyLine
865 raw <- many1 $ defRawBlock compact
873 raw <- many1 $ defRawBlock compact
866− term <- parseFromString (trimInlinesF . mconcat <$> many inline) rawLine'
874+ term <- parseFromString (trimInlines . mconcat <$> many inline) rawLine'
867 contents <- mapM (parseFromString parseBlocks) raw
875 contents <- mapM (parseFromString parseBlocks) raw
868 optional blanklines
876 optional blanklines
869− return $ liftM2 (,) term (sequence contents)
877+ return (term, contents)
871defRawBlock :: Bool -> MarkdownParser String
879defRawBlock :: Bool -> MarkdownParser String
872defRawBlock compact = try $ do
880defRawBlock compact = try $ do
@@ -889,32 +897,32 @@ defRawBlock compact = try $ do
889 return $ trimr (firstline ++ "\n" ++ unlines rawlines ++ cont) ++
897 return $ trimr (firstline ++ "\n" ++ unlines rawlines ++ cont) ++
890 if hasBlank || not (null cont) then "\n\n" else ""
898 if hasBlank || not (null cont) then "\n\n" else ""
892−definitionList :: MarkdownParser (F Blocks)
900+definitionList :: MarkdownParser Blocks
893definitionList = try $ do
901definitionList = try $ do
894 lookAhead (anyLine >> optional blankline >> defListMarker)
902 lookAhead (anyLine >> optional blankline >> defListMarker)
895 compactDefinitionList <|> normalDefinitionList
903 compactDefinitionList <|> normalDefinitionList
897−compactDefinitionList :: MarkdownParser (F Blocks)
905+compactDefinitionList :: MarkdownParser Blocks
898compactDefinitionList = do
906compactDefinitionList = do
899 guardEnabled Ext_compact_definition_lists
907 guardEnabled Ext_compact_definition_lists
900− items <- fmap sequence $ many1 $ definitionListItem True
908+ items <- many1 $ definitionListItem True
901− return $ B.definitionList <$> fmap compactify'DL items
909+ return $ B.definitionList (compactify'DL items)
903−normalDefinitionList :: MarkdownParser (F Blocks)
911+normalDefinitionList :: MarkdownParser Blocks
904normalDefinitionList = do
912normalDefinitionList = do
905 guardEnabled Ext_definition_lists
913 guardEnabled Ext_definition_lists
906− items <- fmap sequence $ many1 $ definitionListItem False
914+ items <- many1 $ definitionListItem False
907− return $ B.definitionList <$> items
915+ return $ B.definitionList items
910-- paragraph block
918-- paragraph block
913−para :: MarkdownParser (F Blocks)
921+para :: MarkdownParser Blocks
914para = try $ do
922para = try $ do
915 exts <- getOption readerExtensions
923 exts <- getOption readerExtensions
916− result <- trimInlinesF . mconcat <$> many1 inline
924+ result <- trimInlines . mconcat <$> many1 inline
917− option (B.plain <$> result)
925+ option (B.plain result)
918 $ try $ do
926 $ try $ do
920 (blanklines >> return mempty)
928 (blanklines >> return mempty)
@@ -931,18 +939,17 @@ para = try $ do
931 Just "div" -> () <$
939 Just "div" -> () <$
932 lookAhead (htmlTag (~== TagClose "div"))
940 lookAhead (htmlTag (~== TagClose "div"))
933 _ -> mzero
941 _ -> mzero
934− return $ do
942+ return $
936− case B.toList result' of
943+ case B.toList result of
937 [Image alt (src,tit)]
944 [Image alt (src,tit)]
938 | Ext_implicit_figures `Set.member` exts ->
945 | Ext_implicit_figures `Set.member` exts ->
939 -- the fig: at beginning of title indicates a figure
946 -- the fig: at beginning of title indicates a figure
940− return $ B.para $ B.singleton
947+ B.para $ B.singleton
941 $ Image alt (src,'f':'i':'g':':':tit)
948 $ Image alt (src,'f':'i':'g':':':tit)
942− _ -> return $ B.para result'
949+ _ -> B.para result
944−plain :: MarkdownParser (F Blocks)
951+plain :: MarkdownParser Blocks
945−plain = fmap B.plain . trimInlinesF . mconcat <$> many1 inline
952+plain = B.plain . trimInlines . mconcat <$> many1 inline
948-- raw html
955-- raw html
@@ -953,13 +960,13 @@ htmlElement = rawVerbatimBlock
953 <|> strictHtmlBlock
960 <|> strictHtmlBlock
954 <|> liftM snd (htmlTag isBlockTag)
961 <|> liftM snd (htmlTag isBlockTag)
956−htmlBlock :: MarkdownParser (F Blocks)
963+htmlBlock :: MarkdownParser Blocks
957htmlBlock = do
964htmlBlock = do
958 guardEnabled Ext_raw_html
965 guardEnabled Ext_raw_html
960 (TagOpen t attrs) <- lookAhead $ fst <$> htmlTag isBlockTag
967 (TagOpen t attrs) <- lookAhead $ fst <$> htmlTag isBlockTag
961 (guard (t `elem` ["pre","style","script"]) >>
968 (guard (t `elem` ["pre","style","script"]) >>
962− (return . B.rawBlock "html") <$> rawVerbatimBlock)
969+ B.rawBlock "html" <$> rawVerbatimBlock)
963 <|> (do guardEnabled Ext_markdown_attribute
970 <|> (do guardEnabled Ext_markdown_attribute
964 oldMarkdownAttribute <- stateMarkdownAttribute <$> getState
971 oldMarkdownAttribute <- stateMarkdownAttribute <$> getState
965 markdownAttribute <-
972 markdownAttribute <-
@@ -978,35 +985,35 @@ htmlBlock = do
978 <|> (guardEnabled Ext_markdown_in_html_blocks >> rawHtmlBlocks))
985 <|> (guardEnabled Ext_markdown_in_html_blocks >> rawHtmlBlocks))
979 <|> htmlBlock'
986 <|> htmlBlock'
981−htmlBlock' :: MarkdownParser (F Blocks)
988+htmlBlock' :: MarkdownParser Blocks
982htmlBlock' = try $ do
989htmlBlock' = try $ do
983 first <- htmlElement
990 first <- htmlElement
984 skipMany spaceChar
991 skipMany spaceChar
985 optional blanklines
992 optional blanklines
986− return $ return $ B.rawBlock "html" first
993+ return $ B.rawBlock "html" first
988strictHtmlBlock :: MarkdownParser String
995strictHtmlBlock :: MarkdownParser String
989strictHtmlBlock = htmlInBalanced (not . isInlineTag)
996strictHtmlBlock = htmlInBalanced (not . isInlineTag)
991rawVerbatimBlock :: MarkdownParser String
998rawVerbatimBlock :: MarkdownParser String
992rawVerbatimBlock = try $ do
999rawVerbatimBlock = try $ do
993− (TagOpen tag _, open) <- htmlTag (tagOpen (flip elem
1000+ (TagOpen tag _, open) <-
994− ["pre", "style", "script"])
1001+ htmlTag (tagOpen (`elem` ["pre", "style", "script"])
995− (const True))
1002+ (const True))
996 contents <- manyTill anyChar (htmlTag (~== TagClose tag))
1003 contents <- manyTill anyChar (htmlTag (~== TagClose tag))
997 return $ open ++ contents ++ renderTags' [TagClose tag]
1004 return $ open ++ contents ++ renderTags' [TagClose tag]
999−rawTeXBlock :: MarkdownParser (F Blocks)
1006+rawTeXBlock :: MarkdownParser Blocks
1000rawTeXBlock = do
1007rawTeXBlock = do
1001 guardEnabled Ext_raw_tex
1008 guardEnabled Ext_raw_tex
1002 result <- (B.rawBlock "latex" . concat <$>
1009 result <- (B.rawBlock "latex" . concat <$>
1003− rawLaTeXBlock `sepEndBy1` blankline)
1010+ generalize rawLaTeXBlock `sepEndBy1` blankline)
1004 <|> (B.rawBlock "context" . concat <$>
1011 <|> (B.rawBlock "context" . concat <$>
1005 rawConTeXtEnvironment `sepEndBy1` blankline)
1012 rawConTeXtEnvironment `sepEndBy1` blankline)
1007− return $ return result
1014+ return result
1009−rawHtmlBlocks :: MarkdownParser (F Blocks)
1016+rawHtmlBlocks :: MarkdownParser Blocks
1010rawHtmlBlocks = do
1017rawHtmlBlocks = do
1011 (TagOpen tagtype _, raw) <- htmlTag isBlockTag
1018 (TagOpen tagtype _, raw) <- htmlTag isBlockTag
1012 -- try to find closing tag
1019 -- try to find closing tag
@@ -1018,10 +1025,10 @@ rawHtmlBlocks = do
1018 contents <- mconcat <$> many (notFollowedBy' closer >> block)
1025 contents <- mconcat <$> many (notFollowedBy' closer >> block)
1019 result <-
1026 result <-
1020 (closer >>= \(_, rawcloser) -> return (
1027 (closer >>= \(_, rawcloser) -> return (
1021− return (B.rawBlock "html" $ stripMarkdownAttribute raw) <>
1028+ (B.rawBlock "html" $ stripMarkdownAttribute raw) <>
1022 contents <>
1029 contents <>
1023− return (B.rawBlock "html" rawcloser)))
1030+ (B.rawBlock "html" rawcloser)))
1024− <|> return (return (B.rawBlock "html" raw) <> contents)
1031+ <|> return (B.rawBlock "html" raw <> contents)
1025 updateState $ \st -> st{ stateInHtmlBlock = oldInHtmlBlock }
1032 updateState $ \st -> st{ stateInHtmlBlock = oldInHtmlBlock }
1026 return result
1033 return result
@@ -1036,12 +1043,12 @@ stripMarkdownAttribute s = renderTags' $ map filterAttrib $ parseTags s
1036-- line block
1043-- line block
1039−lineBlock :: MarkdownParser (F Blocks)
1046+lineBlock :: MarkdownParser Blocks
1040lineBlock = try $ do
1047lineBlock = try $ do
1041 guardEnabled Ext_line_blocks
1048 guardEnabled Ext_line_blocks
1042 lines' <- lineBlockLines >>=
1049 lines' <- lineBlockLines >>=
1043− mapM (parseFromString (trimInlinesF . mconcat <$> many inline))
1050+ mapM (parseFromString (trimInlines . mconcat <$> many inline))
1044− return $ B.para <$> (mconcat $ intersperse (return B.linebreak) lines')
1051+ return $ B.para (mconcat $ intersperse B.linebreak lines')
1047-- Tables
1054-- Tables
@@ -1049,17 +1056,17 @@ lineBlock = try $ do
1050-- Parse a dashed line with optional trailing spaces; return its length
1057-- Parse a dashed line with optional trailing spaces; return its length
1051-- and the length including trailing space.
1058-- and the length including trailing space.
1052−dashedLine :: Char
1059+dashedLine :: Monad m => Char
1053− -> Parser [Char] st (Int, Int)
1060+ -> ParserT [Char] st m (Int, Int)
1054dashedLine ch = do
1061dashedLine ch = do
1055 dashes <- many1 (char ch)
1062 dashes <- many1 (char ch)
1056 sp <- many spaceChar
1063 sp <- many spaceChar
1057− return $ (length dashes, length $ dashes ++ sp)
1064+ return (length dashes, length $ dashes ++ sp)
1059-- Parse a table header with dashed lines of '-' preceded by
1066-- Parse a table header with dashed lines of '-' preceded by
1060-- one (or zero) line of text.
1067-- one (or zero) line of text.
1061simpleTableHeader :: Bool -- ^ Headerless table
1068simpleTableHeader :: Bool -- ^ Headerless table
1062− -> MarkdownParser (F [Blocks], [Alignment], [Int])
1069+ -> MarkdownParser ([Blocks], [Alignment], [Int])
1063simpleTableHeader headless = try $ do
1070simpleTableHeader headless = try $ do
1064 rawContent <- if headless
1071 rawContent <- if headless
1065 then return ""
1072 then return ""
@@ -1078,9 +1085,8 @@ simpleTableHeader headless = try $ do
1078 let rawHeads' = if headless
1085 let rawHeads' = if headless
1079 then replicate (length dashes) ""
1086 then replicate (length dashes) ""
1080 else rawHeads
1087 else rawHeads
1081− heads <- fmap sequence
1088+ heads <-
1082− $ mapM (parseFromString (mconcat <$> many plain))
1089+ mapM (parseFromString (mconcat <$> many plain) . trim) rawHeads'
1083− $ map trim rawHeads'
1084 return (heads, aligns, indices)
1090 return (heads, aligns, indices)
1086-- Returns an alignment type for a table, based on a list of strings
1092-- Returns an alignment type for a table, based on a list of strings
@@ -1121,30 +1127,30 @@ rawTableLine indices = do
1122-- Parse a table line and return a list of lists of blocks (columns).
1128-- Parse a table line and return a list of lists of blocks (columns).
1123tableLine :: [Int]
1129tableLine :: [Int]
1124− -> MarkdownParser (F [Blocks])
1130+ -> MarkdownParser [Blocks]
1125tableLine indices = rawTableLine indices >>=
1131tableLine indices = rawTableLine indices >>=
1126− fmap sequence . mapM (parseFromString (mconcat <$> many plain))
1132+ mapM (parseFromString (mconcat <$> many plain))
1128-- Parse a multiline table row and return a list of blocks (columns).
1134-- Parse a multiline table row and return a list of blocks (columns).
1129multilineRow :: [Int]
1135multilineRow :: [Int]
1130− -> MarkdownParser (F [Blocks])
1136+ -> MarkdownParser [Blocks]
1131multilineRow indices = do
1137multilineRow indices = do
1132 colLines <- many1 (rawTableLine indices)
1138 colLines <- many1 (rawTableLine indices)
1133 let cols = map unlines $ transpose colLines
1139 let cols = map unlines $ transpose colLines
1134− fmap sequence $ mapM (parseFromString (mconcat <$> many plain)) cols
1140+ mapM (parseFromString (mconcat <$> many plain)) cols
1136-- Parses a table caption: inlines beginning with 'Table:'
1142-- Parses a table caption: inlines beginning with 'Table:'
1137-- and followed by blank lines.
1143-- and followed by blank lines.
1138−tableCaption :: MarkdownParser (F Inlines)
1144+tableCaption :: MarkdownParser Inlines
1139tableCaption = try $ do
1145tableCaption = try $ do
1140 guardEnabled Ext_table_captions
1146 guardEnabled Ext_table_captions
1141 skipNonindentSpaces
1147 skipNonindentSpaces
1142 string ":" <|> string "Table:"
1148 string ":" <|> string "Table:"
1143− trimInlinesF . mconcat <$> many1 inline <* blanklines
1149+ trimInlines . mconcat <$> many1 inline <* blanklines
1145-- Parse a simple table with '---' header and one line per row.
1151-- Parse a simple table with '---' header and one line per row.
1146simpleTable :: Bool -- ^ Headerless table
1152simpleTable :: Bool -- ^ Headerless table
1147− -> MarkdownParser ([Alignment], [Double], F [Blocks], F [[Blocks]])
1153+ -> MarkdownParser ([Alignment], [Double], [Blocks], [[Blocks]])
1148simpleTable headless = do
1154simpleTable headless = do
1149 (aligns, _widths, heads', lines') <-
1155 (aligns, _widths, heads', lines') <-
1150 tableWith (simpleTableHeader headless) tableLine
1156 tableWith (simpleTableHeader headless) tableLine
@@ -1158,12 +1164,12 @@ simpleTable headless = do
1158-- which may be multiline, separated by blank lines, and
1164-- which may be multiline, separated by blank lines, and
1159-- ending with a footer (dashed line followed by blank line).
1165-- ending with a footer (dashed line followed by blank line).
1160multilineTable :: Bool -- ^ Headerless table
1166multilineTable :: Bool -- ^ Headerless table
1161− -> MarkdownParser ([Alignment], [Double], F [Blocks], F [[Blocks]])
1167+ -> MarkdownParser ([Alignment], [Double], [Blocks], [[Blocks]])
1162multilineTable headless =
1168multilineTable headless =
1163 tableWith (multilineTableHeader headless) multilineRow blanklines tableFooter
1169 tableWith (multilineTableHeader headless) multilineRow blanklines tableFooter
1165multilineTableHeader :: Bool -- ^ Headerless table
1171multilineTableHeader :: Bool -- ^ Headerless table
1166− -> MarkdownParser (F [Blocks], [Alignment], [Int])
1172+ -> MarkdownParser ([Blocks], [Alignment], [Int])
1167multilineTableHeader headless = try $ do
1173multilineTableHeader headless = try $ do
1168 unless headless $
1174 unless headless $
1169 tableSep >> notFollowedBy blankline
1175 tableSep >> notFollowedBy blankline
@@ -1185,7 +1191,7 @@ multilineTableHeader headless = try $ do
1185 let rawHeads = if headless
1191 let rawHeads = if headless
1186 then replicate (length dashes) ""
1192 then replicate (length dashes) ""
1187 else map (unlines . map trim) rawHeadsList
1193 else map (unlines . map trim) rawHeadsList
1188− heads <- fmap sequence $
1194+ heads <-
1189 mapM (parseFromString (mconcat <$> many plain)) $
1195 mapM (parseFromString (mconcat <$> many plain)) $
1190 map trim rawHeads
1196 map trim rawHeads
1191 return (heads, aligns, indices)
1197 return (heads, aligns, indices)
@@ -1195,7 +1201,7 @@ multilineTableHeader headless = try $ do
1195-- which may be grid, separated by blank lines, and
1201-- which may be grid, separated by blank lines, and
1196-- ending with a footer (dashed line followed by blank line).
1202-- ending with a footer (dashed line followed by blank line).
1197gridTable :: Bool -- ^ Headerless table
1203gridTable :: Bool -- ^ Headerless table
1198− -> MarkdownParser ([Alignment], [Double], F [Blocks], F [[Blocks]])
1204+ -> MarkdownParser ([Alignment], [Double], [Blocks], [[Blocks]])
1199gridTable headless =
1205gridTable headless =
1200 tableWith (gridTableHeader headless) gridTableRow
1206 tableWith (gridTableHeader headless) gridTableRow
1201 (gridTableSep '-') gridTableFooter
1207 (gridTableSep '-') gridTableFooter
@@ -1204,13 +1210,13 @@ gridTableSplitLine :: [Int] -> String -> [String]
1204gridTableSplitLine indices line = map removeFinalBar $ tail $
1210gridTableSplitLine indices line = map removeFinalBar $ tail $
1205 splitStringByIndices (init indices) $ trimr line
1211 splitStringByIndices (init indices) $ trimr line
1207−gridPart :: Char -> Parser [Char] st (Int, Int)
1213+gridPart :: Monad m => Char -> ParserT [Char] st m (Int, Int)
1208gridPart ch = do
1214gridPart ch = do
1209 dashes <- many1 (char ch)
1215 dashes <- many1 (char ch)
1210 char '+'
1216 char '+'
1211 return (length dashes, length dashes + 1)
1217 return (length dashes, length dashes + 1)
1213−gridDashedLines :: Char -> Parser [Char] st [(Int,Int)]
1219+gridDashedLines :: Monad m => Char -> ParserT [Char] st m [(Int,Int)]
1214gridDashedLines ch = try $ char '+' >> many1 (gridPart ch) <* blankline
1220gridDashedLines ch = try $ char '+' >> many1 (gridPart ch) <* blankline
1216removeFinalBar :: String -> String
1222removeFinalBar :: String -> String
@@ -1223,7 +1229,7 @@ gridTableSep ch = try $ gridDashedLines ch >> return '\n'
1224-- | Parse header for a grid table.
1230-- | Parse header for a grid table.
1225gridTableHeader :: Bool -- ^ Headerless table
1231gridTableHeader :: Bool -- ^ Headerless table
1226− -> MarkdownParser (F [Blocks], [Alignment], [Int])
1232+ -> MarkdownParser ([Blocks], [Alignment], [Int])
1227gridTableHeader headless = try $ do
1233gridTableHeader headless = try $ do
1228 optional blanklines
1234 optional blanklines
1229 dashes <- gridDashedLines '-'
1235 dashes <- gridDashedLines '-'
@@ -1232,9 +1238,7 @@ gridTableHeader headless = try $ do
1232 else many1
1238 else many1
1233 (notFollowedBy (gridTableSep '=') >> char '|' >>
1239 (notFollowedBy (gridTableSep '=') >> char '|' >>
1234 many1Till anyChar newline)
1240 many1Till anyChar newline)
1237− else gridTableSep '=' >> return ()
1241+ unless headless (void $ gridTableSep '=')
1238 let lines' = map snd dashes
1242 let lines' = map snd dashes
1239 let indices = scanl (+) 0 lines'
1243 let indices = scanl (+) 0 lines'
1240 let aligns = replicate (length lines') AlignDefault
1244 let aligns = replicate (length lines') AlignDefault
@@ -1243,7 +1247,7 @@ gridTableHeader headless = try $ do
1243 then replicate (length dashes) ""
1247 then replicate (length dashes) ""
1244 else map (unlines . map trim) $ transpose
1248 else map (unlines . map trim) $ transpose
1245 $ map (gridTableSplitLine indices) rawContent
1249 $ map (gridTableSplitLine indices) rawContent
1246− heads <- fmap sequence $ mapM (parseFromString parseBlocks . trim) rawHeads
1250+ heads <- mapM (parseFromString parseBlocks . trim) rawHeads
1247 return (heads, aligns, indices)
1251 return (heads, aligns, indices)
1249gridTableRawLine :: [Int] -> MarkdownParser [String]
1253gridTableRawLine :: [Int] -> MarkdownParser [String]
@@ -1254,12 +1258,12 @@ gridTableRawLine indices = do
1255-- | Parse row of grid table.
1259-- | Parse row of grid table.
1256gridTableRow :: [Int]
1260gridTableRow :: [Int]
1257− -> MarkdownParser (F [Blocks])
1261+ -> MarkdownParser [Blocks]
1258gridTableRow indices = do
1262gridTableRow indices = do
1259 colLines <- many1 (gridTableRawLine indices)
1263 colLines <- many1 (gridTableRawLine indices)
1260 let cols = map ((++ "\n") . unlines . removeOneLeadingSpace) $
1264 let cols = map ((++ "\n") . unlines . removeOneLeadingSpace) $
1261 transpose colLines
1265 transpose colLines
1262− fmap compactify' <$> fmap sequence (mapM (parseFromString parseBlocks) cols)
1266+ compactify' <$> mapM (parseFromString parseBlocks) cols
1264removeOneLeadingSpace :: [String] -> [String]
1268removeOneLeadingSpace :: [String] -> [String]
1265removeOneLeadingSpace xs =
1269removeOneLeadingSpace xs =
@@ -1285,14 +1289,12 @@ pipeBreak = try $ do
1285 blankline
1289 blankline
1286 return (first:rest)
1290 return (first:rest)
1288−pipeTable :: MarkdownParser ([Alignment], [Double], F [Blocks], F [[Blocks]])
1292+pipeTable :: MarkdownParser ([Alignment], [Double], [Blocks], [[Blocks]])
1289pipeTable = try $ do
1293pipeTable = try $ do
1290− (heads,aligns) <- pipeTableRow >>= \row ->
1294+ (heads,aligns) <- (,) <$> pipeTableRow <*> pipeBreak
1291− pipeBreak >>= \als ->
1293− lines' <- sequence <$> many1 pipeTableRow
1295+ lines' <- many1 pipeTableRow
1294 let widths = replicate (length aligns) 0.0
1296 let widths = replicate (length aligns) 0.0
1295− return $ (aligns, widths, heads, lines')
1297+ return (aligns, widths, heads, lines')
1297sepPipe :: MarkdownParser ()
1299sepPipe :: MarkdownParser ()
1298sepPipe = try $ do
1300sepPipe = try $ do
@@ -1300,7 +1302,7 @@ sepPipe = try $ do
1300 notFollowedBy blankline
1302 notFollowedBy blankline
1302-- parse a row, also returning probable alignments for org-table cells
1304-- parse a row, also returning probable alignments for org-table cells
1303−pipeTableRow :: MarkdownParser (F [Blocks])
1305+pipeTableRow :: MarkdownParser [Blocks]
1304pipeTableRow = do
1306pipeTableRow = do
1305 nonindentSpaces
1307 nonindentSpaces
1306 openPipe <- (True <$ char '|') <|> return False
1308 openPipe <- (True <$ char '|') <|> return False
@@ -1312,16 +1314,14 @@ pipeTableRow = do
1312 guard $ not (null rest && not openPipe)
1314 guard $ not (null rest && not openPipe)
1313 optional (char '|')
1315 optional (char '|')
1314 blankline
1316 blankline
1315− let cells = sequence (first:rest)
1317+ let cells = first:rest
1316− return $ do
1318+ return $
1319− (\ils ->
1319+ map (\ils ->
1320 case trimInlines ils of
1320 case trimInlines ils of
1321 ils' | B.isNull ils' -> mempty
1321 ils' | B.isNull ils' -> mempty
1322− | otherwise -> B.plain $ ils') cells'
1322+ | otherwise -> B.plain ils') cells
1324−pipeTableHeaderPart :: Parser [Char] st Alignment
1324+pipeTableHeaderPart :: Monad m => ParserT [Char] st m Alignment
1325pipeTableHeaderPart = try $ do
1325pipeTableHeaderPart = try $ do
1326 skipMany spaceChar
1326 skipMany spaceChar
1327 left <- optionMaybe (char ':')
1327 left <- optionMaybe (char ':')
@@ -1336,7 +1336,7 @@ pipeTableHeaderPart = try $ do
1336 (Just _,Just _) -> AlignCenter
1336 (Just _,Just _) -> AlignCenter
1338-- Succeed only if current line contains a pipe.
1338-- Succeed only if current line contains a pipe.
1339−scanForPipe :: Parser [Char] st ()
1339+scanForPipe :: Monad m => ParserT [Char] st m ()
1340scanForPipe = do
1340scanForPipe = do
1341 inp <- getInput
1341 inp <- getInput
1342 case break (\c -> c == '\n' || c == '|') inp of
1342 case break (\c -> c == '\n' || c == '|') inp of
@@ -1346,22 +1346,22 @@ scanForPipe = do
1346-- | Parse a table using 'headerParser', 'rowParser',
1346-- | Parse a table using 'headerParser', 'rowParser',
1347-- 'lineParser', and 'footerParser'. Variant of the version in
1347-- 'lineParser', and 'footerParser'. Variant of the version in
1348-- Text.Pandoc.Parsing.
1348-- Text.Pandoc.Parsing.
1349−tableWith :: MarkdownParser (F [Blocks], [Alignment], [Int])
1349+tableWith :: MarkdownParser ([Blocks], [Alignment], [Int])
1350− -> ([Int] -> MarkdownParser (F [Blocks]))
1350+ -> ([Int] -> MarkdownParser [Blocks])
1351 -> MarkdownParser sep
1351 -> MarkdownParser sep
1352 -> MarkdownParser end
1352 -> MarkdownParser end
1353− -> MarkdownParser ([Alignment], [Double], F [Blocks], F [[Blocks]])
1353+ -> MarkdownParser ([Alignment], [Double], [Blocks], [[Blocks]])
1354tableWith headerParser rowParser lineParser footerParser = try $ do
1354tableWith headerParser rowParser lineParser footerParser = try $ do
1355 (heads, aligns, indices) <- headerParser
1355 (heads, aligns, indices) <- headerParser
1356− lines' <- fmap sequence $ rowParser indices `sepEndBy1` lineParser
1356+ lines' <- rowParser indices `sepEndBy1` lineParser
1357 footerParser
1357 footerParser
1358 numColumns <- getOption readerColumns
1358 numColumns <- getOption readerColumns
1359− let widths = if (indices == [])
1359+ let widths = case indices of
1360− then replicate (length aligns) 0.0
1360+ [] -> replicate (length aligns) 0.0
1361− else widthsFromIndices numColumns indices
1361+ _ -> widthsFromIndices numColumns indices
1362− return $ (aligns, widths, heads, lines')
1362+ return (aligns, widths, heads, lines')
1364−table :: MarkdownParser (F Blocks)
1364+table :: MarkdownParser Blocks
1365table = try $ do
1365table = try $ do
1366 frontCaption <- option Nothing (Just <$> tableCaption)
1366 frontCaption <- option Nothing (Just <$> tableCaption)
1367 (aligns, widths, heads, lns) <-
1367 (aligns, widths, heads, lns) <-
@@ -1376,19 +1376,15 @@ table = try $ do
1376 (gridTable False <|> gridTable True)) <?> "table"
1376 (gridTable False <|> gridTable True)) <?> "table"
1377 optional blanklines
1377 optional blanklines
1378 caption <- case frontCaption of
1378 caption <- case frontCaption of
1379− Nothing -> option (return mempty) tableCaption
1379+ Nothing -> option mempty tableCaption
1380 Just c -> return c
1380 Just c -> return c
1382− caption' <- caption
1385− return $ B.table caption' (zip aligns widths) heads' lns'
1381+ return $ B.table caption (zip aligns widths) heads lns
1388-- inline
1384-- inline
1391−inline :: MarkdownParser (F Inlines)
1387+inline :: MarkdownParser Inlines
1392inline = choice [ whitespace
1388inline = choice [ whitespace
1393 , bareURL
1389 , bareURL
@@ -1411,7 +1407,7 @@ inline = choice [ whitespace
1411 , rawLaTeXInline'
1407 , rawLaTeXInline'
1412 , exampleRef
1408 , exampleRef
1414− , return . B.singleton <$> charRef
1410+ , B.singleton <$> charRef
1415 , symbol
1411 , symbol
1416 , ltSign
1412 , ltSign
1417 ] <?> "inline"
1413 ] <?> "inline"
@@ -1422,43 +1418,42 @@ escapedChar' = try $ do
1422 (guardEnabled Ext_all_symbols_escapable >> satisfy (not . isAlphaNum))
1418 (guardEnabled Ext_all_symbols_escapable >> satisfy (not . isAlphaNum))
1423 <|> oneOf "\\`*_{}[]()>#+-.!~\""
1419 <|> oneOf "\\`*_{}[]()>#+-.!~\""
1425−escapedChar :: MarkdownParser (F Inlines)
1421+escapedChar :: MarkdownParser Inlines
1426escapedChar = do
1422escapedChar = do
1427 result <- escapedChar'
1423 result <- escapedChar'
1428 case result of
1424 case result of
1429− ' ' -> return $ return $ B.str "\160" -- "\ " is a nonbreaking space
1425+ ' ' -> return $ B.str "\160" -- "\ " is a nonbreaking space
1430 '\n' -> guardEnabled Ext_escaped_line_breaks >>
1426 '\n' -> guardEnabled Ext_escaped_line_breaks >>
1431− return (return B.linebreak) -- "\[newline]" is a linebreak
1427+ return B.linebreak -- "\[newline]" is a linebreak
1432− _ -> return $ return $ B.str [result]
1428+ _ -> return $ B.str [result]
1434−ltSign :: MarkdownParser (F Inlines)
1430+ltSign :: MarkdownParser Inlines
1435ltSign = do
1431ltSign = do
1436 guardDisabled Ext_raw_html
1432 guardDisabled Ext_raw_html
1437 <|> (notFollowedByHtmlCloser >> notFollowedBy' (htmlTag isBlockTag))
1433 <|> (notFollowedByHtmlCloser >> notFollowedBy' (htmlTag isBlockTag))
1438 char '<'
1434 char '<'
1439− return $ return $ B.str "<"
1435+ return $ B.str "<"
1441−exampleRef :: MarkdownParser (F Inlines)
1437+exampleRef :: MarkdownParser Inlines
1442exampleRef = try $ do
1438exampleRef = try $ do
1443 guardEnabled Ext_example_lists
1439 guardEnabled Ext_example_lists
1444 char '@'
1440 char '@'
1445 lab <- many1 (alphaNum <|> oneOf "-_")
1441 lab <- many1 (alphaNum <|> oneOf "-_")
1446− return $ do
1442+ st <- ask
1448− return $ case M.lookup lab (stateExamples st) of
1443+ return $ case M.lookup lab (stateExamples st) of
1449− Just n -> B.str (show n)
1444+ Just n -> B.str (show n)
1450− Nothing -> B.str ('@':lab)
1445+ Nothing -> B.str ('@':lab)
1452−symbol :: MarkdownParser (F Inlines)
1447+symbol :: MarkdownParser Inlines
1453symbol = do
1448symbol = do
1454 result <- noneOf "<\\\n\t "
1449 result <- noneOf "<\\\n\t "
1455 <|> try (do lookAhead $ char '\\'
1450 <|> try (do lookAhead $ char '\\'
1456 notFollowedBy' (() <$ rawTeXBlock)
1451 notFollowedBy' (() <$ rawTeXBlock)
1457 char '\\')
1452 char '\\')
1458− return $ return $ B.str [result]
1453+ return $ B.str [result]
1460-- parses inline code, between n `s and n `s
1455-- parses inline code, between n `s and n `s
1461−code :: MarkdownParser (F Inlines)
1456+code :: MarkdownParser Inlines
1462code = try $ do
1457code = try $ do
1463 starts <- many1 (char '`')
1458 starts <- many1 (char '`')
1464 skipSpaces
1459 skipSpaces
@@ -1468,16 +1463,16 @@ code = try $ do
1468 notFollowedBy (char '`')))
1463 notFollowedBy (char '`')))
1469 attr <- option ([],[],[]) (try $ guardEnabled Ext_inline_code_attributes >>
1464 attr <- option ([],[],[]) (try $ guardEnabled Ext_inline_code_attributes >>
1470 optional whitespace >> attributes)
1465 optional whitespace >> attributes)
1471− return $ return $ B.codeWith attr $ trim $ concat result
1466+ return $ B.codeWith attr $ trim $ concat result
1473−math :: MarkdownParser (F Inlines)
1468+math :: MarkdownParser Inlines
1474−math = (return . B.displayMath <$> (mathDisplay >>= applyMacros'))
1469+math = (B.displayMath <$> (mathDisplay >>= applyMacros'))
1475− <|> (return . B.math <$> (mathInline >>= applyMacros'))
1470+ <|> (B.math <$> (mathInline >>= applyMacros'))
1477-- Parses material enclosed in *s, **s, _s, or __s.
1472-- Parses material enclosed in *s, **s, _s, or __s.
1478-- Designed to avoid backtracking.
1473-- Designed to avoid backtracking.
1479enclosure :: Char
1474enclosure :: Char
1480− -> MarkdownParser (F Inlines)
1475+ -> MarkdownParser Inlines
1481enclosure c = do
1476enclosure c = do
1482 -- we can't start an enclosure with _ if after a string and
1477 -- we can't start an enclosure with _ if after a string and
1483 -- the intraword_underscores extension is enabled:
1478 -- the intraword_underscores extension is enabled:
@@ -1485,13 +1480,13 @@ enclosure c = do
1485 <|> guard (c == '*')
1480 <|> guard (c == '*')
1486 <|> (guard =<< notAfterString)
1481 <|> (guard =<< notAfterString)
1487 cs <- many1 (char c)
1482 cs <- many1 (char c)
1488− (return (B.str cs) <>) <$> whitespace
1483+ (B.str cs <>) <$> whitespace
1490 case length cs of
1485 case length cs of
1491 3 -> three c
1486 3 -> three c
1492 2 -> two c mempty
1487 2 -> two c mempty
1493 1 -> one c mempty
1488 1 -> one c mempty
1494− _ -> return (return $ B.str cs)
1489+ _ -> return $ B.str cs
1496ender :: Char -> Int -> MarkdownParser ()
1491ender :: Char -> Int -> MarkdownParser ()
1497ender c n = try $ do
1492ender c n = try $ do
@@ -1504,74 +1499,74 @@ ender c n = try $ do
1504-- If one c, emit emph and then parse two.
1499-- If one c, emit emph and then parse two.
1505-- If two cs, emit strong and then parse one.
1500-- If two cs, emit strong and then parse one.
1506-- Otherwise, emit ccc then the results.
1501-- Otherwise, emit ccc then the results.
1507−three :: Char -> MarkdownParser (F Inlines)
1502+three :: Char -> MarkdownParser Inlines
1508three c = do
1503three c = do
1509 contents <- mconcat <$> many (notFollowedBy (ender c 1) >> inline)
1504 contents <- mconcat <$> many (notFollowedBy (ender c 1) >> inline)
1510− (ender c 3 >> return ((B.strong . B.emph) <$> contents))
1505+ (ender c 3 >> return ((B.strong . B.emph) contents))
1511− <|> (ender c 2 >> one c (B.strong <$> contents))
1506+ <|> (ender c 2 >> one c (B.strong contents))
1512− <|> (ender c 1 >> two c (B.emph <$> contents))
1507+ <|> (ender c 1 >> two c (B.emph contents))
1513− <|> return (return (B.str [c,c,c]) <> contents)
1508+ <|> return (B.str [c,c,c] <> contents)
1515-- Parse inlines til you hit two c's, and emit strong.
1510-- Parse inlines til you hit two c's, and emit strong.
1516-- If you never do hit two cs, emit ** plus inlines parsed.
1511-- If you never do hit two cs, emit ** plus inlines parsed.
1517−two :: Char -> F Inlines -> MarkdownParser (F Inlines)
1512+two :: Char -> Inlines -> MarkdownParser Inlines
1518two c prefix' = do
1513two c prefix' = do
1519 contents <- mconcat <$> many (try $ notFollowedBy (ender c 2) >> inline)
1514 contents <- mconcat <$> many (try $ notFollowedBy (ender c 2) >> inline)
1520− (ender c 2 >> return (B.strong <$> (prefix' <> contents)))
1515+ (ender c 2 >> return (B.strong (prefix' <> contents)))
1521− <|> return (return (B.str [c,c]) <> (prefix' <> contents))
1516+ <|> return (B.str [c,c] <> (prefix' <> contents))
1523-- Parse inlines til you hit a c, and emit emph.
1518-- Parse inlines til you hit a c, and emit emph.
1524-- If you never hit a c, emit * plus inlines parsed.
1519-- If you never hit a c, emit * plus inlines parsed.
1525−one :: Char -> F Inlines -> MarkdownParser (F Inlines)
1520+one :: Char -> Inlines -> MarkdownParser Inlines
1526one c prefix' = do
1521one c prefix' = do
1527 contents <- mconcat <$> many ( (notFollowedBy (ender c 1) >> inline)
1522 contents <- mconcat <$> many ( (notFollowedBy (ender c 1) >> inline)
1528 <|> try (string [c,c] >>
1523 <|> try (string [c,c] >>
1529 notFollowedBy (ender c 1) >>
1524 notFollowedBy (ender c 1) >>
1530 two c mempty) )
1525 two c mempty) )
1531− (ender c 1 >> return (B.emph <$> (prefix' <> contents)))
1526+ (ender c 1 >> return (B.emph (prefix' <> contents)))
1532− <|> return (return (B.str [c]) <> (prefix' <> contents))
1527+ <|> return (B.str [c] <> (prefix' <> contents))
1534−strongOrEmph :: MarkdownParser (F Inlines)
1529+strongOrEmph :: MarkdownParser Inlines
1535strongOrEmph = enclosure '*' <|> enclosure '_'
1530strongOrEmph = enclosure '*' <|> enclosure '_'
1537−-- | Parses a list of inlines between start and end delimiters.
1532+-- | Parses a list oInlines between start and end delimiters.
1538inlinesBetween :: (Show b)
1533inlinesBetween :: (Show b)
1539 => MarkdownParser a
1534 => MarkdownParser a
1540 -> MarkdownParser b
1535 -> MarkdownParser b
1541− -> MarkdownParser (F Inlines)
1536+ -> MarkdownParser Inlines
1542inlinesBetween start end =
1537inlinesBetween start end =
1543− (trimInlinesF . mconcat) <$> try (start >> many1Till inner end)
1538+ (trimInlines . mconcat) <$> try (start >> many1Till inner end)
1544 where inner = innerSpace <|> (notFollowedBy' (() <$ whitespace) >> inline)
1539 where inner = innerSpace <|> (notFollowedBy' (() <$ whitespace) >> inline)
1545 innerSpace = try $ whitespace <* notFollowedBy' end
1540 innerSpace = try $ whitespace <* notFollowedBy' end
1547−strikeout :: MarkdownParser (F Inlines)
1542+strikeout :: MarkdownParser Inlines
1548−strikeout = fmap B.strikeout <$>
1543+strikeout = B.strikeout <$>
1549 (guardEnabled Ext_strikeout >> inlinesBetween strikeStart strikeEnd)
1544 (guardEnabled Ext_strikeout >> inlinesBetween strikeStart strikeEnd)
1550 where strikeStart = string "~~" >> lookAhead nonspaceChar
1545 where strikeStart = string "~~" >> lookAhead nonspaceChar
1551 >> notFollowedBy (char '~')
1546 >> notFollowedBy (char '~')
1552 strikeEnd = try $ string "~~"
1547 strikeEnd = try $ string "~~"
1554−superscript :: MarkdownParser (F Inlines)
1549+superscript :: MarkdownParser Inlines
1555−superscript = fmap B.superscript <$> try (do
1550+superscript = B.superscript <$> try (do
1556 guardEnabled Ext_superscript
1551 guardEnabled Ext_superscript
1557 char '^'
1552 char '^'
1558 mconcat <$> many1Till (notFollowedBy spaceChar >> inline) (char '^'))
1553 mconcat <$> many1Till (notFollowedBy spaceChar >> inline) (char '^'))
1560−subscript :: MarkdownParser (F Inlines)
1555+subscript :: MarkdownParser Inlines
1561−subscript = fmap B.subscript <$> try (do
1556+subscript = B.subscript <$> try (do
1562 guardEnabled Ext_subscript
1557 guardEnabled Ext_subscript
1563 char '~'
1558 char '~'
1564 mconcat <$> many1Till (notFollowedBy spaceChar >> inline) (char '~'))
1559 mconcat <$> many1Till (notFollowedBy spaceChar >> inline) (char '~'))
1566−whitespace :: MarkdownParser (F Inlines)
1561+whitespace :: MarkdownParser Inlines
1567−whitespace = spaceChar >> return <$> (lb <|> regsp) <?> "whitespace"
1562+whitespace = spaceChar >> (lb <|> regsp) <?> "whitespace"
1568 where lb = spaceChar >> skipMany spaceChar >> option B.space (endline >> return B.linebreak)
1563 where lb = spaceChar >> skipMany spaceChar >> option B.space (endline >> return B.linebreak)
1569 regsp = skipMany spaceChar >> return B.space
1564 regsp = skipMany spaceChar >> return B.space
1571−nonEndline :: Parser [Char] st Char
1566+nonEndline :: Monad m => ParserT [Char] st m Char
1572nonEndline = satisfy (/='\n')
1567nonEndline = satisfy (/='\n')
1574−str :: MarkdownParser (F Inlines)
1569+str :: MarkdownParser Inlines
1576 result <- many1 alphaNum
1571 result <- many1 alphaNum
1577 updateLastStrPos
1572 updateLastStrPos
@@ -1579,14 +1574,14 @@ str = do
1579 isSmart <- getOption readerSmart
1574 isSmart <- getOption readerSmart
1580 if isSmart
1575 if isSmart
1581 then case likelyAbbrev result of
1576 then case likelyAbbrev result of
1582− [] -> return $ return $ B.str result
1577+ [] -> return $ B.str result
1583 xs -> choice (map (\x ->
1578 xs -> choice (map (\x ->
1584 try (string x >> oneOf " \n" >>
1579 try (string x >> oneOf " \n" >>
1585 lookAhead alphaNum >>
1580 lookAhead alphaNum >>
1586− return (return $ B.str
1581+ return (B.str $
1587− $ result ++ spacesToNbr x ++ "\160"))) xs)
1582+ result ++ spacesToNbr x ++ "\160"))) xs)
1588− <|> (return $ return $ B.str result)
1583+ <|> (return $ B.str result)
1589− else return $ return $ B.str result
1584+ else return $ B.str result
1591-- | if the string matches the beginning of an abbreviation (before
1586-- | if the string matches the beginning of an abbreviation (before
1592-- the first period, return strings that would finish the abbreviation.
1587-- the first period, return strings that would finish the abbreviation.
@@ -1601,7 +1596,7 @@ likelyAbbrev x =
1601 in map snd $ filter (\(y,_) -> y == x) abbrPairs
1596 in map snd $ filter (\(y,_) -> y == x) abbrPairs
1603-- an endline character that can be treated as a space, not a structural break
1598-- an endline character that can be treated as a space, not a structural break
1604−endline :: MarkdownParser (F Inlines)
1599+endline :: MarkdownParser Inlines
1605endline = try $ do
1600endline = try $ do
1607 notFollowedBy blankline
1602 notFollowedBy blankline
@@ -1614,18 +1609,18 @@ endline = try $ do
1614 notFollowedBy (() <$ (lookAhead (char '`') >> codeBlockFenced))
1609 notFollowedBy (() <$ (lookAhead (char '`') >> codeBlockFenced))
1615 notFollowedByHtmlCloser
1610 notFollowedByHtmlCloser
1616 (eof >> return mempty)
1611 (eof >> return mempty)
1617− <|> (guardEnabled Ext_hard_line_breaks >> return (return B.linebreak))
1612+ <|> (guardEnabled Ext_hard_line_breaks >> return B.linebreak)
1618 <|> (guardEnabled Ext_ignore_line_breaks >> return mempty)
1613 <|> (guardEnabled Ext_ignore_line_breaks >> return mempty)
1619− <|> (return $ return B.space)
1614+ <|> return B.space
1625-- a reference label for a link
1620-- a reference label for a link
1626−reference :: MarkdownParser (F Inlines, String)
1621+reference :: MarkdownParser (Inlines, String)
1627reference = do notFollowedBy' (string "[^") -- footnote reference
1622reference = do notFollowedBy' (string "[^") -- footnote reference
1628− withRaw $ trimInlinesF <$> inlinesInBalancedBrackets
1623+ withRaw $ trimInlines <$> inlinesInBalancedBrackets
1630parenthesizedChars :: MarkdownParser [Char]
1625parenthesizedChars :: MarkdownParser [Char]
1631parenthesizedChars = do
1626parenthesizedChars = do
@@ -1653,7 +1648,7 @@ source = do
1653linkTitle :: MarkdownParser String
1648linkTitle :: MarkdownParser String
1654linkTitle = quotedTitle '"' <|> quotedTitle '\''
1649linkTitle = quotedTitle '"' <|> quotedTitle '\''
1656−link :: MarkdownParser (F Inlines)
1651+link :: MarkdownParser Inlines
1657link = try $ do
1652link = try $ do
1658 st <- getState
1653 st <- getState
1659 guard $ stateAllowLinks st
1654 guard $ stateAllowLinks st
@@ -1663,14 +1658,14 @@ link = try $ do
1663 regLink B.link lab <|> referenceLink B.link (lab,raw)
1658 regLink B.link lab <|> referenceLink B.link (lab,raw)
1665regLink :: (String -> String -> Inlines -> Inlines)
1660regLink :: (String -> String -> Inlines -> Inlines)
1666− -> F Inlines -> MarkdownParser (F Inlines)
1661+ -> Inlines -> MarkdownParser Inlines
1667regLink constructor lab = try $ do
1662regLink constructor lab = try $ do
1668 (src, tit) <- source
1663 (src, tit) <- source
1669− return $ constructor src tit <$> lab
1664+ return $ constructor src tit lab
1671-- a link like [this][ref] or [this][] or [this]
1666-- a link like [this][ref] or [this][] or [this]
1672referenceLink :: (String -> String -> Inlines -> Inlines)
1667referenceLink :: (String -> String -> Inlines -> Inlines)
1673− -> (F Inlines, String) -> MarkdownParser (F Inlines)
1668+ -> (Inlines, String) -> MarkdownParser Inlines
1674referenceLink constructor (lab, raw) = do
1669referenceLink constructor (lab, raw) = do
1675 sp <- (True <$ lookAhead (char ' ')) <|> return False
1670 sp <- (True <$ lookAhead (char ' ')) <|> return False
1676 (ref,raw') <- option (mempty, "") $
1671 (ref,raw') <- option (mempty, "") $
@@ -1684,24 +1679,22 @@ referenceLink constructor (lab, raw) = do
1684 fallback <- parseFromString (mconcat <$> many inline) $ dropBrackets raw
1679 fallback <- parseFromString (mconcat <$> many inline) $ dropBrackets raw
1685 implicitHeaderRefs <- option False $
1680 implicitHeaderRefs <- option False $
1686 True <$ guardEnabled Ext_implicit_header_references
1681 True <$ guardEnabled Ext_implicit_header_references
1687− let makeFallback = do
1682+ let makeFallback =
1688− parsedRaw' <- parsedRaw
1689− fallback' <- fallback
1690− return $ B.str "[" <> fallback' <> B.str "]" <>
1683+ B.str "[" <> fallback <> B.str "]" <>
1691 (if sp && not (null raw) then B.space else mempty) <>
1684 (if sp && not (null raw) then B.space else mempty) <>
1692− parsedRaw'
1685+ parsedRaw
1694− keys <- asksF stateKeys
1686+ keys <- asks stateKeys
1687+ headers <- asks stateHeaders
1695− case M.lookup key keys of
1689+ case M.lookup key keys of
1696− Nothing -> do
1690+ Nothing ->
1697− headers <- asksF stateHeaders
1698− ref' <- if labIsRef then lab else ref
1691+ let ref' = if labIsRef then lab else ref in
1699− if implicitHeaderRefs
1692+ if implicitHeaderRefs
1700− then case M.lookup ref' headers of
1693+ then case M.lookup ref' headers of
1701− Just ident -> constructor ('#':ident) "" <$> lab
1694+ Just ident -> constructor ('#':ident) "" lab
1702− Nothing -> makeFallback
1695+ Nothing -> makeFallback
1703− else makeFallback
1696+ else makeFallback
1704− Just (src,tit) -> constructor src tit <$> lab
1697+ Just (src,tit) -> constructor src tit lab
1706dropBrackets :: String -> String
1699dropBrackets :: String -> String
1707dropBrackets = reverse . dropRB . reverse . dropLB
1700dropBrackets = reverse . dropRB . reverse . dropLB
@@ -1710,14 +1703,14 @@ dropBrackets = reverse . dropRB . reverse . dropLB
1710 dropLB ('[':xs) = xs
1703 dropLB ('[':xs) = xs
1711 dropLB xs = xs
1704 dropLB xs = xs
1713−bareURL :: MarkdownParser (F Inlines)
1706+bareURL :: MarkdownParser Inlines
1714bareURL = try $ do
1707bareURL = try $ do
1715 guardEnabled Ext_autolink_bare_uris
1708 guardEnabled Ext_autolink_bare_uris
1716 (orig, src) <- uri <|> emailAddress
1709 (orig, src) <- uri <|> emailAddress
1717 notFollowedBy $ try $ spaces >> htmlTag (~== TagClose "a")
1710 notFollowedBy $ try $ spaces >> htmlTag (~== TagClose "a")
1718− return $ return $ B.link src "" (B.str orig)
1711+ return $ B.link src "" (B.str orig)
1720−autoLink :: MarkdownParser (F Inlines)
1713+autoLink :: MarkdownParser Inlines
1721autoLink = try $ do
1714autoLink = try $ do
1722 char '<'
1715 char '<'
1723 (orig, src) <- uri <|> emailAddress
1716 (orig, src) <- uri <|> emailAddress
@@ -1726,9 +1719,9 @@ autoLink = try $ do
1726 -- final punctuation. for example: in `<http://hi---there>`,
1719 -- final punctuation. for example: in `<http://hi---there>`,
1727 -- the URI parser will stop before the dashes.
1720 -- the URI parser will stop before the dashes.
1728 extra <- fromEntities <$> manyTill nonspaceChar (char '>')
1721 extra <- fromEntities <$> manyTill nonspaceChar (char '>')
1729− return $ return $ B.link (src ++ escapeURI extra) "" (B.str $ orig ++ extra)
1722+ return $ B.link (src ++ escapeURI extra) "" (B.str $ orig ++ extra)
1731−image :: MarkdownParser (F Inlines)
1724+image :: MarkdownParser Inlines
1732image = try $ do
1725image = try $ do
1733 char '!'
1726 char '!'
1734 (lab,raw) <- reference
1727 (lab,raw) <- reference
@@ -1738,38 +1731,33 @@ image = try $ do
1738 _ -> B.image src
1731 _ -> B.image src
1739 regLink constructor lab <|> referenceLink constructor (lab,raw)
1732 regLink constructor lab <|> referenceLink constructor (lab,raw)
1741−note :: MarkdownParser (F Inlines)
1734+note :: MarkdownParser Inlines
1742note = try $ do
1735note = try $ do
1743 guardEnabled Ext_footnotes
1736 guardEnabled Ext_footnotes
1737+ (stateInFootnote <$> getState) >>= guard . not
1744 ref <- noteMarker
1738 ref <- noteMarker
1746− notes <- asksF stateNotes'
1739+ notes <- asks stateNotes'
1747 case lookup ref notes of
1741 case lookup ref notes of
1748− Nothing -> return $ B.str $ "[^" ++ ref ++ "]"
1742+ Nothing -> B.str $ "[^" ++ ref ++ "]"
1749− Just contents -> do
1743+ Just contents -> B.note contents
1751− -- process the note in a context that doesn't resolve
1752− -- notes, to avoid infinite looping with notes inside
1754− let contents' = runF contents st{ stateNotes' = [] }
1755− return $ B.note contents'
1757−inlineNote :: MarkdownParser (F Inlines)
1745+inlineNote :: MarkdownParser Inlines
1758inlineNote = try $ do
1746inlineNote = try $ do
1759 guardEnabled Ext_inline_notes
1747 guardEnabled Ext_inline_notes
1760 char '^'
1748 char '^'
1761 contents <- inlinesInBalancedBrackets
1749 contents <- inlinesInBalancedBrackets
1762− return $ B.note . B.para <$> contents
1750+ return . B.note . B.para $ contents
1764−rawLaTeXInline' :: MarkdownParser (F Inlines)
1752+rawLaTeXInline' :: MarkdownParser Inlines
1765rawLaTeXInline' = try $ do
1753rawLaTeXInline' = try $ do
1766 guardEnabled Ext_raw_tex
1754 guardEnabled Ext_raw_tex
1767 lookAhead $ char '\\' >> notFollowedBy' (string "start") -- context env
1755 lookAhead $ char '\\' >> notFollowedBy' (string "start") -- context env
1768− RawInline _ s <- rawLaTeXInline
1756+ RawInline _ s <- generalize rawLaTeXInline
1769− return $ return $ B.rawInline "tex" s
1757+ return $ B.rawInline "tex" s
1770 -- "tex" because it might be context or latex
1758 -- "tex" because it might be context or latex
1772−rawConTeXtEnvironment :: Parser [Char] st String
1760+rawConTeXtEnvironment :: Monad m => ParserT [Char] st m String
1773rawConTeXtEnvironment = try $ do
1761rawConTeXtEnvironment = try $ do
1774 string "\\start"
1762 string "\\start"
1775 completion <- inBrackets (letter <|> digit <|> spaceChar)
1763 completion <- inBrackets (letter <|> digit <|> spaceChar)
@@ -1778,14 +1766,14 @@ rawConTeXtEnvironment = try $ do
1778 (try $ string "\\stop" >> string completion)
1766 (try $ string "\\stop" >> string completion)
1779 return $ "\\start" ++ completion ++ concat contents ++ "\\stop" ++ completion
1767 return $ "\\start" ++ completion ++ concat contents ++ "\\stop" ++ completion
1781−inBrackets :: (Parser [Char] st Char) -> Parser [Char] st String
1769+inBrackets :: Monad m => (ParserT [Char] st m Char) -> ParserT [Char] st m String
1782inBrackets parser = do
1770inBrackets parser = do
1783 char '['
1771 char '['
1784 contents <- many parser
1772 contents <- many parser
1785 char ']'
1773 char ']'
1786 return $ "[" ++ contents ++ "]"
1774 return $ "[" ++ contents ++ "]"
1788−spanHtml :: MarkdownParser (F Inlines)
1776+spanHtml :: MarkdownParser Inlines
1789spanHtml = try $ do
1777spanHtml = try $ do
1790 guardEnabled Ext_native_spans
1778 guardEnabled Ext_native_spans
1791 (TagOpen _ attrs, _) <- htmlTag (~== TagOpen "span" [])
1779 (TagOpen _ attrs, _) <- htmlTag (~== TagOpen "span" [])
@@ -1797,10 +1785,10 @@ spanHtml = try $ do
1797 Just s | null ident && null classes &&
1785 Just s | null ident && null classes &&
1798 map toLower (filter (`notElem` " \t;") s) ==
1786 map toLower (filter (`notElem` " \t;") s) ==
1799 "font-variant:small-caps"
1787 "font-variant:small-caps"
1800− -> return $ B.smallcaps <$> contents
1788+ -> return $ B.smallcaps contents
1801− _ -> return $ B.spanWith (ident, classes, keyvals) <$> contents
1789+ _ -> return $ B.spanWith (ident, classes, keyvals) contents
1803−divHtml :: MarkdownParser (F Blocks)
1791+divHtml :: MarkdownParser Blocks
1804divHtml = try $ do
1792divHtml = try $ do
1805 guardEnabled Ext_native_divs
1793 guardEnabled Ext_native_divs
1806 (TagOpen _ attrs, rawtag) <- htmlTag (~== TagOpen "div" [])
1794 (TagOpen _ attrs, rawtag) <- htmlTag (~== TagOpen "div" [])
@@ -1818,11 +1806,11 @@ divHtml = try $ do
1818 let ident = fromMaybe "" $ lookup "id" attrs
1806 let ident = fromMaybe "" $ lookup "id" attrs
1819 let classes = maybe [] words $ lookup "class" attrs
1807 let classes = maybe [] words $ lookup "class" attrs
1820 let keyvals = [(k,v) | (k,v) <- attrs, k /= "id" && k /= "class"]
1808 let keyvals = [(k,v) | (k,v) <- attrs, k /= "id" && k /= "class"]
1821− return $ B.divWith (ident, classes, keyvals) <$> contents
1809+ return $ B.divWith (ident, classes, keyvals) contents
1822 else -- avoid backtracing
1810 else -- avoid backtracing
1823− return $ return (B.rawBlock "html" (rawtag <> bls)) <> contents
1811+ return $ B.rawBlock "html" (rawtag <> bls) <> contents
1825−rawHtmlInline :: MarkdownParser (F Inlines)
1813+rawHtmlInline :: MarkdownParser Inlines
1826rawHtmlInline = do
1814rawHtmlInline = do
1827 guardEnabled Ext_raw_html
1815 guardEnabled Ext_raw_html
1828 inHtmlBlock <- stateInHtmlBlock <$> getState
1816 inHtmlBlock <- stateInHtmlBlock <$> getState
@@ -1837,19 +1825,17 @@ rawHtmlInline = do
1837 then (\x -> isInlineTag x &&
1825 then (\x -> isInlineTag x &&
1838 not (isCloseBlockTag x))
1826 not (isCloseBlockTag x))
1839 else not . isTextTag
1827 else not . isTextTag
1840− return $ return $ B.rawInline "html" result
1828+ return $ B.rawInline "html" result
1842-- Citations
1830-- Citations
1844−cite :: MarkdownParser (F Inlines)
1832+cite :: MarkdownParser Inlines
1845cite = do
1833cite = do
1846 guardEnabled Ext_citations
1834 guardEnabled Ext_citations
1847− citations <- textualCite
1848− <|> do (cs, raw) <- withRaw normalCite
1835+ textualCite <|> do (cs, raw) <- withRaw normalCite
1849− return $ (flip B.cite (B.text raw)) <$> cs
1836+ return $ B.cite cs (B.text raw)
1852−textualCite :: MarkdownParser (F Inlines)
1838+textualCite :: MarkdownParser Inlines
1853textualCite = try $ do
1839textualCite = try $ do
1854 (_, key) <- citeKey
1840 (_, key) <- citeKey
1855 let first = Citation{ citationId = key
1841 let first = Citation{ citationId = key
@@ -1863,29 +1849,26 @@ textualCite = try $ do
1863 case mbrest of
1849 case mbrest of
1864 Just (rest, raw) ->
1850 Just (rest, raw) ->
1865 return $ (flip B.cite (B.text $ '@':key ++ " " ++ raw) . (first:))
1851 return $ (flip B.cite (B.text $ '@':key ++ " " ++ raw) . (first:))
1867 Nothing ->
1853 Nothing ->
1868 (do (cs, raw) <- withRaw $ bareloc first
1854 (do (cs, raw) <- withRaw $ bareloc first
1869− return $ (flip B.cite (B.text $ '@':key ++ " " ++ raw)) <$> cs)
1855+ return $ B.cite cs (B.text $ '@':key ++ " " ++ raw))
1870− <|> return (do st <- askF
1856+ <|> do st <- ask
1871− return $ case M.lookup key (stateExamples st) of
1857+ return $ case M.lookup key (stateExamples st) of
1872− Just n -> B.str (show n)
1858+ Just n -> B.str (show n)
1873− _ -> B.cite [first] $ B.str $ '@':key)
1859+ _ -> B.cite [first] $ B.str $ '@':key
1875−bareloc :: Citation -> MarkdownParser (F [Citation])
1861+bareloc :: Citation -> MarkdownParser [Citation]
1876bareloc c = try $ do
1862bareloc c = try $ do
1878 char '['
1864 char '['
1879 suff <- suffix
1865 suff <- suffix
1880− rest <- option (return []) $ try $ char ';' >> citeList
1866+ rest <- option [] $ try $ char ';' >> citeList
1882 char ']'
1868 char ']'
1886− return $ c{ citationSuffix = B.toList suff' } : rest'
1869+ return $ c{ citationSuffix = B.toList suff } : rest
1888−normalCite :: MarkdownParser (F [Citation])
1871+normalCite :: MarkdownParser [Citation]
1889normalCite = try $ do
1872normalCite = try $ do
1890 char '['
1873 char '['
@@ -1894,60 +1877,57 @@ normalCite = try $ do
1894 char ']'
1877 char ']'
1895 return citations
1878 return citations
1897−suffix :: MarkdownParser (F Inlines)
1880+suffix :: MarkdownParser Inlines
1898suffix = try $ do
1881suffix = try $ do
1899 hasSpace <- option False (notFollowedBy nonspaceChar >> return True)
1882 hasSpace <- option False (notFollowedBy nonspaceChar >> return True)
1901− rest <- trimInlinesF . mconcat <$> many (notFollowedBy (oneOf ";]") >> inline)
1884+ rest <- trimInlines . mconcat <$> many (notFollowedBy (oneOf ";]") >> inline)
1902 return $ if hasSpace
1885 return $ if hasSpace
1903− then (B.space <>) <$> rest
1886+ then B.space <> rest
1904 else rest
1887 else rest
1906−prefix :: MarkdownParser (F Inlines)
1889+prefix :: MarkdownParser Inlines
1907−prefix = trimInlinesF . mconcat <$>
1890+prefix = trimInlines . mconcat <$>
1908 manyTill inline (char ']' <|> liftM (const ']') (lookAhead citeKey))
1891 manyTill inline (char ']' <|> liftM (const ']') (lookAhead citeKey))
1910−citeList :: MarkdownParser (F [Citation])
1893+citeList :: MarkdownParser [Citation]
1911−citeList = fmap sequence $ sepBy1 citation (try $ char ';' >> spnl)
1894+citeList = sepBy1 citation (try $ char ';' >> spnl)
1913−citation :: MarkdownParser (F Citation)
1896+citation :: MarkdownParser Citation
1914citation = try $ do
1897citation = try $ do
1915 pref <- prefix
1898 pref <- prefix
1916 (suppress_author, key) <- citeKey
1899 (suppress_author, key) <- citeKey
1917 suff <- suffix
1900 suff <- suffix
1921− return $ Citation{ citationId = key
1901+ return Citation{ citationId = key
1922− , citationPrefix = B.toList x
1902+ , citationPrefix = B.toList pref
1923− , citationSuffix = B.toList y
1903+ , citationSuffix = B.toList suff
1924− , citationMode = if suppress_author
1904+ , citationMode = if suppress_author
1925− then SuppressAuthor
1905+ then SuppressAuthor
1926− else NormalCitation
1906+ else NormalCitation
1927− , citationNoteNum = 0
1907+ , citationNoteNum = 0
1928− , citationHash = 0
1908+ , citationHash = 0
1931−smart :: MarkdownParser (F Inlines)
1911+smart :: MarkdownParser Inlines
1932smart = do
1912smart = do
1933 getOption readerSmart >>= guard
1913 getOption readerSmart >>= guard
1934 doubleQuoted <|> singleQuoted <|>
1914 doubleQuoted <|> singleQuoted <|>
1935− choice (map (return <$>) [apostrophe, dash, ellipses])
1915+ choice [apostrophe, dash, ellipses]
1937−singleQuoted :: MarkdownParser (F Inlines)
1917+singleQuoted :: MarkdownParser Inlines
1938singleQuoted = try $ do
1918singleQuoted = try $ do
1939 singleQuoteStart
1919 singleQuoteStart
1940 withQuoteContext InSingleQuote $
1920 withQuoteContext InSingleQuote $
1941− fmap B.singleQuoted . trimInlinesF . mconcat <$>
1921+ B.singleQuoted . trimInlines . mconcat <$>
1942 many1Till inline singleQuoteEnd
1922 many1Till inline singleQuoteEnd
1944-- doubleQuoted will handle regular double-quoted sections, as well
1924-- doubleQuoted will handle regular double-quoted sections, as well
1945-- as dialogues with an open double-quote without a close double-quote
1925-- as dialogues with an open double-quote without a close double-quote
1946-- in the same paragraph.
1926-- in the same paragraph.
1947−doubleQuoted :: MarkdownParser (F Inlines)
1927+doubleQuoted :: MarkdownParser Inlines
1948doubleQuoted = try $ do
1928doubleQuoted = try $ do
1949 doubleQuoteStart
1929 doubleQuoteStart
1950 contents <- mconcat <$> many (try $ notFollowedBy doubleQuoteEnd >> inline)
1930 contents <- mconcat <$> many (try $ notFollowedBy doubleQuoteEnd >> inline)
1951− (withQuoteContext InDoubleQuote $ doubleQuoteEnd >> return
1931+ (withQuoteContext InDoubleQuote doubleQuoteEnd >> return
1952− (fmap B.doubleQuoted . trimInlinesF $ contents))
1932+ (B.doubleQuoted . trimInlines $ contents))
1953− <|> (return $ return (B.str "\8220") <> contents)
1933+ <|> return (B.str "\8220" <> contents)