Skip to content

Commit

Permalink
[0.2.0] Fix: inline code rule shouldn't consume empty blocks (#26)
Browse files Browse the repository at this point in the history
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```
  • Loading branch information
lytefast authored Dec 8, 2020
1 parent 4b739d2 commit 652f427
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,19 @@ class MainActivity : AppCompatActivity() {
setContentView(R.layout.activity_main)

parser = Parser<RenderContext, Node<RenderContext>, ParseState>()
.addRules(UserMentionRule(), CustomMarkdownRules.createBlockQuoteRule())
.addRules(
// Allow callers to escape markdown commands such as code block ticks
SimpleMarkdownRules.createEscapeRule(),
UserMentionRule(),
CustomMarkdownRules.createBlockQuoteRule())
.addRules(CustomMarkdownRules.createMarkdownRules(
this@MainActivity,
listOf(R.style.Demo_Header_1, R.style.Demo_Header_2, R.style.Demo_Header_3),
listOf(R.style.Demo_Header_1_Add, R.style.Demo_Header_1_Remove, R.style.Demo_Header_1_Fix)))
.addRules(
CustomMarkdownRules.createCodeRule(this@MainActivity),
CustomMarkdownRules.createCodeInlineRule(this@MainActivity))
.addRules(SimpleMarkdownRules.createSimpleMarkdownRules())
.addRules(SimpleMarkdownRules.createSimpleMarkdownRules(includeEscapeRule = false))

resultText = findViewById(R.id.result_text)
input = findViewById(R.id.input)
Expand Down
2 changes: 1 addition & 1 deletion simpleast-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ android {
minSdkVersion 21
targetSdkVersion 30
versionCode 28
versionName "2.1.3"
versionName "2.2.0"

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ object CodeRules {
Pattern.compile("""^```(?:([\w+\-.]+?)?(\s*\n))?([^\n].*?)\n*```""", Pattern.DOTALL)

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

private const val CODE_BLOCK_LANGUAGE_GROUP = 1
private const val CODE_BLOCK_WS_PREFIX = 2
Expand Down Expand Up @@ -272,6 +272,9 @@ object CodeRules {
override fun parse(matcher: Matcher, parser: Parser<R, in Node<R>, S>, state: S)
: ParseSpec<R, S> {
val codeBody = matcher.group(1).orEmpty()
if (codeBody.isEmpty()) {
return ParseSpec.createTerminal(TextNode(matcher.group()), state)
}

val content = CodeNode.Content.Raw(codeBody)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ object SimpleMarkdownRules {
fun <R, S> createEscapeRule(): Rule<R, Node<R>, S> {
return object : Rule<R, Node<R>, S>(PATTERN_ESCAPE) {
override fun parse(matcher: Matcher, parser: Parser<R, in Node<R>, S>, state: S): ParseSpec<R, S> {
return ParseSpec.createTerminal(TextNode(matcher.group(1)), state)
return ParseSpec.createTerminal(TextNode(matcher.group(1)!!), state)
}
}
}
Expand All @@ -80,7 +80,7 @@ object SimpleMarkdownRules {
val startIndex: Int
val endIndex: Int
val asteriskMatch = matcher.group(2)
if (asteriskMatch != null && asteriskMatch.length > 0) {
if (asteriskMatch != null && asteriskMatch.isNotEmpty()) {
startIndex = matcher.start(2)
endIndex = matcher.end(2)
} else {
Expand All @@ -98,9 +98,11 @@ object SimpleMarkdownRules {
}

@JvmOverloads @JvmStatic
fun <R, S> createSimpleMarkdownRules(includeTextRule: Boolean = true): MutableList<Rule<R, Node<R>, S>> {
fun <R, S> createSimpleMarkdownRules(includeTextRule: Boolean = true, includeEscapeRule:Boolean = true): MutableList<Rule<R, Node<R>, S>> {
val rules = ArrayList<Rule<R, Node<R>, S>>()
rules.add(createEscapeRule())
if (includeEscapeRule) {
rules.add(createEscapeRule())
}
rules.add(createNewlineRule())
rules.add(createBoldRule())
rules.add(createUnderlineRule())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package com.discord.simpleast.code

import android.graphics.Color
import android.text.style.BackgroundColorSpan
import com.discord.simpleast.assertNodeContents
import com.discord.simpleast.core.node.Node
import com.discord.simpleast.core.node.StyleNode
import com.discord.simpleast.core.node.TextNode
import com.discord.simpleast.core.parser.Parser
import com.discord.simpleast.core.simple.SimpleMarkdownRules
import com.discord.simpleast.core.utils.TreeMatcher
Expand All @@ -21,15 +24,51 @@ class CodeRulesTest {
fun setup() {
parser = Parser()
val codeStyleProviders = CodeStyleProviders<TestRenderContext>()
parser.addRule(CodeRules.createCodeRule(
codeStyleProviders.defaultStyleProvider,
CodeRules.createCodeLanguageMap(codeStyleProviders))
)
parser.addRules(SimpleMarkdownRules.createSimpleMarkdownRules())
parser
// Duplicated in `getBasicRules` but required to occur before block + quotes
.addRule(SimpleMarkdownRules.createEscapeRule())
.addRule(CodeRules.createCodeRule(
codeStyleProviders.defaultStyleProvider,
CodeRules.createCodeLanguageMap(codeStyleProviders))
)
.addRule(CodeRules.createInlineCodeRule(
{ listOf(BackgroundColorSpan(Color.WHITE)) },
{ listOf(BackgroundColorSpan(Color.DKGRAY)) })
)
.addRules(SimpleMarkdownRules.createSimpleMarkdownRules(includeEscapeRule = false))
treeMatcher = TreeMatcher()
treeMatcher.registerDefaultMatchers()
}

@Test
fun inlined() {
val ast = parser.parse("""
`inlined`
`inline extra``
""".trimIndent(), TestState())

ast.assertNodeContents<CodeNode<*>>("inlined", "inline extra")
ast.assertNodeContents<TextNode<*>>("inlined", "\n", "inline extra", "`")
}

@Test
fun inlineNoContent() {
val ast = parser.parse("""
``
""".trimIndent(), TestState())

ast.assertNodeContents<TextNode<*>>("``")
}

@Test
fun inlineEscapedBlock() {
val ast = parser.parse("""
\```test```
""".trimIndent(), TestState())

ast.assertNodeContents<TextNode<*>>("`", "``", "test", "``", "`")
}

@Test
fun noLanguageOneLined() {
val ast = parser.parse("""
Expand Down

0 comments on commit 652f427

Please sign in to comment.