This artifact encapsulates HTML parsing from the core artifact and provides
few predefined
TagHandlers
final Markwon markwon = Markwon.builder(context).usePlugin(HtmlPlugin.create()).build();
As this artifact brings modified
jsoup
library
it was moved to a standalone module in order to minimize dependencies and unused code
in applications that does not require HTML render capabilities.
Before
2.0.0
Markwon
used android
Html
class for parsing and
rendering. Unfortunately, according to markdown specification, markdown can contain
HTML in
unpredictable
way if rendered
outside
of browser. For example:
<i>
Hello from italics tag
</i><b>bold></b>
This snippet could be represented as:
HtmlBlock (
<i>\nHello from italics tag
)
HtmlInline (
<i>
)
HtmlInline (
<b>
)
Text (
bold
)
HtmlInline (
</b>
)
A bit of background
This issue
had brought attention to differences between HTML & commonmark implementations.
Unfortunately Android
HTML
class cannot parse a
fragment
of HTML to later
be included in a bigger set of content. This is why the decision was made to bring
HTML parsing
in-markwon-house
All predefined tag handlers will use styling spans for native markdown content.
So, if your
Markwon
instance was configured to, for example, render Emphasis
nodes as a
red text
then HTML tag handler will
use the same span. This includes images, links, UrlResolver, LinkProcessor, etc
Staring with
4.0.0
you can exclude all default tag handlers:
To define a tag-handler that applies style for the whole tag content (from start to end),
a
SimpleTagHandler
can be used. For example, let's define
<align>
tag, which can be used
like this:
<align center>centered text</align>
<align end>this should be aligned at the end (right for LTR locales)</align>
<align>regular alignment</align>
publicclassAlignTagHandlerextendsSimpleTagHandler{@Nullable@Overridepublic Object getSpans(@NonNull MarkwonConfiguration configuration,@NonNull RenderProps renderProps,@NonNull HtmlTag tag){final Layout.Alignment alignment;// html attribute without value, <align center></align>if(tag.attributes().containsKey("center")){
alignment = Layout.Alignment.ALIGN_CENTER;}elseif(tag.attributes().containsKey("end")){
alignment = Layout.Alignment.ALIGN_OPPOSITE;}else{// empty value or any other will make regular alignment
alignment = Layout.Alignment.ALIGN_NORMAL;returnnewAlignmentSpan.Standard(alignment);@NonNull@Overridepublic Collection<String>supportedTags(){return Collections.singleton("align");
TIP
SimpleTagHandler
can return an array of spans from
getSpans
method
final Markwon markwon = Markwon.builder(this).usePlugin(HtmlPlugin.create(plugin -> plugin.addHandler(newAlignTagHandler()))).build();
If a tag requires special handling
TagHandler
can be used directly. For example
let's define an
<enhance>
tag with
start
and
end
arguments, that will mark
start and end positions of the text that needs to be enlarged:
<enhancestart="5"end="12">This is text that must be enhanced, at least a part of it</enhance>
publicclassEnhanceTagHandlerextendsTagHandler{privatefinalint enhanceTextSize;EnhanceTagHandler(@Pxint enhanceTextSize){this.enhanceTextSize = enhanceTextSize;@Overridepublicvoidhandle(@NonNull MarkwonVisitor visitor,@NonNull MarkwonHtmlRenderer renderer,@NonNull HtmlTag tag){// we require start and end to be presentfinalint start =parsePosition(tag.attributes().get("start"));finalint end =parsePosition(tag.attributes().get("end"));if(start >-1&& end >-1){
visitor.builder().setSpan(newAbsoluteSizeSpan(enhanceTextSize),
tag.start()+ start,
tag.start()+ end
@NonNull@Overridepublic Collection<String>supportedTags(){return Collections.singleton("enhance");privatestaticintparsePosition(@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;