Sample app process outgoing repositories links
This commit is contained in:
		
							parent
							
								
									186390805a
								
							
						
					
					
						commit
						1a90f1e609
					
				| @ -85,6 +85,6 @@ dependencies { | ||||
|         implementation it['adapt'] | ||||
|         implementation it['debug'] | ||||
|         implementation it['android-svg'] | ||||
|         implementation it['android-gif'] | ||||
|         implementation it['android-gif-impl'] | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -35,9 +35,13 @@ | ||||
| 
 | ||||
|                 <data | ||||
|                     android:host="github.com" | ||||
|                     android:pathPattern=".*\\.md" | ||||
|                     android:scheme="https" /> | ||||
| 
 | ||||
|                 <data android:pathPattern=".*\\.md" /> | ||||
|                 <data android:pathPattern=".*\\..*\\.md" /> | ||||
|                 <data android:pathPattern=".*\\..*\\..*\\.md"/> | ||||
|                 <data android:pathPattern=".*\\..*\\..*\\..*\\.md"/> | ||||
| 
 | ||||
|             </intent-filter> | ||||
|         </activity> | ||||
| 
 | ||||
|  | ||||
| @ -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 { | ||||
|  | ||||
| @ -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) | ||||
|  | ||||
| @ -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) | ||||
|     } | ||||
| } | ||||
| @ -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")) | ||||
|     } | ||||
| } | ||||
| @ -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', | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Dimitry Ivanov
						Dimitry Ivanov