### Basic Markwon Editor Setup Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/editor/README.md Initialize Markwon, create a MarkwonEditor instance, and attach a TextWatcher to an EditText for in-place markdown highlighting. ```java final Markwon markwon = Markwon.create(this); final MarkwonEditor editor = MarkwonEditor.create(markwon); editText.addTextChangedListener(MarkwonEditorTextWatcher.withProcess(editor)); ``` -------------------------------- ### Configure Plugins with Registry Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/core/plugins.md Use the Registry to pre-configure and determine the order of plugins within a Markwon instance. This example shows how to require the CorePlugin. ```java final Markwon markwon = Markwon.builder(context) .usePlugin(new AbstractMarkwonPlugin() { @Override public void configure(@NonNull Registry registry) { final CorePlugin corePlugin = registry.require(CorePlugin.class); // or registry.require(CorePlugin.class, new Action() { @Override public void apply(@NonNull CorePlugin corePlugin) { } }); } }) .build(); ``` -------------------------------- ### Basic MarkwonAdapter Setup Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/recycler/README.md Initialize MarkwonAdapter for a TextView root layout. Include custom views for specific Markdown elements like FencedCodeBlock. ```java final MarkwonAdapter adapter = MarkwonAdapter.builderTextViewIsRoot(R.layout.adapter_default_entry) .include(FencedCodeBlock.class, SimpleEntry.create(R.layout.adapter_fenced_code_block, R.id.text_view)) .build(); ``` -------------------------------- ### HTML Inline Example Source: https://github.com/noties/markwon/blob/master/README.md Shows how inline HTML can be rendered. ```html HTML ``` -------------------------------- ### Inline Code Example Source: https://github.com/noties/markwon/blob/master/README.md Demonstrates how to format inline code using back-ticks. ```markdown Inline `code` has `back-ticks around` it. ``` -------------------------------- ### Example EmphasisHandler Source: https://github.com/noties/markwon/blob/master/docs/docs/v2/html.md An example implementation of `SimpleTagHandler` for handling emphasis tags. ```java public class EmphasisHandler extends SimpleTagHandler { @Nullable @Override public Object getSpans(@NonNull SpannableConfiguration configuration, @NonNull HtmlTag tag) { return configuration.factory().emphasis(); } } ``` -------------------------------- ### Define a configurable plugin Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/core/registry.md Example of a custom plugin with an enabled state that can be configured externally. ```java public class MyPlugin extends AbstractMarkwonPlugin { private boolean enabled; public boolean enabled() { return enabled; } @NonNull public MyPlugin enabled(boolean enabled) { this.enabled = enabled; return this; } {...} } ``` -------------------------------- ### Multiline Java Code Example Source: https://github.com/noties/markwon/blob/master/markwon-core/src/test/resources/tests/second.md A basic example demonstrating multiline code within a Java fenced code block. ```java the code in multiline ``` -------------------------------- ### Configure AsyncDrawableLoader Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/core/configuration.md Example of configuring an AsyncDrawableLoader using a plugin. This is useful when you want to disable image loading or provide a custom implementation. ```java final Markwon markwon = Markwon.builder(context) .usePlugin(new AbstractMarkwonPlugin() { @Override public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { builder.asyncDrawableLoader(AsyncDrawableLoader.noOp()); } }) .build(); ``` -------------------------------- ### Create Markwon with TableEntryPlugin Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/recycler-table/README.md Use TableEntryPlugin to display TableBlock as a TableLayout. This example shows creating the plugin with default TableTheme. ```java final Markwon markwon = Markwon.builder(context) .usePlugin(TableEntryPlugin.create(context)) // other plugins .build(); ``` -------------------------------- ### Python Syntax Highlighting Source: https://github.com/noties/markwon/blob/master/README.md Example of Python code block for syntax highlighting. ```python s = "Python syntax highlighting" print s ``` -------------------------------- ### HTML Image Examples with Size Attributes Source: https://github.com/noties/markwon/blob/master/docs/docs/v2/configure.md Demonstrates various ways to specify image dimensions using HTML img tags, including percentages, em units, and absolute pixel values. ```html ``` -------------------------------- ### Configure Visitor Builder Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/core/visitor.md Configure the MarkwonVisitor.Builder to customize node visiting behavior. This example shows how to add a custom visitor for SoftLineBreak nodes to force a new line. ```java final Markwon markwon = Markwon.builder(contex) .usePlugin(new AbstractMarkwonPlugin() { @Override public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) { builder.on(SoftLineBreak.class, new MarkwonVisitor.NodeVisitor() { @Override public void visit(@NonNull MarkwonVisitor visitor, @NonNull SoftLineBreak softLineBreak) { visitor.forceNewLine(); } }); } }); ``` -------------------------------- ### Add Markwon Core Dependency Source: https://github.com/noties/markwon/blob/master/docs/docs/v2/install.md Include the core Markwon artifact in your project's build.gradle file to start displaying markdown. ```groovy implementation "ru.noties:markwon:${markwonVersion}" ``` -------------------------------- ### Install Markwon Core Dependency Source: https://github.com/noties/markwon/blob/master/README.md Add the core Markwon library to your Android project's dependencies. Ensure you replace the placeholder with the actual version number. ```kotlin implementation "io.noties.markwon:core:${markwonVersion}" ``` -------------------------------- ### Define Simple Delimited Extension with Same Characters Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/simple-ext/README.md Use `SimpleExtPlugin.create()` to add an extension with identical opening and closing characters. This example registers '+' as a delimiter for an emphasis span. ```java final Markwon markwon = Markwon.builder(this) .usePlugin(SimpleExtPlugin.create(plugin -> plugin // +sometext+ .addExtension(1, '+', new SpanFactory() { @Override public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps props) { return new EmphasisSpan(); } }) .build(); ``` -------------------------------- ### Example of HTML Parsing with Mixed Content Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/html/README.md Illustrates how Markwon might parse a mixed HTML string containing various tags and text. This shows the potential breakdown into different node types. ```markdown Hello from italics tag bold> ``` -------------------------------- ### Register TableEntry with MarkwonAdapter Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/recycler-table/README.md Register an instance of TableEntry with MarkwonAdapter to render TableBlocks. This example shows how to include TableBlock and configure its layout for the table and individual cells. ```java final MarkwonAdapter adapter = MarkwonAdapter.builder(R.layout.adapter_default_entry, R.id.text) .include(TableBlock.class, TableEntry.create(builder -> builder .tableLayout(R.layout.adapter_table_block, R.id.table_layout) .textLayoutIsRoot(R.layout.view_table_entry_cell))) .build(); ``` -------------------------------- ### Create Markwon with Custom TableEntryPlugin Theme Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/recycler-table/README.md Create a TableEntryPlugin with a custom theme configuration. This example demonstrates setting table border width to 0 and header row background color to red. ```java final Markwon markwon = Markwon.builder(context) .usePlugin(TableEntryPlugin.create(builder -> builder .tableBorderWidth(0) .tableHeaderRowBackgroundColor(Color.RED))) // other plugins .build(); ``` -------------------------------- ### Configure Link Resolver Source: https://github.com/noties/markwon/blob/master/docs/docs/v2/configure.md Configure a custom link resolver to handle link clicks in markdown/HTML. The default implementation attempts to start an associated Activity, failing silently if none is found. ```java SpannableConfiguration.builder(context) .linkResolver(LinkSpan.Resolver) .build(); ``` -------------------------------- ### Initialize Markwon with OkHttpImagesPlugin Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/image/okhttp.md Demonstrates how to build a Markwon instance and register the OkHttpImagesPlugin for image loading. You can use the default OkHttpClient or provide a custom-configured one. ```java final Markwon markwon = Markwon.builder(context) // it's required to register ImagesPlugin .usePlugin(ImagesPlugin.create(context)) // will create default instance of OkHttpClient .usePlugin(OkHttpImagesPlugin.create()) // or accept a configured client .usePlugin(OkHttpImagesPlugin.create(new OkHttpClient())) .build(); ``` -------------------------------- ### Define Simple Delimited Extension with Different Characters Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/simple-ext/README.md Use `addExtension` with distinct opening and closing characters to define extensions for texts like `@@text$$`. This example uses '@' and '$' to apply a red foreground color span. ```java plugin.addExtension( /*length*/2, /*openingCharacter*/'@', /*closingCharacter*/'$', /*spanFactory*/(configuration, props) -> new ForegroundColorSpan(Color.RED)))) ``` -------------------------------- ### Configure a plugin using Registry Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/core/registry.md Demonstrates how one plugin can require and configure another plugin using the Registry. ```java public class MyOtherPlugin extends AbstractMarkwonPlugin { @Override public void configure(@NonNull Registry registry) { registry.require(MyPlugin.class, new Action() { @Override public void apply(@NonNull MyPlugin myPlugin) { myPlugin.enabled(false); } }); } } ``` -------------------------------- ### Registering a Plugin with Markwon Builder Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/core/plugins.md Demonstrates how to register a plugin, specifically CorePlugin, using the Markwon.Builder. This is the standard way to initialize Markwon with plugins. ```java Markwon.builder(context) .usePlugin(CorePlugin.create()) .build(); ``` -------------------------------- ### JavaScript Syntax Highlighting Source: https://github.com/noties/markwon/blob/master/README.md Example of JavaScript code block for syntax highlighting. ```javascript var s = "JavaScript syntax highlighting"; alert(s); ``` -------------------------------- ### Run Markwon Sample App Tests with JDK 1.8 Source: https://github.com/noties/markwon/blob/master/app-sample/README.md Command to run Markwon sample app tests using Robolectric, specifying the JDK path. This is necessary when using a JDK version higher than 1.8, as Robolectric has compatibility issues with newer JDKs. ```bash ./gradlew :app-s:testDe -Dorg.gradle.java.home="{INSERT BUNDLED JDK PATH HERE}" ``` -------------------------------- ### Get Markdown as CharSequence Source: https://github.com/noties/markwon/blob/master/docs/docs/v2/getting-started.md Obtain parsed and styled Markdown as a CharSequence to use elsewhere, such as in Toasts. ```java // parsed and styled markdown final CharSequence markdown = Markwon.markdown(context, "**Hello there!**"); // use it Toast.makeText(context, markdown, Toast.LENGTH_LONG).show(); ``` -------------------------------- ### Initialize Markwon with GlideImagesPlugin Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/image-glide/README.md Demonstrates three ways to initialize the GlideImagesPlugin: automatically creating a Glide instance, using a pre-existing Glide instance, or providing a custom GlideStore for more control over image loading and cancellation. ```java final Markwon markwon = Markwon.builder(context) // automatically create Glide instance .usePlugin(GlideImagesPlugin.create(context)) // use supplied Glide instance .usePlugin(GlideImagesPlugin.create(Glide.with(context))) // if you need more control .usePlugin(GlideImagesPlugin.create(new GlideImagesPlugin.GlideStore() { @NonNull @Override public RequestBuilder load(@NonNull AsyncDrawable drawable) { return Glide.with(context).load(drawable.getDestination()); } @Override public void cancel(@NonNull Target target) { Glide.with(context).clear(target); } })) .build(); ``` -------------------------------- ### Release Library and Sample App Source: https://github.com/noties/markwon/blob/master/release-management.md Use these commands to trigger library releases (stable or snapshot based on gradle.properties) and sample app releases. ```bash # Stable and snapshot library release (depending on the version specified in `gradle.properties`) ./gradlew upA -Prelease # Sample app release ./app-sample/deploy.sh ``` -------------------------------- ### Define Heading Level Prop Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/core/render-props.md Example of defining a specific Prop for heading level within CorePlugin. ```java public static final Prop HEADING_LEVEL = Prop.of("heading-level"); ``` -------------------------------- ### Configure Markwon with PicassoImagesPlugin Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/image-picasso/README.md Demonstrates how to configure Markwon to use the PicassoImagesPlugin. You can automatically create a Picasso instance, use a provided instance, or implement a custom PicassoStore for advanced control. ```java final Markwon markwon = Markwon.builder(context) // automatically create Picasso instance .usePlugin(PicassoImagesPlugin.create(context)) // use provided picasso instance .usePlugin(PicassoImagesPlugin.create(Picasso.get())) // if you need more control .usePlugin(PicassoImagesPlugin.create(new PicassoImagesPlugin.PicassoStore() { @NonNull @Override public RequestCreator load(@NonNull AsyncDrawable drawable) { return Picasso.get() .load(drawable.getDestination()) // please note that drawable should be used as tag (not a destination) // otherwise there won't be support for multiple images with the same URL .tag(drawable); } @Override public void cancel(@NonNull AsyncDrawable drawable) { Picasso.get() .cancelTag(drawable); } })) .build(); ``` -------------------------------- ### Runtime validation of plugin presence Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/core/registry.md Example demonstrating how the Registry throws an exception at runtime if a required plugin is not present. ```java final Markwon markwon = Markwon.builder(context) .usePlugin(new AbstractMarkwonPlugin() { @Override public void configure(@NonNull Registry registry) { // will throw an exception if `NotPresentPlugin` is not present registry.require(NotPresentPlugin.class); } }) .build(); ``` -------------------------------- ### Build Markwon with configured plugins Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/core/registry.md Instantiates Markwon, including a plugin that requires and configures another plugin. ```java final Markwon markwon = Markwon.builder(context) .usePlugin(new MyOtherPlugin()) .usePlugin(new MyPlugin()) .build(); ``` -------------------------------- ### Pre-process Markdown with a Plugin Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/core/plugins.md Implement a plugin to modify markdown input before parsing. This example replaces all occurrences of 'foo' with 'bar'. ```java final Markwon markwon = Markwon.builder(context) .usePlugin(new AbstractMarkwonPlugin() { @NonNull @Override public String processMarkdown(@NonNull String markdown) { return markdown.replaceAll("foo", "bar"); } }) .build(); ``` -------------------------------- ### Integrate SyntaxHighlightPlugin with Markwon Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/syntax-highlight/README.md Build a Markwon instance and use the SyntaxHighlightPlugin, providing the Prism4j instance and Prism4jTheme. This integrates the syntax highlighting functionality into the Markwon renderer. ```java final Markwon markwon = Markwon.builder(context) .usePlugin(SyntaxHighlightPlugin.create(prism4j, prism4jTheme)) .build(); ``` -------------------------------- ### Provide a Placeholder Drawable Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/image/README.md Configure the ImagesPlugin to use a custom PlaceholderProvider. This example shows how to return null, effectively disabling placeholders. ```java final Markwon markwon = Markwon.builder(context) .usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() { @Override public void configureImages(@NonNull ImagesPlugin plugin) { plugin.placeholderProvider(new ImagesPlugin.PlaceholderProvider() { @Nullable @Override public Drawable providePlaceholder(@NonNull AsyncDrawable drawable) { return null; } }); } })) .build(); ``` -------------------------------- ### Initialize Markwon with JLatexMathPlugin Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/ext-latex/README.md Integrate the JLatexMathPlugin into Markwon to enable LaTeX rendering. Ensure the plugin is created with the desired text size. ```java Markwon.builder(context) .use(ImagesPlugin.create(context)) .use(JLatexMathPlugin.create(textSize)) .build(); ``` -------------------------------- ### Implementing SchemeHandler for InputStream Decoding Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/image/README.md Example of a SchemeHandler that returns an InputStream for further decoding by a MediaDecoder. This is used for image types that require processing. ```java imagesPlugin.addSchemeHandler(new SchemeHandler() { @NonNull @Override public ImageItem handle(@NonNull String raw, @NonNull Uri uri) { return ImageItem.withDecodingNeeded("image/png", load(raw)); } @NonNull private InputStream load(@NonNull String raw) {...} }); ``` -------------------------------- ### Configure GifMediaDecoder in Markwon Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/image/README.md Adds support for GIF media. Registration happens automatically if the dependency is found. Manually configure autoplay behavior. ```java final Markwon markwon = Markwon.builder(context) .usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() { @Override public void configureImages(@NonNull ImagesPlugin plugin) { // autoplayGif controls if GIF should be automatically started plugin.addMediaDecoder(GifMediaDecoder.create(/*autoplayGif*/false)); } })) .build(); ``` -------------------------------- ### Delimiter Restriction Example Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/simple-ext/README.md The space character cannot be used as a delimiter for `SimpleExtPlugin`. Attempting to use a space as an opening or closing character will not work. ```java plugin.addExtension(1, '@', ' ', /*spanFactory*/); ``` -------------------------------- ### Initialize Markwon with TaskListPlugin Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/ext-tasklist/README.md Initialize Markwon with the TaskListPlugin to enable GFM task list rendering. ```java final Markwon markwon = Markwon.builder(context) .usePlugin(TaskListPlugin.create(context)) .build(); ``` -------------------------------- ### Initialize Markwon with TextSetter Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/core/text-setter.md Demonstrates how to configure Markwon to use a custom TextSetter, specifically PrecomputedTextSetterCompat, during its initialization. ```java final Markwon markwon = Markwon.builder(context) .usePlugin(/**/) .textSetter(PrecomputedTextSetterCompat.create(Executors.newCachedThreadPool())) .build(); ``` -------------------------------- ### Block code background color example Source: https://github.com/noties/markwon/blob/master/docs/docs/v2/theme.md Sets the background color for code blocks. Defaults to the inline code background color. ```java The color of background of code block text ``` -------------------------------- ### Create CorePlugin Instance Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/core/core-plugin.md Instantiate the CorePlugin to enable basic markdown parsing and rendering features in Markwon. ```java CorePlugin.create(); ``` -------------------------------- ### Block code text color example Source: https://github.com/noties/markwon/blob/master/docs/docs/v2/theme.md Sets the text color for code blocks. Defaults to the inline code text color. ```java The color of code block text ``` -------------------------------- ### Create Prism4jSyntaxHighlight Instance Source: https://github.com/noties/markwon/blob/master/docs/docs/v2/syntax-highlight.md Obtain an instance of Prism4jSyntaxHighlight to implement Markwon's SyntaxHighlight interface. This is the primary way to enable syntax highlighting. ```java final SyntaxHighlight highlight = Prism4jSyntaxHighlight.create(Prism4j, Prism4jTheme); ``` -------------------------------- ### Custom Markwon Plugin for FencedCodeBlock Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/recycler/README.md Configure Markwon initialization with a custom plugin to handle FencedCodeBlock rendering. This allows for manual styling and syntax highlighting within the visitor pattern, bypassing default styling when custom views are used. ```java final Markwon markwon = Markwon.builder(context) .usePlugin(new AbstractMarkwonPlugin() { @Override public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) { builder.on(FencedCodeBlock.class, (visitor, fencedCodeBlock) -> { final CharSequence code = visitor.configuration() .syntaxHighlight() .highlight(fencedCodeBlock.getInfo(), fencedCodeBlock.getLiteral().trim()); visitor.builder().append(code); }); } }) .build(); ``` -------------------------------- ### Initialize Markwon with ImagesPlugin Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/image/README.md Basic initialization of Markwon with the ImagesPlugin enabled to support image rendering. ```java final Markwon markwon = Markwon.builder(context) .usePlugin(ImagesPlugin.create()) .build(); ``` -------------------------------- ### Initialize Markwon with Strikethrough Plugin Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/ext-strikethrough/README.md Basic usage of the StrikethroughPlugin to enable strikethrough functionality in Markwon. ```java Markwon.builder(context) .usePlugin(StrikethroughPlugin.create()) ``` -------------------------------- ### Configure Parser with Plugin Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/core/plugins.md Register a new commonmark-java Parser extension by configuring the parser builder within a plugin. This example adds the StrikethroughExtension. ```java final Markwon markwon = Markwon.builder(context) .usePlugin(new AbstractMarkwonPlugin() { @Override public void configureParser(@NonNull Parser.Builder builder) { // no need to call `super.configureParser(builder)` builder.extensions(Collections.singleton(StrikethroughExtension.create())); } }) .build(); ``` -------------------------------- ### Create Adapter with Custom Layout and Initialize RecyclerView Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/recycler/README.md Use `create` to initialize a MarkwonAdapter with a specific layout and TextView ID, allowing for more complex item structures. This snippet also shows how to set up the RecyclerView, obtain a Markwon instance, and display markdown. ```java final MarkwonAdapter adapter = MarkwonAdapter.create(R.layout.adapter_default_entry, R.id.text_view); final RecyclerView recyclerView = obtainRecyclerView(); recyclerView.setAdapter(adapter); final Markwon markwon = obtainMarkwon(); adapter.setMarkdown(markwon, "# This is markdown!"); adapter.notifyDataSetChanged(); ``` -------------------------------- ### Initialize Markwon with FileSchemeHandler for Assets Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/image/README.md Configures Markwon to use a FileSchemeHandler with assets support, enabling image loading from the assets folder. ```java final Markwon markwon = Markwon.builder(context) .usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() { @Override public void configureImages(@NonNull ImagesPlugin plugin) { plugin.addSchemeHandler(FileSchemeHandler.createWithAssets(context)); } })) .build(); ``` -------------------------------- ### UrlProcessorAndroidAssets Example Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/core/configuration.md UrlProcessorAndroidAssets processes links to point to the Android assets folder. It only affects URLs without a scheme, converting them to a file URI. ```java new UrlProcessorAndroidAssets() ``` -------------------------------- ### Clean and Build Markwon Sample App Source: https://github.com/noties/markwon/blob/master/app-sample/README.md Perform a clean build of the Markwon sample app. This is often required after adding or removing samples to ensure the annotation processor generates 'samples.json' and the Android Gradle plugin bundles resources correctly. ```bash ./gradlew :app-s:clean :app-s:asDe ``` -------------------------------- ### Using afterSetText Plugin Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/core/plugins.md Demonstrates how to use the `afterSetText` callback within a custom Markwon plugin to schedule asynchronous drawable updates for a TextView. ```java final Markwon markwon = Markwon.builder(context) .usePlugin(new AbstractMarkwonPlugin() { @Override public void afterSetText(@NonNull TextView textView) { AsyncDrawableScheduler.schedule(textView); } }) .build(); ``` -------------------------------- ### HTML Image Tag with Size Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/image/README.md Example of an HTML img tag with a specified width. The HtmlPlugin automatically handles images from HTML, including size attributes. ```html ``` -------------------------------- ### Render Table in Custom Widget Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/ext-tables/README.md Parse a table from Markdown and set it to a custom widget for rendering. This is a conceptual example; actual implementation depends on the custom widget. ```java final Table table = Table.parse(Markwon, TableBlock); myTableWidget.setTable(table); ``` -------------------------------- ### Configure SyntaxHighlight with No-Op Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/core/configuration.md This snippet shows how to use a plugin to configure Markwon with a no-operation syntax highlighter. This is useful when syntax highlighting is not desired or handled elsewhere. ```java final Markwon markwon = Markwon.builder(this) .usePlugin(new AbstractMarkwonPlugin() { @Override public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { builder.syntaxHighlight(new SyntaxHighlightNoOp()); } }) .build(); ``` -------------------------------- ### Customize Strikethrough Span in Markwon Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/ext-strikethrough/README.md Demonstrates how to customize the Strikethrough Span using a custom SpanFactory. This example replaces the default strikethrough span with an underline span. ```java Markwon.builder(context) .usePlugin(StrikethroughPlugin.create()) .usePlugin(new AbstractMarkwonPlugin() { @Override public void configureSpansFactory(@NonNull MarkwonSpansFactory.Builder builder) { builder.setFactory(Strikethrough.class, new SpanFactory() { @Override public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps props) { // will use Underline span instead of Strikethrough return new UnderlineSpan(); } }); } }) ``` -------------------------------- ### Initialize Markwon with GIF Support Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/image/gif.md This snippet shows how to configure Markwon to support GIF images by registering the ImagesPlugin and GifPlugin. Ensure the android-gif-drawable library is available. ```java final Markwon markwon = Markwon.builder(context) // it's required to register ImagesPlugin .usePlugin(ImagesPlugin.create(context)) // add GIF support for images .usePlugin(GifPlugin.create()) .build(); ``` -------------------------------- ### Define Custom Enhance Tag Handler Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/html/README.md Extends TagHandler to enlarge specific parts of text within an tag, using 'start' and 'end' attributes. ```html This is text that must be enhanced, at least a part of it ``` ```java public class EnhanceTagHandler extends TagHandler { private final int enhanceTextSize; EnhanceTagHandler(@Px int enhanceTextSize) { this.enhanceTextSize = enhanceTextSize; } @Override public void handle( @NonNull MarkwonVisitor visitor, @NonNull MarkwonHtmlRenderer renderer, @NonNull HtmlTag tag) { // we require start and end to be present final int start = parsePosition(tag.attributes().get("start")); final int end = parsePosition(tag.attributes().get("end")); if (start > -1 && end > -1) { visitor.builder().setSpan( new AbsoluteSizeSpan(enhanceTextSize), tag.start() + start, tag.start() + end ); } } @NonNull @Override public Collection supportedTags() { return Collections.singleton("enhance"); } private static int parsePosition(@Nullable String value) { int position; if (!TextUtils.isEmpty(value)) { try { position = Integer.parseInt(value); } catch (NumberFormatException e) { e.printStackTrace(); position = -1; } } else { position = -1; } return position; } } ``` -------------------------------- ### Implementing SchemeHandler for Drawable Resources Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/image/README.md Example of a SchemeHandler that loads images from drawable resources using a custom 'drawable://' scheme. This handler returns a Drawable directly. ```java final Markwon markwon = Markwon.builder(context) .usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() { @Override public void configureImages(@NonNull ImagesPlugin plugin) { // for example to return a drawable resource plugin.addSchemeHandler(new SchemeHandler() { @NonNull @Override public ImageItem handle(@NonNull String raw, @NonNull Uri uri) { // will handle URLs like `drawable://ic_account_24dp_white` final int resourceId = context.getResources().getIdentifier( raw.substring("drawable://".length()), "drawable", context.getPackageName()); // it's fine if it throws, async-image-loader will catch exception final Drawable drawable = context.getDrawable(resourceId); return ImageItem.withResult(drawable); } @NonNull @Override public Collection supportedSchemes() { return Collections.singleton("drawable"); } }); } })) .build(); ``` -------------------------------- ### Initialize Markwon with HTML Plugin Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/html/README.md Initialize Markwon with the HtmlPlugin to enable HTML parsing. This is the primary way to integrate HTML rendering into your Markwon instance. ```java final Markwon markwon = Markwon.builder(context) .usePlugin(HtmlPlugin.create()) .build(); ``` -------------------------------- ### Create Priority Instances Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/core/plugins.md Demonstrates factory methods for creating Priority instances, including none, single dependency, multiple dependencies, and using a builder for more than two dependencies. ```java // none Priority.none(); ``` ```java // single dependency Priority.after(CorePlugin.class); ``` ```java // 2 dependencies Priority.after(CorePlugin.class, ImagesPlugin.class); ``` ```java // for a number >2, use #builder Priority.builder() .after(CorePlugin.class) .after(ImagesPlugin.class) .after(StrikethroughPlugin.class) .build(); ``` -------------------------------- ### Custom Task List Drawable Implementation Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/ext-tasklist/README.md Provides an example implementation of a custom Drawable for task list items, handling state changes for checked and unchecked states. ```java public class MyTaskListDrawable extends Drawable { private boolean isChecked; @Override public void draw(@NonNull Canvas canvas) { // draw accordingly to the isChecked value } /* implementation omitted */ @Override protected boolean onStateChange(int[] state) { final boolean isChecked = contains(state, android.R.attr.state_checked); final boolean result = this.isChecked != isChecked; if (result) { this.isChecked = isChecked; } return result; } private static boolean contains(@Nullable int[] states, int value) { if (states != null) { for (int state : states) { if (state == value) { // NB return here return true; } } } return false; } } ``` -------------------------------- ### Initialize HtmlPlugin for Markwon Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/core/configuration.md Use this snippet to enable HTML rendering in Markwon by adding the HtmlPlugin. This is required for any HTML content to be displayed. ```java Markwon.builder(context) .usePlugin(HtmlPlugin.create()) ``` -------------------------------- ### Data URI with SVG Content Source: https://github.com/noties/markwon/blob/master/docs/docs/v2/image-loader.md An example of an HTML `img` tag using a `data` URI with inline SVG content. This is useful for embedding vector graphics directly. ```html ``` -------------------------------- ### Configure Theme Properties with Plugin Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/core/theme.md Use an AbstractMarkwonPlugin to configure theme properties like code text and background color. This is the recommended approach for Markwon v3.0.0 and later. ```java final Markwon markwon = Markwon.builder(context) .usePlugin(new AbstractMarkwonPlugin() { @Override public void configureTheme(@NonNull MarkwonTheme.Builder builder) { builder .codeTextColor(Color.BLACK) .codeBackgroundColor(Color.GREEN); } }) .build(); ``` -------------------------------- ### Open Specific Sample via Deeplink Source: https://github.com/noties/markwon/blob/master/app-sample/README.md Use this command to open a specific sample in the Markwon app using its ID. Ensure the URL is properly encoded if necessary. ```bash adb shell am start -a android.intent.action.ACTION_VIEW -d markwon://sample/ID ``` -------------------------------- ### Configure Custom HTML Tag Handler Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/core/plugins.md Register a custom handler for an HTML tag (e.g., 'center') to control its rendering. This example centers text within the specified tag. ```java final Markwon markwon = Markwon.builder(context) .usePlugin(HtmlPlugin.create()) .usePlugin(new AbstractMarkwonPlugin() { @Override public void configureHtmlRenderer(@NonNull MarkwonHtmlRenderer.Builder builder) { //
tag handling (deprecated but valid in our case) // can be any tag name, there is no connection with _real_ HTML tags, // builder.addHandler("center", new SimpleTagHandler() { @Override public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps renderProps, @NonNull HtmlTag tag) { return new AlignmentSpan() { @Override public Layout.Alignment getAlignment() { return Layout.Alignment.ALIGN_CENTER; } }; } }); } }) .build(); ``` -------------------------------- ### Register Custom Strikethrough Node Visitor Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/core/plugins.md Example of registering a custom visitor for the Strikethrough Node. This is useful for adding custom rendering logic for specific Markdown elements not covered by default. ```java final Markwon markwon = Markwon.builder(context) .usePlugin(new AbstractMarkwonPlugin() { @Override public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) { builder .on(Strikethrough.class, new MarkwonVisitor.NodeVisitor() { @Override public void visit(@NonNull MarkwonVisitor visitor, @NonNull Strikethrough strikethrough) { final int length = visitor.length(); visitor.visitChildren(strikethrough); visitor.setSpansForNodeOptional(strikethrough, length); } }); } }) .build(); ``` -------------------------------- ### Registering Custom Plugins Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/core/plugins.md Demonstrates how to register a custom plugin using `Markwon.builder`. Note that `CorePlugin` is automatically registered since version 4.0.0. ```java Markwon.builder(context) // @since 4.0.0 there is no need to register CorePlugin, as it's registered automatically // .usePlugin(CorePlugin.create()) .usePlugin(MyPlugin.create()) .build(); ``` -------------------------------- ### Initialize Markwon with SVG Support Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/image/svg.md Use this snippet to configure Markwon with the ImagesPlugin and SvgPlugin for rendering SVG images in markdown. Ensure the context and resources are correctly provided. ```java final Markwon markwon = Markwon.builder(context) // it's required to register ImagesPlugin .usePlugin(ImagesPlugin.create(context)) .usePlugin(SvgPlugin.create(context.getResources())) .build(); ``` -------------------------------- ### Prepare TextView Before Applying Markdown Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/core/plugins.md The `beforeSetText` method in an AbstractMarkwonPlugin allows you to prepare a TextView before markdown is applied. This is useful for tasks like unscheduling previous AsyncDrawableSpans to prevent memory leaks. ```java final Markwon markwon = Markwon.builder(context) .usePlugin(new AbstractMarkwonPlugin() { @Override public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { // clean-up previous AsyncDrawableScheduler.unschedule(textView); } }) .build(); ``` -------------------------------- ### Configure SvgMediaDecoder in Markwon Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/image/README.md Adds support for SVG media. Registration happens automatically if the dependency is found. Can use supplied or system resources. ```java final Markwon markwon = Markwon.builder(context) .usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() { @Override public void configureImages(@NonNull ImagesPlugin plugin) { // uses supplied Resources plugin.addMediaDecoder(SvgMediaDecoder.create(context.getResources())); // uses Resources.getSystem() plugin.addMediaDecoder(SvgMediaDecoder.create()); } })) .build(); ``` -------------------------------- ### Markwon Editor with Background Processing Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/editor/README.md Use `withPreRender` to offload markdown highlighting to a background thread using a provided ExecutorService. This is recommended for larger markdown inputs to prevent UI freezes. ```java editText.addTextChangedListener(MarkwonEditorTextWatcher.withPreRender( editor, Executors.newCachedThreadPool(), editText)); ``` -------------------------------- ### Markdown Reference to Rendered LaTeX Image Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/ext-latex/README.md Example of using a markdown reference to an image, where the image is a base64 encoded SVG/PNG/GIF of a rendered LaTeX formula. Requires an image loader that supports data URIs. ```markdown ![markdown-reference] of a solution... [markdown-reference]: data:image/svg+xml;base64,base64encodeddata== ``` -------------------------------- ### Data URI with Base64 Encoding Source: https://github.com/noties/markwon/blob/master/docs/docs/v2/image-loader.md An example of an HTML `img` tag using a `data` URI with base64 encoded PNG image data. This allows embedding small images directly within the HTML. ```html Red dot ``` -------------------------------- ### Create Default HTML Parser Implementation Source: https://github.com/noties/markwon/blob/master/docs/docs/v2/html.md Instantiate the default HTML parser implementation provided by Markwon. This is the standard way to enable HTML parsing. ```java final MarkwonHtmlParser htmlParser = MarkwonHtmlParserImpl.create(); ``` -------------------------------- ### Implement Additional Markdown Handling with EditHandler Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/editor/README.md Utilize `useEditHandler` to add custom logic for highlighting markdown input within the editor. This example demonstrates how to persist and handle `StrongEmphasisSpan` by representing it as a `Bold` span in the `EditText`. ```java final MarkwonEditor editor = MarkwonEditor.builder(Markwon.create(this)) .useEditHandler(new AbstractEditHandler() { @Override public void configurePersistedSpans(@NonNull PersistedSpans.Builder builder) { // Here we define which span is _persisted_ in EditText, it is not removed // from EditText between text changes, but instead - reused (by changing // position). Consider it as a cache for spans. We could use `StrongEmphasisSpan` // here also, but I chose Bold to indicate that this span is not the same // as in off-screen rendered markdown builder.persistSpan(Bold.class, Bold::new); } @Override public void handleMarkdownSpan( @NonNull PersistedSpans persistedSpans, @NonNull Editable editable, @NonNull String input, @NonNull StrongEmphasisSpan span, int spanStart, int spanTextLength) { // Unfortunately we cannot hardcode delimiters length here (aka spanTextLength + 4) // because multiple inline markdown nodes can refer to the same text. // For example, `**_~~hey~~_**` - we will receive `**_~~` in this method, // and thus will have to manually find actual position in raw user input final MarkwonEditorUtils.Match match = MarkwonEditorUtils.findDelimited(input, spanStart, "**", "__"); if (match != null) { editable.setSpan( // we handle StrongEmphasisSpan and represent it with Bold in EditText // we still could use StrongEmphasisSpan, but it must be accessed // via persistedSpans persistedSpans.get(Bold.class), match.start(), match.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE ); } } @NonNull @Override public Class markdownSpanType() { return StrongEmphasisSpan.class; } }) .build(); ``` -------------------------------- ### Add Snapshot Repository Source: https://github.com/noties/markwon/blob/master/docs/docs/v2/install.md Configure your root project's build.gradle to include the Sonatype snapshot repository for using the latest SNAPSHOT versions of Markwon. ```groovy allprojects { repositories { jcenter() google() maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' } } } ``` -------------------------------- ### Markdown Image with Data URI (Base64) Source: https://github.com/noties/markwon/blob/master/docs/docs/v2/image-loader.md A Markdown image syntax example using a `data` URI with base64 encoded SVG content. Note that only base64 encoded data URIs are supported in this Markdown context. ```markdown ![svg](data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGFyaWEtaGlkZGVuPSJ0cnVlIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDEwMCAxMDAiIHdpZHRoPSIxNSIgaGVpZ2h0PSIxNSIgY2xhc3M9Imljb24gb3V0Ym91bmQiPjxwYXRoIGZpbGw9ImN1cnJlbnRDb2xvciIgZD0iTTE4LjgsODUuMWg1NmwwLDBjMi4yLDAsNC0xLjgsNC00di0zMmgtOHYyOGgtNDh2LTQ4aDI4di04aC0zMmwwLDBjLTIuMiwwLTQsMS44LTQsNHY1NkMxNC44LDgzLjMsMTYuNiw4NS4xLDE4LjgsODUuMXoiPjwvcGF0aD4gPHBvbHlnb24gZmlsbD0iY3VycmVudENvbG9yIiBwb2ludHM9IjQ1LjcsNDguNyA1MS4zLDU0LjMgNzcuMiwyOC41IDc3LjIsMzcuMiA4NS4yLDM3LjIgODUuMiwxNC45IDYyLjgsMTQuOSA2Mi44LDIyLjkgNzEuNSwyMi45Ij48L3BvbHlnb24+PC9zdmc+) ``` -------------------------------- ### Custom Visitor for Heading Nodes Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/core/visitor.md Implement a custom visitor for Heading nodes to control their rendering. This example demonstrates visiting children, applying spans based on configuration, and ensuring new lines after the heading if it's not the last block. ```java @Override public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) { builder.on(Heading.class, new MarkwonVisitor.NodeVisitor() { @Override public void visit(@NonNull MarkwonVisitor visitor, @NonNull Heading heading) { // or just `visitor.length()` final int start = visitor.builder().length(); visitor.visitChildren(heading); // or just `visitor.setSpansForNodeOptional(heading, start)` final SpanFactory factory = visitor.configuration().spansFactory().get(heading.getClass()); if (factory != null) { visitor.setSpans(start, factory.getSpans(visitor.configuration(), visitor.renderProps())); } if (visitor.hasNext(heading)) { visitor.ensureNewLine(); visitor.forceNewLine(); } } }); } ``` -------------------------------- ### Configure Media Decoders with a List Source: https://github.com/noties/markwon/blob/master/docs/docs/v2/image-loader.md Provide a list of MediaDecoders to handle various image formats. Order matters, with a generic decoder recommended at the end. ```java AsyncDrawableLoader.builder() .mediaDecoders( SvgMediaDecoder.create(Resources), GifMediaDecoder.create(boolean), ImageMediaDecoder.create(Resources) ) .build(); ``` -------------------------------- ### Configure OkHttp Client for AsyncDrawableLoader Source: https://github.com/noties/markwon/blob/master/docs/docs/v2/image-loader.md Set a custom OkHttpClient for network requests. If not provided, a default client is used. ```java AsyncDrawableLoader.builder() .client(OkHttpClient) .build(); ``` -------------------------------- ### Customize BlockHandler to Control New Lines After Headings Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/core/visitor.md This example shows how to use a custom BlockHandler to modify the default behavior of inserting new lines after markdown blocks. Specifically, it prevents an extra new line after Heading nodes while preserving the default behavior for other block types. ```java final Markwon markwon = Markwon.builder(this) .usePlugin(new AbstractMarkwonPlugin() { @Override public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) { builder.blockHandler(new BlockHandlerDef() { @Override public void blockEnd(@NonNull MarkwonVisitor visitor, @NonNull Node node) { if (node instanceof Heading) { if (visitor.hasNext(node)) { visitor.ensureNewLine(); // ensure new line but do not force insert one } } else { super.blockEnd(visitor, node); } } }); } }) .build(); ``` -------------------------------- ### Adapter with Custom FencedCodeBlock Rendering Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/recycler/README.md Use `builderTextViewIsRoot` and `include` to configure the adapter to render specific markdown elements, like FencedCodeBlock, using custom entry classes. This allows for specialized display of certain markdown types. ```java final MarkwonAdapter adapter = MarkwonAdapter.builderTextViewIsRoot(R.layout.adapter_default_entry) .include(FencedCodeBlock.class, new FencedCodeBlockEntry()) .build(); ``` -------------------------------- ### Include and Register HtmlPlugin Source: https://github.com/noties/markwon/blob/master/docs/docs/v3/core/html-renderer.md To render HTML content, you must include the `markwon-html` artifact and register the `HtmlPlugin` with Markwon. ```java Markwon.builder(context) .usePlugin(HtmlPlugin.create()) ``` -------------------------------- ### Create Default Table Plugin Source: https://github.com/noties/markwon/blob/master/docs/docs/v4/ext-tables/README.md Instantiate the TablePlugin with default settings to enable basic table rendering. ```java final Markwon markwon = Markwon.builder(context) .usePlugin(TablePlugin.create(context)) .build(); ```