From cd0653914a05c0753f1732d60a1fc9b1e183e734 Mon Sep 17 00:00:00 2001
From: Michael Howell
Date: Tue, 31 Oct 2023 16:54:03 -0700
Subject: [PATCH] Parse footnote definitions with lazy continuation
Fixes #126
This change brings it into alignment with GitHub,
[markdown-it](https://markdown-it.github.io/#md3=%7B%22source%22%3A%22%5B%5Efoo%5D%3Abar%5Cnbaz%5Cn%5Cn%20%20%20%20quux%5Cnarst%5Cn%20%20%20%20qwfp%5Cn%5Cn%5B%5Efoo%5D%22%2C%22defaults%22%3A%7B%22html%22%3Afalse%2C%22xhtmlOut%22%3Afalse%2C%22breaks%22%3Afalse%2C%22langPrefix%22%3A%22language-%22%2C%22linkify%22%3Atrue%2C%22typographer%22%3Atrue%2C%22_highlight%22%3Atrue%2C%22_strict%22%3Afalse%2C%22_view%22%3A%22html%22%7D%7D),
and hugo/goldmark.
---
.../src/Commonmark/Extensions/Footnote.hs | 20 ++++---
commonmark-extensions/test/footnotes.md | 56 +++++++++++++++++++
2 files changed, 69 insertions(+), 7 deletions(-)
diff --git a/commonmark-extensions/src/Commonmark/Extensions/Footnote.hs b/commonmark-extensions/src/Commonmark/Extensions/Footnote.hs
index c2d11b1..8fd555a 100644
--- a/commonmark-extensions/src/Commonmark/Extensions/Footnote.hs
+++ b/commonmark-extensions/src/Commonmark/Extensions/Footnote.hs
@@ -66,25 +66,31 @@ footnoteBlockSpec = BlockSpec
updateState $ \s -> s{ counters =
M.insert "footnote" (toDyn (num + 1))
(counters s) }
+ isBlankLine <- option False $ try (skipWhile (hasType Spaces) >> True <$ lookAhead lineEnd)
addNodeToStack $
Node (defBlockData footnoteBlockSpec){
- blockData = toDyn (num, lab')
+ blockData = toDyn (num, lab', isBlankLine)
, blockStartPos = [pos] } []
return BlockStartMatch
, blockCanContain = const True
, blockContainsLines = False
, blockParagraph = False
- , blockContinue = \n -> try $ do
- () <$ (gobbleSpaces 4)
- <|> (skipWhile (hasType Spaces) >> () <$ lookAhead lineEnd)
- pos <- getPosition
- return $! (pos, n)
+ , blockContinue = \(Node root children) -> try $ do
+ let (num, lab', needsIndented) = fromDyn (blockData root) (1 :: Int, mempty :: Text, False)
+ isBlankLine <- option False $ try (skipWhile (hasType Spaces) >> True <$ lookAhead lineEnd)
+ if needsIndented && not isBlankLine then
+ gobbleSpaces 4
+ else
+ gobbleUpToSpaces 4
+ pos <- getPosition
+ let footnoteData = toDyn (num, lab', isBlankLine)
+ return $! (pos, Node root{ blockData = footnoteData} children)
, blockConstructor = \node ->
mconcat <$> mapM (\n ->
blockConstructor (blockSpec (rootLabel n)) n)
(subForest (reverseSubforests node))
, blockFinalize = \(Node root children) parent -> do
- let (num, lab') = fromDyn (blockData root) (1, mempty)
+ let (num, lab', _indented) = fromDyn (blockData root) (1, mempty, False)
st <- getState
let mkNoteContents refmap =
runParserT
diff --git a/commonmark-extensions/test/footnotes.md b/commonmark-extensions/test/footnotes.md
index 148e5f9..b98673a 100644
--- a/commonmark-extensions/test/footnotes.md
+++ b/commonmark-extensions/test/footnotes.md
@@ -196,3 +196,59 @@ second
[^third
fourth]
````````````````````````````````
+
+Only the first line of a footnote's following paragraph needs indented.
+
+```````````````````````````````` example
+[^foo]:bar
+baz
+
+ quux
+arst
+ qwfp
+
+[^foo]
+.
+
+
+````````````````````````````````
+
+Lazy continuations require the first line to have text in it,
+and to lazily continue a paragraph after the first, it will need to
+start with an indented line also.
+
+```````````````````````````````` example
+[^foo]:
+baz
+
+ quux
+
+[^foo]
+.
+baz
+quux
+
+
+
+````````````````````````````````