Markdown reader: Improved inlinesInBalancedBrackets.

The change both improves performance and fixes a
regression whereby normal citations inside inline notes
were not parsed correctly.

Closes jgm/pandoc-citeproc#315.
This commit is contained in:
John MacFarlane 2018-01-14 12:23:16 -08:00
parent cd80b8d76f
commit d9584d73f9
4 changed files with 29 additions and 14 deletions

View file

@ -180,6 +180,7 @@ module Text.Pandoc.Parsing ( takeWhileP,
sourceLine,
setSourceColumn,
setSourceLine,
incSourceColumn,
newPos,
Line,
Column

View file

@ -148,19 +148,27 @@ litChar = escapedChar'
-- | Parse a sequence of inline elements between square brackets,
-- including inlines between balanced pairs of square brackets.
inlinesInBalancedBrackets :: PandocMonad m => MarkdownParser m (F Inlines)
inlinesInBalancedBrackets = try $ char '[' >> go 1
where go :: PandocMonad m => Int -> MarkdownParser m (F Inlines)
go 0 = return mempty
go openBrackets =
(mappend <$> (bracketedSpan <|> link <|> image) <*>
go openBrackets)
<|> ((if openBrackets > 1
then (return (B.str "]") <>)
else id) <$>
(char ']' >> go (openBrackets - 1)))
<|> ((return (B.str "[") <>) <$>
(char '[' >> go (openBrackets + 1)))
<|> (mappend <$> inline <*> go openBrackets)
inlinesInBalancedBrackets =
try $ char '[' >> withRaw (go 1) >>=
parseFromString inlines . stripBracket . snd
where stripBracket [] = []
stripBracket xs = if last xs == ']' then init xs else xs
go :: PandocMonad m => Int -> MarkdownParser m ()
go 0 = return ()
go openBrackets = do
(() <$ (escapedChar <|>
code <|>
rawHtmlInline <|>
rawLaTeXInline') >> go openBrackets)
<|>
(do char ']'
if openBrackets > 1
then go (openBrackets - 1)
else return ())
<|>
(char '[' >> go (openBrackets + 1))
<|>
(anyChar >> go openBrackets)
--
-- document structure

View file

@ -200,7 +200,7 @@ tests = [ testGroup "inline code"
":smile: and :+1:" =?> para (text "😄 and 👍")
]
, "unbalanced brackets" =:
"[[[[[[[[[[[hi" =?> para (text "[[[[[[[[[[[hi")
"[[[[[[[[[[[[hi" =?> para (text "[[[[[[[[[[[[hi")
, testGroup "backslash escapes"
[ "in URL" =:
"[hi](/there\\))"

View file

@ -0,0 +1,6 @@
```
% pandoc -t native
foo^[bar [@doe]]
^D
[Para [Str "foo",Note [Para [Str "bar",Space,Cite [Citation {citationId = "doe", citationPrefix = [], citationSuffix = [], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0}] [Str "[@doe]"]]]]]
```