Skip to content

Commit 652f427

Browse files
authored
[0.2.0] Fix: inline code rule shouldn't consume empty blocks (#26)
Empty inline blocks should behave as if they were just text. Additionally add updates to sample app + test to handle escaping ticks Bump the version to 2.2.0 for the change to `createSimpleMarkdownRules` API Context: This enables text such as \```sample text``` to be rendered as: ```sample text```
1 parent 4b739d2 commit 652f427

File tree

5 files changed

+61
-13
lines changed

5 files changed

+61
-13
lines changed

app/src/main/java/com/discord/simpleast/sample/MainActivity.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,19 @@ class MainActivity : AppCompatActivity() {
3535
setContentView(R.layout.activity_main)
3636

3737
parser = Parser<RenderContext, Node<RenderContext>, ParseState>()
38-
.addRules(UserMentionRule(), CustomMarkdownRules.createBlockQuoteRule())
38+
.addRules(
39+
// Allow callers to escape markdown commands such as code block ticks
40+
SimpleMarkdownRules.createEscapeRule(),
41+
UserMentionRule(),
42+
CustomMarkdownRules.createBlockQuoteRule())
3943
.addRules(CustomMarkdownRules.createMarkdownRules(
4044
this@MainActivity,
4145
listOf(R.style.Demo_Header_1, R.style.Demo_Header_2, R.style.Demo_Header_3),
4246
listOf(R.style.Demo_Header_1_Add, R.style.Demo_Header_1_Remove, R.style.Demo_Header_1_Fix)))
4347
.addRules(
4448
CustomMarkdownRules.createCodeRule(this@MainActivity),
4549
CustomMarkdownRules.createCodeInlineRule(this@MainActivity))
46-
.addRules(SimpleMarkdownRules.createSimpleMarkdownRules())
50+
.addRules(SimpleMarkdownRules.createSimpleMarkdownRules(includeEscapeRule = false))
4751

4852
resultText = findViewById(R.id.result_text)
4953
input = findViewById(R.id.input)

simpleast-core/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ android {
88
minSdkVersion 21
99
targetSdkVersion 30
1010
versionCode 28
11-
versionName "2.1.3"
11+
versionName "2.2.0"
1212

1313
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
1414

simpleast-core/src/main/java/com/discord/simpleast/code/CodeRules.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ object CodeRules {
4141
Pattern.compile("""^```(?:([\w+\-.]+?)?(\s*\n))?([^\n].*?)\n*```""", Pattern.DOTALL)
4242

4343
val PATTERN_CODE_INLINE: Pattern =
44-
Pattern.compile("""^`(?:\s*)([^\n].*?)\n*`""", Pattern.DOTALL)
44+
Pattern.compile("""^`([^`]*?)`""", Pattern.DOTALL)
4545

4646
private const val CODE_BLOCK_LANGUAGE_GROUP = 1
4747
private const val CODE_BLOCK_WS_PREFIX = 2
@@ -272,6 +272,9 @@ object CodeRules {
272272
override fun parse(matcher: Matcher, parser: Parser<R, in Node<R>, S>, state: S)
273273
: ParseSpec<R, S> {
274274
val codeBody = matcher.group(1).orEmpty()
275+
if (codeBody.isEmpty()) {
276+
return ParseSpec.createTerminal(TextNode(matcher.group()), state)
277+
}
275278

276279
val content = CodeNode.Content.Raw(codeBody)
277280

simpleast-core/src/main/java/com/discord/simpleast/core/simple/SimpleMarkdownRules.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ object SimpleMarkdownRules {
6969
fun <R, S> createEscapeRule(): Rule<R, Node<R>, S> {
7070
return object : Rule<R, Node<R>, S>(PATTERN_ESCAPE) {
7171
override fun parse(matcher: Matcher, parser: Parser<R, in Node<R>, S>, state: S): ParseSpec<R, S> {
72-
return ParseSpec.createTerminal(TextNode(matcher.group(1)), state)
72+
return ParseSpec.createTerminal(TextNode(matcher.group(1)!!), state)
7373
}
7474
}
7575
}
@@ -80,7 +80,7 @@ object SimpleMarkdownRules {
8080
val startIndex: Int
8181
val endIndex: Int
8282
val asteriskMatch = matcher.group(2)
83-
if (asteriskMatch != null && asteriskMatch.length > 0) {
83+
if (asteriskMatch != null && asteriskMatch.isNotEmpty()) {
8484
startIndex = matcher.start(2)
8585
endIndex = matcher.end(2)
8686
} else {
@@ -98,9 +98,11 @@ object SimpleMarkdownRules {
9898
}
9999

100100
@JvmOverloads @JvmStatic
101-
fun <R, S> createSimpleMarkdownRules(includeTextRule: Boolean = true): MutableList<Rule<R, Node<R>, S>> {
101+
fun <R, S> createSimpleMarkdownRules(includeTextRule: Boolean = true, includeEscapeRule:Boolean = true): MutableList<Rule<R, Node<R>, S>> {
102102
val rules = ArrayList<Rule<R, Node<R>, S>>()
103-
rules.add(createEscapeRule())
103+
if (includeEscapeRule) {
104+
rules.add(createEscapeRule())
105+
}
104106
rules.add(createNewlineRule())
105107
rules.add(createBoldRule())
106108
rules.add(createUnderlineRule())

simpleast-core/src/test/java/com/discord/simpleast/code/CodeRulesTest.kt

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package com.discord.simpleast.code
22

3+
import android.graphics.Color
4+
import android.text.style.BackgroundColorSpan
35
import com.discord.simpleast.assertNodeContents
46
import com.discord.simpleast.core.node.Node
57
import com.discord.simpleast.core.node.StyleNode
8+
import com.discord.simpleast.core.node.TextNode
69
import com.discord.simpleast.core.parser.Parser
710
import com.discord.simpleast.core.simple.SimpleMarkdownRules
811
import com.discord.simpleast.core.utils.TreeMatcher
@@ -21,15 +24,51 @@ class CodeRulesTest {
2124
fun setup() {
2225
parser = Parser()
2326
val codeStyleProviders = CodeStyleProviders<TestRenderContext>()
24-
parser.addRule(CodeRules.createCodeRule(
25-
codeStyleProviders.defaultStyleProvider,
26-
CodeRules.createCodeLanguageMap(codeStyleProviders))
27-
)
28-
parser.addRules(SimpleMarkdownRules.createSimpleMarkdownRules())
27+
parser
28+
// Duplicated in `getBasicRules` but required to occur before block + quotes
29+
.addRule(SimpleMarkdownRules.createEscapeRule())
30+
.addRule(CodeRules.createCodeRule(
31+
codeStyleProviders.defaultStyleProvider,
32+
CodeRules.createCodeLanguageMap(codeStyleProviders))
33+
)
34+
.addRule(CodeRules.createInlineCodeRule(
35+
{ listOf(BackgroundColorSpan(Color.WHITE)) },
36+
{ listOf(BackgroundColorSpan(Color.DKGRAY)) })
37+
)
38+
.addRules(SimpleMarkdownRules.createSimpleMarkdownRules(includeEscapeRule = false))
2939
treeMatcher = TreeMatcher()
3040
treeMatcher.registerDefaultMatchers()
3141
}
3242

43+
@Test
44+
fun inlined() {
45+
val ast = parser.parse("""
46+
`inlined`
47+
`inline extra``
48+
""".trimIndent(), TestState())
49+
50+
ast.assertNodeContents<CodeNode<*>>("inlined", "inline extra")
51+
ast.assertNodeContents<TextNode<*>>("inlined", "\n", "inline extra", "`")
52+
}
53+
54+
@Test
55+
fun inlineNoContent() {
56+
val ast = parser.parse("""
57+
``
58+
""".trimIndent(), TestState())
59+
60+
ast.assertNodeContents<TextNode<*>>("``")
61+
}
62+
63+
@Test
64+
fun inlineEscapedBlock() {
65+
val ast = parser.parse("""
66+
\```test```
67+
""".trimIndent(), TestState())
68+
69+
ast.assertNodeContents<TextNode<*>>("`", "``", "test", "``", "`")
70+
}
71+
3372
@Test
3473
fun noLanguageOneLined() {
3574
val ast = parser.parse("""

0 commit comments

Comments
 (0)