From 1a90f1e609ab0e0e078be7b67397969087ccbbe9 Mon Sep 17 00:00:00 2001 From: Dimitry Ivanov Date: Fri, 26 Jun 2020 17:51:59 +0300 Subject: [PATCH] Sample app process outgoing repositories links --- app-sample/build.gradle | 2 +- app-sample/src/main/AndroidManifest.xml | 6 +++- .../main/java/io/noties/markwon/app/App.kt | 31 +++++++++++++++++++ .../markwon/app/readme/ReadMeActivity.kt | 9 ++++++ .../markwon/app/readme/ReadMeLinkResolver.kt | 18 +++++++++++ .../noties/markwon/app/utils/ReadMeUtils.kt | 20 ++++++++++-- build.gradle | 2 ++ 7 files changed, 83 insertions(+), 5 deletions(-) create mode 100644 app-sample/src/main/java/io/noties/markwon/app/readme/ReadMeLinkResolver.kt diff --git a/app-sample/build.gradle b/app-sample/build.gradle index 0ea4fa44..dc3ac690 100644 --- a/app-sample/build.gradle +++ b/app-sample/build.gradle @@ -85,6 +85,6 @@ dependencies { implementation it['adapt'] implementation it['debug'] implementation it['android-svg'] - implementation it['android-gif'] + implementation it['android-gif-impl'] } } diff --git a/app-sample/src/main/AndroidManifest.xml b/app-sample/src/main/AndroidManifest.xml index 16c2d250..ac691724 100644 --- a/app-sample/src/main/AndroidManifest.xml +++ b/app-sample/src/main/AndroidManifest.xml @@ -35,9 +35,13 @@ + + + + + diff --git a/app-sample/src/main/java/io/noties/markwon/app/App.kt b/app-sample/src/main/java/io/noties/markwon/app/App.kt index 41351f0c..55c08b9a 100644 --- a/app-sample/src/main/java/io/noties/markwon/app/App.kt +++ b/app-sample/src/main/java/io/noties/markwon/app/App.kt @@ -1,8 +1,14 @@ package io.noties.markwon.app import android.app.Application +import android.content.ComponentName +import android.content.Intent +import android.content.pm.ShortcutInfo +import android.content.pm.ShortcutManager +import android.os.Build import io.noties.debug.AndroidLogDebugOutput import io.noties.debug.Debug +import io.noties.markwon.app.readme.ReadMeActivity import io.noties.markwon.app.sample.SampleManager import java.util.concurrent.ExecutorService import java.util.concurrent.Executors @@ -17,6 +23,31 @@ class App : Application() { executorService = Executors.newCachedThreadPool() sampleManager = SampleManager(this, executorService) + + ensureReadmeShortcut() + } + + private fun ensureReadmeShortcut() { + if (Build.VERSION.SDK_INT < 25) { + return + } + + val manager = getSystemService(ShortcutManager::class.java) ?: return + + @Suppress("ReplaceNegatedIsEmptyWithIsNotEmpty") + if (!manager.dynamicShortcuts.isEmpty()) { + return + } + + val intent = Intent(Intent.ACTION_VIEW).apply { + component = ComponentName(this@App, ReadMeActivity::class.java) + } + + val shortcut = ShortcutInfo.Builder(this, "readme") + .setShortLabel("README") + .setIntent(intent) + .build() + manager.addDynamicShortcuts(mutableListOf(shortcut)) } companion object { diff --git a/app-sample/src/main/java/io/noties/markwon/app/readme/ReadMeActivity.kt b/app-sample/src/main/java/io/noties/markwon/app/readme/ReadMeActivity.kt index 870c2b29..3a5231f8 100644 --- a/app-sample/src/main/java/io/noties/markwon/app/readme/ReadMeActivity.kt +++ b/app-sample/src/main/java/io/noties/markwon/app/readme/ReadMeActivity.kt @@ -12,12 +12,14 @@ import androidx.recyclerview.widget.RecyclerView import io.noties.debug.Debug import io.noties.markwon.AbstractMarkwonPlugin import io.noties.markwon.Markwon +import io.noties.markwon.MarkwonConfiguration import io.noties.markwon.MarkwonVisitor import io.noties.markwon.app.R import io.noties.markwon.app.utils.ReadMeUtils import io.noties.markwon.app.utils.hidden import io.noties.markwon.app.utils.loadReadMe import io.noties.markwon.app.utils.textOrHide +import io.noties.markwon.ext.strikethrough.StrikethroughPlugin import io.noties.markwon.ext.tasklist.TaskListPlugin import io.noties.markwon.html.HtmlPlugin import io.noties.markwon.image.ImagesPlugin @@ -27,6 +29,7 @@ import io.noties.markwon.recycler.table.TableEntry import io.noties.markwon.recycler.table.TableEntryPlugin import io.noties.markwon.syntax.Prism4jThemeDefault import io.noties.markwon.syntax.SyntaxHighlightPlugin +import io.noties.markwon.utils.DumpNodes import io.noties.prism4j.Prism4j import io.noties.prism4j.annotations.PrismBundle import okhttp3.Call @@ -65,6 +68,7 @@ class ReadMeActivity : Activity() { .usePlugin(TableEntryPlugin.create(this)) .usePlugin(SyntaxHighlightPlugin.create(Prism4j(GrammarLocatorDef()), Prism4jThemeDefault.create(0))) .usePlugin(TaskListPlugin.create(this)) + .usePlugin(StrikethroughPlugin.create()) .usePlugin(ReadMeImageDestinationPlugin(intent.data)) .usePlugin(object : AbstractMarkwonPlugin() { override fun configureVisitor(builder: MarkwonVisitor.Builder) { @@ -79,6 +83,10 @@ class ReadMeActivity : Activity() { visitor.builder().append(code) } } + + override fun configureConfiguration(builder: MarkwonConfiguration.Builder) { + builder.linkResolver(ReadMeLinkResolver()) + } }) .build() @@ -120,6 +128,7 @@ class ReadMeActivity : Activity() { is Result.Success -> { val markwon = markwon val node = markwon.parse(result.markdown) + Debug.i(DumpNodes.dump(node)) if (window != null) { recyclerView.post { adapter.setParsedMarkdown(markwon, node) diff --git a/app-sample/src/main/java/io/noties/markwon/app/readme/ReadMeLinkResolver.kt b/app-sample/src/main/java/io/noties/markwon/app/readme/ReadMeLinkResolver.kt new file mode 100644 index 00000000..f83f67ad --- /dev/null +++ b/app-sample/src/main/java/io/noties/markwon/app/readme/ReadMeLinkResolver.kt @@ -0,0 +1,18 @@ +package io.noties.markwon.app.readme + +import android.view.View +import io.noties.markwon.LinkResolverDef +import io.noties.markwon.app.utils.ReadMeUtils + +class ReadMeLinkResolver : LinkResolverDef() { + + override fun resolve(view: View, link: String) { + val matcher = ReadMeUtils.RE_REPOSITORY.matcher(link) + val url = if (matcher.matches()) { + ReadMeUtils.buildRepositoryReadMeUrl(matcher.group(1), matcher.group(2)) + } else { + link + } + super.resolve(view, url) + } +} \ No newline at end of file diff --git a/app-sample/src/main/java/io/noties/markwon/app/utils/ReadMeUtils.kt b/app-sample/src/main/java/io/noties/markwon/app/utils/ReadMeUtils.kt index a6fbfebf..f603bd17 100644 --- a/app-sample/src/main/java/io/noties/markwon/app/utils/ReadMeUtils.kt +++ b/app-sample/src/main/java/io/noties/markwon/app/utils/ReadMeUtils.kt @@ -4,8 +4,13 @@ import android.net.Uri import java.util.regex.Pattern object ReadMeUtils { + // username, repo, branch, lastPathSegment - private val RE = Pattern.compile("^https:\\/\\/github\\.com\\/(\\w+?)\\/(\\w+?)\\/(?:blob|raw)\\/(\\w+?)\\/(.+)") + @Suppress("RegExpRedundantEscape") + private val RE_FILE = Pattern.compile("^https:\\/\\/github\\.com\\/([\\w-.]+?)\\/([\\w-.]+?)\\/(?:blob|raw)\\/([\\w-.]+?)\\/(.+)\$") + + @Suppress("RegExpRedundantEscape") + val RE_REPOSITORY: Pattern = Pattern.compile("^https:\\/\\/github.com\\/([\\w-.]+?)\\/([\\w-.]+?)\\/*\$") data class GithubInfo( val username: String, @@ -20,7 +25,7 @@ object ReadMeUtils { return null } - val matcher = RE.matcher(data.toString()) + val matcher = RE_FILE.matcher(data.toString()) if (!matcher.matches()) { return null } @@ -38,7 +43,16 @@ object ReadMeUtils { return if (info == null) { data.toString() } else { - "https://github.com/${info.username}/${info.repository}/raw/${info.branch}/${info.fileName}" + buildRawGithubUrl(info) } } + + @Suppress("MemberVisibilityCanBePrivate") + fun buildRawGithubUrl(info: GithubInfo): String { + return "https://github.com/${info.username}/${info.repository}/raw/${info.branch}/${info.fileName}" + } + + fun buildRepositoryReadMeUrl(username: String, repository: String): String { + return buildRawGithubUrl(GithubInfo(username, repository, "master", "README.md")) + } } \ No newline at end of file diff --git a/build.gradle b/build.gradle index 78636b1d..7394e5d0 100644 --- a/build.gradle +++ b/build.gradle @@ -76,7 +76,9 @@ ext { 'commonmark-strikethrough': "com.atlassian.commonmark:commonmark-ext-gfm-strikethrough:$commonMarkVersion", 'commonmark-table' : "com.atlassian.commonmark:commonmark-ext-gfm-tables:$commonMarkVersion", 'android-svg' : 'com.caverock:androidsvg:1.4', + // we need 2 gif artifacts at long as we have a difference in version used for API compatibility 'android-gif' : 'pl.droidsonroids.gif:android-gif-drawable:1.2.15', + 'android-gif-impl' : 'pl.droidsonroids.gif:android-gif-drawable:1.2.20', 'jlatexmath-android' : 'ru.noties:jlatexmath-android:0.2.0', 'okhttp' : 'com.squareup.okhttp3:okhttp:3.9.0', 'prism4j' : 'io.noties:prism4j:2.0.0',