POC for plugin system
This commit is contained in:
		
							parent
							
								
									340ce5753c
								
							
						
					
					
						commit
						498c811987
					
				| @ -9,7 +9,7 @@ import android.util.AttributeSet; | ||||
| import android.view.View; | ||||
| 
 | ||||
| import ru.noties.markwon.R; | ||||
| import ru.noties.markwon.spans.TaskListDrawable; | ||||
| import ru.noties.markwon.tasklist.TaskListDrawable; | ||||
| 
 | ||||
| public class DebugCheckboxDrawableView extends View { | ||||
| 
 | ||||
|  | ||||
| @ -7,7 +7,7 @@ import ru.noties.markwon.renderer.ImageSize; | ||||
| import ru.noties.markwon.renderer.ImageSizeResolver; | ||||
| import ru.noties.markwon.spans.AsyncDrawable; | ||||
| import ru.noties.markwon.spans.AsyncDrawableSpan; | ||||
| import ru.noties.markwon.spans.SpannableTheme; | ||||
| import ru.noties.markwon.spans.MarkwonTheme; | ||||
| 
 | ||||
| public class GifAwareSpannableFactory extends SpannableFactoryDef { | ||||
| 
 | ||||
| @ -19,7 +19,7 @@ public class GifAwareSpannableFactory extends SpannableFactoryDef { | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object image(@NonNull SpannableTheme theme, @NonNull String destination, @NonNull AsyncDrawable.Loader loader, @NonNull ImageSizeResolver imageSizeResolver, @Nullable ImageSize imageSize, boolean replacementTextIsLink) { | ||||
|     public Object image(@NonNull MarkwonTheme theme, @NonNull String destination, @NonNull AsyncDrawable.Loader loader, @NonNull ImageSizeResolver imageSizeResolver, @Nullable ImageSize imageSize, boolean replacementTextIsLink) { | ||||
|         return new AsyncDrawableSpan( | ||||
|                 theme, | ||||
|                 new GifAwareAsyncDrawable( | ||||
|  | ||||
| @ -12,6 +12,9 @@ import android.widget.TextView; | ||||
| import javax.inject.Inject; | ||||
| 
 | ||||
| import ru.noties.debug.Debug; | ||||
| import ru.noties.markwon.core.CorePlugin; | ||||
| import ru.noties.markwon.tasklist.TaskListDrawable; | ||||
| import ru.noties.markwon.tasklist.TaskListPlugin; | ||||
| 
 | ||||
| public class MainActivity extends Activity { | ||||
| 
 | ||||
| @ -40,7 +43,7 @@ public class MainActivity extends Activity { | ||||
| 
 | ||||
|         themes.apply(this); | ||||
| 
 | ||||
|         // how can we obtain SpannableConfiguration after theme was applied? | ||||
|         // how can we obtain MarkwonConfiguration after theme was applied? | ||||
|         // as we inject `themes` we won't be able to inject configuration, as it requires theme set | ||||
| 
 | ||||
|         setContentView(R.layout.activity_main); | ||||
| @ -63,6 +66,16 @@ public class MainActivity extends Activity { | ||||
| 
 | ||||
|         appBarRenderer.render(appBarState()); | ||||
| 
 | ||||
|         if (true) { | ||||
|             final Markwon2 markwon2 = Markwon2.builder(this) | ||||
|                     .use(new CorePlugin()) | ||||
|                     .use(TaskListPlugin.create(new TaskListDrawable(0xffff0000, 0xffff0000, -1))) | ||||
|                     .build(); | ||||
|             final CharSequence markdown = markwon2.markdown("**hello _dear_** `code`\n\n- [ ] first\n- [x] second"); | ||||
|             textView.setText(markdown); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         markdownLoader.load(uri(), new MarkdownLoader.OnMarkdownTextLoaded() { | ||||
|             @Override | ||||
|             public void apply(final String text) { | ||||
|  | ||||
| @ -14,7 +14,7 @@ import javax.inject.Inject; | ||||
| 
 | ||||
| import ru.noties.debug.Debug; | ||||
| import ru.noties.markwon.spans.AsyncDrawable; | ||||
| import ru.noties.markwon.spans.SpannableTheme; | ||||
| import ru.noties.markwon.spans.MarkwonTheme; | ||||
| import ru.noties.markwon.syntax.Prism4jSyntaxHighlight; | ||||
| import ru.noties.markwon.syntax.Prism4jTheme; | ||||
| import ru.noties.markwon.syntax.Prism4jThemeDarkula; | ||||
| @ -87,11 +87,11 @@ public class MarkdownRenderer { | ||||
|                         0x20000000 | ||||
|                 ); | ||||
| 
 | ||||
|                 final SpannableConfiguration configuration = SpannableConfiguration.builder(context) | ||||
|                 final MarkwonConfiguration configuration = MarkwonConfiguration.builder(context) | ||||
|                         .asyncDrawableLoader(loader) | ||||
|                         .urlProcessor(urlProcessor) | ||||
|                         .syntaxHighlight(Prism4jSyntaxHighlight.create(prism4j, prism4jTheme)) | ||||
|                         .theme(SpannableTheme.builderWithDefaults(context) | ||||
|                         .theme(MarkwonTheme.builderWithDefaults(context) | ||||
|                                 .codeBackgroundColor(background) | ||||
|                                 .codeTextColor(prism4jTheme.textColor()) | ||||
|                                 .build()) | ||||
|  | ||||
| @ -209,4 +209,4 @@ Background of header table row | ||||
| 
 | ||||
| Drawable of task list item | ||||
| 
 | ||||
| <ThemeProperty name="taskListDrawable" type="android.graphics.drawable.Drawable" defaults="ru.noties.markwon.spans.TaskListDrawable" /> | ||||
| <ThemeProperty name="taskListDrawable" type="android.graphics.drawable.Drawable" defaults="ru.noties.markwon.tasklist.TaskListDrawable" /> | ||||
|  | ||||
| @ -3,27 +3,27 @@ package ru.noties.markwon.view.debug; | ||||
| import android.content.Context; | ||||
| import android.support.annotation.NonNull; | ||||
| 
 | ||||
| import ru.noties.markwon.SpannableConfiguration; | ||||
| import ru.noties.markwon.spans.SpannableTheme; | ||||
| import ru.noties.markwon.MarkwonConfiguration; | ||||
| import ru.noties.markwon.spans.MarkwonTheme; | ||||
| import ru.noties.markwon.view.IMarkwonView; | ||||
| 
 | ||||
| public class DebugConfigurationProvider implements IMarkwonView.ConfigurationProvider { | ||||
| 
 | ||||
|     private SpannableConfiguration cached; | ||||
|     private MarkwonConfiguration cached; | ||||
| 
 | ||||
|     @NonNull | ||||
|     @Override | ||||
|     public SpannableConfiguration provide(@NonNull Context context) { | ||||
|     public MarkwonConfiguration provide(@NonNull Context context) { | ||||
|         if (cached == null) { | ||||
|             cached = SpannableConfiguration.builder(context) | ||||
|             cached = MarkwonConfiguration.builder(context) | ||||
|                     .theme(debugTheme(context)) | ||||
|                     .build(); | ||||
|         } | ||||
|         return cached; | ||||
|     } | ||||
| 
 | ||||
|     private static SpannableTheme debugTheme(@NonNull Context context) { | ||||
|         return SpannableTheme.builderWithDefaults(context) | ||||
|     private static MarkwonTheme debugTheme(@NonNull Context context) { | ||||
|         return MarkwonTheme.builderWithDefaults(context) | ||||
|                 .blockQuoteColor(0xFFff0000) | ||||
|                 .codeBackgroundColor(0x40FF0000) | ||||
|                 .build(); | ||||
|  | ||||
| @ -4,19 +4,19 @@ import android.content.Context; | ||||
| import android.support.annotation.NonNull; | ||||
| import android.support.annotation.Nullable; | ||||
| 
 | ||||
| import ru.noties.markwon.SpannableConfiguration; | ||||
| import ru.noties.markwon.MarkwonConfiguration; | ||||
| 
 | ||||
| public interface IMarkwonView { | ||||
| 
 | ||||
|     interface ConfigurationProvider { | ||||
|         @NonNull | ||||
|         SpannableConfiguration provide(@NonNull Context context); | ||||
|         MarkwonConfiguration provide(@NonNull Context context); | ||||
|     } | ||||
| 
 | ||||
|     void setConfigurationProvider(@NonNull ConfigurationProvider provider); | ||||
| 
 | ||||
|     void setMarkdown(@Nullable String markdown); | ||||
|     void setMarkdown(@Nullable SpannableConfiguration configuration, @Nullable String markdown); | ||||
|     void setMarkdown(@Nullable MarkwonConfiguration configuration, @Nullable String markdown); | ||||
| 
 | ||||
|     @Nullable | ||||
|     String getMarkdown(); | ||||
|  | ||||
| @ -7,7 +7,7 @@ import android.support.annotation.Nullable; | ||||
| import android.util.AttributeSet; | ||||
| import android.widget.TextView; | ||||
| 
 | ||||
| import ru.noties.markwon.SpannableConfiguration; | ||||
| import ru.noties.markwon.MarkwonConfiguration; | ||||
| 
 | ||||
| @SuppressLint("AppCompatCustomView") | ||||
| public class MarkwonView extends TextView implements IMarkwonView { | ||||
| @ -38,7 +38,7 @@ public class MarkwonView extends TextView implements IMarkwonView { | ||||
|         helper.setMarkdown(markdown); | ||||
|     } | ||||
| 
 | ||||
|     public void setMarkdown(@Nullable SpannableConfiguration configuration, @Nullable String markdown) { | ||||
|     public void setMarkdown(@Nullable MarkwonConfiguration configuration, @Nullable String markdown) { | ||||
|         helper.setMarkdown(configuration, markdown); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -6,7 +6,7 @@ import android.support.annotation.Nullable; | ||||
| import android.support.v7.widget.AppCompatTextView; | ||||
| import android.util.AttributeSet; | ||||
| 
 | ||||
| import ru.noties.markwon.SpannableConfiguration; | ||||
| import ru.noties.markwon.MarkwonConfiguration; | ||||
| 
 | ||||
| public class MarkwonViewCompat extends AppCompatTextView implements IMarkwonView { | ||||
| 
 | ||||
| @ -38,7 +38,7 @@ public class MarkwonViewCompat extends AppCompatTextView implements IMarkwonView | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void setMarkdown(@Nullable SpannableConfiguration configuration, @Nullable String markdown) { | ||||
|     public void setMarkdown(@Nullable MarkwonConfiguration configuration, @Nullable String markdown) { | ||||
|         helper.setMarkdown(configuration, markdown); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -9,7 +9,7 @@ import android.util.AttributeSet; | ||||
| import android.widget.TextView; | ||||
| 
 | ||||
| import ru.noties.markwon.Markwon; | ||||
| import ru.noties.markwon.SpannableConfiguration; | ||||
| import ru.noties.markwon.MarkwonConfiguration; | ||||
| 
 | ||||
| public class MarkwonViewHelper implements IMarkwonView { | ||||
| 
 | ||||
| @ -21,7 +21,7 @@ public class MarkwonViewHelper implements IMarkwonView { | ||||
| 
 | ||||
|     private ConfigurationProvider provider; | ||||
| 
 | ||||
|     private SpannableConfiguration configuration; | ||||
|     private MarkwonConfiguration configuration; | ||||
|     private String markdown; | ||||
| 
 | ||||
|     private MarkwonViewHelper(@NonNull TextView textView) { | ||||
| @ -71,14 +71,14 @@ public class MarkwonViewHelper implements IMarkwonView { | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void setMarkdown(@Nullable SpannableConfiguration configuration, @Nullable String markdown) { | ||||
|     public void setMarkdown(@Nullable MarkwonConfiguration configuration, @Nullable String markdown) { | ||||
|         this.markdown = markdown; | ||||
|         if (configuration == null) { | ||||
|             if (this.configuration == null) { | ||||
|                 if (provider != null) { | ||||
|                     this.configuration = provider.provide(textView.getContext()); | ||||
|                 } else { | ||||
|                     this.configuration = SpannableConfiguration.create(textView.getContext()); | ||||
|                     this.configuration = MarkwonConfiguration.create(textView.getContext()); | ||||
|                 } | ||||
|             } | ||||
|             configuration = this.configuration; | ||||
|  | ||||
| @ -0,0 +1,46 @@ | ||||
| package ru.noties.markwon; | ||||
| 
 | ||||
| import android.support.annotation.NonNull; | ||||
| import android.widget.TextView; | ||||
| 
 | ||||
| import org.commonmark.parser.Parser; | ||||
| 
 | ||||
| import ru.noties.markwon.spans.MarkwonTheme; | ||||
| 
 | ||||
| public abstract class AbstractMarkwonPlugin implements MarkwonPlugin { | ||||
|     @Override | ||||
|     public void configureParser(@NonNull Parser.Builder builder) { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void configureTheme(@NonNull MarkwonTheme.Builder builder) { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     @Override | ||||
|     public String processMarkdown(@NonNull String markdown) { | ||||
|         return markdown; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void beforeSetText(@NonNull TextView textView, @NonNull SpannableBuilder builder) { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void afterSetText(@NonNull TextView textView, @NonNull SpannableBuilder builder) { | ||||
| 
 | ||||
|     } | ||||
| } | ||||
| @ -40,11 +40,11 @@ public abstract class Markwon { | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @see #setMarkdown(TextView, SpannableConfiguration, String) | ||||
|      * @see #setMarkdown(TextView, MarkwonConfiguration, String) | ||||
|      * @since 1.0.0 | ||||
|      */ | ||||
|     public static void setMarkdown(@NonNull TextView view, @NonNull String markdown) { | ||||
|         setMarkdown(view, SpannableConfiguration.create(view.getContext()), markdown); | ||||
|         setMarkdown(view, MarkwonConfiguration.create(view.getContext()), markdown); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -52,16 +52,16 @@ public abstract class Markwon { | ||||
|      * and applies it to view | ||||
|      * | ||||
|      * @param view          {@link TextView} to set markdown into | ||||
|      * @param configuration a {@link SpannableConfiguration} instance | ||||
|      * @param configuration a {@link MarkwonConfiguration} instance | ||||
|      * @param markdown      raw markdown String (for example: {@code `**Hello**`}) | ||||
|      * @see #markdown(SpannableConfiguration, String) | ||||
|      * @see #markdown(MarkwonConfiguration, String) | ||||
|      * @see #setText(TextView, CharSequence) | ||||
|      * @see SpannableConfiguration | ||||
|      * @see MarkwonConfiguration | ||||
|      * @since 1.0.0 | ||||
|      */ | ||||
|     public static void setMarkdown( | ||||
|             @NonNull TextView view, | ||||
|             @NonNull SpannableConfiguration configuration, | ||||
|             @NonNull MarkwonConfiguration configuration, | ||||
|             @NonNull String markdown | ||||
|     ) { | ||||
| 
 | ||||
| @ -117,7 +117,7 @@ public abstract class Markwon { | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Returns parsed markdown with default {@link SpannableConfiguration} obtained from {@link Context} | ||||
|      * Returns parsed markdown with default {@link MarkwonConfiguration} obtained from {@link Context} | ||||
|      * | ||||
|      * @param context  {@link Context} | ||||
|      * @param markdown raw markdown | ||||
| @ -126,21 +126,21 @@ public abstract class Markwon { | ||||
|      */ | ||||
|     @NonNull | ||||
|     public static CharSequence markdown(@NonNull Context context, @NonNull String markdown) { | ||||
|         final SpannableConfiguration configuration = SpannableConfiguration.create(context); | ||||
|         final MarkwonConfiguration configuration = MarkwonConfiguration.create(context); | ||||
|         return markdown(configuration, markdown); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Returns parsed markdown with provided {@link SpannableConfiguration} | ||||
|      * Returns parsed markdown with provided {@link MarkwonConfiguration} | ||||
|      * | ||||
|      * @param configuration a {@link SpannableConfiguration} | ||||
|      * @param configuration a {@link MarkwonConfiguration} | ||||
|      * @param markdown      raw markdown | ||||
|      * @return parsed markdown | ||||
|      * @see SpannableConfiguration | ||||
|      * @see MarkwonConfiguration | ||||
|      * @since 1.0.0 | ||||
|      */ | ||||
|     @NonNull | ||||
|     public static CharSequence markdown(@NonNull SpannableConfiguration configuration, @NonNull String markdown) { | ||||
|     public static CharSequence markdown(@NonNull MarkwonConfiguration configuration, @NonNull String markdown) { | ||||
|         final Parser parser = createParser(); | ||||
|         final Node node = parser.parse(markdown); | ||||
|         final SpannableRenderer renderer = new SpannableRenderer(); | ||||
|  | ||||
							
								
								
									
										32
									
								
								markwon/src/main/java/ru/noties/markwon/Markwon2.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								markwon/src/main/java/ru/noties/markwon/Markwon2.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | ||||
| package ru.noties.markwon; | ||||
| 
 | ||||
| import android.content.Context; | ||||
| import android.support.annotation.NonNull; | ||||
| 
 | ||||
| import org.commonmark.node.Node; | ||||
| 
 | ||||
| public abstract class Markwon2 { | ||||
| 
 | ||||
|     @NonNull | ||||
|     public static Builder builder(@NonNull Context context) { | ||||
|         return new MarkwonBuilderImpl(context); | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     public abstract Node parse(@NonNull String input); | ||||
| 
 | ||||
|     @NonNull | ||||
|     public abstract CharSequence render(@NonNull Node node); | ||||
| 
 | ||||
|     @NonNull | ||||
|     public abstract CharSequence markdown(@NonNull String input); | ||||
| 
 | ||||
|     public interface Builder { | ||||
| 
 | ||||
|         @NonNull | ||||
|         Builder use(@NonNull MarkwonPlugin plugin); | ||||
| 
 | ||||
|         @NonNull | ||||
|         Markwon2 build(); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,53 @@ | ||||
| package ru.noties.markwon; | ||||
| 
 | ||||
| import android.content.Context; | ||||
| import android.support.annotation.NonNull; | ||||
| 
 | ||||
| import org.commonmark.parser.Parser; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collections; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import ru.noties.markwon.spans.MarkwonTheme; | ||||
| 
 | ||||
| class MarkwonBuilderImpl implements Markwon2.Builder { | ||||
| 
 | ||||
|     private final Context context; | ||||
| 
 | ||||
|     private final List<MarkwonPlugin> plugins = new ArrayList<>(3); | ||||
| 
 | ||||
|     MarkwonBuilderImpl(@NonNull Context context) { | ||||
|         this.context = context; | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     @Override | ||||
|     public Markwon2.Builder use(@NonNull MarkwonPlugin plugin) { | ||||
|         plugins.add(plugin); | ||||
|         return this; | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     @Override | ||||
|     public Markwon2 build() { | ||||
| 
 | ||||
|         final Parser.Builder parserBuilder = new Parser.Builder(); | ||||
|         final MarkwonTheme.Builder themeBuilder = MarkwonTheme.builderWithDefaults(context); | ||||
|         final MarkwonConfiguration.Builder configurationBuilder = new MarkwonConfiguration.Builder(context); | ||||
|         final MarkwonVisitor.Builder visitorBuilder = new MarkwonVisitorImpl.BuilderImpl(); | ||||
| 
 | ||||
|         for (MarkwonPlugin plugin : plugins) { | ||||
|             plugin.configureParser(parserBuilder); | ||||
|             plugin.configureTheme(themeBuilder); | ||||
|             plugin.configureConfiguration(configurationBuilder); | ||||
|             plugin.configureVisitor(visitorBuilder); | ||||
|         } | ||||
| 
 | ||||
|         return new MarkwonImpl( | ||||
|                 parserBuilder.build(), | ||||
|                 visitorBuilder.build(themeBuilder.build(), configurationBuilder.build()), | ||||
|                 Collections.unmodifiableList(plugins) | ||||
|         ); | ||||
|     } | ||||
| } | ||||
| @ -9,14 +9,17 @@ import ru.noties.markwon.renderer.ImageSizeResolverDef; | ||||
| import ru.noties.markwon.renderer.html2.MarkwonHtmlRenderer; | ||||
| import ru.noties.markwon.spans.AsyncDrawable; | ||||
| import ru.noties.markwon.spans.LinkSpan; | ||||
| import ru.noties.markwon.spans.SpannableTheme; | ||||
| import ru.noties.markwon.spans.MarkwonTheme; | ||||
| 
 | ||||
| /** | ||||
|  * since 3.0.0 renamed `SpannableConfiguration` -> `MarkwonConfiguration` | ||||
|  */ | ||||
| @SuppressWarnings("WeakerAccess") | ||||
| public class SpannableConfiguration { | ||||
| public class MarkwonConfiguration { | ||||
| 
 | ||||
|     // creates default configuration | ||||
|     @NonNull | ||||
|     public static SpannableConfiguration create(@NonNull Context context) { | ||||
|     public static MarkwonConfiguration create(@NonNull Context context) { | ||||
|         return new Builder(context).build(); | ||||
|     } | ||||
| 
 | ||||
| @ -25,7 +28,9 @@ public class SpannableConfiguration { | ||||
|         return new Builder(context); | ||||
|     } | ||||
| 
 | ||||
|     private final SpannableTheme theme; | ||||
|     @Deprecated | ||||
|     private final MarkwonTheme theme; | ||||
| 
 | ||||
|     private final AsyncDrawable.Loader asyncDrawableLoader; | ||||
|     private final SyntaxHighlight syntaxHighlight; | ||||
|     private final LinkSpan.Resolver linkResolver; | ||||
| @ -37,7 +42,7 @@ public class SpannableConfiguration { | ||||
|     private final MarkwonHtmlRenderer htmlRenderer; // @since 2.0.0 | ||||
|     private final boolean htmlAllowNonClosedTags; // @since 2.0.0 | ||||
| 
 | ||||
|     private SpannableConfiguration(@NonNull Builder builder) { | ||||
|     private MarkwonConfiguration(@NonNull Builder builder) { | ||||
|         this.theme = builder.theme; | ||||
|         this.asyncDrawableLoader = builder.asyncDrawableLoader; | ||||
|         this.syntaxHighlight = builder.syntaxHighlight; | ||||
| @ -60,7 +65,8 @@ public class SpannableConfiguration { | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     public SpannableTheme theme() { | ||||
|     @Deprecated | ||||
|     public MarkwonTheme theme() { | ||||
|         return theme; | ||||
|     } | ||||
| 
 | ||||
| @ -130,7 +136,9 @@ public class SpannableConfiguration { | ||||
|     public static class Builder { | ||||
| 
 | ||||
|         private final Context context; | ||||
|         private SpannableTheme theme; | ||||
| 
 | ||||
|         @Deprecated | ||||
|         private MarkwonTheme theme; | ||||
|         private AsyncDrawable.Loader asyncDrawableLoader; | ||||
|         private SyntaxHighlight syntaxHighlight; | ||||
|         private LinkSpan.Resolver linkResolver; | ||||
| @ -146,7 +154,7 @@ public class SpannableConfiguration { | ||||
|             this.context = context; | ||||
|         } | ||||
| 
 | ||||
|         Builder(@NonNull Context context, @NonNull SpannableConfiguration configuration) { | ||||
|         Builder(@NonNull Context context, @NonNull MarkwonConfiguration configuration) { | ||||
|             this(context); | ||||
|             this.theme = configuration.theme; | ||||
|             this.asyncDrawableLoader = configuration.asyncDrawableLoader; | ||||
| @ -162,7 +170,8 @@ public class SpannableConfiguration { | ||||
|         } | ||||
| 
 | ||||
|         @NonNull | ||||
|         public Builder theme(@NonNull SpannableTheme theme) { | ||||
|         @Deprecated | ||||
|         public Builder theme(@NonNull MarkwonTheme theme) { | ||||
|             this.theme = theme; | ||||
|             return this; | ||||
|         } | ||||
| @ -254,10 +263,10 @@ public class SpannableConfiguration { | ||||
|         } | ||||
| 
 | ||||
|         @NonNull | ||||
|         public SpannableConfiguration build() { | ||||
|         public MarkwonConfiguration build() { | ||||
| 
 | ||||
|             if (theme == null) { | ||||
|                 theme = SpannableTheme.create(context); | ||||
|                 theme = MarkwonTheme.create(context); | ||||
|             } | ||||
| 
 | ||||
|             if (asyncDrawableLoader == null) { | ||||
| @ -300,7 +309,7 @@ public class SpannableConfiguration { | ||||
|                 htmlRenderer = MarkwonHtmlRenderer.create(); | ||||
|             } | ||||
| 
 | ||||
|             return new SpannableConfiguration(this); | ||||
|             return new MarkwonConfiguration(this); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
							
								
								
									
										48
									
								
								markwon/src/main/java/ru/noties/markwon/MarkwonImpl.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								markwon/src/main/java/ru/noties/markwon/MarkwonImpl.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | ||||
| package ru.noties.markwon; | ||||
| 
 | ||||
| import android.support.annotation.NonNull; | ||||
| 
 | ||||
| import org.commonmark.node.Node; | ||||
| import org.commonmark.parser.Parser; | ||||
| 
 | ||||
| import java.util.List; | ||||
| 
 | ||||
| class MarkwonImpl extends Markwon2 { | ||||
| 
 | ||||
|     private final Parser parser; | ||||
|     private final MarkwonVisitor visitor; | ||||
|     private final List<MarkwonPlugin> plugins; | ||||
| 
 | ||||
|     MarkwonImpl( | ||||
|             @NonNull Parser parser, | ||||
|             @NonNull MarkwonVisitor visitor, | ||||
|             @NonNull List<MarkwonPlugin> plugins) { | ||||
|         this.parser = parser; | ||||
|         this.visitor = visitor; | ||||
|         this.plugins = plugins; | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     @Override | ||||
|     public Node parse(@NonNull String input) { | ||||
| 
 | ||||
|         for (MarkwonPlugin plugin : plugins) { | ||||
|             input = plugin.processMarkdown(input); | ||||
|         } | ||||
| 
 | ||||
|         return parser.parse(input); | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     @Override | ||||
|     public CharSequence render(@NonNull Node node) { | ||||
|         node.accept(visitor); | ||||
|         return visitor.builder().text(); | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     @Override | ||||
|     public CharSequence markdown(@NonNull String input) { | ||||
|         return render(parse(input)); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										29
									
								
								markwon/src/main/java/ru/noties/markwon/MarkwonPlugin.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								markwon/src/main/java/ru/noties/markwon/MarkwonPlugin.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | ||||
| package ru.noties.markwon; | ||||
| 
 | ||||
| import android.support.annotation.NonNull; | ||||
| import android.widget.TextView; | ||||
| 
 | ||||
| import org.commonmark.parser.Parser; | ||||
| 
 | ||||
| import ru.noties.markwon.spans.MarkwonTheme; | ||||
| 
 | ||||
| public interface MarkwonPlugin { | ||||
| 
 | ||||
|     void configureParser(@NonNull Parser.Builder builder); | ||||
| 
 | ||||
|     void configureTheme(@NonNull MarkwonTheme.Builder builder); | ||||
| 
 | ||||
|     void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder); | ||||
| 
 | ||||
|     void configureVisitor(@NonNull MarkwonVisitor.Builder builder); | ||||
| 
 | ||||
|     // images | ||||
|     // html | ||||
| 
 | ||||
|     @NonNull | ||||
|     String processMarkdown(@NonNull String markdown); | ||||
| 
 | ||||
|     void beforeSetText(@NonNull TextView textView, @NonNull SpannableBuilder builder); | ||||
| 
 | ||||
|     void afterSetText(@NonNull TextView textView, @NonNull SpannableBuilder builder); | ||||
| } | ||||
							
								
								
									
										60
									
								
								markwon/src/main/java/ru/noties/markwon/MarkwonVisitor.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								markwon/src/main/java/ru/noties/markwon/MarkwonVisitor.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,60 @@ | ||||
| package ru.noties.markwon; | ||||
| 
 | ||||
| import android.support.annotation.NonNull; | ||||
| import android.support.annotation.Nullable; | ||||
| 
 | ||||
| import org.commonmark.node.Node; | ||||
| import org.commonmark.node.Visitor; | ||||
| 
 | ||||
| import ru.noties.markwon.spans.MarkwonTheme; | ||||
| 
 | ||||
| public interface MarkwonVisitor extends Visitor { | ||||
| 
 | ||||
|     interface NodeVisitor<N extends Node> { | ||||
|         void visit(@NonNull MarkwonVisitor visitor, @NonNull N n); | ||||
|     } | ||||
| 
 | ||||
|     interface Builder { | ||||
| 
 | ||||
|         @NonNull | ||||
|         <N extends Node> Builder on(@NonNull Class<N> node, @NonNull NodeVisitor<N> nodeVisitor); | ||||
| 
 | ||||
|         @NonNull | ||||
|         MarkwonVisitor build(@NonNull MarkwonTheme theme, @NonNull MarkwonConfiguration configuration); | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     MarkwonTheme theme(); | ||||
| 
 | ||||
|     @NonNull | ||||
|     MarkwonConfiguration configuration(); | ||||
| 
 | ||||
|     @NonNull | ||||
|     SpannableBuilder builder(); | ||||
| 
 | ||||
|     void visitChildren(@NonNull Node node); | ||||
| 
 | ||||
|     boolean hasNext(@NonNull Node node); | ||||
| 
 | ||||
|     void incrementBlockQuoteIndent(); | ||||
| 
 | ||||
|     void decrementBlockQuoteIndent(); | ||||
| 
 | ||||
|     void blockQuoteIntent(int blockQuoteIndent); | ||||
| 
 | ||||
|     int blockQuoteIndent(); | ||||
| 
 | ||||
|     void incrementListLevel(); | ||||
| 
 | ||||
|     void decrementListLevel(); | ||||
| 
 | ||||
|     int listLevel(); | ||||
| 
 | ||||
|     void ensureNewLine(); | ||||
| 
 | ||||
|     void forceNewLine(); | ||||
| 
 | ||||
|     int length(); | ||||
| 
 | ||||
|     void setSpans(int start, @Nullable Object spans); | ||||
| } | ||||
							
								
								
									
										290
									
								
								markwon/src/main/java/ru/noties/markwon/MarkwonVisitorImpl.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										290
									
								
								markwon/src/main/java/ru/noties/markwon/MarkwonVisitorImpl.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,290 @@ | ||||
| package ru.noties.markwon; | ||||
| 
 | ||||
| import android.support.annotation.NonNull; | ||||
| import android.support.annotation.Nullable; | ||||
| 
 | ||||
| import org.commonmark.node.BlockQuote; | ||||
| import org.commonmark.node.BulletList; | ||||
| import org.commonmark.node.Code; | ||||
| import org.commonmark.node.CustomBlock; | ||||
| import org.commonmark.node.CustomNode; | ||||
| import org.commonmark.node.Document; | ||||
| import org.commonmark.node.Emphasis; | ||||
| import org.commonmark.node.FencedCodeBlock; | ||||
| import org.commonmark.node.HardLineBreak; | ||||
| import org.commonmark.node.Heading; | ||||
| import org.commonmark.node.HtmlBlock; | ||||
| import org.commonmark.node.HtmlInline; | ||||
| import org.commonmark.node.Image; | ||||
| import org.commonmark.node.IndentedCodeBlock; | ||||
| import org.commonmark.node.Link; | ||||
| import org.commonmark.node.ListItem; | ||||
| import org.commonmark.node.Node; | ||||
| import org.commonmark.node.OrderedList; | ||||
| import org.commonmark.node.Paragraph; | ||||
| import org.commonmark.node.SoftLineBreak; | ||||
| import org.commonmark.node.StrongEmphasis; | ||||
| import org.commonmark.node.Text; | ||||
| import org.commonmark.node.ThematicBreak; | ||||
| 
 | ||||
| import java.util.Collections; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| import ru.noties.markwon.spans.MarkwonTheme; | ||||
| 
 | ||||
| class MarkwonVisitorImpl implements MarkwonVisitor { | ||||
| 
 | ||||
|     private final Map<Class<? extends Node>, NodeVisitor<? extends Node>> nodes; | ||||
| 
 | ||||
|     private final MarkwonTheme theme; | ||||
|     private final MarkwonConfiguration configuration; | ||||
|     private final SpannableBuilder builder = new SpannableBuilder(); | ||||
| 
 | ||||
|     private int blockQuoteIndent; | ||||
|     private int listLevel; | ||||
| 
 | ||||
|     private MarkwonVisitorImpl( | ||||
|             @NonNull MarkwonTheme theme, | ||||
|             @NonNull MarkwonConfiguration configuration, | ||||
|             @NonNull Map<Class<? extends Node>, NodeVisitor<? extends Node>> nodes) { | ||||
|         this.theme = theme; | ||||
|         this.configuration = configuration; | ||||
|         this.nodes = nodes; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void visit(BlockQuote blockQuote) { | ||||
|         visit((Node) blockQuote); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void visit(BulletList bulletList) { | ||||
|         visit((Node) bulletList); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void visit(Code code) { | ||||
|         visit((Node) code); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void visit(Document document) { | ||||
|         visit((Node) document); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void visit(Emphasis emphasis) { | ||||
|         visit((Node) emphasis); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void visit(FencedCodeBlock fencedCodeBlock) { | ||||
|         visit((Node) fencedCodeBlock); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void visit(HardLineBreak hardLineBreak) { | ||||
|         visit((Node) hardLineBreak); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void visit(Heading heading) { | ||||
|         visit((Node) heading); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void visit(ThematicBreak thematicBreak) { | ||||
|         visit((Node) thematicBreak); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void visit(HtmlInline htmlInline) { | ||||
|         visit((Node) htmlInline); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void visit(HtmlBlock htmlBlock) { | ||||
|         visit((Node) htmlBlock); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void visit(Image image) { | ||||
|         visit((Node) image); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void visit(IndentedCodeBlock indentedCodeBlock) { | ||||
|         visit((Node) indentedCodeBlock); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void visit(Link link) { | ||||
|         visit((Node) link); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void visit(ListItem listItem) { | ||||
|         visit((Node) listItem); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void visit(OrderedList orderedList) { | ||||
|         visit((Node) orderedList); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void visit(Paragraph paragraph) { | ||||
|         visit((Node) paragraph); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void visit(SoftLineBreak softLineBreak) { | ||||
|         visit((Node) softLineBreak); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void visit(StrongEmphasis strongEmphasis) { | ||||
|         visit((Node) strongEmphasis); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void visit(Text text) { | ||||
|         visit((Node) text); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void visit(CustomBlock customBlock) { | ||||
|         visit((Node) customBlock); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void visit(CustomNode customNode) { | ||||
|         visit((Node) customNode); | ||||
|     } | ||||
| 
 | ||||
|     private void visit(@NonNull Node node) { | ||||
|         //noinspection unchecked | ||||
|         final NodeVisitor<Node> nodeVisitor = (NodeVisitor<Node>) nodes.get(node.getClass()); | ||||
|         if (nodeVisitor != null) { | ||||
|             nodeVisitor.visit(this, node); | ||||
|         } else { | ||||
|             visitChildren(node); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     @Override | ||||
|     public MarkwonTheme theme() { | ||||
|         return theme; | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     @Override | ||||
|     public MarkwonConfiguration configuration() { | ||||
|         return configuration; | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     @Override | ||||
|     public SpannableBuilder builder() { | ||||
|         return builder; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void visitChildren(@NonNull Node parent) { | ||||
|         Node node = parent.getFirstChild(); | ||||
|         while (node != null) { | ||||
|             // A subclass of this visitor might modify the node, resulting in getNext returning a different node or no | ||||
|             // node after visiting it. So get the next node before visiting. | ||||
|             Node next = node.getNext(); | ||||
|             node.accept(this); | ||||
|             node = next; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean hasNext(@NonNull Node node) { | ||||
|         return node.getNext() != null; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void incrementBlockQuoteIndent() { | ||||
|         blockQuoteIndent += 1; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void decrementBlockQuoteIndent() { | ||||
|         blockQuoteIndent -= 1; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void blockQuoteIntent(int blockQuoteIndent) { | ||||
|         this.blockQuoteIndent = blockQuoteIndent; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public int blockQuoteIndent() { | ||||
|         return blockQuoteIndent; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void incrementListLevel() { | ||||
|         listLevel += 1; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void decrementListLevel() { | ||||
|         listLevel -= 1; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public int listLevel() { | ||||
|         return listLevel; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void ensureNewLine() { | ||||
|         if (builder.length() > 0 | ||||
|                 && '\n' != builder.lastChar()) { | ||||
|             builder.append('\n'); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void forceNewLine() { | ||||
|         builder.append('\n'); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public int length() { | ||||
|         return builder.length(); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void setSpans(int start, @Nullable Object spans) { | ||||
|         SpannableBuilder.setSpans(builder, spans, start, builder.length()); | ||||
|     } | ||||
| 
 | ||||
|     static class BuilderImpl implements Builder { | ||||
| 
 | ||||
|         private final Map<Class<? extends Node>, NodeVisitor<? extends Node>> nodes = | ||||
|                 new HashMap<>(3); | ||||
| 
 | ||||
|         @NonNull | ||||
|         @Override | ||||
|         public <N extends Node> Builder on(@NonNull Class<N> node, @NonNull NodeVisitor<N> nodeVisitor) { | ||||
|             nodes.put(node, nodeVisitor); | ||||
|             return this; | ||||
|         } | ||||
| 
 | ||||
|         @NonNull | ||||
|         @Override | ||||
|         public MarkwonVisitor build(@NonNull MarkwonTheme theme, @NonNull MarkwonConfiguration configuration) { | ||||
|             return new MarkwonVisitorImpl( | ||||
|                     theme, | ||||
|                     configuration, | ||||
|                     Collections.unmodifiableMap(nodes)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -208,7 +208,7 @@ public class SpannableBuilder implements Appendable, CharSequence { | ||||
|     /** | ||||
|      * This method will return all {@link Span} spans that <em>overlap</em> specified range, | ||||
|      * so if for example a 1..9 range is specified some spans might have 0..6 or 0..10 start/end ranges. | ||||
|      * NB spans are returned in reversed order (no in order that we store them internally) | ||||
|      * NB spans are returned in reversed order (not in order that we store them internally) | ||||
|      * | ||||
|      * @since 2.0.1 | ||||
|      */ | ||||
|  | ||||
| @ -9,7 +9,7 @@ import ru.noties.markwon.renderer.ImageSize; | ||||
| import ru.noties.markwon.renderer.ImageSizeResolver; | ||||
| import ru.noties.markwon.spans.AsyncDrawable; | ||||
| import ru.noties.markwon.spans.LinkSpan; | ||||
| import ru.noties.markwon.spans.SpannableTheme; | ||||
| import ru.noties.markwon.spans.MarkwonTheme; | ||||
| import ru.noties.markwon.spans.TableRowSpan; | ||||
| 
 | ||||
| /** | ||||
| @ -26,32 +26,32 @@ public interface SpannableFactory { | ||||
|     Object emphasis(); | ||||
| 
 | ||||
|     @Nullable | ||||
|     Object blockQuote(@NonNull SpannableTheme theme); | ||||
|     Object blockQuote(@NonNull MarkwonTheme theme); | ||||
| 
 | ||||
|     @Nullable | ||||
|     Object code(@NonNull SpannableTheme theme, boolean multiline); | ||||
|     Object code(@NonNull MarkwonTheme theme, boolean multiline); | ||||
| 
 | ||||
|     @Nullable | ||||
|     Object orderedListItem(@NonNull SpannableTheme theme, int startNumber); | ||||
|     Object orderedListItem(@NonNull MarkwonTheme theme, int startNumber); | ||||
| 
 | ||||
|     @Nullable | ||||
|     Object bulletListItem(@NonNull SpannableTheme theme, int level); | ||||
|     Object bulletListItem(@NonNull MarkwonTheme theme, int level); | ||||
| 
 | ||||
|     @Nullable | ||||
|     Object thematicBreak(@NonNull SpannableTheme theme); | ||||
|     Object thematicBreak(@NonNull MarkwonTheme theme); | ||||
| 
 | ||||
|     @Nullable | ||||
|     Object heading(@NonNull SpannableTheme theme, int level); | ||||
|     Object heading(@NonNull MarkwonTheme theme, int level); | ||||
| 
 | ||||
|     @Nullable | ||||
|     Object strikethrough(); | ||||
| 
 | ||||
|     @Nullable | ||||
|     Object taskListItem(@NonNull SpannableTheme theme, int blockIndent, boolean isDone); | ||||
|     Object taskListItem(@NonNull MarkwonTheme theme, int blockIndent, boolean isDone); | ||||
| 
 | ||||
|     @Nullable | ||||
|     Object tableRow( | ||||
|             @NonNull SpannableTheme theme, | ||||
|             @NonNull MarkwonTheme theme, | ||||
|             @NonNull List<TableRowSpan.Cell> cells, | ||||
|             boolean isHeader, | ||||
|             boolean isOdd); | ||||
| @ -64,7 +64,7 @@ public interface SpannableFactory { | ||||
| 
 | ||||
|     @Nullable | ||||
|     Object image( | ||||
|             @NonNull SpannableTheme theme, | ||||
|             @NonNull MarkwonTheme theme, | ||||
|             @NonNull String destination, | ||||
|             @NonNull AsyncDrawable.Loader loader, | ||||
|             @NonNull ImageSizeResolver imageSizeResolver, | ||||
| @ -73,17 +73,17 @@ public interface SpannableFactory { | ||||
| 
 | ||||
|     @Nullable | ||||
|     Object link( | ||||
|             @NonNull SpannableTheme theme, | ||||
|             @NonNull MarkwonTheme theme, | ||||
|             @NonNull String destination, | ||||
|             @NonNull LinkSpan.Resolver resolver); | ||||
| 
 | ||||
|     // Currently used by HTML parser | ||||
|     @Nullable | ||||
|     Object superScript(@NonNull SpannableTheme theme); | ||||
|     Object superScript(@NonNull MarkwonTheme theme); | ||||
| 
 | ||||
|     // Currently used by HTML parser | ||||
|     @Nullable | ||||
|     Object subScript(@NonNull SpannableTheme theme); | ||||
|     Object subScript(@NonNull MarkwonTheme theme); | ||||
| 
 | ||||
|     // Currently used by HTML parser | ||||
|     @Nullable | ||||
|  | ||||
| @ -18,12 +18,12 @@ import ru.noties.markwon.spans.EmphasisSpan; | ||||
| import ru.noties.markwon.spans.HeadingSpan; | ||||
| import ru.noties.markwon.spans.LinkSpan; | ||||
| import ru.noties.markwon.spans.OrderedListItemSpan; | ||||
| import ru.noties.markwon.spans.SpannableTheme; | ||||
| import ru.noties.markwon.spans.MarkwonTheme; | ||||
| import ru.noties.markwon.spans.StrongEmphasisSpan; | ||||
| import ru.noties.markwon.spans.SubScriptSpan; | ||||
| import ru.noties.markwon.spans.SuperScriptSpan; | ||||
| import ru.noties.markwon.spans.TableRowSpan; | ||||
| import ru.noties.markwon.spans.TaskListSpan; | ||||
| import ru.noties.markwon.tasklist.TaskListSpan; | ||||
| import ru.noties.markwon.spans.ThematicBreakSpan; | ||||
| 
 | ||||
| /** | ||||
| @ -50,38 +50,38 @@ public class SpannableFactoryDef implements SpannableFactory { | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object blockQuote(@NonNull SpannableTheme theme) { | ||||
|     public Object blockQuote(@NonNull MarkwonTheme theme) { | ||||
|         return new BlockQuoteSpan(theme); | ||||
|     } | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object code(@NonNull SpannableTheme theme, boolean multiline) { | ||||
|     public Object code(@NonNull MarkwonTheme theme, boolean multiline) { | ||||
|         return new CodeSpan(theme, multiline); | ||||
|     } | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object orderedListItem(@NonNull SpannableTheme theme, int startNumber) { | ||||
|     public Object orderedListItem(@NonNull MarkwonTheme theme, int startNumber) { | ||||
|         // todo| in order to provide real RTL experience there must be a way to provide this string | ||||
|         return new OrderedListItemSpan(theme, String.valueOf(startNumber) + "." + '\u00a0'); | ||||
|     } | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object bulletListItem(@NonNull SpannableTheme theme, int level) { | ||||
|     public Object bulletListItem(@NonNull MarkwonTheme theme, int level) { | ||||
|         return new BulletListItemSpan(theme, level); | ||||
|     } | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object thematicBreak(@NonNull SpannableTheme theme) { | ||||
|     public Object thematicBreak(@NonNull MarkwonTheme theme) { | ||||
|         return new ThematicBreakSpan(theme); | ||||
|     } | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object heading(@NonNull SpannableTheme theme, int level) { | ||||
|     public Object heading(@NonNull MarkwonTheme theme, int level) { | ||||
|         return new HeadingSpan(theme, level); | ||||
|     } | ||||
| 
 | ||||
| @ -93,13 +93,13 @@ public class SpannableFactoryDef implements SpannableFactory { | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object taskListItem(@NonNull SpannableTheme theme, int blockIndent, boolean isDone) { | ||||
|     public Object taskListItem(@NonNull MarkwonTheme theme, int blockIndent, boolean isDone) { | ||||
|         return new TaskListSpan(theme, blockIndent, isDone); | ||||
|     } | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object tableRow(@NonNull SpannableTheme theme, @NonNull List<TableRowSpan.Cell> cells, boolean isHeader, boolean isOdd) { | ||||
|     public Object tableRow(@NonNull MarkwonTheme theme, @NonNull List<TableRowSpan.Cell> cells, boolean isHeader, boolean isOdd) { | ||||
|         return new TableRowSpan(theme, cells, isHeader, isOdd); | ||||
|     } | ||||
| 
 | ||||
| @ -114,7 +114,7 @@ public class SpannableFactoryDef implements SpannableFactory { | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object image(@NonNull SpannableTheme theme, @NonNull String destination, @NonNull AsyncDrawable.Loader loader, @NonNull ImageSizeResolver imageSizeResolver, @Nullable ImageSize imageSize, boolean replacementTextIsLink) { | ||||
|     public Object image(@NonNull MarkwonTheme theme, @NonNull String destination, @NonNull AsyncDrawable.Loader loader, @NonNull ImageSizeResolver imageSizeResolver, @Nullable ImageSize imageSize, boolean replacementTextIsLink) { | ||||
|         return new AsyncDrawableSpan( | ||||
|                 theme, | ||||
|                 new AsyncDrawable( | ||||
| @ -130,18 +130,18 @@ public class SpannableFactoryDef implements SpannableFactory { | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object link(@NonNull SpannableTheme theme, @NonNull String destination, @NonNull LinkSpan.Resolver resolver) { | ||||
|     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 SpannableTheme theme) { | ||||
|     public Object superScript(@NonNull MarkwonTheme theme) { | ||||
|         return new SuperScriptSpan(theme); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public Object subScript(@NonNull SpannableTheme theme) { | ||||
|     public Object subScript(@NonNull MarkwonTheme theme) { | ||||
|         return new SubScriptSpan(theme); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										268
									
								
								markwon/src/main/java/ru/noties/markwon/core/CorePlugin.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										268
									
								
								markwon/src/main/java/ru/noties/markwon/core/CorePlugin.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,268 @@ | ||||
| package ru.noties.markwon.core; | ||||
| 
 | ||||
| import android.support.annotation.NonNull; | ||||
| import android.support.annotation.Nullable; | ||||
| import android.widget.TextView; | ||||
| 
 | ||||
| import org.commonmark.node.BlockQuote; | ||||
| import org.commonmark.node.BulletList; | ||||
| import org.commonmark.node.Code; | ||||
| import org.commonmark.node.Emphasis; | ||||
| import org.commonmark.node.FencedCodeBlock; | ||||
| import org.commonmark.node.IndentedCodeBlock; | ||||
| import org.commonmark.node.ListItem; | ||||
| import org.commonmark.node.Node; | ||||
| import org.commonmark.node.OrderedList; | ||||
| import org.commonmark.node.StrongEmphasis; | ||||
| import org.commonmark.node.Text; | ||||
| import org.commonmark.node.ThematicBreak; | ||||
| 
 | ||||
| import ru.noties.markwon.AbstractMarkwonPlugin; | ||||
| import ru.noties.markwon.MarkwonVisitor; | ||||
| import ru.noties.markwon.SpannableBuilder; | ||||
| import ru.noties.markwon.spans.OrderedListItemSpan; | ||||
| 
 | ||||
| public class CorePlugin extends AbstractMarkwonPlugin { | ||||
| 
 | ||||
|     // todo: factory. Logically it must be here only, but in order to make spans | ||||
|     // uniform in HTML (for example) we should expose it... Anyway, this factory _must_ | ||||
|     // include only _core_ spans | ||||
| 
 | ||||
|     // todo: softBreak adds new line should be here (or maybe removed even?) | ||||
| 
 | ||||
|     @Override | ||||
|     public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) { | ||||
|         text(builder); | ||||
|         strongEmphasis(builder); | ||||
|         emphasis(builder); | ||||
|         blockQuote(builder); | ||||
|         code(builder); | ||||
|         fencedCodeBlock(builder); | ||||
|         indentedCodeBlock(builder); | ||||
|         bulletList(builder); | ||||
|         orderedList(builder); | ||||
|         listItem(builder); | ||||
|         thematicBreak(builder); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void beforeSetText(@NonNull TextView textView, @NonNull SpannableBuilder builder) { | ||||
|         OrderedListItemSpan.measure(textView, builder); | ||||
|     } | ||||
| 
 | ||||
|     protected void text(@NonNull MarkwonVisitor.Builder builder) { | ||||
|         builder.on(Text.class, new MarkwonVisitor.NodeVisitor<Text>() { | ||||
|             @Override | ||||
|             public void visit(@NonNull MarkwonVisitor visitor, @NonNull Text text) { | ||||
|                 visitor.builder().append(text.getLiteral()); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     protected void strongEmphasis(@NonNull MarkwonVisitor.Builder builder) { | ||||
|         builder.on(StrongEmphasis.class, new MarkwonVisitor.NodeVisitor<StrongEmphasis>() { | ||||
|             @Override | ||||
|             public void visit(@NonNull MarkwonVisitor visitor, @NonNull StrongEmphasis strongEmphasis) { | ||||
|                 final int length = visitor.length(); | ||||
|                 visitor.visitChildren(strongEmphasis); | ||||
|                 visitor.setSpans(length, visitor.configuration().factory().strongEmphasis()); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     protected void emphasis(@NonNull MarkwonVisitor.Builder builder) { | ||||
|         builder.on(Emphasis.class, new MarkwonVisitor.NodeVisitor<Emphasis>() { | ||||
|             @Override | ||||
|             public void visit(@NonNull MarkwonVisitor visitor, @NonNull Emphasis emphasis) { | ||||
|                 final int length = visitor.length(); | ||||
|                 visitor.visitChildren(emphasis); | ||||
|                 visitor.setSpans(length, visitor.configuration().factory().emphasis()); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     protected void blockQuote(@NonNull MarkwonVisitor.Builder builder) { | ||||
|         builder.on(BlockQuote.class, new MarkwonVisitor.NodeVisitor<BlockQuote>() { | ||||
|             @Override | ||||
|             public void visit(@NonNull MarkwonVisitor visitor, @NonNull BlockQuote blockQuote) { | ||||
| 
 | ||||
|                 visitor.ensureNewLine(); | ||||
| 
 | ||||
|                 if (visitor.blockQuoteIndent() > 0) { | ||||
|                     visitor.forceNewLine(); | ||||
|                 } | ||||
| 
 | ||||
|                 final int length = visitor.length(); | ||||
|                 visitor.incrementBlockQuoteIndent(); | ||||
|                 visitor.visitChildren(blockQuote); | ||||
|                 visitor.setSpans(length, visitor.configuration().factory().blockQuote(visitor.theme())); | ||||
|                 visitor.decrementBlockQuoteIndent(); | ||||
| 
 | ||||
|                 if (visitor.hasNext(blockQuote)) { | ||||
|                     visitor.ensureNewLine(); | ||||
|                     if (visitor.blockQuoteIndent() > 0) { | ||||
|                         visitor.forceNewLine(); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     protected void code(@NonNull MarkwonVisitor.Builder builder) { | ||||
|         builder.on(Code.class, new MarkwonVisitor.NodeVisitor<Code>() { | ||||
|             @Override | ||||
|             public void visit(@NonNull MarkwonVisitor visitor, @NonNull Code code) { | ||||
| 
 | ||||
|                 final int length = visitor.length(); | ||||
| 
 | ||||
|                 // NB, in order to provide a _padding_ feeling code is wrapped inside two unbreakable spaces | ||||
|                 // unfortunately we cannot use this for multiline code as we cannot control where a new line break will be inserted | ||||
|                 visitor.builder() | ||||
|                         .append('\u00a0') | ||||
|                         .append(code.getLiteral()) | ||||
|                         .append('\u00a0'); | ||||
| 
 | ||||
|                 visitor.setSpans(length, visitor.configuration().factory().code(visitor.theme(), false)); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     protected void fencedCodeBlock(@NonNull MarkwonVisitor.Builder builder) { | ||||
|         builder.on(FencedCodeBlock.class, new MarkwonVisitor.NodeVisitor<FencedCodeBlock>() { | ||||
|             @Override | ||||
|             public void visit(@NonNull MarkwonVisitor visitor, @NonNull FencedCodeBlock fencedCodeBlock) { | ||||
|                 visitCodeBlock(visitor, fencedCodeBlock.getInfo(), fencedCodeBlock.getLiteral(), fencedCodeBlock); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     protected void indentedCodeBlock(@NonNull MarkwonVisitor.Builder builder) { | ||||
|         builder.on(IndentedCodeBlock.class, new MarkwonVisitor.NodeVisitor<IndentedCodeBlock>() { | ||||
|             @Override | ||||
|             public void visit(@NonNull MarkwonVisitor visitor, @NonNull IndentedCodeBlock indentedCodeBlock) { | ||||
|                 visitCodeBlock(visitor, null, indentedCodeBlock.getLiteral(), indentedCodeBlock); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     protected void visitCodeBlock( | ||||
|             @NonNull MarkwonVisitor visitor, | ||||
|             @Nullable String info, | ||||
|             @NonNull String code, | ||||
|             @NonNull Node node) { | ||||
| 
 | ||||
|         visitor.ensureNewLine(); | ||||
| 
 | ||||
|         final int length = visitor.length(); | ||||
| 
 | ||||
|         visitor.builder() | ||||
|                 .append('\u00a0').append('\n') | ||||
|                 .append(visitor.configuration().syntaxHighlight().highlight(info, code)); | ||||
| 
 | ||||
|         visitor.ensureNewLine(); | ||||
| 
 | ||||
|         visitor.builder().append('\u00a0'); | ||||
| 
 | ||||
|         visitor.setSpans(length, visitor.configuration().factory().code(visitor.theme(), true)); | ||||
| 
 | ||||
|         if (visitor.hasNext(node)) { | ||||
|             visitor.ensureNewLine(); | ||||
|             visitor.forceNewLine(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     protected void bulletList(@NonNull MarkwonVisitor.Builder builder) { | ||||
|         builder.on(BulletList.class, new MarkwonVisitor.NodeVisitor<BulletList>() { | ||||
|             @Override | ||||
|             public void visit(@NonNull MarkwonVisitor visitor, @NonNull BulletList bulletList) { | ||||
|                 visitList(visitor, bulletList); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     protected void orderedList(@NonNull MarkwonVisitor.Builder builder) { | ||||
|         builder.on(OrderedList.class, new MarkwonVisitor.NodeVisitor<OrderedList>() { | ||||
|             @Override | ||||
|             public void visit(@NonNull MarkwonVisitor visitor, @NonNull OrderedList orderedList) { | ||||
|                 visitList(visitor, orderedList); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     protected void visitList(@NonNull MarkwonVisitor visitor, @NonNull Node node) { | ||||
| 
 | ||||
|         visitor.ensureNewLine(); | ||||
| 
 | ||||
|         visitor.visitChildren(node); | ||||
| 
 | ||||
|         if (visitor.hasNext(node)) { | ||||
|             visitor.ensureNewLine(); | ||||
|             if (visitor.listLevel() == 0 | ||||
|                     && visitor.blockQuoteIndent() == 0) { | ||||
|                 visitor.forceNewLine(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     protected void listItem(@NonNull MarkwonVisitor.Builder builder) { | ||||
|         builder.on(ListItem.class, new MarkwonVisitor.NodeVisitor<ListItem>() { | ||||
|             @Override | ||||
|             public void visit(@NonNull MarkwonVisitor visitor, @NonNull ListItem listItem) { | ||||
| 
 | ||||
|                 final int length = visitor.length(); | ||||
| 
 | ||||
|                 visitor.incrementBlockQuoteIndent(); | ||||
|                 visitor.incrementListLevel(); | ||||
| 
 | ||||
|                 final Node parent = listItem.getParent(); | ||||
|                 if (parent instanceof OrderedList) { | ||||
| 
 | ||||
|                     final int start = ((OrderedList) parent).getStartNumber(); | ||||
| 
 | ||||
|                     visitor.visitChildren(listItem); | ||||
|                     visitor.setSpans(length, visitor.configuration().factory().orderedListItem(visitor.theme(), start)); | ||||
| 
 | ||||
| 
 | ||||
|                     // after we have visited the children increment start number | ||||
|                     final OrderedList orderedList = (OrderedList) parent; | ||||
|                     orderedList.setStartNumber(orderedList.getStartNumber() + 1); | ||||
| 
 | ||||
|                 } else { | ||||
| 
 | ||||
|                     visitor.visitChildren(listItem); | ||||
|                     visitor.setSpans(length, visitor.configuration().factory().bulletListItem(visitor.theme(), visitor.listLevel() - 1)); | ||||
| 
 | ||||
|                 } | ||||
| 
 | ||||
|                 visitor.decrementBlockQuoteIndent(); | ||||
|                 visitor.decrementListLevel(); | ||||
| 
 | ||||
|                 if (visitor.hasNext(listItem)) { | ||||
|                     visitor.ensureNewLine(); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     protected void thematicBreak(@NonNull MarkwonVisitor.Builder builder) { | ||||
|         builder.on(ThematicBreak.class, new MarkwonVisitor.NodeVisitor<ThematicBreak>() { | ||||
|             @Override | ||||
|             public void visit(@NonNull MarkwonVisitor visitor, @NonNull ThematicBreak thematicBreak) { | ||||
| 
 | ||||
|                 visitor.ensureNewLine(); | ||||
| 
 | ||||
|                 final int length = visitor.length(); | ||||
| 
 | ||||
|                 // without space it won't render | ||||
|                 visitor.builder().append('\u00a0'); | ||||
| 
 | ||||
|                 visitor.setSpans(length, visitor.configuration().factory().thematicBreak(visitor.theme())); | ||||
| 
 | ||||
|                 if (visitor.hasNext(thematicBreak)) { | ||||
|                     visitor.ensureNewLine(); | ||||
|                     visitor.forceNewLine(); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| } | ||||
| @ -38,10 +38,10 @@ import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import ru.noties.markwon.SpannableBuilder; | ||||
| import ru.noties.markwon.SpannableConfiguration; | ||||
| import ru.noties.markwon.MarkwonConfiguration; | ||||
| import ru.noties.markwon.SpannableFactory; | ||||
| import ru.noties.markwon.html.api.MarkwonHtmlParser; | ||||
| import ru.noties.markwon.spans.SpannableTheme; | ||||
| import ru.noties.markwon.spans.MarkwonTheme; | ||||
| import ru.noties.markwon.spans.TableRowSpan; | ||||
| import ru.noties.markwon.tasklist.TaskListBlock; | ||||
| import ru.noties.markwon.tasklist.TaskListItem; | ||||
| @ -49,11 +49,11 @@ import ru.noties.markwon.tasklist.TaskListItem; | ||||
| @SuppressWarnings("WeakerAccess") | ||||
| public class SpannableMarkdownVisitor extends AbstractVisitor { | ||||
| 
 | ||||
|     private final SpannableConfiguration configuration; | ||||
|     private final MarkwonConfiguration configuration; | ||||
|     private final SpannableBuilder builder; | ||||
|     private final MarkwonHtmlParser htmlParser; | ||||
| 
 | ||||
|     private final SpannableTheme theme; | ||||
|     private final MarkwonTheme theme; | ||||
|     private final SpannableFactory factory; | ||||
| 
 | ||||
|     private int blockQuoteIndent; | ||||
| @ -64,7 +64,7 @@ public class SpannableMarkdownVisitor extends AbstractVisitor { | ||||
|     private int tableRows; | ||||
| 
 | ||||
|     public SpannableMarkdownVisitor( | ||||
|             @NonNull SpannableConfiguration configuration, | ||||
|             @NonNull MarkwonConfiguration configuration, | ||||
|             @NonNull SpannableBuilder builder | ||||
|     ) { | ||||
|         this.configuration = configuration; | ||||
|  | ||||
| @ -4,13 +4,13 @@ import android.support.annotation.NonNull; | ||||
| 
 | ||||
| import org.commonmark.node.Node; | ||||
| 
 | ||||
| import ru.noties.markwon.MarkwonConfiguration; | ||||
| import ru.noties.markwon.SpannableBuilder; | ||||
| import ru.noties.markwon.SpannableConfiguration; | ||||
| 
 | ||||
| public class SpannableRenderer { | ||||
| 
 | ||||
|     @NonNull | ||||
|     public CharSequence render(@NonNull SpannableConfiguration configuration, @NonNull Node node) { | ||||
|     public CharSequence render(@NonNull MarkwonConfiguration configuration, @NonNull Node node) { | ||||
|         final SpannableBuilder builder = new SpannableBuilder(); | ||||
|         node.accept(new SpannableMarkdownVisitor(configuration, builder)); | ||||
|         return builder.text(); | ||||
|  | ||||
| @ -9,7 +9,7 @@ import java.util.Locale; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| import ru.noties.markwon.SpannableBuilder; | ||||
| import ru.noties.markwon.SpannableConfiguration; | ||||
| 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; | ||||
| @ -30,7 +30,7 @@ import ru.noties.markwon.renderer.html2.tag.UnderlineHandler; | ||||
| public abstract class MarkwonHtmlRenderer { | ||||
| 
 | ||||
|     public abstract void render( | ||||
|             @NonNull SpannableConfiguration configuration, | ||||
|             @NonNull MarkwonConfiguration configuration, | ||||
|             @NonNull SpannableBuilder builder, | ||||
|             @NonNull MarkwonHtmlParser parser | ||||
|     ); | ||||
|  | ||||
| @ -7,7 +7,7 @@ import java.util.List; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| import ru.noties.markwon.SpannableBuilder; | ||||
| import ru.noties.markwon.SpannableConfiguration; | ||||
| 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; | ||||
| @ -22,7 +22,7 @@ class MarkwonHtmlRendererImpl extends MarkwonHtmlRenderer { | ||||
| 
 | ||||
|     @Override | ||||
|     public void render( | ||||
|             @NonNull final SpannableConfiguration configuration, | ||||
|             @NonNull final MarkwonConfiguration configuration, | ||||
|             @NonNull final SpannableBuilder builder, | ||||
|             @NonNull MarkwonHtmlParser parser) { | ||||
| 
 | ||||
|  | ||||
| @ -3,14 +3,14 @@ package ru.noties.markwon.renderer.html2.tag; | ||||
| import android.support.annotation.NonNull; | ||||
| 
 | ||||
| import ru.noties.markwon.SpannableBuilder; | ||||
| import ru.noties.markwon.SpannableConfiguration; | ||||
| import ru.noties.markwon.MarkwonConfiguration; | ||||
| import ru.noties.markwon.html.api.HtmlTag; | ||||
| 
 | ||||
| public class BlockquoteHandler extends TagHandler { | ||||
| 
 | ||||
|     @Override | ||||
|     public void handle( | ||||
|             @NonNull SpannableConfiguration configuration, | ||||
|             @NonNull MarkwonConfiguration configuration, | ||||
|             @NonNull SpannableBuilder builder, | ||||
|             @NonNull HtmlTag tag) { | ||||
| 
 | ||||
|  | ||||
| @ -3,13 +3,13 @@ package ru.noties.markwon.renderer.html2.tag; | ||||
| import android.support.annotation.NonNull; | ||||
| import android.support.annotation.Nullable; | ||||
| 
 | ||||
| import ru.noties.markwon.SpannableConfiguration; | ||||
| import ru.noties.markwon.MarkwonConfiguration; | ||||
| import ru.noties.markwon.html.api.HtmlTag; | ||||
| 
 | ||||
| public class EmphasisHandler extends SimpleTagHandler { | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object getSpans(@NonNull SpannableConfiguration configuration, @NonNull HtmlTag tag) { | ||||
|     public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull HtmlTag tag) { | ||||
|         return configuration.factory().emphasis(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -3,7 +3,7 @@ package ru.noties.markwon.renderer.html2.tag; | ||||
| import android.support.annotation.NonNull; | ||||
| import android.support.annotation.Nullable; | ||||
| 
 | ||||
| import ru.noties.markwon.SpannableConfiguration; | ||||
| import ru.noties.markwon.MarkwonConfiguration; | ||||
| import ru.noties.markwon.html.api.HtmlTag; | ||||
| 
 | ||||
| public class HeadingHandler extends SimpleTagHandler { | ||||
| @ -16,7 +16,7 @@ public class HeadingHandler extends SimpleTagHandler { | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object getSpans(@NonNull SpannableConfiguration configuration, @NonNull HtmlTag tag) { | ||||
|     public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull HtmlTag tag) { | ||||
|         return configuration.factory().heading(configuration.theme(), level); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -6,7 +6,7 @@ import android.text.TextUtils; | ||||
| 
 | ||||
| import java.util.Map; | ||||
| 
 | ||||
| import ru.noties.markwon.SpannableConfiguration; | ||||
| import ru.noties.markwon.MarkwonConfiguration; | ||||
| import ru.noties.markwon.html.api.HtmlTag; | ||||
| import ru.noties.markwon.renderer.ImageSize; | ||||
| import ru.noties.markwon.renderer.html2.CssInlineStyleParser; | ||||
| @ -31,7 +31,7 @@ public class ImageHandler extends SimpleTagHandler { | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object getSpans(@NonNull SpannableConfiguration configuration, @NonNull HtmlTag tag) { | ||||
|     public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull HtmlTag tag) { | ||||
| 
 | ||||
|         final Map<String, String> attributes = tag.attributes(); | ||||
|         final String src = attributes.get("src"); | ||||
|  | ||||
| @ -4,13 +4,13 @@ import android.support.annotation.NonNull; | ||||
| import android.support.annotation.Nullable; | ||||
| import android.text.TextUtils; | ||||
| 
 | ||||
| import ru.noties.markwon.SpannableConfiguration; | ||||
| import ru.noties.markwon.MarkwonConfiguration; | ||||
| import ru.noties.markwon.html.api.HtmlTag; | ||||
| 
 | ||||
| public class LinkHandler extends SimpleTagHandler { | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object getSpans(@NonNull SpannableConfiguration configuration, @NonNull HtmlTag tag) { | ||||
|     public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull HtmlTag tag) { | ||||
|         final String destination = tag.attributes().get("href"); | ||||
|         if (!TextUtils.isEmpty(destination)) { | ||||
|             return configuration.factory().link( | ||||
|  | ||||
| @ -2,15 +2,15 @@ package ru.noties.markwon.renderer.html2.tag; | ||||
| 
 | ||||
| import android.support.annotation.NonNull; | ||||
| 
 | ||||
| import ru.noties.markwon.MarkwonConfiguration; | ||||
| import ru.noties.markwon.SpannableBuilder; | ||||
| import ru.noties.markwon.SpannableConfiguration; | ||||
| import ru.noties.markwon.html.api.HtmlTag; | ||||
| 
 | ||||
| public class ListHandler extends TagHandler { | ||||
| 
 | ||||
|     @Override | ||||
|     public void handle( | ||||
|             @NonNull SpannableConfiguration configuration, | ||||
|             @NonNull MarkwonConfiguration configuration, | ||||
|             @NonNull SpannableBuilder builder, | ||||
|             @NonNull HtmlTag tag) { | ||||
| 
 | ||||
|  | ||||
| @ -4,16 +4,16 @@ import android.support.annotation.NonNull; | ||||
| import android.support.annotation.Nullable; | ||||
| 
 | ||||
| import ru.noties.markwon.SpannableBuilder; | ||||
| import ru.noties.markwon.SpannableConfiguration; | ||||
| import ru.noties.markwon.MarkwonConfiguration; | ||||
| import ru.noties.markwon.html.api.HtmlTag; | ||||
| 
 | ||||
| public abstract class SimpleTagHandler extends TagHandler { | ||||
| 
 | ||||
|     @Nullable | ||||
|     public abstract Object getSpans(@NonNull SpannableConfiguration configuration, @NonNull HtmlTag tag); | ||||
|     public abstract Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull HtmlTag tag); | ||||
| 
 | ||||
|     @Override | ||||
|     public void handle(@NonNull SpannableConfiguration configuration, @NonNull SpannableBuilder builder, @NonNull HtmlTag tag) { | ||||
|     public void handle(@NonNull MarkwonConfiguration configuration, @NonNull SpannableBuilder builder, @NonNull HtmlTag tag) { | ||||
|         final Object spans = getSpans(configuration, tag); | ||||
|         if (spans != null) { | ||||
|             SpannableBuilder.setSpans(builder, spans, tag.start(), tag.end()); | ||||
|  | ||||
| @ -2,15 +2,15 @@ package ru.noties.markwon.renderer.html2.tag; | ||||
| 
 | ||||
| import android.support.annotation.NonNull; | ||||
| 
 | ||||
| import ru.noties.markwon.MarkwonConfiguration; | ||||
| import ru.noties.markwon.SpannableBuilder; | ||||
| import ru.noties.markwon.SpannableConfiguration; | ||||
| import ru.noties.markwon.html.api.HtmlTag; | ||||
| 
 | ||||
| public class StrikeHandler extends TagHandler { | ||||
| 
 | ||||
|     @Override | ||||
|     public void handle( | ||||
|             @NonNull SpannableConfiguration configuration, | ||||
|             @NonNull MarkwonConfiguration configuration, | ||||
|             @NonNull SpannableBuilder builder, | ||||
|             @NonNull HtmlTag tag) { | ||||
| 
 | ||||
|  | ||||
| @ -3,13 +3,13 @@ package ru.noties.markwon.renderer.html2.tag; | ||||
| import android.support.annotation.NonNull; | ||||
| import android.support.annotation.Nullable; | ||||
| 
 | ||||
| import ru.noties.markwon.SpannableConfiguration; | ||||
| import ru.noties.markwon.MarkwonConfiguration; | ||||
| import ru.noties.markwon.html.api.HtmlTag; | ||||
| 
 | ||||
| public class StrongEmphasisHandler extends SimpleTagHandler { | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object getSpans(@NonNull SpannableConfiguration configuration, @NonNull HtmlTag tag) { | ||||
|     public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull HtmlTag tag) { | ||||
|         return configuration.factory().strongEmphasis(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -3,13 +3,13 @@ package ru.noties.markwon.renderer.html2.tag; | ||||
| import android.support.annotation.NonNull; | ||||
| import android.support.annotation.Nullable; | ||||
| 
 | ||||
| import ru.noties.markwon.SpannableConfiguration; | ||||
| import ru.noties.markwon.MarkwonConfiguration; | ||||
| import ru.noties.markwon.html.api.HtmlTag; | ||||
| 
 | ||||
| public class SubScriptHandler extends SimpleTagHandler { | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object getSpans(@NonNull SpannableConfiguration configuration, @NonNull HtmlTag tag) { | ||||
|     public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull HtmlTag tag) { | ||||
|         return configuration.factory().subScript(configuration.theme()); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -3,13 +3,13 @@ package ru.noties.markwon.renderer.html2.tag; | ||||
| import android.support.annotation.NonNull; | ||||
| import android.support.annotation.Nullable; | ||||
| 
 | ||||
| import ru.noties.markwon.SpannableConfiguration; | ||||
| import ru.noties.markwon.MarkwonConfiguration; | ||||
| import ru.noties.markwon.html.api.HtmlTag; | ||||
| 
 | ||||
| public class SuperScriptHandler extends SimpleTagHandler { | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object getSpans(@NonNull SpannableConfiguration configuration, @NonNull HtmlTag tag) { | ||||
|     public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull HtmlTag tag) { | ||||
|         return configuration.factory().superScript(configuration.theme()); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -2,20 +2,20 @@ package ru.noties.markwon.renderer.html2.tag; | ||||
| 
 | ||||
| import android.support.annotation.NonNull; | ||||
| 
 | ||||
| import ru.noties.markwon.MarkwonConfiguration; | ||||
| import ru.noties.markwon.SpannableBuilder; | ||||
| import ru.noties.markwon.SpannableConfiguration; | ||||
| import ru.noties.markwon.html.api.HtmlTag; | ||||
| 
 | ||||
| public abstract class TagHandler { | ||||
| 
 | ||||
|     public abstract void handle( | ||||
|             @NonNull SpannableConfiguration configuration, | ||||
|             @NonNull MarkwonConfiguration configuration, | ||||
|             @NonNull SpannableBuilder builder, | ||||
|             @NonNull HtmlTag tag | ||||
|     ); | ||||
| 
 | ||||
|     protected static void visitChildren( | ||||
|             @NonNull SpannableConfiguration configuration, | ||||
|             @NonNull MarkwonConfiguration configuration, | ||||
|             @NonNull SpannableBuilder builder, | ||||
|             @NonNull HtmlTag.Block block) { | ||||
| 
 | ||||
|  | ||||
| @ -3,14 +3,14 @@ package ru.noties.markwon.renderer.html2.tag; | ||||
| import android.support.annotation.NonNull; | ||||
| 
 | ||||
| import ru.noties.markwon.SpannableBuilder; | ||||
| import ru.noties.markwon.SpannableConfiguration; | ||||
| import ru.noties.markwon.MarkwonConfiguration; | ||||
| import ru.noties.markwon.html.api.HtmlTag; | ||||
| 
 | ||||
| public class UnderlineHandler extends TagHandler { | ||||
| 
 | ||||
|     @Override | ||||
|     public void handle( | ||||
|             @NonNull SpannableConfiguration configuration, | ||||
|             @NonNull MarkwonConfiguration configuration, | ||||
|             @NonNull SpannableBuilder builder, | ||||
|             @NonNull HtmlTag tag) { | ||||
| 
 | ||||
|  | ||||
| @ -24,24 +24,24 @@ public class AsyncDrawableSpan extends ReplacementSpan { | ||||
|     public static final int ALIGN_BASELINE = 1; | ||||
|     public static final int ALIGN_CENTER = 2; // will only center if drawable height is less than text line height | ||||
| 
 | ||||
|     private final SpannableTheme theme; | ||||
|     private final MarkwonTheme theme; | ||||
|     private final AsyncDrawable drawable; | ||||
|     private final int alignment; | ||||
|     private final boolean replacementTextIsLink; | ||||
| 
 | ||||
|     public AsyncDrawableSpan(@NonNull SpannableTheme theme, @NonNull AsyncDrawable drawable) { | ||||
|     public AsyncDrawableSpan(@NonNull MarkwonTheme theme, @NonNull AsyncDrawable drawable) { | ||||
|         this(theme, drawable, ALIGN_BOTTOM); | ||||
|     } | ||||
| 
 | ||||
|     public AsyncDrawableSpan( | ||||
|             @NonNull SpannableTheme theme, | ||||
|             @NonNull MarkwonTheme theme, | ||||
|             @NonNull AsyncDrawable drawable, | ||||
|             @Alignment int alignment) { | ||||
|         this(theme, drawable, alignment, false); | ||||
|     } | ||||
| 
 | ||||
|     public AsyncDrawableSpan( | ||||
|             @NonNull SpannableTheme theme, | ||||
|             @NonNull MarkwonTheme theme, | ||||
|             @NonNull AsyncDrawable drawable, | ||||
|             @Alignment int alignment, | ||||
|             boolean replacementTextIsLink) { | ||||
|  | ||||
| @ -9,11 +9,11 @@ import android.text.style.LeadingMarginSpan; | ||||
| 
 | ||||
| public class BlockQuoteSpan implements LeadingMarginSpan { | ||||
| 
 | ||||
|     private final SpannableTheme theme; | ||||
|     private final MarkwonTheme theme; | ||||
|     private final Rect rect = ObjectsPool.rect(); | ||||
|     private final Paint paint = ObjectsPool.paint(); | ||||
| 
 | ||||
|     public BlockQuoteSpan(@NonNull SpannableTheme theme) { | ||||
|     public BlockQuoteSpan(@NonNull MarkwonTheme theme) { | ||||
|         this.theme = theme; | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -9,9 +9,11 @@ import android.support.annotation.NonNull; | ||||
| import android.text.Layout; | ||||
| import android.text.style.LeadingMarginSpan; | ||||
| 
 | ||||
| import ru.noties.markwon.utils.LeadingMarginUtils; | ||||
| 
 | ||||
| public class BulletListItemSpan implements LeadingMarginSpan { | ||||
| 
 | ||||
|     private SpannableTheme theme; | ||||
|     private MarkwonTheme theme; | ||||
| 
 | ||||
|     private final Paint paint = ObjectsPool.paint(); | ||||
|     private final RectF circle = ObjectsPool.rectF(); | ||||
| @ -20,7 +22,7 @@ public class BulletListItemSpan implements LeadingMarginSpan { | ||||
|     private final int level; | ||||
| 
 | ||||
|     public BulletListItemSpan( | ||||
|             @NonNull SpannableTheme theme, | ||||
|             @NonNull MarkwonTheme theme, | ||||
|             @IntRange(from = 0) int level) { | ||||
|         this.theme = theme; | ||||
|         this.level = level; | ||||
|  | ||||
| @ -11,13 +11,13 @@ import android.text.style.MetricAffectingSpan; | ||||
| 
 | ||||
| public class CodeSpan extends MetricAffectingSpan implements LeadingMarginSpan { | ||||
| 
 | ||||
|     private final SpannableTheme theme; | ||||
|     private final MarkwonTheme theme; | ||||
|     private final Rect rect = ObjectsPool.rect(); | ||||
|     private final Paint paint = ObjectsPool.paint(); | ||||
| 
 | ||||
|     private final boolean multiline; | ||||
| 
 | ||||
|     public CodeSpan(@NonNull SpannableTheme theme, boolean multiline) { | ||||
|     public CodeSpan(@NonNull MarkwonTheme theme, boolean multiline) { | ||||
|         this.theme = theme; | ||||
|         this.multiline = multiline; | ||||
|     } | ||||
|  | ||||
| @ -10,14 +10,16 @@ import android.text.TextPaint; | ||||
| import android.text.style.LeadingMarginSpan; | ||||
| import android.text.style.MetricAffectingSpan; | ||||
| 
 | ||||
| import ru.noties.markwon.utils.LeadingMarginUtils; | ||||
| 
 | ||||
| public class HeadingSpan extends MetricAffectingSpan implements LeadingMarginSpan { | ||||
| 
 | ||||
|     private final SpannableTheme theme; | ||||
|     private final MarkwonTheme theme; | ||||
|     private final Rect rect = ObjectsPool.rect(); | ||||
|     private final Paint paint = ObjectsPool.paint(); | ||||
|     private final int level; | ||||
| 
 | ||||
|     public HeadingSpan(@NonNull SpannableTheme theme, @IntRange(from = 1, to = 6) int level) { | ||||
|     public HeadingSpan(@NonNull MarkwonTheme theme, @IntRange(from = 1, to = 6) int level) { | ||||
|         this.theme = theme; | ||||
|         this.level = level; | ||||
|     } | ||||
|  | ||||
| @ -2,7 +2,6 @@ package ru.noties.markwon.spans; | ||||
| 
 | ||||
| import android.support.annotation.NonNull; | ||||
| import android.text.TextPaint; | ||||
| import android.text.style.ClickableSpan; | ||||
| import android.text.style.URLSpan; | ||||
| import android.view.View; | ||||
| 
 | ||||
| @ -12,11 +11,11 @@ public class LinkSpan extends URLSpan { | ||||
|         void resolve(View view, @NonNull String link); | ||||
|     } | ||||
| 
 | ||||
|     private final SpannableTheme theme; | ||||
|     private final MarkwonTheme theme; | ||||
|     private final String link; | ||||
|     private final Resolver resolver; | ||||
| 
 | ||||
|     public LinkSpan(@NonNull SpannableTheme theme, @NonNull String link, @NonNull Resolver resolver) { | ||||
|     public LinkSpan(@NonNull MarkwonTheme theme, @NonNull String link, @NonNull Resolver resolver) { | ||||
|         super(link); | ||||
|         this.theme = theme; | ||||
|         this.link = link; | ||||
|  | ||||
| @ -7,7 +7,6 @@ import android.graphics.Typeface; | ||||
| import android.graphics.drawable.Drawable; | ||||
| import android.support.annotation.AttrRes; | ||||
| import android.support.annotation.ColorInt; | ||||
| import android.support.annotation.Dimension; | ||||
| import android.support.annotation.FloatRange; | ||||
| import android.support.annotation.IntRange; | ||||
| import android.support.annotation.NonNull; | ||||
| @ -20,19 +19,21 @@ import android.util.TypedValue; | ||||
| import java.util.Arrays; | ||||
| import java.util.Locale; | ||||
| 
 | ||||
| import ru.noties.markwon.tasklist.TaskListDrawable; | ||||
| 
 | ||||
| @SuppressWarnings("WeakerAccess") | ||||
| public class SpannableTheme { | ||||
| public class MarkwonTheme { | ||||
| 
 | ||||
|     /** | ||||
|      * Factory method to obtain an instance of {@link SpannableTheme} with all values as defaults | ||||
|      * Factory method to obtain an instance of {@link MarkwonTheme} with all values as defaults | ||||
|      * | ||||
|      * @param context Context in order to resolve defaults | ||||
|      * @return {@link SpannableTheme} instance | ||||
|      * @return {@link MarkwonTheme} instance | ||||
|      * @see #builderWithDefaults(Context) | ||||
|      * @since 1.0.0 | ||||
|      */ | ||||
|     @NonNull | ||||
|     public static SpannableTheme create(@NonNull Context context) { | ||||
|     public static MarkwonTheme create(@NonNull Context context) { | ||||
|         return builderWithDefaults(context).build(); | ||||
|     } | ||||
| 
 | ||||
| @ -43,7 +44,7 @@ public class SpannableTheme { | ||||
|      * | ||||
|      * @return {@link Builder instance} | ||||
|      * @see #builderWithDefaults(Context) | ||||
|      * @see #builder(SpannableTheme) | ||||
|      * @see #builder(MarkwonTheme) | ||||
|      * @since 1.0.0 | ||||
|      */ | ||||
|     @NonNull | ||||
| @ -53,15 +54,15 @@ public class SpannableTheme { | ||||
| 
 | ||||
|     /** | ||||
|      * Factory method to create a {@link Builder} instance and initialize it with values | ||||
|      * from supplied {@link SpannableTheme} | ||||
|      * from supplied {@link MarkwonTheme} | ||||
|      * | ||||
|      * @param copyFrom {@link SpannableTheme} to copy values from | ||||
|      * @param copyFrom {@link MarkwonTheme} to copy values from | ||||
|      * @return {@link Builder} instance | ||||
|      * @see #builderWithDefaults(Context) | ||||
|      * @since 1.0.0 | ||||
|      */ | ||||
|     @NonNull | ||||
|     public static Builder builder(@NonNull SpannableTheme copyFrom) { | ||||
|     public static Builder builder(@NonNull MarkwonTheme copyFrom) { | ||||
|         return new Builder(copyFrom); | ||||
|     } | ||||
| 
 | ||||
| @ -217,9 +218,10 @@ public class SpannableTheme { | ||||
| 
 | ||||
|     // drawable that will be used to render checkbox (should be stateful) | ||||
|     // TaskListDrawable can be used | ||||
|     @Deprecated | ||||
|     protected final Drawable taskListDrawable; | ||||
| 
 | ||||
|     protected SpannableTheme(@NonNull Builder builder) { | ||||
|     protected MarkwonTheme(@NonNull Builder builder) { | ||||
|         this.linkColor = builder.linkColor; | ||||
|         this.blockMargin = builder.blockMargin; | ||||
|         this.blockQuoteWidth = builder.blockQuoteWidth; | ||||
| @ -526,6 +528,7 @@ public class SpannableTheme { | ||||
|      * @since 1.0.1 | ||||
|      */ | ||||
|     @Nullable | ||||
|     @Deprecated | ||||
|     public Drawable getTaskListDrawable() { | ||||
|         return taskListDrawable; | ||||
|     } | ||||
| @ -565,7 +568,7 @@ public class SpannableTheme { | ||||
|         Builder() { | ||||
|         } | ||||
| 
 | ||||
|         Builder(@NonNull SpannableTheme theme) { | ||||
|         Builder(@NonNull MarkwonTheme theme) { | ||||
|             this.linkColor = theme.linkColor; | ||||
|             this.blockMargin = theme.blockMargin; | ||||
|             this.blockQuoteWidth = theme.blockQuoteWidth; | ||||
| @ -792,14 +795,15 @@ public class SpannableTheme { | ||||
|          * @since 1.0.1 | ||||
|          */ | ||||
|         @NonNull | ||||
|         @Deprecated | ||||
|         public Builder taskListDrawable(@NonNull Drawable taskListDrawable) { | ||||
|             this.taskListDrawable = taskListDrawable; | ||||
|             return this; | ||||
|         } | ||||
| 
 | ||||
|         @NonNull | ||||
|         public SpannableTheme build() { | ||||
|             return new SpannableTheme(this); | ||||
|         public MarkwonTheme build() { | ||||
|             return new MarkwonTheme(this); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -9,6 +9,8 @@ import android.text.TextPaint; | ||||
| import android.text.style.LeadingMarginSpan; | ||||
| import android.widget.TextView; | ||||
| 
 | ||||
| import ru.noties.markwon.utils.LeadingMarginUtils; | ||||
| 
 | ||||
| public class OrderedListItemSpan implements LeadingMarginSpan { | ||||
| 
 | ||||
|     /** | ||||
| @ -42,7 +44,7 @@ public class OrderedListItemSpan implements LeadingMarginSpan { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private final SpannableTheme theme; | ||||
|     private final MarkwonTheme theme; | ||||
|     private final String number; | ||||
|     private final Paint paint = ObjectsPool.paint(); | ||||
| 
 | ||||
| @ -52,7 +54,7 @@ public class OrderedListItemSpan implements LeadingMarginSpan { | ||||
|     private int margin; | ||||
| 
 | ||||
|     public OrderedListItemSpan( | ||||
|             @NonNull SpannableTheme theme, | ||||
|             @NonNull MarkwonTheme theme, | ||||
|             @NonNull String number | ||||
|     ) { | ||||
|         this.theme = theme; | ||||
|  | ||||
| @ -6,9 +6,9 @@ import android.text.style.MetricAffectingSpan; | ||||
| 
 | ||||
| public class SubScriptSpan extends MetricAffectingSpan { | ||||
| 
 | ||||
|     private final SpannableTheme theme; | ||||
|     private final MarkwonTheme theme; | ||||
| 
 | ||||
|     public SubScriptSpan(@NonNull SpannableTheme theme) { | ||||
|     public SubScriptSpan(@NonNull MarkwonTheme theme) { | ||||
|         this.theme = theme; | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -6,9 +6,9 @@ import android.text.style.MetricAffectingSpan; | ||||
| 
 | ||||
| public class SuperScriptSpan extends MetricAffectingSpan { | ||||
| 
 | ||||
|     private final SpannableTheme theme; | ||||
|     private final MarkwonTheme theme; | ||||
| 
 | ||||
|     public SuperScriptSpan(@NonNull SpannableTheme theme) { | ||||
|     public SuperScriptSpan(@NonNull MarkwonTheme theme) { | ||||
|         this.theme = theme; | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -61,7 +61,7 @@ public class TableRowSpan extends ReplacementSpan { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private final SpannableTheme theme; | ||||
|     private final MarkwonTheme theme; | ||||
|     private final List<Cell> cells; | ||||
|     private final List<StaticLayout> layouts; | ||||
|     private final TextPaint textPaint; | ||||
| @ -76,7 +76,7 @@ public class TableRowSpan extends ReplacementSpan { | ||||
|     private Invalidator invalidator; | ||||
| 
 | ||||
|     public TableRowSpan( | ||||
|             @NonNull SpannableTheme theme, | ||||
|             @NonNull MarkwonTheme theme, | ||||
|             @NonNull List<Cell> cells, | ||||
|             boolean header, | ||||
|             boolean odd) { | ||||
|  | ||||
| @ -9,11 +9,11 @@ import android.text.style.LeadingMarginSpan; | ||||
| 
 | ||||
| public class ThematicBreakSpan implements LeadingMarginSpan { | ||||
| 
 | ||||
|     private final SpannableTheme theme; | ||||
|     private final MarkwonTheme theme; | ||||
|     private final Rect rect = ObjectsPool.rect(); | ||||
|     private final Paint paint = ObjectsPool.paint(); | ||||
| 
 | ||||
|     public ThematicBreakSpan(@NonNull SpannableTheme theme) { | ||||
|     public ThematicBreakSpan(@NonNull MarkwonTheme theme) { | ||||
|         this.theme = theme; | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| package ru.noties.markwon.spans; | ||||
| package ru.noties.markwon.tasklist; | ||||
| 
 | ||||
| import android.graphics.Canvas; | ||||
| import android.graphics.ColorFilter; | ||||
| @ -7,6 +7,7 @@ import org.commonmark.parser.Parser; | ||||
| /** | ||||
|  * @since 1.0.1 | ||||
|  */ | ||||
| @Deprecated | ||||
| public class TaskListExtension implements Parser.ParserExtension { | ||||
| 
 | ||||
|     @NonNull | ||||
|  | ||||
| @ -0,0 +1,93 @@ | ||||
| package ru.noties.markwon.tasklist; | ||||
| 
 | ||||
| import android.content.Context; | ||||
| import android.graphics.drawable.Drawable; | ||||
| import android.support.annotation.ColorInt; | ||||
| import android.support.annotation.NonNull; | ||||
| 
 | ||||
| import org.commonmark.parser.Parser; | ||||
| 
 | ||||
| import ru.noties.markwon.AbstractMarkwonPlugin; | ||||
| import ru.noties.markwon.MarkwonVisitor; | ||||
| 
 | ||||
| public class TaskListPlugin extends AbstractMarkwonPlugin { | ||||
| 
 | ||||
|     /** | ||||
|      * @see TaskListDrawable | ||||
|      */ | ||||
|     @NonNull | ||||
|     public static TaskListPlugin create(@NonNull Drawable drawable) { | ||||
|         return new TaskListPlugin(drawable); | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     public static TaskListPlugin create(@NonNull Context context) { | ||||
|         // resolve link color and background color | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     public static TaskListPlugin create( | ||||
|             @ColorInt int checkedFillColor, | ||||
|             @ColorInt int normalOutlineColor, | ||||
|             @ColorInt int checkMarkColor) { | ||||
|         return new TaskListPlugin(new TaskListDrawable( | ||||
|                 checkedFillColor, | ||||
|                 normalOutlineColor, | ||||
|                 checkMarkColor)); | ||||
|     } | ||||
| 
 | ||||
|     private final Drawable drawable; | ||||
| 
 | ||||
|     private TaskListPlugin(@NonNull Drawable drawable) { | ||||
|         this.drawable = drawable; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void configureParser(@NonNull Parser.Builder builder) { | ||||
|         builder.customBlockParserFactory(new TaskListBlockParser.Factory()); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) { | ||||
|         builder | ||||
|                 .on(TaskListBlock.class, new MarkwonVisitor.NodeVisitor<TaskListBlock>() { | ||||
|                     @Override | ||||
|                     public void visit(@NonNull MarkwonVisitor visitor, @NonNull TaskListBlock taskListBlock) { | ||||
| 
 | ||||
|                         visitor.ensureNewLine(); | ||||
| 
 | ||||
|                         visitor.incrementBlockQuoteIndent(); | ||||
|                         visitor.visitChildren(taskListBlock); | ||||
|                         visitor.decrementBlockQuoteIndent(); | ||||
| 
 | ||||
|                         if (visitor.hasNext(taskListBlock)) { | ||||
|                             visitor.ensureNewLine(); | ||||
|                             visitor.forceNewLine(); | ||||
|                         } | ||||
|                     } | ||||
|                 }) | ||||
|                 .on(TaskListItem.class, new MarkwonVisitor.NodeVisitor<TaskListItem>() { | ||||
|                     @Override | ||||
|                     public void visit(@NonNull MarkwonVisitor visitor, @NonNull TaskListItem taskListItem) { | ||||
| 
 | ||||
|                         final int length = visitor.length(); | ||||
| 
 | ||||
|                         final int indent = visitor.blockQuoteIndent(); | ||||
|                         visitor.blockQuoteIntent(indent + taskListItem.indent()); | ||||
|                         visitor.visitChildren(taskListItem); | ||||
|                         visitor.setSpans(length, new TaskListSpan( | ||||
|                                 visitor.theme(), | ||||
|                                 drawable, | ||||
|                                 visitor.blockQuoteIndent(), | ||||
|                                 taskListItem.done())); | ||||
| 
 | ||||
|                         if (visitor.hasNext(taskListItem)) { | ||||
|                             visitor.ensureNewLine(); | ||||
|                         } | ||||
| 
 | ||||
|                         visitor.blockQuoteIntent(indent); | ||||
|                     } | ||||
|                 }); | ||||
|     } | ||||
| } | ||||
| @ -1,4 +1,4 @@ | ||||
| package ru.noties.markwon.spans; | ||||
| package ru.noties.markwon.tasklist; | ||||
| 
 | ||||
| import android.graphics.Canvas; | ||||
| import android.graphics.Paint; | ||||
| @ -7,6 +7,9 @@ import android.support.annotation.NonNull; | ||||
| import android.text.Layout; | ||||
| import android.text.style.LeadingMarginSpan; | ||||
| 
 | ||||
| import ru.noties.markwon.spans.MarkwonTheme; | ||||
| import ru.noties.markwon.utils.LeadingMarginUtils; | ||||
| 
 | ||||
| /** | ||||
|  * @since 1.0.1 | ||||
|  */ | ||||
| @ -16,14 +19,24 @@ public class TaskListSpan implements LeadingMarginSpan { | ||||
| 
 | ||||
|     private static final int[] STATE_NONE = new int[0]; | ||||
| 
 | ||||
|     private final SpannableTheme theme; | ||||
|     private final MarkwonTheme theme; | ||||
|     private final Drawable drawable; | ||||
|     private final int blockIndent; | ||||
| 
 | ||||
|     // @since 2.0.1 field is NOT final (to allow mutation) | ||||
|     private boolean isDone; | ||||
| 
 | ||||
|     public TaskListSpan(@NonNull SpannableTheme theme, int blockIndent, boolean isDone) { | ||||
|     @Deprecated | ||||
|     public TaskListSpan(@NonNull MarkwonTheme theme, int blockIndent, boolean isDone) { | ||||
|         this.theme = theme; | ||||
|         this.drawable = null; | ||||
|         this.blockIndent = blockIndent; | ||||
|         this.isDone = isDone; | ||||
|     } | ||||
| 
 | ||||
|     public TaskListSpan(@NonNull MarkwonTheme theme, @NonNull Drawable drawable, int blockIndent, boolean isDone) { | ||||
|         this.theme = theme; | ||||
|         this.drawable = drawable; | ||||
|         this.blockIndent = blockIndent; | ||||
|         this.isDone = isDone; | ||||
|     } | ||||
| @ -58,10 +71,10 @@ public class TaskListSpan implements LeadingMarginSpan { | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         final Drawable drawable = theme.getTaskListDrawable(); | ||||
|         if (drawable == null) { | ||||
|             return; | ||||
|         } | ||||
| //        final Drawable drawable = theme.getTaskListDrawable(); | ||||
| //        if (drawable == null) { | ||||
| //            return; | ||||
| //        } | ||||
| 
 | ||||
|         final int save = c.save(); | ||||
|         try { | ||||
| @ -1,14 +1,14 @@ | ||||
| package ru.noties.markwon.spans; | ||||
| package ru.noties.markwon.utils; | ||||
| 
 | ||||
| import android.text.Spanned; | ||||
| 
 | ||||
| abstract class LeadingMarginUtils { | ||||
| public abstract class LeadingMarginUtils { | ||||
| 
 | ||||
|     static boolean selfStart(int start, CharSequence text, Object span) { | ||||
|     public static boolean selfStart(int start, CharSequence text, Object span) { | ||||
|         return text instanceof Spanned && ((Spanned) text).getSpanStart(span) == start; | ||||
|     } | ||||
| 
 | ||||
|     static boolean selfEnd(int end, CharSequence text, Object span) { | ||||
|     public static boolean selfEnd(int end, CharSequence text, Object span) { | ||||
|         return text instanceof Spanned && ((Spanned) text).getSpanEnd(span) == end; | ||||
|     } | ||||
| 
 | ||||
| @ -2,7 +2,7 @@ package ru.noties.markwon.renderer; | ||||
| 
 | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| import ru.noties.markwon.SpannableConfiguration; | ||||
| import ru.noties.markwon.MarkwonConfiguration; | ||||
| import ru.noties.markwon.SpannableFactory; | ||||
| import ru.noties.markwon.SyntaxHighlight; | ||||
| import ru.noties.markwon.UrlProcessor; | ||||
| @ -10,17 +10,17 @@ import ru.noties.markwon.html.api.MarkwonHtmlParser; | ||||
| import ru.noties.markwon.renderer.html2.MarkwonHtmlRenderer; | ||||
| import ru.noties.markwon.spans.AsyncDrawable; | ||||
| import ru.noties.markwon.spans.LinkSpan; | ||||
| import ru.noties.markwon.spans.SpannableTheme; | ||||
| import ru.noties.markwon.spans.MarkwonTheme; | ||||
| 
 | ||||
| import static org.junit.Assert.assertEquals; | ||||
| import static org.mockito.Mockito.mock; | ||||
| public class SpannableConfigurationTest { | ||||
| public class MarkwonConfigurationTest { | ||||
| 
 | ||||
|     @Test | ||||
|     public void testNewBuilder() { | ||||
|         final SpannableConfiguration configuration = SpannableConfiguration | ||||
|         final MarkwonConfiguration configuration = MarkwonConfiguration | ||||
|                 .builder(null) | ||||
|                 .theme(mock(SpannableTheme.class)) | ||||
|                 .theme(mock(MarkwonTheme.class)) | ||||
|                 .asyncDrawableLoader(mock(AsyncDrawable.Loader.class)) | ||||
|                 .syntaxHighlight(mock(SyntaxHighlight.class)) | ||||
|                 .linkResolver(mock(LinkSpan.Resolver.class)) | ||||
| @ -33,7 +33,7 @@ public class SpannableConfigurationTest { | ||||
|                 .htmlAllowNonClosedTags(true) | ||||
|                 .build(); | ||||
| 
 | ||||
|         final SpannableConfiguration newConfiguration = configuration | ||||
|         final MarkwonConfiguration newConfiguration = configuration | ||||
|                 .newBuilder(null) | ||||
|                 .build(); | ||||
| 
 | ||||
| @ -13,11 +13,11 @@ import org.junit.runner.RunWith; | ||||
| import org.robolectric.RobolectricTestRunner; | ||||
| import org.robolectric.annotation.Config; | ||||
| 
 | ||||
| import ru.noties.markwon.MarkwonConfiguration; | ||||
| import ru.noties.markwon.SpannableBuilder; | ||||
| import ru.noties.markwon.SpannableConfiguration; | ||||
| import ru.noties.markwon.SpannableFactory; | ||||
| import ru.noties.markwon.SyntaxHighlight; | ||||
| import ru.noties.markwon.spans.SpannableTheme; | ||||
| import ru.noties.markwon.spans.MarkwonTheme; | ||||
| 
 | ||||
| import static org.junit.Assert.assertEquals; | ||||
| import static org.junit.Assert.assertTrue; | ||||
| @ -63,12 +63,12 @@ public class SyntaxHighlightTest { | ||||
|         }; | ||||
| 
 | ||||
|         final SpannableFactory factory = mock(SpannableFactory.class); | ||||
|         when(factory.code(any(SpannableTheme.class), anyBoolean())).thenReturn(codeSpan); | ||||
|         when(factory.code(any(MarkwonTheme.class), anyBoolean())).thenReturn(codeSpan); | ||||
| 
 | ||||
|         final SpannableConfiguration configuration = SpannableConfiguration.builder(mock(Context.class)) | ||||
|         final MarkwonConfiguration configuration = MarkwonConfiguration.builder(mock(Context.class)) | ||||
|                 .syntaxHighlight(highlight) | ||||
|                 .factory(factory) | ||||
|                 .theme(mock(SpannableTheme.class)) | ||||
|                 .theme(mock(MarkwonTheme.class)) | ||||
|                 .build(); | ||||
| 
 | ||||
|         final SpannableBuilder builder = new SpannableBuilder(); | ||||
|  | ||||
| @ -14,12 +14,12 @@ import java.util.Collection; | ||||
| 
 | ||||
| import ru.noties.markwon.LinkResolverDef; | ||||
| import ru.noties.markwon.Markwon; | ||||
| import ru.noties.markwon.MarkwonConfiguration; | ||||
| import ru.noties.markwon.SpannableBuilder; | ||||
| import ru.noties.markwon.SpannableConfiguration; | ||||
| import ru.noties.markwon.SpannableFactory; | ||||
| import ru.noties.markwon.html.api.MarkwonHtmlParser; | ||||
| import ru.noties.markwon.renderer.SpannableMarkdownVisitor; | ||||
| import ru.noties.markwon.spans.SpannableTheme; | ||||
| import ru.noties.markwon.spans.MarkwonTheme; | ||||
| 
 | ||||
| import static org.junit.Assert.assertEquals; | ||||
| import static org.mockito.Mockito.mock; | ||||
| @ -44,7 +44,7 @@ public class SpannableMarkdownVisitorTest { | ||||
| 
 | ||||
|         final TestData data = TestDataReader.readTest(file); | ||||
| 
 | ||||
|         final SpannableConfiguration configuration = configuration(data.config()); | ||||
|         final MarkwonConfiguration configuration = configuration(data.config()); | ||||
|         final SpannableBuilder builder = new SpannableBuilder(); | ||||
|         final SpannableMarkdownVisitor visitor = new SpannableMarkdownVisitor(configuration, builder); | ||||
|         final Node node = Markwon.createParser().parse(data.input()); | ||||
| @ -73,7 +73,7 @@ public class SpannableMarkdownVisitorTest { | ||||
| 
 | ||||
|     @SuppressWarnings("ConstantConditions") | ||||
|     @NonNull | ||||
|     private SpannableConfiguration configuration(@NonNull TestConfig config) { | ||||
|     private MarkwonConfiguration configuration(@NonNull TestConfig config) { | ||||
| 
 | ||||
|         final SpannableFactory factory = new TestFactory(config.hasOption(TestConfig.USE_PARAGRAPHS)); | ||||
|         final MarkwonHtmlParser htmlParser = config.hasOption(TestConfig.USE_HTML) | ||||
| @ -83,8 +83,8 @@ public class SpannableMarkdownVisitorTest { | ||||
|         final boolean softBreakAddsNewLine = config.hasOption(TestConfig.SOFT_BREAK_ADDS_NEW_LINE); | ||||
|         final boolean htmlAllowNonClosedTags = config.hasOption(TestConfig.HTML_ALLOW_NON_CLOSED_TAGS); | ||||
| 
 | ||||
|         return SpannableConfiguration.builder(null) | ||||
|                 .theme(mock(SpannableTheme.class)) | ||||
|         return MarkwonConfiguration.builder(null) | ||||
|                 .theme(mock(MarkwonTheme.class)) | ||||
|                 .linkResolver(mock(LinkResolverDef.class)) | ||||
|                 .htmlParser(htmlParser) | ||||
|                 .factory(factory) | ||||
|  | ||||
| @ -13,7 +13,7 @@ import ru.noties.markwon.renderer.ImageSize; | ||||
| import ru.noties.markwon.renderer.ImageSizeResolver; | ||||
| import ru.noties.markwon.spans.AsyncDrawable; | ||||
| import ru.noties.markwon.spans.LinkSpan; | ||||
| import ru.noties.markwon.spans.SpannableTheme; | ||||
| import ru.noties.markwon.spans.MarkwonTheme; | ||||
| import ru.noties.markwon.spans.TableRowSpan; | ||||
| 
 | ||||
| import static ru.noties.markwon.renderer.visitor.TestSpan.BLOCK_QUOTE; | ||||
| @ -57,13 +57,13 @@ class TestFactory implements SpannableFactory { | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object blockQuote(@NonNull SpannableTheme theme) { | ||||
|     public Object blockQuote(@NonNull MarkwonTheme theme) { | ||||
|         return new TestSpan(BLOCK_QUOTE); | ||||
|     } | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object code(@NonNull SpannableTheme theme, boolean multiline) { | ||||
|     public Object code(@NonNull MarkwonTheme theme, boolean multiline) { | ||||
|         final String name = multiline | ||||
|                 ? CODE_BLOCK | ||||
|                 : CODE; | ||||
| @ -72,25 +72,25 @@ class TestFactory implements SpannableFactory { | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object orderedListItem(@NonNull SpannableTheme theme, int startNumber) { | ||||
|     public Object orderedListItem(@NonNull MarkwonTheme theme, int startNumber) { | ||||
|         return new TestSpan(ORDERED_LIST, map("start", startNumber)); | ||||
|     } | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object bulletListItem(@NonNull SpannableTheme theme, int level) { | ||||
|     public Object bulletListItem(@NonNull MarkwonTheme theme, int level) { | ||||
|         return new TestSpan(BULLET_LIST, map("level", level)); | ||||
|     } | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object thematicBreak(@NonNull SpannableTheme theme) { | ||||
|     public Object thematicBreak(@NonNull MarkwonTheme theme) { | ||||
|         return new TestSpan(THEMATIC_BREAK); | ||||
|     } | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object heading(@NonNull SpannableTheme theme, int level) { | ||||
|     public Object heading(@NonNull MarkwonTheme theme, int level) { | ||||
|         return new TestSpan(HEADING + level); | ||||
|     } | ||||
| 
 | ||||
| @ -102,7 +102,7 @@ class TestFactory implements SpannableFactory { | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object taskListItem(@NonNull SpannableTheme theme, int blockIndent, boolean isDone) { | ||||
|     public Object taskListItem(@NonNull MarkwonTheme theme, int blockIndent, boolean isDone) { | ||||
|         return new TestSpan(TASK_LIST, map( | ||||
|                 Pair.of("blockIdent", blockIndent), | ||||
|                 Pair.of("done", isDone) | ||||
| @ -111,7 +111,7 @@ class TestFactory implements SpannableFactory { | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object tableRow(@NonNull SpannableTheme theme, @NonNull List<TableRowSpan.Cell> cells, boolean isHeader, boolean isOdd) { | ||||
|     public Object tableRow(@NonNull MarkwonTheme theme, @NonNull List<TableRowSpan.Cell> cells, boolean isHeader, boolean isOdd) { | ||||
|         return new TestSpan(TABLE_ROW, map( | ||||
|                 Pair.of("cells", cells), | ||||
|                 Pair.of("header", isHeader), | ||||
| @ -129,7 +129,7 @@ class TestFactory implements SpannableFactory { | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object image(@NonNull SpannableTheme theme, @NonNull String destination, @NonNull AsyncDrawable.Loader loader, @NonNull ImageSizeResolver imageSizeResolver, @Nullable ImageSize imageSize, boolean replacementTextIsLink) { | ||||
|     public Object image(@NonNull MarkwonTheme theme, @NonNull String destination, @NonNull AsyncDrawable.Loader loader, @NonNull ImageSizeResolver imageSizeResolver, @Nullable ImageSize imageSize, boolean replacementTextIsLink) { | ||||
|         return new TestSpan(IMAGE, map( | ||||
|                 Pair.of("src", destination), | ||||
|                 Pair.of("imageSize", imageSize), | ||||
| @ -139,19 +139,19 @@ class TestFactory implements SpannableFactory { | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object link(@NonNull SpannableTheme theme, @NonNull String destination, @NonNull LinkSpan.Resolver resolver) { | ||||
|     public Object link(@NonNull MarkwonTheme theme, @NonNull String destination, @NonNull LinkSpan.Resolver resolver) { | ||||
|         return new TestSpan(LINK, map("href", destination)); | ||||
|     } | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object superScript(@NonNull SpannableTheme theme) { | ||||
|     public Object superScript(@NonNull MarkwonTheme theme) { | ||||
|         return new TestSpan(SUPER_SCRIPT); | ||||
|     } | ||||
| 
 | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public Object subScript(@NonNull SpannableTheme theme) { | ||||
|     public Object subScript(@NonNull MarkwonTheme theme) { | ||||
|         return new TestSpan(SUB_SCRIPT); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -2,12 +2,11 @@ package ru.noties.markwon.sample.extension; | ||||
| 
 | ||||
| import android.support.annotation.NonNull; | ||||
| import android.text.TextUtils; | ||||
| import android.widget.TextView; | ||||
| 
 | ||||
| import org.commonmark.node.CustomNode; | ||||
| 
 | ||||
| import ru.noties.markwon.SpannableBuilder; | ||||
| import ru.noties.markwon.SpannableConfiguration; | ||||
| import ru.noties.markwon.MarkwonConfiguration; | ||||
| import ru.noties.markwon.renderer.SpannableMarkdownVisitor; | ||||
| 
 | ||||
| @SuppressWarnings("WeakerAccess") | ||||
| @ -18,7 +17,7 @@ public class IconVisitor extends SpannableMarkdownVisitor { | ||||
|     private final IconSpanProvider iconSpanProvider; | ||||
| 
 | ||||
|     public IconVisitor( | ||||
|             @NonNull SpannableConfiguration configuration, | ||||
|             @NonNull MarkwonConfiguration configuration, | ||||
|             @NonNull SpannableBuilder builder, | ||||
|             @NonNull IconSpanProvider iconSpanProvider | ||||
|     ) { | ||||
|  | ||||
| @ -12,9 +12,9 @@ import org.commonmark.parser.Parser; | ||||
| 
 | ||||
| import java.util.Arrays; | ||||
| 
 | ||||
| import ru.noties.markwon.MarkwonConfiguration; | ||||
| import ru.noties.markwon.SpannableBuilder; | ||||
| import ru.noties.markwon.SpannableConfiguration; | ||||
| import ru.noties.markwon.spans.SpannableTheme; | ||||
| import ru.noties.markwon.spans.MarkwonTheme; | ||||
| import ru.noties.markwon.tasklist.TaskListExtension; | ||||
| 
 | ||||
| public class MainActivity extends Activity { | ||||
| @ -53,8 +53,8 @@ public class MainActivity extends Activity { | ||||
|         final IconSpanProvider spanProvider = IconSpanProvider.create(this, 0); | ||||
| 
 | ||||
|         final float[] textSizeMultipliers = new float[]{3f, 2f, 1.5f, 1f, .5f, .25f}; | ||||
|         SpannableConfiguration configuration = SpannableConfiguration.builder(this) | ||||
|                 .theme(SpannableTheme.builder() | ||||
|         MarkwonConfiguration configuration = MarkwonConfiguration.builder(this) | ||||
|                 .theme(MarkwonTheme.builder() | ||||
|                         .headingTypeface(Typeface.MONOSPACE) | ||||
|                         .headingTextSizeMultipliers(textSizeMultipliers) | ||||
|                         .build()) | ||||
|  | ||||
| @ -10,8 +10,8 @@ import org.commonmark.parser.Parser; | ||||
| 
 | ||||
| import ru.noties.jlatexmath.JLatexMathAndroid; | ||||
| import ru.noties.markwon.Markwon; | ||||
| import ru.noties.markwon.MarkwonConfiguration; | ||||
| import ru.noties.markwon.SpannableBuilder; | ||||
| import ru.noties.markwon.SpannableConfiguration; | ||||
| import ru.noties.markwon.il.AsyncDrawableLoader; | ||||
| import ru.noties.markwon.renderer.ImageSize; | ||||
| import ru.noties.markwon.renderer.SpannableMarkdownVisitor; | ||||
| @ -55,7 +55,7 @@ public class MainActivity extends Activity { | ||||
|                 .mediaDecoders(jLatexMathMedia.mediaDecoder()) | ||||
|                 .build(); | ||||
| 
 | ||||
|         final SpannableConfiguration configuration = SpannableConfiguration.builder(this) | ||||
|         final MarkwonConfiguration configuration = MarkwonConfiguration.builder(this) | ||||
|                 .asyncDrawableLoader(asyncDrawableLoader) | ||||
|                 .build(); | ||||
| 
 | ||||
| @ -68,7 +68,7 @@ public class MainActivity extends Activity { | ||||
| 
 | ||||
|         final Node node = parser.parse(markdown); | ||||
|         final SpannableBuilder builder = new SpannableBuilder(); | ||||
|         final SpannableMarkdownVisitor visitor = new SpannableMarkdownVisitor(SpannableConfiguration.create(this), builder) { | ||||
|         final SpannableMarkdownVisitor visitor = new SpannableMarkdownVisitor(MarkwonConfiguration.create(this), builder) { | ||||
| 
 | ||||
|             @Override | ||||
|             public void visit(CustomBlock customBlock) { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Dimitry Ivanov
						Dimitry Ivanov