diff --git a/app/src/main/java/ru/noties/markwon/MarkdownRenderer.java b/app/src/main/java/ru/noties/markwon/MarkdownRenderer.java
index 053fde93..fc6af948 100644
--- a/app/src/main/java/ru/noties/markwon/MarkdownRenderer.java
+++ b/app/src/main/java/ru/noties/markwon/MarkdownRenderer.java
@@ -77,10 +77,6 @@ public class MarkdownRenderer {
? prism4jThemeDefault
: prism4JThemeDarkula;
-// final int background = isLightTheme
-// ? prism4jTheme.background()
-// : 0x0Fffffff;
-
final Markwon2 markwon2 = Markwon2.builder(context)
.use(CorePlugin.create())
.use(ImagesPlugin.createWithAssets(context))
diff --git a/markwon-html-parser-api/build.gradle b/markwon-html-parser-api/build.gradle
deleted file mode 100644
index 8e38acbb..00000000
--- a/markwon-html-parser-api/build.gradle
+++ /dev/null
@@ -1,23 +0,0 @@
-apply plugin: 'com.android.library'
-
-android {
-
- compileSdkVersion config['compile-sdk']
- buildToolsVersion config['build-tools']
-
- defaultConfig {
- minSdkVersion config['min-sdk']
- targetSdkVersion config['target-sdk']
- versionCode 1
- versionName version
- }
-}
-
-dependencies {
-
- deps.with {
- api it['support-annotations']
- }
-}
-
-registerArtifact(this)
diff --git a/markwon-html-parser-api/gradle.properties b/markwon-html-parser-api/gradle.properties
deleted file mode 100644
index 5be4658d..00000000
--- a/markwon-html-parser-api/gradle.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-POM_NAME=Markwon
-POM_ARTIFACT_ID=markwon-html-parser-api
-POM_PACKAGING=aar
\ No newline at end of file
diff --git a/markwon-html-parser-api/src/main/AndroidManifest.xml b/markwon-html-parser-api/src/main/AndroidManifest.xml
deleted file mode 100644
index 872543b3..00000000
--- a/markwon-html-parser-api/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/markwon-html-parser-impl/build.gradle b/markwon-html/build.gradle
similarity index 88%
rename from markwon-html-parser-impl/build.gradle
rename to markwon-html/build.gradle
index 2af46373..b61b12de 100644
--- a/markwon-html-parser-impl/build.gradle
+++ b/markwon-html/build.gradle
@@ -15,7 +15,7 @@ android {
dependencies {
- api project(':markwon-html-parser-api')
+ api project(':markwon')
deps.with {
api it['support-annotations']
@@ -25,6 +25,7 @@ dependencies {
deps.test.with {
testImplementation it['junit']
testImplementation it['robolectric']
+ testImplementation it['ix-java']
}
}
diff --git a/markwon-html-parser-impl/gradle.properties b/markwon-html/gradle.properties
similarity index 100%
rename from markwon-html-parser-impl/gradle.properties
rename to markwon-html/gradle.properties
diff --git a/markwon-html-parser-impl/src/main/AndroidManifest.xml b/markwon-html/src/main/AndroidManifest.xml
similarity index 100%
rename from markwon-html-parser-impl/src/main/AndroidManifest.xml
rename to markwon-html/src/main/AndroidManifest.xml
diff --git a/markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/AppendableUtils.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/AppendableUtils.java
similarity index 100%
rename from markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/AppendableUtils.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/AppendableUtils.java
diff --git a/markwon/src/main/java/ru/noties/markwon/renderer/html2/CssInlineStyleParser.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/CssInlineStyleParser.java
similarity index 99%
rename from markwon/src/main/java/ru/noties/markwon/renderer/html2/CssInlineStyleParser.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/CssInlineStyleParser.java
index 9670d018..a42fab05 100644
--- a/markwon/src/main/java/ru/noties/markwon/renderer/html2/CssInlineStyleParser.java
+++ b/markwon-html/src/main/java/ru/noties/markwon/html/impl/CssInlineStyleParser.java
@@ -1,4 +1,4 @@
-package ru.noties.markwon.renderer.html2;
+package ru.noties.markwon.html.impl;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
diff --git a/markwon/src/main/java/ru/noties/markwon/renderer/html2/CssProperty.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/CssProperty.java
similarity index 94%
rename from markwon/src/main/java/ru/noties/markwon/renderer/html2/CssProperty.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/CssProperty.java
index aa490361..405d7c61 100644
--- a/markwon/src/main/java/ru/noties/markwon/renderer/html2/CssProperty.java
+++ b/markwon-html/src/main/java/ru/noties/markwon/html/impl/CssProperty.java
@@ -1,4 +1,4 @@
-package ru.noties.markwon.renderer.html2;
+package ru.noties.markwon.html.impl;
import android.support.annotation.NonNull;
diff --git a/markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/HtmlEmptyTagReplacement.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/HtmlEmptyTagReplacement.java
similarity index 97%
rename from markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/HtmlEmptyTagReplacement.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/HtmlEmptyTagReplacement.java
index c0d304dc..6604242b 100644
--- a/markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/HtmlEmptyTagReplacement.java
+++ b/markwon-html/src/main/java/ru/noties/markwon/html/impl/HtmlEmptyTagReplacement.java
@@ -3,7 +3,7 @@ package ru.noties.markwon.html.impl;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
-import ru.noties.markwon.html.api.HtmlTag;
+import ru.noties.markwon.html.HtmlTag;
/**
* This class will be used to append some text to output in order to
diff --git a/markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/HtmlTagImpl.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/HtmlTagImpl.java
similarity index 99%
rename from markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/HtmlTagImpl.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/HtmlTagImpl.java
index 01466106..8cedc767 100644
--- a/markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/HtmlTagImpl.java
+++ b/markwon-html/src/main/java/ru/noties/markwon/html/impl/HtmlTagImpl.java
@@ -7,7 +7,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
-import ru.noties.markwon.html.api.HtmlTag;
+import ru.noties.markwon.html.HtmlTag;
abstract class HtmlTagImpl implements HtmlTag {
diff --git a/markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/MarkwonHtmlParserImpl.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/MarkwonHtmlParserImpl.java
similarity index 98%
rename from markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/MarkwonHtmlParserImpl.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/MarkwonHtmlParserImpl.java
index 86f985a2..1bd639c6 100644
--- a/markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/MarkwonHtmlParserImpl.java
+++ b/markwon-html/src/main/java/ru/noties/markwon/html/impl/MarkwonHtmlParserImpl.java
@@ -14,10 +14,10 @@ import java.util.Locale;
import java.util.Map;
import java.util.Set;
-import ru.noties.markwon.html.api.HtmlTag;
-import ru.noties.markwon.html.api.HtmlTag.Block;
-import ru.noties.markwon.html.api.HtmlTag.Inline;
-import ru.noties.markwon.html.api.MarkwonHtmlParser;
+import ru.noties.markwon.html.HtmlTag;
+import ru.noties.markwon.html.HtmlTag.Block;
+import ru.noties.markwon.html.HtmlTag.Inline;
+import ru.noties.markwon.html.MarkwonHtmlParser;
import ru.noties.markwon.html.impl.jsoup.nodes.Attribute;
import ru.noties.markwon.html.impl.jsoup.nodes.Attributes;
import ru.noties.markwon.html.impl.jsoup.parser.CharacterReader;
diff --git a/markwon-html/src/main/java/ru/noties/markwon/html/impl/MarkwonHtmlRendererImpl.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/MarkwonHtmlRendererImpl.java
new file mode 100644
index 00000000..6ec8f26b
--- /dev/null
+++ b/markwon-html/src/main/java/ru/noties/markwon/html/impl/MarkwonHtmlRendererImpl.java
@@ -0,0 +1,167 @@
+package ru.noties.markwon.html.impl;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import ru.noties.markwon.MarkwonConfiguration;
+import ru.noties.markwon.SpannableBuilder;
+import ru.noties.markwon.html.HtmlTag;
+import ru.noties.markwon.html.MarkwonHtmlParser;
+import ru.noties.markwon.html.MarkwonHtmlRenderer;
+import ru.noties.markwon.html.TagHandler;
+import ru.noties.markwon.html.impl.tag.BlockquoteHandler;
+import ru.noties.markwon.html.impl.tag.EmphasisHandler;
+import ru.noties.markwon.html.impl.tag.HeadingHandler;
+import ru.noties.markwon.html.impl.tag.ImageHandler;
+import ru.noties.markwon.html.impl.tag.LinkHandler;
+import ru.noties.markwon.html.impl.tag.ListHandler;
+import ru.noties.markwon.html.impl.tag.StrikeHandler;
+import ru.noties.markwon.html.impl.tag.StrongEmphasisHandler;
+import ru.noties.markwon.html.impl.tag.SubScriptHandler;
+import ru.noties.markwon.html.impl.tag.SuperScriptHandler;
+import ru.noties.markwon.html.impl.tag.UnderlineHandler;
+
+public class MarkwonHtmlRendererImpl extends MarkwonHtmlRenderer {
+
+ @NonNull
+ public static MarkwonHtmlRendererImpl create() {
+ return builderWithDefaults().build();
+ }
+
+ @NonNull
+ public static Builder builderWithDefaults() {
+
+ final EmphasisHandler emphasisHandler = new EmphasisHandler();
+ final StrongEmphasisHandler strongEmphasisHandler = new StrongEmphasisHandler();
+ final StrikeHandler strikeHandler = new StrikeHandler();
+ final UnderlineHandler underlineHandler = new UnderlineHandler();
+ final ListHandler listHandler = new ListHandler();
+
+ return builder()
+ .handler("i", emphasisHandler)
+ .handler("em", emphasisHandler)
+ .handler("cite", emphasisHandler)
+ .handler("dfn", emphasisHandler)
+ .handler("b", strongEmphasisHandler)
+ .handler("strong", strongEmphasisHandler)
+ .handler("sup", new SuperScriptHandler())
+ .handler("sub", new SubScriptHandler())
+ .handler("u", underlineHandler)
+ .handler("ins", underlineHandler)
+ .handler("del", strikeHandler)
+ .handler("s", strikeHandler)
+ .handler("strike", strikeHandler)
+ .handler("a", new LinkHandler())
+ .handler("ul", listHandler)
+ .handler("ol", listHandler)
+ .handler("img", ImageHandler.create())
+ .handler("blockquote", new BlockquoteHandler())
+ .handler("h1", new HeadingHandler(1))
+ .handler("h2", new HeadingHandler(2))
+ .handler("h3", new HeadingHandler(3))
+ .handler("h4", new HeadingHandler(4))
+ .handler("h5", new HeadingHandler(5))
+ .handler("h6", new HeadingHandler(6));
+ }
+
+ @NonNull
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static final float SCRIPT_DEF_TEXT_SIZE_RATIO = .75F;
+
+ private final Map tagHandlers;
+
+ private MarkwonHtmlRendererImpl(@NonNull Map tagHandlers) {
+ this.tagHandlers = tagHandlers;
+ }
+
+ @Override
+ public void render(
+ @NonNull final MarkwonConfiguration configuration,
+ @NonNull final SpannableBuilder builder,
+ @NonNull MarkwonHtmlParser parser) {
+
+ final int end;
+ if (!configuration.htmlAllowNonClosedTags()) {
+ end = HtmlTag.NO_END;
+ } else {
+ end = builder.length();
+ }
+
+ parser.flushInlineTags(end, new MarkwonHtmlParser.FlushAction() {
+ @Override
+ public void apply(@NonNull List tags) {
+
+ TagHandler handler;
+
+ for (HtmlTag.Inline inline : tags) {
+
+ // if tag is not closed -> do not render
+ if (!inline.isClosed()) {
+ continue;
+ }
+
+ handler = tagHandler(inline.name());
+ if (handler != null) {
+ handler.handle(configuration, builder, inline);
+ }
+ }
+ }
+ });
+
+ parser.flushBlockTags(end, new MarkwonHtmlParser.FlushAction() {
+ @Override
+ public void apply(@NonNull List tags) {
+
+ TagHandler handler;
+
+ for (HtmlTag.Block block : tags) {
+
+ if (!block.isClosed()) {
+ continue;
+ }
+
+ handler = tagHandler(block.name());
+ if (handler != null) {
+ handler.handle(configuration, builder, block);
+ } else {
+ // see if any of children can be handled
+ apply(block.children());
+ }
+ }
+ }
+ });
+
+ parser.reset();
+ }
+
+ @Nullable
+ @Override
+ public TagHandler tagHandler(@NonNull String tagName) {
+ return tagHandlers.get(tagName);
+ }
+
+ public static class Builder {
+
+ private final Map tagHandlers = new HashMap<>(2);
+
+ @NonNull
+ public Builder handler(@NonNull String tagName, @NonNull TagHandler tagHandler) {
+ tagHandlers.put(tagName.toLowerCase(Locale.US), tagHandler);
+ return this;
+ }
+
+ @NonNull
+ public MarkwonHtmlRendererImpl build() {
+ return new MarkwonHtmlRendererImpl(Collections.unmodifiableMap(tagHandlers));
+ }
+ }
+}
diff --git a/markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/TrimmingAppender.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/TrimmingAppender.java
similarity index 100%
rename from markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/TrimmingAppender.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/TrimmingAppender.java
diff --git a/markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/jsoup/UncheckedIOException.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/jsoup/UncheckedIOException.java
similarity index 100%
rename from markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/jsoup/UncheckedIOException.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/jsoup/UncheckedIOException.java
diff --git a/markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/jsoup/helper/Normalizer.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/jsoup/helper/Normalizer.java
similarity index 100%
rename from markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/jsoup/helper/Normalizer.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/jsoup/helper/Normalizer.java
diff --git a/markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/jsoup/helper/Validate.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/jsoup/helper/Validate.java
similarity index 100%
rename from markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/jsoup/helper/Validate.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/jsoup/helper/Validate.java
diff --git a/markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/jsoup/nodes/Attribute.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/jsoup/nodes/Attribute.java
similarity index 100%
rename from markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/jsoup/nodes/Attribute.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/jsoup/nodes/Attribute.java
diff --git a/markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/jsoup/nodes/Attributes.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/jsoup/nodes/Attributes.java
similarity index 100%
rename from markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/jsoup/nodes/Attributes.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/jsoup/nodes/Attributes.java
diff --git a/markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/jsoup/nodes/CommonMarkEntities.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/jsoup/nodes/CommonMarkEntities.java
similarity index 100%
rename from markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/jsoup/nodes/CommonMarkEntities.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/jsoup/nodes/CommonMarkEntities.java
diff --git a/markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/jsoup/nodes/DocumentType.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/jsoup/nodes/DocumentType.java
similarity index 100%
rename from markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/jsoup/nodes/DocumentType.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/jsoup/nodes/DocumentType.java
diff --git a/markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/jsoup/parser/CharacterReader.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/jsoup/parser/CharacterReader.java
similarity index 100%
rename from markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/jsoup/parser/CharacterReader.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/jsoup/parser/CharacterReader.java
diff --git a/markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/jsoup/parser/ParseError.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/jsoup/parser/ParseError.java
similarity index 100%
rename from markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/jsoup/parser/ParseError.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/jsoup/parser/ParseError.java
diff --git a/markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/jsoup/parser/ParseErrorList.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/jsoup/parser/ParseErrorList.java
similarity index 100%
rename from markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/jsoup/parser/ParseErrorList.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/jsoup/parser/ParseErrorList.java
diff --git a/markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/jsoup/parser/Token.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/jsoup/parser/Token.java
similarity index 100%
rename from markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/jsoup/parser/Token.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/jsoup/parser/Token.java
diff --git a/markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/jsoup/parser/Tokeniser.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/jsoup/parser/Tokeniser.java
similarity index 100%
rename from markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/jsoup/parser/Tokeniser.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/jsoup/parser/Tokeniser.java
diff --git a/markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/jsoup/parser/TokeniserState.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/jsoup/parser/TokeniserState.java
similarity index 100%
rename from markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/jsoup/parser/TokeniserState.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/jsoup/parser/TokeniserState.java
diff --git a/markwon-html/src/main/java/ru/noties/markwon/html/impl/span/SubScriptSpan.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/span/SubScriptSpan.java
new file mode 100644
index 00000000..8eca8fdc
--- /dev/null
+++ b/markwon-html/src/main/java/ru/noties/markwon/html/impl/span/SubScriptSpan.java
@@ -0,0 +1,25 @@
+package ru.noties.markwon.html.impl.span;
+
+import android.support.annotation.NonNull;
+import android.text.TextPaint;
+import android.text.style.MetricAffectingSpan;
+
+import ru.noties.markwon.html.impl.MarkwonHtmlRendererImpl;
+
+public class SubScriptSpan extends MetricAffectingSpan {
+
+ @Override
+ public void updateDrawState(TextPaint tp) {
+ apply(tp);
+ }
+
+ @Override
+ public void updateMeasureState(@NonNull TextPaint tp) {
+ apply(tp);
+ }
+
+ private void apply(TextPaint paint) {
+ paint.setTextSize(paint.getTextSize() * MarkwonHtmlRendererImpl.SCRIPT_DEF_TEXT_SIZE_RATIO);
+ paint.baselineShift -= (int) (paint.ascent() / 2);
+ }
+}
diff --git a/markwon-html/src/main/java/ru/noties/markwon/html/impl/span/SuperScriptSpan.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/span/SuperScriptSpan.java
new file mode 100644
index 00000000..d33a2bea
--- /dev/null
+++ b/markwon-html/src/main/java/ru/noties/markwon/html/impl/span/SuperScriptSpan.java
@@ -0,0 +1,25 @@
+package ru.noties.markwon.html.impl.span;
+
+import android.support.annotation.NonNull;
+import android.text.TextPaint;
+import android.text.style.MetricAffectingSpan;
+
+import ru.noties.markwon.html.impl.MarkwonHtmlRendererImpl;
+
+public class SuperScriptSpan extends MetricAffectingSpan {
+
+ @Override
+ public void updateDrawState(TextPaint tp) {
+ apply(tp);
+ }
+
+ @Override
+ public void updateMeasureState(@NonNull TextPaint tp) {
+ apply(tp);
+ }
+
+ private void apply(TextPaint paint) {
+ paint.setTextSize(paint.getTextSize() * MarkwonHtmlRendererImpl.SCRIPT_DEF_TEXT_SIZE_RATIO);
+ paint.baselineShift += (int) (paint.ascent() / 2);
+ }
+}
diff --git a/markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/BlockquoteHandler.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/BlockquoteHandler.java
similarity index 84%
rename from markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/BlockquoteHandler.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/BlockquoteHandler.java
index 9f90dc93..2687ea94 100644
--- a/markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/BlockquoteHandler.java
+++ b/markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/BlockquoteHandler.java
@@ -1,10 +1,11 @@
-package ru.noties.markwon.renderer.html2.tag;
+package ru.noties.markwon.html.impl.tag;
import android.support.annotation.NonNull;
-import ru.noties.markwon.SpannableBuilder;
import ru.noties.markwon.MarkwonConfiguration;
-import ru.noties.markwon.html.api.HtmlTag;
+import ru.noties.markwon.SpannableBuilder;
+import ru.noties.markwon.html.HtmlTag;
+import ru.noties.markwon.html.TagHandler;
public class BlockquoteHandler extends TagHandler {
diff --git a/markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/EmphasisHandler.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/EmphasisHandler.java
similarity index 80%
rename from markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/EmphasisHandler.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/EmphasisHandler.java
index aa452ebf..0385266a 100644
--- a/markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/EmphasisHandler.java
+++ b/markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/EmphasisHandler.java
@@ -1,10 +1,10 @@
-package ru.noties.markwon.renderer.html2.tag;
+package ru.noties.markwon.html.impl.tag;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import ru.noties.markwon.MarkwonConfiguration;
-import ru.noties.markwon.html.api.HtmlTag;
+import ru.noties.markwon.html.HtmlTag;
public class EmphasisHandler extends SimpleTagHandler {
@Nullable
diff --git a/markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/HeadingHandler.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/HeadingHandler.java
similarity index 85%
rename from markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/HeadingHandler.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/HeadingHandler.java
index 99626259..d675351e 100644
--- a/markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/HeadingHandler.java
+++ b/markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/HeadingHandler.java
@@ -1,10 +1,10 @@
-package ru.noties.markwon.renderer.html2.tag;
+package ru.noties.markwon.html.impl.tag;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import ru.noties.markwon.MarkwonConfiguration;
-import ru.noties.markwon.html.api.HtmlTag;
+import ru.noties.markwon.html.HtmlTag;
public class HeadingHandler extends SimpleTagHandler {
diff --git a/markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/ImageHandler.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/ImageHandler.java
similarity index 92%
rename from markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/ImageHandler.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/ImageHandler.java
index fe41f9d1..adbf745e 100644
--- a/markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/ImageHandler.java
+++ b/markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/ImageHandler.java
@@ -1,4 +1,4 @@
-package ru.noties.markwon.renderer.html2.tag;
+package ru.noties.markwon.html.impl.tag;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@@ -7,9 +7,9 @@ import android.text.TextUtils;
import java.util.Map;
import ru.noties.markwon.MarkwonConfiguration;
-import ru.noties.markwon.html.api.HtmlTag;
+import ru.noties.markwon.html.HtmlTag;
+import ru.noties.markwon.html.impl.CssInlineStyleParser;
import ru.noties.markwon.renderer.ImageSize;
-import ru.noties.markwon.renderer.html2.CssInlineStyleParser;
public class ImageHandler extends SimpleTagHandler {
diff --git a/markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/ImageSizeParserImpl.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/ImageSizeParserImpl.java
similarity index 94%
rename from markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/ImageSizeParserImpl.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/ImageSizeParserImpl.java
index 56ad13c0..04556327 100644
--- a/markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/ImageSizeParserImpl.java
+++ b/markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/ImageSizeParserImpl.java
@@ -1,4 +1,4 @@
-package ru.noties.markwon.renderer.html2.tag;
+package ru.noties.markwon.html.impl.tag;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@@ -7,9 +7,9 @@ import android.text.TextUtils;
import java.util.Map;
+import ru.noties.markwon.html.impl.CssInlineStyleParser;
+import ru.noties.markwon.html.impl.CssProperty;
import ru.noties.markwon.renderer.ImageSize;
-import ru.noties.markwon.renderer.html2.CssInlineStyleParser;
-import ru.noties.markwon.renderer.html2.CssProperty;
class ImageSizeParserImpl implements ImageHandler.ImageSizeParser {
diff --git a/markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/LinkHandler.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/LinkHandler.java
similarity index 89%
rename from markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/LinkHandler.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/LinkHandler.java
index 74ac3c00..1faba510 100644
--- a/markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/LinkHandler.java
+++ b/markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/LinkHandler.java
@@ -1,11 +1,11 @@
-package ru.noties.markwon.renderer.html2.tag;
+package ru.noties.markwon.html.impl.tag;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import ru.noties.markwon.MarkwonConfiguration;
-import ru.noties.markwon.html.api.HtmlTag;
+import ru.noties.markwon.html.HtmlTag;
public class LinkHandler extends SimpleTagHandler {
@Nullable
diff --git a/markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/ListHandler.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/ListHandler.java
similarity index 93%
rename from markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/ListHandler.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/ListHandler.java
index 671e2297..80094b5c 100644
--- a/markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/ListHandler.java
+++ b/markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/ListHandler.java
@@ -1,10 +1,11 @@
-package ru.noties.markwon.renderer.html2.tag;
+package ru.noties.markwon.html.impl.tag;
import android.support.annotation.NonNull;
import ru.noties.markwon.MarkwonConfiguration;
import ru.noties.markwon.SpannableBuilder;
-import ru.noties.markwon.html.api.HtmlTag;
+import ru.noties.markwon.html.HtmlTag;
+import ru.noties.markwon.html.TagHandler;
public class ListHandler extends TagHandler {
diff --git a/markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/SimpleTagHandler.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/SimpleTagHandler.java
similarity index 84%
rename from markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/SimpleTagHandler.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/SimpleTagHandler.java
index d6fd93dc..ad68ef30 100644
--- a/markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/SimpleTagHandler.java
+++ b/markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/SimpleTagHandler.java
@@ -1,11 +1,12 @@
-package ru.noties.markwon.renderer.html2.tag;
+package ru.noties.markwon.html.impl.tag;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
-import ru.noties.markwon.SpannableBuilder;
import ru.noties.markwon.MarkwonConfiguration;
-import ru.noties.markwon.html.api.HtmlTag;
+import ru.noties.markwon.SpannableBuilder;
+import ru.noties.markwon.html.HtmlTag;
+import ru.noties.markwon.html.TagHandler;
public abstract class SimpleTagHandler extends TagHandler {
diff --git a/markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/StrikeHandler.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/StrikeHandler.java
similarity index 84%
rename from markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/StrikeHandler.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/StrikeHandler.java
index 9b8cad2d..4d59b152 100644
--- a/markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/StrikeHandler.java
+++ b/markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/StrikeHandler.java
@@ -1,10 +1,11 @@
-package ru.noties.markwon.renderer.html2.tag;
+package ru.noties.markwon.html.impl.tag;
import android.support.annotation.NonNull;
import ru.noties.markwon.MarkwonConfiguration;
import ru.noties.markwon.SpannableBuilder;
-import ru.noties.markwon.html.api.HtmlTag;
+import ru.noties.markwon.html.HtmlTag;
+import ru.noties.markwon.html.TagHandler;
public class StrikeHandler extends TagHandler {
diff --git a/markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/StrongEmphasisHandler.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/StrongEmphasisHandler.java
similarity index 81%
rename from markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/StrongEmphasisHandler.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/StrongEmphasisHandler.java
index 7e50bc72..6b5f8230 100644
--- a/markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/StrongEmphasisHandler.java
+++ b/markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/StrongEmphasisHandler.java
@@ -1,10 +1,10 @@
-package ru.noties.markwon.renderer.html2.tag;
+package ru.noties.markwon.html.impl.tag;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import ru.noties.markwon.MarkwonConfiguration;
-import ru.noties.markwon.html.api.HtmlTag;
+import ru.noties.markwon.html.HtmlTag;
public class StrongEmphasisHandler extends SimpleTagHandler {
@Nullable
diff --git a/markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/SubScriptHandler.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/SubScriptHandler.java
similarity index 65%
rename from markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/SubScriptHandler.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/SubScriptHandler.java
index 145cf261..9adf5684 100644
--- a/markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/SubScriptHandler.java
+++ b/markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/SubScriptHandler.java
@@ -1,15 +1,16 @@
-package ru.noties.markwon.renderer.html2.tag;
+package ru.noties.markwon.html.impl.tag;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import ru.noties.markwon.MarkwonConfiguration;
-import ru.noties.markwon.html.api.HtmlTag;
+import ru.noties.markwon.html.HtmlTag;
+import ru.noties.markwon.html.impl.span.SubScriptSpan;
public class SubScriptHandler extends SimpleTagHandler {
@Nullable
@Override
public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull HtmlTag tag) {
- return configuration.factory().subScript(configuration.theme());
+ return new SubScriptSpan();
}
}
diff --git a/markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/SuperScriptHandler.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/SuperScriptHandler.java
similarity index 65%
rename from markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/SuperScriptHandler.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/SuperScriptHandler.java
index 60da420d..42e00075 100644
--- a/markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/SuperScriptHandler.java
+++ b/markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/SuperScriptHandler.java
@@ -1,15 +1,16 @@
-package ru.noties.markwon.renderer.html2.tag;
+package ru.noties.markwon.html.impl.tag;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import ru.noties.markwon.MarkwonConfiguration;
-import ru.noties.markwon.html.api.HtmlTag;
+import ru.noties.markwon.html.HtmlTag;
+import ru.noties.markwon.html.impl.span.SuperScriptSpan;
public class SuperScriptHandler extends SimpleTagHandler {
@Nullable
@Override
public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull HtmlTag tag) {
- return configuration.factory().superScript(configuration.theme());
+ return new SuperScriptSpan();
}
}
diff --git a/markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/UnderlineHandler.java b/markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/UnderlineHandler.java
similarity index 78%
rename from markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/UnderlineHandler.java
rename to markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/UnderlineHandler.java
index d9e03e2a..fb492dda 100644
--- a/markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/UnderlineHandler.java
+++ b/markwon-html/src/main/java/ru/noties/markwon/html/impl/tag/UnderlineHandler.java
@@ -1,10 +1,12 @@
-package ru.noties.markwon.renderer.html2.tag;
+package ru.noties.markwon.html.impl.tag;
import android.support.annotation.NonNull;
+import android.text.style.UnderlineSpan;
-import ru.noties.markwon.SpannableBuilder;
import ru.noties.markwon.MarkwonConfiguration;
-import ru.noties.markwon.html.api.HtmlTag;
+import ru.noties.markwon.SpannableBuilder;
+import ru.noties.markwon.html.HtmlTag;
+import ru.noties.markwon.html.TagHandler;
public class UnderlineHandler extends TagHandler {
@@ -23,7 +25,7 @@ public class UnderlineHandler extends TagHandler {
SpannableBuilder.setSpans(
builder,
- configuration.factory().underline(),
+ new UnderlineSpan(),
tag.start(),
tag.end()
);
diff --git a/markwon-html/src/test/java/ru/noties/markwon/html/impl/CssInlineStyleParserTest.java b/markwon-html/src/test/java/ru/noties/markwon/html/impl/CssInlineStyleParserTest.java
new file mode 100644
index 00000000..36c7d798
--- /dev/null
+++ b/markwon-html/src/test/java/ru/noties/markwon/html/impl/CssInlineStyleParserTest.java
@@ -0,0 +1,239 @@
+package ru.noties.markwon.html.impl;
+
+import android.support.annotation.NonNull;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import ix.Ix;
+import ix.IxFunction;
+import ru.noties.markwon.test.TestUtils;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static ru.noties.markwon.test.TestUtils.with;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+public class CssInlineStyleParserTest {
+
+ private CssInlineStyleParser.Impl impl;
+
+ @Before
+ public void before() {
+ impl = new CssInlineStyleParser.Impl();
+ }
+
+ @Test
+ public void simple_single_pair() {
+
+ final String input = "key: value;";
+
+ final List list = listProperties(input);
+
+ assertEquals(1, list.size());
+
+ with(list.get(0), new TestUtils.Action() {
+ @Override
+ public void apply(@NonNull CssProperty cssProperty) {
+ assertEquals("key", cssProperty.key());
+ assertEquals("value", cssProperty.value());
+ }
+ });
+ }
+
+ @Test
+ public void simple_two_pairs() {
+
+ final String input = "key1: value1; key2: value2;";
+
+ final List list = listProperties(input);
+
+ assertEquals(2, list.size());
+
+ with(list.get(0), new TestUtils.Action() {
+ @Override
+ public void apply(@NonNull CssProperty cssProperty) {
+ assertEquals("key1", cssProperty.key());
+ assertEquals("value1", cssProperty.value());
+ }
+ });
+
+ with(list.get(1), new TestUtils.Action() {
+ @Override
+ public void apply(@NonNull CssProperty cssProperty) {
+ assertEquals("key2", cssProperty.key());
+ assertEquals("value2", cssProperty.value());
+ }
+ });
+ }
+
+ @Test
+ public void one_pair_eof() {
+
+ final String input = "key: value";
+ final List list = listProperties(input);
+ assertEquals(1, list.size());
+
+ with(list.get(0), new TestUtils.Action() {
+ @Override
+ public void apply(@NonNull CssProperty cssProperty) {
+ assertEquals("key", cssProperty.key());
+ assertEquals("value", cssProperty.value());
+ }
+ });
+ }
+
+ @Test
+ public void one_pair_eof_whitespaces() {
+
+ final String input = "key: value \n\n\t";
+ final List list = listProperties(input);
+ assertEquals(1, list.size());
+
+ with(list.get(0), new TestUtils.Action() {
+ @Override
+ public void apply(@NonNull CssProperty cssProperty) {
+ assertEquals("key", cssProperty.key());
+ assertEquals("value", cssProperty.value());
+ }
+ });
+ }
+
+ @Test
+ public void white_spaces() {
+
+ final String input = "\n\n\n\t \t key1 \n\n\n\t : \n\n\n\n \t value1 \n\n\n\n ; \n key2\n : \n value2 \n ; ";
+ final List list = listProperties(input);
+ assertEquals(2, list.size());
+
+ with(list.get(0), new TestUtils.Action() {
+ @Override
+ public void apply(@NonNull CssProperty cssProperty) {
+ assertEquals("key1", cssProperty.key());
+ assertEquals("value1", cssProperty.value());
+ }
+ });
+
+ with(list.get(1), new TestUtils.Action() {
+ @Override
+ public void apply(@NonNull CssProperty cssProperty) {
+ assertEquals("key2", cssProperty.key());
+ assertEquals("value2", cssProperty.value());
+ }
+ });
+ }
+
+ @Test
+ public void list_of_keys() {
+
+ final String input = "key1 key2 key3 key4";
+ final List list = listProperties(input);
+
+ assertEquals(0, list.size());
+ }
+
+ @Test
+ public void list_of_keys_and_value() {
+
+ final String input = "key1 key2 key3 key4: value4";
+ final List list = listProperties(input);
+ assertEquals(1, list.size());
+
+ with(list.get(0), new TestUtils.Action() {
+ @Override
+ public void apply(@NonNull CssProperty cssProperty) {
+ assertEquals("key4", cssProperty.key());
+ assertEquals("value4", cssProperty.value());
+ }
+ });
+ }
+
+ @Test
+ public void list_of_keys_separated_by_semi_colon() {
+
+ final String input = "key1;key2;key3;key4;";
+ final List list = listProperties(input);
+ assertEquals(0, list.size());
+ }
+
+ @Test
+ public void key_value_with_invalid_between() {
+
+ final String input = "key1: value1; key2 key3: value3;";
+ final List list = listProperties(input);
+
+ assertEquals(2, list.size());
+
+ with(list.get(0), new TestUtils.Action() {
+ @Override
+ public void apply(@NonNull CssProperty cssProperty) {
+ assertEquals("key1", cssProperty.key());
+ assertEquals("value1", cssProperty.value());
+ }
+ });
+
+ with(list.get(1), new TestUtils.Action() {
+ @Override
+ public void apply(@NonNull CssProperty cssProperty) {
+ assertEquals("key3", cssProperty.key());
+ assertEquals("value3", cssProperty.value());
+ }
+ });
+ }
+
+ @Test
+ public void css_functions() {
+
+ final Map map = new HashMap() {{
+ put("attr", "\" (\" attr(href) \")\"");
+ put("calc", "calc(100% - 100px)");
+ put("cubic-bezier", "cubic-bezier(0.1, 0.7, 1.0, 0.1)");
+ put("hsl", "hsl(120,100%,50%)");
+ put("hsla", "hsla(120,100%,50%,0.3)");
+ put("linear-gradient", "linear-gradient(red, yellow, blue)");
+ put("radial-gradient", "radial-gradient(red, green, blue)");
+ put("repeating-linear-gradient", "repeating-linear-gradient(red, yellow 10%, green 20%)");
+ put("repeating-radial-gradient", "repeating-radial-gradient(red, yellow 10%, green 15%)");
+ put("rgb", "rgb(255,0,0)");
+ put("rgba", "rgba(255,0,0,0.3)");
+ put("var", "var(--some-variable)");
+ put("url", "url(\"url.gif\")");
+ }};
+
+ final StringBuilder builder = new StringBuilder();
+ for (Map.Entry entry: map.entrySet()) {
+ builder.append(entry.getKey())
+ .append(':')
+ .append(entry.getValue())
+ .append(';');
+ }
+
+ for (CssProperty cssProperty: impl.parse(builder.toString())) {
+ final String value = map.remove(cssProperty.key());
+ assertNotNull(cssProperty.key(), value);
+ assertEquals(cssProperty.key(), value, cssProperty.value());
+ }
+
+ assertEquals(0, map.size());
+ }
+
+ @NonNull
+ private List listProperties(@NonNull String input) {
+ return Ix.from(impl.parse(input))
+ .map(new IxFunction() {
+ @Override
+ public CssProperty apply(CssProperty cssProperty) {
+ return cssProperty.mutate();
+ }
+ })
+ .toList();
+ }
+}
\ No newline at end of file
diff --git a/markwon-html-parser-impl/src/test/java/ru/noties/markwon/html/impl/HtmlEmptyTagReplacementTest.java b/markwon-html/src/test/java/ru/noties/markwon/html/impl/HtmlEmptyTagReplacementTest.java
similarity index 100%
rename from markwon-html-parser-impl/src/test/java/ru/noties/markwon/html/impl/HtmlEmptyTagReplacementTest.java
rename to markwon-html/src/test/java/ru/noties/markwon/html/impl/HtmlEmptyTagReplacementTest.java
diff --git a/markwon-html-parser-impl/src/test/java/ru/noties/markwon/html/impl/MarkwonHtmlParserImplTest.java b/markwon-html/src/test/java/ru/noties/markwon/html/impl/MarkwonHtmlParserImplTest.java
similarity index 100%
rename from markwon-html-parser-impl/src/test/java/ru/noties/markwon/html/impl/MarkwonHtmlParserImplTest.java
rename to markwon-html/src/test/java/ru/noties/markwon/html/impl/MarkwonHtmlParserImplTest.java
diff --git a/markwon-html-parser-impl/src/test/java/ru/noties/markwon/html/impl/TrimmingAppenderTest.java b/markwon-html/src/test/java/ru/noties/markwon/html/impl/TrimmingAppenderTest.java
similarity index 100%
rename from markwon-html-parser-impl/src/test/java/ru/noties/markwon/html/impl/TrimmingAppenderTest.java
rename to markwon-html/src/test/java/ru/noties/markwon/html/impl/TrimmingAppenderTest.java
diff --git a/markwon-html-parser-impl/src/test/java/ru/noties/markwon/html/impl/jsoup/nodes/CommonMarkEntitiesTest.java b/markwon-html/src/test/java/ru/noties/markwon/html/impl/jsoup/nodes/CommonMarkEntitiesTest.java
similarity index 100%
rename from markwon-html-parser-impl/src/test/java/ru/noties/markwon/html/impl/jsoup/nodes/CommonMarkEntitiesTest.java
rename to markwon-html/src/test/java/ru/noties/markwon/html/impl/jsoup/nodes/CommonMarkEntitiesTest.java
diff --git a/markwon-html/src/test/java/ru/noties/markwon/html/impl/tag/ImageSizeParserImplTest.java b/markwon-html/src/test/java/ru/noties/markwon/html/impl/tag/ImageSizeParserImplTest.java
new file mode 100644
index 00000000..006427e8
--- /dev/null
+++ b/markwon-html/src/test/java/ru/noties/markwon/html/impl/tag/ImageSizeParserImplTest.java
@@ -0,0 +1,186 @@
+package ru.noties.markwon.html.impl.tag;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import ru.noties.markwon.renderer.ImageSize;
+import ru.noties.markwon.renderer.html2.CssInlineStyleParser;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+public class ImageSizeParserImplTest {
+
+ private static final float DELTA = 1e-7F;
+
+ private ImageSizeParserImpl impl;
+
+ @Before
+ public void before() {
+ impl = new ImageSizeParserImpl(CssInlineStyleParser.create());
+ }
+
+ @Test
+ public void nothing() {
+ assertNull(impl.parse(Collections.emptyMap()));
+ }
+
+ @Test
+ public void width_height_from_style() {
+
+ final String style = "width: 123; height: 321";
+
+ assertImageSize(
+ new ImageSize(dimension(123, null), dimension(321, null)),
+ impl.parse(Collections.singletonMap("style", style))
+ );
+ }
+
+ @Test
+ public void style_has_higher_priority_width() {
+
+ // if property is found in styles, do not lookup raw attribute
+ final Map attributes = new HashMap() {{
+ put("style", "width: 43");
+ put("width", "991");
+ }};
+
+ assertImageSize(
+ new ImageSize(dimension(43, null), null),
+ impl.parse(attributes)
+ );
+ }
+
+ @Test
+ public void style_has_higher_priority_height() {
+
+ // if property is found in styles, do not lookup raw attribute
+ final Map attributes = new HashMap() {{
+ put("style", "height: 177");
+ put("height", "8");
+ }};
+
+ assertImageSize(
+ new ImageSize(null, dimension(177, null)),
+ impl.parse(attributes)
+ );
+ }
+
+ @Test
+ public void width_style_height_attributes() {
+
+ final Map attributes = new HashMap() {{
+ put("style", "width: 99");
+ put("height", "7");
+ }};
+
+ assertImageSize(
+ new ImageSize(dimension(99, null), dimension(7, null)),
+ impl.parse(attributes)
+ );
+ }
+
+ @Test
+ public void height_style_width_attributes() {
+
+ final Map attributes = new HashMap() {{
+ put("style", "height: 15");
+ put("width", "88");
+ }};
+
+ assertImageSize(
+ new ImageSize(dimension(88, null), dimension(15, null)),
+ impl.parse(attributes)
+ );
+ }
+
+ @Test
+ public void non_empty_styles_width_height_attributes() {
+
+ final Map attributes = new HashMap() {{
+ put("style", "key1: value1; width0: 123; height0: 99");
+ put("width", "40");
+ put("height", "77");
+ }};
+
+ assertImageSize(
+ new ImageSize(dimension(40, null), dimension(77, null)),
+ impl.parse(attributes)
+ );
+ }
+
+ @Test
+ public void dimension_units() {
+
+ final Map map = new HashMap() {{
+ put("100", dimension(100, null));
+ put("100%", dimension(100, "%"));
+ put("1%", dimension(1, "%"));
+ put("0.2em", dimension(0.2F, "em"));
+ put("155px", dimension(155, "px"));
+ put("67blah", dimension(67, "blah"));
+ put("-1", dimension(-1, null));
+ put("-0.01pt", dimension(-0.01F, "pt"));
+ }};
+
+ for (Map.Entry entry : map.entrySet()) {
+ assertDimension(entry.getKey(), entry.getValue(), impl.dimension(entry.getKey()));
+ }
+ }
+
+ @Test
+ public void bad_dimension() {
+
+ final String[] dimensions = {
+ "calc(5px + 10rem)",
+ "whataver6",
+ "165 165",
+ "!@#$%^&*(%"
+ };
+
+ for (String dimension : dimensions) {
+ assertNull(dimension, impl.dimension(dimension));
+ }
+ }
+
+ private static void assertImageSize(@Nullable ImageSize expected, @Nullable ImageSize actual) {
+ if (expected == null) {
+ assertNull(actual);
+ } else {
+ assertNotNull(actual);
+ assertDimension("width", expected.width, actual.width);
+ assertDimension("height", expected.height, actual.height);
+ }
+ }
+
+ private static void assertDimension(
+ @NonNull String name,
+ @Nullable ImageSize.Dimension expected,
+ @Nullable ImageSize.Dimension actual) {
+ if (expected == null) {
+ assertNull(name, actual);
+ } else {
+ assertNotNull(name, actual);
+ assertEquals(name, expected.value, actual.value, DELTA);
+ assertEquals(name, expected.unit, actual.unit);
+ }
+ }
+
+ @NonNull
+ private static ImageSize.Dimension dimension(float value, @Nullable String unit) {
+ return new ImageSize.Dimension(value, unit);
+ }
+}
\ No newline at end of file
diff --git a/markwon-image-loader/build.gradle b/markwon-image-loader/build.gradle
deleted file mode 100644
index fd4293c8..00000000
--- a/markwon-image-loader/build.gradle
+++ /dev/null
@@ -1,37 +0,0 @@
-apply plugin: 'com.android.library'
-
-android {
-
- compileSdkVersion config['compile-sdk']
- buildToolsVersion config['build-tools']
-
- defaultConfig {
- minSdkVersion config['min-sdk']
- targetSdkVersion config['target-sdk']
- versionCode 1
- versionName version
- }
-
- lintOptions {
- // okio....
- disable 'InvalidPackage'
- }
-}
-
-dependencies {
-
- api project(':markwon')
-
- deps.with {
- api it['android-svg']
- api it['android-gif']
- api it['okhttp']
- }
-
- deps['test'].with {
- testImplementation it['junit']
- testImplementation it['robolectric']
- }
-}
-
-registerArtifact(this)
diff --git a/markwon-image-loader/gradle.properties b/markwon-image-loader/gradle.properties
deleted file mode 100644
index 4dbec709..00000000
--- a/markwon-image-loader/gradle.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-POM_NAME=Markwon-Image-Loader
-POM_ARTIFACT_ID=markwon-image-loader
-POM_PACKAGING=aar
\ No newline at end of file
diff --git a/markwon-image-loader/src/main/AndroidManifest.xml b/markwon-image-loader/src/main/AndroidManifest.xml
deleted file mode 100644
index 35da8e8a..00000000
--- a/markwon-image-loader/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/markwon-image-loader/src/main/java/ru/noties/markwon/il/AsyncDrawableLoader.java b/markwon-image-loader/src/main/java/ru/noties/markwon/il/AsyncDrawableLoader.java
deleted file mode 100644
index 5f7a5f01..00000000
--- a/markwon-image-loader/src/main/java/ru/noties/markwon/il/AsyncDrawableLoader.java
+++ /dev/null
@@ -1,405 +0,0 @@
-package ru.noties.markwon.il;
-
-import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Looper;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-
-import okhttp3.OkHttpClient;
-import ru.noties.markwon.image.AsyncDrawable;
-
-public class AsyncDrawableLoader implements AsyncDrawable.Loader {
-
- @NonNull
- public static AsyncDrawableLoader create() {
- return builder().build();
- }
-
- @NonNull
- public static AsyncDrawableLoader.Builder builder() {
- return new Builder();
- }
-
- private final ExecutorService executorService;
- private final Handler mainThread;
- private final Drawable errorDrawable;
- private final Map schemeHandlers;
- private final List mediaDecoders;
-
- private final Map> requests;
-
- AsyncDrawableLoader(Builder builder) {
- this.executorService = builder.executorService;
- this.mainThread = new Handler(Looper.getMainLooper());
- this.errorDrawable = builder.errorDrawable;
- this.schemeHandlers = builder.schemeHandlers;
- this.mediaDecoders = builder.mediaDecoders;
- this.requests = new HashMap<>(3);
- }
-
-
- @Override
- public void load(@NonNull String destination, @NonNull AsyncDrawable drawable) {
- // if drawable is not a link -> show loading placeholder...
- requests.put(destination, execute(destination, drawable));
- }
-
- @Override
- public void cancel(@NonNull String destination) {
-
- final Future> request = requests.remove(destination);
- if (request != null) {
- request.cancel(true);
- }
-
- for (SchemeHandler schemeHandler : schemeHandlers.values()) {
- schemeHandler.cancel(destination);
- }
- }
-
- private Future> execute(@NonNull final String destination, @NonNull AsyncDrawable drawable) {
-
- final WeakReference reference = new WeakReference(drawable);
-
- // todo: should we cancel pending request for the same destination?
- // we _could_ but there is possibility that one resource is request in multiple places
-
- // todo: error handing (simply applying errorDrawable is not a good solution
- // as reason for an error is unclear (no scheme handler, no input data, error decoding, etc)
-
- // todo: more efficient ImageMediaDecoder... BitmapFactory.decodeStream is a bit not optimal
- // for big images for sure. We _could_ introduce internal Drawable that will check for
- // image bounds (but we will need to cache inputStream in order to inspect and optimize
- // input image...)
-
- return executorService.submit(new Runnable() {
- @Override
- public void run() {
-
- final ImageItem item;
-
- final Uri uri = Uri.parse(destination);
-
- final SchemeHandler schemeHandler = schemeHandlers.get(uri.getScheme());
- if (schemeHandler != null) {
- item = schemeHandler.handle(destination, uri);
- } else {
- item = null;
- }
-
- final InputStream inputStream = item != null
- ? item.inputStream()
- : null;
-
- Drawable result = null;
-
- if (inputStream != null) {
- try {
-
- final String fileName = item.fileName();
- final MediaDecoder mediaDecoder = fileName != null
- ? mediaDecoderFromFile(fileName)
- : mediaDecoderFromContentType(item.contentType());
-
- if (mediaDecoder != null) {
- result = mediaDecoder.decode(inputStream);
- }
-
- } finally {
- try {
- inputStream.close();
- } catch (IOException e) {
- // ignored
- }
- }
- }
-
- // if result is null, we assume it's an error
- if (result == null) {
- result = errorDrawable;
- }
-
- if (result != null) {
- final Drawable out = result;
- mainThread.post(new Runnable() {
- @Override
- public void run() {
- final AsyncDrawable asyncDrawable = reference.get();
- if (asyncDrawable != null && asyncDrawable.isAttached()) {
- asyncDrawable.setResult(out);
- }
- }
- });
- }
-
- requests.remove(destination);
- }
- });
- }
-
- @Nullable
- private MediaDecoder mediaDecoderFromFile(@NonNull String fileName) {
-
- MediaDecoder out = null;
-
- for (MediaDecoder mediaDecoder : mediaDecoders) {
- if (mediaDecoder.canDecodeByFileName(fileName)) {
- out = mediaDecoder;
- break;
- }
- }
-
- return out;
- }
-
- @Nullable
- private MediaDecoder mediaDecoderFromContentType(@Nullable String contentType) {
-
- MediaDecoder out = null;
-
- for (MediaDecoder mediaDecoder : mediaDecoders) {
- if (mediaDecoder.canDecodeByContentType(contentType)) {
- out = mediaDecoder;
- break;
- }
- }
-
- return out;
- }
-
- // todo: as now we have different layers of abstraction (for scheme handling and media decoding)
- // we no longer should add dependencies implicitly, it would be way better to allow adding
- // multiple artifacts (file, data, network, svg, gif)... at least, maybe we can extract API
- // for this module (without implementations), but keep _all-in_ (fat) artifact with all of these.
- public static class Builder {
-
- /**
- * @deprecated 2.0.0 add {@link NetworkSchemeHandler} directly
- */
- @Deprecated
- private OkHttpClient client;
-
- /**
- * @deprecated 2.0.0 construct {@link MediaDecoder} and {@link SchemeHandler} appropriately
- */
- @Deprecated
- private Resources resources;
-
- private ExecutorService executorService;
- private Drawable errorDrawable;
-
- // @since 1.1.0
- private final List mediaDecoders = new ArrayList<>(3);
-
- // @since 2.0.0
- private final Map schemeHandlers = new HashMap<>(3);
-
- /**
- * @deprecated 2.0.0 add {@link NetworkSchemeHandler} directly
- */
- @NonNull
- @Deprecated
- public Builder client(@NonNull OkHttpClient client) {
- this.client = client;
- return this;
- }
-
- /**
- * Supplied resources argument will be used to open files from assets directory
- * and to create default {@link MediaDecoder}\'s which require resources instance
- *
- * @return self
- */
- @NonNull
- public Builder resources(@NonNull Resources resources) {
- this.resources = resources;
- return this;
- }
-
- @NonNull
- public Builder executorService(@NonNull ExecutorService executorService) {
- this.executorService = executorService;
- return this;
- }
-
- @NonNull
- public Builder errorDrawable(@NonNull Drawable errorDrawable) {
- this.errorDrawable = errorDrawable;
- return this;
- }
-
- /**
- * @since 2.0.0
- */
- @SuppressWarnings("UnusedReturnValue")
- @NonNull
- public Builder addSchemeHandler(@NonNull SchemeHandler schemeHandler) {
-
- SchemeHandler previous;
-
- for (String scheme : schemeHandler.schemes()) {
- previous = schemeHandlers.put(scheme, schemeHandler);
- if (previous != null) {
- throw new IllegalStateException(String.format("Multiple scheme handlers handle " +
- "the same scheme: `%s`, %s %s", scheme, previous, schemeHandler));
- }
- }
-
- return this;
- }
-
- /**
- * @see #addMediaDecoder(MediaDecoder)
- * @see #addMediaDecoders(MediaDecoder...)
- * @see #addMediaDecoders(Iterable)
- * @since 1.1.0
- * @deprecated 2.0.0
- */
- @Deprecated
- @NonNull
- public Builder mediaDecoders(@NonNull List mediaDecoders) {
-
- // previously it was clearing before adding
-
- for (MediaDecoder mediaDecoder : mediaDecoders) {
- this.mediaDecoders.add(requireNonNull(mediaDecoder));
- }
-
- return this;
- }
-
- /**
- * @see #addMediaDecoder(MediaDecoder)
- * @see #addMediaDecoders(MediaDecoder...)
- * @see #addMediaDecoders(Iterable)
- * @since 1.1.0
- * @deprecated 2.0.0
- */
- @NonNull
- @Deprecated
- public Builder mediaDecoders(MediaDecoder... mediaDecoders) {
-
- // previously it was clearing before adding
-
- final int length = mediaDecoders != null
- ? mediaDecoders.length
- : 0;
-
- if (length > 0) {
- for (int i = 0; i < length; i++) {
- this.mediaDecoders.add(requireNonNull(mediaDecoders[i]));
- }
- }
-
- return this;
- }
-
- /**
- * @see SvgMediaDecoder
- * @see GifMediaDecoder
- * @see ImageMediaDecoder
- * @since 2.0.0
- */
- @NonNull
- public Builder addMediaDecoder(@NonNull MediaDecoder mediaDecoder) {
- mediaDecoders.add(mediaDecoder);
- return this;
- }
-
- /**
- * @see SvgMediaDecoder
- * @see GifMediaDecoder
- * @see ImageMediaDecoder
- * @since 2.0.0
- */
- @NonNull
- public Builder addMediaDecoders(@NonNull Iterable mediaDecoders) {
- for (MediaDecoder mediaDecoder : mediaDecoders) {
- this.mediaDecoders.add(requireNonNull(mediaDecoder));
- }
- return this;
- }
-
- /**
- * @see SvgMediaDecoder
- * @see GifMediaDecoder
- * @see ImageMediaDecoder
- * @since 2.0.0
- */
- @NonNull
- public Builder addMediaDecoders(MediaDecoder... mediaDecoders) {
-
- final int length = mediaDecoders != null
- ? mediaDecoders.length
- : 0;
-
- if (length > 0) {
- for (int i = 0; i < length; i++) {
- this.mediaDecoders.add(requireNonNull(mediaDecoders[i]));
- }
- }
-
- return this;
- }
-
- @NonNull
- public AsyncDrawableLoader build() {
-
- // I think we should deprecate this...
- if (resources == null) {
- resources = Resources.getSystem();
- }
-
- if (executorService == null) {
- // @since 2.0.0 we are using newCachedThreadPool instead
- // of `okHttpClient.dispatcher().executorService()`
- executorService = Executors.newCachedThreadPool();
- }
-
- // @since 2.0.0
- // put default scheme handlers (to mimic previous behavior)
- // remove in 3.0.0 with plugins
- if (schemeHandlers.size() == 0) {
- if (client == null) {
- client = new OkHttpClient();
- }
- addSchemeHandler(NetworkSchemeHandler.create(client));
- addSchemeHandler(FileSchemeHandler.createWithAssets(resources.getAssets()));
- addSchemeHandler(DataUriSchemeHandler.create());
- }
-
- // add default media decoders if not specified
- // remove in 3.0.0 with plugins
- if (mediaDecoders.size() == 0) {
- mediaDecoders.add(SvgMediaDecoder.create(resources));
- mediaDecoders.add(GifMediaDecoder.create(true));
- mediaDecoders.add(ImageMediaDecoder.create(resources));
- }
-
- return new AsyncDrawableLoader(this);
- }
- }
-
- // @since 2.0.0
- @NonNull
- private static T requireNonNull(@Nullable T t) {
- if (t == null) {
- throw new NullPointerException();
- }
- return t;
- }
-}
diff --git a/markwon-image-loader/src/main/java/ru/noties/markwon/il/DataUri.java b/markwon-image-loader/src/main/java/ru/noties/markwon/il/DataUri.java
deleted file mode 100644
index 697b7b2e..00000000
--- a/markwon-image-loader/src/main/java/ru/noties/markwon/il/DataUri.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package ru.noties.markwon.il;
-
-import android.support.annotation.Nullable;
-
-public class DataUri {
-
- private final String contentType;
- private final boolean base64;
- private final String data;
-
- public DataUri(@Nullable String contentType, boolean base64, @Nullable String data) {
- this.contentType = contentType;
- this.base64 = base64;
- this.data = data;
- }
-
- @Nullable
- public String contentType() {
- return contentType;
- }
-
- public boolean base64() {
- return base64;
- }
-
- @Nullable
- public String data() {
- return data;
- }
-
- @Override
- public String toString() {
- return "DataUri{" +
- "contentType='" + contentType + '\'' +
- ", base64=" + base64 +
- ", data='" + data + '\'' +
- '}';
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- DataUri dataUri = (DataUri) o;
-
- if (base64 != dataUri.base64) return false;
- if (contentType != null ? !contentType.equals(dataUri.contentType) : dataUri.contentType != null)
- return false;
- return data != null ? data.equals(dataUri.data) : dataUri.data == null;
- }
-
- @Override
- public int hashCode() {
- int result = contentType != null ? contentType.hashCode() : 0;
- result = 31 * result + (base64 ? 1 : 0);
- result = 31 * result + (data != null ? data.hashCode() : 0);
- return result;
- }
-}
diff --git a/markwon-image-loader/src/main/java/ru/noties/markwon/il/DataUriDecoder.java b/markwon-image-loader/src/main/java/ru/noties/markwon/il/DataUriDecoder.java
deleted file mode 100644
index ffb0d840..00000000
--- a/markwon-image-loader/src/main/java/ru/noties/markwon/il/DataUriDecoder.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package ru.noties.markwon.il;
-
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.text.TextUtils;
-import android.util.Base64;
-
-public abstract class DataUriDecoder {
-
- @Nullable
- public abstract byte[] decode(@NonNull DataUri dataUri);
-
- @NonNull
- public static DataUriDecoder create() {
- return new Impl();
- }
-
- static class Impl extends DataUriDecoder {
-
- @Nullable
- @Override
- public byte[] decode(@NonNull DataUri dataUri) {
-
- final String data = dataUri.data();
-
- if (!TextUtils.isEmpty(data)) {
- try {
- if (dataUri.base64()) {
- return Base64.decode(data.getBytes("UTF-8"), Base64.DEFAULT);
- } else {
- return data.getBytes("UTF-8");
- }
- } catch (Throwable t) {
- return null;
- }
- } else {
- return null;
- }
- }
- }
-}
diff --git a/markwon-image-loader/src/main/java/ru/noties/markwon/il/DataUriParser.java b/markwon-image-loader/src/main/java/ru/noties/markwon/il/DataUriParser.java
deleted file mode 100644
index 63744a42..00000000
--- a/markwon-image-loader/src/main/java/ru/noties/markwon/il/DataUriParser.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package ru.noties.markwon.il;
-
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-
-public abstract class DataUriParser {
-
- @Nullable
- public abstract DataUri parse(@NonNull String input);
-
-
- @NonNull
- public static DataUriParser create() {
- return new Impl();
- }
-
- static class Impl extends DataUriParser {
-
- @Nullable
- @Override
- public DataUri parse(@NonNull String input) {
-
- final int index = input.indexOf(',');
- // we expect exactly one comma
- if (index < 0) {
- return null;
- }
-
- final String contentType;
- final boolean base64;
-
- if (index > 0) {
- final String part = input.substring(0, index);
- final String[] parts = part.split(";");
- final int length = parts.length;
- if (length > 0) {
- // if one: either content-type or base64
- if (length == 1) {
- final String value = parts[0];
- if ("base64".equals(value)) {
- contentType = null;
- base64 = true;
- } else {
- contentType = value.indexOf('/') > -1
- ? value
- : null;
- base64 = false;
- }
- } else {
- contentType = parts[0].indexOf('/') > -1
- ? parts[0]
- : null;
- base64 = "base64".equals(parts[length - 1]);
- }
- } else {
- contentType = null;
- base64 = false;
- }
- } else {
- contentType = null;
- base64 = false;
- }
-
- final String data;
- if (index < input.length()) {
- final String value = input.substring(index + 1, input.length()).replaceAll("\n", "");
- if (value.length() == 0) {
- data = null;
- } else {
- data = value;
- }
- } else {
- data = null;
- }
-
- return new DataUri(contentType, base64, data);
- }
- }
-}
diff --git a/markwon-image-loader/src/main/java/ru/noties/markwon/il/DataUriSchemeHandler.java b/markwon-image-loader/src/main/java/ru/noties/markwon/il/DataUriSchemeHandler.java
deleted file mode 100644
index c70ea863..00000000
--- a/markwon-image-loader/src/main/java/ru/noties/markwon/il/DataUriSchemeHandler.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package ru.noties.markwon.il;
-
-import android.net.Uri;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-
-import java.io.ByteArrayInputStream;
-import java.util.Collection;
-import java.util.Collections;
-
-/**
- * @since 2.0.0
- */
-public class DataUriSchemeHandler extends SchemeHandler {
-
- @NonNull
- public static DataUriSchemeHandler create() {
- return new DataUriSchemeHandler(DataUriParser.create(), DataUriDecoder.create());
- }
-
- private static final String START = "data:";
-
- private final DataUriParser uriParser;
- private final DataUriDecoder uriDecoder;
-
- @SuppressWarnings("WeakerAccess")
- DataUriSchemeHandler(@NonNull DataUriParser uriParser, @NonNull DataUriDecoder uriDecoder) {
- this.uriParser = uriParser;
- this.uriDecoder = uriDecoder;
- }
-
- @Nullable
- @Override
- public ImageItem handle(@NonNull String raw, @NonNull Uri uri) {
-
- if (!raw.startsWith(START)) {
- return null;
- }
-
- String part = raw.substring(START.length());
-
- // this part is added to support `data://` with which this functionality was released
- if (part.startsWith("//")) {
- part = part.substring(2);
- }
-
- final DataUri dataUri = uriParser.parse(part);
- if (dataUri == null) {
- return null;
- }
-
- final byte[] bytes = uriDecoder.decode(dataUri);
- if (bytes == null) {
- return null;
- }
-
- return new ImageItem(
- dataUri.contentType(),
- new ByteArrayInputStream(bytes),
- null
- );
- }
-
- @Override
- public void cancel(@NonNull String raw) {
- // no op
- }
-
- @NonNull
- @Override
- public Collection schemes() {
- return Collections.singleton("data");
- }
-}
diff --git a/markwon-image-loader/src/main/java/ru/noties/markwon/il/DrawableUtils.java b/markwon-image-loader/src/main/java/ru/noties/markwon/il/DrawableUtils.java
deleted file mode 100644
index f2aef636..00000000
--- a/markwon-image-loader/src/main/java/ru/noties/markwon/il/DrawableUtils.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package ru.noties.markwon.il;
-
-import android.graphics.drawable.Drawable;
-import android.support.annotation.NonNull;
-
-abstract class DrawableUtils {
-
- static void intrinsicBounds(@NonNull Drawable drawable) {
- drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
- }
-
- private DrawableUtils() {}
-}
diff --git a/markwon-image-loader/src/main/java/ru/noties/markwon/il/FileSchemeHandler.java b/markwon-image-loader/src/main/java/ru/noties/markwon/il/FileSchemeHandler.java
deleted file mode 100644
index 437bbf7a..00000000
--- a/markwon-image-loader/src/main/java/ru/noties/markwon/il/FileSchemeHandler.java
+++ /dev/null
@@ -1,109 +0,0 @@
-package ru.noties.markwon.il;
-
-import android.content.res.AssetManager;
-import android.net.Uri;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * @since 2.0.0
- */
-public class FileSchemeHandler extends SchemeHandler {
-
- @NonNull
- public static FileSchemeHandler createWithAssets(@NonNull AssetManager assetManager) {
- return new FileSchemeHandler(assetManager);
- }
-
- @NonNull
- public static FileSchemeHandler create() {
- return new FileSchemeHandler(null);
- }
-
- private static final String FILE_ANDROID_ASSETS = "android_asset";
-
- @Nullable
- private final AssetManager assetManager;
-
- @SuppressWarnings("WeakerAccess")
- FileSchemeHandler(@Nullable AssetManager assetManager) {
- this.assetManager = assetManager;
- }
-
- @Nullable
- @Override
- public ImageItem handle(@NonNull String raw, @NonNull 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 ImageItem out;
-
- InputStream inputStream = null;
-
- final boolean assets = FILE_ANDROID_ASSETS.equals(segments.get(0));
- final String fileName = uri.getLastPathSegment();
-
- if (assets) {
-
- // no handling of assets here if we have no assetsManager
- if (assetManager != null) {
-
- 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
-
- try {
- inputStream = assetManager.open(path.toString());
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- } else {
- try {
- inputStream = new BufferedInputStream(new FileInputStream(new File(uri.getPath())));
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- }
- }
-
- if (inputStream != null) {
- out = new ImageItem(fileName, inputStream, fileName);
- } else {
- out = null;
- }
-
- return out;
- }
-
- @Override
- public void cancel(@NonNull String raw) {
- // no op
- }
-
- @NonNull
- @Override
- public Collection schemes() {
- return Collections.singleton("file");
- }
-}
diff --git a/markwon-image-loader/src/main/java/ru/noties/markwon/il/GifMediaDecoder.java b/markwon-image-loader/src/main/java/ru/noties/markwon/il/GifMediaDecoder.java
deleted file mode 100644
index 8342e7d5..00000000
--- a/markwon-image-loader/src/main/java/ru/noties/markwon/il/GifMediaDecoder.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package ru.noties.markwon.il;
-
-import android.graphics.drawable.Drawable;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-import pl.droidsonroids.gif.GifDrawable;
-
-/**
- * @since 1.1.0
- */
-@SuppressWarnings("WeakerAccess")
-public class GifMediaDecoder extends MediaDecoder {
-
- protected static final String CONTENT_TYPE_GIF = "image/gif";
- protected static final String FILE_EXTENSION_GIF = ".gif";
-
- @NonNull
- public static GifMediaDecoder create(boolean autoPlayGif) {
- return new GifMediaDecoder(autoPlayGif);
- }
-
- private final boolean autoPlayGif;
-
- protected GifMediaDecoder(boolean autoPlayGif) {
- this.autoPlayGif = autoPlayGif;
- }
-
- @Override
- public boolean canDecodeByContentType(@Nullable String contentType) {
- return CONTENT_TYPE_GIF.equals(contentType);
- }
-
- @Override
- public boolean canDecodeByFileName(@NonNull String fileName) {
- return fileName.endsWith(FILE_EXTENSION_GIF);
- }
-
- @Nullable
- @Override
- public Drawable decode(@NonNull InputStream inputStream) {
-
- Drawable out = null;
-
- final byte[] bytes = readBytes(inputStream);
- if (bytes != null) {
- try {
- out = newGifDrawable(bytes);
- DrawableUtils.intrinsicBounds(out);
-
- if (!autoPlayGif) {
- ((GifDrawable) out).pause();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- return out;
- }
-
- @NonNull
- protected Drawable newGifDrawable(@NonNull byte[] bytes) throws IOException {
- return new GifDrawable(bytes);
- }
-
- @Nullable
- protected static byte[] readBytes(@NonNull InputStream stream) {
-
- byte[] out = null;
-
- try {
- final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- final int length = 1024 * 8;
- final byte[] buffer = new byte[length];
- int read;
- while ((read = stream.read(buffer, 0, length)) != -1) {
- outputStream.write(buffer, 0, read);
- }
- out = outputStream.toByteArray();
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- return out;
- }
-}
diff --git a/markwon-image-loader/src/main/java/ru/noties/markwon/il/ImageItem.java b/markwon-image-loader/src/main/java/ru/noties/markwon/il/ImageItem.java
deleted file mode 100644
index 3ac9e9ec..00000000
--- a/markwon-image-loader/src/main/java/ru/noties/markwon/il/ImageItem.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package ru.noties.markwon.il;
-
-import android.support.annotation.Nullable;
-
-import java.io.InputStream;
-
-/**
- * @since 2.0.0
- */
-public class ImageItem {
-
- private final String contentType;
- private final InputStream inputStream;
- private final String fileName;
-
- public ImageItem(
- @Nullable String contentType,
- @Nullable InputStream inputStream,
- @Nullable String fileName) {
- this.contentType = contentType;
- this.inputStream = inputStream;
- this.fileName = fileName;
- }
-
- @Nullable
- public String contentType() {
- return contentType;
- }
-
- @Nullable
- public InputStream inputStream() {
- return inputStream;
- }
-
- @Nullable
- public String fileName() {
- return fileName;
- }
-}
diff --git a/markwon-image-loader/src/main/java/ru/noties/markwon/il/ImageMediaDecoder.java b/markwon-image-loader/src/main/java/ru/noties/markwon/il/ImageMediaDecoder.java
deleted file mode 100644
index c36545ea..00000000
--- a/markwon-image-loader/src/main/java/ru/noties/markwon/il/ImageMediaDecoder.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package ru.noties.markwon.il;
-
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-
-import java.io.InputStream;
-
-/**
- * This class can be used as the last {@link MediaDecoder} to _try_ to handle all rest cases.
- * Here we just assume that supplied InputStream is of image type and try to decode it.
- *
- * @since 1.1.0
- */
-public class ImageMediaDecoder extends MediaDecoder {
-
- @NonNull
- public static ImageMediaDecoder create(@NonNull Resources resources) {
- return new ImageMediaDecoder(resources);
- }
-
- private final Resources resources;
-
- @SuppressWarnings("WeakerAccess")
- ImageMediaDecoder(Resources resources) {
- this.resources = resources;
- }
-
- @Override
- public boolean canDecodeByContentType(@Nullable String contentType) {
- return true;
- }
-
- @Override
- public boolean canDecodeByFileName(@NonNull String fileName) {
- return true;
- }
-
- @Nullable
- @Override
- public Drawable decode(@NonNull InputStream inputStream) {
-
- final Drawable out;
-
- // absolutely not optimal... thing
- final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
- if (bitmap != null) {
- out = new BitmapDrawable(resources, bitmap);
- DrawableUtils.intrinsicBounds(out);
- } else {
- out = null;
- }
-
- return out;
- }
-}
diff --git a/markwon-image-loader/src/main/java/ru/noties/markwon/il/MediaDecoder.java b/markwon-image-loader/src/main/java/ru/noties/markwon/il/MediaDecoder.java
deleted file mode 100644
index 294b716b..00000000
--- a/markwon-image-loader/src/main/java/ru/noties/markwon/il/MediaDecoder.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package ru.noties.markwon.il;
-
-import android.graphics.drawable.Drawable;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-
-import java.io.InputStream;
-
-/**
- * @since 1.1.0
- */
-public abstract class MediaDecoder {
-
- public abstract boolean canDecodeByContentType(@Nullable String contentType);
-
- public abstract boolean canDecodeByFileName(@NonNull String fileName);
-
- @Nullable
- public abstract Drawable decode(@NonNull InputStream inputStream);
-}
diff --git a/markwon-image-loader/src/main/java/ru/noties/markwon/il/NetworkSchemeHandler.java b/markwon-image-loader/src/main/java/ru/noties/markwon/il/NetworkSchemeHandler.java
deleted file mode 100644
index d87c4019..00000000
--- a/markwon-image-loader/src/main/java/ru/noties/markwon/il/NetworkSchemeHandler.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package ru.noties.markwon.il;
-
-import android.net.Uri;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-
-import okhttp3.Call;
-import okhttp3.OkHttpClient;
-import okhttp3.Request;
-import okhttp3.Response;
-import okhttp3.ResponseBody;
-
-/**
- * @since 2.0.0
- */
-public class NetworkSchemeHandler extends SchemeHandler {
-
- @NonNull
- public static NetworkSchemeHandler create(@NonNull OkHttpClient client) {
- return new NetworkSchemeHandler(client);
- }
-
- private static final String HEADER_CONTENT_TYPE = "Content-Type";
-
- private final OkHttpClient client;
-
- @SuppressWarnings("WeakerAccess")
- NetworkSchemeHandler(@NonNull OkHttpClient client) {
- this.client = client;
- }
-
- @Nullable
- @Override
- public ImageItem handle(@NonNull String raw, @NonNull Uri uri) {
-
- ImageItem out = null;
-
- final Request request = new Request.Builder()
- .url(raw)
- .tag(raw)
- .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 contentType = response.header(HEADER_CONTENT_TYPE);
- out = new ImageItem(contentType, inputStream, null);
- }
- }
- }
-
- return out;
- }
-
- @Override
- public void cancel(@NonNull String raw) {
- final List calls = client.dispatcher().queuedCalls();
- if (calls != null) {
- for (Call call : calls) {
- if (!call.isCanceled()) {
- if (raw.equals(call.request().tag())) {
- call.cancel();
- }
- }
- }
- }
- }
-
- @NonNull
- @Override
- public Collection schemes() {
- return Arrays.asList("http", "https");
- }
-}
diff --git a/markwon-image-loader/src/main/java/ru/noties/markwon/il/SchemeHandler.java b/markwon-image-loader/src/main/java/ru/noties/markwon/il/SchemeHandler.java
deleted file mode 100644
index 6d8a44d1..00000000
--- a/markwon-image-loader/src/main/java/ru/noties/markwon/il/SchemeHandler.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package ru.noties.markwon.il;
-
-import android.net.Uri;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-
-import java.util.Collection;
-
-/**
- * @since 2.0.0
- */
-public abstract class SchemeHandler {
-
- @Nullable
- public abstract ImageItem handle(@NonNull String raw, @NonNull Uri uri);
-
- public abstract void cancel(@NonNull String raw);
-
- /**
- * Will be called only once during initialization, should return schemes that are
- * handled by this handler
- */
- @NonNull
- public abstract Collection schemes();
-}
diff --git a/markwon-image-loader/src/main/java/ru/noties/markwon/il/SvgMediaDecoder.java b/markwon-image-loader/src/main/java/ru/noties/markwon/il/SvgMediaDecoder.java
deleted file mode 100644
index ff32255a..00000000
--- a/markwon-image-loader/src/main/java/ru/noties/markwon/il/SvgMediaDecoder.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package ru.noties.markwon.il;
-
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-
-import com.caverock.androidsvg.SVG;
-import com.caverock.androidsvg.SVGParseException;
-
-import java.io.InputStream;
-
-/**
- * @since 1.1.0
- */
-public class SvgMediaDecoder extends MediaDecoder {
-
- private static final String CONTENT_TYPE_SVG = "image/svg+xml";
- private static final String FILE_EXTENSION_SVG = ".svg";
-
- @NonNull
- public static SvgMediaDecoder create(@NonNull Resources resources) {
- return new SvgMediaDecoder(resources);
- }
-
- private final Resources resources;
-
- @SuppressWarnings("WeakerAccess")
- SvgMediaDecoder(Resources resources) {
- this.resources = resources;
- }
-
- @Override
- public boolean canDecodeByContentType(@Nullable String contentType) {
- return contentType != null && contentType.startsWith(CONTENT_TYPE_SVG);
- }
-
- @Override
- public boolean canDecodeByFileName(@NonNull String fileName) {
- return fileName.endsWith(FILE_EXTENSION_SVG);
- }
-
- @Nullable
- @Override
- public Drawable decode(@NonNull InputStream inputStream) {
-
- final Drawable out;
-
- SVG svg = null;
- try {
- svg = SVG.getFromInputStream(inputStream);
- } catch (SVGParseException e) {
- e.printStackTrace();
- }
-
- if (svg == null) {
- out = null;
- } else {
-
- final float w = svg.getDocumentWidth();
- final float h = svg.getDocumentHeight();
- final float density = resources.getDisplayMetrics().density;
-
- final int width = (int) (w * density + .5F);
- final int height = (int) (h * density + .5F);
-
- final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444);
- final Canvas canvas = new Canvas(bitmap);
- canvas.scale(density, density);
- svg.renderToCanvas(canvas);
-
- out = new BitmapDrawable(resources, bitmap);
- DrawableUtils.intrinsicBounds(out);
- }
-
- return out;
- }
-}
diff --git a/markwon-image-loader/src/test/java/ru/noties/markwon/il/DataUriParserTest.java b/markwon-image-loader/src/test/java/ru/noties/markwon/il/DataUriParserTest.java
deleted file mode 100644
index 6de01af5..00000000
--- a/markwon-image-loader/src/test/java/ru/noties/markwon/il/DataUriParserTest.java
+++ /dev/null
@@ -1,119 +0,0 @@
-package ru.noties.markwon.il;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-
-@RunWith(RobolectricTestRunner.class)
-@Config(manifest = Config.NONE)
-public class DataUriParserTest {
-
- private DataUriParser.Impl impl;
-
- @Before
- public void before() {
- impl = new DataUriParser.Impl();
- }
-
- @Test
- public void test() {
-
- final Map data = new LinkedHashMap() {{
- put(",", new DataUri(null, false, null));
- put("image/svg+xml;base64,!@#$%^&*(", new DataUri("image/svg+xml", true, "!@#$%^&*("));
- put("text/vnd-example+xyz;foo=bar;base64,R0lGODdh", new DataUri("text/vnd-example+xyz", true, "R0lGODdh"));
- put("text/plain;charset=UTF-8;page=21,the%20data:1234,5678", new DataUri("text/plain", false, "the%20data:1234,5678"));
- }};
-
- for (Map.Entry entry : data.entrySet()) {
- assertEquals(entry.getKey(), entry.getValue(), impl.parse(entry.getKey()));
- }
- }
-
- @Test
- public void data_new_lines_are_ignored() {
-
- final String input = "image/png;base64,iVBORw0KGgoAAA\n" +
- "ANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4\n" +
- "//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU\n" +
- "5ErkJggg==";
-
- assertEquals(
- new DataUri("image/png", true, "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="),
- impl.parse(input)
- );
- }
-
- @Test
- public void no_comma_returns_null() {
-
- final String[] inputs = {
- "",
- "what-ever",
- ";;;;;;;",
- "some crazy data"
- };
-
- for (String input : inputs) {
- assertNull(input, impl.parse(input));
- }
- }
-
- @Test
- public void two_commas() {
- final String input = ",,"; // <- second one would be considered data...
- assertEquals(
- input,
- new DataUri(null, false, ","),
- impl.parse(input)
- );
- }
-
- @Test
- public void more_commas() {
- final String input = "first,second,third"; // <- first is just a value (will be ignored)
- assertEquals(
- input,
- new DataUri(null, false, "second,third"),
- impl.parse(input)
- );
- }
-
- @Test
- public void base64_no_content_type() {
- final String input = ";base64,12345";
- assertEquals(
- input,
- new DataUri(null, true, "12345"),
- impl.parse(input)
- );
- }
-
- @Test
- public void not_base64_no_content_type() {
- final String input = ",qweRTY";
- assertEquals(
- input,
- new DataUri(null, false, "qweRTY"),
- impl.parse(input)
- );
- }
-
- @Test
- public void content_type_data_no_base64() {
- final String input = "image/png,aSdFg";
- assertEquals(
- input,
- new DataUri("image/png", false, "aSdFg"),
- impl.parse(input)
- );
- }
-}
\ No newline at end of file
diff --git a/markwon-image-loader/src/test/java/ru/noties/markwon/il/DataUriSchemeHandlerTest.java b/markwon-image-loader/src/test/java/ru/noties/markwon/il/DataUriSchemeHandlerTest.java
deleted file mode 100644
index 1473744a..00000000
--- a/markwon-image-loader/src/test/java/ru/noties/markwon/il/DataUriSchemeHandlerTest.java
+++ /dev/null
@@ -1,112 +0,0 @@
-package ru.noties.markwon.il;
-
-import android.net.Uri;
-import android.support.annotation.NonNull;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Scanner;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-@RunWith(RobolectricTestRunner.class)
-@Config(manifest = Config.NONE)
-public class DataUriSchemeHandlerTest {
-
- private DataUriSchemeHandler handler;
-
- @Before
- public void before() {
- handler = DataUriSchemeHandler.create();
- }
-
- @Test
- public void scheme_specific_part_is_empty() {
- assertNull(handler.handle("data:", Uri.parse("data:")));
- }
-
- @Test
- public void data_uri_is_empty() {
- assertNull(handler.handle("data://whatever", Uri.parse("data://whatever")));
- }
-
- @Test
- public void no_data() {
- assertNull(handler.handle("data://,", Uri.parse("data://,")));
- }
-
- @Test
- public void correct() {
-
- final class Item {
-
- final String contentType;
- final String data;
-
- Item(String contentType, String data) {
- this.contentType = contentType;
- this.data = data;
- }
- }
-
- final Map expected = new HashMap() {{
- put("data://text/plain;,123", new Item("text/plain", "123"));
- put("data://image/svg+xml;base64,MTIz", new Item("image/svg+xml", "123"));
- }};
-
- for (Map.Entry entry : expected.entrySet()) {
- final ImageItem item = handler.handle(entry.getKey(), Uri.parse(entry.getKey()));
- assertNotNull(entry.getKey(), item);
- assertEquals(entry.getKey(), entry.getValue().contentType, item.contentType());
- assertEquals(entry.getKey(), entry.getValue().data, readStream(item.inputStream()));
- }
- }
-
- @Test
- public void correct_real() {
-
- final class Item {
-
- final String contentType;
- final String data;
-
- Item(String contentType, String data) {
- this.contentType = contentType;
- this.data = data;
- }
- }
-
- final Map expected = new HashMap() {{
- put("data:text/plain;,123", new Item("text/plain", "123"));
- put("data:image/svg+xml;base64,MTIz", new Item("image/svg+xml", "123"));
- }};
-
- for (Map.Entry entry : expected.entrySet()) {
- final ImageItem item = handler.handle(entry.getKey(), Uri.parse(entry.getKey()));
- assertNotNull(entry.getKey(), item);
- assertEquals(entry.getKey(), entry.getValue().contentType, item.contentType());
- assertEquals(entry.getKey(), entry.getValue().data, readStream(item.inputStream()));
- }
- }
-
- @NonNull
- private static String readStream(@NonNull InputStream stream) {
- try {
- final Scanner scanner = new Scanner(stream, "UTF-8").useDelimiter("\\A");
- return scanner.hasNext()
- ? scanner.next()
- : "";
- } catch (Throwable t) {
- throw new RuntimeException(t);
- }
- }
-}
\ No newline at end of file
diff --git a/markwon-syntax-highlight/src/main/java/ru/noties/markwon/syntax/Prism4jThemeDarkula.java b/markwon-syntax-highlight/src/main/java/ru/noties/markwon/syntax/Prism4jThemeDarkula.java
index 9a941951..13bfe48b 100644
--- a/markwon-syntax-highlight/src/main/java/ru/noties/markwon/syntax/Prism4jThemeDarkula.java
+++ b/markwon-syntax-highlight/src/main/java/ru/noties/markwon/syntax/Prism4jThemeDarkula.java
@@ -16,6 +16,10 @@ public class Prism4jThemeDarkula extends Prism4jThemeBase {
return new Prism4jThemeDarkula(0xFF2d2d2d);
}
+ /**
+ * @param background color
+ * @since 3.0.0
+ */
@NonNull
public static Prism4jThemeDarkula create(@ColorInt int background) {
return new Prism4jThemeDarkula(background);
diff --git a/markwon/build.gradle b/markwon/build.gradle
index fc3dc8ff..3cb54118 100644
--- a/markwon/build.gradle
+++ b/markwon/build.gradle
@@ -15,9 +15,6 @@ android {
dependencies {
- api project(':markwon-html-parser-api')
- api project(':markwon-html-parser-impl')
-
deps.with {
api it['support-annotations']
api it['commonmark']
diff --git a/markwon/src/main/java/ru/noties/markwon/MarkwonConfiguration.java b/markwon/src/main/java/ru/noties/markwon/MarkwonConfiguration.java
index 1f6e2216..7c9fad92 100644
--- a/markwon/src/main/java/ru/noties/markwon/MarkwonConfiguration.java
+++ b/markwon/src/main/java/ru/noties/markwon/MarkwonConfiguration.java
@@ -3,12 +3,12 @@ package ru.noties.markwon;
import android.content.Context;
import android.support.annotation.NonNull;
-import ru.noties.markwon.html.api.MarkwonHtmlParser;
+import ru.noties.markwon.html.MarkwonHtmlParser;
+import ru.noties.markwon.html.MarkwonHtmlRenderer;
import ru.noties.markwon.image.AsyncDrawableLoader;
import ru.noties.markwon.image.AsyncDrawableLoaderNoOp;
import ru.noties.markwon.renderer.ImageSizeResolver;
import ru.noties.markwon.renderer.ImageSizeResolverDef;
-import ru.noties.markwon.renderer.html2.MarkwonHtmlRenderer;
import ru.noties.markwon.spans.LinkSpan;
import ru.noties.markwon.spans.MarkwonTheme;
@@ -37,7 +37,6 @@ public class MarkwonConfiguration {
private final UrlProcessor urlProcessor;
private final ImageSizeResolver imageSizeResolver;
private final SpannableFactory factory; // @since 1.1.0
- private final boolean softBreakAddsNewLine; // @since 1.1.1
private final MarkwonHtmlParser htmlParser; // @since 2.0.0
private final MarkwonHtmlRenderer htmlRenderer; // @since 2.0.0
private final boolean htmlAllowNonClosedTags; // @since 2.0.0
@@ -50,7 +49,6 @@ public class MarkwonConfiguration {
this.urlProcessor = builder.urlProcessor;
this.imageSizeResolver = builder.imageSizeResolver;
this.factory = builder.factory;
- this.softBreakAddsNewLine = builder.softBreakAddsNewLine;
this.htmlParser = builder.htmlParser;
this.htmlRenderer = builder.htmlRenderer;
this.htmlAllowNonClosedTags = builder.htmlAllowNonClosedTags;
@@ -99,15 +97,6 @@ public class MarkwonConfiguration {
return factory;
}
- /**
- * @return a flag indicating if soft break should be treated as a hard
- * break and thus adding a new line instead of adding a white space
- * @since 1.1.1
- */
- public boolean softBreakAddsNewLine() {
- return softBreakAddsNewLine;
- }
-
/**
* @since 2.0.0
*/
@@ -143,7 +132,6 @@ public class MarkwonConfiguration {
private UrlProcessor urlProcessor;
private ImageSizeResolver imageSizeResolver;
private SpannableFactory factory; // @since 1.1.0
- private boolean softBreakAddsNewLine; // @since 1.1.1
private MarkwonHtmlParser htmlParser; // @since 2.0.0
private MarkwonHtmlRenderer htmlRenderer; // @since 2.0.0
private boolean htmlAllowNonClosedTags; // @since 2.0.0
@@ -161,7 +149,6 @@ public class MarkwonConfiguration {
this.urlProcessor = configuration.urlProcessor;
this.imageSizeResolver = configuration.imageSizeResolver;
this.factory = configuration.factory;
- this.softBreakAddsNewLine = configuration.softBreakAddsNewLine;
this.htmlParser = configuration.htmlParser;
this.htmlRenderer = configuration.htmlRenderer;
this.htmlAllowNonClosedTags = configuration.htmlAllowNonClosedTags;
@@ -203,19 +190,6 @@ public class MarkwonConfiguration {
return this;
}
- /**
- * @param softBreakAddsNewLine a flag indicating if soft break should be treated as a hard
- * break and thus adding a new line instead of adding a white space
- * @return self
- * @see spec
- * @since 1.1.1
- */
- @NonNull
- public Builder softBreakAddsNewLine(boolean softBreakAddsNewLine) {
- this.softBreakAddsNewLine = softBreakAddsNewLine;
- return this;
- }
-
/**
* @since 2.0.0
*/
@@ -276,17 +250,12 @@ public class MarkwonConfiguration {
// @since 2.0.0
if (htmlParser == null) {
- try {
- // if impl artifact was excluded -> fallback to no-op implementation
- htmlParser = ru.noties.markwon.html.impl.MarkwonHtmlParserImpl.create();
- } catch (Throwable t) {
- htmlParser = MarkwonHtmlParser.noOp();
- }
+ htmlParser = MarkwonHtmlParser.noOp();
}
// @since 2.0.0
if (htmlRenderer == null) {
- htmlRenderer = MarkwonHtmlRenderer.create();
+ htmlRenderer = MarkwonHtmlRenderer.noOp();
}
return new MarkwonConfiguration(this);
diff --git a/markwon/src/main/java/ru/noties/markwon/SpannableFactory.java b/markwon/src/main/java/ru/noties/markwon/SpannableFactory.java
index 13a64cf4..3efec181 100644
--- a/markwon/src/main/java/ru/noties/markwon/SpannableFactory.java
+++ b/markwon/src/main/java/ru/noties/markwon/SpannableFactory.java
@@ -63,16 +63,4 @@ public interface SpannableFactory {
@NonNull MarkwonTheme theme,
@NonNull String destination,
@NonNull LinkSpan.Resolver resolver);
-
- // Currently used by HTML parser
- @Nullable
- Object superScript(@NonNull MarkwonTheme theme);
-
- // Currently used by HTML parser
- @Nullable
- Object subScript(@NonNull MarkwonTheme theme);
-
- // Currently used by HTML parser
- @Nullable
- Object underline();
}
diff --git a/markwon/src/main/java/ru/noties/markwon/SpannableFactoryDef.java b/markwon/src/main/java/ru/noties/markwon/SpannableFactoryDef.java
index 21074983..75726b2a 100644
--- a/markwon/src/main/java/ru/noties/markwon/SpannableFactoryDef.java
+++ b/markwon/src/main/java/ru/noties/markwon/SpannableFactoryDef.java
@@ -118,21 +118,4 @@ public class SpannableFactoryDef implements SpannableFactory {
public Object link(@NonNull MarkwonTheme theme, @NonNull String destination, @NonNull LinkSpan.Resolver resolver) {
return new LinkSpan(theme, destination, resolver);
}
-
- @Nullable
- @Override
- public Object superScript(@NonNull MarkwonTheme theme) {
- return new SuperScriptSpan(theme);
- }
-
- @Override
- public Object subScript(@NonNull MarkwonTheme theme) {
- return new SubScriptSpan(theme);
- }
-
- @Nullable
- @Override
- public Object underline() {
- return new UnderlineSpan();
- }
}
diff --git a/markwon-html-parser-api/src/main/java/ru/noties/markwon/html/api/HtmlTag.java b/markwon/src/main/java/ru/noties/markwon/html/HtmlTag.java
similarity index 98%
rename from markwon-html-parser-api/src/main/java/ru/noties/markwon/html/api/HtmlTag.java
rename to markwon/src/main/java/ru/noties/markwon/html/HtmlTag.java
index f3245876..fbe417e9 100644
--- a/markwon-html-parser-api/src/main/java/ru/noties/markwon/html/api/HtmlTag.java
+++ b/markwon/src/main/java/ru/noties/markwon/html/HtmlTag.java
@@ -1,4 +1,4 @@
-package ru.noties.markwon.html.api;
+package ru.noties.markwon.html;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
diff --git a/markwon-html-parser-api/src/main/java/ru/noties/markwon/html/api/MarkwonHtmlParser.java b/markwon/src/main/java/ru/noties/markwon/html/MarkwonHtmlParser.java
similarity index 92%
rename from markwon-html-parser-api/src/main/java/ru/noties/markwon/html/api/MarkwonHtmlParser.java
rename to markwon/src/main/java/ru/noties/markwon/html/MarkwonHtmlParser.java
index 8d168a72..01bea86a 100644
--- a/markwon-html-parser-api/src/main/java/ru/noties/markwon/html/api/MarkwonHtmlParser.java
+++ b/markwon/src/main/java/ru/noties/markwon/html/MarkwonHtmlParser.java
@@ -1,4 +1,4 @@
-package ru.noties.markwon.html.api;
+package ru.noties.markwon.html;
import android.support.annotation.NonNull;
@@ -34,7 +34,7 @@ public abstract class MarkwonHtmlParser {
* If you wish to keep them open (do not force close at the end of a
* document pass here {@link HtmlTag#NO_END}. Later non-closed tags
* can be detected by calling {@link HtmlTag#isClosed()}
- * @param action {@link FlushAction} to be called with resulting tags ({@link ru.noties.markwon.html.api.HtmlTag.Inline})
+ * @param action {@link FlushAction} to be called with resulting tags ({@link HtmlTag.Inline})
*/
public abstract void flushInlineTags(
int documentLength,
@@ -49,7 +49,7 @@ public abstract class MarkwonHtmlParser {
* If you wish to keep them open (do not force close at the end of a
* document pass here {@link HtmlTag#NO_END}. Later non-closed tags
* can be detected by calling {@link HtmlTag#isClosed()}
- * @param action {@link FlushAction} to be called with resulting tags ({@link ru.noties.markwon.html.api.HtmlTag.Block})
+ * @param action {@link FlushAction} to be called with resulting tags ({@link HtmlTag.Block})
*/
public abstract void flushBlockTags(
int documentLength,
diff --git a/markwon-html-parser-api/src/main/java/ru/noties/markwon/html/api/MarkwonHtmlParserNoOp.java b/markwon/src/main/java/ru/noties/markwon/html/MarkwonHtmlParserNoOp.java
similarity index 95%
rename from markwon-html-parser-api/src/main/java/ru/noties/markwon/html/api/MarkwonHtmlParserNoOp.java
rename to markwon/src/main/java/ru/noties/markwon/html/MarkwonHtmlParserNoOp.java
index 0a024865..3b49528a 100644
--- a/markwon-html-parser-api/src/main/java/ru/noties/markwon/html/api/MarkwonHtmlParserNoOp.java
+++ b/markwon/src/main/java/ru/noties/markwon/html/MarkwonHtmlParserNoOp.java
@@ -1,4 +1,4 @@
-package ru.noties.markwon.html.api;
+package ru.noties.markwon.html;
import android.support.annotation.NonNull;
diff --git a/markwon/src/main/java/ru/noties/markwon/html/MarkwonHtmlRenderer.java b/markwon/src/main/java/ru/noties/markwon/html/MarkwonHtmlRenderer.java
new file mode 100644
index 00000000..9e9d222f
--- /dev/null
+++ b/markwon/src/main/java/ru/noties/markwon/html/MarkwonHtmlRenderer.java
@@ -0,0 +1,30 @@
+package ru.noties.markwon.html;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
+import ru.noties.markwon.MarkwonConfiguration;
+import ru.noties.markwon.SpannableBuilder;
+
+/**
+ * @since 2.0.0
+ */
+public abstract class MarkwonHtmlRenderer {
+
+ /**
+ * @since 3.0.0
+ */
+ @NonNull
+ public static MarkwonHtmlRenderer noOp() {
+ return new MarkwonHtmlRendererNoOp();
+ }
+
+ public abstract void render(
+ @NonNull MarkwonConfiguration configuration,
+ @NonNull SpannableBuilder builder,
+ @NonNull MarkwonHtmlParser parser
+ );
+
+ @Nullable
+ public abstract TagHandler tagHandler(@NonNull String tagName);
+}
diff --git a/markwon/src/main/java/ru/noties/markwon/html/MarkwonHtmlRendererNoOp.java b/markwon/src/main/java/ru/noties/markwon/html/MarkwonHtmlRendererNoOp.java
new file mode 100644
index 00000000..7df5027c
--- /dev/null
+++ b/markwon/src/main/java/ru/noties/markwon/html/MarkwonHtmlRendererNoOp.java
@@ -0,0 +1,21 @@
+package ru.noties.markwon.html;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
+import ru.noties.markwon.MarkwonConfiguration;
+import ru.noties.markwon.SpannableBuilder;
+
+class MarkwonHtmlRendererNoOp extends MarkwonHtmlRenderer {
+
+ @Override
+ public void render(@NonNull MarkwonConfiguration configuration, @NonNull SpannableBuilder builder, @NonNull MarkwonHtmlParser parser) {
+
+ }
+
+ @Nullable
+ @Override
+ public TagHandler tagHandler(@NonNull String tagName) {
+ return null;
+ }
+}
diff --git a/markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/TagHandler.java b/markwon/src/main/java/ru/noties/markwon/html/TagHandler.java
similarity index 91%
rename from markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/TagHandler.java
rename to markwon/src/main/java/ru/noties/markwon/html/TagHandler.java
index bdf9b134..50af33d8 100644
--- a/markwon/src/main/java/ru/noties/markwon/renderer/html2/tag/TagHandler.java
+++ b/markwon/src/main/java/ru/noties/markwon/html/TagHandler.java
@@ -1,10 +1,9 @@
-package ru.noties.markwon.renderer.html2.tag;
+package ru.noties.markwon.html;
import android.support.annotation.NonNull;
import ru.noties.markwon.MarkwonConfiguration;
import ru.noties.markwon.SpannableBuilder;
-import ru.noties.markwon.html.api.HtmlTag;
public abstract class TagHandler {
diff --git a/markwon/src/main/java/ru/noties/markwon/renderer/html2/MarkwonHtmlRenderer.java b/markwon/src/main/java/ru/noties/markwon/renderer/html2/MarkwonHtmlRenderer.java
deleted file mode 100644
index b66045e6..00000000
--- a/markwon/src/main/java/ru/noties/markwon/renderer/html2/MarkwonHtmlRenderer.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package ru.noties.markwon.renderer.html2;
-
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-
-import ru.noties.markwon.SpannableBuilder;
-import ru.noties.markwon.MarkwonConfiguration;
-import ru.noties.markwon.html.api.MarkwonHtmlParser;
-import ru.noties.markwon.renderer.html2.tag.BlockquoteHandler;
-import ru.noties.markwon.renderer.html2.tag.EmphasisHandler;
-import ru.noties.markwon.renderer.html2.tag.HeadingHandler;
-import ru.noties.markwon.renderer.html2.tag.ImageHandler;
-import ru.noties.markwon.renderer.html2.tag.LinkHandler;
-import ru.noties.markwon.renderer.html2.tag.ListHandler;
-import ru.noties.markwon.renderer.html2.tag.StrikeHandler;
-import ru.noties.markwon.renderer.html2.tag.StrongEmphasisHandler;
-import ru.noties.markwon.renderer.html2.tag.SubScriptHandler;
-import ru.noties.markwon.renderer.html2.tag.SuperScriptHandler;
-import ru.noties.markwon.renderer.html2.tag.TagHandler;
-import ru.noties.markwon.renderer.html2.tag.UnderlineHandler;
-
-/**
- * @since 2.0.0
- */
-public abstract class MarkwonHtmlRenderer {
-
- public abstract void render(
- @NonNull MarkwonConfiguration configuration,
- @NonNull SpannableBuilder builder,
- @NonNull MarkwonHtmlParser parser
- );
-
- @Nullable
- public abstract TagHandler tagHandler(@NonNull String tagName);
-
- @NonNull
- public static MarkwonHtmlRenderer create() {
- return builderWithDefaults().build();
- }
-
- @NonNull
- public static Builder builderWithDefaults() {
-
- final EmphasisHandler emphasisHandler = new EmphasisHandler();
- final StrongEmphasisHandler strongEmphasisHandler = new StrongEmphasisHandler();
- final StrikeHandler strikeHandler = new StrikeHandler();
- final UnderlineHandler underlineHandler = new UnderlineHandler();
- final ListHandler listHandler = new ListHandler();
-
- return builder()
- .handler("i", emphasisHandler)
- .handler("em", emphasisHandler)
- .handler("cite", emphasisHandler)
- .handler("dfn", emphasisHandler)
- .handler("b", strongEmphasisHandler)
- .handler("strong", strongEmphasisHandler)
- .handler("sup", new SuperScriptHandler())
- .handler("sub", new SubScriptHandler())
- .handler("u", underlineHandler)
- .handler("ins", underlineHandler)
- .handler("del", strikeHandler)
- .handler("s", strikeHandler)
- .handler("strike", strikeHandler)
- .handler("a", new LinkHandler())
- .handler("ul", listHandler)
- .handler("ol", listHandler)
- .handler("img", ImageHandler.create())
- .handler("blockquote", new BlockquoteHandler())
- .handler("h1", new HeadingHandler(1))
- .handler("h2", new HeadingHandler(2))
- .handler("h3", new HeadingHandler(3))
- .handler("h4", new HeadingHandler(4))
- .handler("h5", new HeadingHandler(5))
- .handler("h6", new HeadingHandler(6));
- }
-
- @NonNull
- public static Builder builder() {
- return new Builder();
- }
-
- public static class Builder {
-
- private final Map tagHandlers = new HashMap<>(2);
-
- public Builder handler(@NonNull String tagName, @NonNull TagHandler tagHandler) {
- tagHandlers.put(tagName.toLowerCase(Locale.US), tagHandler);
- return this;
- }
-
- @NonNull
- public MarkwonHtmlRenderer build() {
- return new MarkwonHtmlRendererImpl(Collections.unmodifiableMap(tagHandlers));
- }
- }
-}
diff --git a/markwon/src/main/java/ru/noties/markwon/renderer/html2/MarkwonHtmlRendererImpl.java b/markwon/src/main/java/ru/noties/markwon/renderer/html2/MarkwonHtmlRendererImpl.java
deleted file mode 100644
index cc34f55b..00000000
--- a/markwon/src/main/java/ru/noties/markwon/renderer/html2/MarkwonHtmlRendererImpl.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package ru.noties.markwon.renderer.html2;
-
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-
-import java.util.List;
-import java.util.Map;
-
-import ru.noties.markwon.SpannableBuilder;
-import ru.noties.markwon.MarkwonConfiguration;
-import ru.noties.markwon.html.api.HtmlTag;
-import ru.noties.markwon.html.api.MarkwonHtmlParser;
-import ru.noties.markwon.renderer.html2.tag.TagHandler;
-
-class MarkwonHtmlRendererImpl extends MarkwonHtmlRenderer {
-
- private final Map tagHandlers;
-
- MarkwonHtmlRendererImpl(@NonNull Map tagHandlers) {
- this.tagHandlers = tagHandlers;
- }
-
- @Override
- public void render(
- @NonNull final MarkwonConfiguration configuration,
- @NonNull final SpannableBuilder builder,
- @NonNull MarkwonHtmlParser parser) {
-
- final int end;
- if (!configuration.htmlAllowNonClosedTags()) {
- end = HtmlTag.NO_END;
- } else {
- end = builder.length();
- }
-
- parser.flushInlineTags(end, new MarkwonHtmlParser.FlushAction() {
- @Override
- public void apply(@NonNull List tags) {
-
- TagHandler handler;
-
- for (HtmlTag.Inline inline : tags) {
-
- // if tag is not closed -> do not render
- if (!inline.isClosed()) {
- continue;
- }
-
- handler = tagHandler(inline.name());
- if (handler != null) {
- handler.handle(configuration, builder, inline);
- }
- }
- }
- });
-
- parser.flushBlockTags(end, new MarkwonHtmlParser.FlushAction() {
- @Override
- public void apply(@NonNull List tags) {
-
- TagHandler handler;
-
- for (HtmlTag.Block block : tags) {
-
- if (!block.isClosed()) {
- continue;
- }
-
- handler = tagHandler(block.name());
- if (handler != null) {
- handler.handle(configuration, builder, block);
- } else {
- // see if any of children can be handled
- apply(block.children());
- }
- }
- }
- });
-
- parser.reset();
- }
-
- @Nullable
- @Override
- public TagHandler tagHandler(@NonNull String tagName) {
- return tagHandlers.get(tagName);
- }
-}
diff --git a/markwon/src/test/java/ru/noties/markwon/renderer/MarkwonConfigurationTest.java b/markwon/src/test/java/ru/noties/markwon/renderer/MarkwonConfigurationTest.java
index 108df62d..11f539b3 100644
--- a/markwon/src/test/java/ru/noties/markwon/renderer/MarkwonConfigurationTest.java
+++ b/markwon/src/test/java/ru/noties/markwon/renderer/MarkwonConfigurationTest.java
@@ -7,7 +7,7 @@ import ru.noties.markwon.SpannableFactory;
import ru.noties.markwon.SyntaxHighlight;
import ru.noties.markwon.UrlProcessor;
import ru.noties.markwon.html.api.MarkwonHtmlParser;
-import ru.noties.markwon.renderer.html2.MarkwonHtmlRenderer;
+import ru.noties.markwon.html.MarkwonHtmlRenderer;
import ru.noties.markwon.image.AsyncDrawable;
import ru.noties.markwon.spans.LinkSpan;
import ru.noties.markwon.spans.MarkwonTheme;
diff --git a/settings.gradle b/settings.gradle
index 3a1678e4..ca458b18 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,3 +1,3 @@
rootProject.name = 'MarkwonProject'
include ':app', ':markwon', ':markwon-view', ':sample-custom-extension', ':sample-latex-math', ':markwon-image-svg', ':markwon-image-gif',
- ':markwon-syntax-highlight', ':markwon-html-parser-api', ':markwon-html-parser-impl'
+ ':markwon-syntax-highlight', ':markwon-html'