From 08a8cece611ac5f4bf17ac9471e5aacc32386b03 Mon Sep 17 00:00:00 2001 From: Dimitry Ivanov Date: Thu, 12 Nov 2020 01:54:33 +0300 Subject: [PATCH] sample, add exclude from parsing --- app-sample/build.gradle | 2 +- app-sample/samples.json | 25 +++++++ .../app/samples/ExcludeFromParsingSample.kt | 75 +++++++++++++++++++ .../parser/CustomHeadingParserSample.kt | 47 ++++++++++++ 4 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 app-sample/src/main/java/io/noties/markwon/app/samples/ExcludeFromParsingSample.kt create mode 100644 app-sample/src/main/java/io/noties/markwon/app/samples/parser/CustomHeadingParserSample.kt diff --git a/app-sample/build.gradle b/app-sample/build.gradle index 9e827415..7f511069 100644 --- a/app-sample/build.gradle +++ b/app-sample/build.gradle @@ -167,4 +167,4 @@ dependencies { testImplementation it['robolectric'] testImplementation it['mockito'] } -} +} \ No newline at end of file diff --git a/app-sample/samples.json b/app-sample/samples.json index 4ba4ff18..d7cd5f02 100644 --- a/app-sample/samples.json +++ b/app-sample/samples.json @@ -1,4 +1,29 @@ [ + { + "javaClassName": "io.noties.markwon.app.samples.ExcludeFromParsingSample", + "id": "20201111221945", + "title": "Exclude part of input from parsing", + "description": "Exclude part of input from parsing by splitting input with delimiters", + "artifacts": [ + "CORE" + ], + "tags": [ + "parsing" + ] + }, + { + "javaClassName": "io.noties.markwon.app.samples.parser.CustomHeadingParserSample", + "id": "20201111221207", + "title": "Custom heading parser", + "description": "Custom heading block parser. Actual parser is not implemented", + "artifacts": [ + "CORE" + ], + "tags": [ + "heading", + "parsing" + ] + }, { "javaClassName": "io.noties.markwon.app.samples.editor.WYSIWYGEditorSample", "id": "20200908133515", diff --git a/app-sample/src/main/java/io/noties/markwon/app/samples/ExcludeFromParsingSample.kt b/app-sample/src/main/java/io/noties/markwon/app/samples/ExcludeFromParsingSample.kt new file mode 100644 index 00000000..6bcaa25d --- /dev/null +++ b/app-sample/src/main/java/io/noties/markwon/app/samples/ExcludeFromParsingSample.kt @@ -0,0 +1,75 @@ +package io.noties.markwon.app.samples + +import android.text.SpannableStringBuilder +import io.noties.debug.Debug +import io.noties.markwon.Markwon +import io.noties.markwon.app.sample.Tags +import io.noties.markwon.app.sample.ui.MarkwonTextViewSample +import io.noties.markwon.sample.annotations.MarkwonArtifact +import io.noties.markwon.sample.annotations.MarkwonSampleInfo +import java.util.regex.Pattern + +@MarkwonSampleInfo( + id = "20201111221945", + title = "Exclude part of input from parsing", + description = "Exclude part of input from parsing by splitting input with delimiters", + artifacts = [MarkwonArtifact.CORE], + tags = [Tags.parsing] +) +class ExcludeFromParsingSample : MarkwonTextViewSample() { + override fun render() { + + // cannot have continuous markdown between parts (so a node started in one part and ended in other) + // with this approach + // also exclude will start a new block and won't seamlessly continue any existing markdown one (so + // if started inside a blockquote, then blockquote would be closed) + + val md = """ + # Hello + + we are **going** to exclude some parts of this input _from_ parsing + + $EXCLUDE_START + what is **good** is that we + > do not need to care about blocks or inlines + * and + * everything + * else + $EXCLUDE_END + + **then** markdown _again_ + + and empty exclude at end: $EXCLUDE_START$EXCLUDE_END + """.trimIndent() + + val markwon = Markwon.create(context) + val matcher = Pattern.compile(RE, Pattern.MULTILINE).matcher(md) + + val builder by lazy(LazyThreadSafetyMode.NONE) { + SpannableStringBuilder() + } + + var end: Int = 0 + + while (matcher.find()) { + val start = matcher.start() + Debug.i(end, start, md.substring(end, start)) + builder.append(markwon.toMarkdown(md.substring(end, start))) + builder.append(matcher.group(1)) + end = matcher.end() + } + + if (end != md.length) { + builder.append(markwon.toMarkdown(md.substring(end))) + } + + markwon.setParsedMarkdown(textView, builder) + } + + private companion object { + const val EXCLUDE_START = "##IGNORE##" + const val EXCLUDE_END = "--IGNORE--" + + const val RE = "${EXCLUDE_START}([\\s\\S]*?)${EXCLUDE_END}" + } +} \ No newline at end of file diff --git a/app-sample/src/main/java/io/noties/markwon/app/samples/parser/CustomHeadingParserSample.kt b/app-sample/src/main/java/io/noties/markwon/app/samples/parser/CustomHeadingParserSample.kt new file mode 100644 index 00000000..214bcae2 --- /dev/null +++ b/app-sample/src/main/java/io/noties/markwon/app/samples/parser/CustomHeadingParserSample.kt @@ -0,0 +1,47 @@ +package io.noties.markwon.app.samples.parser + +import io.noties.markwon.AbstractMarkwonPlugin +import io.noties.markwon.Markwon +import io.noties.markwon.app.sample.Tags +import io.noties.markwon.app.sample.ui.MarkwonTextViewSample +import io.noties.markwon.core.CorePlugin +import io.noties.markwon.sample.annotations.MarkwonArtifact +import io.noties.markwon.sample.annotations.MarkwonSampleInfo +import org.commonmark.node.Heading +import org.commonmark.parser.Parser +import org.commonmark.parser.block.BlockParserFactory +import org.commonmark.parser.block.BlockStart +import org.commonmark.parser.block.MatchedBlockParser +import org.commonmark.parser.block.ParserState + +@MarkwonSampleInfo( + id = "20201111221207", + title = "Custom heading parser", + description = "Custom heading block parser. Actual parser is not implemented", + artifacts = [MarkwonArtifact.CORE], + tags = [Tags.parsing, Tags.heading] +) +class CustomHeadingParserSample : MarkwonTextViewSample() { + override fun render() { + val md = "#Head" + val markwon = Markwon.builder(context) + .usePlugin(object : AbstractMarkwonPlugin() { + override fun configureParser(builder: Parser.Builder) { + val enabled = CorePlugin.enabledBlockTypes() + .filter { it != Heading::class.java } + .toSet() + builder.enabledBlockTypes(enabled) + builder.customBlockParserFactory(MyHeadingBlockParserFactory) + } + }) + .build() + markwon.setMarkdown(textView, md) + } + + object MyHeadingBlockParserFactory : BlockParserFactory { + override fun tryStart(state: ParserState, matchedBlockParser: MatchedBlockParser): BlockStart { + // TODO("Not yet implemented") + return BlockStart.none() + } + } +} \ No newline at end of file