Skip to content

Commit

Permalink
Allow fenced code blocks interrupt paragraphs
Browse files Browse the repository at this point in the history
  • Loading branch information
mrkkrp committed Dec 14, 2017
1 parent 8f00dc6 commit d24a463
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 27 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## MMark 0.0.3.0

* Code can interrupt paragraphs now, as per Common Mark spec.

## MMark 0.0.2.1

* Improved performance of the parser. Mainly the inline-level parser to be
Expand Down
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,6 @@ do, the closing `*` won't be in right-flanking position anymore. God dammit.

Block-level parsing:

* Code blocks should be separated from paragraphs and lists by at least one
empty line.
* If a line starts with hash signs it is expected to be a valid *non-empty*
header (level 1–6 inclusive). If you want to start a paragraph with
hashes, just escape the first hash with backslash and that will be enough.
Expand Down
56 changes: 33 additions & 23 deletions Text/MMark/Parser.hs
Original file line number Diff line number Diff line change
Expand Up @@ -334,33 +334,42 @@ pAtxHeading = do

pFencedCodeBlock :: BParser (Block Isp)
pFencedCodeBlock = do
let p ch = try $ do
void $ count 3 (char ch)
n <- (+ 3) . length <$> many (char ch)
ml <- optional
(T.strip <$> someEscapedWith notNewline <?> "info string")
guard (maybe True (not . T.any (== '`')) ml)
return
(ch, n,
case ml of
Nothing -> Nothing
Just l ->
if T.null l
then Nothing
else Just l)
alevel <- L.indentLevel
(ch, n, infoString) <- (p '`' <|> p '~') <* eol
(ch, n, infoString) <- pOpeningFence
let content = label "code block content" (option "" nonEmptyLine <* eol)
closingFence = try . label "closing code fence" $ do
clevel <- ilevel <$> asks benvRefLevel
void $ L.indentGuard sc' LT clevel
void $ count n (char ch)
(void . many . char) ch
sc'
eof <|> eol
ls <- manyTill content closingFence
ls <- manyTill content (pClosingFence ch n)
CodeBlock infoString (assembleCodeBlock alevel ls) <$ sc

-- | Parse the opening fence of a fenced code block.

pOpeningFence :: BParser (Char, Int, Maybe Text)
pOpeningFence = p '`' <|> p '~'
where
p ch = try $ do
void $ count 3 (char ch)
n <- (+ 3) . length <$> many (char ch)
ml <- optional
(T.strip <$> someEscapedWith notNewline <?> "info string")
guard (maybe True (not . T.any (== '`')) ml)
(ch, n,
case ml of
Nothing -> Nothing
Just l ->
if T.null l
then Nothing
else Just l) <$ eol

-- | Parse the closing fence of a fenced code block.

pClosingFence :: Char -> Int -> BParser ()
pClosingFence ch n = try . label "closing code fence" $ do
clevel <- ilevel <$> asks benvRefLevel
void $ L.indentGuard sc' LT clevel
void $ count n (char ch)
(void . many . char) ch
sc'
eof <|> eol

-- | Parse an indented code block.

pIndentedCodeBlock :: BParser (Block Isp)
Expand Down Expand Up @@ -532,6 +541,7 @@ pParagraph = do
[ void (char '>')
, void pThematicBreak
, void pAtxHeading
, void pOpeningFence
, void (pListBullet Nothing)
, void (pListIndex Nothing) ]
if isBlank l
Expand Down
4 changes: 2 additions & 2 deletions tests/Text/MMarkSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ spec = parallel $ do
it "CM94" $
let s = "```"
in s ~-> err (posN 3 s)
(ueof <> etok '`' <> elabel "info string" <> elabel "newline")
(ueib <> etok '`' <> elabel "code span content")
it "CM95" $
let s = "`````\n\n```\naaa\n"
in s ~-> err (posN 15 s)
Expand Down Expand Up @@ -266,7 +266,7 @@ spec = parallel $ do
(ueof <> elabel "closing code fence" <> elabel "code block content")
it "CM108" $
"foo\n```\nbar\n```\nbaz" ==->
"<p>foo\n<code>bar</code>\nbaz</p>\n"
"<p>foo</p>\n<pre><code>bar\n</code></pre>\n<p>baz</p>\n"
xit "CM109" $ -- FIXME pending setext headings
"foo\n---\n~~~\nbar\n~~~\n# baz" ==->
"<h2>foo</h2>\n<pre><code>bar\n</code></pre>\n<h1>baz</h1>\n"
Expand Down

0 comments on commit d24a463

Please sign in to comment.