Parsing: Provide parseFromString'.

This is a verison of parseFromString specialied to
ParserState, which resets stateLastStrPos at the end.
This is almost always what we want.

This fixes a bug where `_hi_` wasn't treated as emphasis in
the following, because pandoc got confused about the
position of the last word:

    - [o] _hi_

Closes #3690.
This commit is contained in:
John MacFarlane 2017-05-24 22:41:47 +02:00
parent d4ccd1e001
commit bc6aac7b47
8 changed files with 88 additions and 62 deletions

View file

@ -50,6 +50,7 @@ module Text.Pandoc.Parsing ( anyLine,
enclosed, enclosed,
stringAnyCase, stringAnyCase,
parseFromString, parseFromString,
parseFromString',
lineClump, lineClump,
charsInBalanced, charsInBalanced,
romanNumeral, romanNumeral,
@ -358,7 +359,10 @@ stringAnyCase (x:xs) = do
return (firstChar:rest) return (firstChar:rest)
-- | Parse contents of 'str' using 'parser' and return result. -- | Parse contents of 'str' using 'parser' and return result.
parseFromString :: Monad m => ParserT String st m a -> String -> ParserT String st m a parseFromString :: Monad m
=> ParserT String st m a
-> String
-> ParserT String st m a
parseFromString parser str = do parseFromString parser str = do
oldPos <- getPosition oldPos <- getPosition
oldInput <- getInput oldInput <- getInput
@ -370,6 +374,18 @@ parseFromString parser str = do
setPosition oldPos setPosition oldPos
return result return result
-- | Like 'parseFromString' but specialized for 'ParserState'.
-- This resets 'stateLastStrPos', which is almost always what we want.
parseFromString' :: Monad m
=> ParserT String ParserState m a
-> String
-> ParserT String ParserState m a
parseFromString' parser str = do
oldStrPos <- stateLastStrPos <$> getState
res <- parseFromString parser str
updateState $ \st -> st{ stateLastStrPos = oldStrPos }
return res
-- | Parse raw line block up to and including blank lines. -- | Parse raw line block up to and including blank lines.
lineClump :: Stream [Char] m Char => ParserT [Char] st m String lineClump :: Stream [Char] m Char => ParserT [Char] st m String
lineClump = blanklines lineClump = blanklines

View file

@ -304,8 +304,8 @@ blockCommand = try $ do
rawcommand <- getRawCommand name' rawcommand <- getRawCommand name'
transformed <- applyMacros' rawcommand transformed <- applyMacros' rawcommand
guard $ transformed /= rawcommand guard $ transformed /= rawcommand
notFollowedBy $ parseFromString inlines transformed notFollowedBy $ parseFromString' inlines transformed
parseFromString blocks transformed parseFromString' blocks transformed
lookupListDefault raw [name',name] blockCommands lookupListDefault raw [name',name] blockCommands
inBrackets :: Inlines -> Inlines inBrackets :: Inlines -> Inlines
@ -475,7 +475,7 @@ inlineCommand = try $ do
transformed <- applyMacros' rawcommand transformed <- applyMacros' rawcommand
exts <- getOption readerExtensions exts <- getOption readerExtensions
if transformed /= rawcommand if transformed /= rawcommand
then parseFromString inlines transformed then parseFromString' inlines transformed
else if extensionEnabled Ext_raw_tex exts else if extensionEnabled Ext_raw_tex exts
then return $ rawInline "latex" rawcommand then return $ rawInline "latex" rawcommand
else ignore rawcommand else ignore rawcommand
@ -1021,7 +1021,7 @@ rawEnv name = do
(bs, raw) <- withRaw $ env name blocks (bs, raw) <- withRaw $ env name blocks
raw' <- applyMacros' $ beginCommand ++ raw raw' <- applyMacros' $ beginCommand ++ raw
if raw' /= beginCommand ++ raw if raw' /= beginCommand ++ raw
then parseFromString blocks raw' then parseFromString' blocks raw'
else if parseRaw else if parseRaw
then return $ rawBlock "latex" $ beginCommand ++ raw' then return $ rawBlock "latex" $ beginCommand ++ raw'
else do else do
@ -1119,7 +1119,7 @@ keyvals :: PandocMonad m => LP m [(String, String)]
keyvals = try $ char '[' *> manyTill keyval (char ']') keyvals = try $ char '[' *> manyTill keyval (char ']')
alltt :: PandocMonad m => String -> LP m Blocks alltt :: PandocMonad m => String -> LP m Blocks
alltt t = walk strToCode <$> parseFromString blocks alltt t = walk strToCode <$> parseFromString' blocks
(substitute " " "\\ " $ substitute "%" "\\%" $ (substitute " " "\\ " $ substitute "%" "\\%" $
intercalate "\\\\\n" $ lines t) intercalate "\\\\\n" $ lines t)
where strToCode (Str s) = Code nullAttr s where strToCode (Str s) = Code nullAttr s
@ -1503,7 +1503,7 @@ parseTableRow cols prefixes suffixes = try $ do
guard $ length rawcells == cols guard $ length rawcells == cols
let rawcells' = zipWith3 (\c p s -> p ++ trim c ++ s) let rawcells' = zipWith3 (\c p s -> p ++ trim c ++ s)
rawcells prefixes suffixes rawcells prefixes suffixes
cells' <- mapM (parseFromString tableCell) rawcells' cells' <- mapM (parseFromString' tableCell) rawcells'
let numcells = length cells' let numcells = length cells'
guard $ numcells <= cols && numcells >= 1 guard $ numcells <= cols && numcells >= 1
guard $ cells' /= [mempty] guard $ cells' /= [mempty]

View file

@ -155,9 +155,11 @@ litChar = escapedChar'
inlinesInBalancedBrackets :: PandocMonad m => MarkdownParser m (F Inlines) inlinesInBalancedBrackets :: PandocMonad m => MarkdownParser m (F Inlines)
inlinesInBalancedBrackets = do inlinesInBalancedBrackets = do
char '[' char '['
pos <- getPosition
(_, raw) <- withRaw $ charsInBalancedBrackets 1 (_, raw) <- withRaw $ charsInBalancedBrackets 1
guard $ not $ null raw guard $ not $ null raw
parseFromString (trimInlinesF . mconcat <$> many inline) (init raw) parseFromString' (setPosition pos >>
trimInlinesF . mconcat <$> many inline) (init raw)
charsInBalancedBrackets :: PandocMonad m => Int -> MarkdownParser m () charsInBalancedBrackets :: PandocMonad m => Int -> MarkdownParser m ()
charsInBalancedBrackets 0 = return () charsInBalancedBrackets 0 = return ()
@ -189,7 +191,7 @@ rawTitleBlockLine = do
titleLine :: PandocMonad m => MarkdownParser m (F Inlines) titleLine :: PandocMonad m => MarkdownParser m (F Inlines)
titleLine = try $ do titleLine = try $ do
raw <- rawTitleBlockLine raw <- rawTitleBlockLine
res <- parseFromString (many inline) raw res <- parseFromString' (many inline) raw
return $ trimInlinesF $ mconcat res return $ trimInlinesF $ mconcat res
authorsLine :: PandocMonad m => MarkdownParser m (F [Inlines]) authorsLine :: PandocMonad m => MarkdownParser m (F [Inlines])
@ -200,12 +202,12 @@ authorsLine = try $ do
(trimInlinesF . mconcat <$> many (trimInlinesF . mconcat <$> many
(try $ notFollowedBy sep >> inline)) (try $ notFollowedBy sep >> inline))
sep sep
sequence <$> parseFromString pAuthors raw sequence <$> parseFromString' pAuthors raw
dateLine :: PandocMonad m => MarkdownParser m (F Inlines) dateLine :: PandocMonad m => MarkdownParser m (F Inlines)
dateLine = try $ do dateLine = try $ do
raw <- rawTitleBlockLine raw <- rawTitleBlockLine
res <- parseFromString (many inline) raw res <- parseFromString' (many inline) raw
return $ trimInlinesF $ mconcat res return $ trimInlinesF $ mconcat res
titleBlock :: PandocMonad m => MarkdownParser m () titleBlock :: PandocMonad m => MarkdownParser m ()
@ -290,7 +292,7 @@ ignorable t = (T.pack "_") `T.isSuffixOf` t
toMetaValue :: PandocMonad m toMetaValue :: PandocMonad m
=> Text -> MarkdownParser m (F MetaValue) => Text -> MarkdownParser m (F MetaValue)
toMetaValue x = toMeta <$> parseFromString parseBlocks (T.unpack x) toMetaValue x = toMeta <$> parseFromString' parseBlocks (T.unpack x)
where where
toMeta p = do toMeta p = do
p' <- p p' <- p
@ -466,7 +468,7 @@ noteBlock = try $ do
rest <- many $ try $ blanklines >> indentSpaces >> rawLines rest <- many $ try $ blanklines >> indentSpaces >> rawLines
let raw = unlines (first:rest) ++ "\n" let raw = unlines (first:rest) ++ "\n"
optional blanklines optional blanklines
parsed <- parseFromString parseBlocks raw parsed <- parseFromString' parseBlocks raw
let newnote = (ref, parsed) let newnote = (ref, parsed)
oldnotes <- stateNotes' <$> getState oldnotes <- stateNotes' <$> getState
case lookup ref oldnotes of case lookup ref oldnotes of
@ -774,7 +776,7 @@ blockQuote :: PandocMonad m => MarkdownParser m (F Blocks)
blockQuote = do blockQuote = do
raw <- emailBlockQuote raw <- emailBlockQuote
-- parse the extracted block, which may contain various block elements: -- parse the extracted block, which may contain various block elements:
contents <- parseFromString parseBlocks $ (intercalate "\n" raw) ++ "\n\n" contents <- parseFromString' parseBlocks $ (intercalate "\n" raw) ++ "\n\n"
return $ B.blockQuote <$> contents return $ B.blockQuote <$> contents
-- --
@ -887,7 +889,7 @@ listItem start = try $ do
setState $ state {stateParserContext = ListItemState} setState $ state {stateParserContext = ListItemState}
-- parse the extracted block, which may contain various block elements: -- parse the extracted block, which may contain various block elements:
let raw = concat (first:continuations) let raw = concat (first:continuations)
contents <- parseFromString parseBlocks raw contents <- parseFromString' parseBlocks raw
updateState (\st -> st {stateParserContext = oldContext}) updateState (\st -> st {stateParserContext = oldContext})
return contents return contents
@ -934,8 +936,8 @@ definitionListItem :: PandocMonad m => Bool -> MarkdownParser m (F (Inlines, [Bl
definitionListItem compact = try $ do definitionListItem compact = try $ do
rawLine' <- anyLine rawLine' <- anyLine
raw <- many1 $ defRawBlock compact raw <- many1 $ defRawBlock compact
term <- parseFromString (trimInlinesF . mconcat <$> many inline) rawLine' term <- parseFromString' (trimInlinesF . mconcat <$> many inline) rawLine'
contents <- mapM (parseFromString parseBlocks . (++"\n")) raw contents <- mapM (parseFromString' parseBlocks . (++"\n")) raw
optional blanklines optional blanklines
return $ liftM2 (,) term (sequence contents) return $ liftM2 (,) term (sequence contents)
@ -1127,7 +1129,7 @@ lineBlock :: PandocMonad m => MarkdownParser m (F Blocks)
lineBlock = try $ do lineBlock = try $ do
guardEnabled Ext_line_blocks guardEnabled Ext_line_blocks
lines' <- lineBlockLines >>= lines' <- lineBlockLines >>=
mapM (parseFromString (trimInlinesF . mconcat <$> many inline)) mapM (parseFromString' (trimInlinesF . mconcat <$> many inline))
return $ B.lineBlock <$> sequence lines' return $ B.lineBlock <$> sequence lines'
-- --
@ -1170,7 +1172,7 @@ simpleTableHeader headless = try $ do
then replicate (length dashes) "" then replicate (length dashes) ""
else rawHeads else rawHeads
heads <- fmap sequence heads <- fmap sequence
$ mapM (parseFromString (mconcat <$> many plain)) $ mapM (parseFromString' (mconcat <$> many plain))
$ map trim rawHeads' $ map trim rawHeads'
return (heads, aligns, indices) return (heads, aligns, indices)
@ -1216,7 +1218,7 @@ tableLine :: PandocMonad m
=> [Int] => [Int]
-> MarkdownParser m (F [Blocks]) -> MarkdownParser m (F [Blocks])
tableLine indices = rawTableLine indices >>= tableLine indices = rawTableLine indices >>=
fmap sequence . mapM (parseFromString (mconcat <$> many plain)) fmap sequence . mapM (parseFromString' (mconcat <$> many plain))
-- Parse a multiline table row and return a list of blocks (columns). -- Parse a multiline table row and return a list of blocks (columns).
multilineRow :: PandocMonad m multilineRow :: PandocMonad m
@ -1225,7 +1227,7 @@ multilineRow :: PandocMonad m
multilineRow indices = do multilineRow indices = do
colLines <- many1 (rawTableLine indices) colLines <- many1 (rawTableLine indices)
let cols = map unlines $ transpose colLines let cols = map unlines $ transpose colLines
fmap sequence $ mapM (parseFromString (mconcat <$> many plain)) cols fmap sequence $ mapM (parseFromString' (mconcat <$> many plain)) cols
-- Parses a table caption: inlines beginning with 'Table:' -- Parses a table caption: inlines beginning with 'Table:'
-- and followed by blank lines. -- and followed by blank lines.
@ -1283,7 +1285,7 @@ multilineTableHeader headless = try $ do
then replicate (length dashes) "" then replicate (length dashes) ""
else map (unlines . map trim) rawHeadsList else map (unlines . map trim) rawHeadsList
heads <- fmap sequence $ heads <- fmap sequence $
mapM (parseFromString (mconcat <$> many plain)) $ mapM (parseFromString' (mconcat <$> many plain)) $
map trim rawHeads map trim rawHeads
return (heads, aligns, indices) return (heads, aligns, indices)
@ -1340,7 +1342,7 @@ pipeTableRow = try $ do
let chunk = void (code <|> math <|> rawHtmlInline <|> escapedChar <|> rawLaTeXInline') let chunk = void (code <|> math <|> rawHtmlInline <|> escapedChar <|> rawLaTeXInline')
<|> void (noneOf "|\n\r") <|> void (noneOf "|\n\r")
let cellContents = ((trim . snd) <$> withRaw (many chunk)) >>= let cellContents = ((trim . snd) <$> withRaw (many chunk)) >>=
parseFromString pipeTableCell parseFromString' pipeTableCell
cells <- cellContents `sepEndBy1` (char '|') cells <- cellContents `sepEndBy1` (char '|')
-- surrounding pipes needed for a one-column table: -- surrounding pipes needed for a one-column table:
guard $ not (length cells == 1 && not openPipe) guard $ not (length cells == 1 && not openPipe)
@ -1747,8 +1749,8 @@ referenceLink constructor (lab, raw) = do
when (raw' == "") $ guardEnabled Ext_shortcut_reference_links when (raw' == "") $ guardEnabled Ext_shortcut_reference_links
let labIsRef = raw' == "" || raw' == "[]" let labIsRef = raw' == "" || raw' == "[]"
let key = toKey $ if labIsRef then raw else raw' let key = toKey $ if labIsRef then raw else raw'
parsedRaw <- parseFromString (mconcat <$> many inline) raw' parsedRaw <- parseFromString' (mconcat <$> many inline) raw'
fallback <- parseFromString (mconcat <$> many inline) $ dropBrackets raw fallback <- parseFromString' (mconcat <$> many inline) $ dropBrackets raw
implicitHeaderRefs <- option False $ implicitHeaderRefs <- option False $
True <$ guardEnabled Ext_implicit_header_references True <$ guardEnabled Ext_implicit_header_references
let makeFallback = do let makeFallback = do
@ -1954,7 +1956,7 @@ textualCite = try $ do
let (spaces',raw') = span isSpace raw let (spaces',raw') = span isSpace raw
spc | null spaces' = mempty spc | null spaces' = mempty
| otherwise = B.space | otherwise = B.space
lab <- parseFromString (mconcat <$> many inline) $ dropBrackets raw' lab <- parseFromString' (mconcat <$> many inline) $ dropBrackets raw'
fallback <- referenceLink B.linkWith (lab,raw') fallback <- referenceLink B.linkWith (lab,raw')
return $ do return $ do
fallback' <- fallback fallback' <- fallback

View file

@ -196,7 +196,7 @@ parseRST = do
parseCitation :: PandocMonad m parseCitation :: PandocMonad m
=> (String, String) -> RSTParser m (Inlines, [Blocks]) => (String, String) -> RSTParser m (Inlines, [Blocks])
parseCitation (ref, raw) = do parseCitation (ref, raw) = do
contents <- parseFromString parseBlocks raw contents <- parseFromString' parseBlocks raw
return $ (B.spanWith (ref, ["citation-label"], []) (B.str ref), return $ (B.spanWith (ref, ["citation-label"], []) (B.str ref),
[contents]) [contents])
@ -246,7 +246,7 @@ fieldListItem :: PandocMonad m => Int -> RSTParser m (Inlines, [Blocks])
fieldListItem minIndent = try $ do fieldListItem minIndent = try $ do
(name, raw) <- rawFieldListItem minIndent (name, raw) <- rawFieldListItem minIndent
term <- parseInlineFromString name term <- parseInlineFromString name
contents <- parseFromString parseBlocks raw contents <- parseFromString' parseBlocks raw
optional blanklines optional blanklines
return (term, [contents]) return (term, [contents])
@ -445,7 +445,7 @@ blockQuote :: PandocMonad m => RSTParser m Blocks
blockQuote = do blockQuote = do
raw <- indentedBlock raw <- indentedBlock
-- parse the extracted block, which may contain various block elements: -- parse the extracted block, which may contain various block elements:
contents <- parseFromString parseBlocks $ raw ++ "\n\n" contents <- parseFromString' parseBlocks $ raw ++ "\n\n"
return $ B.blockQuote contents return $ B.blockQuote contents
{- {-
@ -533,7 +533,7 @@ definitionListItem = try $ do
term <- trimInlines . mconcat <$> many1Till inline endline term <- trimInlines . mconcat <$> many1Till inline endline
raw <- indentedBlock raw <- indentedBlock
-- parse the extracted block, which may contain various block elements: -- parse the extracted block, which may contain various block elements:
contents <- parseFromString parseBlocks $ raw ++ "\n" contents <- parseFromString' parseBlocks $ raw ++ "\n"
return (term, [contents]) return (term, [contents])
definitionList :: PandocMonad m => RSTParser m Blocks definitionList :: PandocMonad m => RSTParser m Blocks
@ -595,7 +595,7 @@ listItem start = try $ do
let oldContext = stateParserContext state let oldContext = stateParserContext state
setState $ state {stateParserContext = ListItemState} setState $ state {stateParserContext = ListItemState}
-- parse the extracted block, which may itself contain block elements -- parse the extracted block, which may itself contain block elements
parsed <- parseFromString parseBlocks $ concat (first:rest) ++ "\n" parsed <- parseFromString' parseBlocks $ concat (first:rest) ++ "\n"
updateState (\st -> st {stateParserContext = oldContext}) updateState (\st -> st {stateParserContext = oldContext})
return $ case B.toList parsed of return $ case B.toList parsed of
[Para xs] -> [Para xs] ->
@ -686,19 +686,19 @@ directive' = do
"line-block" -> lineBlockDirective body' "line-block" -> lineBlockDirective body'
"raw" -> return $ B.rawBlock (trim top) (stripTrailingNewlines body) "raw" -> return $ B.rawBlock (trim top) (stripTrailingNewlines body)
"role" -> addNewRole top $ map (\(k,v) -> (k, trim v)) fields "role" -> addNewRole top $ map (\(k,v) -> (k, trim v)) fields
"container" -> parseFromString parseBlocks body' "container" -> parseFromString' parseBlocks body'
"replace" -> B.para <$> -- consumed by substKey "replace" -> B.para <$> -- consumed by substKey
parseInlineFromString (trim top) parseInlineFromString (trim top)
"unicode" -> B.para <$> -- consumed by substKey "unicode" -> B.para <$> -- consumed by substKey
parseInlineFromString (trim $ unicodeTransform top) parseInlineFromString (trim $ unicodeTransform top)
"compound" -> parseFromString parseBlocks body' "compound" -> parseFromString' parseBlocks body'
"pull-quote" -> B.blockQuote <$> parseFromString parseBlocks body' "pull-quote" -> B.blockQuote <$> parseFromString' parseBlocks body'
"epigraph" -> B.blockQuote <$> parseFromString parseBlocks body' "epigraph" -> B.blockQuote <$> parseFromString' parseBlocks body'
"highlights" -> B.blockQuote <$> parseFromString parseBlocks body' "highlights" -> B.blockQuote <$> parseFromString' parseBlocks body'
"rubric" -> B.para . B.strong <$> parseInlineFromString top "rubric" -> B.para . B.strong <$> parseInlineFromString top
_ | label `elem` ["attention","caution","danger","error","hint", _ | label `elem` ["attention","caution","danger","error","hint",
"important","note","tip","warning","admonition"] -> "important","note","tip","warning","admonition"] ->
do bod <- parseFromString parseBlocks $ top ++ "\n\n" ++ body' do bod <- parseFromString' parseBlocks $ top ++ "\n\n" ++ body'
let lab = case label of let lab = case label of
"admonition" -> mempty "admonition" -> mempty
(l:ls) -> B.divWith ("",["admonition-title"],[]) (l:ls) -> B.divWith ("",["admonition-title"],[])
@ -711,11 +711,11 @@ directive' = do
(trim top ++ if null subtit (trim top ++ if null subtit
then "" then ""
else (": " ++ subtit)) else (": " ++ subtit))
bod <- parseFromString parseBlocks body' bod <- parseFromString' parseBlocks body'
return $ B.divWith ("",["sidebar"],[]) $ tit <> bod return $ B.divWith ("",["sidebar"],[]) $ tit <> bod
"topic" -> "topic" ->
do tit <- B.para . B.strong <$> parseInlineFromString top do tit <- B.para . B.strong <$> parseInlineFromString top
bod <- parseFromString parseBlocks body' bod <- parseFromString' parseBlocks body'
return $ B.divWith ("",["topic"],[]) $ tit <> bod return $ B.divWith ("",["topic"],[]) $ tit <> bod
"default-role" -> mempty <$ updateState (\s -> "default-role" -> mempty <$ updateState (\s ->
s { stateRstDefaultRole = s { stateRstDefaultRole =
@ -731,7 +731,7 @@ directive' = do
"math" -> return $ B.para $ mconcat $ map B.displayMath "math" -> return $ B.para $ mconcat $ map B.displayMath
$ toChunks $ top ++ "\n\n" ++ body $ toChunks $ top ++ "\n\n" ++ body
"figure" -> do "figure" -> do
(caption, legend) <- parseFromString extractCaption body' (caption, legend) <- parseFromString' extractCaption body'
let src = escapeURI $ trim top let src = escapeURI $ trim top
return $ B.para (B.imageWith (imgAttr "figclass") src "fig:" return $ B.para (B.imageWith (imgAttr "figclass") src "fig:"
caption) <> legend caption) <> legend
@ -750,21 +750,21 @@ directive' = do
-- directive content or the first immediately following element -- directive content or the first immediately following element
children <- case body of children <- case body of
"" -> block "" -> block
_ -> parseFromString parseBlocks body' _ -> parseFromString' parseBlocks body'
return $ B.divWith attrs children return $ B.divWith attrs children
other -> do other -> do
pos <- getPosition pos <- getPosition
logMessage $ SkippedContent (".. " ++ other) pos logMessage $ SkippedContent (".. " ++ other) pos
bod <- parseFromString parseBlocks $ top ++ "\n\n" ++ body' bod <- parseFromString' parseBlocks $ top ++ "\n\n" ++ body'
return $ B.divWith ("",[other],[]) bod return $ B.divWith ("",[other],[]) bod
tableDirective :: PandocMonad m tableDirective :: PandocMonad m
=> String -> [(String, String)] -> String -> RSTParser m Blocks => String -> [(String, String)] -> String -> RSTParser m Blocks
tableDirective top _fields body = do tableDirective top _fields body = do
bs <- parseFromString parseBlocks body bs <- parseFromString' parseBlocks body
case B.toList bs of case B.toList bs of
[Table _ aligns' widths' header' rows'] -> do [Table _ aligns' widths' header' rows'] -> do
title <- parseFromString (trimInlines . mconcat <$> many inline) top title <- parseFromString' (trimInlines . mconcat <$> many inline) top
-- TODO widths -- TODO widths
-- align is not applicable since we can't represent whole table align -- align is not applicable since we can't represent whole table align
return $ B.singleton $ Table (B.toList title) return $ B.singleton $ Table (B.toList title)
@ -780,8 +780,8 @@ listTableDirective :: PandocMonad m
=> String -> [(String, String)] -> String => String -> [(String, String)] -> String
-> RSTParser m Blocks -> RSTParser m Blocks
listTableDirective top fields body = do listTableDirective top fields body = do
bs <- parseFromString parseBlocks body bs <- parseFromString' parseBlocks body
title <- parseFromString (trimInlines . mconcat <$> many inline) top title <- parseFromString' (trimInlines . mconcat <$> many inline) top
let rows = takeRows $ B.toList bs let rows = takeRows $ B.toList bs
headerRowsNum = fromMaybe (0 :: Int) $ headerRowsNum = fromMaybe (0 :: Int) $
lookup "header-rows" fields >>= safeRead lookup "header-rows" fields >>= safeRead
@ -812,7 +812,7 @@ addNewRole :: PandocMonad m
=> String -> [(String, String)] -> RSTParser m Blocks => String -> [(String, String)] -> RSTParser m Blocks
addNewRole roleString fields = do addNewRole roleString fields = do
pos <- getPosition pos <- getPosition
(role, parentRole) <- parseFromString inheritedRole roleString (role, parentRole) <- parseFromString' inheritedRole roleString
customRoles <- stateRstCustomRoles <$> getState customRoles <- stateRstCustomRoles <$> getState
let getBaseRole (r, f, a) roles = let getBaseRole (r, f, a) roles =
case M.lookup r roles of case M.lookup r roles of
@ -1127,7 +1127,7 @@ simpleTableRow indices = do
let cols = map unlines . transpose $ firstLine : conLines ++ let cols = map unlines . transpose $ firstLine : conLines ++
[replicate (length indices) "" [replicate (length indices) ""
| not (null conLines)] | not (null conLines)]
mapM (parseFromString parseBlocks) cols mapM (parseFromString' parseBlocks) cols
simpleTableSplitLine :: [Int] -> String -> [String] simpleTableSplitLine :: [Int] -> String -> [String]
simpleTableSplitLine indices line = simpleTableSplitLine indices line =
@ -1150,7 +1150,7 @@ simpleTableHeader headless = try $ do
let rawHeads = if headless let rawHeads = if headless
then replicate (length dashes) "" then replicate (length dashes) ""
else simpleTableSplitLine indices rawContent else simpleTableSplitLine indices rawContent
heads <- mapM (parseFromString (mconcat <$> many plain)) $ heads <- mapM (parseFromString' (mconcat <$> many plain)) $
map trim rawHeads map trim rawHeads
return (heads, aligns, indices) return (heads, aligns, indices)
@ -1206,7 +1206,7 @@ inline = choice [ note -- can start with whitespace, so try before ws
, symbol ] <?> "inline" , symbol ] <?> "inline"
parseInlineFromString :: PandocMonad m => String -> RSTParser m Inlines parseInlineFromString :: PandocMonad m => String -> RSTParser m Inlines
parseInlineFromString = parseFromString (trimInlines . mconcat <$> many inline) parseInlineFromString = parseFromString' (trimInlines . mconcat <$> many inline)
hyphens :: Monad m => RSTParser m Inlines hyphens :: Monad m => RSTParser m Inlines
hyphens = do hyphens = do
@ -1470,7 +1470,7 @@ note = try $ do
-- Note references inside other notes are allowed in reST, but -- Note references inside other notes are allowed in reST, but
-- not yet in this implementation. -- not yet in this implementation.
updateState $ \st -> st{ stateNotes = [] } updateState $ \st -> st{ stateNotes = [] }
contents <- parseFromString parseBlocks raw contents <- parseFromString' parseBlocks raw
let newnotes = if (ref == "*" || ref == "#") -- auto-numbered let newnotes = if (ref == "*" || ref == "#") -- auto-numbered
-- delete the note so the next auto-numbered note -- delete the note so the next auto-numbered note
-- doesn't get the same contents: -- doesn't get the same contents:

View file

@ -106,7 +106,7 @@ parseHtmlContentWithAttrs tag parser = do
parsedContent <- try $ parseContent content parsedContent <- try $ parseContent content
return (attr, parsedContent) return (attr, parsedContent)
where where
parseContent = parseFromString $ nested $ manyTill parser endOfContent parseContent = parseFromString' $ nested $ manyTill parser endOfContent
endOfContent = try $ skipMany blankline >> skipSpaces >> eof endOfContent = try $ skipMany blankline >> skipSpaces >> eof
parseHtmlContent :: PandocMonad m => String -> TWParser m a -> TWParser m [a] parseHtmlContent :: PandocMonad m => String -> TWParser m a -> TWParser m [a]
@ -233,7 +233,7 @@ listItemLine prefix marker = lineContent >>= parseContent >>= return . mconcat
filterSpaces = reverse . dropWhile (== ' ') . reverse filterSpaces = reverse . dropWhile (== ' ') . reverse
listContinuation = notFollowedBy (string prefix >> marker) >> listContinuation = notFollowedBy (string prefix >> marker) >>
string " " >> lineContent string " " >> lineContent
parseContent = parseFromString $ many1 $ nestedList <|> parseInline parseContent = parseFromString' $ many1 $ nestedList <|> parseInline
parseInline = many1Till inline (lastNewline <|> newlineBeforeNestedList) >>= parseInline = many1Till inline (lastNewline <|> newlineBeforeNestedList) >>=
return . B.plain . mconcat return . B.plain . mconcat
nestedList = list prefix nestedList = list prefix
@ -297,7 +297,7 @@ noautolink = do
setState $ st{ stateAllowLinks = True } setState $ st{ stateAllowLinks = True }
return $ mconcat blocks return $ mconcat blocks
where where
parseContent = parseFromString $ many $ block parseContent = parseFromString' $ many $ block
para :: PandocMonad m => TWParser m B.Blocks para :: PandocMonad m => TWParser m B.Blocks
para = many1Till inline endOfParaElement >>= return . result . mconcat para = many1Till inline endOfParaElement >>= return . result . mconcat
@ -525,4 +525,4 @@ linkText = do
return (url, "", content) return (url, "", content)
where where
linkContent = (char '[') >> many1Till anyChar (char ']') >>= parseLinkContent linkContent = (char '[') >> many1Till anyChar (char ']') >>= parseLinkContent
parseLinkContent = parseFromString $ many1 inline parseLinkContent = parseFromString' $ many1 inline

View file

@ -315,7 +315,7 @@ definitionListItem = try $ do
optional whitespace >> newline optional whitespace >> newline
s <- many1Till anyChar (try (string "=:" >> newline)) s <- many1Till anyChar (try (string "=:" >> newline))
-- this ++ "\n\n" does not look very good -- this ++ "\n\n" does not look very good
ds <- parseFromString parseBlocks (s ++ "\n\n") ds <- parseFromString' parseBlocks (s ++ "\n\n")
return [ds] return [ds]
-- raw content -- raw content
@ -367,7 +367,7 @@ tableCell = try $ do
notFollowedBy blankline notFollowedBy blankline
raw <- trim <$> raw <- trim <$>
many (noneOf "|\n" <|> try (char '\n' <* notFollowedBy blankline)) many (noneOf "|\n" <|> try (char '\n' <* notFollowedBy blankline))
content <- mconcat <$> parseFromString (many inline) raw content <- mconcat <$> parseFromString' (many inline) raw
return ((isHeader, alignment), B.plain content) return ((isHeader, alignment), B.plain content)
-- | A table row is made of many table cells -- | A table row is made of many table cells
@ -389,7 +389,7 @@ table = try $ do
_ <- attributes _ <- attributes
char '.' char '.'
rawcapt <- trim <$> anyLine rawcapt <- trim <$> anyLine
parseFromString (mconcat <$> many inline) rawcapt parseFromString' (mconcat <$> many inline) rawcapt
rawrows <- many1 $ (skipMany ignorableRow) >> tableRow rawrows <- many1 $ (skipMany ignorableRow) >> tableRow
skipMany ignorableRow skipMany ignorableRow
blanklines blanklines
@ -507,7 +507,7 @@ note = try $ do
notes <- stateNotes <$> getState notes <- stateNotes <$> getState
case lookup ref notes of case lookup ref notes of
Nothing -> fail "note not found" Nothing -> fail "note not found"
Just raw -> B.note <$> parseFromString parseBlocks raw Just raw -> B.note <$> parseFromString' parseBlocks raw
-- | Special chars -- | Special chars
markupChars :: [Char] markupChars :: [Char]

View file

@ -212,7 +212,7 @@ quote :: T2T Blocks
quote = try $ do quote = try $ do
lookAhead tab lookAhead tab
rawQuote <- many1 (tab *> optional spaces *> anyLine) rawQuote <- many1 (tab *> optional spaces *> anyLine)
contents <- parseFromString parseBlocks (intercalate "\n" rawQuote ++ "\n\n") contents <- parseFromString' parseBlocks (intercalate "\n" rawQuote ++ "\n\n")
return $ B.blockQuote contents return $ B.blockQuote contents
commentLine :: T2T Inlines commentLine :: T2T Inlines
@ -264,7 +264,7 @@ listItem start end = try $ do
firstLine <- anyLineNewline firstLine <- anyLineNewline
blank <- option "" ("\n" <$ blankline) blank <- option "" ("\n" <$ blankline)
rest <- concat <$> many (listContinuation markerLength) rest <- concat <$> many (listContinuation markerLength)
parseFromString end $ firstLine ++ blank ++ rest parseFromString' end $ firstLine ++ blank ++ rest
-- continuation of a list item - indented and separated by blankline or endline. -- continuation of a list item - indented and separated by blankline or endline.
-- Note: nested lists are parsed as continuations. -- Note: nested lists are parsed as continuations.
@ -439,7 +439,7 @@ inlineMarkup p f c special = try $ do
Just middle -> do Just middle -> do
lastChar <- anyChar lastChar <- anyChar
end <- many1 (char c) end <- many1 (char c)
let parser inp = parseFromString (mconcat <$> many p) inp let parser inp = parseFromString' (mconcat <$> many p) inp
let start' = case drop 2 start of let start' = case drop 2 start of
"" -> mempty "" -> mempty
xs -> special xs xs -> special xs

8
test/command/3690.md Normal file
View file

@ -0,0 +1,8 @@
```
% pandoc
- [o] _hi_
^D
<ul>
<li>[o] <em>hi</em></li>
</ul>
```