Skip to content

Commit 1077177

Browse files
committed
fix(parser): trim initial spaces from fenced code block
1 parent 26df44f commit 1077177

File tree

5 files changed

+46
-2
lines changed

5 files changed

+46
-2
lines changed

quarkdown-core/src/main/kotlin/com/quarkdown/core/lexer/patterns/BaseMarkdownBlockTokenRegexPatterns.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ open class BaseMarkdownBlockTokenRegexPatterns {
109109
wrap = ::FencesCodeToken,
110110
regex =
111111
RegexBuilder(
112-
"^ {0,3}fencesstart[ \\t]*lang?[ \\t]*caption?[ \\t]*customid?$" +
112+
"^( {0,3})fencesstart[ \\t]*lang?[ \\t]*caption?[ \\t]*customid?$" +
113113
"(?s)(.+?)" +
114114
"fencesend[ \\t]*$",
115115
).withReference("fencesstart", "(?<fenceschar>[`~]){3,}")

quarkdown-core/src/main/kotlin/com/quarkdown/core/parser/BlockTokenParser.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,15 +99,26 @@ class BlockTokenParser(
9999

100100
override fun visit(token: FencesCodeToken): Node {
101101
val groups = token.data.groups.iterator(consumeAmount = 2)
102+
val initialSpaces = groups.next().length // Amount of spaces before the fence.
102103
val language = token.data.namedGroups["fencescodelang"]
103104
val caption = token.data.namedGroups["fencescodecaption"]?.trim()
104105
val referenceId = token.data.namedGroups["fencescodecustomid"]?.trim()
105106

107+
// Removes, at most, the initial spaces from each line (GFM #101).
108+
val content =
109+
groups
110+
.next()
111+
.lineSequence()
112+
.map { it.replace("^ {0,$initialSpaces}".toRegex(), "") }
113+
.joinToString(separator = "\n")
114+
.removePrefix("\n")
115+
.removeSuffix("\n")
116+
106117
return Code(
107118
language = language?.takeIf { it.isNotBlank() }?.trim(),
108119
caption = caption?.trimDelimiters(),
109120
referenceId = referenceId,
110-
content = groups.next().trim(),
121+
content = content,
111122
)
112123
}
113124

quarkdown-core/src/test/kotlin/com/quarkdown/core/BlockParserTest.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,10 @@ class BlockParserTest {
204204
assertEquals("Code line 1\n Code line 2", content)
205205
assertNull(language)
206206
}
207+
with(nodes.next()) {
208+
assertEquals("Code line 1\nCode line 2\n Code line 3\n Code line 4", content)
209+
assertNull(language)
210+
}
207211
with(nodes.next()) {
208212
assertEquals("Code", content)
209213
assertEquals("text", language)

quarkdown-core/src/test/resources/parsing/fencescode.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ Code line 1
1616
Code line 2
1717
```
1818

19+
```
20+
Code line 1
21+
Code line 2
22+
Code line 3
23+
Code line 4
24+
```
25+
1926
```text
2027
Code
2128
```

quarkdown-test/src/test/kotlin/com/quarkdown/test/CodeTest.kt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,28 @@ class CodeTest {
8181
}
8282
}
8383

84+
// #259
85+
@Test
86+
fun `indented block`() {
87+
execute(
88+
"""
89+
- indented context .br
90+
```
91+
aaaa
92+
bbbb
93+
cccc
94+
```
95+
""".trimIndent(),
96+
) {
97+
assertEquals(
98+
"<ul><li>indented context <br />" +
99+
"<pre><code>aaaa\nbbbb\ncccc</code></pre>" +
100+
"</li></ul>",
101+
it,
102+
)
103+
}
104+
}
105+
84106
// #32
85107
@Test
86108
fun `long block`() {

0 commit comments

Comments
 (0)