Markdown for Android, supports TextView && EditText (Live Preview), supports code high light.

Overview

RxMarkdown

License API Android Arsenal

RxMarkdown is an Android library that helps to display simple markdown text in android.widget.EditText or android.widget.TextView, at same time, it supports code high light .

It is backed by RxJava, implementing complicated APIs as handy reactive observables.

中文:README-zh-rCN.md

Demo apk : DOWNLOAD

QR Code : CLICK

Change Log : SEE

RxMarkdown.gif

Gradle

implementation 'com.yydcdut:markdown-processor:0.1.3'
implementation 'com.yydcdut:rxmarkdown-wrapper:0.1.3'

Or if you don't want to use RxJava, you can simply refer to markdown-processor :

implementation 'com.yydcdut:markdown-processor:0.1.3'

Support Syntax

RxMarkdown now provides 2 factories to parse markdown, TextFactory and EditFactory .

TextFactory : Supports most of the markdown syntax,but it will destroy the integrity of the content. So, it applies to render in TextView .

EditFactory : Supports some syntax,and it won't destroy the integrity of the content, the parsing speed is faster than TextFactory , So, it applies to real-time preview in EditText .

TextFactory

  • Header # / ## / ### / #### / ##### / #######
  • BlockQuote >
  • Nested BlockQuote > >
  • Emphasis Bold ** __
  • Emphasis Italic * _
  • Nested Bold && Italic
  • Ordered List 1.
  • Nested Ordered List
  • UnOrdered List * / + / -
  • Nested UnOrdered List
  • Image ![]()
  • Hyper Link []()
  • Inline Code
  • Code
  • Backslash \
  • Horizontal Rules *** / ***** / --- / -----------------
  • Strike Through ~~
  • Footnote [^]
  • Todo - [ ] / - [x]
  • Table | Table | Table |
  • code high light

Other Syntax

  • Center Align []

EditFactory

  • Header # / ## / ### / #### / ##### / #######
  • BlockQuote >
  • Nested BlockQuote > >
  • Emphasis Bold ** __
  • Emphasis Italic * _
  • Nested Bold && Italic
  • Ordered List 1.
  • Nested Ordered List
  • UnOrdered List * / + / -
  • Nested UnOrdered List
  • Image ![]()
  • Hyper Link []()
  • Inline Code
  • Code
  • Backslash \
  • Horizontal Rules *** / ***** / --- / -----------------
  • Strike Through ~~
  • Footnote [^]
  • Todo - [ ] / - [x]
  • Table | Table | Table |
  • code high light

Other Syntax

  • Center Align []

HtmlFactory

//TODO

Quick Start

Setup

implementation 'com.yydcdut:markdown-processor:0.1.3'
implementation 'com.yydcdut:rxmarkdown-wrapper:0.1.3'

implementation 'io.reactivex:rxandroid:1.2.0'
implementation 'io.reactivex:rxjava:1.1.5'

Configuration

All options in Configuration builder are optional. Use only those you really want to customize (RxMDConfiguration#Builder and MarkdownConfiguration#Builder are the same usage):

RxMDConfiguration rxMDConfiguration = new RxMDConfiguration.Builder(context)
        .setHeader1RelativeSize(1.6f)//default relative size of header1
        .setHeader2RelativeSize(1.5f)//default relative size of header2
        .setHeader3RelativeSize(1.4f)//default relative size of header3
        .setHeader4RelativeSize(1.3f)//default relative size of header4
        .setHeader5RelativeSize(1.2f)//default relative size of header5
        .setHeader6RelativeSize(1.1f)//default relative size of header6
        .setBlockQuotesLineColor(Color.LTGRAY)//default color of block quotes line
        .setBlockQuotesBgColor(Color.LTGRAY, Color.RED, Color.BLUE)//default color of block quotes background and nested background
        .setBlockQuotesRelativeSize(Color.LTGRAY, Color.RED, Color.BLUE)//default relative size of block quotes text size
        .setHorizontalRulesColor(Color.LTGRAY)//default color of horizontal rules's background
        .setHorizontalRulesHeight(Color.LTGRAY)//default height of horizontal rules
        .setCodeFontColor(Color.LTGRAY)//default color of inline code's font
        .setCodeBgColor(Color.LTGRAY)//default color of inline code's background
        .setTheme(new ThemeDefault())//default code block theme
        .setTodoColor(Color.DKGRAY)//default color of todo
        .setTodoDoneColor(Color.DKGRAY)//default color of done
        .setOnTodoClickCallback(new OnTodoClickCallback() {//todo or done click callback
        	@Override
        	public CharSequence onTodoClicked(View view, String line) {
                return textView.getText();
        	}
        })
        .setUnOrderListColor(Color.BLACK)//default color of unorder list
        .setLinkFontColor(Color.RED)//default color of link text
        .showLinkUnderline(true)//default value of whether displays link underline
        .setOnLinkClickCallback(new OnLinkClickCallback() {//link click callback
        	@Override
        	public void onLinkClicked(View view, String link) {
        	}
        })
        .setRxMDImageLoader(new DefaultLoader(context))//default image loader
        .setDefaultImageSize(100, 100)//default image width & height
        .build();

Rx Usage

  • EditText , live preview :

    RxMarkdown.live(rxMDEditText)
            .config(rxMDConfiguration)
            .factory(EditFactory.create())
            .intoObservable()
            .subscribe();
  • cancel real-time preview :

    rxMDEditText.clear();
  • TextView render :

    RxMarkdown.with(content, this)
            .config(rxMDConfiguration)
            .factory(TextFactory.create())
            .intoObservable()
            .subscribeOn(Schedulers.computation())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Subscriber<CharSequence>() {
                @Override
                public void onCompleted() {}
    
                @Override
                public void onError(Throwable e) {}
    
                @Override
                public void onNext(CharSequence charSequence) {
                    rxMDTextView.setText(charSequence, TextView.BufferType.SPANNABLE);
                }
            });

non-Rx Usage

  • EditText , live preview :

    MarkdownProcessor markdownProcessor = new MarkdownProcessor(this);
    markdownProcessor.config(markdownConfiguration);
    markdownProcessor.factory(EditFactory.create());
    markdownProcessor.live(markdownEditText);
  • cancel real-time preview :

    markdownEditText.clear();
  • TextView render :

    MarkdownProcessor markdownProcessor = new MarkdownProcessor(this);
    markdownProcessor.factory(TextFactory.create());
    markdownProcessor.config(markdownConfiguration);
    textView.setText(markdownProcessor.parse(content));

Note

RxMDImageLoader

  • Acceptable URIs examples

    "http://web.com/image.png" // from Web
    "file:///mnt/sdcard/image.png" // from SD card
    "assets://image.png" // from assets
    "drawable://" + R.drawable.img // from drawables (non-9patch images)
  • Custom image loader

    public class MDLoader implements RxMDImageLoader {
        @Nullable
        @Override
        public byte[] loadSync(@NonNull String url) throws IOException {
            return new byte[0];
        }
    }

Image Size

The image of 320 pixels width and 320 pixels height will display on the screen :

![image](http://web.com/image.png/320$320)

Code HighLight Theme

The lib supports some themes, ThemeDefault, ThemeDesert, ThemeSonsOfObsidian and ThemeSunburst.

ThemeDefault ThemeDesert ThemeSonsOfObsidian ThemeSunburst
ThemeDefault ThemeDesert ThemeSonsOfObsidian ThemeSunburst

You can implement the interface Theme to realize your own theme.

public class CodeHighLightTheme implements Theme {

    @Override
    public int getBackgroundColor() {//background color
        return 0xffcccccc;
    }

    @Override
    public int getTypeColor() {//color for type
        return 0xff660066;
    }

    @Override
    public int getKeyWordColor() {//color for keyword
        return 0xff000088;
    }

    @Override
    public int getLiteralColor() {//color for literal
        return 0xff006666;
    }

    @Override
    public int getCommentColor() {//color for comment
        return 0xff880000;
    }

    @Override
    public int getStringColor() {//color for string
        return 0xff008800;
    }

    @Override
    public int getPunctuationColor() {//color for punctuation
        return 0xff666600;
    }

    @Override
    public int getTagColor() {//color for html/xml tag
        return 0xff000088;
    }

    @Override
    public int getPlainTextColor() {//color for a plain text
        return 0xff000000;
    }

    @Override
    public int getDecimalColor() {//color for a markup declaration such as a DOCTYPE
        return 0xff000000;
    }

    @Override
    public int getAttributeNameColor() {//color for html/xml attribute name
        return 0xff660066;
    }

    @Override
    public int getAttributeValueColor() {//color for html/xml attribute value
        return 0xff008800;
    }

    @Override
    public int getOpnColor() {//color for opn
        return 0xff666600;
    }

    @Override
    public int getCloColor() {//color for clo
        return 0xff666600;
    }

    @Override
    public int getVarColor() {//color for var
        return 0xff660066;
    }

    @Override
    public int getFunColor() {//color for fun
        return Color.RED;
    }

    @Override
    public int getNocodeColor() {color for nocode
        return 0xff000000;
    }
}

License

Copyright 2016 yydcdut

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.

Comments
  • IndexOutOfBoundsException caused by BlockQuotesController

    IndexOutOfBoundsException caused by BlockQuotesController

    I'm getting a reproducable IndexOutOfBoundsException caused by BlockQuotesController. Way to reproduce:

    Type Test into a RxMDEditText. Then press 4 times backspace in order to remove all characters. On removing the third character, the following exception is thrown:

    java.lang.IndexOutOfBoundsException: getChars (1 ... 2) ends beyond length 1
        at android.text.SpannableStringBuilder.checkRange(SpannableStringBuilder.java:1090)
        at android.text.SpannableStringBuilder.getChars(SpannableStringBuilder.java:972)
        at android.text.TextUtils.getChars(TextUtils.java:87)
        at android.text.SpannableStringBuilder.<init>(SpannableStringBuilder.java:65)
        at android.text.SpannableStringBuilder.subSequence(SpannableStringBuilder.java:964)
        at com.yydcdut.rxmarkdown.edit.BlockQuotesController.onTextChanged(BlockQuotesController.java:74)
        at com.yydcdut.rxmarkdown.RxMDEditText.onTextChanged4Controller(RxMDEditText.java:265)
        at com.yydcdut.rxmarkdown.RxMDEditText.access$800(RxMDEditText.java:54)
        at com.yydcdut.rxmarkdown.RxMDEditText$1.onTextChanged(RxMDEditText.java:186)
        at android.widget.TextView.sendOnTextChanged(TextView.java:7991)
        at android.widget.TextView.handleTextChanged(TextView.java:8053)
        at android.widget.TextView$ChangeWatcher.onTextChanged(TextView.java:10157)
        at android.text.SpannableStringBuilder.sendTextChanged(SpannableStringBuilder.java:1033)
        at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:559)
        at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:492)
        at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:491)
        at android.view.inputmethod.BaseInputConnection.replaceText(BaseInputConnection.java:685)
        at android.view.inputmethod.BaseInputConnection.setComposingText(BaseInputConnection.java:445)
        at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.java:340)
        at com.android.internal.view.IInputConnectionWrapper$MyHandler.handleMessage(IInputConnectionWrapper.java:78)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:148)
        at android.app.ActivityThread.main(ActivityThread.java:5417)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
    
    bug 
    opened by korelstar 11
  • checkboxes can't be (un)checked easily

    checkboxes can't be (un)checked easily

    I use RxMarkdown in nextcloud-notes (https://github.com/stefan-niedermann/nextcloud-notes/) With the syntax '- [ ] item 1' '- [x] item 2' I have two nice checkboxes in 'view mode' but I can't check or uncheck the checkboxes. See the bugs https://github.com/stefan-niedermann/nextcloud-notes/issues/287 and https://github.com/stefan-niedermann/nextcloud-notes/issues/157

    Please can you enhance this point?

    opened by jpggithub 9
  • line-height (space between the lines) is too small

    line-height (space between the lines) is too small

    As a user i would like to have the option to configure the line-height to enhance readability. Alternativeley this issue would be solved for me if the line-height would be increased hardcoded by 50%.

    opened by stefan-niedermann 9
  • Rendering of **Text**

    Rendering of **Text**

    The Library is really working well and appreciate its responsiveness compared to other MarkDown renders I've interacted with. But, I have encountered problem while rendering bold text of the form Text

    opened by DBetta 7
  • Some style issues

    Some style issues

    Hi @yydcdut, first of all: thanks for this great lib! I am planning to use it in the Nextcloud Notes-app. Currently i am struggling with some style issues we experienced while testing. Maybe these style issues could be fixed or at least a configuration option could be provided by you for these?

    • [x] 1.) Headings in TextView have a padding or margin on the left side: (fixed in #10)

    hadings

    Expected behavior: There is no padding or margin or there is a configuration to disable it or set it to zero.

    • [ ] 2.) Very long quotes (> Text) that do not fit into a single line crash on the grey border (TextView && EditView)

    quote

    Expected behavior: Even if the line breaks because it does not fit into a single row the padding/margin on the left side should be equal to the first line. Bonus: Make the padding configurable (i personally would like to have some more padding here)

    bug enhancement 
    opened by stefan-niedermann 6
  • Auto-link URLs

    Auto-link URLs

    It would be nice, if for any URL, a link is created automatically.

    For RxMDEditText, every URL should be auto-linked (regardless if it is inside of a []() or not). However, there will be a conflict between positioning the cursor by clicking and open the link by clicking. Therefore, I would propose to open the link by long-clicking (maybe using an additional menu), so that normal clicking still performs cursor positioning.

    For RxMDTextView, links outside of a []() should be linked. Here, opening the link can be called by normal clicking.

    enhancement 
    opened by korelstar 5
  • URLSpans don't work properly

    URLSpans don't work properly

    If we got:

    This is another [link](http://deathstar-qa.herokuapp.com/reporting) please
    

    It's not printing the url span properly, it just prints the text.

    I've checked the code, and also I've been retrieving the spans, and it seems the span is there URLSpan[] spans = stringBuilder.getSpans(0, charSequence.length(), URLSpan.class); but it's not being drawn properly:

    screenshot_20170403-163147

    opened by cesards 4
  • Stop creating new list items on multiple Enter-presses

    Stop creating new list items on multiple Enter-presses

    Given you edited a list and want to continue with a normal paragraph. You press Enter, a new list item is generated (using a *-sign). When you do not enter anything but press enter again Then the empty list template (The *-sign) should be removed and a empty line should be inserted to enable the user to go ahead with a normal paragraph.

    Current behavior If you press enter x times, there are generated x new empty list items

    unbenannt

    opened by stefan-niedermann 4
  • Check-Boxes in every line-start of long paragraph

    Check-Boxes in every line-start of long paragraph

    I use Android App "Nextcloud Notes" (https://github.com/stefan-niedermann/nextcloud-notes).

    Problem:

    In view-mode you get a checkbox at every line's start within a long paragraph when viewing on small devices which force line-breaks.

    start snip

    Test ToDo

    • [ ] lore ipsum infernalis lore ipsum infernalis lore ipsum infernalis

    stop snip

    Steps to reproduce the issue:

    Android version:** 7.1.2 LineageOs Device: Sony Xperia Z System language: German App version: 0.1.21 App source: F-Droid

    • open the app
    • click on a note
    • use the edit button
    • insert long text with checkbox
    opened by treborxy 3
  • Modifications to...

    Modifications to...

    • Better identify inappropriate italics and bold (e.g. in file names, with incorrect whitespace usage).
    • Quote relative size, colored backgrounds, and custom colored backgrounds depending on nesting level.
    • Code uses a monospace typeface.
    opened by bjdupuis 3
  • Pasting images

    Pasting images

    Hello, im trying to use the edittext widget, i need users to be able to past images (copied from webpage in chrome) into it but the images are pasted as a green/azure square with the DefaultLoader. Is there any way to get the images correctly when pasted?

    opened by RedLann 2
  • How to change code font colour for TextFactory?

    How to change code font colour for TextFactory?

    Hi

    This is really good library for markdown. It save my time a lot. I have one issue regarding the code font colour.

    I want to show code font in red colour so using RxMDConfiguration, set below 2 things: .setCodeBgColor(Color.LTGRAY) .setCodeFontColor(Color.RED)

    In app, code font color always remain same(Black). Not change according to setCodeFontColor(means not show red colour).

    please guide/help me. I am waiting for you answer

    Regards, Rup

    opened by Rupkuvarba 0
  • add try catch when parsing image tag

    add try catch when parsing image tag

    ![]() will make the app crash.

    E/AndroidRuntime: FATAL EXCEPTION: OkHttp Dispatcher
        Process: com.abbysyyu.diary, PID: 5017
        java.lang.IndexOutOfBoundsException: replace (5 ... 15) ends beyond length 10
            at android.text.SpannableStringBuilder.checkRange(SpannableStringBuilder.java:1090)
            at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:498)
            at android.text.SpannableStringBuilder.delete(SpannableStringBuilder.java:225)
    ...
    
    opened by ray1422 0
  • Link detection faulty

    Link detection faulty

    Hello,

    while trying to hook into hyperlink processing (to make relative links work), I realized that hyperlink parsing in general seems to be broken.

    problem

    Suppose we have a markdown like

     1. [link!](https://www.example.com)
     2. [link!](example.com)
     3. [link!](56366)
    

    All three should be valid and interpreted as links. But rxmarkdown only interprets (1) as a link. The others are ignored and rendered as [link!](example.com) and [link!](56366) in the output.

    presumed cause

    com.yydcdut.markdown.syntax.text.HyperLinkSyntax#contains seems to be broken. It return in all three cases false. While it should actually return true in all three cases.

    As a result, you only check in line 60 the AUTO_LINK_PATTERN regex to see if you can do auto linking in this line. And for case (1) this actually works. That's why line (1) is interpreted correctly as a link but the other two not.

    The problem lies in line 106 and following. Here

                        if (TextHelper.getChar(array, ++i) == 0 || TextHelper.getChar(findArray, ++findPosition) == 0) {
                            return false;
                        }
                        if (TextHelper.getChar(array, ++i) != TextHelper.getChar(findArray, ++findPosition)) {
                            findPosition--;
                        } else {
                            findPosition++;
                        }
    

    you increment i and findPosition in the method calls which results in incorrect behaviour. I guess replacing eg. ++i with i+1 (and the same for findPosition would solve the problem.

    On the other hand, I'm not entirely sure, why you need this method at all. Isn't matching with the PATTERN regex from the same file enough to detect whether the string contains a markdown link? It looks like the method tries to do the same as matching the regex programmatically (but does it faulty).

    regards,

    Simon

    opened by lenzls 0
Releases(v0.1.3)
Owner
yydcdut
花Q!
yydcdut
Androids EditText that animates the typed text. EditText is extended to create AnimatedEditText and a PinEntryEditText.

AnimatedEditText for Android This repository contains AnimatedEditText and TextDrawable all of which extend the behaviour of EditText and implement fe

Ali Muzaffar 439 Nov 29, 2022
A library to show emoji in TextView, EditText (like WhatsApp) for Android

Discontinued This projected is discontinued. Please consider using other alternative, i.e EmojiCompat. Contact me if you want to continue working on a

Hieu Rocker 3.6k Jan 5, 2023
An extension of Android's TextView, EditText and Button that let's you use the font of your choice

AnyTextView (deprecated) Note: AnyTextView is no longer being maintained. I recommend replacing AnyTextView with the Calligraphy library instead. Frus

Hans Petter Eide 165 Nov 11, 2022
Form validation and feedback library for Android. Provides .setText for more than just TextView and EditText widgets. Provides easy means to validate with dependencies.

android-formidable-validation Form validation and feedback library for Android. Provides .setText for more than just TextView and EditText widgets. Pr

Linden 147 Nov 20, 2022
Simple way to create linked text, such as @username or #hashtag, in Android TextView and EditText

Simple Linkable Text Simple way to create link text, such as @username or #hashtag, in Android TextView and EditText Installation Gradle Add dependenc

Aditya Pradana Sugiarto 76 Nov 29, 2022
A simple and flexible Checked TextView or Checkable TextView

CheckableTextView Checkable TextView [KOTLIN] ⚡ A simple and flexible Checked TextView or Checkable TextView written in Kotlin ⚡ What's New Animation

null 110 Nov 20, 2022
Mentions-TextView - Make Mentions and hashtags clickable in Textview

Mentions Textview Custome Textview with Mentions and hashtags being clickable. D

null 2 Jan 9, 2022
A module designed to encapsulate the use of an Android EditText field for gathering currency information from a user. Supports all ISO-3166 compliant locales/currencies.

CurrencyEditText CurrencyEditText is an extension of Android's EditText view object. It is a module designed to provide ease-of-use when using an Edit

Josh Kitchens 335 Dec 25, 2022
Light-weighted, convenient implementation of expandable text view that supports expanding & collapsing animations for Android projects

ExpandableTextView Light-weighted, convenient implementation of expandable text view that supports expanding & collapsing animations for Android proje

Giang H. Pham 22 Jan 6, 2023
AutoLinkTextView is TextView that supports Hashtags (#), Mentions (@) , URLs (http://), Phone and Email automatically detecting and ability to handle clicks.

AutoLinkTextView Deprecated Please use the new version of AutoLinkTextView AutoLinkTextView is TextView that supports Hashtags (#), Mentions (@) , URL

Arman 1.1k Nov 23, 2022
MarkdownView is an Android webview with the capablity of loading Markdown text or file and display it as HTML, it uses MarkdownJ and extends Android webview.

MarkdownView is an Android webview with the capablity of loading Markdown text or file and display it as HTML, it uses MarkdownJ and extends Android webview.

Feras Alnatsheh 1k Dec 20, 2022
Markdown Text for Android Jetpack Compose 📋.

Markdown Text for Android Jetpack Compose ??.

Jeziel Lago 250 Jan 4, 2023
Dealing with Android Text by simple way to get high performance.

Gapo Android RichText RichText supports Hashtag, Mention, Url, Phone Number, Email, Markdown, Custom Span, SeeMore/SeeLess by limited line or length,

GapoWork 8 Oct 20, 2021
Dealing with Android Text by simple way to get high performance.

Gapo Android RichText RichText supports Hashtag, Mention, Url, Phone Number, Email, Markdown, Custom Span, SeeMore/SeeLess by limited line or length,

GapoWork 8 Oct 20, 2021
Android library contain custom realisation of EditText component for masking and formatting input text

Masked-Edittext Masked-Edittext android library EditText widget wrapper add masking and formatting input text functionality. Install Maven <dependency

Evgeny Safronov 600 Nov 29, 2022
AutosizeEditText for Android is an extension of native EditText that offer a smooth auto scale text size.

AutoscaleEditText AutosizeEditText for Android is an extension of native EditText that offer a smooth auto scale text size. Latest Version How to use

Txus Ballesteros 354 Nov 28, 2022
Add text masking functionality to Android EditText. It will prevent user from inserting not allowed signs, and format input as well.

MaskFormatter MaskFormatter adds mask functionality to your EditText. It will prevent user from inserting not allowed signs, and format input as well.

Azimo Labs 161 Nov 25, 2022
A simple Android Tag EditText

TagEditText A simple Android Tag EditText. Setup The easiest way to add the TagEditText library to your project is by adding it as a dependency to you

HearSilent 15 May 5, 2022
An Android App example of how to create a custom EditText using DoubleLinkedList Data Structure

DoubleLinkedListEditText Library This is a library to create an EditText based on the Doubly Linked List data structure so that the user can enter cod

Layon Martins 1 Nov 9, 2021