Giter Site home page Giter Site logo

markwon's Introduction

logo

Markwon

Build

Markwon is a markdown library for Android. It parses markdown following commonmark-spec with the help of amazing commonmark-java library and renders result as Android-native Spannables. No HTML is involved as an intermediate step. No WebView is required. It's extremely fast, feature-rich and extensible.

It gives ability to display markdown in all TextView widgets (TextView, Button, Switch, CheckBox, etc), Toasts and all other places that accept Spanned content. Library provides reasonable defaults to display style of a markdown content but also gives all the means to tweak the appearance if desired. All markdown features listed in commonmark-spec are supported (including support for inlined/block HTML code, markdown tables, images and syntax highlight).

Markwon comes with a sample application. It is a collection of library usages that comes with search and source code for each code sample.

Since version 4.2.0 Markwon comes with an editor to highlight markdown input as user types (for example in EditText).

Installation

stable snapshot

implementation "io.noties.markwon:core:${markwonVersion}"

Full list of available artifacts is present in the install section of the documentation web-site.

Please visit documentation web-site for further reference.

You can find previous version of Markwon in 2.x.x and 3.x.x branches

Supported markdown features:

  • Emphasis (*, _)
  • Strong emphasis (**, __)
  • Strike-through (~~)
  • Headers (#{1,6})
  • Links ([]() && [][])
  • Images
  • Thematic break (---, ***, ___)
  • Quotes & nested quotes (>{1,})
  • Ordered & non-ordered lists & nested ones
  • Inline code
  • Code blocks
  • Tables (with limitations)
  • Syntax highlight
  • LaTeX formulas
  • HTML
    • Emphasis (<i>, <em>, <cite>, <dfn>)
    • Strong emphasis (<b>, <strong>)
    • SuperScript (<sup>)
    • SubScript (<sub>)
    • Underline (<u>, ins)
    • Strike-through (<s>, <strike>, <del>)
    • Link (a)
    • Lists (ul, ol)
    • Images (img will require configured image loader)
    • Blockquote (blockquote)
    • Heading (h1, h2, h3, h4, h5, h6)
    • there is support to render any HTML tag
  • Task lists:
  • Not done
    • Done with X
    • and or small x

Screenshots

Taken with default configuration (except for image loading) in sample app:

By default configuration uses TextView textColor for styling, so changing textColor changes style


Documentation

Please visit documentation web-site for reference

Consulting

Paid consulting is available. Please reach me out at markwon+consulting[at]noties.io to discuss your idea or a project


Demo

Based on this cheatsheet


Headers


Header 1

Header 2

Header 3

Header 4

Header 5
Header 6

Emphasis

Emphasis, aka italics, with asterisks or underscores.

Strong emphasis, aka bold, with asterisks or underscores.

Combined emphasis with asterisks and underscores.

Strikethrough uses two tildes. Scratch this.


Lists

  1. First ordered list item
  2. Another item
  • Unordered sub-list.
  1. Actual numbers don't matter, just that it's a number

  2. Ordered sub-list

  3. And another item.

    You can have properly indented paragraphs within list items. Notice the blank line above, and the leading spaces (at least one, but we'll use three here to also align the raw Markdown).

    To have a line break without a paragraph, you will need to use two trailing spaces. Note that this line is separate, but within the same paragraph. (This is contrary to the typical GFM line break behaviour, where trailing spaces are not required.)

  • Unordered list can use asterisks
  • Or minuses
  • Or pluses

Links

I'm an inline-style link

I'm a reference-style link

I'm a relative reference to a repository file

You can use numbers for reference-style link definitions

Or leave it empty and use the link text itself.


Code

Inline code has back-ticks around it.

var s = "JavaScript syntax highlighting";
alert(s);
s = "Python syntax highlighting"
print s
/**
 * Helper method to obtain a Parser with registered strike-through &amp; table extensions
 * &amp; task lists (added in 1.0.1)
 *
 * @return a Parser instance that is supported by this library
 * @since 1.0.0
 */
@NonNull
public static Parser createParser() {
  return new Parser.Builder()
      .extensions(Arrays.asList(
          StrikethroughExtension.create(),
          TablesExtension.create(),
          TaskListExtension.create()
      ))
      .build();
}
<ScrollView
  android:id="@+id/scroll_view"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:layout_marginTop="?android:attr/actionBarSize">

  <TextView
    android:id="@+id/text"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="16dip"
    android:lineSpacingExtra="2dip"
    android:textSize="16sp"
    tools:text="yo\nman" />

</ScrollView>
No language indicated, so no syntax highlighting.
But let's throw in a <b>tag</b>.

Tables

Colons can be used to align columns.

Tables Are Cool
col 3 is right-aligned $1600
col 2 is centered $12
zebra stripes are neat $1

There must be at least 3 dashes separating each header cell. The outer pipes (|) are optional, and you don't need to make the raw Markdown line up prettily. You can also use inline Markdown.

Markdown Less Pretty
Still renders nicely
1 2 3

Blockquotes

Blockquotes are very handy in email to emulate reply text. This line is part of the same quote.

Quote break.

This is a very long line that will still be quoted properly when it wraps. Oh boy let's keep writing to make sure this is long enough to actually wrap for everyone. Oh, you can put Markdown into a blockquote.

Nested quotes

Hello!

And to you!


Inline HTML

<u><i>H<sup>T<sub>M</sub></sup><b><s>L</s></b></i></u>

HTML


Horizontal Rule

Three or more...


Hyphens (-)


Asterisks (*)


Underscores (_)

License

  Copyright 2019 Dimitry Ivanov ([email protected])

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

markwon's People

Contributors

c-b-h avatar dallasgutauckis avatar drakeet avatar florianobermayer avatar francescocervone avatar kirkbushman avatar magnusvs avatar noties avatar tunous avatar tylerbwong avatar ubuntudroid avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

markwon's Issues

Unable to use markwon-image-loader with proguard enabled

if import image-load and minifyEnabled true

compile 'ru.noties:markwon-image-loader:1.0.5'

the compile log:

Warning: com.caverock.androidsvg.SVGImageView: can't find referenced class com.caverock.androidsvg.R$styleable
Warning: com.caverock.androidsvg.SVGImageView: can't find referenced class com.caverock.androidsvg.R$styleable
Warning: com.caverock.androidsvg.SVGImageView: can't find referenced class com.caverock.androidsvg.R
Note: com.jrummyapps.android.shell.Shell$SU: can't find dynamically referenced class android.os.SELinux
Note: the configuration keeps the entry point 'com.caverock.androidsvg.SVGImageView { void setSVG(com.caverock.androidsvg.SVG); }', but not the descriptor class 'com.caverock.androidsvg.SVG'

...
...

Note: the configuration keeps the entry point 'ru.noties.markwon.tasklist.TaskListBlockParser$Factory { org.commonmark.parser.block.BlockStart tryStart(org.commonmark.parser.block.ParserState,org.commonmark.parser.block.MatchedBlockParser); }', but not the descriptor class 'org.commonmark.parser.block.ParserState'
Note: the configuration keeps the entry point 'ru.noties.markwon.tasklist.TaskListBlockParser$Factory { org.commonmark.parser.block.BlockStart tryStart(org.commonmark.parser.block.ParserState,org.commonmark.parser.block.MatchedBlockParser); }', but not the descriptor class 'org.commonmark.parser.block.MatchedBlockParser'
Note: the configuration keeps the entry point 'ru.noties.markwon.tasklist.TaskListExtension { void extend(org.commonmark.parser.Parser$Builder); }', but not the descriptor class 'org.commonmark.parser.Parser$Builder'

#1 it's not working now.

Maths / custom css support

Hi there, looking at the code I understand this could be a long and complicated task but I am just wondering the possibility of supporting maths rendering (like katex) or at least custom css rules which I presume would be the main speed bumb.

How to implement an inline parser extension

Hello!
I'm trying to implement parsing of Special GitLab References
Specifically those ones, where only starting delimiter exists: ~bug ~"Multiple word fea"
How can i do this?
I've already tried DelimiterProcessor but it seems not to support such cases.
Also, i've tried to implement custom BlockParser but it looks like it's consuming the whole line and does not give default parsers ability to do their work.
Seems that it is because of this code inside DocumentParser:

while (tryBlockStarts) {
...
tryBlockStarts = newBlockParser.isContainer();

Does it mean that i can not use BlockParser for this purpose?
Is there any way to implement InlineParser extension?

As I can see, currently library gives me two ways:

  1. Implement own InlineParser. This way seems like an overengineering and too hard for such small feature.
  2. Do not extend parsing at all and iterate over AST to find Text nodes and replace necessary parts with custom nodes. This way seems a bit hacky.

Same question in commonmark-java repo

SoftLineBreak not allowing newlines

I noticed that SpannableMarkdownVisitor.visit(SoftLineBreak softLineBreak) is appending a ' ' (space) rather than '\n'. That means processing a simple string such as "First line\nSecond line" with Markwon.markdown has a different effect than using it with SpannableStringBuilder.append.

The treatment of \n also seems inconsistent, because whereas a single \n has the effect of zero linebreaks, doing \n\n has the visual effect of not one linebreak, but two.

Is this by design? I'm trying to match an Android UI as closely to an HTML UI and simple line breaks are possible with HTML (github text for example).

Is there an alternative (or best practise) besides adding an additional \n where required and then doing textView.setLineSpacing(0, 0.5f);?

It seems like a bug, but the code seems to have explicitly done this for a reason.

Unable to use this library with proguard enabled

I'm getting the following error when I use this library with proguard enabled:

Warning:ru.noties.markwon.spans.AsyncDrawableSpan: can't find referenced class ru.noties.markwon.spans.AsyncDrawableSpan$Alignment
Warning:there were 2 unresolved references to classes or interfaces.
Warning:Exception while processing task java.io.IOException: Please correct the above warnings first.
Error:Execution failed for task ':app:transformClassesAndResourcesWithProguardForRelease'.
> Job failed, see logs for details

I tried adding this line in proguard-rules.pro but it didn't helped either:

-keep class ru.noties.markwon.** { *; }

PS: If I disable proguard, it works fine.

Selecting text causes crash

Setting textIsSelectable=true and then trying to select some text causes an IndexOutOfBoundsException:

Fatal Exception: java.lang.IndexOutOfBoundsException: setSpan (-1 ... -1) starts before 0
       at android.text.SpannableStringInternal.checkRange(SpannableStringInternal.java:442)
       at android.text.SpannableStringInternal.setSpan(SpannableStringInternal.java:163)
       at android.text.SpannableStringInternal.setSpan(SpannableStringInternal.java:152)
       at android.text.SpannableString.setSpan(SpannableString.java:46)
       at android.text.Selection.setSelection(Selection.java:76)
       at android.widget.Editor$SelectionModifierCursorController.resetDragAcceleratorState(Editor.java:5613)
       at android.widget.Editor$SelectionModifierCursorController.onTouchEvent(Editor.java:5450)
       at android.widget.Editor.onTouchEvent(Editor.java:1370)
       at android.widget.TextView.onTouchEvent(TextView.java:9657)
       at android.view.View.dispatchTouchEvent(View.java:11776)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
       at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:448)
       at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1829)
       at android.app.Activity.dispatchTouchEvent(Activity.java:3307)
       at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:68)
       at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:68)
       at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:410)
       at android.view.View.dispatchPointerEvent(View.java:12015)
       at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4795)
       at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4609)
       at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4147)
       at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4200)
       at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4166)
       at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4293)
       at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4174)
       at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4350)
       at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4147)
       at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4200)
       at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4166)
       at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4174)
       at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4147)
       at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6661)
       at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6635)
       at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6596)
       at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6764)
       at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:186)
       at android.os.MessageQueue.nativePollOnce(MessageQueue.java)
       at android.os.MessageQueue.next(MessageQueue.java:325)
       at android.os.Looper.loop(Looper.java:142)
       at android.app.ActivityThread.main(ActivityThread.java:6494)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

After a bit of searching it seems like it might be something to do with the textIsSelectable property not playing nicely with the LinkMovementMethod that is being set.
https://issuetracker.google.com/issues/37068143

I've worked around the issue for now using the answer provided here – extending MarkwonCompatView – but it would be good to get a fix in the library.

Number with dot not appearing

Hi, i use below code to with string 1. but TextView shows nothing:

 Markwon.setMarkdown(text_title, "1.")

Lib version: 1.0.5
Android v: 8.0.0
SDK: 27

Plugin system

Create a plugin system that will allow easy customization and extension of current Markwon context.

* This issue will be updated.
** Branch v3.0.0 will be created after v2.0.0 release

final Markwon markwon = Markwon.builder()
    .use(new MyPlugin()) // maybe different name
    .build();
public interface MarkwonPlugin {

    void configureParser(@NonNull Parser.Builder builder);

    void configureConfiguration(@NonNull SpannableConfiguration.Builder builder);

    void configureVisitor(@NonNull MarkdownVisitor.Builder builder);

    void configureImages(@NonNull AsyncDrawableLoader.Builder builder);

    @NonNull
    String processMarkdown(@NonNull String markdown);

    void beforeSetText(
            @NonNull TextView textView,
            @NonNull SpannableBuilder builder);

    void afterSetText(
            @NonNull TextView textView,
            @NonNull SpannableBuilder builder);
}
public class MarkdownVisitor extends AbstractVisitor {

    public interface NodeVisitor<N extends Node> {
        void visit(@NonNull MarkdownVisitor visitor, @NonNull N node);
    }

    public interface Builder {

        @NonNull
        <N extends Node> Builder on(@NonNull Class<N> node, @NonNull NodeVisitor<N> nodeVisitor);

        @NonNull
        MarkdownVisitor build(
                @NonNull SpannableConfiguration configuration,
                @NonNull SpannableBuilder builder);
    }
}

General

  • Make Markwon methods instance specific
  • Rename SpannableMarkdownVisitor -> MarkdownVisitor
  • Ensure that required by plugins methods and properties are accessible
  • Update documentation web site and provide migration guide
  • update sample applications to use plugin system
  • make sure everything can still be achieved by using old way (manually create parser, visitor, etc)

Tables

  • Remove table specific code from Visitor, Theme and Factory
  • Create TablePlugin
  • Move table feature to standalone module

Strikethrough

(maybe this functionality should be included in core features)

  • Remove specific code from Visitor, Theme and Factory
  • Create StrikethroughPlugin
  • Move strikethrough feature to standalone module

Task list

  • Remove specific code from Visitor, Theme and Factory
  • Create TaskListPlugin
  • Move task list feature to standalone module

Images

  • Move AsyncDrawableLoader to main markwon module (now it has no external dependencies)
  • Make AsyncDrawableLoader abstract or an interface (no need for this abstraction to be in AsyncDrawable
  • Create svg and gif media decoders modules
  • Create network scheme handler module
  • AsyncDrawableLoader.Builder should have addMediaDecoder method

Html

  • Provide a simple HtmlParser that will simply use Html.fromHtml (maybe include by default with the main module).
  • Combine somehow current html-parser-impl and HtmlRendererImpl (in main module). They are tightly connected anyway. Maybe by creating a new module html (keep current artifacts as-is)

Syntax highlight

  • Create syntax highlight plugin in current syntax highlight module

Issues to resolve

  • As SpannableTheme is tight with rendering context it should be decoupled from Markwon instance. Maybe create a MarkwonFactory that will accept theme as argument
  • Maybe add a gradle plugin that will automatically add required dependencies (as their number grow) and generate an entry class (factory or something). But most likely additional modules will require additional configuration..
  • Handling of duplicate Node when registering NodeVisitors. Currently I see no way of allowing at max 1 override of a node (so, only one plugin can override it). Trying to register another would fail

No GIF playback with textIsSelectable=true

I am having an issue displaying GIF with textIsSelectable=true in TextView. The GIF loads, but it does not play. If I make textIsSelectable false, it plays just fine. I have tried both in emulator and actual device with version 1.0.5

HELP: Syntax Highlighting

How can I automatic syntax highlighting. I checked the docs but I'm not able to figure it out, can you gimme a working example? Thanks

Can't display image in TextView and MarkwonView

I couldn't find a way to display an image in TextView using Markwon. The README says "Images (requires special handling)" but I couldn't find the doc on that.

Currently, in place of an image, it only shows the alternate text of the image.

Please help. Thank you very much.

Using custom fonts

Is it possible to use custom fonts painlessly? SpannableTheme does not represent such an opportunity. You can use the custom font, but only for blocks of code.

Malware warning?

My Android device is reporting the Markwon sample app as malware. Any ideas why?

Support multi visitor

I want to custom multi node processor, if i call visitor, the content is dumplicated.

// trigger visit node.accept(visitor); node.accept(channelVisitor);

Handling Link Event in TextView

Hi @noties, I am new to this library and I am stuck with handling the links on my TextView. On click I am getting the following message:
W/LinkResolverDef: Actvity was not found for intent, Intent { act=android.intent.action.VIEW dat=Romans:1:18 (has extras) }
I need to pick the text Romans1:18 from the link and format it for further processing. Can you please guide me to use this library?

Remove LinkSpan in favor of URLSpan

Hey @noties, thanks for open sourcing this project. You have saved me a lot of time. Small suggestion about links. I think that the existence of LinkSpan is not justified in Markwon. It requires extra effort to support it and breaks compatibility with other libraries.

Replacing it with URLSpan will enable,

  • Android to pick-up textColorLink from TextView's theme instead of picking it from the Context's theme. This is a problem if I use Application context for supplying a SpannableConfiguration object through my Dagger graph.

  • Third-party libraries like my Better-Link-Movement-Method and perhaps others that work with URLSpan for extracting links will continue to work just fine. My library will treat the text as the url if ClickableSpan was found instead of an URLSpan.

The responsibility of resolving links is not on a markdown processing library. This could be optional, but the responsibility of handling links should be left to MovementMethod.

In case you're wondering why can't I just register a LinkResolver to fix this problem, I extract the location of a URLSpan using a custom MovementMethod that also keeps a track of TouchEvents. This let's me display contextual popups where the links are present.

Thoughts?

Feature request: Parser adapter and renderer adapter

Hello!
Looks like currently library supports only commonmark-java for parsing Markdown.
Here is a lot more powerful library named flexmark-java.
It supports more markdown dialects and extensions.

How about adding ability to make some kind of adapter interface for parser to be able to use libraries other than commonmark-java?

I think to make it possible we need:

  • Make parser adapter
  • Make renderer adapter

Extra linebreak added at the end

Hey!

Thank you for building this library.

We are trying to use your library at Crisp (Messaging App), to replace the previous one witch our users didn't like.

It works great so far, but we noticed that it's adding an extra space at the end:

image

Quote typeface

Hello,
is it possible to change typeface and text size of quote ?
Cannot see possibility of changing anything in SpannableTheme to achieve that effect.
Is it possible to do without forking and implementing custom span ?

Todo items

Спасибо за великолепную библиотеку!

Вопрос вот в чём: будет ли введена поддержка todo-итемов?

 - [ ] пустой чекбокс
 - [x] заполненный чекбокс
  • пустой чекбокс
  • заполненный чекбокс

text\ntext not parsed correctly

Hello, thank you for this amazing library! I really love it!

While I was using it, I found a small bug where the \n character is not rendered correctly. When I did Markwon.setMarkdown(textView, "haha\ngaga");, the outcome looks like this:

image

Where I would expect there's a newline between "haha" and "gaga". Could anyone show me how to fix this? Greatly appreciated!

No image size resolving in visitor

Hi. Thanks for wonderful Markdown view, was a life-saver to me.

Here: SpannableMarkdownVisitor#visit(org.commonmark.node.Image)

The AsyncDrawable is created without imageSizeResolver and it's rendered veeeery big

I understand that there are no size constraints in native Markdown syntax but at least some level of customization should be possible for images to fit/scale into the textview.

Exception in selection mode

Hello, thanks for helping me fix the newline bug, I really appreciate it!

I would like to report another bug that's affecting a lot of our users, and it's trigger when I enable the selection mode using TextView.setIsTextSelectable(true). The error is shown as below:

image

Any idea why this is happening and how to fix this?

Really appreciate it!

Coloring headlines

Hi,

Is there a way to color all headlines in some color? I found the option for the line below a headline but not the text color itself.

Thanks for creating Markwon!

Bullet point circles don't indent with encompassing LeadingMarginSpan

I've noticed that the bullet points from a Markdown render don't indent when they're encompassed by a LeadingMarginSpan. The text of the bullet points will indent correctly though. The circles appear to be absolutely positioned to the left margin.

The following code should should the issue.

SpannableConfiguration spannableConfiguration = SpannableConfiguration.create(this);
SpannableStringBuilder ssb = new SpannableStringBuilder();

ssb.append("First line\n");
int start = ssb.length();
ssb.append(Markwon.markdown(spannableConfiguration, "* first item\n * second item\n" ));
ssb.setSpan(new LeadingMarginSpan() {
      @Override
      public int getLeadingMargin(boolean first) {
          return 200;
      }
      @Override
      public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, int top, int baseline, int bottom, CharSequence text, int start, int end, boolean first, Layout layout) {
      }
}, start, ssb.length(), 0);

ssb.append("last line");

textView.setText(ssb);

Should BulletListItemSpan::drawLeadingMargin be receiving an indented x value? It will always have zero with this example.

More customizable headers

Great library. I'm not crazy about these two things related to headers, though:

  1. I'd like to control the typeface of the header. I'm following this approach (#20) but it feels super clunky. If I submitted a PR with this added to SpannableTheme, would that be acceptable?
  2. I'd like to specifically control the textSize of the header. AFAICT this isn't supported at all (the HEADING_SIZES multipliers are private and final). Same question about PR-friendliness.

Number of issues

Hi, first and foremost - thank you very much for this library, I'm really impressed with it so far.
I'm developing a reddit app and using the markdown in this comment I have come accross the following issues, where the top part of the screen is what it should look like, and bottom part is what it looks like with this library:

  1. Superscripts are not supported
  2. Headers don't work when hashtag isn't followed with a space working as intended according to commonmark-java
  3. Headers are underlined
  4. Ordered lists don't start from 1 working as intended according to commonmark-java
  5. Code blocks don't work

2 Might not follow the markdown spec but I'm not sure.

I also can't use Markwon.scheduleTableRows(textView) as I'm using a custom view to draw the text. Looking at the source, it shouldn't be too hard I think to implement this, as all it would need would be to provide an interface with setText and getText methods

Bullet lists don't work when appending to a SpannableStringBuilder

I'm attempting to append multiple lines of independently processed markdown to a SpannableStringBuilder like so.

String line1 = "Initial _line_.";
String line2 = "List: \n* item 1 \n* item 2\n";
String line3 = "Simple _line_.";

SpannableConfiguration spannableConfiguration = SpannableConfiguration.create(this);
SpannableStringBuilder ssb = new SpannableStringBuilder();

ssb.append(Markwon.markdown(spannableConfiguration, line1));
ssb.append(Markwon.markdown(spannableConfiguration, line2));
ssb.append(Markwon.markdown(spannableConfiguration, line3));

contactTextView.setText(ssb);

This won't show/render the bullet points for line2. However, if the lines are appended as line2, line1 then line3 (i.e. the markdown string with the bullet points is append first, then the bullet points will render.

Is this by design or is there a bug?

Text truncated in list

Hello!

One of our users is seeing this rendering bug:

If you look on the right side, some text are being truncated.

Please let me know if this could be fixed! Happy to provide more information!

Implementation of WYSIWYG Editor / Colored Text

I have 2 issues I am working on:

  1. I'd like to implement a WYSIWYG Editor based on Markwon.
  • Switching from Plaintext to rendered Markdown is no problem.
  • I like to have one view with buttons/functions so the user does not need to write Markdown or switch the views
  • How to achieve that? Is there anything possible with the use of Markwon?
  1. I'd like to be able to change the text color of normal text and to save it. Markdown is not capable nor designed to implement something like color. Are there any suggestions on how to achieve that? Maybe something like adding custom attributes/values to the markdown file/string and render them with a custom Markwon parser?

Last bullet at end of markdown is rendered too small

If the markdown ends with a bullet list, the last bullet is smaller than the others.

The markdown "* Line 1\n* Line 2\n* Line 3" gets rendered as
image

If you add an extra paragraph, the last bullet gets rendered correctly.

Can't change code blocks margin

Hi

I recently started using this lib, but I'm unable to change the margin (left and right) of code blocks. I've set it as low as 1 (px if I'm not wrong) but it doesn't works.

Also, the annotation is set as @Dimension when it should be either @Px, I think.

Additionally I want to ask how can I increase the line spacing, because 2 code parts in different lines look like they are connected when they are not.

I've already set android:lineSpacingMultiplier="1.2" in the TextView but it doesn't work.

Thanks in advance.

Here's the setup

val theme = SpannableTheme.builder()
    .blockMargin(1)
    .codeMultilineMargin(1)
    .blockQuoteWidth(1)
    .build()
val config = SpannableConfiguration.builder(context)
    .softBreakAddsNewLine(true)
    .theme(theme)
    .build()
Markwon.setMarkdown(it, config, message.message)

Here's the text I'm showing

`this is a test`
`and another one`

---

`this is a test`

`and another one`

And here's the final look:
screenshot_20181111-203430

Syntax for Task Lists

The readme says there is Task List Support. I tried - [ ] as well as [x] or - [X] but nothing seems to get rendered.

Text alignment on the Ordered list

Testing with the GitHub Cheatsheet, I'm seeing the numbers on the list not being baseline aligned to the text.

Using 1.1.0. I am using BetterLinkMovement and a SpannableMarkdownVisitor subclass to handle soft breaks, but I don't think this should have anything to do with that.

Feature: image sizes

Right now library doesn't support custom sizing of images. But it would be a good thing to support it.

There is no standard about image sizes in markdown. But as markdown supports inline HTML, library might be parsing HTML arguments specified in <img> tag:

  • width=
  • height=
  • style="width: ; height: ;"

Another thing is what measure units to support. I suggest using:

  • % percent
  • px pixels (all other units pt, em defaults to pixels). And pixels should be treated as dp on Android

Image on a newline is not parsed correctly

With markdown like this:

Sample image:

<img src="https://upload.wikimedia.org/wikipedia/en/f/f4/Unrealtournament.jpg" />

Image is parsed as HtmlBlock by Commonmark parser, not as HtmlInline, later this is handled by SpannableMarkdownVisitor::visit(HtmlBlock htmlBlock) which assumes tag as null and passes it to Html.fromHtml which doesn't support images.

image

Table spans are unstable if there's text around it

Table spans are quite brittle, the don't survive additions of simple text content before them.
This test-case outlines that (written in Kotlin, hope you don't mind).

    @Test
    fun testMarkwonTable() {
        val table = javaClass.getResourceAsStream("/sample-table.md").bufferedReader().readText()
        val spanned = Markwon.markdown(activity, table) as Spannable
        val spans = spanned.getSpans(0, spanned.length, TableRowSpan::class.java)
        Assert.assertTrue("Should have table spans!", spans.isNotEmpty())

        val tableWithHeader = """
            With header everything is ok
            =============================

                              """.trimIndent() + table
        val spannedHeader = Markwon.markdown(activity, tableWithHeader) as Spannable
        val spansHeader = spannedHeader.getSpans(0, spannedHeader.length, TableRowSpan::class.java)
        Assert.assertTrue("Should have table spans!", spansHeader.isNotEmpty())

        val tableAfterText = """
            But adding just text before the table causes it to collapse

                            """.trimIndent() + table

        val spannedAfterText = Markwon.markdown(activity, tableAfterText) as Spannable
        val spansAfterText = spannedAfterText.getSpans(0, spannedAfterText.length, TableRowSpan::class.java)
        Assert.assertTrue("Should have table spans!", spansAfterText.isNotEmpty())
    }

contents of sample table:

|          One ring           |         Patterns         |              Titanic              |   |   |   |
|-----------------------------|--------------------------|-----------------------------------|---|---|---|
|  One ring to rule them all  |There's one for the sorrow|      Roll on, Titanic, roll       |   |   |   |
|    One ring to find them    |   And two for the joy    |You're the pride of White Star Line|   |   |   |
| One ring to bring them all  | And three for the girls  |      Roll on, Titanic, roll       |   |   |   |
|And in the darkness bind them|  And four for the boys   |      Into the mists of time       |   |   |   |

This test fails on the last assert for me.

Image scale preserving aspect ratio with Spannable logic

Hello, thanks for the library. I have a question about image size.
According to default ImageSizeResolverDef implementation for Spannable case, my image is cut off. I want my image to be scaled preserving aspect ratio. Is it possible to implement?

This is cut image:
cut_image

This is full image:
full_image

Support multi visitor

I want to custom multi node processor, if i call visitor, the content is dumplicated.

node.accept(visitor); node.accept(channelVisitor);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.