From 97f13926e02fa8687f24403b590191b04fc31b02 Mon Sep 17 00:00:00 2001 From: Dimitry Ivanov Date: Sat, 27 May 2017 14:12:21 +0300 Subject: [PATCH] Added ability to load from assets --- README.md | 34 +++- app/src/main/assets/art/markwon_logo.png | 1 + .../java/ru/noties/markwon/AppModule.java | 1 + .../ru/noties/markwon/MarkdownRenderer.java | 8 +- art/markwon_logo.png | Bin 0 -> 12303 bytes library-image-loader/build.gradle | 1 - .../markwon/il/AsyncDrawableLoader.java | 170 ++++++++++++++---- library/build.gradle | 2 - .../markwon/UrlProcessorAndroidAssets.java | 39 ++++ .../renderer/SpannableMarkdownVisitor.java | 7 - 10 files changed, 206 insertions(+), 57 deletions(-) create mode 120000 app/src/main/assets/art/markwon_logo.png create mode 100644 art/markwon_logo.png create mode 100644 library/src/main/java/ru/noties/markwon/UrlProcessorAndroidAssets.java diff --git a/README.md b/README.md index 25518070..dd397986 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +![logo](./art/markwon_logo.png) + # Markwon [![maven|markwon](https://img.shields.io/maven-central/v/ru.noties/markwon.svg?label=maven%7Cmarkwon)](http://search.maven.org/#search|ga|1|g%3A%22ru.noties%22%20AND%20a%3A%markwon%22) @@ -40,6 +42,9 @@ compile 'ru.noties:markwon-image-loader:1.0.0' // optional * other inline html is rendered via (`Html.fromHtml(...)`) +--- + + ### Emphasis *Lorem ipsum dolor sit amet* @@ -55,6 +60,9 @@ _Lorem ipsum dolor sit amet_ Lorem ipsum dolor sit amet +--- + + ### Strong emphasis **Lorem ipsum dolor sit amet** @@ -66,6 +74,9 @@ __Lorem ipsum dolor sit amet__ Lorem ipsum dolor sit amet +--- + + ### Strike-through ~~Lorem ipsum dolor sit amet~~ @@ -97,9 +108,7 @@ __Lorem ipsum dolor sit amet__ click me - -### Images -// todo, normal ones & svg & gif +--- ### Thematic break @@ -114,6 +123,9 @@ ___ >>> Lorem ipsum dolor sit amet +--- + + ### Ordered lists 1. Lorem ipsum dolor sit amet 2. Lorem ipsum dolor sit amet @@ -123,6 +135,9 @@ ___ 3. Lorem ipsum dolor sit amet +--- + + ### Non-ordered lists * Lorem ipsum dolor sit amet * Lorem ipsum dolor sit amet @@ -132,6 +147,9 @@ ___ * Lorem ipsum dolor sit amet +--- + + ### Inline code `Lorem` ipsum dolor sit amet Lorem `ipsum` dolor sit amet @@ -142,6 +160,9 @@ Lorem ipsum dolor sit `amet` `Lorem ipsum dolor sit amet` +--- + + ### Code block ``` Lorem ipsum dolor sit amet @@ -149,11 +170,16 @@ Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet ``` +--- + ### H.T.M.L. OKA424342Y +--- + + ### Tables Header #1 | Header #2 | Header #3 ---: | :---: | :--- @@ -173,4 +199,4 @@ long long long skjfs fgjsdfhj sf `dfk df` | sdsd,fklsdfklsdfklsdfkl sdfkl dsfjks [github]: https://github.com [commonmark-java]: https://github.com/atlassian/commonmark-java/blob/master/README.md -[library]: https://github.com/noties/Markwon/blob/master/README.md \ No newline at end of file +[library]: https://github.com/noties/Markwon/blob/master/library/README.md \ No newline at end of file diff --git a/app/src/main/assets/art/markwon_logo.png b/app/src/main/assets/art/markwon_logo.png new file mode 120000 index 00000000..16f26621 --- /dev/null +++ b/app/src/main/assets/art/markwon_logo.png @@ -0,0 +1 @@ +../../../../../art/markwon_logo.png \ No newline at end of file diff --git a/app/src/main/java/ru/noties/markwon/AppModule.java b/app/src/main/java/ru/noties/markwon/AppModule.java index 7d04a4db..09c5e230 100644 --- a/app/src/main/java/ru/noties/markwon/AppModule.java +++ b/app/src/main/java/ru/noties/markwon/AppModule.java @@ -42,6 +42,7 @@ class AppModule { return new OkHttpClient.Builder() .cache(new Cache(app.getCacheDir(), 1024L * 20)) .followRedirects(true) + .retryOnConnectionFailure(true) .build(); } diff --git a/app/src/main/java/ru/noties/markwon/MarkdownRenderer.java b/app/src/main/java/ru/noties/markwon/MarkdownRenderer.java index 1d0c4dc5..dbbe368a 100644 --- a/app/src/main/java/ru/noties/markwon/MarkdownRenderer.java +++ b/app/src/main/java/ru/noties/markwon/MarkdownRenderer.java @@ -6,17 +6,11 @@ import android.os.Handler; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import org.commonmark.ext.gfm.strikethrough.StrikethroughExtension; -import org.commonmark.node.Node; -import org.commonmark.parser.Parser; - -import java.util.Collections; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import javax.inject.Inject; -import ru.noties.markwon.renderer.SpannableRenderer; import ru.noties.markwon.spans.AsyncDrawable; @ActivityScope @@ -53,7 +47,7 @@ public class MarkdownRenderer { final UrlProcessor urlProcessor; if (uri == null) { - urlProcessor = null; + urlProcessor = new UrlProcessorAndroidAssets(); } else { urlProcessor = new UrlProcessorRelativeToAbsolute(uri.toString()); } diff --git a/art/markwon_logo.png b/art/markwon_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..817bacb43839fa7013c37f8eff02d0ae739a60ca GIT binary patch literal 12303 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 F{y!G-Cz1dF literal 0 HcmV?d00001 diff --git a/library-image-loader/build.gradle b/library-image-loader/build.gradle index 68bfa8f1..847ef752 100644 --- a/library-image-loader/build.gradle +++ b/library-image-loader/build.gradle @@ -14,7 +14,6 @@ android { } dependencies { - compile project(':library') compile ANDROID_SVG compile ANDROID_GIF diff --git a/library-image-loader/src/main/java/ru/noties/markwon/il/AsyncDrawableLoader.java b/library-image-loader/src/main/java/ru/noties/markwon/il/AsyncDrawableLoader.java index c890baae..a9574d13 100644 --- a/library-image-loader/src/main/java/ru/noties/markwon/il/AsyncDrawableLoader.java +++ b/library-image-loader/src/main/java/ru/noties/markwon/il/AsyncDrawableLoader.java @@ -6,6 +6,7 @@ import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; +import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.support.annotation.NonNull; @@ -14,7 +15,11 @@ import android.text.TextUtils; import com.caverock.androidsvg.SVG; import com.caverock.androidsvg.SVGParseException; +import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.lang.ref.WeakReference; @@ -46,6 +51,8 @@ public class AsyncDrawableLoader implements AsyncDrawable.Loader { private static final String CONTENT_TYPE_SVG = "image/svg+xml"; private static final String CONTENT_TYPE_GIF = "image/gif"; + private static final String FILE_ANDROID_ASSETS = "android_asset"; + private final OkHttpClient client; private final Resources resources; private final ExecutorService executorService; @@ -97,47 +104,32 @@ public class AsyncDrawableLoader implements AsyncDrawable.Loader { @Override public void run() { - final Request request = new Request.Builder() - .url(destination) - .tag(destination) - .build(); + final Item item; - Response response = null; - try { - response = client.newCall(request).execute(); - } catch (IOException e) { - e.printStackTrace(); + final Uri uri = Uri.parse(destination); + if ("file".equals(uri.getScheme())) { + item = fromFile(uri); + } else { + item = fromNetwork(destination); } Drawable result = null; - if (response != null) { - - final ResponseBody body = response.body(); - if (body != null) { - final InputStream inputStream = body.byteStream(); - if (inputStream != null) { - final String contentType = response.header(HEADER_CONTENT_TYPE); - try { - // svg can have `image/svg+xml;charset=...` - if (CONTENT_TYPE_SVG.equals(contentType) - || (!TextUtils.isEmpty(contentType) && contentType.startsWith(CONTENT_TYPE_SVG))) { - // handle SVG - result = handleSvg(inputStream); - } else if (CONTENT_TYPE_GIF.equals(contentType)) { - // handle gif - result = handleGif(inputStream); - } else { - result = handleSimple(inputStream); - // just try to decode whatever it is - } - } finally { - try { - inputStream.close(); - } catch (IOException e) { - // no op - } - } + if (item != null + && item.inputStream != null) { + try { + if (CONTENT_TYPE_SVG.equals(item.type)) { + result = handleSvg(item.inputStream); + } else if (CONTENT_TYPE_GIF.equals(item.type)) { + result = handleGif(item.inputStream); + } else { + result = handleSimple(item.inputStream); + } + } finally { + try { + item.inputStream.close(); + } catch (IOException e) { + // no op } } } @@ -165,6 +157,102 @@ public class AsyncDrawableLoader implements AsyncDrawable.Loader { }); } + private Item fromFile(Uri uri) { + + final List segments = uri.getPathSegments(); + if (segments == null + || segments.size() == 0) { + // pointing to file & having no path segments is no use + return null; + } + + final Item out; + final String type; + final InputStream inputStream; + + final boolean assets = FILE_ANDROID_ASSETS.equals(segments.get(0)); + final String lastSegment = uri.getLastPathSegment(); + + if (lastSegment.endsWith(".svg")) { + type = CONTENT_TYPE_SVG; + } else if (lastSegment.endsWith(".gif")) { + type = CONTENT_TYPE_GIF; + } else { + type = null; + } + + if (assets) { + final StringBuilder path = new StringBuilder(); + for (int i = 1, size = segments.size(); i < size; i++) { + if (i != 1) { + path.append('/'); + } + path.append(segments.get(i)); + } + // load assets + InputStream inner = null; + try { + inner = resources.getAssets().open(path.toString()); + } catch (IOException e) { + e.printStackTrace(); + } + inputStream = inner; + } else { + InputStream inner = null; + try { + inner = new BufferedInputStream(new FileInputStream(new File(uri.getPath()))); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + inputStream = inner; + } + + if (inputStream != null) { + out = new Item(type, inputStream); + } else { + out = null; + } + + return out; + } + + private Item fromNetwork(String destination) { + + Item out = null; + + final Request request = new Request.Builder() + .url(destination) + .tag(destination) + .build(); + + Response response = null; + try { + response = client.newCall(request).execute(); + } catch (IOException e) { + e.printStackTrace(); + } + + if (response != null) { + final ResponseBody body = response.body(); + if (body != null) { + final InputStream inputStream = body.byteStream(); + if (inputStream != null) { + final String type; + final String contentType = response.header(HEADER_CONTENT_TYPE); + if (!TextUtils.isEmpty(contentType) + && contentType.startsWith(CONTENT_TYPE_SVG)) { + type = CONTENT_TYPE_SVG; + } else { + type = contentType; + } + out = new Item(type, inputStream); + } + } + } + + return out; + } + private Drawable handleSvg(InputStream stream) { final Drawable out; @@ -292,4 +380,14 @@ public class AsyncDrawableLoader implements AsyncDrawable.Loader { return new AsyncDrawableLoader(this); } } + + private static class Item { + final String type; + final InputStream inputStream; + + Item(String type, InputStream inputStream) { + this.type = type; + this.inputStream = inputStream; + } + } } diff --git a/library/build.gradle b/library/build.gradle index 043d931e..c384c1b6 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -18,8 +18,6 @@ dependencies { compile COMMON_MARK compile COMMON_MARK_STRIKETHROUGHT compile COMMON_MARK_TABLE - - compile 'ru.noties:debug:3.0.0@jar' } if (project.hasProperty('release')) { diff --git a/library/src/main/java/ru/noties/markwon/UrlProcessorAndroidAssets.java b/library/src/main/java/ru/noties/markwon/UrlProcessorAndroidAssets.java new file mode 100644 index 00000000..82faf4e2 --- /dev/null +++ b/library/src/main/java/ru/noties/markwon/UrlProcessorAndroidAssets.java @@ -0,0 +1,39 @@ +package ru.noties.markwon; + +import android.net.Uri; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.text.TextUtils; + +public class UrlProcessorAndroidAssets implements UrlProcessor { + + private final UrlProcessorRelativeToAbsolute assetsProcessor + = new UrlProcessorRelativeToAbsolute("file:///android_asset/"); + + private final UrlProcessor processor; + + public UrlProcessorAndroidAssets() { + this(null); + } + + public UrlProcessorAndroidAssets(@Nullable UrlProcessor parent) { + this.processor = parent; + } + + @NonNull + @Override + public String process(@NonNull String destination) { + final String out; + final Uri uri = Uri.parse(destination); + if (TextUtils.isEmpty(uri.getScheme())) { + out = assetsProcessor.process(destination); + } else { + if (processor != null) { + out = processor.process(destination); + } else { + out = destination; + } + } + return out; + } +} diff --git a/library/src/main/java/ru/noties/markwon/renderer/SpannableMarkdownVisitor.java b/library/src/main/java/ru/noties/markwon/renderer/SpannableMarkdownVisitor.java index 8ac89cb0..757f735f 100644 --- a/library/src/main/java/ru/noties/markwon/renderer/SpannableMarkdownVisitor.java +++ b/library/src/main/java/ru/noties/markwon/renderer/SpannableMarkdownVisitor.java @@ -38,7 +38,6 @@ import java.util.ArrayList; import java.util.Deque; import java.util.List; -import ru.noties.debug.Debug; import ru.noties.markwon.SpannableConfiguration; import ru.noties.markwon.renderer.html.SpannableHtmlParser; import ru.noties.markwon.spans.AsyncDrawable; @@ -273,8 +272,6 @@ public class SpannableMarkdownVisitor extends AbstractVisitor { @Override public void visit(CustomNode customNode) { -// Log.e(null, String.valueOf(customNode)); - if (customNode instanceof Strikethrough) { final int length = builder.length(); @@ -290,8 +287,6 @@ public class SpannableMarkdownVisitor extends AbstractVisitor { final boolean handled; - Debug.i(node); - if (node instanceof TableBody) { visitChildren(node); tableRows = 0; @@ -306,8 +301,6 @@ public class SpannableMarkdownVisitor extends AbstractVisitor { if (pendingTableRow != null) { builder.append(' '); - Debug.i("adding a row: %d", tableRows); - final TableRowSpan span = new TableRowSpan( configuration.theme(), pendingTableRow,