Markwon/docs/v2/html.html
Dimitry Ivanov b00d0efa9d deploy
2021-01-12 12:50:41 +03:00

176 lines
41 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>HTML | Markwon</title>
<meta name="description" content="Android markdown library based on commonmark specification that renders markdown as system-native Spannables (no WebView)">
<link rel="apple-touch-icon" sizes="180x180" href="/Markwon/apple-touch-icon.png?v=1">
<link rel="icon" type="image/png" sizes="16x16" href="/Markwon/favicon-16x16.png?v=1">
<link rel="icon" href="/Markwon/favicon.ico?v=1">
<link rel="icon" type="image/png" sizes="32x32" href="/Markwon/favicon-32x32.png?v=1">
<link rel="manifest" href="/Markwon/manifest.json?v=1">
<meta name="keywords" content="android,markdown,library,spannable,markwon,commonmark">
<link rel="preload" href="/Markwon/assets/css/0.styles.3fbbce9e.css" as="style"><link rel="preload" href="/Markwon/assets/js/app.bdfd2bc6.js" as="script"><link rel="preload" href="/Markwon/assets/js/25.507307eb.js" as="script"><link rel="preload" href="/Markwon/assets/js/3.eaac0903.js" as="script"><link rel="preload" href="/Markwon/assets/js/12.98308542.js" as="script"><link rel="preload" href="/Markwon/assets/js/9.7d018a47.js" as="script"><link rel="prefetch" href="/Markwon/assets/js/42.d7ca0851.js"><link rel="prefetch" href="/Markwon/assets/js/2.81714ae9.js"><link rel="prefetch" href="/Markwon/assets/js/4.31fa5321.js"><link rel="prefetch" href="/Markwon/assets/js/5.6234b6a3.js"><link rel="prefetch" href="/Markwon/assets/js/6.ef59e46d.js"><link rel="prefetch" href="/Markwon/assets/js/7.e9b37c71.js"><link rel="prefetch" href="/Markwon/assets/js/8.9dff76ac.js"><link rel="prefetch" href="/Markwon/assets/js/10.99fc608c.js"><link rel="prefetch" href="/Markwon/assets/js/11.cdc173e9.js"><link rel="prefetch" href="/Markwon/assets/js/13.83b81b01.js"><link rel="prefetch" href="/Markwon/assets/js/14.0e5fe31e.js"><link rel="prefetch" href="/Markwon/assets/js/15.724f3dc4.js"><link rel="prefetch" href="/Markwon/assets/js/16.076204be.js"><link rel="prefetch" href="/Markwon/assets/js/17.9412daf3.js"><link rel="prefetch" href="/Markwon/assets/js/18.187f0167.js"><link rel="prefetch" href="/Markwon/assets/js/19.af3507a7.js"><link rel="prefetch" href="/Markwon/assets/js/20.dc11e22f.js"><link rel="prefetch" href="/Markwon/assets/js/21.393a507f.js"><link rel="prefetch" href="/Markwon/assets/js/22.a6ac92c5.js"><link rel="prefetch" href="/Markwon/assets/js/23.9edcc0b3.js"><link rel="prefetch" href="/Markwon/assets/js/24.073942b3.js"><link rel="prefetch" href="/Markwon/assets/js/26.87c7e366.js"><link rel="prefetch" href="/Markwon/assets/js/27.a6f7a96f.js"><link rel="prefetch" href="/Markwon/assets/js/28.c0caacb4.js"><link rel="prefetch" href="/Markwon/assets/js/29.230c7321.js"><link rel="prefetch" href="/Markwon/assets/js/30.45e92827.js"><link rel="prefetch" href="/Markwon/assets/js/31.3a2ff699.js"><link rel="prefetch" href="/Markwon/assets/js/32.662e2ab9.js"><link rel="prefetch" href="/Markwon/assets/js/33.d83b2cb7.js"><link rel="prefetch" href="/Markwon/assets/js/34.4b19ef85.js"><link rel="prefetch" href="/Markwon/assets/js/35.1684da38.js"><link rel="prefetch" href="/Markwon/assets/js/36.9852715d.js"><link rel="prefetch" href="/Markwon/assets/js/37.e98b3352.js"><link rel="prefetch" href="/Markwon/assets/js/38.09771599.js"><link rel="prefetch" href="/Markwon/assets/js/39.37003a65.js"><link rel="prefetch" href="/Markwon/assets/js/40.bf595a01.js"><link rel="prefetch" href="/Markwon/assets/js/41.db50f781.js"><link rel="prefetch" href="/Markwon/assets/js/43.78500964.js"><link rel="prefetch" href="/Markwon/assets/js/44.60fec7f9.js"><link rel="prefetch" href="/Markwon/assets/js/45.78224b99.js"><link rel="prefetch" href="/Markwon/assets/js/46.9a7f306b.js"><link rel="prefetch" href="/Markwon/assets/js/47.42b56911.js"><link rel="prefetch" href="/Markwon/assets/js/48.cceb75d4.js"><link rel="prefetch" href="/Markwon/assets/js/49.20507df8.js"><link rel="prefetch" href="/Markwon/assets/js/50.f89d88b1.js"><link rel="prefetch" href="/Markwon/assets/js/51.d7ac54ce.js"><link rel="prefetch" href="/Markwon/assets/js/52.394ded4e.js"><link rel="prefetch" href="/Markwon/assets/js/53.144cf408.js"><link rel="prefetch" href="/Markwon/assets/js/54.0f936c4f.js"><link rel="prefetch" href="/Markwon/assets/js/55.5b7382a9.js"><link rel="prefetch" href="/Markwon/assets/js/56.1cf2f788.js"><link rel="prefetch" href="/Markwon/assets/js/57.1b7dddc1.js"><link rel="prefetch" href="/Markwon/assets/js/58.5271aaaf.js"><link rel="prefetch" href="/Markwon/assets/js/59.7ef6ac9a.js"><link rel="prefetch" href="/Markwon/assets/js/60.9bbfa80f.js"><link rel="prefetch" href="/Markwon/assets/js/61.628c1500.js"><link rel="prefetch" href="/Markwon/assets/js/62.d4d206d7.js"><link rel="prefetch" href="/Markwon/assets/js/63.8ccf8bfc.js"><link rel="prefetch" href="/Markwon/assets/js/64.7672a52b.js"><link rel="prefetch" href="/Markwon/assets/js/65.c4f000dc.js"><link rel="prefetch" href="/Markwon/assets/js/66.4a29728a.js"><link rel="prefetch" href="/Markwon/assets/js/67.7331c7c7.js"><link rel="prefetch" href="/Markwon/assets/js/68.9d1d2ae1.js"><link rel="prefetch" href="/Markwon/assets/js/69.fd31295a.js"><link rel="prefetch" href="/Markwon/assets/js/70.fac8f892.js"><link rel="prefetch" href="/Markwon/assets/js/71.c3fcfb65.js"><link rel="prefetch" href="/Markwon/assets/js/72.d2389fc9.js"><link rel="prefetch" href="/Markwon/assets/js/73.6ce21170.js"><link rel="prefetch" href="/Markwon/assets/js/74.2ad91074.js"><link rel="prefetch" href="/Markwon/assets/js/75.1d59d27c.js"><link rel="prefetch" href="/Markwon/assets/js/76.f3844391.js"><link rel="prefetch" href="/Markwon/assets/js/77.4e5a82c3.js"><link rel="prefetch" href="/Markwon/assets/js/78.ff7203ee.js"><link rel="prefetch" href="/Markwon/assets/js/79.b1718a0d.js"><link rel="prefetch" href="/Markwon/assets/js/80.802db0eb.js"><link rel="prefetch" href="/Markwon/assets/js/81.9edd3cd9.js"><link rel="prefetch" href="/Markwon/assets/js/82.52f04a34.js"><link rel="prefetch" href="/Markwon/assets/js/83.3bd397c0.js"><link rel="prefetch" href="/Markwon/assets/js/84.a9af8a34.js"><link rel="prefetch" href="/Markwon/assets/js/85.2a0d8d40.js">
<link rel="stylesheet" href="/Markwon/assets/css/0.styles.3fbbce9e.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/Markwon/" class="home-link router-link-active"><!----> <span class="site-name">Markwon</span></a> <div class="links" style="max-width:nullpx;"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/Markwon/docs/v4/install.html" class="nav-link">Install</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">API Version</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><h4>Latest</h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/Markwon/" class="nav-link">4.x.x</a></li></ul></li><li class="dropdown-item"><h4>Legacy</h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/Markwon/docs/v3/install.html" class="nav-link">3.x.x</a></li><li class="dropdown-subitem"><a href="/Markwon/docs/v2/" class="nav-link router-link-active">2.x.x</a></li></ul></li></ul></div></div><div class="nav-item"><a href="https://github.com/noties/Markwon/blob/master/CHANGELOG.md" target="_blank" rel="noopener noreferrer" class="nav-link external">
Changelog
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div><div class="nav-item"><a href="https://github.com/noties/Markwon" target="_blank" rel="noopener noreferrer" class="nav-link external">
Github
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <div class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/Markwon/docs/v4/install.html" class="nav-link">Install</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">API Version</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><h4>Latest</h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/Markwon/" class="nav-link">4.x.x</a></li></ul></li><li class="dropdown-item"><h4>Legacy</h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/Markwon/docs/v3/install.html" class="nav-link">3.x.x</a></li><li class="dropdown-subitem"><a href="/Markwon/docs/v2/" class="nav-link router-link-active">2.x.x</a></li></ul></li></ul></div></div><div class="nav-item"><a href="https://github.com/noties/Markwon/blob/master/CHANGELOG.md" target="_blank" rel="noopener noreferrer" class="nav-link external">
Changelog
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div><div class="nav-item"><a href="https://github.com/noties/Markwon" target="_blank" rel="noopener noreferrer" class="nav-link external">
Github
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div> <!----></nav> <ul class="sidebar-links"><li><a href="/Markwon/docs/v2/getting-started.html" class="sidebar-link">Getting started</a></li><li><a href="/Markwon/docs/v2/install.html" class="sidebar-link">Installation</a></li><li><a href="/Markwon/docs/v2/configure.html" class="sidebar-link">Configuration</a></li><li><a href="/Markwon/docs/v2/theme.html" class="sidebar-link">Theme</a></li><li><a href="/Markwon/docs/v2/factory.html" class="sidebar-link">Factory</a></li><li><a href="/Markwon/docs/v2/image-loader.html" class="sidebar-link">Images</a></li><li><a href="/Markwon/docs/v2/syntax-highlight.html" class="sidebar-link">Syntax highlight</a></li><li><a href="/Markwon/docs/v2/html.html" class="active sidebar-link">HTML</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/Markwon/docs/v2/html.html#parser" class="sidebar-link">Parser</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/Markwon/docs/v2/html.html#empty-tag-replacement" class="sidebar-link">Empty tag replacement</a></li><li class="sidebar-sub-header"><a href="/Markwon/docs/v2/html.html#non-closed-tags" class="sidebar-link">Non-closed tags</a></li><li class="sidebar-sub-header"><a href="/Markwon/docs/v2/html.html#implementation-note" class="sidebar-link">Implementation note</a></li></ul></li><li class="sidebar-sub-header"><a href="/Markwon/docs/v2/html.html#renderer" class="sidebar-link">Renderer</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/Markwon/docs/v2/html.html#custom-tag-handler" class="sidebar-link">Custom tag handler</a></li></ul></li><li class="sidebar-sub-header"><a href="/Markwon/docs/v2/html.html#exclude-html-parsing" class="sidebar-link">Exclude HTML parsing</a></li></ul></li><li><a href="/Markwon/docs/v2/view.html" class="sidebar-link">MarkwonView</a></li></ul> </div> <div class="page"> <div class="content"><h1 id="html"><a href="#html" aria-hidden="true" class="header-anchor">#</a> HTML <span class="badge tip top" data-v-099ab69c>2.0.0</span></h1> <div class="warning custom-block"><p class="custom-block-title">WARNING</p> <p>This is documentation for <u>legacy</u> versions. For the most current version <a href="/Markwon/">click here.</a></p></div> <p>Starting with version <code>2.0.0</code> <code>Markwon</code> brings the whole HTML parsing/rendering
stack <em>on-site</em>. The main reason for this are <em>special</em> definitions of HTML nodes
by <a href="https://spec.commonmark.org/0.28/" target="_blank" rel="noopener noreferrer">
commonmark spec
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>. More specifically: <a href="https://spec.commonmark.org/0.28/#raw-html" target="_blank" rel="noopener noreferrer">
inline
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>
and <a href="https://spec.commonmark.org/0.28/#html-blocks" target="_blank" rel="noopener noreferrer">
block
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>.
These two are <em>a bit</em> different from <em>native</em> HTML understanding.
Well, they are <em>completely</em> different and share only the same names as
<a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Inline_elements" target="_blank" rel="noopener noreferrer">
HTML-inline
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a> and <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements" target="_blank" rel="noopener noreferrer">
HTML-block
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>
elements. This leads to situations when for example an <code>&lt;i&gt;</code> tag is considered
a block when it's used like this:</p> <div class="language-markdown extra-class"><pre class="language-markdown"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>i</span><span class="token punctuation">&gt;</span></span>
Hello from italics tag
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>i</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="tip custom-block"><p class="custom-block-title">A bit of background</p> <br> <a href="https://github.com/noties/Markwon/issues/52" target="_blank" rel="noopener noreferrer">This issue<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a> had brought attention to differences between HTML &amp; commonmark implementations. <br><br></div> <p>Let's modify code snippet above <em>a bit</em>:</p> <div class="language-markdown extra-class"><div class="highlight-lines"><br><br><div class="highlighted"> </div><br><br></div><pre class="language-markdown"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>i</span><span class="token punctuation">&gt;</span></span>
Hello from italics tag
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>i</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>We have just added a <code>new-line</code> before closing <code>&lt;/i&gt;</code> tag. And this
changes everything as now, according to the <a href="https://spec.commonmark.org/dingus/" target="_blank" rel="noopener noreferrer">
commonmark dingus
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>,
we have 2 HtmlBlocks: one before <code>new-line</code> (containing open <code>&lt;i&gt;</code> tag and text content)
and one after (containing as little as closing <code>&lt;/i&gt;</code> tag).</p> <p>If we modify code snippet <em>a bit</em> again:</p> <div class="language-markdown extra-class"><div class="highlight-lines"><br><br><br><div class="highlighted"> </div><br></div><pre class="language-markdown"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>i</span><span class="token punctuation">&gt;</span></span>
Hello from italics tag
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>i</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>b</span><span class="token punctuation">&gt;</span></span>bold&gt;<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>b</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>We will have 1 HtmlBlock (from previous snippet) and a bunch of HtmlInlines:</p> <ul><li>HtmlInline (<code>&lt;i&gt;</code>)</li> <li>HtmlInline (<code>&lt;b&gt;</code>)</li> <li>Text (<code>bold</code>)</li> <li>HtmlInline (<code>&lt;/b&gt;</code>)</li></ul> <p>Those <em>little</em> differences render <code>Html.fromHtml</code> (which was used in <code>1.x.x</code> versions)
useless. And actually it renders most of the HTML parsers implementations useless,
as most of them do not allow processing of HTML fragments in a raw fashion
without <em>fixing</em> content on-the-fly.</p> <p>Both <code>TagSoup</code> and <code>Jsoup</code> HTML parsers (that were considered for this project) are built to deal with
<em>malicious</em> HTML code (<em>all HTML code</em>? 😶). So, when supplied
with a <code>&lt;i&gt;italic</code> fragment they will make it <code>&lt;i&gt;italic&lt;/i&gt;</code>.
And it's a good thing, but consider these fragments for the sake of markdown:</p> <ul><li><code>&lt;i&gt;italic</code></li> <li><code>&lt;b&gt;bold italic</code></li> <li><code>&lt;/b&gt;&lt;i&gt;</code></li></ul> <p>We will get:</p> <ul><li><code>&lt;i&gt;italic &lt;/i&gt;</code></li> <li><code>&lt;b&gt;bold italic&lt;/b&gt;</code></li></ul> <p><em><sup>*</sup> Or to be precise: <code>&lt;html&gt;&lt;head&gt;&lt;/head&gt;&lt;body&gt;&lt;i&gt;italic &lt;/i&gt;&lt;/body&gt;&lt;/html&gt;</code> &amp;
<code>&lt;html&gt;&lt;head&gt;&lt;/head&gt;&lt;body&gt;&lt;b&gt;bold italic&lt;/b&gt;&lt;/body&gt;&lt;/html&gt;</code></em></p> <p>Which will be rendered in a final document:</p> <table><thead><tr><th>expected</th> <th>actual</th></tr></thead> <tbody><tr><td><i>italic <b>bold italic</b></i></td> <td><i>italic </i><b>bold italic</b></td></tr></tbody></table> <p>This might seem like a minor problem, but add more tags to a document,
introduce some deeply nested structures, spice openning and closing tags up
by adding markdown markup between them and finally write <em>malicious</em> HTML code 😆!</p> <p>There is no such problem on the <em>frontend</em> for which commonmark specification is mostly
aimed as <em>frontend</em> runs in a web-browser environment. After all <em>parsed</em> markdown
will become HTML tags (most common usage). And web-browser will know how to render final result.</p> <p>We, on the other hand, do not posess HTML heritage (<em>thank 🤖!</em>), but still
want to display some HTML to style resulting markdown a bit. That's why <code>Markwon</code>
incorporated own HTML parsing logic. It is based on the <a href="https://github.com/jhy/jsoup/" target="_blank" rel="noopener noreferrer">
Jsoup
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a> project.
And makes usage of the <code>Tokekiser</code> class that allows to <em>tokenise</em> input HTML.
All other code that doesn't follow this purpose was removed. It's safe to use
in projects that already have <code>jsoup</code> dependency as <code>Markwon</code> repackaged <strong>jsoup</strong> source classes
(which could be found <a href="https://github.com/noties/Markwon/tree/master/markwon-html-parser-impl/src/main/java/ru/noties/markwon/html/impl/jsoup" target="_blank" rel="noopener noreferrer">
here
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>)</p> <h2 id="parser"><a href="#parser" aria-hidden="true" class="header-anchor">#</a> Parser</h2> <p>There are no additional steps to configure HTML parsing. It's enabled by default.
If you wish to <em>exclude</em> it, please follow the <a href="#exclude-html-parsing">exclude</a> section below.</p> <p>The key class here is: <code>MarkwonHtmlParser</code> that is defined in <code>markwon-html-parser-api</code> module.
<code>markwon-html-parser-api</code> is a simple module that defines HTML parsing contract and
does not provide implementation.</p> <p>To change what implementation <code>Markwon</code> should use, <code>SpannableConfiguration</code> can be used:</p> <div class="language-java extra-class"><div class="highlight-lines"><br><div class="highlighted"> </div><br><br></div><pre class="language-java"><code>SpannableConfiguration<span class="token punctuation">.</span><span class="token function">builder</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">htmlParser</span><span class="token punctuation">(</span>MarkwonHtmlParser<span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">build</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p><code>markwon-html-parser-impl</code> on the other hand provides <code>MarkwonHtmlParser</code> implementation.
It's called <code>MarkwonHtmlParserImpl</code>. It can be created like this:</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token keyword">final</span> MarkwonHtmlParser htmlParser <span class="token operator">=</span> MarkwonHtmlParserImpl<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// or</span>
<span class="token keyword">final</span> MarkwonHtmlParser htmlParser <span class="token operator">=</span> MarkwonHtmlParserImpl<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span>HtmlEmptyTagReplacement<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="empty-tag-replacement"><a href="#empty-tag-replacement" aria-hidden="true" class="header-anchor">#</a> Empty tag replacement</h3> <p>In order to append text content for self-closing, void or just <em>empty</em> HTML tags,
<code>HtmlEmptyTagReplacement</code> can be used. As we cannot set Span for empty content,
we must represent empty tag with text during parsing stage (if we want it to be represented).</p> <p>Consider this:</p> <ul><li><code>&lt;img src=&quot;me-sad.JPG&quot;&gt;</code></li> <li><code>&lt;br /&gt;</code></li> <li><code>&lt;who-am-i&gt;&lt;/who-am-i&gt;</code></li></ul> <p>By default (<code>HtmlEmptyTagReplacement.create()</code>) will handle <code>img</code> and <code>br</code> tags.
<code>img</code> will be replaced with <code>alt</code> property if it is present and <code>\uFFFC</code> if it is not.
And <code>br</code> will insert a new line.</p> <h3 id="non-closed-tags"><a href="#non-closed-tags" aria-hidden="true" class="header-anchor">#</a> Non-closed tags</h3> <p>It's possible that your HTML can contain non-closed tags. By default <code>Markwon</code> will ignore them,
but if you wish to get a bit closer to a web-browser experience, you can allow this behaviour:</p> <div class="language-java extra-class"><div class="highlight-lines"><br><div class="highlighted"> </div><br><br></div><pre class="language-java"><code>SpannableConfiguration<span class="token punctuation">.</span><span class="token function">builder</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">htmlAllowNonClosedTags</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">build</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><div class="warning custom-block"><p class="custom-block-title">Note</p> <p>If there is (for example) an <code>&lt;i&gt;</code> tag at the start of a document and it's not closed
and <code>Markwon</code> is configured to <strong>not</strong> ignore non-closed tags (<code>.htmlAllowNonClosedTags(true)</code>),
it will make the whole document in italics</p></div> <h3 id="implementation-note"><a href="#implementation-note" aria-hidden="true" class="header-anchor">#</a> Implementation note</h3> <p><code>MarkwonHtmlParserImpl</code> does not create a unified HTML node. Instead it creates
2 collections: inline tags and block tags. Inline tags are represented as a <code>List</code>
of inline tags (<a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Inline_elements" target="_blank" rel="noopener noreferrer">
reference
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>). And
block tags are structured in a tree. This helps to achieve <em>browser</em>-like behaviour,
when open inline tag is applied to all content (even if inside blocks) until closing tag.
All tags that are not <em>inline</em> are considered to be <em>block</em> ones.</p> <h2 id="renderer"><a href="#renderer" aria-hidden="true" class="header-anchor">#</a> Renderer</h2> <p>Unlike <code>MarkwonHtmlParser</code> <code>Markwon</code> comes with a <code>MarkwonHtmlRenderer</code> by default.</p> <p>Default implementation can be obtain like this:</p> <div class="language-java extra-class"><pre class="language-java"><code>MarkwonHtmlRenderer<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>Default instance have these tags <em>handled</em>:</p> <ul><li>emphasis
<ul><li><code>i</code></li> <li><code>em</code></li> <li><code>cite</code></li> <li><code>dfn</code></li></ul></li> <li>strong emphasis
<ul><li><code>b</code></li> <li><code>strong</code></li></ul></li> <li><code>sup</code> (super script)</li> <li><code>sub</code> (sub script)</li> <li>underline
<ul><li><code>u</code></li> <li><code>ins</code></li></ul></li> <li>strike through
<ul><li><code>del</code></li> <li><code>s</code></li> <li><code>strike</code></li></ul></li> <li><code>a</code> (link)</li> <li><code>ul</code> (unordered list)</li> <li><code>ol</code> (ordered list)</li> <li><code>img</code> (image)</li> <li><code>blockquote</code> (block quote)</li> <li><code>h{1-6}</code> (heading)</li></ul> <p>If you wish to <em>extend</em> default handling (or override existing),
<code>#builderWithDefaults</code> factory method can be used:</p> <div class="language-java extra-class"><pre class="language-java"><code>MarkwonHtmlRenderer<span class="token punctuation">.</span><span class="token function">builderWithDefaults</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>For a completely <em>clean</em> configurable instance <code>#builder</code> method can be used:</p> <div class="language-java extra-class"><pre class="language-java"><code>MarkwonHtmlRenderer<span class="token punctuation">.</span><span class="token function">builder</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="custom-tag-handler"><a href="#custom-tag-handler" aria-hidden="true" class="header-anchor">#</a> Custom tag handler</h3> <p>To configure <code>MarkwonHtmlRenderer</code> to handle tags differently or
create a new tag handler - <code>TagHandler</code> can be used</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">abstract</span> <span class="token keyword">class</span> <span class="token class-name">TagHandler</span> <span class="token punctuation">{</span>
<span class="token keyword">public</span> <span class="token keyword">abstract</span> <span class="token keyword">void</span> <span class="token function">handle</span><span class="token punctuation">(</span>
<span class="token annotation punctuation">@NonNull</span> SpannableConfiguration configuration<span class="token punctuation">,</span>
<span class="token annotation punctuation">@NonNull</span> SpannableBuilder builder<span class="token punctuation">,</span>
<span class="token annotation punctuation">@NonNull</span> HtmlTag tag
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>For the most simple <em>inline</em> tag handler a <code>SimpleTagHandler</code> can be used:</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">abstract</span> <span class="token keyword">class</span> <span class="token class-name">SimpleTagHandler</span> <span class="token keyword">extends</span> <span class="token class-name">TagHandler</span> <span class="token punctuation">{</span>
<span class="token annotation punctuation">@Nullable</span>
<span class="token keyword">public</span> <span class="token keyword">abstract</span> Object <span class="token function">getSpans</span><span class="token punctuation">(</span><span class="token annotation punctuation">@NonNull</span> SpannableConfiguration configuration<span class="token punctuation">,</span> <span class="token annotation punctuation">@NonNull</span> HtmlTag tag<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>For example, <code>EmphasisHandler</code>:</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">EmphasisHandler</span> <span class="token keyword">extends</span> <span class="token class-name">SimpleTagHandler</span> <span class="token punctuation">{</span>
<span class="token annotation punctuation">@Nullable</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> Object <span class="token function">getSpans</span><span class="token punctuation">(</span><span class="token annotation punctuation">@NonNull</span> SpannableConfiguration configuration<span class="token punctuation">,</span> <span class="token annotation punctuation">@NonNull</span> HtmlTag tag<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> configuration<span class="token punctuation">.</span><span class="token function">factory</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">emphasis</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>If you wish to handle a <em>block</em> HTML node (for example <code>&lt;ul&gt;&lt;li&gt;First&lt;li&gt;Second&lt;/ul&gt;</code>) refer
to <code>ListHandler</code> source code for reference.</p> <div class="warning custom-block"><p class="custom-block-title">WARNING</p> <p>The most important thing when implementing custom <code>TagHandler</code> is to know
what type of <code>HtmlTag</code> we are dealing with. There are 2: inline &amp; block.
Inline tag cannot contain children. Block <em>can</em> contain children. And they
<em>most likely</em> should also be visited and <em>handled</em> by registered <code>TagHandler</code> (if any)
accordingly. See <code>TagHandler#visitChildren(configuration, builder, child);</code></p></div> <h4 id="css-inline-style-parser"><a href="#css-inline-style-parser" aria-hidden="true" class="header-anchor">#</a> Css inline style parser</h4> <p>When implementing own <code>TagHandler</code> you might want to inspect inline CSS styles
of a HTML element. <code>Markwon</code> provides an utility parser for that purpose:</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token keyword">final</span> CssInlineStyleParser inlineStyleParser <span class="token operator">=</span> CssInlineStyleParser<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span>CssProperty property<span class="token operator">:</span> inlineStyleParser<span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span><span class="token string">&quot;width: 100%; height: 100%;&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// [0] = CssProperty({width=100%}),</span>
<span class="token comment">// [1] = CssProperty({height=100%})</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="exclude-html-parsing"><a href="#exclude-html-parsing" aria-hidden="true" class="header-anchor">#</a> Exclude HTML parsing</h2> <p>If you wish to exclude HTML parsing altogether, you can manually
exclude <code>markwon-html-parser-impl</code> artifact from your projects compile classpath.
This can be beneficial if you know that markdown input won't contain
HTML and/or you wish to ignore it. Excluding HTML parsing
can speed up <code>Markwon</code> parsing and will decrease final size of
<code>Markwon</code> dependency by around <code>100kb</code>.</p> <a href="http://search.maven.org/#search|ga|1|g%3A%22ru.noties.markwon%22%20AND%20a%3A%22markwon%22"><img src="https://img.shields.io/maven-central/v/ru.noties.markwon/markwon.svg?label=markwon" alt="markwon"></a> <div class="language-groovy extra-class"><pre class="language-groovy"><code>dependencies <span class="token punctuation">{</span>
<span class="token function">implementation</span><span class="token punctuation">(</span><span class="token string gstring">&quot;ru.noties:markwon:<span class="token expression"><span class="token punctuation">$</span><span class="token punctuation">{</span>markwonVersion<span class="token punctuation">}</span></span>&quot;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
exclude module<span class="token punctuation">:</span> <span class="token string">'markwon-html-parser-impl'</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>Excluding <code>markwon-html-parser-impl</code> this way will result in
<code>MarkwonHtmlParser#noOp</code> implementation. No further steps are
required.</p> <div class="warning custom-block"><p class="custom-block-title">Note</p> <p>Excluding <code>markwon-html-parser-impl</code> won't remove <em>all</em> the content between
HTML tags. It will if <code>commonmark</code> decides that a specific fragment is a
<code>HtmlBlock</code>, but it won't if fragment is considered a <code>HtmlInline</code> as <code>HtmlInline</code>
does not contain content (just a tag definition).</p></div></div> <div class="page-edit"><!----> <div class="last-updated"><span class="prefix">Last Updated: </span> <span class="time">6/17/2019, 2:08:33 PM</span></div></div> <div class="page-nav"><p class="inner"><span class="prev">
<a href="/Markwon/docs/v2/syntax-highlight.html" class="prev">
Syntax highlight
</a></span> <span class="next"><a href="/Markwon/docs/v2/view.html">
MarkwonView
</a>
</span></p></div> </div> <!----></div></div>
<script src="/Markwon/assets/js/25.507307eb.js" defer></script><script src="/Markwon/assets/js/3.eaac0903.js" defer></script><script src="/Markwon/assets/js/12.98308542.js" defer></script><script src="/Markwon/assets/js/9.7d018a47.js" defer></script><script src="/Markwon/assets/js/app.bdfd2bc6.js" defer></script>
</body>
</html>