diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-29 04:24:24 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-29 04:24:24 +0000 |
commit | 12e8343068b906f8b2afddc5569968a8a91fa5b0 (patch) | |
tree | 75cc5e05a4392ea0292251898f992a15a16b172b /tests | |
parent | Initial commit. (diff) | |
download | markdown-it-py-upstream/2.1.0.tar.xz markdown-it-py-upstream/2.1.0.zip |
Adding upstream version 2.1.0.upstream/2.1.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests')
34 files changed, 34140 insertions, 0 deletions
diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/__init__.py diff --git a/tests/test_api/test_main.py b/tests/test_api/test_main.py new file mode 100644 index 0000000..007259e --- /dev/null +++ b/tests/test_api/test_main.py @@ -0,0 +1,279 @@ +from markdown_it import MarkdownIt +from markdown_it.token import Token + + +def test_get_rules(): + md = MarkdownIt("zero") + # print(md.get_all_rules()) + assert md.get_all_rules() == { + "core": [ + "normalize", + "block", + "inline", + "linkify", + "replacements", + "smartquotes", + ], + "block": [ + "table", + "code", + "fence", + "blockquote", + "hr", + "list", + "reference", + "html_block", + "heading", + "lheading", + "paragraph", + ], + "inline": [ + "text", + "newline", + "escape", + "backticks", + "strikethrough", + "emphasis", + "link", + "image", + "autolink", + "html_inline", + "entity", + ], + "inline2": ["balance_pairs", "strikethrough", "emphasis", "text_collapse"], + } + + +def test_load_presets(): + md = MarkdownIt("zero") + assert md.get_active_rules() == { + "block": ["paragraph"], + "core": ["normalize", "block", "inline"], + "inline": ["text"], + "inline2": ["balance_pairs", "text_collapse"], + } + md = MarkdownIt("commonmark") + assert md.get_active_rules() == { + "core": ["normalize", "block", "inline"], + "block": [ + "code", + "fence", + "blockquote", + "hr", + "list", + "reference", + "html_block", + "heading", + "lheading", + "paragraph", + ], + "inline": [ + "text", + "newline", + "escape", + "backticks", + "emphasis", + "link", + "image", + "autolink", + "html_inline", + "entity", + ], + "inline2": ["balance_pairs", "emphasis", "text_collapse"], + } + + +def test_override_options(): + md = MarkdownIt("zero") + assert md.options["maxNesting"] == 20 + md = MarkdownIt("zero", {"maxNesting": 99}) + assert md.options["maxNesting"] == 99 + + +def test_enable(): + md = MarkdownIt("zero").enable("heading") + assert md.get_active_rules() == { + "block": ["heading", "paragraph"], + "core": ["normalize", "block", "inline"], + "inline": ["text"], + "inline2": ["balance_pairs", "text_collapse"], + } + md.enable(["backticks", "autolink"]) + assert md.get_active_rules() == { + "block": ["heading", "paragraph"], + "core": ["normalize", "block", "inline"], + "inline": ["text", "backticks", "autolink"], + "inline2": ["balance_pairs", "text_collapse"], + } + + +def test_disable(): + md = MarkdownIt("zero").disable("inline") + assert md.get_active_rules() == { + "block": ["paragraph"], + "core": ["normalize", "block"], + "inline": ["text"], + "inline2": ["balance_pairs", "text_collapse"], + } + md.disable(["text"]) + assert md.get_active_rules() == { + "block": ["paragraph"], + "core": ["normalize", "block"], + "inline": [], + "inline2": ["balance_pairs", "text_collapse"], + } + + +def test_reset(): + md = MarkdownIt("zero") + with md.reset_rules(): + md.disable("inline") + assert md.get_active_rules() == { + "block": ["paragraph"], + "core": ["normalize", "block"], + "inline": ["text"], + "inline2": ["balance_pairs", "text_collapse"], + } + assert md.get_active_rules() == { + "block": ["paragraph"], + "core": ["normalize", "block", "inline"], + "inline": ["text"], + "inline2": ["balance_pairs", "text_collapse"], + } + + +def test_parseInline(): + md = MarkdownIt() + tokens = md.parseInline("abc\n\n> xyz") + assert tokens == [ + Token( + type="inline", + tag="", + nesting=0, + attrs=None, + map=[0, 1], + level=0, + children=[ + Token( + type="text", + tag="", + nesting=0, + attrs=None, + map=None, + level=0, + children=None, + content="abc", + markup="", + info="", + meta={}, + block=False, + hidden=False, + ), + Token( + type="softbreak", + tag="br", + nesting=0, + attrs=None, + map=None, + level=0, + children=None, + content="", + markup="", + info="", + meta={}, + block=False, + hidden=False, + ), + Token( + type="softbreak", + tag="br", + nesting=0, + attrs=None, + map=None, + level=0, + children=None, + content="", + markup="", + info="", + meta={}, + block=False, + hidden=False, + ), + Token( + type="text", + tag="", + nesting=0, + attrs=None, + map=None, + level=0, + children=None, + content="> xyz", + markup="", + info="", + meta={}, + block=False, + hidden=False, + ), + ], + content="abc\n\n> xyz", + markup="", + info="", + meta={}, + block=False, + hidden=False, + ) + ] + + +def test_renderInline(): + md = MarkdownIt("zero") + tokens = md.renderInline("abc\n\n*xyz*") + assert tokens == "abc\n\n*xyz*" + + +def test_emptyStr(): + md = MarkdownIt() + tokens = md.parseInline("") + assert tokens == [ + Token( + type="inline", + tag="", + nesting=0, + attrs=None, + map=[0, 1], + level=0, + children=[], + content="", + markup="", + info="", + meta={}, + block=False, + hidden=False, + ) + ] + + +def test_empty_env(): + """Test that an empty `env` is mutated, not copied and mutated.""" + md = MarkdownIt() + + env = {} + md.render("[foo]: /url\n[foo]", env) + assert "references" in env + + env = {} + md.parse("[foo]: /url\n[foo]", env) + assert "references" in env + + +def test_table_tokens(data_regression): + md = MarkdownIt("js-default") + tokens = md.parse( + """ +| Heading 1 | Heading 2 +| --------- | --------- +| Cell 1 | Cell 2 +| Cell 3 | Cell 4 + """ + ) + data_regression.check([t.as_dict() for t in tokens]) diff --git a/tests/test_api/test_main/test_table_tokens.yml b/tests/test_api/test_main/test_table_tokens.yml new file mode 100644 index 0000000..5bac044 --- /dev/null +++ b/tests/test_api/test_main/test_table_tokens.yml @@ -0,0 +1,492 @@ +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 0 + map: + - 1 + - 5 + markup: '' + meta: {} + nesting: 1 + tag: table + type: table_open +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 1 + map: + - 1 + - 2 + markup: '' + meta: {} + nesting: 1 + tag: thead + type: thead_open +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 2 + map: + - 1 + - 2 + markup: '' + meta: {} + nesting: 1 + tag: tr + type: tr_open +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 3 + map: null + markup: '' + meta: {} + nesting: 1 + tag: th + type: th_open +- attrs: null + block: true + children: + - attrs: null + block: false + children: null + content: Heading 1 + hidden: false + info: '' + level: 0 + map: null + markup: '' + meta: {} + nesting: 0 + tag: '' + type: text + content: Heading 1 + hidden: false + info: '' + level: 4 + map: + - 1 + - 2 + markup: '' + meta: {} + nesting: 0 + tag: '' + type: inline +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 3 + map: null + markup: '' + meta: {} + nesting: -1 + tag: th + type: th_close +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 3 + map: null + markup: '' + meta: {} + nesting: 1 + tag: th + type: th_open +- attrs: null + block: true + children: + - attrs: null + block: false + children: null + content: Heading 2 + hidden: false + info: '' + level: 0 + map: null + markup: '' + meta: {} + nesting: 0 + tag: '' + type: text + content: Heading 2 + hidden: false + info: '' + level: 4 + map: + - 1 + - 2 + markup: '' + meta: {} + nesting: 0 + tag: '' + type: inline +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 3 + map: null + markup: '' + meta: {} + nesting: -1 + tag: th + type: th_close +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 2 + map: null + markup: '' + meta: {} + nesting: -1 + tag: tr + type: tr_close +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 1 + map: null + markup: '' + meta: {} + nesting: -1 + tag: thead + type: thead_close +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 1 + map: + - 3 + - 5 + markup: '' + meta: {} + nesting: 1 + tag: tbody + type: tbody_open +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 2 + map: + - 3 + - 4 + markup: '' + meta: {} + nesting: 1 + tag: tr + type: tr_open +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 3 + map: null + markup: '' + meta: {} + nesting: 1 + tag: td + type: td_open +- attrs: null + block: true + children: + - attrs: null + block: false + children: null + content: Cell 1 + hidden: false + info: '' + level: 0 + map: null + markup: '' + meta: {} + nesting: 0 + tag: '' + type: text + content: Cell 1 + hidden: false + info: '' + level: 4 + map: + - 3 + - 4 + markup: '' + meta: {} + nesting: 0 + tag: '' + type: inline +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 3 + map: null + markup: '' + meta: {} + nesting: -1 + tag: td + type: td_close +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 3 + map: null + markup: '' + meta: {} + nesting: 1 + tag: td + type: td_open +- attrs: null + block: true + children: + - attrs: null + block: false + children: null + content: Cell 2 + hidden: false + info: '' + level: 0 + map: null + markup: '' + meta: {} + nesting: 0 + tag: '' + type: text + content: Cell 2 + hidden: false + info: '' + level: 4 + map: + - 3 + - 4 + markup: '' + meta: {} + nesting: 0 + tag: '' + type: inline +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 3 + map: null + markup: '' + meta: {} + nesting: -1 + tag: td + type: td_close +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 2 + map: null + markup: '' + meta: {} + nesting: -1 + tag: tr + type: tr_close +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 2 + map: + - 4 + - 5 + markup: '' + meta: {} + nesting: 1 + tag: tr + type: tr_open +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 3 + map: null + markup: '' + meta: {} + nesting: 1 + tag: td + type: td_open +- attrs: null + block: true + children: + - attrs: null + block: false + children: null + content: Cell 3 + hidden: false + info: '' + level: 0 + map: null + markup: '' + meta: {} + nesting: 0 + tag: '' + type: text + content: Cell 3 + hidden: false + info: '' + level: 4 + map: + - 4 + - 5 + markup: '' + meta: {} + nesting: 0 + tag: '' + type: inline +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 3 + map: null + markup: '' + meta: {} + nesting: -1 + tag: td + type: td_close +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 3 + map: null + markup: '' + meta: {} + nesting: 1 + tag: td + type: td_open +- attrs: null + block: true + children: + - attrs: null + block: false + children: null + content: Cell 4 + hidden: false + info: '' + level: 0 + map: null + markup: '' + meta: {} + nesting: 0 + tag: '' + type: text + content: Cell 4 + hidden: false + info: '' + level: 4 + map: + - 4 + - 5 + markup: '' + meta: {} + nesting: 0 + tag: '' + type: inline +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 3 + map: null + markup: '' + meta: {} + nesting: -1 + tag: td + type: td_close +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 2 + map: null + markup: '' + meta: {} + nesting: -1 + tag: tr + type: tr_close +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 1 + map: null + markup: '' + meta: {} + nesting: -1 + tag: tbody + type: tbody_close +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 0 + map: null + markup: '' + meta: {} + nesting: -1 + tag: table + type: table_close diff --git a/tests/test_api/test_plugin_creation.py b/tests/test_api/test_plugin_creation.py new file mode 100644 index 0000000..3a9af8b --- /dev/null +++ b/tests/test_api/test_plugin_creation.py @@ -0,0 +1,88 @@ +"""Test basic plugin creation functionality: +that they can be added and are called correctly +""" +from markdown_it import MarkdownIt + + +def inline_rule(state, silent): + print("plugin called") + + +def test_inline_after(capsys): + def _plugin(_md): + _md.inline.ruler.after("text", "new_rule", inline_rule) + + MarkdownIt().use(_plugin).parse("[") + assert "plugin called" in capsys.readouterr().out + + +def test_inline_before(capsys): + def _plugin(_md): + _md.inline.ruler.before("text", "new_rule", inline_rule) + + MarkdownIt().use(_plugin).parse("a") + assert "plugin called" in capsys.readouterr().out + + +def test_inline_at(capsys): + def _plugin(_md): + _md.inline.ruler.at("text", inline_rule) + + MarkdownIt().use(_plugin).parse("a") + assert "plugin called" in capsys.readouterr().out + + +def block_rule(state, startLine, endLine, silent): + print("plugin called") + + +def test_block_after(capsys): + def _plugin(_md): + _md.block.ruler.after("hr", "new_rule", block_rule) + + MarkdownIt().use(_plugin).parse("a") + assert "plugin called" in capsys.readouterr().out + + +def test_block_before(capsys): + def _plugin(_md): + _md.block.ruler.before("hr", "new_rule", block_rule) + + MarkdownIt().use(_plugin).parse("a") + assert "plugin called" in capsys.readouterr().out + + +def test_block_at(capsys): + def _plugin(_md): + _md.block.ruler.at("hr", block_rule) + + MarkdownIt().use(_plugin).parse("a") + assert "plugin called" in capsys.readouterr().out + + +def core_rule(state): + print("plugin called") + + +def test_core_after(capsys): + def _plugin(_md): + _md.core.ruler.after("normalize", "new_rule", core_rule) + + MarkdownIt().use(_plugin).parse("a") + assert "plugin called" in capsys.readouterr().out + + +def test_core_before(capsys): + def _plugin(_md): + _md.core.ruler.before("normalize", "new_rule", core_rule) + + MarkdownIt().use(_plugin).parse("a") + assert "plugin called" in capsys.readouterr().out + + +def test_core_at(capsys): + def _plugin(_md): + _md.core.ruler.at("normalize", core_rule) + + MarkdownIt().use(_plugin).parse("a") + assert "plugin called" in capsys.readouterr().out diff --git a/tests/test_api/test_token.py b/tests/test_api/test_token.py new file mode 100644 index 0000000..e3806b5 --- /dev/null +++ b/tests/test_api/test_token.py @@ -0,0 +1,38 @@ +import warnings + +from markdown_it.token import Token + + +def test_token(): + token = Token("name", "tag", 0) + assert token.as_dict() == { + "type": "name", + "tag": "tag", + "nesting": 0, + "attrs": None, + "map": None, + "level": 0, + "children": None, + "content": "", + "markup": "", + "info": "", + "meta": {}, + "block": False, + "hidden": False, + } + token.attrSet("a", "b") + assert token.attrGet("a") == "b" + token.attrJoin("a", "c") + assert token.attrGet("a") == "b c" + token.attrPush(["x", "y"]) + assert token.attrGet("x") == "y" + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + assert token.attrIndex("a") == 0 + assert token.attrIndex("x") == 1 + assert token.attrIndex("j") == -1 + + +def test_serialization(): + token = Token("name", "tag", 0, children=[Token("other", "tag2", 0)]) + assert token == Token.from_dict(token.as_dict()) diff --git a/tests/test_cli.py b/tests/test_cli.py new file mode 100644 index 0000000..57d6b93 --- /dev/null +++ b/tests/test_cli.py @@ -0,0 +1,36 @@ +import pathlib +import tempfile +from unittest.mock import patch + +import pytest + +from markdown_it.cli import parse + + +def test_parse(): + with tempfile.TemporaryDirectory() as tempdir: + path = pathlib.Path(tempdir).joinpath("test.md") + path.write_text("a b c") + assert parse.main([str(path)]) == 0 + + +def test_parse_fail(): + with pytest.raises(SystemExit) as exc_info: + parse.main(["/tmp/nonexistant_path/for_cli_test.md"]) + assert exc_info.value.code == 1 + + +def test_print_heading(): + with patch("builtins.print") as patched: + parse.print_heading() + patched.assert_called() + + +def test_interactive(): + def mock_input(prompt): + raise KeyboardInterrupt + + with patch("builtins.print") as patched: + with patch("builtins.input", mock_input): + parse.interactive() + patched.assert_called() diff --git a/tests/test_cmark_spec/commonmark.json b/tests/test_cmark_spec/commonmark.json new file mode 100644 index 0000000..d742f94 --- /dev/null +++ b/tests/test_cmark_spec/commonmark.json @@ -0,0 +1,5218 @@ +[ + { + "markdown": "\tfoo\tbaz\t\tbim\n", + "html": "<pre><code>foo\tbaz\t\tbim\n</code></pre>\n", + "example": 1, + "start_line": 356, + "end_line": 361, + "section": "Tabs" + }, + { + "markdown": " \tfoo\tbaz\t\tbim\n", + "html": "<pre><code>foo\tbaz\t\tbim\n</code></pre>\n", + "example": 2, + "start_line": 363, + "end_line": 368, + "section": "Tabs" + }, + { + "markdown": " a\ta\n ὐ\ta\n", + "html": "<pre><code>a\ta\nὐ\ta\n</code></pre>\n", + "example": 3, + "start_line": 370, + "end_line": 377, + "section": "Tabs" + }, + { + "markdown": " - foo\n\n\tbar\n", + "html": "<ul>\n<li>\n<p>foo</p>\n<p>bar</p>\n</li>\n</ul>\n", + "example": 4, + "start_line": 383, + "end_line": 394, + "section": "Tabs" + }, + { + "markdown": "- foo\n\n\t\tbar\n", + "html": "<ul>\n<li>\n<p>foo</p>\n<pre><code> bar\n</code></pre>\n</li>\n</ul>\n", + "example": 5, + "start_line": 396, + "end_line": 408, + "section": "Tabs" + }, + { + "markdown": ">\t\tfoo\n", + "html": "<blockquote>\n<pre><code> foo\n</code></pre>\n</blockquote>\n", + "example": 6, + "start_line": 419, + "end_line": 426, + "section": "Tabs" + }, + { + "markdown": "-\t\tfoo\n", + "html": "<ul>\n<li>\n<pre><code> foo\n</code></pre>\n</li>\n</ul>\n", + "example": 7, + "start_line": 428, + "end_line": 437, + "section": "Tabs" + }, + { + "markdown": " foo\n\tbar\n", + "html": "<pre><code>foo\nbar\n</code></pre>\n", + "example": 8, + "start_line": 440, + "end_line": 447, + "section": "Tabs" + }, + { + "markdown": " - foo\n - bar\n\t - baz\n", + "html": "<ul>\n<li>foo\n<ul>\n<li>bar\n<ul>\n<li>baz</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n", + "example": 9, + "start_line": 449, + "end_line": 465, + "section": "Tabs" + }, + { + "markdown": "#\tFoo\n", + "html": "<h1>Foo</h1>\n", + "example": 10, + "start_line": 467, + "end_line": 471, + "section": "Tabs" + }, + { + "markdown": "*\t*\t*\t\n", + "html": "<hr />\n", + "example": 11, + "start_line": 473, + "end_line": 477, + "section": "Tabs" + }, + { + "markdown": "\\!\\\"\\#\\$\\%\\&\\'\\(\\)\\*\\+\\,\\-\\.\\/\\:\\;\\<\\=\\>\\?\\@\\[\\\\\\]\\^\\_\\`\\{\\|\\}\\~\n", + "html": "<p>!"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~</p>\n", + "example": 12, + "start_line": 490, + "end_line": 494, + "section": "Backslash escapes" + }, + { + "markdown": "\\\t\\A\\a\\ \\3\\φ\\«\n", + "html": "<p>\\\t\\A\\a\\ \\3\\φ\\«</p>\n", + "example": 13, + "start_line": 500, + "end_line": 504, + "section": "Backslash escapes" + }, + { + "markdown": "\\*not emphasized*\n\\<br/> not a tag\n\\[not a link](/foo)\n\\`not code`\n1\\. not a list\n\\* not a list\n\\# not a heading\n\\[foo]: /url \"not a reference\"\n\\ö not a character entity\n", + "html": "<p>*not emphasized*\n<br/> not a tag\n[not a link](/foo)\n`not code`\n1. not a list\n* not a list\n# not a heading\n[foo]: /url "not a reference"\n&ouml; not a character entity</p>\n", + "example": 14, + "start_line": 510, + "end_line": 530, + "section": "Backslash escapes" + }, + { + "markdown": "\\\\*emphasis*\n", + "html": "<p>\\<em>emphasis</em></p>\n", + "example": 15, + "start_line": 535, + "end_line": 539, + "section": "Backslash escapes" + }, + { + "markdown": "foo\\\nbar\n", + "html": "<p>foo<br />\nbar</p>\n", + "example": 16, + "start_line": 544, + "end_line": 550, + "section": "Backslash escapes" + }, + { + "markdown": "`` \\[\\` ``\n", + "html": "<p><code>\\[\\`</code></p>\n", + "example": 17, + "start_line": 556, + "end_line": 560, + "section": "Backslash escapes" + }, + { + "markdown": " \\[\\]\n", + "html": "<pre><code>\\[\\]\n</code></pre>\n", + "example": 18, + "start_line": 563, + "end_line": 568, + "section": "Backslash escapes" + }, + { + "markdown": "~~~\n\\[\\]\n~~~\n", + "html": "<pre><code>\\[\\]\n</code></pre>\n", + "example": 19, + "start_line": 571, + "end_line": 578, + "section": "Backslash escapes" + }, + { + "markdown": "<http://example.com?find=\\*>\n", + "html": "<p><a href=\"http://example.com?find=%5C*\">http://example.com?find=\\*</a></p>\n", + "example": 20, + "start_line": 581, + "end_line": 585, + "section": "Backslash escapes" + }, + { + "markdown": "<a href=\"/bar\\/)\">\n", + "html": "<a href=\"/bar\\/)\">\n", + "example": 21, + "start_line": 588, + "end_line": 592, + "section": "Backslash escapes" + }, + { + "markdown": "[foo](/bar\\* \"ti\\*tle\")\n", + "html": "<p><a href=\"/bar*\" title=\"ti*tle\">foo</a></p>\n", + "example": 22, + "start_line": 598, + "end_line": 602, + "section": "Backslash escapes" + }, + { + "markdown": "[foo]\n\n[foo]: /bar\\* \"ti\\*tle\"\n", + "html": "<p><a href=\"/bar*\" title=\"ti*tle\">foo</a></p>\n", + "example": 23, + "start_line": 605, + "end_line": 611, + "section": "Backslash escapes" + }, + { + "markdown": "``` foo\\+bar\nfoo\n```\n", + "html": "<pre><code class=\"language-foo+bar\">foo\n</code></pre>\n", + "example": 24, + "start_line": 614, + "end_line": 621, + "section": "Backslash escapes" + }, + { + "markdown": " & © Æ Ď\n¾ ℋ ⅆ\n∲ ≧̸\n", + "html": "<p> & © Æ Ď\n¾ ℋ ⅆ\n∲ ≧̸</p>\n", + "example": 25, + "start_line": 650, + "end_line": 658, + "section": "Entity and numeric character references" + }, + { + "markdown": "# Ӓ Ϡ �\n", + "html": "<p># Ӓ Ϡ �</p>\n", + "example": 26, + "start_line": 669, + "end_line": 673, + "section": "Entity and numeric character references" + }, + { + "markdown": "" ആ ಫ\n", + "html": "<p>" ആ ಫ</p>\n", + "example": 27, + "start_line": 682, + "end_line": 686, + "section": "Entity and numeric character references" + }, + { + "markdown": "  &x; &#; &#x;\n�\n&#abcdef0;\n&ThisIsNotDefined; &hi?;\n", + "html": "<p>&nbsp &x; &#; &#x;\n&#87654321;\n&#abcdef0;\n&ThisIsNotDefined; &hi?;</p>\n", + "example": 28, + "start_line": 691, + "end_line": 701, + "section": "Entity and numeric character references" + }, + { + "markdown": "©\n", + "html": "<p>&copy</p>\n", + "example": 29, + "start_line": 708, + "end_line": 712, + "section": "Entity and numeric character references" + }, + { + "markdown": "&MadeUpEntity;\n", + "html": "<p>&MadeUpEntity;</p>\n", + "example": 30, + "start_line": 718, + "end_line": 722, + "section": "Entity and numeric character references" + }, + { + "markdown": "<a href=\"öö.html\">\n", + "html": "<a href=\"öö.html\">\n", + "example": 31, + "start_line": 729, + "end_line": 733, + "section": "Entity and numeric character references" + }, + { + "markdown": "[foo](/föö \"föö\")\n", + "html": "<p><a href=\"/f%C3%B6%C3%B6\" title=\"föö\">foo</a></p>\n", + "example": 32, + "start_line": 736, + "end_line": 740, + "section": "Entity and numeric character references" + }, + { + "markdown": "[foo]\n\n[foo]: /föö \"föö\"\n", + "html": "<p><a href=\"/f%C3%B6%C3%B6\" title=\"föö\">foo</a></p>\n", + "example": 33, + "start_line": 743, + "end_line": 749, + "section": "Entity and numeric character references" + }, + { + "markdown": "``` föö\nfoo\n```\n", + "html": "<pre><code class=\"language-föö\">foo\n</code></pre>\n", + "example": 34, + "start_line": 752, + "end_line": 759, + "section": "Entity and numeric character references" + }, + { + "markdown": "`föö`\n", + "html": "<p><code>f&ouml;&ouml;</code></p>\n", + "example": 35, + "start_line": 765, + "end_line": 769, + "section": "Entity and numeric character references" + }, + { + "markdown": " föfö\n", + "html": "<pre><code>f&ouml;f&ouml;\n</code></pre>\n", + "example": 36, + "start_line": 772, + "end_line": 777, + "section": "Entity and numeric character references" + }, + { + "markdown": "*foo*\n*foo*\n", + "html": "<p>*foo*\n<em>foo</em></p>\n", + "example": 37, + "start_line": 784, + "end_line": 790, + "section": "Entity and numeric character references" + }, + { + "markdown": "* foo\n\n* foo\n", + "html": "<p>* foo</p>\n<ul>\n<li>foo</li>\n</ul>\n", + "example": 38, + "start_line": 792, + "end_line": 801, + "section": "Entity and numeric character references" + }, + { + "markdown": "foo bar\n", + "html": "<p>foo\n\nbar</p>\n", + "example": 39, + "start_line": 803, + "end_line": 809, + "section": "Entity and numeric character references" + }, + { + "markdown": "	foo\n", + "html": "<p>\tfoo</p>\n", + "example": 40, + "start_line": 811, + "end_line": 815, + "section": "Entity and numeric character references" + }, + { + "markdown": "[a](url "tit")\n", + "html": "<p>[a](url "tit")</p>\n", + "example": 41, + "start_line": 818, + "end_line": 822, + "section": "Entity and numeric character references" + }, + { + "markdown": "- `one\n- two`\n", + "html": "<ul>\n<li>`one</li>\n<li>two`</li>\n</ul>\n", + "example": 42, + "start_line": 841, + "end_line": 849, + "section": "Precedence" + }, + { + "markdown": "***\n---\n___\n", + "html": "<hr />\n<hr />\n<hr />\n", + "example": 43, + "start_line": 880, + "end_line": 888, + "section": "Thematic breaks" + }, + { + "markdown": "+++\n", + "html": "<p>+++</p>\n", + "example": 44, + "start_line": 893, + "end_line": 897, + "section": "Thematic breaks" + }, + { + "markdown": "===\n", + "html": "<p>===</p>\n", + "example": 45, + "start_line": 900, + "end_line": 904, + "section": "Thematic breaks" + }, + { + "markdown": "--\n**\n__\n", + "html": "<p>--\n**\n__</p>\n", + "example": 46, + "start_line": 909, + "end_line": 917, + "section": "Thematic breaks" + }, + { + "markdown": " ***\n ***\n ***\n", + "html": "<hr />\n<hr />\n<hr />\n", + "example": 47, + "start_line": 922, + "end_line": 930, + "section": "Thematic breaks" + }, + { + "markdown": " ***\n", + "html": "<pre><code>***\n</code></pre>\n", + "example": 48, + "start_line": 935, + "end_line": 940, + "section": "Thematic breaks" + }, + { + "markdown": "Foo\n ***\n", + "html": "<p>Foo\n***</p>\n", + "example": 49, + "start_line": 943, + "end_line": 949, + "section": "Thematic breaks" + }, + { + "markdown": "_____________________________________\n", + "html": "<hr />\n", + "example": 50, + "start_line": 954, + "end_line": 958, + "section": "Thematic breaks" + }, + { + "markdown": " - - -\n", + "html": "<hr />\n", + "example": 51, + "start_line": 963, + "end_line": 967, + "section": "Thematic breaks" + }, + { + "markdown": " ** * ** * ** * **\n", + "html": "<hr />\n", + "example": 52, + "start_line": 970, + "end_line": 974, + "section": "Thematic breaks" + }, + { + "markdown": "- - - -\n", + "html": "<hr />\n", + "example": 53, + "start_line": 977, + "end_line": 981, + "section": "Thematic breaks" + }, + { + "markdown": "- - - - \n", + "html": "<hr />\n", + "example": 54, + "start_line": 986, + "end_line": 990, + "section": "Thematic breaks" + }, + { + "markdown": "_ _ _ _ a\n\na------\n\n---a---\n", + "html": "<p>_ _ _ _ a</p>\n<p>a------</p>\n<p>---a---</p>\n", + "example": 55, + "start_line": 995, + "end_line": 1005, + "section": "Thematic breaks" + }, + { + "markdown": " *-*\n", + "html": "<p><em>-</em></p>\n", + "example": 56, + "start_line": 1011, + "end_line": 1015, + "section": "Thematic breaks" + }, + { + "markdown": "- foo\n***\n- bar\n", + "html": "<ul>\n<li>foo</li>\n</ul>\n<hr />\n<ul>\n<li>bar</li>\n</ul>\n", + "example": 57, + "start_line": 1020, + "end_line": 1032, + "section": "Thematic breaks" + }, + { + "markdown": "Foo\n***\nbar\n", + "html": "<p>Foo</p>\n<hr />\n<p>bar</p>\n", + "example": 58, + "start_line": 1037, + "end_line": 1045, + "section": "Thematic breaks" + }, + { + "markdown": "Foo\n---\nbar\n", + "html": "<h2>Foo</h2>\n<p>bar</p>\n", + "example": 59, + "start_line": 1054, + "end_line": 1061, + "section": "Thematic breaks" + }, + { + "markdown": "* Foo\n* * *\n* Bar\n", + "html": "<ul>\n<li>Foo</li>\n</ul>\n<hr />\n<ul>\n<li>Bar</li>\n</ul>\n", + "example": 60, + "start_line": 1067, + "end_line": 1079, + "section": "Thematic breaks" + }, + { + "markdown": "- Foo\n- * * *\n", + "html": "<ul>\n<li>Foo</li>\n<li>\n<hr />\n</li>\n</ul>\n", + "example": 61, + "start_line": 1084, + "end_line": 1094, + "section": "Thematic breaks" + }, + { + "markdown": "# foo\n## foo\n### foo\n#### foo\n##### foo\n###### foo\n", + "html": "<h1>foo</h1>\n<h2>foo</h2>\n<h3>foo</h3>\n<h4>foo</h4>\n<h5>foo</h5>\n<h6>foo</h6>\n", + "example": 62, + "start_line": 1113, + "end_line": 1127, + "section": "ATX headings" + }, + { + "markdown": "####### foo\n", + "html": "<p>####### foo</p>\n", + "example": 63, + "start_line": 1132, + "end_line": 1136, + "section": "ATX headings" + }, + { + "markdown": "#5 bolt\n\n#hashtag\n", + "html": "<p>#5 bolt</p>\n<p>#hashtag</p>\n", + "example": 64, + "start_line": 1147, + "end_line": 1154, + "section": "ATX headings" + }, + { + "markdown": "\\## foo\n", + "html": "<p>## foo</p>\n", + "example": 65, + "start_line": 1159, + "end_line": 1163, + "section": "ATX headings" + }, + { + "markdown": "# foo *bar* \\*baz\\*\n", + "html": "<h1>foo <em>bar</em> *baz*</h1>\n", + "example": 66, + "start_line": 1168, + "end_line": 1172, + "section": "ATX headings" + }, + { + "markdown": "# foo \n", + "html": "<h1>foo</h1>\n", + "example": 67, + "start_line": 1177, + "end_line": 1181, + "section": "ATX headings" + }, + { + "markdown": " ### foo\n ## foo\n # foo\n", + "html": "<h3>foo</h3>\n<h2>foo</h2>\n<h1>foo</h1>\n", + "example": 68, + "start_line": 1186, + "end_line": 1194, + "section": "ATX headings" + }, + { + "markdown": " # foo\n", + "html": "<pre><code># foo\n</code></pre>\n", + "example": 69, + "start_line": 1199, + "end_line": 1204, + "section": "ATX headings" + }, + { + "markdown": "foo\n # bar\n", + "html": "<p>foo\n# bar</p>\n", + "example": 70, + "start_line": 1207, + "end_line": 1213, + "section": "ATX headings" + }, + { + "markdown": "## foo ##\n ### bar ###\n", + "html": "<h2>foo</h2>\n<h3>bar</h3>\n", + "example": 71, + "start_line": 1218, + "end_line": 1224, + "section": "ATX headings" + }, + { + "markdown": "# foo ##################################\n##### foo ##\n", + "html": "<h1>foo</h1>\n<h5>foo</h5>\n", + "example": 72, + "start_line": 1229, + "end_line": 1235, + "section": "ATX headings" + }, + { + "markdown": "### foo ### \n", + "html": "<h3>foo</h3>\n", + "example": 73, + "start_line": 1240, + "end_line": 1244, + "section": "ATX headings" + }, + { + "markdown": "### foo ### b\n", + "html": "<h3>foo ### b</h3>\n", + "example": 74, + "start_line": 1251, + "end_line": 1255, + "section": "ATX headings" + }, + { + "markdown": "# foo#\n", + "html": "<h1>foo#</h1>\n", + "example": 75, + "start_line": 1260, + "end_line": 1264, + "section": "ATX headings" + }, + { + "markdown": "### foo \\###\n## foo #\\##\n# foo \\#\n", + "html": "<h3>foo ###</h3>\n<h2>foo ###</h2>\n<h1>foo #</h1>\n", + "example": 76, + "start_line": 1270, + "end_line": 1278, + "section": "ATX headings" + }, + { + "markdown": "****\n## foo\n****\n", + "html": "<hr />\n<h2>foo</h2>\n<hr />\n", + "example": 77, + "start_line": 1284, + "end_line": 1292, + "section": "ATX headings" + }, + { + "markdown": "Foo bar\n# baz\nBar foo\n", + "html": "<p>Foo bar</p>\n<h1>baz</h1>\n<p>Bar foo</p>\n", + "example": 78, + "start_line": 1295, + "end_line": 1303, + "section": "ATX headings" + }, + { + "markdown": "## \n#\n### ###\n", + "html": "<h2></h2>\n<h1></h1>\n<h3></h3>\n", + "example": 79, + "start_line": 1308, + "end_line": 1316, + "section": "ATX headings" + }, + { + "markdown": "Foo *bar*\n=========\n\nFoo *bar*\n---------\n", + "html": "<h1>Foo <em>bar</em></h1>\n<h2>Foo <em>bar</em></h2>\n", + "example": 80, + "start_line": 1351, + "end_line": 1360, + "section": "Setext headings" + }, + { + "markdown": "Foo *bar\nbaz*\n====\n", + "html": "<h1>Foo <em>bar\nbaz</em></h1>\n", + "example": 81, + "start_line": 1365, + "end_line": 1372, + "section": "Setext headings" + }, + { + "markdown": " Foo *bar\nbaz*\t\n====\n", + "html": "<h1>Foo <em>bar\nbaz</em></h1>\n", + "example": 82, + "start_line": 1379, + "end_line": 1386, + "section": "Setext headings" + }, + { + "markdown": "Foo\n-------------------------\n\nFoo\n=\n", + "html": "<h2>Foo</h2>\n<h1>Foo</h1>\n", + "example": 83, + "start_line": 1391, + "end_line": 1400, + "section": "Setext headings" + }, + { + "markdown": " Foo\n---\n\n Foo\n-----\n\n Foo\n ===\n", + "html": "<h2>Foo</h2>\n<h2>Foo</h2>\n<h1>Foo</h1>\n", + "example": 84, + "start_line": 1406, + "end_line": 1419, + "section": "Setext headings" + }, + { + "markdown": " Foo\n ---\n\n Foo\n---\n", + "html": "<pre><code>Foo\n---\n\nFoo\n</code></pre>\n<hr />\n", + "example": 85, + "start_line": 1424, + "end_line": 1437, + "section": "Setext headings" + }, + { + "markdown": "Foo\n ---- \n", + "html": "<h2>Foo</h2>\n", + "example": 86, + "start_line": 1443, + "end_line": 1448, + "section": "Setext headings" + }, + { + "markdown": "Foo\n ---\n", + "html": "<p>Foo\n---</p>\n", + "example": 87, + "start_line": 1453, + "end_line": 1459, + "section": "Setext headings" + }, + { + "markdown": "Foo\n= =\n\nFoo\n--- -\n", + "html": "<p>Foo\n= =</p>\n<p>Foo</p>\n<hr />\n", + "example": 88, + "start_line": 1464, + "end_line": 1475, + "section": "Setext headings" + }, + { + "markdown": "Foo \n-----\n", + "html": "<h2>Foo</h2>\n", + "example": 89, + "start_line": 1480, + "end_line": 1485, + "section": "Setext headings" + }, + { + "markdown": "Foo\\\n----\n", + "html": "<h2>Foo\\</h2>\n", + "example": 90, + "start_line": 1490, + "end_line": 1495, + "section": "Setext headings" + }, + { + "markdown": "`Foo\n----\n`\n\n<a title=\"a lot\n---\nof dashes\"/>\n", + "html": "<h2>`Foo</h2>\n<p>`</p>\n<h2><a title="a lot</h2>\n<p>of dashes"/></p>\n", + "example": 91, + "start_line": 1501, + "end_line": 1514, + "section": "Setext headings" + }, + { + "markdown": "> Foo\n---\n", + "html": "<blockquote>\n<p>Foo</p>\n</blockquote>\n<hr />\n", + "example": 92, + "start_line": 1520, + "end_line": 1528, + "section": "Setext headings" + }, + { + "markdown": "> foo\nbar\n===\n", + "html": "<blockquote>\n<p>foo\nbar\n===</p>\n</blockquote>\n", + "example": 93, + "start_line": 1531, + "end_line": 1541, + "section": "Setext headings" + }, + { + "markdown": "- Foo\n---\n", + "html": "<ul>\n<li>Foo</li>\n</ul>\n<hr />\n", + "example": 94, + "start_line": 1544, + "end_line": 1552, + "section": "Setext headings" + }, + { + "markdown": "Foo\nBar\n---\n", + "html": "<h2>Foo\nBar</h2>\n", + "example": 95, + "start_line": 1559, + "end_line": 1566, + "section": "Setext headings" + }, + { + "markdown": "---\nFoo\n---\nBar\n---\nBaz\n", + "html": "<hr />\n<h2>Foo</h2>\n<h2>Bar</h2>\n<p>Baz</p>\n", + "example": 96, + "start_line": 1572, + "end_line": 1584, + "section": "Setext headings" + }, + { + "markdown": "\n====\n", + "html": "<p>====</p>\n", + "example": 97, + "start_line": 1589, + "end_line": 1594, + "section": "Setext headings" + }, + { + "markdown": "---\n---\n", + "html": "<hr />\n<hr />\n", + "example": 98, + "start_line": 1601, + "end_line": 1607, + "section": "Setext headings" + }, + { + "markdown": "- foo\n-----\n", + "html": "<ul>\n<li>foo</li>\n</ul>\n<hr />\n", + "example": 99, + "start_line": 1610, + "end_line": 1618, + "section": "Setext headings" + }, + { + "markdown": " foo\n---\n", + "html": "<pre><code>foo\n</code></pre>\n<hr />\n", + "example": 100, + "start_line": 1621, + "end_line": 1628, + "section": "Setext headings" + }, + { + "markdown": "> foo\n-----\n", + "html": "<blockquote>\n<p>foo</p>\n</blockquote>\n<hr />\n", + "example": 101, + "start_line": 1631, + "end_line": 1639, + "section": "Setext headings" + }, + { + "markdown": "\\> foo\n------\n", + "html": "<h2>> foo</h2>\n", + "example": 102, + "start_line": 1645, + "end_line": 1650, + "section": "Setext headings" + }, + { + "markdown": "Foo\n\nbar\n---\nbaz\n", + "html": "<p>Foo</p>\n<h2>bar</h2>\n<p>baz</p>\n", + "example": 103, + "start_line": 1676, + "end_line": 1686, + "section": "Setext headings" + }, + { + "markdown": "Foo\nbar\n\n---\n\nbaz\n", + "html": "<p>Foo\nbar</p>\n<hr />\n<p>baz</p>\n", + "example": 104, + "start_line": 1692, + "end_line": 1704, + "section": "Setext headings" + }, + { + "markdown": "Foo\nbar\n* * *\nbaz\n", + "html": "<p>Foo\nbar</p>\n<hr />\n<p>baz</p>\n", + "example": 105, + "start_line": 1710, + "end_line": 1720, + "section": "Setext headings" + }, + { + "markdown": "Foo\nbar\n\\---\nbaz\n", + "html": "<p>Foo\nbar\n---\nbaz</p>\n", + "example": 106, + "start_line": 1725, + "end_line": 1735, + "section": "Setext headings" + }, + { + "markdown": " a simple\n indented code block\n", + "html": "<pre><code>a simple\n indented code block\n</code></pre>\n", + "example": 107, + "start_line": 1753, + "end_line": 1760, + "section": "Indented code blocks" + }, + { + "markdown": " - foo\n\n bar\n", + "html": "<ul>\n<li>\n<p>foo</p>\n<p>bar</p>\n</li>\n</ul>\n", + "example": 108, + "start_line": 1767, + "end_line": 1778, + "section": "Indented code blocks" + }, + { + "markdown": "1. foo\n\n - bar\n", + "html": "<ol>\n<li>\n<p>foo</p>\n<ul>\n<li>bar</li>\n</ul>\n</li>\n</ol>\n", + "example": 109, + "start_line": 1781, + "end_line": 1794, + "section": "Indented code blocks" + }, + { + "markdown": " <a/>\n *hi*\n\n - one\n", + "html": "<pre><code><a/>\n*hi*\n\n- one\n</code></pre>\n", + "example": 110, + "start_line": 1801, + "end_line": 1812, + "section": "Indented code blocks" + }, + { + "markdown": " chunk1\n\n chunk2\n \n \n \n chunk3\n", + "html": "<pre><code>chunk1\n\nchunk2\n\n\n\nchunk3\n</code></pre>\n", + "example": 111, + "start_line": 1817, + "end_line": 1834, + "section": "Indented code blocks" + }, + { + "markdown": " chunk1\n \n chunk2\n", + "html": "<pre><code>chunk1\n \n chunk2\n</code></pre>\n", + "example": 112, + "start_line": 1840, + "end_line": 1849, + "section": "Indented code blocks" + }, + { + "markdown": "Foo\n bar\n\n", + "html": "<p>Foo\nbar</p>\n", + "example": 113, + "start_line": 1855, + "end_line": 1862, + "section": "Indented code blocks" + }, + { + "markdown": " foo\nbar\n", + "html": "<pre><code>foo\n</code></pre>\n<p>bar</p>\n", + "example": 114, + "start_line": 1869, + "end_line": 1876, + "section": "Indented code blocks" + }, + { + "markdown": "# Heading\n foo\nHeading\n------\n foo\n----\n", + "html": "<h1>Heading</h1>\n<pre><code>foo\n</code></pre>\n<h2>Heading</h2>\n<pre><code>foo\n</code></pre>\n<hr />\n", + "example": 115, + "start_line": 1882, + "end_line": 1897, + "section": "Indented code blocks" + }, + { + "markdown": " foo\n bar\n", + "html": "<pre><code> foo\nbar\n</code></pre>\n", + "example": 116, + "start_line": 1902, + "end_line": 1909, + "section": "Indented code blocks" + }, + { + "markdown": "\n \n foo\n \n\n", + "html": "<pre><code>foo\n</code></pre>\n", + "example": 117, + "start_line": 1915, + "end_line": 1924, + "section": "Indented code blocks" + }, + { + "markdown": " foo \n", + "html": "<pre><code>foo \n</code></pre>\n", + "example": 118, + "start_line": 1929, + "end_line": 1934, + "section": "Indented code blocks" + }, + { + "markdown": "```\n<\n >\n```\n", + "html": "<pre><code><\n >\n</code></pre>\n", + "example": 119, + "start_line": 1984, + "end_line": 1993, + "section": "Fenced code blocks" + }, + { + "markdown": "~~~\n<\n >\n~~~\n", + "html": "<pre><code><\n >\n</code></pre>\n", + "example": 120, + "start_line": 1998, + "end_line": 2007, + "section": "Fenced code blocks" + }, + { + "markdown": "``\nfoo\n``\n", + "html": "<p><code>foo</code></p>\n", + "example": 121, + "start_line": 2011, + "end_line": 2017, + "section": "Fenced code blocks" + }, + { + "markdown": "```\naaa\n~~~\n```\n", + "html": "<pre><code>aaa\n~~~\n</code></pre>\n", + "example": 122, + "start_line": 2022, + "end_line": 2031, + "section": "Fenced code blocks" + }, + { + "markdown": "~~~\naaa\n```\n~~~\n", + "html": "<pre><code>aaa\n```\n</code></pre>\n", + "example": 123, + "start_line": 2034, + "end_line": 2043, + "section": "Fenced code blocks" + }, + { + "markdown": "````\naaa\n```\n``````\n", + "html": "<pre><code>aaa\n```\n</code></pre>\n", + "example": 124, + "start_line": 2048, + "end_line": 2057, + "section": "Fenced code blocks" + }, + { + "markdown": "~~~~\naaa\n~~~\n~~~~\n", + "html": "<pre><code>aaa\n~~~\n</code></pre>\n", + "example": 125, + "start_line": 2060, + "end_line": 2069, + "section": "Fenced code blocks" + }, + { + "markdown": "```\n", + "html": "<pre><code></code></pre>\n", + "example": 126, + "start_line": 2075, + "end_line": 2079, + "section": "Fenced code blocks" + }, + { + "markdown": "`````\n\n```\naaa\n", + "html": "<pre><code>\n```\naaa\n</code></pre>\n", + "example": 127, + "start_line": 2082, + "end_line": 2092, + "section": "Fenced code blocks" + }, + { + "markdown": "> ```\n> aaa\n\nbbb\n", + "html": "<blockquote>\n<pre><code>aaa\n</code></pre>\n</blockquote>\n<p>bbb</p>\n", + "example": 128, + "start_line": 2095, + "end_line": 2106, + "section": "Fenced code blocks" + }, + { + "markdown": "```\n\n \n```\n", + "html": "<pre><code>\n \n</code></pre>\n", + "example": 129, + "start_line": 2111, + "end_line": 2120, + "section": "Fenced code blocks" + }, + { + "markdown": "```\n```\n", + "html": "<pre><code></code></pre>\n", + "example": 130, + "start_line": 2125, + "end_line": 2130, + "section": "Fenced code blocks" + }, + { + "markdown": " ```\n aaa\naaa\n```\n", + "html": "<pre><code>aaa\naaa\n</code></pre>\n", + "example": 131, + "start_line": 2137, + "end_line": 2146, + "section": "Fenced code blocks" + }, + { + "markdown": " ```\naaa\n aaa\naaa\n ```\n", + "html": "<pre><code>aaa\naaa\naaa\n</code></pre>\n", + "example": 132, + "start_line": 2149, + "end_line": 2160, + "section": "Fenced code blocks" + }, + { + "markdown": " ```\n aaa\n aaa\n aaa\n ```\n", + "html": "<pre><code>aaa\n aaa\naaa\n</code></pre>\n", + "example": 133, + "start_line": 2163, + "end_line": 2174, + "section": "Fenced code blocks" + }, + { + "markdown": " ```\n aaa\n ```\n", + "html": "<pre><code>```\naaa\n```\n</code></pre>\n", + "example": 134, + "start_line": 2179, + "end_line": 2188, + "section": "Fenced code blocks" + }, + { + "markdown": "```\naaa\n ```\n", + "html": "<pre><code>aaa\n</code></pre>\n", + "example": 135, + "start_line": 2194, + "end_line": 2201, + "section": "Fenced code blocks" + }, + { + "markdown": " ```\naaa\n ```\n", + "html": "<pre><code>aaa\n</code></pre>\n", + "example": 136, + "start_line": 2204, + "end_line": 2211, + "section": "Fenced code blocks" + }, + { + "markdown": "```\naaa\n ```\n", + "html": "<pre><code>aaa\n ```\n</code></pre>\n", + "example": 137, + "start_line": 2216, + "end_line": 2224, + "section": "Fenced code blocks" + }, + { + "markdown": "``` ```\naaa\n", + "html": "<p><code> </code>\naaa</p>\n", + "example": 138, + "start_line": 2230, + "end_line": 2236, + "section": "Fenced code blocks" + }, + { + "markdown": "~~~~~~\naaa\n~~~ ~~\n", + "html": "<pre><code>aaa\n~~~ ~~\n</code></pre>\n", + "example": 139, + "start_line": 2239, + "end_line": 2247, + "section": "Fenced code blocks" + }, + { + "markdown": "foo\n```\nbar\n```\nbaz\n", + "html": "<p>foo</p>\n<pre><code>bar\n</code></pre>\n<p>baz</p>\n", + "example": 140, + "start_line": 2253, + "end_line": 2264, + "section": "Fenced code blocks" + }, + { + "markdown": "foo\n---\n~~~\nbar\n~~~\n# baz\n", + "html": "<h2>foo</h2>\n<pre><code>bar\n</code></pre>\n<h1>baz</h1>\n", + "example": 141, + "start_line": 2270, + "end_line": 2282, + "section": "Fenced code blocks" + }, + { + "markdown": "```ruby\ndef foo(x)\n return 3\nend\n```\n", + "html": "<pre><code class=\"language-ruby\">def foo(x)\n return 3\nend\n</code></pre>\n", + "example": 142, + "start_line": 2292, + "end_line": 2303, + "section": "Fenced code blocks" + }, + { + "markdown": "~~~~ ruby startline=3 $%@#$\ndef foo(x)\n return 3\nend\n~~~~~~~\n", + "html": "<pre><code class=\"language-ruby\">def foo(x)\n return 3\nend\n</code></pre>\n", + "example": 143, + "start_line": 2306, + "end_line": 2317, + "section": "Fenced code blocks" + }, + { + "markdown": "````;\n````\n", + "html": "<pre><code class=\"language-;\"></code></pre>\n", + "example": 144, + "start_line": 2320, + "end_line": 2325, + "section": "Fenced code blocks" + }, + { + "markdown": "``` aa ```\nfoo\n", + "html": "<p><code>aa</code>\nfoo</p>\n", + "example": 145, + "start_line": 2330, + "end_line": 2336, + "section": "Fenced code blocks" + }, + { + "markdown": "~~~ aa ``` ~~~\nfoo\n~~~\n", + "html": "<pre><code class=\"language-aa\">foo\n</code></pre>\n", + "example": 146, + "start_line": 2341, + "end_line": 2348, + "section": "Fenced code blocks" + }, + { + "markdown": "```\n``` aaa\n```\n", + "html": "<pre><code>``` aaa\n</code></pre>\n", + "example": 147, + "start_line": 2353, + "end_line": 2360, + "section": "Fenced code blocks" + }, + { + "markdown": "<table><tr><td>\n<pre>\n**Hello**,\n\n_world_.\n</pre>\n</td></tr></table>\n", + "html": "<table><tr><td>\n<pre>\n**Hello**,\n<p><em>world</em>.\n</pre></p>\n</td></tr></table>\n", + "example": 148, + "start_line": 2432, + "end_line": 2447, + "section": "HTML blocks" + }, + { + "markdown": "<table>\n <tr>\n <td>\n hi\n </td>\n </tr>\n</table>\n\nokay.\n", + "html": "<table>\n <tr>\n <td>\n hi\n </td>\n </tr>\n</table>\n<p>okay.</p>\n", + "example": 149, + "start_line": 2461, + "end_line": 2480, + "section": "HTML blocks" + }, + { + "markdown": " <div>\n *hello*\n <foo><a>\n", + "html": " <div>\n *hello*\n <foo><a>\n", + "example": 150, + "start_line": 2483, + "end_line": 2491, + "section": "HTML blocks" + }, + { + "markdown": "</div>\n*foo*\n", + "html": "</div>\n*foo*\n", + "example": 151, + "start_line": 2496, + "end_line": 2502, + "section": "HTML blocks" + }, + { + "markdown": "<DIV CLASS=\"foo\">\n\n*Markdown*\n\n</DIV>\n", + "html": "<DIV CLASS=\"foo\">\n<p><em>Markdown</em></p>\n</DIV>\n", + "example": 152, + "start_line": 2507, + "end_line": 2517, + "section": "HTML blocks" + }, + { + "markdown": "<div id=\"foo\"\n class=\"bar\">\n</div>\n", + "html": "<div id=\"foo\"\n class=\"bar\">\n</div>\n", + "example": 153, + "start_line": 2523, + "end_line": 2531, + "section": "HTML blocks" + }, + { + "markdown": "<div id=\"foo\" class=\"bar\n baz\">\n</div>\n", + "html": "<div id=\"foo\" class=\"bar\n baz\">\n</div>\n", + "example": 154, + "start_line": 2534, + "end_line": 2542, + "section": "HTML blocks" + }, + { + "markdown": "<div>\n*foo*\n\n*bar*\n", + "html": "<div>\n*foo*\n<p><em>bar</em></p>\n", + "example": 155, + "start_line": 2546, + "end_line": 2555, + "section": "HTML blocks" + }, + { + "markdown": "<div id=\"foo\"\n*hi*\n", + "html": "<div id=\"foo\"\n*hi*\n", + "example": 156, + "start_line": 2562, + "end_line": 2568, + "section": "HTML blocks" + }, + { + "markdown": "<div class\nfoo\n", + "html": "<div class\nfoo\n", + "example": 157, + "start_line": 2571, + "end_line": 2577, + "section": "HTML blocks" + }, + { + "markdown": "<div *???-&&&-<---\n*foo*\n", + "html": "<div *???-&&&-<---\n*foo*\n", + "example": 158, + "start_line": 2583, + "end_line": 2589, + "section": "HTML blocks" + }, + { + "markdown": "<div><a href=\"bar\">*foo*</a></div>\n", + "html": "<div><a href=\"bar\">*foo*</a></div>\n", + "example": 159, + "start_line": 2595, + "end_line": 2599, + "section": "HTML blocks" + }, + { + "markdown": "<table><tr><td>\nfoo\n</td></tr></table>\n", + "html": "<table><tr><td>\nfoo\n</td></tr></table>\n", + "example": 160, + "start_line": 2602, + "end_line": 2610, + "section": "HTML blocks" + }, + { + "markdown": "<div></div>\n``` c\nint x = 33;\n```\n", + "html": "<div></div>\n``` c\nint x = 33;\n```\n", + "example": 161, + "start_line": 2619, + "end_line": 2629, + "section": "HTML blocks" + }, + { + "markdown": "<a href=\"foo\">\n*bar*\n</a>\n", + "html": "<a href=\"foo\">\n*bar*\n</a>\n", + "example": 162, + "start_line": 2636, + "end_line": 2644, + "section": "HTML blocks" + }, + { + "markdown": "<Warning>\n*bar*\n</Warning>\n", + "html": "<Warning>\n*bar*\n</Warning>\n", + "example": 163, + "start_line": 2649, + "end_line": 2657, + "section": "HTML blocks" + }, + { + "markdown": "<i class=\"foo\">\n*bar*\n</i>\n", + "html": "<i class=\"foo\">\n*bar*\n</i>\n", + "example": 164, + "start_line": 2660, + "end_line": 2668, + "section": "HTML blocks" + }, + { + "markdown": "</ins>\n*bar*\n", + "html": "</ins>\n*bar*\n", + "example": 165, + "start_line": 2671, + "end_line": 2677, + "section": "HTML blocks" + }, + { + "markdown": "<del>\n*foo*\n</del>\n", + "html": "<del>\n*foo*\n</del>\n", + "example": 166, + "start_line": 2686, + "end_line": 2694, + "section": "HTML blocks" + }, + { + "markdown": "<del>\n\n*foo*\n\n</del>\n", + "html": "<del>\n<p><em>foo</em></p>\n</del>\n", + "example": 167, + "start_line": 2701, + "end_line": 2711, + "section": "HTML blocks" + }, + { + "markdown": "<del>*foo*</del>\n", + "html": "<p><del><em>foo</em></del></p>\n", + "example": 168, + "start_line": 2719, + "end_line": 2723, + "section": "HTML blocks" + }, + { + "markdown": "<pre language=\"haskell\"><code>\nimport Text.HTML.TagSoup\n\nmain :: IO ()\nmain = print $ parseTags tags\n</code></pre>\nokay\n", + "html": "<pre language=\"haskell\"><code>\nimport Text.HTML.TagSoup\n\nmain :: IO ()\nmain = print $ parseTags tags\n</code></pre>\n<p>okay</p>\n", + "example": 169, + "start_line": 2735, + "end_line": 2751, + "section": "HTML blocks" + }, + { + "markdown": "<script type=\"text/javascript\">\n// JavaScript example\n\ndocument.getElementById(\"demo\").innerHTML = \"Hello JavaScript!\";\n</script>\nokay\n", + "html": "<script type=\"text/javascript\">\n// JavaScript example\n\ndocument.getElementById(\"demo\").innerHTML = \"Hello JavaScript!\";\n</script>\n<p>okay</p>\n", + "example": 170, + "start_line": 2756, + "end_line": 2770, + "section": "HTML blocks" + }, + { + "markdown": "<textarea>\n\n*foo*\n\n_bar_\n\n</textarea>\n", + "html": "<textarea>\n\n*foo*\n\n_bar_\n\n</textarea>\n", + "example": 171, + "start_line": 2775, + "end_line": 2791, + "section": "HTML blocks" + }, + { + "markdown": "<style\n type=\"text/css\">\nh1 {color:red;}\n\np {color:blue;}\n</style>\nokay\n", + "html": "<style\n type=\"text/css\">\nh1 {color:red;}\n\np {color:blue;}\n</style>\n<p>okay</p>\n", + "example": 172, + "start_line": 2795, + "end_line": 2811, + "section": "HTML blocks" + }, + { + "markdown": "<style\n type=\"text/css\">\n\nfoo\n", + "html": "<style\n type=\"text/css\">\n\nfoo\n", + "example": 173, + "start_line": 2818, + "end_line": 2828, + "section": "HTML blocks" + }, + { + "markdown": "> <div>\n> foo\n\nbar\n", + "html": "<blockquote>\n<div>\nfoo\n</blockquote>\n<p>bar</p>\n", + "example": 174, + "start_line": 2831, + "end_line": 2842, + "section": "HTML blocks" + }, + { + "markdown": "- <div>\n- foo\n", + "html": "<ul>\n<li>\n<div>\n</li>\n<li>foo</li>\n</ul>\n", + "example": 175, + "start_line": 2845, + "end_line": 2855, + "section": "HTML blocks" + }, + { + "markdown": "<style>p{color:red;}</style>\n*foo*\n", + "html": "<style>p{color:red;}</style>\n<p><em>foo</em></p>\n", + "example": 176, + "start_line": 2860, + "end_line": 2866, + "section": "HTML blocks" + }, + { + "markdown": "<!-- foo -->*bar*\n*baz*\n", + "html": "<!-- foo -->*bar*\n<p><em>baz</em></p>\n", + "example": 177, + "start_line": 2869, + "end_line": 2875, + "section": "HTML blocks" + }, + { + "markdown": "<script>\nfoo\n</script>1. *bar*\n", + "html": "<script>\nfoo\n</script>1. *bar*\n", + "example": 178, + "start_line": 2881, + "end_line": 2889, + "section": "HTML blocks" + }, + { + "markdown": "<!-- Foo\n\nbar\n baz -->\nokay\n", + "html": "<!-- Foo\n\nbar\n baz -->\n<p>okay</p>\n", + "example": 179, + "start_line": 2894, + "end_line": 2906, + "section": "HTML blocks" + }, + { + "markdown": "<?php\n\n echo '>';\n\n?>\nokay\n", + "html": "<?php\n\n echo '>';\n\n?>\n<p>okay</p>\n", + "example": 180, + "start_line": 2912, + "end_line": 2926, + "section": "HTML blocks" + }, + { + "markdown": "<!DOCTYPE html>\n", + "html": "<!DOCTYPE html>\n", + "example": 181, + "start_line": 2931, + "end_line": 2935, + "section": "HTML blocks" + }, + { + "markdown": "<![CDATA[\nfunction matchwo(a,b)\n{\n if (a < b && a < 0) then {\n return 1;\n\n } else {\n\n return 0;\n }\n}\n]]>\nokay\n", + "html": "<![CDATA[\nfunction matchwo(a,b)\n{\n if (a < b && a < 0) then {\n return 1;\n\n } else {\n\n return 0;\n }\n}\n]]>\n<p>okay</p>\n", + "example": 182, + "start_line": 2940, + "end_line": 2968, + "section": "HTML blocks" + }, + { + "markdown": " <!-- foo -->\n\n <!-- foo -->\n", + "html": " <!-- foo -->\n<pre><code><!-- foo -->\n</code></pre>\n", + "example": 183, + "start_line": 2974, + "end_line": 2982, + "section": "HTML blocks" + }, + { + "markdown": " <div>\n\n <div>\n", + "html": " <div>\n<pre><code><div>\n</code></pre>\n", + "example": 184, + "start_line": 2985, + "end_line": 2993, + "section": "HTML blocks" + }, + { + "markdown": "Foo\n<div>\nbar\n</div>\n", + "html": "<p>Foo</p>\n<div>\nbar\n</div>\n", + "example": 185, + "start_line": 2999, + "end_line": 3009, + "section": "HTML blocks" + }, + { + "markdown": "<div>\nbar\n</div>\n*foo*\n", + "html": "<div>\nbar\n</div>\n*foo*\n", + "example": 186, + "start_line": 3016, + "end_line": 3026, + "section": "HTML blocks" + }, + { + "markdown": "Foo\n<a href=\"bar\">\nbaz\n", + "html": "<p>Foo\n<a href=\"bar\">\nbaz</p>\n", + "example": 187, + "start_line": 3031, + "end_line": 3039, + "section": "HTML blocks" + }, + { + "markdown": "<div>\n\n*Emphasized* text.\n\n</div>\n", + "html": "<div>\n<p><em>Emphasized</em> text.</p>\n</div>\n", + "example": 188, + "start_line": 3072, + "end_line": 3082, + "section": "HTML blocks" + }, + { + "markdown": "<div>\n*Emphasized* text.\n</div>\n", + "html": "<div>\n*Emphasized* text.\n</div>\n", + "example": 189, + "start_line": 3085, + "end_line": 3093, + "section": "HTML blocks" + }, + { + "markdown": "<table>\n\n<tr>\n\n<td>\nHi\n</td>\n\n</tr>\n\n</table>\n", + "html": "<table>\n<tr>\n<td>\nHi\n</td>\n</tr>\n</table>\n", + "example": 190, + "start_line": 3107, + "end_line": 3127, + "section": "HTML blocks" + }, + { + "markdown": "<table>\n\n <tr>\n\n <td>\n Hi\n </td>\n\n </tr>\n\n</table>\n", + "html": "<table>\n <tr>\n<pre><code><td>\n Hi\n</td>\n</code></pre>\n </tr>\n</table>\n", + "example": 191, + "start_line": 3134, + "end_line": 3155, + "section": "HTML blocks" + }, + { + "markdown": "[foo]: /url \"title\"\n\n[foo]\n", + "html": "<p><a href=\"/url\" title=\"title\">foo</a></p>\n", + "example": 192, + "start_line": 3183, + "end_line": 3189, + "section": "Link reference definitions" + }, + { + "markdown": " [foo]: \n /url \n 'the title' \n\n[foo]\n", + "html": "<p><a href=\"/url\" title=\"the title\">foo</a></p>\n", + "example": 193, + "start_line": 3192, + "end_line": 3200, + "section": "Link reference definitions" + }, + { + "markdown": "[Foo*bar\\]]:my_(url) 'title (with parens)'\n\n[Foo*bar\\]]\n", + "html": "<p><a href=\"my_(url)\" title=\"title (with parens)\">Foo*bar]</a></p>\n", + "example": 194, + "start_line": 3203, + "end_line": 3209, + "section": "Link reference definitions" + }, + { + "markdown": "[Foo bar]:\n<my url>\n'title'\n\n[Foo bar]\n", + "html": "<p><a href=\"my%20url\" title=\"title\">Foo bar</a></p>\n", + "example": 195, + "start_line": 3212, + "end_line": 3220, + "section": "Link reference definitions" + }, + { + "markdown": "[foo]: /url '\ntitle\nline1\nline2\n'\n\n[foo]\n", + "html": "<p><a href=\"/url\" title=\"\ntitle\nline1\nline2\n\">foo</a></p>\n", + "example": 196, + "start_line": 3225, + "end_line": 3239, + "section": "Link reference definitions" + }, + { + "markdown": "[foo]: /url 'title\n\nwith blank line'\n\n[foo]\n", + "html": "<p>[foo]: /url 'title</p>\n<p>with blank line'</p>\n<p>[foo]</p>\n", + "example": 197, + "start_line": 3244, + "end_line": 3254, + "section": "Link reference definitions" + }, + { + "markdown": "[foo]:\n/url\n\n[foo]\n", + "html": "<p><a href=\"/url\">foo</a></p>\n", + "example": 198, + "start_line": 3259, + "end_line": 3266, + "section": "Link reference definitions" + }, + { + "markdown": "[foo]:\n\n[foo]\n", + "html": "<p>[foo]:</p>\n<p>[foo]</p>\n", + "example": 199, + "start_line": 3271, + "end_line": 3278, + "section": "Link reference definitions" + }, + { + "markdown": "[foo]: <>\n\n[foo]\n", + "html": "<p><a href=\"\">foo</a></p>\n", + "example": 200, + "start_line": 3283, + "end_line": 3289, + "section": "Link reference definitions" + }, + { + "markdown": "[foo]: <bar>(baz)\n\n[foo]\n", + "html": "<p>[foo]: <bar>(baz)</p>\n<p>[foo]</p>\n", + "example": 201, + "start_line": 3294, + "end_line": 3301, + "section": "Link reference definitions" + }, + { + "markdown": "[foo]: /url\\bar\\*baz \"foo\\\"bar\\baz\"\n\n[foo]\n", + "html": "<p><a href=\"/url%5Cbar*baz\" title=\"foo"bar\\baz\">foo</a></p>\n", + "example": 202, + "start_line": 3307, + "end_line": 3313, + "section": "Link reference definitions" + }, + { + "markdown": "[foo]\n\n[foo]: url\n", + "html": "<p><a href=\"url\">foo</a></p>\n", + "example": 203, + "start_line": 3318, + "end_line": 3324, + "section": "Link reference definitions" + }, + { + "markdown": "[foo]\n\n[foo]: first\n[foo]: second\n", + "html": "<p><a href=\"first\">foo</a></p>\n", + "example": 204, + "start_line": 3330, + "end_line": 3337, + "section": "Link reference definitions" + }, + { + "markdown": "[FOO]: /url\n\n[Foo]\n", + "html": "<p><a href=\"/url\">Foo</a></p>\n", + "example": 205, + "start_line": 3343, + "end_line": 3349, + "section": "Link reference definitions" + }, + { + "markdown": "[ΑΓΩ]: /φου\n\n[αγω]\n", + "html": "<p><a href=\"/%CF%86%CE%BF%CF%85\">αγω</a></p>\n", + "example": 206, + "start_line": 3352, + "end_line": 3358, + "section": "Link reference definitions" + }, + { + "markdown": "[foo]: /url\n", + "html": "", + "example": 207, + "start_line": 3367, + "end_line": 3370, + "section": "Link reference definitions" + }, + { + "markdown": "[\nfoo\n]: /url\nbar\n", + "html": "<p>bar</p>\n", + "example": 208, + "start_line": 3375, + "end_line": 3382, + "section": "Link reference definitions" + }, + { + "markdown": "[foo]: /url \"title\" ok\n", + "html": "<p>[foo]: /url "title" ok</p>\n", + "example": 209, + "start_line": 3388, + "end_line": 3392, + "section": "Link reference definitions" + }, + { + "markdown": "[foo]: /url\n\"title\" ok\n", + "html": "<p>"title" ok</p>\n", + "example": 210, + "start_line": 3397, + "end_line": 3402, + "section": "Link reference definitions" + }, + { + "markdown": " [foo]: /url \"title\"\n\n[foo]\n", + "html": "<pre><code>[foo]: /url "title"\n</code></pre>\n<p>[foo]</p>\n", + "example": 211, + "start_line": 3408, + "end_line": 3416, + "section": "Link reference definitions" + }, + { + "markdown": "```\n[foo]: /url\n```\n\n[foo]\n", + "html": "<pre><code>[foo]: /url\n</code></pre>\n<p>[foo]</p>\n", + "example": 212, + "start_line": 3422, + "end_line": 3432, + "section": "Link reference definitions" + }, + { + "markdown": "Foo\n[bar]: /baz\n\n[bar]\n", + "html": "<p>Foo\n[bar]: /baz</p>\n<p>[bar]</p>\n", + "example": 213, + "start_line": 3437, + "end_line": 3446, + "section": "Link reference definitions" + }, + { + "markdown": "# [Foo]\n[foo]: /url\n> bar\n", + "html": "<h1><a href=\"/url\">Foo</a></h1>\n<blockquote>\n<p>bar</p>\n</blockquote>\n", + "example": 214, + "start_line": 3452, + "end_line": 3461, + "section": "Link reference definitions" + }, + { + "markdown": "[foo]: /url\nbar\n===\n[foo]\n", + "html": "<h1>bar</h1>\n<p><a href=\"/url\">foo</a></p>\n", + "example": 215, + "start_line": 3463, + "end_line": 3471, + "section": "Link reference definitions" + }, + { + "markdown": "[foo]: /url\n===\n[foo]\n", + "html": "<p>===\n<a href=\"/url\">foo</a></p>\n", + "example": 216, + "start_line": 3473, + "end_line": 3480, + "section": "Link reference definitions" + }, + { + "markdown": "[foo]: /foo-url \"foo\"\n[bar]: /bar-url\n \"bar\"\n[baz]: /baz-url\n\n[foo],\n[bar],\n[baz]\n", + "html": "<p><a href=\"/foo-url\" title=\"foo\">foo</a>,\n<a href=\"/bar-url\" title=\"bar\">bar</a>,\n<a href=\"/baz-url\">baz</a></p>\n", + "example": 217, + "start_line": 3486, + "end_line": 3499, + "section": "Link reference definitions" + }, + { + "markdown": "[foo]\n\n> [foo]: /url\n", + "html": "<p><a href=\"/url\">foo</a></p>\n<blockquote>\n</blockquote>\n", + "example": 218, + "start_line": 3507, + "end_line": 3515, + "section": "Link reference definitions" + }, + { + "markdown": "aaa\n\nbbb\n", + "html": "<p>aaa</p>\n<p>bbb</p>\n", + "example": 219, + "start_line": 3529, + "end_line": 3536, + "section": "Paragraphs" + }, + { + "markdown": "aaa\nbbb\n\nccc\nddd\n", + "html": "<p>aaa\nbbb</p>\n<p>ccc\nddd</p>\n", + "example": 220, + "start_line": 3541, + "end_line": 3552, + "section": "Paragraphs" + }, + { + "markdown": "aaa\n\n\nbbb\n", + "html": "<p>aaa</p>\n<p>bbb</p>\n", + "example": 221, + "start_line": 3557, + "end_line": 3565, + "section": "Paragraphs" + }, + { + "markdown": " aaa\n bbb\n", + "html": "<p>aaa\nbbb</p>\n", + "example": 222, + "start_line": 3570, + "end_line": 3576, + "section": "Paragraphs" + }, + { + "markdown": "aaa\n bbb\n ccc\n", + "html": "<p>aaa\nbbb\nccc</p>\n", + "example": 223, + "start_line": 3582, + "end_line": 3590, + "section": "Paragraphs" + }, + { + "markdown": " aaa\nbbb\n", + "html": "<p>aaa\nbbb</p>\n", + "example": 224, + "start_line": 3596, + "end_line": 3602, + "section": "Paragraphs" + }, + { + "markdown": " aaa\nbbb\n", + "html": "<pre><code>aaa\n</code></pre>\n<p>bbb</p>\n", + "example": 225, + "start_line": 3605, + "end_line": 3612, + "section": "Paragraphs" + }, + { + "markdown": "aaa \nbbb \n", + "html": "<p>aaa<br />\nbbb</p>\n", + "example": 226, + "start_line": 3619, + "end_line": 3625, + "section": "Paragraphs" + }, + { + "markdown": " \n\naaa\n \n\n# aaa\n\n \n", + "html": "<p>aaa</p>\n<h1>aaa</h1>\n", + "example": 227, + "start_line": 3636, + "end_line": 3648, + "section": "Blank lines" + }, + { + "markdown": "> # Foo\n> bar\n> baz\n", + "html": "<blockquote>\n<h1>Foo</h1>\n<p>bar\nbaz</p>\n</blockquote>\n", + "example": 228, + "start_line": 3704, + "end_line": 3714, + "section": "Block quotes" + }, + { + "markdown": "># Foo\n>bar\n> baz\n", + "html": "<blockquote>\n<h1>Foo</h1>\n<p>bar\nbaz</p>\n</blockquote>\n", + "example": 229, + "start_line": 3719, + "end_line": 3729, + "section": "Block quotes" + }, + { + "markdown": " > # Foo\n > bar\n > baz\n", + "html": "<blockquote>\n<h1>Foo</h1>\n<p>bar\nbaz</p>\n</blockquote>\n", + "example": 230, + "start_line": 3734, + "end_line": 3744, + "section": "Block quotes" + }, + { + "markdown": " > # Foo\n > bar\n > baz\n", + "html": "<pre><code>> # Foo\n> bar\n> baz\n</code></pre>\n", + "example": 231, + "start_line": 3749, + "end_line": 3758, + "section": "Block quotes" + }, + { + "markdown": "> # Foo\n> bar\nbaz\n", + "html": "<blockquote>\n<h1>Foo</h1>\n<p>bar\nbaz</p>\n</blockquote>\n", + "example": 232, + "start_line": 3764, + "end_line": 3774, + "section": "Block quotes" + }, + { + "markdown": "> bar\nbaz\n> foo\n", + "html": "<blockquote>\n<p>bar\nbaz\nfoo</p>\n</blockquote>\n", + "example": 233, + "start_line": 3780, + "end_line": 3790, + "section": "Block quotes" + }, + { + "markdown": "> foo\n---\n", + "html": "<blockquote>\n<p>foo</p>\n</blockquote>\n<hr />\n", + "example": 234, + "start_line": 3804, + "end_line": 3812, + "section": "Block quotes" + }, + { + "markdown": "> - foo\n- bar\n", + "html": "<blockquote>\n<ul>\n<li>foo</li>\n</ul>\n</blockquote>\n<ul>\n<li>bar</li>\n</ul>\n", + "example": 235, + "start_line": 3824, + "end_line": 3836, + "section": "Block quotes" + }, + { + "markdown": "> foo\n bar\n", + "html": "<blockquote>\n<pre><code>foo\n</code></pre>\n</blockquote>\n<pre><code>bar\n</code></pre>\n", + "example": 236, + "start_line": 3842, + "end_line": 3852, + "section": "Block quotes" + }, + { + "markdown": "> ```\nfoo\n```\n", + "html": "<blockquote>\n<pre><code></code></pre>\n</blockquote>\n<p>foo</p>\n<pre><code></code></pre>\n", + "example": 237, + "start_line": 3855, + "end_line": 3865, + "section": "Block quotes" + }, + { + "markdown": "> foo\n - bar\n", + "html": "<blockquote>\n<p>foo\n- bar</p>\n</blockquote>\n", + "example": 238, + "start_line": 3871, + "end_line": 3879, + "section": "Block quotes" + }, + { + "markdown": ">\n", + "html": "<blockquote>\n</blockquote>\n", + "example": 239, + "start_line": 3895, + "end_line": 3900, + "section": "Block quotes" + }, + { + "markdown": ">\n> \n> \n", + "html": "<blockquote>\n</blockquote>\n", + "example": 240, + "start_line": 3903, + "end_line": 3910, + "section": "Block quotes" + }, + { + "markdown": ">\n> foo\n> \n", + "html": "<blockquote>\n<p>foo</p>\n</blockquote>\n", + "example": 241, + "start_line": 3915, + "end_line": 3923, + "section": "Block quotes" + }, + { + "markdown": "> foo\n\n> bar\n", + "html": "<blockquote>\n<p>foo</p>\n</blockquote>\n<blockquote>\n<p>bar</p>\n</blockquote>\n", + "example": 242, + "start_line": 3928, + "end_line": 3939, + "section": "Block quotes" + }, + { + "markdown": "> foo\n> bar\n", + "html": "<blockquote>\n<p>foo\nbar</p>\n</blockquote>\n", + "example": 243, + "start_line": 3950, + "end_line": 3958, + "section": "Block quotes" + }, + { + "markdown": "> foo\n>\n> bar\n", + "html": "<blockquote>\n<p>foo</p>\n<p>bar</p>\n</blockquote>\n", + "example": 244, + "start_line": 3963, + "end_line": 3972, + "section": "Block quotes" + }, + { + "markdown": "foo\n> bar\n", + "html": "<p>foo</p>\n<blockquote>\n<p>bar</p>\n</blockquote>\n", + "example": 245, + "start_line": 3977, + "end_line": 3985, + "section": "Block quotes" + }, + { + "markdown": "> aaa\n***\n> bbb\n", + "html": "<blockquote>\n<p>aaa</p>\n</blockquote>\n<hr />\n<blockquote>\n<p>bbb</p>\n</blockquote>\n", + "example": 246, + "start_line": 3991, + "end_line": 4003, + "section": "Block quotes" + }, + { + "markdown": "> bar\nbaz\n", + "html": "<blockquote>\n<p>bar\nbaz</p>\n</blockquote>\n", + "example": 247, + "start_line": 4009, + "end_line": 4017, + "section": "Block quotes" + }, + { + "markdown": "> bar\n\nbaz\n", + "html": "<blockquote>\n<p>bar</p>\n</blockquote>\n<p>baz</p>\n", + "example": 248, + "start_line": 4020, + "end_line": 4029, + "section": "Block quotes" + }, + { + "markdown": "> bar\n>\nbaz\n", + "html": "<blockquote>\n<p>bar</p>\n</blockquote>\n<p>baz</p>\n", + "example": 249, + "start_line": 4032, + "end_line": 4041, + "section": "Block quotes" + }, + { + "markdown": "> > > foo\nbar\n", + "html": "<blockquote>\n<blockquote>\n<blockquote>\n<p>foo\nbar</p>\n</blockquote>\n</blockquote>\n</blockquote>\n", + "example": 250, + "start_line": 4048, + "end_line": 4060, + "section": "Block quotes" + }, + { + "markdown": ">>> foo\n> bar\n>>baz\n", + "html": "<blockquote>\n<blockquote>\n<blockquote>\n<p>foo\nbar\nbaz</p>\n</blockquote>\n</blockquote>\n</blockquote>\n", + "example": 251, + "start_line": 4063, + "end_line": 4077, + "section": "Block quotes" + }, + { + "markdown": "> code\n\n> not code\n", + "html": "<blockquote>\n<pre><code>code\n</code></pre>\n</blockquote>\n<blockquote>\n<p>not code</p>\n</blockquote>\n", + "example": 252, + "start_line": 4085, + "end_line": 4097, + "section": "Block quotes" + }, + { + "markdown": "A paragraph\nwith two lines.\n\n indented code\n\n> A block quote.\n", + "html": "<p>A paragraph\nwith two lines.</p>\n<pre><code>indented code\n</code></pre>\n<blockquote>\n<p>A block quote.</p>\n</blockquote>\n", + "example": 253, + "start_line": 4139, + "end_line": 4154, + "section": "List items" + }, + { + "markdown": "1. A paragraph\n with two lines.\n\n indented code\n\n > A block quote.\n", + "html": "<ol>\n<li>\n<p>A paragraph\nwith two lines.</p>\n<pre><code>indented code\n</code></pre>\n<blockquote>\n<p>A block quote.</p>\n</blockquote>\n</li>\n</ol>\n", + "example": 254, + "start_line": 4161, + "end_line": 4180, + "section": "List items" + }, + { + "markdown": "- one\n\n two\n", + "html": "<ul>\n<li>one</li>\n</ul>\n<p>two</p>\n", + "example": 255, + "start_line": 4194, + "end_line": 4203, + "section": "List items" + }, + { + "markdown": "- one\n\n two\n", + "html": "<ul>\n<li>\n<p>one</p>\n<p>two</p>\n</li>\n</ul>\n", + "example": 256, + "start_line": 4206, + "end_line": 4217, + "section": "List items" + }, + { + "markdown": " - one\n\n two\n", + "html": "<ul>\n<li>one</li>\n</ul>\n<pre><code> two\n</code></pre>\n", + "example": 257, + "start_line": 4220, + "end_line": 4230, + "section": "List items" + }, + { + "markdown": " - one\n\n two\n", + "html": "<ul>\n<li>\n<p>one</p>\n<p>two</p>\n</li>\n</ul>\n", + "example": 258, + "start_line": 4233, + "end_line": 4244, + "section": "List items" + }, + { + "markdown": " > > 1. one\n>>\n>> two\n", + "html": "<blockquote>\n<blockquote>\n<ol>\n<li>\n<p>one</p>\n<p>two</p>\n</li>\n</ol>\n</blockquote>\n</blockquote>\n", + "example": 259, + "start_line": 4255, + "end_line": 4270, + "section": "List items" + }, + { + "markdown": ">>- one\n>>\n > > two\n", + "html": "<blockquote>\n<blockquote>\n<ul>\n<li>one</li>\n</ul>\n<p>two</p>\n</blockquote>\n</blockquote>\n", + "example": 260, + "start_line": 4282, + "end_line": 4295, + "section": "List items" + }, + { + "markdown": "-one\n\n2.two\n", + "html": "<p>-one</p>\n<p>2.two</p>\n", + "example": 261, + "start_line": 4301, + "end_line": 4308, + "section": "List items" + }, + { + "markdown": "- foo\n\n\n bar\n", + "html": "<ul>\n<li>\n<p>foo</p>\n<p>bar</p>\n</li>\n</ul>\n", + "example": 262, + "start_line": 4314, + "end_line": 4326, + "section": "List items" + }, + { + "markdown": "1. foo\n\n ```\n bar\n ```\n\n baz\n\n > bam\n", + "html": "<ol>\n<li>\n<p>foo</p>\n<pre><code>bar\n</code></pre>\n<p>baz</p>\n<blockquote>\n<p>bam</p>\n</blockquote>\n</li>\n</ol>\n", + "example": 263, + "start_line": 4331, + "end_line": 4353, + "section": "List items" + }, + { + "markdown": "- Foo\n\n bar\n\n\n baz\n", + "html": "<ul>\n<li>\n<p>Foo</p>\n<pre><code>bar\n\n\nbaz\n</code></pre>\n</li>\n</ul>\n", + "example": 264, + "start_line": 4359, + "end_line": 4377, + "section": "List items" + }, + { + "markdown": "123456789. ok\n", + "html": "<ol start=\"123456789\">\n<li>ok</li>\n</ol>\n", + "example": 265, + "start_line": 4381, + "end_line": 4387, + "section": "List items" + }, + { + "markdown": "1234567890. not ok\n", + "html": "<p>1234567890. not ok</p>\n", + "example": 266, + "start_line": 4390, + "end_line": 4394, + "section": "List items" + }, + { + "markdown": "0. ok\n", + "html": "<ol start=\"0\">\n<li>ok</li>\n</ol>\n", + "example": 267, + "start_line": 4399, + "end_line": 4405, + "section": "List items" + }, + { + "markdown": "003. ok\n", + "html": "<ol start=\"3\">\n<li>ok</li>\n</ol>\n", + "example": 268, + "start_line": 4408, + "end_line": 4414, + "section": "List items" + }, + { + "markdown": "-1. not ok\n", + "html": "<p>-1. not ok</p>\n", + "example": 269, + "start_line": 4419, + "end_line": 4423, + "section": "List items" + }, + { + "markdown": "- foo\n\n bar\n", + "html": "<ul>\n<li>\n<p>foo</p>\n<pre><code>bar\n</code></pre>\n</li>\n</ul>\n", + "example": 270, + "start_line": 4442, + "end_line": 4454, + "section": "List items" + }, + { + "markdown": " 10. foo\n\n bar\n", + "html": "<ol start=\"10\">\n<li>\n<p>foo</p>\n<pre><code>bar\n</code></pre>\n</li>\n</ol>\n", + "example": 271, + "start_line": 4459, + "end_line": 4471, + "section": "List items" + }, + { + "markdown": " indented code\n\nparagraph\n\n more code\n", + "html": "<pre><code>indented code\n</code></pre>\n<p>paragraph</p>\n<pre><code>more code\n</code></pre>\n", + "example": 272, + "start_line": 4478, + "end_line": 4490, + "section": "List items" + }, + { + "markdown": "1. indented code\n\n paragraph\n\n more code\n", + "html": "<ol>\n<li>\n<pre><code>indented code\n</code></pre>\n<p>paragraph</p>\n<pre><code>more code\n</code></pre>\n</li>\n</ol>\n", + "example": 273, + "start_line": 4493, + "end_line": 4509, + "section": "List items" + }, + { + "markdown": "1. indented code\n\n paragraph\n\n more code\n", + "html": "<ol>\n<li>\n<pre><code> indented code\n</code></pre>\n<p>paragraph</p>\n<pre><code>more code\n</code></pre>\n</li>\n</ol>\n", + "example": 274, + "start_line": 4515, + "end_line": 4531, + "section": "List items" + }, + { + "markdown": " foo\n\nbar\n", + "html": "<p>foo</p>\n<p>bar</p>\n", + "example": 275, + "start_line": 4542, + "end_line": 4549, + "section": "List items" + }, + { + "markdown": "- foo\n\n bar\n", + "html": "<ul>\n<li>foo</li>\n</ul>\n<p>bar</p>\n", + "example": 276, + "start_line": 4552, + "end_line": 4561, + "section": "List items" + }, + { + "markdown": "- foo\n\n bar\n", + "html": "<ul>\n<li>\n<p>foo</p>\n<p>bar</p>\n</li>\n</ul>\n", + "example": 277, + "start_line": 4569, + "end_line": 4580, + "section": "List items" + }, + { + "markdown": "-\n foo\n-\n ```\n bar\n ```\n-\n baz\n", + "html": "<ul>\n<li>foo</li>\n<li>\n<pre><code>bar\n</code></pre>\n</li>\n<li>\n<pre><code>baz\n</code></pre>\n</li>\n</ul>\n", + "example": 278, + "start_line": 4596, + "end_line": 4617, + "section": "List items" + }, + { + "markdown": "- \n foo\n", + "html": "<ul>\n<li>foo</li>\n</ul>\n", + "example": 279, + "start_line": 4622, + "end_line": 4629, + "section": "List items" + }, + { + "markdown": "-\n\n foo\n", + "html": "<ul>\n<li></li>\n</ul>\n<p>foo</p>\n", + "example": 280, + "start_line": 4636, + "end_line": 4645, + "section": "List items" + }, + { + "markdown": "- foo\n-\n- bar\n", + "html": "<ul>\n<li>foo</li>\n<li></li>\n<li>bar</li>\n</ul>\n", + "example": 281, + "start_line": 4650, + "end_line": 4660, + "section": "List items" + }, + { + "markdown": "- foo\n- \n- bar\n", + "html": "<ul>\n<li>foo</li>\n<li></li>\n<li>bar</li>\n</ul>\n", + "example": 282, + "start_line": 4665, + "end_line": 4675, + "section": "List items" + }, + { + "markdown": "1. foo\n2.\n3. bar\n", + "html": "<ol>\n<li>foo</li>\n<li></li>\n<li>bar</li>\n</ol>\n", + "example": 283, + "start_line": 4680, + "end_line": 4690, + "section": "List items" + }, + { + "markdown": "*\n", + "html": "<ul>\n<li></li>\n</ul>\n", + "example": 284, + "start_line": 4695, + "end_line": 4701, + "section": "List items" + }, + { + "markdown": "foo\n*\n\nfoo\n1.\n", + "html": "<p>foo\n*</p>\n<p>foo\n1.</p>\n", + "example": 285, + "start_line": 4705, + "end_line": 4716, + "section": "List items" + }, + { + "markdown": " 1. A paragraph\n with two lines.\n\n indented code\n\n > A block quote.\n", + "html": "<ol>\n<li>\n<p>A paragraph\nwith two lines.</p>\n<pre><code>indented code\n</code></pre>\n<blockquote>\n<p>A block quote.</p>\n</blockquote>\n</li>\n</ol>\n", + "example": 286, + "start_line": 4727, + "end_line": 4746, + "section": "List items" + }, + { + "markdown": " 1. A paragraph\n with two lines.\n\n indented code\n\n > A block quote.\n", + "html": "<ol>\n<li>\n<p>A paragraph\nwith two lines.</p>\n<pre><code>indented code\n</code></pre>\n<blockquote>\n<p>A block quote.</p>\n</blockquote>\n</li>\n</ol>\n", + "example": 287, + "start_line": 4751, + "end_line": 4770, + "section": "List items" + }, + { + "markdown": " 1. A paragraph\n with two lines.\n\n indented code\n\n > A block quote.\n", + "html": "<ol>\n<li>\n<p>A paragraph\nwith two lines.</p>\n<pre><code>indented code\n</code></pre>\n<blockquote>\n<p>A block quote.</p>\n</blockquote>\n</li>\n</ol>\n", + "example": 288, + "start_line": 4775, + "end_line": 4794, + "section": "List items" + }, + { + "markdown": " 1. A paragraph\n with two lines.\n\n indented code\n\n > A block quote.\n", + "html": "<pre><code>1. A paragraph\n with two lines.\n\n indented code\n\n > A block quote.\n</code></pre>\n", + "example": 289, + "start_line": 4799, + "end_line": 4814, + "section": "List items" + }, + { + "markdown": " 1. A paragraph\nwith two lines.\n\n indented code\n\n > A block quote.\n", + "html": "<ol>\n<li>\n<p>A paragraph\nwith two lines.</p>\n<pre><code>indented code\n</code></pre>\n<blockquote>\n<p>A block quote.</p>\n</blockquote>\n</li>\n</ol>\n", + "example": 290, + "start_line": 4829, + "end_line": 4848, + "section": "List items" + }, + { + "markdown": " 1. A paragraph\n with two lines.\n", + "html": "<ol>\n<li>A paragraph\nwith two lines.</li>\n</ol>\n", + "example": 291, + "start_line": 4853, + "end_line": 4861, + "section": "List items" + }, + { + "markdown": "> 1. > Blockquote\ncontinued here.\n", + "html": "<blockquote>\n<ol>\n<li>\n<blockquote>\n<p>Blockquote\ncontinued here.</p>\n</blockquote>\n</li>\n</ol>\n</blockquote>\n", + "example": 292, + "start_line": 4866, + "end_line": 4880, + "section": "List items" + }, + { + "markdown": "> 1. > Blockquote\n> continued here.\n", + "html": "<blockquote>\n<ol>\n<li>\n<blockquote>\n<p>Blockquote\ncontinued here.</p>\n</blockquote>\n</li>\n</ol>\n</blockquote>\n", + "example": 293, + "start_line": 4883, + "end_line": 4897, + "section": "List items" + }, + { + "markdown": "- foo\n - bar\n - baz\n - boo\n", + "html": "<ul>\n<li>foo\n<ul>\n<li>bar\n<ul>\n<li>baz\n<ul>\n<li>boo</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n", + "example": 294, + "start_line": 4911, + "end_line": 4932, + "section": "List items" + }, + { + "markdown": "- foo\n - bar\n - baz\n - boo\n", + "html": "<ul>\n<li>foo</li>\n<li>bar</li>\n<li>baz</li>\n<li>boo</li>\n</ul>\n", + "example": 295, + "start_line": 4937, + "end_line": 4949, + "section": "List items" + }, + { + "markdown": "10) foo\n - bar\n", + "html": "<ol start=\"10\">\n<li>foo\n<ul>\n<li>bar</li>\n</ul>\n</li>\n</ol>\n", + "example": 296, + "start_line": 4954, + "end_line": 4965, + "section": "List items" + }, + { + "markdown": "10) foo\n - bar\n", + "html": "<ol start=\"10\">\n<li>foo</li>\n</ol>\n<ul>\n<li>bar</li>\n</ul>\n", + "example": 297, + "start_line": 4970, + "end_line": 4980, + "section": "List items" + }, + { + "markdown": "- - foo\n", + "html": "<ul>\n<li>\n<ul>\n<li>foo</li>\n</ul>\n</li>\n</ul>\n", + "example": 298, + "start_line": 4985, + "end_line": 4995, + "section": "List items" + }, + { + "markdown": "1. - 2. foo\n", + "html": "<ol>\n<li>\n<ul>\n<li>\n<ol start=\"2\">\n<li>foo</li>\n</ol>\n</li>\n</ul>\n</li>\n</ol>\n", + "example": 299, + "start_line": 4998, + "end_line": 5012, + "section": "List items" + }, + { + "markdown": "- # Foo\n- Bar\n ---\n baz\n", + "html": "<ul>\n<li>\n<h1>Foo</h1>\n</li>\n<li>\n<h2>Bar</h2>\nbaz</li>\n</ul>\n", + "example": 300, + "start_line": 5017, + "end_line": 5031, + "section": "List items" + }, + { + "markdown": "- foo\n- bar\n+ baz\n", + "html": "<ul>\n<li>foo</li>\n<li>bar</li>\n</ul>\n<ul>\n<li>baz</li>\n</ul>\n", + "example": 301, + "start_line": 5253, + "end_line": 5265, + "section": "Lists" + }, + { + "markdown": "1. foo\n2. bar\n3) baz\n", + "html": "<ol>\n<li>foo</li>\n<li>bar</li>\n</ol>\n<ol start=\"3\">\n<li>baz</li>\n</ol>\n", + "example": 302, + "start_line": 5268, + "end_line": 5280, + "section": "Lists" + }, + { + "markdown": "Foo\n- bar\n- baz\n", + "html": "<p>Foo</p>\n<ul>\n<li>bar</li>\n<li>baz</li>\n</ul>\n", + "example": 303, + "start_line": 5287, + "end_line": 5297, + "section": "Lists" + }, + { + "markdown": "The number of windows in my house is\n14. The number of doors is 6.\n", + "html": "<p>The number of windows in my house is\n14. The number of doors is 6.</p>\n", + "example": 304, + "start_line": 5364, + "end_line": 5370, + "section": "Lists" + }, + { + "markdown": "The number of windows in my house is\n1. The number of doors is 6.\n", + "html": "<p>The number of windows in my house is</p>\n<ol>\n<li>The number of doors is 6.</li>\n</ol>\n", + "example": 305, + "start_line": 5374, + "end_line": 5382, + "section": "Lists" + }, + { + "markdown": "- foo\n\n- bar\n\n\n- baz\n", + "html": "<ul>\n<li>\n<p>foo</p>\n</li>\n<li>\n<p>bar</p>\n</li>\n<li>\n<p>baz</p>\n</li>\n</ul>\n", + "example": 306, + "start_line": 5388, + "end_line": 5407, + "section": "Lists" + }, + { + "markdown": "- foo\n - bar\n - baz\n\n\n bim\n", + "html": "<ul>\n<li>foo\n<ul>\n<li>bar\n<ul>\n<li>\n<p>baz</p>\n<p>bim</p>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n", + "example": 307, + "start_line": 5409, + "end_line": 5431, + "section": "Lists" + }, + { + "markdown": "- foo\n- bar\n\n<!-- -->\n\n- baz\n- bim\n", + "html": "<ul>\n<li>foo</li>\n<li>bar</li>\n</ul>\n<!-- -->\n<ul>\n<li>baz</li>\n<li>bim</li>\n</ul>\n", + "example": 308, + "start_line": 5439, + "end_line": 5457, + "section": "Lists" + }, + { + "markdown": "- foo\n\n notcode\n\n- foo\n\n<!-- -->\n\n code\n", + "html": "<ul>\n<li>\n<p>foo</p>\n<p>notcode</p>\n</li>\n<li>\n<p>foo</p>\n</li>\n</ul>\n<!-- -->\n<pre><code>code\n</code></pre>\n", + "example": 309, + "start_line": 5460, + "end_line": 5483, + "section": "Lists" + }, + { + "markdown": "- a\n - b\n - c\n - d\n - e\n - f\n- g\n", + "html": "<ul>\n<li>a</li>\n<li>b</li>\n<li>c</li>\n<li>d</li>\n<li>e</li>\n<li>f</li>\n<li>g</li>\n</ul>\n", + "example": 310, + "start_line": 5491, + "end_line": 5509, + "section": "Lists" + }, + { + "markdown": "1. a\n\n 2. b\n\n 3. c\n", + "html": "<ol>\n<li>\n<p>a</p>\n</li>\n<li>\n<p>b</p>\n</li>\n<li>\n<p>c</p>\n</li>\n</ol>\n", + "example": 311, + "start_line": 5512, + "end_line": 5530, + "section": "Lists" + }, + { + "markdown": "- a\n - b\n - c\n - d\n - e\n", + "html": "<ul>\n<li>a</li>\n<li>b</li>\n<li>c</li>\n<li>d\n- e</li>\n</ul>\n", + "example": 312, + "start_line": 5536, + "end_line": 5550, + "section": "Lists" + }, + { + "markdown": "1. a\n\n 2. b\n\n 3. c\n", + "html": "<ol>\n<li>\n<p>a</p>\n</li>\n<li>\n<p>b</p>\n</li>\n</ol>\n<pre><code>3. c\n</code></pre>\n", + "example": 313, + "start_line": 5556, + "end_line": 5573, + "section": "Lists" + }, + { + "markdown": "- a\n- b\n\n- c\n", + "html": "<ul>\n<li>\n<p>a</p>\n</li>\n<li>\n<p>b</p>\n</li>\n<li>\n<p>c</p>\n</li>\n</ul>\n", + "example": 314, + "start_line": 5579, + "end_line": 5596, + "section": "Lists" + }, + { + "markdown": "* a\n*\n\n* c\n", + "html": "<ul>\n<li>\n<p>a</p>\n</li>\n<li></li>\n<li>\n<p>c</p>\n</li>\n</ul>\n", + "example": 315, + "start_line": 5601, + "end_line": 5616, + "section": "Lists" + }, + { + "markdown": "- a\n- b\n\n c\n- d\n", + "html": "<ul>\n<li>\n<p>a</p>\n</li>\n<li>\n<p>b</p>\n<p>c</p>\n</li>\n<li>\n<p>d</p>\n</li>\n</ul>\n", + "example": 316, + "start_line": 5623, + "end_line": 5642, + "section": "Lists" + }, + { + "markdown": "- a\n- b\n\n [ref]: /url\n- d\n", + "html": "<ul>\n<li>\n<p>a</p>\n</li>\n<li>\n<p>b</p>\n</li>\n<li>\n<p>d</p>\n</li>\n</ul>\n", + "example": 317, + "start_line": 5645, + "end_line": 5663, + "section": "Lists" + }, + { + "markdown": "- a\n- ```\n b\n\n\n ```\n- c\n", + "html": "<ul>\n<li>a</li>\n<li>\n<pre><code>b\n\n\n</code></pre>\n</li>\n<li>c</li>\n</ul>\n", + "example": 318, + "start_line": 5668, + "end_line": 5687, + "section": "Lists" + }, + { + "markdown": "- a\n - b\n\n c\n- d\n", + "html": "<ul>\n<li>a\n<ul>\n<li>\n<p>b</p>\n<p>c</p>\n</li>\n</ul>\n</li>\n<li>d</li>\n</ul>\n", + "example": 319, + "start_line": 5694, + "end_line": 5712, + "section": "Lists" + }, + { + "markdown": "* a\n > b\n >\n* c\n", + "html": "<ul>\n<li>a\n<blockquote>\n<p>b</p>\n</blockquote>\n</li>\n<li>c</li>\n</ul>\n", + "example": 320, + "start_line": 5718, + "end_line": 5732, + "section": "Lists" + }, + { + "markdown": "- a\n > b\n ```\n c\n ```\n- d\n", + "html": "<ul>\n<li>a\n<blockquote>\n<p>b</p>\n</blockquote>\n<pre><code>c\n</code></pre>\n</li>\n<li>d</li>\n</ul>\n", + "example": 321, + "start_line": 5738, + "end_line": 5756, + "section": "Lists" + }, + { + "markdown": "- a\n", + "html": "<ul>\n<li>a</li>\n</ul>\n", + "example": 322, + "start_line": 5761, + "end_line": 5767, + "section": "Lists" + }, + { + "markdown": "- a\n - b\n", + "html": "<ul>\n<li>a\n<ul>\n<li>b</li>\n</ul>\n</li>\n</ul>\n", + "example": 323, + "start_line": 5770, + "end_line": 5781, + "section": "Lists" + }, + { + "markdown": "1. ```\n foo\n ```\n\n bar\n", + "html": "<ol>\n<li>\n<pre><code>foo\n</code></pre>\n<p>bar</p>\n</li>\n</ol>\n", + "example": 324, + "start_line": 5787, + "end_line": 5801, + "section": "Lists" + }, + { + "markdown": "* foo\n * bar\n\n baz\n", + "html": "<ul>\n<li>\n<p>foo</p>\n<ul>\n<li>bar</li>\n</ul>\n<p>baz</p>\n</li>\n</ul>\n", + "example": 325, + "start_line": 5806, + "end_line": 5821, + "section": "Lists" + }, + { + "markdown": "- a\n - b\n - c\n\n- d\n - e\n - f\n", + "html": "<ul>\n<li>\n<p>a</p>\n<ul>\n<li>b</li>\n<li>c</li>\n</ul>\n</li>\n<li>\n<p>d</p>\n<ul>\n<li>e</li>\n<li>f</li>\n</ul>\n</li>\n</ul>\n", + "example": 326, + "start_line": 5824, + "end_line": 5849, + "section": "Lists" + }, + { + "markdown": "`hi`lo`\n", + "html": "<p><code>hi</code>lo`</p>\n", + "example": 327, + "start_line": 5858, + "end_line": 5862, + "section": "Inlines" + }, + { + "markdown": "`foo`\n", + "html": "<p><code>foo</code></p>\n", + "example": 328, + "start_line": 5890, + "end_line": 5894, + "section": "Code spans" + }, + { + "markdown": "`` foo ` bar ``\n", + "html": "<p><code>foo ` bar</code></p>\n", + "example": 329, + "start_line": 5901, + "end_line": 5905, + "section": "Code spans" + }, + { + "markdown": "` `` `\n", + "html": "<p><code>``</code></p>\n", + "example": 330, + "start_line": 5911, + "end_line": 5915, + "section": "Code spans" + }, + { + "markdown": "` `` `\n", + "html": "<p><code> `` </code></p>\n", + "example": 331, + "start_line": 5919, + "end_line": 5923, + "section": "Code spans" + }, + { + "markdown": "` a`\n", + "html": "<p><code> a</code></p>\n", + "example": 332, + "start_line": 5928, + "end_line": 5932, + "section": "Code spans" + }, + { + "markdown": "` b `\n", + "html": "<p><code> b </code></p>\n", + "example": 333, + "start_line": 5937, + "end_line": 5941, + "section": "Code spans" + }, + { + "markdown": "` `\n` `\n", + "html": "<p><code> </code>\n<code> </code></p>\n", + "example": 334, + "start_line": 5945, + "end_line": 5951, + "section": "Code spans" + }, + { + "markdown": "``\nfoo\nbar \nbaz\n``\n", + "html": "<p><code>foo bar baz</code></p>\n", + "example": 335, + "start_line": 5956, + "end_line": 5964, + "section": "Code spans" + }, + { + "markdown": "``\nfoo \n``\n", + "html": "<p><code>foo </code></p>\n", + "example": 336, + "start_line": 5966, + "end_line": 5972, + "section": "Code spans" + }, + { + "markdown": "`foo bar \nbaz`\n", + "html": "<p><code>foo bar baz</code></p>\n", + "example": 337, + "start_line": 5977, + "end_line": 5982, + "section": "Code spans" + }, + { + "markdown": "`foo\\`bar`\n", + "html": "<p><code>foo\\</code>bar`</p>\n", + "example": 338, + "start_line": 5994, + "end_line": 5998, + "section": "Code spans" + }, + { + "markdown": "``foo`bar``\n", + "html": "<p><code>foo`bar</code></p>\n", + "example": 339, + "start_line": 6005, + "end_line": 6009, + "section": "Code spans" + }, + { + "markdown": "` foo `` bar `\n", + "html": "<p><code>foo `` bar</code></p>\n", + "example": 340, + "start_line": 6011, + "end_line": 6015, + "section": "Code spans" + }, + { + "markdown": "*foo`*`\n", + "html": "<p>*foo<code>*</code></p>\n", + "example": 341, + "start_line": 6023, + "end_line": 6027, + "section": "Code spans" + }, + { + "markdown": "[not a `link](/foo`)\n", + "html": "<p>[not a <code>link](/foo</code>)</p>\n", + "example": 342, + "start_line": 6032, + "end_line": 6036, + "section": "Code spans" + }, + { + "markdown": "`<a href=\"`\">`\n", + "html": "<p><code><a href="</code>">`</p>\n", + "example": 343, + "start_line": 6042, + "end_line": 6046, + "section": "Code spans" + }, + { + "markdown": "<a href=\"`\">`\n", + "html": "<p><a href=\"`\">`</p>\n", + "example": 344, + "start_line": 6051, + "end_line": 6055, + "section": "Code spans" + }, + { + "markdown": "`<http://foo.bar.`baz>`\n", + "html": "<p><code><http://foo.bar.</code>baz>`</p>\n", + "example": 345, + "start_line": 6060, + "end_line": 6064, + "section": "Code spans" + }, + { + "markdown": "<http://foo.bar.`baz>`\n", + "html": "<p><a href=\"http://foo.bar.%60baz\">http://foo.bar.`baz</a>`</p>\n", + "example": 346, + "start_line": 6069, + "end_line": 6073, + "section": "Code spans" + }, + { + "markdown": "```foo``\n", + "html": "<p>```foo``</p>\n", + "example": 347, + "start_line": 6079, + "end_line": 6083, + "section": "Code spans" + }, + { + "markdown": "`foo\n", + "html": "<p>`foo</p>\n", + "example": 348, + "start_line": 6086, + "end_line": 6090, + "section": "Code spans" + }, + { + "markdown": "`foo``bar``\n", + "html": "<p>`foo<code>bar</code></p>\n", + "example": 349, + "start_line": 6095, + "end_line": 6099, + "section": "Code spans" + }, + { + "markdown": "*foo bar*\n", + "html": "<p><em>foo bar</em></p>\n", + "example": 350, + "start_line": 6312, + "end_line": 6316, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "a * foo bar*\n", + "html": "<p>a * foo bar*</p>\n", + "example": 351, + "start_line": 6322, + "end_line": 6326, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "a*\"foo\"*\n", + "html": "<p>a*"foo"*</p>\n", + "example": 352, + "start_line": 6333, + "end_line": 6337, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "* a *\n", + "html": "<p>* a *</p>\n", + "example": 353, + "start_line": 6342, + "end_line": 6346, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "foo*bar*\n", + "html": "<p>foo<em>bar</em></p>\n", + "example": 354, + "start_line": 6351, + "end_line": 6355, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "5*6*78\n", + "html": "<p>5<em>6</em>78</p>\n", + "example": 355, + "start_line": 6358, + "end_line": 6362, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "_foo bar_\n", + "html": "<p><em>foo bar</em></p>\n", + "example": 356, + "start_line": 6367, + "end_line": 6371, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "_ foo bar_\n", + "html": "<p>_ foo bar_</p>\n", + "example": 357, + "start_line": 6377, + "end_line": 6381, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "a_\"foo\"_\n", + "html": "<p>a_"foo"_</p>\n", + "example": 358, + "start_line": 6387, + "end_line": 6391, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "foo_bar_\n", + "html": "<p>foo_bar_</p>\n", + "example": 359, + "start_line": 6396, + "end_line": 6400, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "5_6_78\n", + "html": "<p>5_6_78</p>\n", + "example": 360, + "start_line": 6403, + "end_line": 6407, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "пристаням_стремятся_\n", + "html": "<p>пристаням_стремятся_</p>\n", + "example": 361, + "start_line": 6410, + "end_line": 6414, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "aa_\"bb\"_cc\n", + "html": "<p>aa_"bb"_cc</p>\n", + "example": 362, + "start_line": 6420, + "end_line": 6424, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "foo-_(bar)_\n", + "html": "<p>foo-<em>(bar)</em></p>\n", + "example": 363, + "start_line": 6431, + "end_line": 6435, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "_foo*\n", + "html": "<p>_foo*</p>\n", + "example": 364, + "start_line": 6443, + "end_line": 6447, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "*foo bar *\n", + "html": "<p>*foo bar *</p>\n", + "example": 365, + "start_line": 6453, + "end_line": 6457, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "*foo bar\n*\n", + "html": "<p>*foo bar\n*</p>\n", + "example": 366, + "start_line": 6462, + "end_line": 6468, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "*(*foo)\n", + "html": "<p>*(*foo)</p>\n", + "example": 367, + "start_line": 6475, + "end_line": 6479, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "*(*foo*)*\n", + "html": "<p><em>(<em>foo</em>)</em></p>\n", + "example": 368, + "start_line": 6485, + "end_line": 6489, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "*foo*bar\n", + "html": "<p><em>foo</em>bar</p>\n", + "example": 369, + "start_line": 6494, + "end_line": 6498, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "_foo bar _\n", + "html": "<p>_foo bar _</p>\n", + "example": 370, + "start_line": 6507, + "end_line": 6511, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "_(_foo)\n", + "html": "<p>_(_foo)</p>\n", + "example": 371, + "start_line": 6517, + "end_line": 6521, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "_(_foo_)_\n", + "html": "<p><em>(<em>foo</em>)</em></p>\n", + "example": 372, + "start_line": 6526, + "end_line": 6530, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "_foo_bar\n", + "html": "<p>_foo_bar</p>\n", + "example": 373, + "start_line": 6535, + "end_line": 6539, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "_пристаням_стремятся\n", + "html": "<p>_пристаням_стремятся</p>\n", + "example": 374, + "start_line": 6542, + "end_line": 6546, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "_foo_bar_baz_\n", + "html": "<p><em>foo_bar_baz</em></p>\n", + "example": 375, + "start_line": 6549, + "end_line": 6553, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "_(bar)_.\n", + "html": "<p><em>(bar)</em>.</p>\n", + "example": 376, + "start_line": 6560, + "end_line": 6564, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "**foo bar**\n", + "html": "<p><strong>foo bar</strong></p>\n", + "example": 377, + "start_line": 6569, + "end_line": 6573, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "** foo bar**\n", + "html": "<p>** foo bar**</p>\n", + "example": 378, + "start_line": 6579, + "end_line": 6583, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "a**\"foo\"**\n", + "html": "<p>a**"foo"**</p>\n", + "example": 379, + "start_line": 6590, + "end_line": 6594, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "foo**bar**\n", + "html": "<p>foo<strong>bar</strong></p>\n", + "example": 380, + "start_line": 6599, + "end_line": 6603, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "__foo bar__\n", + "html": "<p><strong>foo bar</strong></p>\n", + "example": 381, + "start_line": 6608, + "end_line": 6612, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "__ foo bar__\n", + "html": "<p>__ foo bar__</p>\n", + "example": 382, + "start_line": 6618, + "end_line": 6622, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "__\nfoo bar__\n", + "html": "<p>__\nfoo bar__</p>\n", + "example": 383, + "start_line": 6626, + "end_line": 6632, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "a__\"foo\"__\n", + "html": "<p>a__"foo"__</p>\n", + "example": 384, + "start_line": 6638, + "end_line": 6642, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "foo__bar__\n", + "html": "<p>foo__bar__</p>\n", + "example": 385, + "start_line": 6647, + "end_line": 6651, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "5__6__78\n", + "html": "<p>5__6__78</p>\n", + "example": 386, + "start_line": 6654, + "end_line": 6658, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "пристаням__стремятся__\n", + "html": "<p>пристаням__стремятся__</p>\n", + "example": 387, + "start_line": 6661, + "end_line": 6665, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "__foo, __bar__, baz__\n", + "html": "<p><strong>foo, <strong>bar</strong>, baz</strong></p>\n", + "example": 388, + "start_line": 6668, + "end_line": 6672, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "foo-__(bar)__\n", + "html": "<p>foo-<strong>(bar)</strong></p>\n", + "example": 389, + "start_line": 6679, + "end_line": 6683, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "**foo bar **\n", + "html": "<p>**foo bar **</p>\n", + "example": 390, + "start_line": 6692, + "end_line": 6696, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "**(**foo)\n", + "html": "<p>**(**foo)</p>\n", + "example": 391, + "start_line": 6705, + "end_line": 6709, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "*(**foo**)*\n", + "html": "<p><em>(<strong>foo</strong>)</em></p>\n", + "example": 392, + "start_line": 6715, + "end_line": 6719, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "**Gomphocarpus (*Gomphocarpus physocarpus*, syn.\n*Asclepias physocarpa*)**\n", + "html": "<p><strong>Gomphocarpus (<em>Gomphocarpus physocarpus</em>, syn.\n<em>Asclepias physocarpa</em>)</strong></p>\n", + "example": 393, + "start_line": 6722, + "end_line": 6728, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "**foo \"*bar*\" foo**\n", + "html": "<p><strong>foo "<em>bar</em>" foo</strong></p>\n", + "example": 394, + "start_line": 6731, + "end_line": 6735, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "**foo**bar\n", + "html": "<p><strong>foo</strong>bar</p>\n", + "example": 395, + "start_line": 6740, + "end_line": 6744, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "__foo bar __\n", + "html": "<p>__foo bar __</p>\n", + "example": 396, + "start_line": 6752, + "end_line": 6756, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "__(__foo)\n", + "html": "<p>__(__foo)</p>\n", + "example": 397, + "start_line": 6762, + "end_line": 6766, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "_(__foo__)_\n", + "html": "<p><em>(<strong>foo</strong>)</em></p>\n", + "example": 398, + "start_line": 6772, + "end_line": 6776, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "__foo__bar\n", + "html": "<p>__foo__bar</p>\n", + "example": 399, + "start_line": 6781, + "end_line": 6785, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "__пристаням__стремятся\n", + "html": "<p>__пристаням__стремятся</p>\n", + "example": 400, + "start_line": 6788, + "end_line": 6792, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "__foo__bar__baz__\n", + "html": "<p><strong>foo__bar__baz</strong></p>\n", + "example": 401, + "start_line": 6795, + "end_line": 6799, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "__(bar)__.\n", + "html": "<p><strong>(bar)</strong>.</p>\n", + "example": 402, + "start_line": 6806, + "end_line": 6810, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "*foo [bar](/url)*\n", + "html": "<p><em>foo <a href=\"/url\">bar</a></em></p>\n", + "example": 403, + "start_line": 6818, + "end_line": 6822, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "*foo\nbar*\n", + "html": "<p><em>foo\nbar</em></p>\n", + "example": 404, + "start_line": 6825, + "end_line": 6831, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "_foo __bar__ baz_\n", + "html": "<p><em>foo <strong>bar</strong> baz</em></p>\n", + "example": 405, + "start_line": 6837, + "end_line": 6841, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "_foo _bar_ baz_\n", + "html": "<p><em>foo <em>bar</em> baz</em></p>\n", + "example": 406, + "start_line": 6844, + "end_line": 6848, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "__foo_ bar_\n", + "html": "<p><em><em>foo</em> bar</em></p>\n", + "example": 407, + "start_line": 6851, + "end_line": 6855, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "*foo *bar**\n", + "html": "<p><em>foo <em>bar</em></em></p>\n", + "example": 408, + "start_line": 6858, + "end_line": 6862, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "*foo **bar** baz*\n", + "html": "<p><em>foo <strong>bar</strong> baz</em></p>\n", + "example": 409, + "start_line": 6865, + "end_line": 6869, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "*foo**bar**baz*\n", + "html": "<p><em>foo<strong>bar</strong>baz</em></p>\n", + "example": 410, + "start_line": 6871, + "end_line": 6875, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "*foo**bar*\n", + "html": "<p><em>foo**bar</em></p>\n", + "example": 411, + "start_line": 6895, + "end_line": 6899, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "***foo** bar*\n", + "html": "<p><em><strong>foo</strong> bar</em></p>\n", + "example": 412, + "start_line": 6908, + "end_line": 6912, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "*foo **bar***\n", + "html": "<p><em>foo <strong>bar</strong></em></p>\n", + "example": 413, + "start_line": 6915, + "end_line": 6919, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "*foo**bar***\n", + "html": "<p><em>foo<strong>bar</strong></em></p>\n", + "example": 414, + "start_line": 6922, + "end_line": 6926, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "foo***bar***baz\n", + "html": "<p>foo<em><strong>bar</strong></em>baz</p>\n", + "example": 415, + "start_line": 6933, + "end_line": 6937, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "foo******bar*********baz\n", + "html": "<p>foo<strong><strong><strong>bar</strong></strong></strong>***baz</p>\n", + "example": 416, + "start_line": 6939, + "end_line": 6943, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "*foo **bar *baz* bim** bop*\n", + "html": "<p><em>foo <strong>bar <em>baz</em> bim</strong> bop</em></p>\n", + "example": 417, + "start_line": 6948, + "end_line": 6952, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "*foo [*bar*](/url)*\n", + "html": "<p><em>foo <a href=\"/url\"><em>bar</em></a></em></p>\n", + "example": 418, + "start_line": 6955, + "end_line": 6959, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "** is not an empty emphasis\n", + "html": "<p>** is not an empty emphasis</p>\n", + "example": 419, + "start_line": 6964, + "end_line": 6968, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "**** is not an empty strong emphasis\n", + "html": "<p>**** is not an empty strong emphasis</p>\n", + "example": 420, + "start_line": 6971, + "end_line": 6975, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "**foo [bar](/url)**\n", + "html": "<p><strong>foo <a href=\"/url\">bar</a></strong></p>\n", + "example": 421, + "start_line": 6984, + "end_line": 6988, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "**foo\nbar**\n", + "html": "<p><strong>foo\nbar</strong></p>\n", + "example": 422, + "start_line": 6991, + "end_line": 6997, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "__foo _bar_ baz__\n", + "html": "<p><strong>foo <em>bar</em> baz</strong></p>\n", + "example": 423, + "start_line": 7003, + "end_line": 7007, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "__foo __bar__ baz__\n", + "html": "<p><strong>foo <strong>bar</strong> baz</strong></p>\n", + "example": 424, + "start_line": 7010, + "end_line": 7014, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "____foo__ bar__\n", + "html": "<p><strong><strong>foo</strong> bar</strong></p>\n", + "example": 425, + "start_line": 7017, + "end_line": 7021, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "**foo **bar****\n", + "html": "<p><strong>foo <strong>bar</strong></strong></p>\n", + "example": 426, + "start_line": 7024, + "end_line": 7028, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "**foo *bar* baz**\n", + "html": "<p><strong>foo <em>bar</em> baz</strong></p>\n", + "example": 427, + "start_line": 7031, + "end_line": 7035, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "**foo*bar*baz**\n", + "html": "<p><strong>foo<em>bar</em>baz</strong></p>\n", + "example": 428, + "start_line": 7038, + "end_line": 7042, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "***foo* bar**\n", + "html": "<p><strong><em>foo</em> bar</strong></p>\n", + "example": 429, + "start_line": 7045, + "end_line": 7049, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "**foo *bar***\n", + "html": "<p><strong>foo <em>bar</em></strong></p>\n", + "example": 430, + "start_line": 7052, + "end_line": 7056, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "**foo *bar **baz**\nbim* bop**\n", + "html": "<p><strong>foo <em>bar <strong>baz</strong>\nbim</em> bop</strong></p>\n", + "example": 431, + "start_line": 7061, + "end_line": 7067, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "**foo [*bar*](/url)**\n", + "html": "<p><strong>foo <a href=\"/url\"><em>bar</em></a></strong></p>\n", + "example": 432, + "start_line": 7070, + "end_line": 7074, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "__ is not an empty emphasis\n", + "html": "<p>__ is not an empty emphasis</p>\n", + "example": 433, + "start_line": 7079, + "end_line": 7083, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "____ is not an empty strong emphasis\n", + "html": "<p>____ is not an empty strong emphasis</p>\n", + "example": 434, + "start_line": 7086, + "end_line": 7090, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "foo ***\n", + "html": "<p>foo ***</p>\n", + "example": 435, + "start_line": 7096, + "end_line": 7100, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "foo *\\**\n", + "html": "<p>foo <em>*</em></p>\n", + "example": 436, + "start_line": 7103, + "end_line": 7107, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "foo *_*\n", + "html": "<p>foo <em>_</em></p>\n", + "example": 437, + "start_line": 7110, + "end_line": 7114, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "foo *****\n", + "html": "<p>foo *****</p>\n", + "example": 438, + "start_line": 7117, + "end_line": 7121, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "foo **\\***\n", + "html": "<p>foo <strong>*</strong></p>\n", + "example": 439, + "start_line": 7124, + "end_line": 7128, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "foo **_**\n", + "html": "<p>foo <strong>_</strong></p>\n", + "example": 440, + "start_line": 7131, + "end_line": 7135, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "**foo*\n", + "html": "<p>*<em>foo</em></p>\n", + "example": 441, + "start_line": 7142, + "end_line": 7146, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "*foo**\n", + "html": "<p><em>foo</em>*</p>\n", + "example": 442, + "start_line": 7149, + "end_line": 7153, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "***foo**\n", + "html": "<p>*<strong>foo</strong></p>\n", + "example": 443, + "start_line": 7156, + "end_line": 7160, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "****foo*\n", + "html": "<p>***<em>foo</em></p>\n", + "example": 444, + "start_line": 7163, + "end_line": 7167, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "**foo***\n", + "html": "<p><strong>foo</strong>*</p>\n", + "example": 445, + "start_line": 7170, + "end_line": 7174, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "*foo****\n", + "html": "<p><em>foo</em>***</p>\n", + "example": 446, + "start_line": 7177, + "end_line": 7181, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "foo ___\n", + "html": "<p>foo ___</p>\n", + "example": 447, + "start_line": 7187, + "end_line": 7191, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "foo _\\__\n", + "html": "<p>foo <em>_</em></p>\n", + "example": 448, + "start_line": 7194, + "end_line": 7198, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "foo _*_\n", + "html": "<p>foo <em>*</em></p>\n", + "example": 449, + "start_line": 7201, + "end_line": 7205, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "foo _____\n", + "html": "<p>foo _____</p>\n", + "example": 450, + "start_line": 7208, + "end_line": 7212, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "foo __\\___\n", + "html": "<p>foo <strong>_</strong></p>\n", + "example": 451, + "start_line": 7215, + "end_line": 7219, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "foo __*__\n", + "html": "<p>foo <strong>*</strong></p>\n", + "example": 452, + "start_line": 7222, + "end_line": 7226, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "__foo_\n", + "html": "<p>_<em>foo</em></p>\n", + "example": 453, + "start_line": 7229, + "end_line": 7233, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "_foo__\n", + "html": "<p><em>foo</em>_</p>\n", + "example": 454, + "start_line": 7240, + "end_line": 7244, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "___foo__\n", + "html": "<p>_<strong>foo</strong></p>\n", + "example": 455, + "start_line": 7247, + "end_line": 7251, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "____foo_\n", + "html": "<p>___<em>foo</em></p>\n", + "example": 456, + "start_line": 7254, + "end_line": 7258, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "__foo___\n", + "html": "<p><strong>foo</strong>_</p>\n", + "example": 457, + "start_line": 7261, + "end_line": 7265, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "_foo____\n", + "html": "<p><em>foo</em>___</p>\n", + "example": 458, + "start_line": 7268, + "end_line": 7272, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "**foo**\n", + "html": "<p><strong>foo</strong></p>\n", + "example": 459, + "start_line": 7278, + "end_line": 7282, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "*_foo_*\n", + "html": "<p><em><em>foo</em></em></p>\n", + "example": 460, + "start_line": 7285, + "end_line": 7289, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "__foo__\n", + "html": "<p><strong>foo</strong></p>\n", + "example": 461, + "start_line": 7292, + "end_line": 7296, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "_*foo*_\n", + "html": "<p><em><em>foo</em></em></p>\n", + "example": 462, + "start_line": 7299, + "end_line": 7303, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "****foo****\n", + "html": "<p><strong><strong>foo</strong></strong></p>\n", + "example": 463, + "start_line": 7309, + "end_line": 7313, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "____foo____\n", + "html": "<p><strong><strong>foo</strong></strong></p>\n", + "example": 464, + "start_line": 7316, + "end_line": 7320, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "******foo******\n", + "html": "<p><strong><strong><strong>foo</strong></strong></strong></p>\n", + "example": 465, + "start_line": 7327, + "end_line": 7331, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "***foo***\n", + "html": "<p><em><strong>foo</strong></em></p>\n", + "example": 466, + "start_line": 7336, + "end_line": 7340, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "_____foo_____\n", + "html": "<p><em><strong><strong>foo</strong></strong></em></p>\n", + "example": 467, + "start_line": 7343, + "end_line": 7347, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "*foo _bar* baz_\n", + "html": "<p><em>foo _bar</em> baz_</p>\n", + "example": 468, + "start_line": 7352, + "end_line": 7356, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "*foo __bar *baz bim__ bam*\n", + "html": "<p><em>foo <strong>bar *baz bim</strong> bam</em></p>\n", + "example": 469, + "start_line": 7359, + "end_line": 7363, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "**foo **bar baz**\n", + "html": "<p>**foo <strong>bar baz</strong></p>\n", + "example": 470, + "start_line": 7368, + "end_line": 7372, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "*foo *bar baz*\n", + "html": "<p>*foo <em>bar baz</em></p>\n", + "example": 471, + "start_line": 7375, + "end_line": 7379, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "*[bar*](/url)\n", + "html": "<p>*<a href=\"/url\">bar*</a></p>\n", + "example": 472, + "start_line": 7384, + "end_line": 7388, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "_foo [bar_](/url)\n", + "html": "<p>_foo <a href=\"/url\">bar_</a></p>\n", + "example": 473, + "start_line": 7391, + "end_line": 7395, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "*<img src=\"foo\" title=\"*\"/>\n", + "html": "<p>*<img src=\"foo\" title=\"*\"/></p>\n", + "example": 474, + "start_line": 7398, + "end_line": 7402, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "**<a href=\"**\">\n", + "html": "<p>**<a href=\"**\"></p>\n", + "example": 475, + "start_line": 7405, + "end_line": 7409, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "__<a href=\"__\">\n", + "html": "<p>__<a href=\"__\"></p>\n", + "example": 476, + "start_line": 7412, + "end_line": 7416, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "*a `*`*\n", + "html": "<p><em>a <code>*</code></em></p>\n", + "example": 477, + "start_line": 7419, + "end_line": 7423, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "_a `_`_\n", + "html": "<p><em>a <code>_</code></em></p>\n", + "example": 478, + "start_line": 7426, + "end_line": 7430, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "**a<http://foo.bar/?q=**>\n", + "html": "<p>**a<a href=\"http://foo.bar/?q=**\">http://foo.bar/?q=**</a></p>\n", + "example": 479, + "start_line": 7433, + "end_line": 7437, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "__a<http://foo.bar/?q=__>\n", + "html": "<p>__a<a href=\"http://foo.bar/?q=__\">http://foo.bar/?q=__</a></p>\n", + "example": 480, + "start_line": 7440, + "end_line": 7444, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "[link](/uri \"title\")\n", + "html": "<p><a href=\"/uri\" title=\"title\">link</a></p>\n", + "example": 481, + "start_line": 7528, + "end_line": 7532, + "section": "Links" + }, + { + "markdown": "[link](/uri)\n", + "html": "<p><a href=\"/uri\">link</a></p>\n", + "example": 482, + "start_line": 7538, + "end_line": 7542, + "section": "Links" + }, + { + "markdown": "[](./target.md)\n", + "html": "<p><a href=\"./target.md\"></a></p>\n", + "example": 483, + "start_line": 7544, + "end_line": 7548, + "section": "Links" + }, + { + "markdown": "[link]()\n", + "html": "<p><a href=\"\">link</a></p>\n", + "example": 484, + "start_line": 7551, + "end_line": 7555, + "section": "Links" + }, + { + "markdown": "[link](<>)\n", + "html": "<p><a href=\"\">link</a></p>\n", + "example": 485, + "start_line": 7558, + "end_line": 7562, + "section": "Links" + }, + { + "markdown": "[]()\n", + "html": "<p><a href=\"\"></a></p>\n", + "example": 486, + "start_line": 7565, + "end_line": 7569, + "section": "Links" + }, + { + "markdown": "[link](/my uri)\n", + "html": "<p>[link](/my uri)</p>\n", + "example": 487, + "start_line": 7574, + "end_line": 7578, + "section": "Links" + }, + { + "markdown": "[link](</my uri>)\n", + "html": "<p><a href=\"/my%20uri\">link</a></p>\n", + "example": 488, + "start_line": 7580, + "end_line": 7584, + "section": "Links" + }, + { + "markdown": "[link](foo\nbar)\n", + "html": "<p>[link](foo\nbar)</p>\n", + "example": 489, + "start_line": 7589, + "end_line": 7595, + "section": "Links" + }, + { + "markdown": "[link](<foo\nbar>)\n", + "html": "<p>[link](<foo\nbar>)</p>\n", + "example": 490, + "start_line": 7597, + "end_line": 7603, + "section": "Links" + }, + { + "markdown": "[a](<b)c>)\n", + "html": "<p><a href=\"b)c\">a</a></p>\n", + "example": 491, + "start_line": 7608, + "end_line": 7612, + "section": "Links" + }, + { + "markdown": "[link](<foo\\>)\n", + "html": "<p>[link](<foo>)</p>\n", + "example": 492, + "start_line": 7616, + "end_line": 7620, + "section": "Links" + }, + { + "markdown": "[a](<b)c\n[a](<b)c>\n[a](<b>c)\n", + "html": "<p>[a](<b)c\n[a](<b)c>\n[a](<b>c)</p>\n", + "example": 493, + "start_line": 7625, + "end_line": 7633, + "section": "Links" + }, + { + "markdown": "[link](\\(foo\\))\n", + "html": "<p><a href=\"(foo)\">link</a></p>\n", + "example": 494, + "start_line": 7637, + "end_line": 7641, + "section": "Links" + }, + { + "markdown": "[link](foo(and(bar)))\n", + "html": "<p><a href=\"foo(and(bar))\">link</a></p>\n", + "example": 495, + "start_line": 7646, + "end_line": 7650, + "section": "Links" + }, + { + "markdown": "[link](foo(and(bar))\n", + "html": "<p>[link](foo(and(bar))</p>\n", + "example": 496, + "start_line": 7655, + "end_line": 7659, + "section": "Links" + }, + { + "markdown": "[link](foo\\(and\\(bar\\))\n", + "html": "<p><a href=\"foo(and(bar)\">link</a></p>\n", + "example": 497, + "start_line": 7662, + "end_line": 7666, + "section": "Links" + }, + { + "markdown": "[link](<foo(and(bar)>)\n", + "html": "<p><a href=\"foo(and(bar)\">link</a></p>\n", + "example": 498, + "start_line": 7669, + "end_line": 7673, + "section": "Links" + }, + { + "markdown": "[link](foo\\)\\:)\n", + "html": "<p><a href=\"foo):\">link</a></p>\n", + "example": 499, + "start_line": 7679, + "end_line": 7683, + "section": "Links" + }, + { + "markdown": "[link](#fragment)\n\n[link](http://example.com#fragment)\n\n[link](http://example.com?foo=3#frag)\n", + "html": "<p><a href=\"#fragment\">link</a></p>\n<p><a href=\"http://example.com#fragment\">link</a></p>\n<p><a href=\"http://example.com?foo=3#frag\">link</a></p>\n", + "example": 500, + "start_line": 7688, + "end_line": 7698, + "section": "Links" + }, + { + "markdown": "[link](foo\\bar)\n", + "html": "<p><a href=\"foo%5Cbar\">link</a></p>\n", + "example": 501, + "start_line": 7704, + "end_line": 7708, + "section": "Links" + }, + { + "markdown": "[link](foo%20bä)\n", + "html": "<p><a href=\"foo%20b%C3%A4\">link</a></p>\n", + "example": 502, + "start_line": 7720, + "end_line": 7724, + "section": "Links" + }, + { + "markdown": "[link](\"title\")\n", + "html": "<p><a href=\"%22title%22\">link</a></p>\n", + "example": 503, + "start_line": 7731, + "end_line": 7735, + "section": "Links" + }, + { + "markdown": "[link](/url \"title\")\n[link](/url 'title')\n[link](/url (title))\n", + "html": "<p><a href=\"/url\" title=\"title\">link</a>\n<a href=\"/url\" title=\"title\">link</a>\n<a href=\"/url\" title=\"title\">link</a></p>\n", + "example": 504, + "start_line": 7740, + "end_line": 7748, + "section": "Links" + }, + { + "markdown": "[link](/url \"title \\\""\")\n", + "html": "<p><a href=\"/url\" title=\"title ""\">link</a></p>\n", + "example": 505, + "start_line": 7754, + "end_line": 7758, + "section": "Links" + }, + { + "markdown": "[link](/url \"title\")\n", + "html": "<p><a href=\"/url%C2%A0%22title%22\">link</a></p>\n", + "example": 506, + "start_line": 7765, + "end_line": 7769, + "section": "Links" + }, + { + "markdown": "[link](/url \"title \"and\" title\")\n", + "html": "<p>[link](/url "title "and" title")</p>\n", + "example": 507, + "start_line": 7774, + "end_line": 7778, + "section": "Links" + }, + { + "markdown": "[link](/url 'title \"and\" title')\n", + "html": "<p><a href=\"/url\" title=\"title "and" title\">link</a></p>\n", + "example": 508, + "start_line": 7783, + "end_line": 7787, + "section": "Links" + }, + { + "markdown": "[link]( /uri\n \"title\" )\n", + "html": "<p><a href=\"/uri\" title=\"title\">link</a></p>\n", + "example": 509, + "start_line": 7808, + "end_line": 7813, + "section": "Links" + }, + { + "markdown": "[link] (/uri)\n", + "html": "<p>[link] (/uri)</p>\n", + "example": 510, + "start_line": 7819, + "end_line": 7823, + "section": "Links" + }, + { + "markdown": "[link [foo [bar]]](/uri)\n", + "html": "<p><a href=\"/uri\">link [foo [bar]]</a></p>\n", + "example": 511, + "start_line": 7829, + "end_line": 7833, + "section": "Links" + }, + { + "markdown": "[link] bar](/uri)\n", + "html": "<p>[link] bar](/uri)</p>\n", + "example": 512, + "start_line": 7836, + "end_line": 7840, + "section": "Links" + }, + { + "markdown": "[link [bar](/uri)\n", + "html": "<p>[link <a href=\"/uri\">bar</a></p>\n", + "example": 513, + "start_line": 7843, + "end_line": 7847, + "section": "Links" + }, + { + "markdown": "[link \\[bar](/uri)\n", + "html": "<p><a href=\"/uri\">link [bar</a></p>\n", + "example": 514, + "start_line": 7850, + "end_line": 7854, + "section": "Links" + }, + { + "markdown": "[link *foo **bar** `#`*](/uri)\n", + "html": "<p><a href=\"/uri\">link <em>foo <strong>bar</strong> <code>#</code></em></a></p>\n", + "example": 515, + "start_line": 7859, + "end_line": 7863, + "section": "Links" + }, + { + "markdown": "[![moon](moon.jpg)](/uri)\n", + "html": "<p><a href=\"/uri\"><img src=\"moon.jpg\" alt=\"moon\" /></a></p>\n", + "example": 516, + "start_line": 7866, + "end_line": 7870, + "section": "Links" + }, + { + "markdown": "[foo [bar](/uri)](/uri)\n", + "html": "<p>[foo <a href=\"/uri\">bar</a>](/uri)</p>\n", + "example": 517, + "start_line": 7875, + "end_line": 7879, + "section": "Links" + }, + { + "markdown": "[foo *[bar [baz](/uri)](/uri)*](/uri)\n", + "html": "<p>[foo <em>[bar <a href=\"/uri\">baz</a>](/uri)</em>](/uri)</p>\n", + "example": 518, + "start_line": 7882, + "end_line": 7886, + "section": "Links" + }, + { + "markdown": "![[[foo](uri1)](uri2)](uri3)\n", + "html": "<p><img src=\"uri3\" alt=\"[foo](uri2)\" /></p>\n", + "example": 519, + "start_line": 7889, + "end_line": 7893, + "section": "Links" + }, + { + "markdown": "*[foo*](/uri)\n", + "html": "<p>*<a href=\"/uri\">foo*</a></p>\n", + "example": 520, + "start_line": 7899, + "end_line": 7903, + "section": "Links" + }, + { + "markdown": "[foo *bar](baz*)\n", + "html": "<p><a href=\"baz*\">foo *bar</a></p>\n", + "example": 521, + "start_line": 7906, + "end_line": 7910, + "section": "Links" + }, + { + "markdown": "*foo [bar* baz]\n", + "html": "<p><em>foo [bar</em> baz]</p>\n", + "example": 522, + "start_line": 7916, + "end_line": 7920, + "section": "Links" + }, + { + "markdown": "[foo <bar attr=\"](baz)\">\n", + "html": "<p>[foo <bar attr=\"](baz)\"></p>\n", + "example": 523, + "start_line": 7926, + "end_line": 7930, + "section": "Links" + }, + { + "markdown": "[foo`](/uri)`\n", + "html": "<p>[foo<code>](/uri)</code></p>\n", + "example": 524, + "start_line": 7933, + "end_line": 7937, + "section": "Links" + }, + { + "markdown": "[foo<http://example.com/?search=](uri)>\n", + "html": "<p>[foo<a href=\"http://example.com/?search=%5D(uri)\">http://example.com/?search=](uri)</a></p>\n", + "example": 525, + "start_line": 7940, + "end_line": 7944, + "section": "Links" + }, + { + "markdown": "[foo][bar]\n\n[bar]: /url \"title\"\n", + "html": "<p><a href=\"/url\" title=\"title\">foo</a></p>\n", + "example": 526, + "start_line": 7978, + "end_line": 7984, + "section": "Links" + }, + { + "markdown": "[link [foo [bar]]][ref]\n\n[ref]: /uri\n", + "html": "<p><a href=\"/uri\">link [foo [bar]]</a></p>\n", + "example": 527, + "start_line": 7993, + "end_line": 7999, + "section": "Links" + }, + { + "markdown": "[link \\[bar][ref]\n\n[ref]: /uri\n", + "html": "<p><a href=\"/uri\">link [bar</a></p>\n", + "example": 528, + "start_line": 8002, + "end_line": 8008, + "section": "Links" + }, + { + "markdown": "[link *foo **bar** `#`*][ref]\n\n[ref]: /uri\n", + "html": "<p><a href=\"/uri\">link <em>foo <strong>bar</strong> <code>#</code></em></a></p>\n", + "example": 529, + "start_line": 8013, + "end_line": 8019, + "section": "Links" + }, + { + "markdown": "[![moon](moon.jpg)][ref]\n\n[ref]: /uri\n", + "html": "<p><a href=\"/uri\"><img src=\"moon.jpg\" alt=\"moon\" /></a></p>\n", + "example": 530, + "start_line": 8022, + "end_line": 8028, + "section": "Links" + }, + { + "markdown": "[foo [bar](/uri)][ref]\n\n[ref]: /uri\n", + "html": "<p>[foo <a href=\"/uri\">bar</a>]<a href=\"/uri\">ref</a></p>\n", + "example": 531, + "start_line": 8033, + "end_line": 8039, + "section": "Links" + }, + { + "markdown": "[foo *bar [baz][ref]*][ref]\n\n[ref]: /uri\n", + "html": "<p>[foo <em>bar <a href=\"/uri\">baz</a></em>]<a href=\"/uri\">ref</a></p>\n", + "example": 532, + "start_line": 8042, + "end_line": 8048, + "section": "Links" + }, + { + "markdown": "*[foo*][ref]\n\n[ref]: /uri\n", + "html": "<p>*<a href=\"/uri\">foo*</a></p>\n", + "example": 533, + "start_line": 8057, + "end_line": 8063, + "section": "Links" + }, + { + "markdown": "[foo *bar][ref]*\n\n[ref]: /uri\n", + "html": "<p><a href=\"/uri\">foo *bar</a>*</p>\n", + "example": 534, + "start_line": 8066, + "end_line": 8072, + "section": "Links" + }, + { + "markdown": "[foo <bar attr=\"][ref]\">\n\n[ref]: /uri\n", + "html": "<p>[foo <bar attr=\"][ref]\"></p>\n", + "example": 535, + "start_line": 8078, + "end_line": 8084, + "section": "Links" + }, + { + "markdown": "[foo`][ref]`\n\n[ref]: /uri\n", + "html": "<p>[foo<code>][ref]</code></p>\n", + "example": 536, + "start_line": 8087, + "end_line": 8093, + "section": "Links" + }, + { + "markdown": "[foo<http://example.com/?search=][ref]>\n\n[ref]: /uri\n", + "html": "<p>[foo<a href=\"http://example.com/?search=%5D%5Bref%5D\">http://example.com/?search=][ref]</a></p>\n", + "example": 537, + "start_line": 8096, + "end_line": 8102, + "section": "Links" + }, + { + "markdown": "[foo][BaR]\n\n[bar]: /url \"title\"\n", + "html": "<p><a href=\"/url\" title=\"title\">foo</a></p>\n", + "example": 538, + "start_line": 8107, + "end_line": 8113, + "section": "Links" + }, + { + "markdown": "[ẞ]\n\n[SS]: /url\n", + "html": "<p><a href=\"/url\">ẞ</a></p>\n", + "example": 539, + "start_line": 8118, + "end_line": 8124, + "section": "Links" + }, + { + "markdown": "[Foo\n bar]: /url\n\n[Baz][Foo bar]\n", + "html": "<p><a href=\"/url\">Baz</a></p>\n", + "example": 540, + "start_line": 8130, + "end_line": 8137, + "section": "Links" + }, + { + "markdown": "[foo] [bar]\n\n[bar]: /url \"title\"\n", + "html": "<p>[foo] <a href=\"/url\" title=\"title\">bar</a></p>\n", + "example": 541, + "start_line": 8143, + "end_line": 8149, + "section": "Links" + }, + { + "markdown": "[foo]\n[bar]\n\n[bar]: /url \"title\"\n", + "html": "<p>[foo]\n<a href=\"/url\" title=\"title\">bar</a></p>\n", + "example": 542, + "start_line": 8152, + "end_line": 8160, + "section": "Links" + }, + { + "markdown": "[foo]: /url1\n\n[foo]: /url2\n\n[bar][foo]\n", + "html": "<p><a href=\"/url1\">bar</a></p>\n", + "example": 543, + "start_line": 8193, + "end_line": 8201, + "section": "Links" + }, + { + "markdown": "[bar][foo\\!]\n\n[foo!]: /url\n", + "html": "<p>[bar][foo!]</p>\n", + "example": 544, + "start_line": 8208, + "end_line": 8214, + "section": "Links" + }, + { + "markdown": "[foo][ref[]\n\n[ref[]: /uri\n", + "html": "<p>[foo][ref[]</p>\n<p>[ref[]: /uri</p>\n", + "example": 545, + "start_line": 8220, + "end_line": 8227, + "section": "Links" + }, + { + "markdown": "[foo][ref[bar]]\n\n[ref[bar]]: /uri\n", + "html": "<p>[foo][ref[bar]]</p>\n<p>[ref[bar]]: /uri</p>\n", + "example": 546, + "start_line": 8230, + "end_line": 8237, + "section": "Links" + }, + { + "markdown": "[[[foo]]]\n\n[[[foo]]]: /url\n", + "html": "<p>[[[foo]]]</p>\n<p>[[[foo]]]: /url</p>\n", + "example": 547, + "start_line": 8240, + "end_line": 8247, + "section": "Links" + }, + { + "markdown": "[foo][ref\\[]\n\n[ref\\[]: /uri\n", + "html": "<p><a href=\"/uri\">foo</a></p>\n", + "example": 548, + "start_line": 8250, + "end_line": 8256, + "section": "Links" + }, + { + "markdown": "[bar\\\\]: /uri\n\n[bar\\\\]\n", + "html": "<p><a href=\"/uri\">bar\\</a></p>\n", + "example": 549, + "start_line": 8261, + "end_line": 8267, + "section": "Links" + }, + { + "markdown": "[]\n\n[]: /uri\n", + "html": "<p>[]</p>\n<p>[]: /uri</p>\n", + "example": 550, + "start_line": 8273, + "end_line": 8280, + "section": "Links" + }, + { + "markdown": "[\n ]\n\n[\n ]: /uri\n", + "html": "<p>[\n]</p>\n<p>[\n]: /uri</p>\n", + "example": 551, + "start_line": 8283, + "end_line": 8294, + "section": "Links" + }, + { + "markdown": "[foo][]\n\n[foo]: /url \"title\"\n", + "html": "<p><a href=\"/url\" title=\"title\">foo</a></p>\n", + "example": 552, + "start_line": 8306, + "end_line": 8312, + "section": "Links" + }, + { + "markdown": "[*foo* bar][]\n\n[*foo* bar]: /url \"title\"\n", + "html": "<p><a href=\"/url\" title=\"title\"><em>foo</em> bar</a></p>\n", + "example": 553, + "start_line": 8315, + "end_line": 8321, + "section": "Links" + }, + { + "markdown": "[Foo][]\n\n[foo]: /url \"title\"\n", + "html": "<p><a href=\"/url\" title=\"title\">Foo</a></p>\n", + "example": 554, + "start_line": 8326, + "end_line": 8332, + "section": "Links" + }, + { + "markdown": "[foo] \n[]\n\n[foo]: /url \"title\"\n", + "html": "<p><a href=\"/url\" title=\"title\">foo</a>\n[]</p>\n", + "example": 555, + "start_line": 8339, + "end_line": 8347, + "section": "Links" + }, + { + "markdown": "[foo]\n\n[foo]: /url \"title\"\n", + "html": "<p><a href=\"/url\" title=\"title\">foo</a></p>\n", + "example": 556, + "start_line": 8359, + "end_line": 8365, + "section": "Links" + }, + { + "markdown": "[*foo* bar]\n\n[*foo* bar]: /url \"title\"\n", + "html": "<p><a href=\"/url\" title=\"title\"><em>foo</em> bar</a></p>\n", + "example": 557, + "start_line": 8368, + "end_line": 8374, + "section": "Links" + }, + { + "markdown": "[[*foo* bar]]\n\n[*foo* bar]: /url \"title\"\n", + "html": "<p>[<a href=\"/url\" title=\"title\"><em>foo</em> bar</a>]</p>\n", + "example": 558, + "start_line": 8377, + "end_line": 8383, + "section": "Links" + }, + { + "markdown": "[[bar [foo]\n\n[foo]: /url\n", + "html": "<p>[[bar <a href=\"/url\">foo</a></p>\n", + "example": 559, + "start_line": 8386, + "end_line": 8392, + "section": "Links" + }, + { + "markdown": "[Foo]\n\n[foo]: /url \"title\"\n", + "html": "<p><a href=\"/url\" title=\"title\">Foo</a></p>\n", + "example": 560, + "start_line": 8397, + "end_line": 8403, + "section": "Links" + }, + { + "markdown": "[foo] bar\n\n[foo]: /url\n", + "html": "<p><a href=\"/url\">foo</a> bar</p>\n", + "example": 561, + "start_line": 8408, + "end_line": 8414, + "section": "Links" + }, + { + "markdown": "\\[foo]\n\n[foo]: /url \"title\"\n", + "html": "<p>[foo]</p>\n", + "example": 562, + "start_line": 8420, + "end_line": 8426, + "section": "Links" + }, + { + "markdown": "[foo*]: /url\n\n*[foo*]\n", + "html": "<p>*<a href=\"/url\">foo*</a></p>\n", + "example": 563, + "start_line": 8432, + "end_line": 8438, + "section": "Links" + }, + { + "markdown": "[foo][bar]\n\n[foo]: /url1\n[bar]: /url2\n", + "html": "<p><a href=\"/url2\">foo</a></p>\n", + "example": 564, + "start_line": 8444, + "end_line": 8451, + "section": "Links" + }, + { + "markdown": "[foo][]\n\n[foo]: /url1\n", + "html": "<p><a href=\"/url1\">foo</a></p>\n", + "example": 565, + "start_line": 8453, + "end_line": 8459, + "section": "Links" + }, + { + "markdown": "[foo]()\n\n[foo]: /url1\n", + "html": "<p><a href=\"\">foo</a></p>\n", + "example": 566, + "start_line": 8463, + "end_line": 8469, + "section": "Links" + }, + { + "markdown": "[foo](not a link)\n\n[foo]: /url1\n", + "html": "<p><a href=\"/url1\">foo</a>(not a link)</p>\n", + "example": 567, + "start_line": 8471, + "end_line": 8477, + "section": "Links" + }, + { + "markdown": "[foo][bar][baz]\n\n[baz]: /url\n", + "html": "<p>[foo]<a href=\"/url\">bar</a></p>\n", + "example": 568, + "start_line": 8482, + "end_line": 8488, + "section": "Links" + }, + { + "markdown": "[foo][bar][baz]\n\n[baz]: /url1\n[bar]: /url2\n", + "html": "<p><a href=\"/url2\">foo</a><a href=\"/url1\">baz</a></p>\n", + "example": 569, + "start_line": 8494, + "end_line": 8501, + "section": "Links" + }, + { + "markdown": "[foo][bar][baz]\n\n[baz]: /url1\n[foo]: /url2\n", + "html": "<p>[foo]<a href=\"/url1\">bar</a></p>\n", + "example": 570, + "start_line": 8507, + "end_line": 8514, + "section": "Links" + }, + { + "markdown": "![foo](/url \"title\")\n", + "html": "<p><img src=\"/url\" alt=\"foo\" title=\"title\" /></p>\n", + "example": 571, + "start_line": 8530, + "end_line": 8534, + "section": "Images" + }, + { + "markdown": "![foo *bar*]\n\n[foo *bar*]: train.jpg \"train & tracks\"\n", + "html": "<p><img src=\"train.jpg\" alt=\"foo bar\" title=\"train & tracks\" /></p>\n", + "example": 572, + "start_line": 8537, + "end_line": 8543, + "section": "Images" + }, + { + "markdown": "![foo ![bar](/url)](/url2)\n", + "html": "<p><img src=\"/url2\" alt=\"foo bar\" /></p>\n", + "example": 573, + "start_line": 8546, + "end_line": 8550, + "section": "Images" + }, + { + "markdown": "![foo [bar](/url)](/url2)\n", + "html": "<p><img src=\"/url2\" alt=\"foo bar\" /></p>\n", + "example": 574, + "start_line": 8553, + "end_line": 8557, + "section": "Images" + }, + { + "markdown": "![foo *bar*][]\n\n[foo *bar*]: train.jpg \"train & tracks\"\n", + "html": "<p><img src=\"train.jpg\" alt=\"foo bar\" title=\"train & tracks\" /></p>\n", + "example": 575, + "start_line": 8567, + "end_line": 8573, + "section": "Images" + }, + { + "markdown": "![foo *bar*][foobar]\n\n[FOOBAR]: train.jpg \"train & tracks\"\n", + "html": "<p><img src=\"train.jpg\" alt=\"foo bar\" title=\"train & tracks\" /></p>\n", + "example": 576, + "start_line": 8576, + "end_line": 8582, + "section": "Images" + }, + { + "markdown": "![foo](train.jpg)\n", + "html": "<p><img src=\"train.jpg\" alt=\"foo\" /></p>\n", + "example": 577, + "start_line": 8585, + "end_line": 8589, + "section": "Images" + }, + { + "markdown": "My ![foo bar](/path/to/train.jpg \"title\" )\n", + "html": "<p>My <img src=\"/path/to/train.jpg\" alt=\"foo bar\" title=\"title\" /></p>\n", + "example": 578, + "start_line": 8592, + "end_line": 8596, + "section": "Images" + }, + { + "markdown": "![foo](<url>)\n", + "html": "<p><img src=\"url\" alt=\"foo\" /></p>\n", + "example": 579, + "start_line": 8599, + "end_line": 8603, + "section": "Images" + }, + { + "markdown": "![](/url)\n", + "html": "<p><img src=\"/url\" alt=\"\" /></p>\n", + "example": 580, + "start_line": 8606, + "end_line": 8610, + "section": "Images" + }, + { + "markdown": "![foo][bar]\n\n[bar]: /url\n", + "html": "<p><img src=\"/url\" alt=\"foo\" /></p>\n", + "example": 581, + "start_line": 8615, + "end_line": 8621, + "section": "Images" + }, + { + "markdown": "![foo][bar]\n\n[BAR]: /url\n", + "html": "<p><img src=\"/url\" alt=\"foo\" /></p>\n", + "example": 582, + "start_line": 8624, + "end_line": 8630, + "section": "Images" + }, + { + "markdown": "![foo][]\n\n[foo]: /url \"title\"\n", + "html": "<p><img src=\"/url\" alt=\"foo\" title=\"title\" /></p>\n", + "example": 583, + "start_line": 8635, + "end_line": 8641, + "section": "Images" + }, + { + "markdown": "![*foo* bar][]\n\n[*foo* bar]: /url \"title\"\n", + "html": "<p><img src=\"/url\" alt=\"foo bar\" title=\"title\" /></p>\n", + "example": 584, + "start_line": 8644, + "end_line": 8650, + "section": "Images" + }, + { + "markdown": "![Foo][]\n\n[foo]: /url \"title\"\n", + "html": "<p><img src=\"/url\" alt=\"Foo\" title=\"title\" /></p>\n", + "example": 585, + "start_line": 8655, + "end_line": 8661, + "section": "Images" + }, + { + "markdown": "![foo] \n[]\n\n[foo]: /url \"title\"\n", + "html": "<p><img src=\"/url\" alt=\"foo\" title=\"title\" />\n[]</p>\n", + "example": 586, + "start_line": 8667, + "end_line": 8675, + "section": "Images" + }, + { + "markdown": "![foo]\n\n[foo]: /url \"title\"\n", + "html": "<p><img src=\"/url\" alt=\"foo\" title=\"title\" /></p>\n", + "example": 587, + "start_line": 8680, + "end_line": 8686, + "section": "Images" + }, + { + "markdown": "![*foo* bar]\n\n[*foo* bar]: /url \"title\"\n", + "html": "<p><img src=\"/url\" alt=\"foo bar\" title=\"title\" /></p>\n", + "example": 588, + "start_line": 8689, + "end_line": 8695, + "section": "Images" + }, + { + "markdown": "![[foo]]\n\n[[foo]]: /url \"title\"\n", + "html": "<p>![[foo]]</p>\n<p>[[foo]]: /url "title"</p>\n", + "example": 589, + "start_line": 8700, + "end_line": 8707, + "section": "Images" + }, + { + "markdown": "![Foo]\n\n[foo]: /url \"title\"\n", + "html": "<p><img src=\"/url\" alt=\"Foo\" title=\"title\" /></p>\n", + "example": 590, + "start_line": 8712, + "end_line": 8718, + "section": "Images" + }, + { + "markdown": "!\\[foo]\n\n[foo]: /url \"title\"\n", + "html": "<p>![foo]</p>\n", + "example": 591, + "start_line": 8724, + "end_line": 8730, + "section": "Images" + }, + { + "markdown": "\\![foo]\n\n[foo]: /url \"title\"\n", + "html": "<p>!<a href=\"/url\" title=\"title\">foo</a></p>\n", + "example": 592, + "start_line": 8736, + "end_line": 8742, + "section": "Images" + }, + { + "markdown": "<http://foo.bar.baz>\n", + "html": "<p><a href=\"http://foo.bar.baz\">http://foo.bar.baz</a></p>\n", + "example": 593, + "start_line": 8769, + "end_line": 8773, + "section": "Autolinks" + }, + { + "markdown": "<http://foo.bar.baz/test?q=hello&id=22&boolean>\n", + "html": "<p><a href=\"http://foo.bar.baz/test?q=hello&id=22&boolean\">http://foo.bar.baz/test?q=hello&id=22&boolean</a></p>\n", + "example": 594, + "start_line": 8776, + "end_line": 8780, + "section": "Autolinks" + }, + { + "markdown": "<irc://foo.bar:2233/baz>\n", + "html": "<p><a href=\"irc://foo.bar:2233/baz\">irc://foo.bar:2233/baz</a></p>\n", + "example": 595, + "start_line": 8783, + "end_line": 8787, + "section": "Autolinks" + }, + { + "markdown": "<MAILTO:FOO@BAR.BAZ>\n", + "html": "<p><a href=\"MAILTO:FOO@BAR.BAZ\">MAILTO:FOO@BAR.BAZ</a></p>\n", + "example": 596, + "start_line": 8792, + "end_line": 8796, + "section": "Autolinks" + }, + { + "markdown": "<a+b+c:d>\n", + "html": "<p><a href=\"a+b+c:d\">a+b+c:d</a></p>\n", + "example": 597, + "start_line": 8804, + "end_line": 8808, + "section": "Autolinks" + }, + { + "markdown": "<made-up-scheme://foo,bar>\n", + "html": "<p><a href=\"made-up-scheme://foo,bar\">made-up-scheme://foo,bar</a></p>\n", + "example": 598, + "start_line": 8811, + "end_line": 8815, + "section": "Autolinks" + }, + { + "markdown": "<http://../>\n", + "html": "<p><a href=\"http://../\">http://../</a></p>\n", + "example": 599, + "start_line": 8818, + "end_line": 8822, + "section": "Autolinks" + }, + { + "markdown": "<localhost:5001/foo>\n", + "html": "<p><a href=\"localhost:5001/foo\">localhost:5001/foo</a></p>\n", + "example": 600, + "start_line": 8825, + "end_line": 8829, + "section": "Autolinks" + }, + { + "markdown": "<http://foo.bar/baz bim>\n", + "html": "<p><http://foo.bar/baz bim></p>\n", + "example": 601, + "start_line": 8834, + "end_line": 8838, + "section": "Autolinks" + }, + { + "markdown": "<http://example.com/\\[\\>\n", + "html": "<p><a href=\"http://example.com/%5C%5B%5C\">http://example.com/\\[\\</a></p>\n", + "example": 602, + "start_line": 8843, + "end_line": 8847, + "section": "Autolinks" + }, + { + "markdown": "<foo@bar.example.com>\n", + "html": "<p><a href=\"mailto:foo@bar.example.com\">foo@bar.example.com</a></p>\n", + "example": 603, + "start_line": 8865, + "end_line": 8869, + "section": "Autolinks" + }, + { + "markdown": "<foo+special@Bar.baz-bar0.com>\n", + "html": "<p><a href=\"mailto:foo+special@Bar.baz-bar0.com\">foo+special@Bar.baz-bar0.com</a></p>\n", + "example": 604, + "start_line": 8872, + "end_line": 8876, + "section": "Autolinks" + }, + { + "markdown": "<foo\\+@bar.example.com>\n", + "html": "<p><foo+@bar.example.com></p>\n", + "example": 605, + "start_line": 8881, + "end_line": 8885, + "section": "Autolinks" + }, + { + "markdown": "<>\n", + "html": "<p><></p>\n", + "example": 606, + "start_line": 8890, + "end_line": 8894, + "section": "Autolinks" + }, + { + "markdown": "< http://foo.bar >\n", + "html": "<p>< http://foo.bar ></p>\n", + "example": 607, + "start_line": 8897, + "end_line": 8901, + "section": "Autolinks" + }, + { + "markdown": "<m:abc>\n", + "html": "<p><m:abc></p>\n", + "example": 608, + "start_line": 8904, + "end_line": 8908, + "section": "Autolinks" + }, + { + "markdown": "<foo.bar.baz>\n", + "html": "<p><foo.bar.baz></p>\n", + "example": 609, + "start_line": 8911, + "end_line": 8915, + "section": "Autolinks" + }, + { + "markdown": "http://example.com\n", + "html": "<p>http://example.com</p>\n", + "example": 610, + "start_line": 8918, + "end_line": 8922, + "section": "Autolinks" + }, + { + "markdown": "foo@bar.example.com\n", + "html": "<p>foo@bar.example.com</p>\n", + "example": 611, + "start_line": 8925, + "end_line": 8929, + "section": "Autolinks" + }, + { + "markdown": "<a><bab><c2c>\n", + "html": "<p><a><bab><c2c></p>\n", + "example": 612, + "start_line": 9006, + "end_line": 9010, + "section": "Raw HTML" + }, + { + "markdown": "<a/><b2/>\n", + "html": "<p><a/><b2/></p>\n", + "example": 613, + "start_line": 9015, + "end_line": 9019, + "section": "Raw HTML" + }, + { + "markdown": "<a /><b2\ndata=\"foo\" >\n", + "html": "<p><a /><b2\ndata=\"foo\" ></p>\n", + "example": 614, + "start_line": 9024, + "end_line": 9030, + "section": "Raw HTML" + }, + { + "markdown": "<a foo=\"bar\" bam = 'baz <em>\"</em>'\n_boolean zoop:33=zoop:33 />\n", + "html": "<p><a foo=\"bar\" bam = 'baz <em>\"</em>'\n_boolean zoop:33=zoop:33 /></p>\n", + "example": 615, + "start_line": 9035, + "end_line": 9041, + "section": "Raw HTML" + }, + { + "markdown": "Foo <responsive-image src=\"foo.jpg\" />\n", + "html": "<p>Foo <responsive-image src=\"foo.jpg\" /></p>\n", + "example": 616, + "start_line": 9046, + "end_line": 9050, + "section": "Raw HTML" + }, + { + "markdown": "<33> <__>\n", + "html": "<p><33> <__></p>\n", + "example": 617, + "start_line": 9055, + "end_line": 9059, + "section": "Raw HTML" + }, + { + "markdown": "<a h*#ref=\"hi\">\n", + "html": "<p><a h*#ref="hi"></p>\n", + "example": 618, + "start_line": 9064, + "end_line": 9068, + "section": "Raw HTML" + }, + { + "markdown": "<a href=\"hi'> <a href=hi'>\n", + "html": "<p><a href="hi'> <a href=hi'></p>\n", + "example": 619, + "start_line": 9073, + "end_line": 9077, + "section": "Raw HTML" + }, + { + "markdown": "< a><\nfoo><bar/ >\n<foo bar=baz\nbim!bop />\n", + "html": "<p>< a><\nfoo><bar/ >\n<foo bar=baz\nbim!bop /></p>\n", + "example": 620, + "start_line": 9082, + "end_line": 9092, + "section": "Raw HTML" + }, + { + "markdown": "<a href='bar'title=title>\n", + "html": "<p><a href='bar'title=title></p>\n", + "example": 621, + "start_line": 9097, + "end_line": 9101, + "section": "Raw HTML" + }, + { + "markdown": "</a></foo >\n", + "html": "<p></a></foo ></p>\n", + "example": 622, + "start_line": 9106, + "end_line": 9110, + "section": "Raw HTML" + }, + { + "markdown": "</a href=\"foo\">\n", + "html": "<p></a href="foo"></p>\n", + "example": 623, + "start_line": 9115, + "end_line": 9119, + "section": "Raw HTML" + }, + { + "markdown": "foo <!-- this is a\ncomment - with hyphen -->\n", + "html": "<p>foo <!-- this is a\ncomment - with hyphen --></p>\n", + "example": 624, + "start_line": 9124, + "end_line": 9130, + "section": "Raw HTML" + }, + { + "markdown": "foo <!-- not a comment -- two hyphens -->\n", + "html": "<p>foo <!-- not a comment -- two hyphens --></p>\n", + "example": 625, + "start_line": 9133, + "end_line": 9137, + "section": "Raw HTML" + }, + { + "markdown": "foo <!--> foo -->\n\nfoo <!-- foo--->\n", + "html": "<p>foo <!--> foo --></p>\n<p>foo <!-- foo---></p>\n", + "example": 626, + "start_line": 9142, + "end_line": 9149, + "section": "Raw HTML" + }, + { + "markdown": "foo <?php echo $a; ?>\n", + "html": "<p>foo <?php echo $a; ?></p>\n", + "example": 627, + "start_line": 9154, + "end_line": 9158, + "section": "Raw HTML" + }, + { + "markdown": "foo <!ELEMENT br EMPTY>\n", + "html": "<p>foo <!ELEMENT br EMPTY></p>\n", + "example": 628, + "start_line": 9163, + "end_line": 9167, + "section": "Raw HTML" + }, + { + "markdown": "foo <![CDATA[>&<]]>\n", + "html": "<p>foo <![CDATA[>&<]]></p>\n", + "example": 629, + "start_line": 9172, + "end_line": 9176, + "section": "Raw HTML" + }, + { + "markdown": "foo <a href=\"ö\">\n", + "html": "<p>foo <a href=\"ö\"></p>\n", + "example": 630, + "start_line": 9182, + "end_line": 9186, + "section": "Raw HTML" + }, + { + "markdown": "foo <a href=\"\\*\">\n", + "html": "<p>foo <a href=\"\\*\"></p>\n", + "example": 631, + "start_line": 9191, + "end_line": 9195, + "section": "Raw HTML" + }, + { + "markdown": "<a href=\"\\\"\">\n", + "html": "<p><a href="""></p>\n", + "example": 632, + "start_line": 9198, + "end_line": 9202, + "section": "Raw HTML" + }, + { + "markdown": "foo \nbaz\n", + "html": "<p>foo<br />\nbaz</p>\n", + "example": 633, + "start_line": 9212, + "end_line": 9218, + "section": "Hard line breaks" + }, + { + "markdown": "foo\\\nbaz\n", + "html": "<p>foo<br />\nbaz</p>\n", + "example": 634, + "start_line": 9224, + "end_line": 9230, + "section": "Hard line breaks" + }, + { + "markdown": "foo \nbaz\n", + "html": "<p>foo<br />\nbaz</p>\n", + "example": 635, + "start_line": 9235, + "end_line": 9241, + "section": "Hard line breaks" + }, + { + "markdown": "foo \n bar\n", + "html": "<p>foo<br />\nbar</p>\n", + "example": 636, + "start_line": 9246, + "end_line": 9252, + "section": "Hard line breaks" + }, + { + "markdown": "foo\\\n bar\n", + "html": "<p>foo<br />\nbar</p>\n", + "example": 637, + "start_line": 9255, + "end_line": 9261, + "section": "Hard line breaks" + }, + { + "markdown": "*foo \nbar*\n", + "html": "<p><em>foo<br />\nbar</em></p>\n", + "example": 638, + "start_line": 9267, + "end_line": 9273, + "section": "Hard line breaks" + }, + { + "markdown": "*foo\\\nbar*\n", + "html": "<p><em>foo<br />\nbar</em></p>\n", + "example": 639, + "start_line": 9276, + "end_line": 9282, + "section": "Hard line breaks" + }, + { + "markdown": "`code \nspan`\n", + "html": "<p><code>code span</code></p>\n", + "example": 640, + "start_line": 9287, + "end_line": 9292, + "section": "Hard line breaks" + }, + { + "markdown": "`code\\\nspan`\n", + "html": "<p><code>code\\ span</code></p>\n", + "example": 641, + "start_line": 9295, + "end_line": 9300, + "section": "Hard line breaks" + }, + { + "markdown": "<a href=\"foo \nbar\">\n", + "html": "<p><a href=\"foo \nbar\"></p>\n", + "example": 642, + "start_line": 9305, + "end_line": 9311, + "section": "Hard line breaks" + }, + { + "markdown": "<a href=\"foo\\\nbar\">\n", + "html": "<p><a href=\"foo\\\nbar\"></p>\n", + "example": 643, + "start_line": 9314, + "end_line": 9320, + "section": "Hard line breaks" + }, + { + "markdown": "foo\\\n", + "html": "<p>foo\\</p>\n", + "example": 644, + "start_line": 9327, + "end_line": 9331, + "section": "Hard line breaks" + }, + { + "markdown": "foo \n", + "html": "<p>foo</p>\n", + "example": 645, + "start_line": 9334, + "end_line": 9338, + "section": "Hard line breaks" + }, + { + "markdown": "### foo\\\n", + "html": "<h3>foo\\</h3>\n", + "example": 646, + "start_line": 9341, + "end_line": 9345, + "section": "Hard line breaks" + }, + { + "markdown": "### foo \n", + "html": "<h3>foo</h3>\n", + "example": 647, + "start_line": 9348, + "end_line": 9352, + "section": "Hard line breaks" + }, + { + "markdown": "foo\nbaz\n", + "html": "<p>foo\nbaz</p>\n", + "example": 648, + "start_line": 9363, + "end_line": 9369, + "section": "Soft line breaks" + }, + { + "markdown": "foo \n baz\n", + "html": "<p>foo\nbaz</p>\n", + "example": 649, + "start_line": 9375, + "end_line": 9381, + "section": "Soft line breaks" + }, + { + "markdown": "hello $.;'there\n", + "html": "<p>hello $.;'there</p>\n", + "example": 650, + "start_line": 9395, + "end_line": 9399, + "section": "Textual content" + }, + { + "markdown": "Foo χρῆν\n", + "html": "<p>Foo χρῆν</p>\n", + "example": 651, + "start_line": 9402, + "end_line": 9406, + "section": "Textual content" + }, + { + "markdown": "Multiple spaces\n", + "html": "<p>Multiple spaces</p>\n", + "example": 652, + "start_line": 9411, + "end_line": 9415, + "section": "Textual content" + } +]
\ No newline at end of file diff --git a/tests/test_cmark_spec/spec.md b/tests/test_cmark_spec/spec.md new file mode 100644 index 0000000..2d79f7b --- /dev/null +++ b/tests/test_cmark_spec/spec.md @@ -0,0 +1,9756 @@ +--- +title: CommonMark Spec +author: John MacFarlane +version: 0.30 +date: '2021-06-19' +license: '[CC-BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/)' +... + +# Introduction + +## What is Markdown? + +Markdown is a plain text format for writing structured documents, +based on conventions for indicating formatting in email +and usenet posts. It was developed by John Gruber (with +help from Aaron Swartz) and released in 2004 in the form of a +[syntax description](http://daringfireball.net/projects/markdown/syntax) +and a Perl script (`Markdown.pl`) for converting Markdown to +HTML. In the next decade, dozens of implementations were +developed in many languages. Some extended the original +Markdown syntax with conventions for footnotes, tables, and +other document elements. Some allowed Markdown documents to be +rendered in formats other than HTML. Websites like Reddit, +StackOverflow, and GitHub had millions of people using Markdown. +And Markdown started to be used beyond the web, to author books, +articles, slide shows, letters, and lecture notes. + +What distinguishes Markdown from many other lightweight markup +syntaxes, which are often easier to write, is its readability. +As Gruber writes: + +> The overriding design goal for Markdown's formatting syntax is +> to make it as readable as possible. The idea is that a +> Markdown-formatted document should be publishable as-is, as +> plain text, without looking like it's been marked up with tags +> or formatting instructions. +> (<http://daringfireball.net/projects/markdown/>) + +The point can be illustrated by comparing a sample of +[AsciiDoc](http://www.methods.co.nz/asciidoc/) with +an equivalent sample of Markdown. Here is a sample of +AsciiDoc from the AsciiDoc manual: + +``` +1. List item one. ++ +List item one continued with a second paragraph followed by an +Indented block. ++ +................. +$ ls *.sh +$ mv *.sh ~/tmp +................. ++ +List item continued with a third paragraph. + +2. List item two continued with an open block. ++ +-- +This paragraph is part of the preceding list item. + +a. This list is nested and does not require explicit item +continuation. ++ +This paragraph is part of the preceding list item. + +b. List item b. + +This paragraph belongs to item two of the outer list. +-- +``` + +And here is the equivalent in Markdown: +``` +1. List item one. + + List item one continued with a second paragraph followed by an + Indented block. + + $ ls *.sh + $ mv *.sh ~/tmp + + List item continued with a third paragraph. + +2. List item two continued with an open block. + + This paragraph is part of the preceding list item. + + 1. This list is nested and does not require explicit item continuation. + + This paragraph is part of the preceding list item. + + 2. List item b. + + This paragraph belongs to item two of the outer list. +``` + +The AsciiDoc version is, arguably, easier to write. You don't need +to worry about indentation. But the Markdown version is much easier +to read. The nesting of list items is apparent to the eye in the +source, not just in the processed document. + +## Why is a spec needed? + +John Gruber's [canonical description of Markdown's +syntax](http://daringfireball.net/projects/markdown/syntax) +does not specify the syntax unambiguously. Here are some examples of +questions it does not answer: + +1. How much indentation is needed for a sublist? The spec says that + continuation paragraphs need to be indented four spaces, but is + not fully explicit about sublists. It is natural to think that + they, too, must be indented four spaces, but `Markdown.pl` does + not require that. This is hardly a "corner case," and divergences + between implementations on this issue often lead to surprises for + users in real documents. (See [this comment by John + Gruber](http://article.gmane.org/gmane.text.markdown.general/1997).) + +2. Is a blank line needed before a block quote or heading? + Most implementations do not require the blank line. However, + this can lead to unexpected results in hard-wrapped text, and + also to ambiguities in parsing (note that some implementations + put the heading inside the blockquote, while others do not). + (John Gruber has also spoken [in favor of requiring the blank + lines](http://article.gmane.org/gmane.text.markdown.general/2146).) + +3. Is a blank line needed before an indented code block? + (`Markdown.pl` requires it, but this is not mentioned in the + documentation, and some implementations do not require it.) + + ``` markdown + paragraph + code? + ``` + +4. What is the exact rule for determining when list items get + wrapped in `<p>` tags? Can a list be partially "loose" and partially + "tight"? What should we do with a list like this? + + ``` markdown + 1. one + + 2. two + 3. three + ``` + + Or this? + + ``` markdown + 1. one + - a + + - b + 2. two + ``` + + (There are some relevant comments by John Gruber + [here](http://article.gmane.org/gmane.text.markdown.general/2554).) + +5. Can list markers be indented? Can ordered list markers be right-aligned? + + ``` markdown + 8. item 1 + 9. item 2 + 10. item 2a + ``` + +6. Is this one list with a thematic break in its second item, + or two lists separated by a thematic break? + + ``` markdown + * a + * * * * * + * b + ``` + +7. When list markers change from numbers to bullets, do we have + two lists or one? (The Markdown syntax description suggests two, + but the perl scripts and many other implementations produce one.) + + ``` markdown + 1. fee + 2. fie + - foe + - fum + ``` + +8. What are the precedence rules for the markers of inline structure? + For example, is the following a valid link, or does the code span + take precedence ? + + ``` markdown + [a backtick (`)](/url) and [another backtick (`)](/url). + ``` + +9. What are the precedence rules for markers of emphasis and strong + emphasis? For example, how should the following be parsed? + + ``` markdown + *foo *bar* baz* + ``` + +10. What are the precedence rules between block-level and inline-level + structure? For example, how should the following be parsed? + + ``` markdown + - `a long code span can contain a hyphen like this + - and it can screw things up` + ``` + +11. Can list items include section headings? (`Markdown.pl` does not + allow this, but does allow blockquotes to include headings.) + + ``` markdown + - # Heading + ``` + +12. Can list items be empty? + + ``` markdown + * a + * + * b + ``` + +13. Can link references be defined inside block quotes or list items? + + ``` markdown + > Blockquote [foo]. + > + > [foo]: /url + ``` + +14. If there are multiple definitions for the same reference, which takes + precedence? + + ``` markdown + [foo]: /url1 + [foo]: /url2 + + [foo][] + ``` + +In the absence of a spec, early implementers consulted `Markdown.pl` +to resolve these ambiguities. But `Markdown.pl` was quite buggy, and +gave manifestly bad results in many cases, so it was not a +satisfactory replacement for a spec. + +Because there is no unambiguous spec, implementations have diverged +considerably. As a result, users are often surprised to find that +a document that renders one way on one system (say, a GitHub wiki) +renders differently on another (say, converting to docbook using +pandoc). To make matters worse, because nothing in Markdown counts +as a "syntax error," the divergence often isn't discovered right away. + +## About this document + +This document attempts to specify Markdown syntax unambiguously. +It contains many examples with side-by-side Markdown and +HTML. These are intended to double as conformance tests. An +accompanying script `spec_tests.py` can be used to run the tests +against any Markdown program: + + python test/spec_tests.py --spec spec.txt --program PROGRAM + +Since this document describes how Markdown is to be parsed into +an abstract syntax tree, it would have made sense to use an abstract +representation of the syntax tree instead of HTML. But HTML is capable +of representing the structural distinctions we need to make, and the +choice of HTML for the tests makes it possible to run the tests against +an implementation without writing an abstract syntax tree renderer. + +Note that not every feature of the HTML samples is mandated by +the spec. For example, the spec says what counts as a link +destination, but it doesn't mandate that non-ASCII characters in +the URL be percent-encoded. To use the automatic tests, +implementers will need to provide a renderer that conforms to +the expectations of the spec examples (percent-encoding +non-ASCII characters in URLs). But a conforming implementation +can use a different renderer and may choose not to +percent-encode non-ASCII characters in URLs. + +This document is generated from a text file, `spec.txt`, written +in Markdown with a small extension for the side-by-side tests. +The script `tools/makespec.py` can be used to convert `spec.txt` into +HTML or CommonMark (which can then be converted into other formats). + +In the examples, the `→` character is used to represent tabs. + +# Preliminaries + +## Characters and lines + +Any sequence of [characters] is a valid CommonMark +document. + +A [character](@) is a Unicode code point. Although some +code points (for example, combining accents) do not correspond to +characters in an intuitive sense, all code points count as characters +for purposes of this spec. + +This spec does not specify an encoding; it thinks of lines as composed +of [characters] rather than bytes. A conforming parser may be limited +to a certain encoding. + +A [line](@) is a sequence of zero or more [characters] +other than line feed (`U+000A`) or carriage return (`U+000D`), +followed by a [line ending] or by the end of file. + +A [line ending](@) is a line feed (`U+000A`), a carriage return +(`U+000D`) not followed by a line feed, or a carriage return and a +following line feed. + +A line containing no characters, or a line containing only spaces +(`U+0020`) or tabs (`U+0009`), is called a [blank line](@). + +The following definitions of character classes will be used in this spec: + +A [Unicode whitespace character](@) is +any code point in the Unicode `Zs` general category, or a tab (`U+0009`), +line feed (`U+000A`), form feed (`U+000C`), or carriage return (`U+000D`). + +[Unicode whitespace](@) is a sequence of one or more +[Unicode whitespace characters]. + +A [tab](@) is `U+0009`. + +A [space](@) is `U+0020`. + +An [ASCII control character](@) is a character between `U+0000–1F` (both +including) or `U+007F`. + +An [ASCII punctuation character](@) +is `!`, `"`, `#`, `$`, `%`, `&`, `'`, `(`, `)`, +`*`, `+`, `,`, `-`, `.`, `/` (U+0021–2F), +`:`, `;`, `<`, `=`, `>`, `?`, `@` (U+003A–0040), +`[`, `\`, `]`, `^`, `_`, `` ` `` (U+005B–0060), +`{`, `|`, `}`, or `~` (U+007B–007E). + +A [Unicode punctuation character](@) is an [ASCII +punctuation character] or anything in +the general Unicode categories `Pc`, `Pd`, `Pe`, `Pf`, `Pi`, `Po`, or `Ps`. + +## Tabs + +Tabs in lines are not expanded to [spaces]. However, +in contexts where spaces help to define block structure, +tabs behave as if they were replaced by spaces with a tab stop +of 4 characters. + +Thus, for example, a tab can be used instead of four spaces +in an indented code block. (Note, however, that internal +tabs are passed through as literal tabs, not expanded to +spaces.) + +```````````````````````````````` example +→foo→baz→→bim +. +<pre><code>foo→baz→→bim +</code></pre> +```````````````````````````````` + +```````````````````````````````` example + →foo→baz→→bim +. +<pre><code>foo→baz→→bim +</code></pre> +```````````````````````````````` + +```````````````````````````````` example + a→a + ὐ→a +. +<pre><code>a→a +ὐ→a +</code></pre> +```````````````````````````````` + +In the following example, a continuation paragraph of a list +item is indented with a tab; this has exactly the same effect +as indentation with four spaces would: + +```````````````````````````````` example + - foo + +→bar +. +<ul> +<li> +<p>foo</p> +<p>bar</p> +</li> +</ul> +```````````````````````````````` + +```````````````````````````````` example +- foo + +→→bar +. +<ul> +<li> +<p>foo</p> +<pre><code> bar +</code></pre> +</li> +</ul> +```````````````````````````````` + +Normally the `>` that begins a block quote may be followed +optionally by a space, which is not considered part of the +content. In the following case `>` is followed by a tab, +which is treated as if it were expanded into three spaces. +Since one of these spaces is considered part of the +delimiter, `foo` is considered to be indented six spaces +inside the block quote context, so we get an indented +code block starting with two spaces. + +```````````````````````````````` example +>→→foo +. +<blockquote> +<pre><code> foo +</code></pre> +</blockquote> +```````````````````````````````` + +```````````````````````````````` example +-→→foo +. +<ul> +<li> +<pre><code> foo +</code></pre> +</li> +</ul> +```````````````````````````````` + + +```````````````````````````````` example + foo +→bar +. +<pre><code>foo +bar +</code></pre> +```````````````````````````````` + +```````````````````````````````` example + - foo + - bar +→ - baz +. +<ul> +<li>foo +<ul> +<li>bar +<ul> +<li>baz</li> +</ul> +</li> +</ul> +</li> +</ul> +```````````````````````````````` + +```````````````````````````````` example +#→Foo +. +<h1>Foo</h1> +```````````````````````````````` + +```````````````````````````````` example +*→*→*→ +. +<hr /> +```````````````````````````````` + + +## Insecure characters + +For security reasons, the Unicode character `U+0000` must be replaced +with the REPLACEMENT CHARACTER (`U+FFFD`). + + +## Backslash escapes + +Any ASCII punctuation character may be backslash-escaped: + +```````````````````````````````` example +\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\`\{\|\}\~ +. +<p>!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~</p> +```````````````````````````````` + + +Backslashes before other characters are treated as literal +backslashes: + +```````````````````````````````` example +\→\A\a\ \3\φ\« +. +<p>\→\A\a\ \3\φ\«</p> +```````````````````````````````` + + +Escaped characters are treated as regular characters and do +not have their usual Markdown meanings: + +```````````````````````````````` example +\*not emphasized* +\<br/> not a tag +\[not a link](/foo) +\`not code` +1\. not a list +\* not a list +\# not a heading +\[foo]: /url "not a reference" +\ö not a character entity +. +<p>*not emphasized* +<br/> not a tag +[not a link](/foo) +`not code` +1. not a list +* not a list +# not a heading +[foo]: /url "not a reference" +&ouml; not a character entity</p> +```````````````````````````````` + + +If a backslash is itself escaped, the following character is not: + +```````````````````````````````` example +\\*emphasis* +. +<p>\<em>emphasis</em></p> +```````````````````````````````` + + +A backslash at the end of the line is a [hard line break]: + +```````````````````````````````` example +foo\ +bar +. +<p>foo<br /> +bar</p> +```````````````````````````````` + + +Backslash escapes do not work in code blocks, code spans, autolinks, or +raw HTML: + +```````````````````````````````` example +`` \[\` `` +. +<p><code>\[\`</code></p> +```````````````````````````````` + + +```````````````````````````````` example + \[\] +. +<pre><code>\[\] +</code></pre> +```````````````````````````````` + + +```````````````````````````````` example +~~~ +\[\] +~~~ +. +<pre><code>\[\] +</code></pre> +```````````````````````````````` + + +```````````````````````````````` example +<http://example.com?find=\*> +. +<p><a href="http://example.com?find=%5C*">http://example.com?find=\*</a></p> +```````````````````````````````` + + +```````````````````````````````` example +<a href="/bar\/)"> +. +<a href="/bar\/)"> +```````````````````````````````` + + +But they work in all other contexts, including URLs and link titles, +link references, and [info strings] in [fenced code blocks]: + +```````````````````````````````` example +[foo](/bar\* "ti\*tle") +. +<p><a href="/bar*" title="ti*tle">foo</a></p> +```````````````````````````````` + + +```````````````````````````````` example +[foo] + +[foo]: /bar\* "ti\*tle" +. +<p><a href="/bar*" title="ti*tle">foo</a></p> +```````````````````````````````` + + +```````````````````````````````` example +``` foo\+bar +foo +``` +. +<pre><code class="language-foo+bar">foo +</code></pre> +```````````````````````````````` + + +## Entity and numeric character references + +Valid HTML entity references and numeric character references +can be used in place of the corresponding Unicode character, +with the following exceptions: + +- Entity and character references are not recognized in code + blocks and code spans. + +- Entity and character references cannot stand in place of + special characters that define structural elements in + CommonMark. For example, although `*` can be used + in place of a literal `*` character, `*` cannot replace + `*` in emphasis delimiters, bullet list markers, or thematic + breaks. + +Conforming CommonMark parsers need not store information about +whether a particular character was represented in the source +using a Unicode character or an entity reference. + +[Entity references](@) consist of `&` + any of the valid +HTML5 entity names + `;`. The +document <https://html.spec.whatwg.org/entities.json> +is used as an authoritative source for the valid entity +references and their corresponding code points. + +```````````````````````````````` example + & © Æ Ď +¾ ℋ ⅆ +∲ ≧̸ +. +<p> & © Æ Ď +¾ ℋ ⅆ +∲ ≧̸</p> +```````````````````````````````` + + +[Decimal numeric character +references](@) +consist of `&#` + a string of 1--7 arabic digits + `;`. A +numeric character reference is parsed as the corresponding +Unicode character. Invalid Unicode code points will be replaced by +the REPLACEMENT CHARACTER (`U+FFFD`). For security reasons, +the code point `U+0000` will also be replaced by `U+FFFD`. + +```````````````````````````````` example +# Ӓ Ϡ � +. +<p># Ӓ Ϡ �</p> +```````````````````````````````` + + +[Hexadecimal numeric character +references](@) consist of `&#` + +either `X` or `x` + a string of 1-6 hexadecimal digits + `;`. +They too are parsed as the corresponding Unicode character (this +time specified with a hexadecimal numeral instead of decimal). + +```````````````````````````````` example +" ആ ಫ +. +<p>" ആ ಫ</p> +```````````````````````````````` + + +Here are some nonentities: + +```````````````````````````````` example +  &x; &#; &#x; +� +&#abcdef0; +&ThisIsNotDefined; &hi?; +. +<p>&nbsp &x; &#; &#x; +&#87654321; +&#abcdef0; +&ThisIsNotDefined; &hi?;</p> +```````````````````````````````` + + +Although HTML5 does accept some entity references +without a trailing semicolon (such as `©`), these are not +recognized here, because it makes the grammar too ambiguous: + +```````````````````````````````` example +© +. +<p>&copy</p> +```````````````````````````````` + + +Strings that are not on the list of HTML5 named entities are not +recognized as entity references either: + +```````````````````````````````` example +&MadeUpEntity; +. +<p>&MadeUpEntity;</p> +```````````````````````````````` + + +Entity and numeric character references are recognized in any +context besides code spans or code blocks, including +URLs, [link titles], and [fenced code block][] [info strings]: + +```````````````````````````````` example +<a href="öö.html"> +. +<a href="öö.html"> +```````````````````````````````` + + +```````````````````````````````` example +[foo](/föö "föö") +. +<p><a href="/f%C3%B6%C3%B6" title="föö">foo</a></p> +```````````````````````````````` + + +```````````````````````````````` example +[foo] + +[foo]: /föö "föö" +. +<p><a href="/f%C3%B6%C3%B6" title="föö">foo</a></p> +```````````````````````````````` + + +```````````````````````````````` example +``` föö +foo +``` +. +<pre><code class="language-föö">foo +</code></pre> +```````````````````````````````` + + +Entity and numeric character references are treated as literal +text in code spans and code blocks: + +```````````````````````````````` example +`föö` +. +<p><code>f&ouml;&ouml;</code></p> +```````````````````````````````` + + +```````````````````````````````` example + föfö +. +<pre><code>f&ouml;f&ouml; +</code></pre> +```````````````````````````````` + + +Entity and numeric character references cannot be used +in place of symbols indicating structure in CommonMark +documents. + +```````````````````````````````` example +*foo* +*foo* +. +<p>*foo* +<em>foo</em></p> +```````````````````````````````` + +```````````````````````````````` example +* foo + +* foo +. +<p>* foo</p> +<ul> +<li>foo</li> +</ul> +```````````````````````````````` + +```````````````````````````````` example +foo bar +. +<p>foo + +bar</p> +```````````````````````````````` + +```````````````````````````````` example +	foo +. +<p>→foo</p> +```````````````````````````````` + + +```````````````````````````````` example +[a](url "tit") +. +<p>[a](url "tit")</p> +```````````````````````````````` + + + +# Blocks and inlines + +We can think of a document as a sequence of +[blocks](@)---structural elements like paragraphs, block +quotations, lists, headings, rules, and code blocks. Some blocks (like +block quotes and list items) contain other blocks; others (like +headings and paragraphs) contain [inline](@) content---text, +links, emphasized text, images, code spans, and so on. + +## Precedence + +Indicators of block structure always take precedence over indicators +of inline structure. So, for example, the following is a list with +two items, not a list with one item containing a code span: + +```````````````````````````````` example +- `one +- two` +. +<ul> +<li>`one</li> +<li>two`</li> +</ul> +```````````````````````````````` + + +This means that parsing can proceed in two steps: first, the block +structure of the document can be discerned; second, text lines inside +paragraphs, headings, and other block constructs can be parsed for inline +structure. The second step requires information about link reference +definitions that will be available only at the end of the first +step. Note that the first step requires processing lines in sequence, +but the second can be parallelized, since the inline parsing of +one block element does not affect the inline parsing of any other. + +## Container blocks and leaf blocks + +We can divide blocks into two types: +[container blocks](#container-blocks), +which can contain other blocks, and [leaf blocks](#leaf-blocks), +which cannot. + +# Leaf blocks + +This section describes the different kinds of leaf block that make up a +Markdown document. + +## Thematic breaks + +A line consisting of optionally up to three spaces of indentation, followed by a +sequence of three or more matching `-`, `_`, or `*` characters, each followed +optionally by any number of spaces or tabs, forms a +[thematic break](@). + +```````````````````````````````` example +*** +--- +___ +. +<hr /> +<hr /> +<hr /> +```````````````````````````````` + + +Wrong characters: + +```````````````````````````````` example ++++ +. +<p>+++</p> +```````````````````````````````` + + +```````````````````````````````` example +=== +. +<p>===</p> +```````````````````````````````` + + +Not enough characters: + +```````````````````````````````` example +-- +** +__ +. +<p>-- +** +__</p> +```````````````````````````````` + + +Up to three spaces of indentation are allowed: + +```````````````````````````````` example + *** + *** + *** +. +<hr /> +<hr /> +<hr /> +```````````````````````````````` + + +Four spaces of indentation is too many: + +```````````````````````````````` example + *** +. +<pre><code>*** +</code></pre> +```````````````````````````````` + + +```````````````````````````````` example +Foo + *** +. +<p>Foo +***</p> +```````````````````````````````` + + +More than three characters may be used: + +```````````````````````````````` example +_____________________________________ +. +<hr /> +```````````````````````````````` + + +Spaces and tabs are allowed between the characters: + +```````````````````````````````` example + - - - +. +<hr /> +```````````````````````````````` + + +```````````````````````````````` example + ** * ** * ** * ** +. +<hr /> +```````````````````````````````` + + +```````````````````````````````` example +- - - - +. +<hr /> +```````````````````````````````` + + +Spaces and tabs are allowed at the end: + +```````````````````````````````` example +- - - - +. +<hr /> +```````````````````````````````` + + +However, no other characters may occur in the line: + +```````````````````````````````` example +_ _ _ _ a + +a------ + +---a--- +. +<p>_ _ _ _ a</p> +<p>a------</p> +<p>---a---</p> +```````````````````````````````` + + +It is required that all of the characters other than spaces or tabs be the same. +So, this is not a thematic break: + +```````````````````````````````` example + *-* +. +<p><em>-</em></p> +```````````````````````````````` + + +Thematic breaks do not need blank lines before or after: + +```````````````````````````````` example +- foo +*** +- bar +. +<ul> +<li>foo</li> +</ul> +<hr /> +<ul> +<li>bar</li> +</ul> +```````````````````````````````` + + +Thematic breaks can interrupt a paragraph: + +```````````````````````````````` example +Foo +*** +bar +. +<p>Foo</p> +<hr /> +<p>bar</p> +```````````````````````````````` + + +If a line of dashes that meets the above conditions for being a +thematic break could also be interpreted as the underline of a [setext +heading], the interpretation as a +[setext heading] takes precedence. Thus, for example, +this is a setext heading, not a paragraph followed by a thematic break: + +```````````````````````````````` example +Foo +--- +bar +. +<h2>Foo</h2> +<p>bar</p> +```````````````````````````````` + + +When both a thematic break and a list item are possible +interpretations of a line, the thematic break takes precedence: + +```````````````````````````````` example +* Foo +* * * +* Bar +. +<ul> +<li>Foo</li> +</ul> +<hr /> +<ul> +<li>Bar</li> +</ul> +```````````````````````````````` + + +If you want a thematic break in a list item, use a different bullet: + +```````````````````````````````` example +- Foo +- * * * +. +<ul> +<li>Foo</li> +<li> +<hr /> +</li> +</ul> +```````````````````````````````` + + +## ATX headings + +An [ATX heading](@) +consists of a string of characters, parsed as inline content, between an +opening sequence of 1--6 unescaped `#` characters and an optional +closing sequence of any number of unescaped `#` characters. +The opening sequence of `#` characters must be followed by spaces or tabs, or +by the end of line. The optional closing sequence of `#`s must be preceded by +spaces or tabs and may be followed by spaces or tabs only. The opening +`#` character may be preceded by up to three spaces of indentation. The raw +contents of the heading are stripped of leading and trailing space or tabs +before being parsed as inline content. The heading level is equal to the number +of `#` characters in the opening sequence. + +Simple headings: + +```````````````````````````````` example +# foo +## foo +### foo +#### foo +##### foo +###### foo +. +<h1>foo</h1> +<h2>foo</h2> +<h3>foo</h3> +<h4>foo</h4> +<h5>foo</h5> +<h6>foo</h6> +```````````````````````````````` + + +More than six `#` characters is not a heading: + +```````````````````````````````` example +####### foo +. +<p>####### foo</p> +```````````````````````````````` + + +At least one space or tab is required between the `#` characters and the +heading's contents, unless the heading is empty. Note that many +implementations currently do not require the space. However, the +space was required by the +[original ATX implementation](http://www.aaronsw.com/2002/atx/atx.py), +and it helps prevent things like the following from being parsed as +headings: + +```````````````````````````````` example +#5 bolt + +#hashtag +. +<p>#5 bolt</p> +<p>#hashtag</p> +```````````````````````````````` + + +This is not a heading, because the first `#` is escaped: + +```````````````````````````````` example +\## foo +. +<p>## foo</p> +```````````````````````````````` + + +Contents are parsed as inlines: + +```````````````````````````````` example +# foo *bar* \*baz\* +. +<h1>foo <em>bar</em> *baz*</h1> +```````````````````````````````` + + +Leading and trailing spaces or tabs are ignored in parsing inline content: + +```````````````````````````````` example +# foo +. +<h1>foo</h1> +```````````````````````````````` + + +Up to three spaces of indentation are allowed: + +```````````````````````````````` example + ### foo + ## foo + # foo +. +<h3>foo</h3> +<h2>foo</h2> +<h1>foo</h1> +```````````````````````````````` + + +Four spaces of indentation is too many: + +```````````````````````````````` example + # foo +. +<pre><code># foo +</code></pre> +```````````````````````````````` + + +```````````````````````````````` example +foo + # bar +. +<p>foo +# bar</p> +```````````````````````````````` + + +A closing sequence of `#` characters is optional: + +```````````````````````````````` example +## foo ## + ### bar ### +. +<h2>foo</h2> +<h3>bar</h3> +```````````````````````````````` + + +It need not be the same length as the opening sequence: + +```````````````````````````````` example +# foo ################################## +##### foo ## +. +<h1>foo</h1> +<h5>foo</h5> +```````````````````````````````` + + +Spaces or tabs are allowed after the closing sequence: + +```````````````````````````````` example +### foo ### +. +<h3>foo</h3> +```````````````````````````````` + + +A sequence of `#` characters with anything but spaces or tabs following it +is not a closing sequence, but counts as part of the contents of the +heading: + +```````````````````````````````` example +### foo ### b +. +<h3>foo ### b</h3> +```````````````````````````````` + + +The closing sequence must be preceded by a space or tab: + +```````````````````````````````` example +# foo# +. +<h1>foo#</h1> +```````````````````````````````` + + +Backslash-escaped `#` characters do not count as part +of the closing sequence: + +```````````````````````````````` example +### foo \### +## foo #\## +# foo \# +. +<h3>foo ###</h3> +<h2>foo ###</h2> +<h1>foo #</h1> +```````````````````````````````` + + +ATX headings need not be separated from surrounding content by blank +lines, and they can interrupt paragraphs: + +```````````````````````````````` example +**** +## foo +**** +. +<hr /> +<h2>foo</h2> +<hr /> +```````````````````````````````` + + +```````````````````````````````` example +Foo bar +# baz +Bar foo +. +<p>Foo bar</p> +<h1>baz</h1> +<p>Bar foo</p> +```````````````````````````````` + + +ATX headings can be empty: + +```````````````````````````````` example +## +# +### ### +. +<h2></h2> +<h1></h1> +<h3></h3> +```````````````````````````````` + + +## Setext headings + +A [setext heading](@) consists of one or more +lines of text, not interrupted by a blank line, of which the first line does not +have more than 3 spaces of indentation, followed by +a [setext heading underline]. The lines of text must be such +that, were they not followed by the setext heading underline, +they would be interpreted as a paragraph: they cannot be +interpretable as a [code fence], [ATX heading][ATX headings], +[block quote][block quotes], [thematic break][thematic breaks], +[list item][list items], or [HTML block][HTML blocks]. + +A [setext heading underline](@) is a sequence of +`=` characters or a sequence of `-` characters, with no more than 3 +spaces of indentation and any number of trailing spaces or tabs. If a line +containing a single `-` can be interpreted as an +empty [list items], it should be interpreted this way +and not as a [setext heading underline]. + +The heading is a level 1 heading if `=` characters are used in +the [setext heading underline], and a level 2 heading if `-` +characters are used. The contents of the heading are the result +of parsing the preceding lines of text as CommonMark inline +content. + +In general, a setext heading need not be preceded or followed by a +blank line. However, it cannot interrupt a paragraph, so when a +setext heading comes after a paragraph, a blank line is needed between +them. + +Simple examples: + +```````````````````````````````` example +Foo *bar* +========= + +Foo *bar* +--------- +. +<h1>Foo <em>bar</em></h1> +<h2>Foo <em>bar</em></h2> +```````````````````````````````` + + +The content of the header may span more than one line: + +```````````````````````````````` example +Foo *bar +baz* +==== +. +<h1>Foo <em>bar +baz</em></h1> +```````````````````````````````` + +The contents are the result of parsing the headings's raw +content as inlines. The heading's raw content is formed by +concatenating the lines and removing initial and final +spaces or tabs. + +```````````````````````````````` example + Foo *bar +baz*→ +==== +. +<h1>Foo <em>bar +baz</em></h1> +```````````````````````````````` + + +The underlining can be any length: + +```````````````````````````````` example +Foo +------------------------- + +Foo += +. +<h2>Foo</h2> +<h1>Foo</h1> +```````````````````````````````` + + +The heading content can be preceded by up to three spaces of indentation, and +need not line up with the underlining: + +```````````````````````````````` example + Foo +--- + + Foo +----- + + Foo + === +. +<h2>Foo</h2> +<h2>Foo</h2> +<h1>Foo</h1> +```````````````````````````````` + + +Four spaces of indentation is too many: + +```````````````````````````````` example + Foo + --- + + Foo +--- +. +<pre><code>Foo +--- + +Foo +</code></pre> +<hr /> +```````````````````````````````` + + +The setext heading underline can be preceded by up to three spaces of +indentation, and may have trailing spaces or tabs: + +```````````````````````````````` example +Foo + ---- +. +<h2>Foo</h2> +```````````````````````````````` + + +Four spaces of indentation is too many: + +```````````````````````````````` example +Foo + --- +. +<p>Foo +---</p> +```````````````````````````````` + + +The setext heading underline cannot contain internal spaces or tabs: + +```````````````````````````````` example +Foo += = + +Foo +--- - +. +<p>Foo += =</p> +<p>Foo</p> +<hr /> +```````````````````````````````` + + +Trailing spaces or tabs in the content line do not cause a hard line break: + +```````````````````````````````` example +Foo +----- +. +<h2>Foo</h2> +```````````````````````````````` + + +Nor does a backslash at the end: + +```````````````````````````````` example +Foo\ +---- +. +<h2>Foo\</h2> +```````````````````````````````` + + +Since indicators of block structure take precedence over +indicators of inline structure, the following are setext headings: + +```````````````````````````````` example +`Foo +---- +` + +<a title="a lot +--- +of dashes"/> +. +<h2>`Foo</h2> +<p>`</p> +<h2><a title="a lot</h2> +<p>of dashes"/></p> +```````````````````````````````` + + +The setext heading underline cannot be a [lazy continuation +line] in a list item or block quote: + +```````````````````````````````` example +> Foo +--- +. +<blockquote> +<p>Foo</p> +</blockquote> +<hr /> +```````````````````````````````` + + +```````````````````````````````` example +> foo +bar +=== +. +<blockquote> +<p>foo +bar +===</p> +</blockquote> +```````````````````````````````` + + +```````````````````````````````` example +- Foo +--- +. +<ul> +<li>Foo</li> +</ul> +<hr /> +```````````````````````````````` + + +A blank line is needed between a paragraph and a following +setext heading, since otherwise the paragraph becomes part +of the heading's content: + +```````````````````````````````` example +Foo +Bar +--- +. +<h2>Foo +Bar</h2> +```````````````````````````````` + + +But in general a blank line is not required before or after +setext headings: + +```````````````````````````````` example +--- +Foo +--- +Bar +--- +Baz +. +<hr /> +<h2>Foo</h2> +<h2>Bar</h2> +<p>Baz</p> +```````````````````````````````` + + +Setext headings cannot be empty: + +```````````````````````````````` example + +==== +. +<p>====</p> +```````````````````````````````` + + +Setext heading text lines must not be interpretable as block +constructs other than paragraphs. So, the line of dashes +in these examples gets interpreted as a thematic break: + +```````````````````````````````` example +--- +--- +. +<hr /> +<hr /> +```````````````````````````````` + + +```````````````````````````````` example +- foo +----- +. +<ul> +<li>foo</li> +</ul> +<hr /> +```````````````````````````````` + + +```````````````````````````````` example + foo +--- +. +<pre><code>foo +</code></pre> +<hr /> +```````````````````````````````` + + +```````````````````````````````` example +> foo +----- +. +<blockquote> +<p>foo</p> +</blockquote> +<hr /> +```````````````````````````````` + + +If you want a heading with `> foo` as its literal text, you can +use backslash escapes: + +```````````````````````````````` example +\> foo +------ +. +<h2>> foo</h2> +```````````````````````````````` + + +**Compatibility note:** Most existing Markdown implementations +do not allow the text of setext headings to span multiple lines. +But there is no consensus about how to interpret + +``` markdown +Foo +bar +--- +baz +``` + +One can find four different interpretations: + +1. paragraph "Foo", heading "bar", paragraph "baz" +2. paragraph "Foo bar", thematic break, paragraph "baz" +3. paragraph "Foo bar --- baz" +4. heading "Foo bar", paragraph "baz" + +We find interpretation 4 most natural, and interpretation 4 +increases the expressive power of CommonMark, by allowing +multiline headings. Authors who want interpretation 1 can +put a blank line after the first paragraph: + +```````````````````````````````` example +Foo + +bar +--- +baz +. +<p>Foo</p> +<h2>bar</h2> +<p>baz</p> +```````````````````````````````` + + +Authors who want interpretation 2 can put blank lines around +the thematic break, + +```````````````````````````````` example +Foo +bar + +--- + +baz +. +<p>Foo +bar</p> +<hr /> +<p>baz</p> +```````````````````````````````` + + +or use a thematic break that cannot count as a [setext heading +underline], such as + +```````````````````````````````` example +Foo +bar +* * * +baz +. +<p>Foo +bar</p> +<hr /> +<p>baz</p> +```````````````````````````````` + + +Authors who want interpretation 3 can use backslash escapes: + +```````````````````````````````` example +Foo +bar +\--- +baz +. +<p>Foo +bar +--- +baz</p> +```````````````````````````````` + + +## Indented code blocks + +An [indented code block](@) is composed of one or more +[indented chunks] separated by blank lines. +An [indented chunk](@) is a sequence of non-blank lines, +each preceded by four or more spaces of indentation. The contents of the code +block are the literal contents of the lines, including trailing +[line endings], minus four spaces of indentation. +An indented code block has no [info string]. + +An indented code block cannot interrupt a paragraph, so there must be +a blank line between a paragraph and a following indented code block. +(A blank line is not needed, however, between a code block and a following +paragraph.) + +```````````````````````````````` example + a simple + indented code block +. +<pre><code>a simple + indented code block +</code></pre> +```````````````````````````````` + + +If there is any ambiguity between an interpretation of indentation +as a code block and as indicating that material belongs to a [list +item][list items], the list item interpretation takes precedence: + +```````````````````````````````` example + - foo + + bar +. +<ul> +<li> +<p>foo</p> +<p>bar</p> +</li> +</ul> +```````````````````````````````` + + +```````````````````````````````` example +1. foo + + - bar +. +<ol> +<li> +<p>foo</p> +<ul> +<li>bar</li> +</ul> +</li> +</ol> +```````````````````````````````` + + + +The contents of a code block are literal text, and do not get parsed +as Markdown: + +```````````````````````````````` example + <a/> + *hi* + + - one +. +<pre><code><a/> +*hi* + +- one +</code></pre> +```````````````````````````````` + + +Here we have three chunks separated by blank lines: + +```````````````````````````````` example + chunk1 + + chunk2 + + + + chunk3 +. +<pre><code>chunk1 + +chunk2 + + + +chunk3 +</code></pre> +```````````````````````````````` + + +Any initial spaces or tabs beyond four spaces of indentation will be included in +the content, even in interior blank lines: + +```````````````````````````````` example + chunk1 + + chunk2 +. +<pre><code>chunk1 + + chunk2 +</code></pre> +```````````````````````````````` + + +An indented code block cannot interrupt a paragraph. (This +allows hanging indents and the like.) + +```````````````````````````````` example +Foo + bar + +. +<p>Foo +bar</p> +```````````````````````````````` + + +However, any non-blank line with fewer than four spaces of indentation ends +the code block immediately. So a paragraph may occur immediately +after indented code: + +```````````````````````````````` example + foo +bar +. +<pre><code>foo +</code></pre> +<p>bar</p> +```````````````````````````````` + + +And indented code can occur immediately before and after other kinds of +blocks: + +```````````````````````````````` example +# Heading + foo +Heading +------ + foo +---- +. +<h1>Heading</h1> +<pre><code>foo +</code></pre> +<h2>Heading</h2> +<pre><code>foo +</code></pre> +<hr /> +```````````````````````````````` + + +The first line can be preceded by more than four spaces of indentation: + +```````````````````````````````` example + foo + bar +. +<pre><code> foo +bar +</code></pre> +```````````````````````````````` + + +Blank lines preceding or following an indented code block +are not included in it: + +```````````````````````````````` example + + + foo + + +. +<pre><code>foo +</code></pre> +```````````````````````````````` + + +Trailing spaces or tabs are included in the code block's content: + +```````````````````````````````` example + foo +. +<pre><code>foo +</code></pre> +```````````````````````````````` + + + +## Fenced code blocks + +A [code fence](@) is a sequence +of at least three consecutive backtick characters (`` ` ``) or +tildes (`~`). (Tildes and backticks cannot be mixed.) +A [fenced code block](@) +begins with a code fence, preceded by up to three spaces of indentation. + +The line with the opening code fence may optionally contain some text +following the code fence; this is trimmed of leading and trailing +spaces or tabs and called the [info string](@). If the [info string] comes +after a backtick fence, it may not contain any backtick +characters. (The reason for this restriction is that otherwise +some inline code would be incorrectly interpreted as the +beginning of a fenced code block.) + +The content of the code block consists of all subsequent lines, until +a closing [code fence] of the same type as the code block +began with (backticks or tildes), and with at least as many backticks +or tildes as the opening code fence. If the leading code fence is +preceded by N spaces of indentation, then up to N spaces of indentation are +removed from each line of the content (if present). (If a content line is not +indented, it is preserved unchanged. If it is indented N spaces or less, all +of the indentation is removed.) + +The closing code fence may be preceded by up to three spaces of indentation, and +may be followed only by spaces or tabs, which are ignored. If the end of the +containing block (or document) is reached and no closing code fence +has been found, the code block contains all of the lines after the +opening code fence until the end of the containing block (or +document). (An alternative spec would require backtracking in the +event that a closing code fence is not found. But this makes parsing +much less efficient, and there seems to be no real down side to the +behavior described here.) + +A fenced code block may interrupt a paragraph, and does not require +a blank line either before or after. + +The content of a code fence is treated as literal text, not parsed +as inlines. The first word of the [info string] is typically used to +specify the language of the code sample, and rendered in the `class` +attribute of the `code` tag. However, this spec does not mandate any +particular treatment of the [info string]. + +Here is a simple example with backticks: + +```````````````````````````````` example +``` +< + > +``` +. +<pre><code>< + > +</code></pre> +```````````````````````````````` + + +With tildes: + +```````````````````````````````` example +~~~ +< + > +~~~ +. +<pre><code>< + > +</code></pre> +```````````````````````````````` + +Fewer than three backticks is not enough: + +```````````````````````````````` example +`` +foo +`` +. +<p><code>foo</code></p> +```````````````````````````````` + +The closing code fence must use the same character as the opening +fence: + +```````````````````````````````` example +``` +aaa +~~~ +``` +. +<pre><code>aaa +~~~ +</code></pre> +```````````````````````````````` + + +```````````````````````````````` example +~~~ +aaa +``` +~~~ +. +<pre><code>aaa +``` +</code></pre> +```````````````````````````````` + + +The closing code fence must be at least as long as the opening fence: + +```````````````````````````````` example +```` +aaa +``` +`````` +. +<pre><code>aaa +``` +</code></pre> +```````````````````````````````` + + +```````````````````````````````` example +~~~~ +aaa +~~~ +~~~~ +. +<pre><code>aaa +~~~ +</code></pre> +```````````````````````````````` + + +Unclosed code blocks are closed by the end of the document +(or the enclosing [block quote][block quotes] or [list item][list items]): + +```````````````````````````````` example +``` +. +<pre><code></code></pre> +```````````````````````````````` + + +```````````````````````````````` example +````` + +``` +aaa +. +<pre><code> +``` +aaa +</code></pre> +```````````````````````````````` + + +```````````````````````````````` example +> ``` +> aaa + +bbb +. +<blockquote> +<pre><code>aaa +</code></pre> +</blockquote> +<p>bbb</p> +```````````````````````````````` + + +A code block can have all empty lines as its content: + +```````````````````````````````` example +``` + + +``` +. +<pre><code> + +</code></pre> +```````````````````````````````` + + +A code block can be empty: + +```````````````````````````````` example +``` +``` +. +<pre><code></code></pre> +```````````````````````````````` + + +Fences can be indented. If the opening fence is indented, +content lines will have equivalent opening indentation removed, +if present: + +```````````````````````````````` example + ``` + aaa +aaa +``` +. +<pre><code>aaa +aaa +</code></pre> +```````````````````````````````` + + +```````````````````````````````` example + ``` +aaa + aaa +aaa + ``` +. +<pre><code>aaa +aaa +aaa +</code></pre> +```````````````````````````````` + + +```````````````````````````````` example + ``` + aaa + aaa + aaa + ``` +. +<pre><code>aaa + aaa +aaa +</code></pre> +```````````````````````````````` + + +Four spaces of indentation is too many: + +```````````````````````````````` example + ``` + aaa + ``` +. +<pre><code>``` +aaa +``` +</code></pre> +```````````````````````````````` + + +Closing fences may be preceded by up to three spaces of indentation, and their +indentation need not match that of the opening fence: + +```````````````````````````````` example +``` +aaa + ``` +. +<pre><code>aaa +</code></pre> +```````````````````````````````` + + +```````````````````````````````` example + ``` +aaa + ``` +. +<pre><code>aaa +</code></pre> +```````````````````````````````` + + +This is not a closing fence, because it is indented 4 spaces: + +```````````````````````````````` example +``` +aaa + ``` +. +<pre><code>aaa + ``` +</code></pre> +```````````````````````````````` + + + +Code fences (opening and closing) cannot contain internal spaces or tabs: + +```````````````````````````````` example +``` ``` +aaa +. +<p><code> </code> +aaa</p> +```````````````````````````````` + + +```````````````````````````````` example +~~~~~~ +aaa +~~~ ~~ +. +<pre><code>aaa +~~~ ~~ +</code></pre> +```````````````````````````````` + + +Fenced code blocks can interrupt paragraphs, and can be followed +directly by paragraphs, without a blank line between: + +```````````````````````````````` example +foo +``` +bar +``` +baz +. +<p>foo</p> +<pre><code>bar +</code></pre> +<p>baz</p> +```````````````````````````````` + + +Other blocks can also occur before and after fenced code blocks +without an intervening blank line: + +```````````````````````````````` example +foo +--- +~~~ +bar +~~~ +# baz +. +<h2>foo</h2> +<pre><code>bar +</code></pre> +<h1>baz</h1> +```````````````````````````````` + + +An [info string] can be provided after the opening code fence. +Although this spec doesn't mandate any particular treatment of +the info string, the first word is typically used to specify +the language of the code block. In HTML output, the language is +normally indicated by adding a class to the `code` element consisting +of `language-` followed by the language name. + +```````````````````````````````` example +```ruby +def foo(x) + return 3 +end +``` +. +<pre><code class="language-ruby">def foo(x) + return 3 +end +</code></pre> +```````````````````````````````` + + +```````````````````````````````` example +~~~~ ruby startline=3 $%@#$ +def foo(x) + return 3 +end +~~~~~~~ +. +<pre><code class="language-ruby">def foo(x) + return 3 +end +</code></pre> +```````````````````````````````` + + +```````````````````````````````` example +````; +```` +. +<pre><code class="language-;"></code></pre> +```````````````````````````````` + + +[Info strings] for backtick code blocks cannot contain backticks: + +```````````````````````````````` example +``` aa ``` +foo +. +<p><code>aa</code> +foo</p> +```````````````````````````````` + + +[Info strings] for tilde code blocks can contain backticks and tildes: + +```````````````````````````````` example +~~~ aa ``` ~~~ +foo +~~~ +. +<pre><code class="language-aa">foo +</code></pre> +```````````````````````````````` + + +Closing code fences cannot have [info strings]: + +```````````````````````````````` example +``` +``` aaa +``` +. +<pre><code>``` aaa +</code></pre> +```````````````````````````````` + + + +## HTML blocks + +An [HTML block](@) is a group of lines that is treated +as raw HTML (and will not be escaped in HTML output). + +There are seven kinds of [HTML block], which can be defined by their +start and end conditions. The block begins with a line that meets a +[start condition](@) (after up to three optional spaces of indentation). +It ends with the first subsequent line that meets a matching +[end condition](@), or the last line of the document, or the last line of +the [container block](#container-blocks) containing the current HTML +block, if no line is encountered that meets the [end condition]. If +the first line meets both the [start condition] and the [end +condition], the block will contain just that line. + +1. **Start condition:** line begins with the string `<pre`, +`<script`, `<style`, or `<textarea` (case-insensitive), followed by a space, +a tab, the string `>`, or the end of the line.\ +**End condition:** line contains an end tag +`</pre>`, `</script>`, `</style>`, or `</textarea>` (case-insensitive; it +need not match the start tag). + +2. **Start condition:** line begins with the string `<!--`.\ +**End condition:** line contains the string `-->`. + +3. **Start condition:** line begins with the string `<?`.\ +**End condition:** line contains the string `?>`. + +4. **Start condition:** line begins with the string `<!` +followed by an ASCII letter.\ +**End condition:** line contains the character `>`. + +5. **Start condition:** line begins with the string +`<![CDATA[`.\ +**End condition:** line contains the string `]]>`. + +6. **Start condition:** line begins the string `<` or `</` +followed by one of the strings (case-insensitive) `address`, +`article`, `aside`, `base`, `basefont`, `blockquote`, `body`, +`caption`, `center`, `col`, `colgroup`, `dd`, `details`, `dialog`, +`dir`, `div`, `dl`, `dt`, `fieldset`, `figcaption`, `figure`, +`footer`, `form`, `frame`, `frameset`, +`h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `head`, `header`, `hr`, +`html`, `iframe`, `legend`, `li`, `link`, `main`, `menu`, `menuitem`, +`nav`, `noframes`, `ol`, `optgroup`, `option`, `p`, `param`, +`section`, `source`, `summary`, `table`, `tbody`, `td`, +`tfoot`, `th`, `thead`, `title`, `tr`, `track`, `ul`, followed +by a space, a tab, the end of the line, the string `>`, or +the string `/>`.\ +**End condition:** line is followed by a [blank line]. + +7. **Start condition:** line begins with a complete [open tag] +(with any [tag name] other than `pre`, `script`, +`style`, or `textarea`) or a complete [closing tag], +followed by zero or more spaces and tabs, followed by the end of the line.\ +**End condition:** line is followed by a [blank line]. + +HTML blocks continue until they are closed by their appropriate +[end condition], or the last line of the document or other [container +block](#container-blocks). This means any HTML **within an HTML +block** that might otherwise be recognised as a start condition will +be ignored by the parser and passed through as-is, without changing +the parser's state. + +For instance, `<pre>` within an HTML block started by `<table>` will not affect +the parser state; as the HTML block was started in by start condition 6, it +will end at any blank line. This can be surprising: + +```````````````````````````````` example +<table><tr><td> +<pre> +**Hello**, + +_world_. +</pre> +</td></tr></table> +. +<table><tr><td> +<pre> +**Hello**, +<p><em>world</em>. +</pre></p> +</td></tr></table> +```````````````````````````````` + +In this case, the HTML block is terminated by the blank line — the `**Hello**` +text remains verbatim — and regular parsing resumes, with a paragraph, +emphasised `world` and inline and block HTML following. + +All types of [HTML blocks] except type 7 may interrupt +a paragraph. Blocks of type 7 may not interrupt a paragraph. +(This restriction is intended to prevent unwanted interpretation +of long tags inside a wrapped paragraph as starting HTML blocks.) + +Some simple examples follow. Here are some basic HTML blocks +of type 6: + +```````````````````````````````` example +<table> + <tr> + <td> + hi + </td> + </tr> +</table> + +okay. +. +<table> + <tr> + <td> + hi + </td> + </tr> +</table> +<p>okay.</p> +```````````````````````````````` + + +```````````````````````````````` example + <div> + *hello* + <foo><a> +. + <div> + *hello* + <foo><a> +```````````````````````````````` + + +A block can also start with a closing tag: + +```````````````````````````````` example +</div> +*foo* +. +</div> +*foo* +```````````````````````````````` + + +Here we have two HTML blocks with a Markdown paragraph between them: + +```````````````````````````````` example +<DIV CLASS="foo"> + +*Markdown* + +</DIV> +. +<DIV CLASS="foo"> +<p><em>Markdown</em></p> +</DIV> +```````````````````````````````` + + +The tag on the first line can be partial, as long +as it is split where there would be whitespace: + +```````````````````````````````` example +<div id="foo" + class="bar"> +</div> +. +<div id="foo" + class="bar"> +</div> +```````````````````````````````` + + +```````````````````````````````` example +<div id="foo" class="bar + baz"> +</div> +. +<div id="foo" class="bar + baz"> +</div> +```````````````````````````````` + + +An open tag need not be closed: +```````````````````````````````` example +<div> +*foo* + +*bar* +. +<div> +*foo* +<p><em>bar</em></p> +```````````````````````````````` + + + +A partial tag need not even be completed (garbage +in, garbage out): + +```````````````````````````````` example +<div id="foo" +*hi* +. +<div id="foo" +*hi* +```````````````````````````````` + + +```````````````````````````````` example +<div class +foo +. +<div class +foo +```````````````````````````````` + + +The initial tag doesn't even need to be a valid +tag, as long as it starts like one: + +```````````````````````````````` example +<div *???-&&&-<--- +*foo* +. +<div *???-&&&-<--- +*foo* +```````````````````````````````` + + +In type 6 blocks, the initial tag need not be on a line by +itself: + +```````````````````````````````` example +<div><a href="bar">*foo*</a></div> +. +<div><a href="bar">*foo*</a></div> +```````````````````````````````` + + +```````````````````````````````` example +<table><tr><td> +foo +</td></tr></table> +. +<table><tr><td> +foo +</td></tr></table> +```````````````````````````````` + + +Everything until the next blank line or end of document +gets included in the HTML block. So, in the following +example, what looks like a Markdown code block +is actually part of the HTML block, which continues until a blank +line or the end of the document is reached: + +```````````````````````````````` example +<div></div> +``` c +int x = 33; +``` +. +<div></div> +``` c +int x = 33; +``` +```````````````````````````````` + + +To start an [HTML block] with a tag that is *not* in the +list of block-level tags in (6), you must put the tag by +itself on the first line (and it must be complete): + +```````````````````````````````` example +<a href="foo"> +*bar* +</a> +. +<a href="foo"> +*bar* +</a> +```````````````````````````````` + + +In type 7 blocks, the [tag name] can be anything: + +```````````````````````````````` example +<Warning> +*bar* +</Warning> +. +<Warning> +*bar* +</Warning> +```````````````````````````````` + + +```````````````````````````````` example +<i class="foo"> +*bar* +</i> +. +<i class="foo"> +*bar* +</i> +```````````````````````````````` + + +```````````````````````````````` example +</ins> +*bar* +. +</ins> +*bar* +```````````````````````````````` + + +These rules are designed to allow us to work with tags that +can function as either block-level or inline-level tags. +The `<del>` tag is a nice example. We can surround content with +`<del>` tags in three different ways. In this case, we get a raw +HTML block, because the `<del>` tag is on a line by itself: + +```````````````````````````````` example +<del> +*foo* +</del> +. +<del> +*foo* +</del> +```````````````````````````````` + + +In this case, we get a raw HTML block that just includes +the `<del>` tag (because it ends with the following blank +line). So the contents get interpreted as CommonMark: + +```````````````````````````````` example +<del> + +*foo* + +</del> +. +<del> +<p><em>foo</em></p> +</del> +```````````````````````````````` + + +Finally, in this case, the `<del>` tags are interpreted +as [raw HTML] *inside* the CommonMark paragraph. (Because +the tag is not on a line by itself, we get inline HTML +rather than an [HTML block].) + +```````````````````````````````` example +<del>*foo*</del> +. +<p><del><em>foo</em></del></p> +```````````````````````````````` + + +HTML tags designed to contain literal content +(`pre`, `script`, `style`, `textarea`), comments, processing instructions, +and declarations are treated somewhat differently. +Instead of ending at the first blank line, these blocks +end at the first line containing a corresponding end tag. +As a result, these blocks can contain blank lines: + +A pre tag (type 1): + +```````````````````````````````` example +<pre language="haskell"><code> +import Text.HTML.TagSoup + +main :: IO () +main = print $ parseTags tags +</code></pre> +okay +. +<pre language="haskell"><code> +import Text.HTML.TagSoup + +main :: IO () +main = print $ parseTags tags +</code></pre> +<p>okay</p> +```````````````````````````````` + + +A script tag (type 1): + +```````````````````````````````` example +<script type="text/javascript"> +// JavaScript example + +document.getElementById("demo").innerHTML = "Hello JavaScript!"; +</script> +okay +. +<script type="text/javascript"> +// JavaScript example + +document.getElementById("demo").innerHTML = "Hello JavaScript!"; +</script> +<p>okay</p> +```````````````````````````````` + + +A textarea tag (type 1): + +```````````````````````````````` example +<textarea> + +*foo* + +_bar_ + +</textarea> +. +<textarea> + +*foo* + +_bar_ + +</textarea> +```````````````````````````````` + +A style tag (type 1): + +```````````````````````````````` example +<style + type="text/css"> +h1 {color:red;} + +p {color:blue;} +</style> +okay +. +<style + type="text/css"> +h1 {color:red;} + +p {color:blue;} +</style> +<p>okay</p> +```````````````````````````````` + + +If there is no matching end tag, the block will end at the +end of the document (or the enclosing [block quote][block quotes] +or [list item][list items]): + +```````````````````````````````` example +<style + type="text/css"> + +foo +. +<style + type="text/css"> + +foo +```````````````````````````````` + + +```````````````````````````````` example +> <div> +> foo + +bar +. +<blockquote> +<div> +foo +</blockquote> +<p>bar</p> +```````````````````````````````` + + +```````````````````````````````` example +- <div> +- foo +. +<ul> +<li> +<div> +</li> +<li>foo</li> +</ul> +```````````````````````````````` + + +The end tag can occur on the same line as the start tag: + +```````````````````````````````` example +<style>p{color:red;}</style> +*foo* +. +<style>p{color:red;}</style> +<p><em>foo</em></p> +```````````````````````````````` + + +```````````````````````````````` example +<!-- foo -->*bar* +*baz* +. +<!-- foo -->*bar* +<p><em>baz</em></p> +```````````````````````````````` + + +Note that anything on the last line after the +end tag will be included in the [HTML block]: + +```````````````````````````````` example +<script> +foo +</script>1. *bar* +. +<script> +foo +</script>1. *bar* +```````````````````````````````` + + +A comment (type 2): + +```````````````````````````````` example +<!-- Foo + +bar + baz --> +okay +. +<!-- Foo + +bar + baz --> +<p>okay</p> +```````````````````````````````` + + + +A processing instruction (type 3): + +```````````````````````````````` example +<?php + + echo '>'; + +?> +okay +. +<?php + + echo '>'; + +?> +<p>okay</p> +```````````````````````````````` + + +A declaration (type 4): + +```````````````````````````````` example +<!DOCTYPE html> +. +<!DOCTYPE html> +```````````````````````````````` + + +CDATA (type 5): + +```````````````````````````````` example +<![CDATA[ +function matchwo(a,b) +{ + if (a < b && a < 0) then { + return 1; + + } else { + + return 0; + } +} +]]> +okay +. +<![CDATA[ +function matchwo(a,b) +{ + if (a < b && a < 0) then { + return 1; + + } else { + + return 0; + } +} +]]> +<p>okay</p> +```````````````````````````````` + + +The opening tag can be preceded by up to three spaces of indentation, but not +four: + +```````````````````````````````` example + <!-- foo --> + + <!-- foo --> +. + <!-- foo --> +<pre><code><!-- foo --> +</code></pre> +```````````````````````````````` + + +```````````````````````````````` example + <div> + + <div> +. + <div> +<pre><code><div> +</code></pre> +```````````````````````````````` + + +An HTML block of types 1--6 can interrupt a paragraph, and need not be +preceded by a blank line. + +```````````````````````````````` example +Foo +<div> +bar +</div> +. +<p>Foo</p> +<div> +bar +</div> +```````````````````````````````` + + +However, a following blank line is needed, except at the end of +a document, and except for blocks of types 1--5, [above][HTML +block]: + +```````````````````````````````` example +<div> +bar +</div> +*foo* +. +<div> +bar +</div> +*foo* +```````````````````````````````` + + +HTML blocks of type 7 cannot interrupt a paragraph: + +```````````````````````````````` example +Foo +<a href="bar"> +baz +. +<p>Foo +<a href="bar"> +baz</p> +```````````````````````````````` + + +This rule differs from John Gruber's original Markdown syntax +specification, which says: + +> The only restrictions are that block-level HTML elements — +> e.g. `<div>`, `<table>`, `<pre>`, `<p>`, etc. — must be separated from +> surrounding content by blank lines, and the start and end tags of the +> block should not be indented with spaces or tabs. + +In some ways Gruber's rule is more restrictive than the one given +here: + +- It requires that an HTML block be preceded by a blank line. +- It does not allow the start tag to be indented. +- It requires a matching end tag, which it also does not allow to + be indented. + +Most Markdown implementations (including some of Gruber's own) do not +respect all of these restrictions. + +There is one respect, however, in which Gruber's rule is more liberal +than the one given here, since it allows blank lines to occur inside +an HTML block. There are two reasons for disallowing them here. +First, it removes the need to parse balanced tags, which is +expensive and can require backtracking from the end of the document +if no matching end tag is found. Second, it provides a very simple +and flexible way of including Markdown content inside HTML tags: +simply separate the Markdown from the HTML using blank lines: + +Compare: + +```````````````````````````````` example +<div> + +*Emphasized* text. + +</div> +. +<div> +<p><em>Emphasized</em> text.</p> +</div> +```````````````````````````````` + + +```````````````````````````````` example +<div> +*Emphasized* text. +</div> +. +<div> +*Emphasized* text. +</div> +```````````````````````````````` + + +Some Markdown implementations have adopted a convention of +interpreting content inside tags as text if the open tag has +the attribute `markdown=1`. The rule given above seems a simpler and +more elegant way of achieving the same expressive power, which is also +much simpler to parse. + +The main potential drawback is that one can no longer paste HTML +blocks into Markdown documents with 100% reliability. However, +*in most cases* this will work fine, because the blank lines in +HTML are usually followed by HTML block tags. For example: + +```````````````````````````````` example +<table> + +<tr> + +<td> +Hi +</td> + +</tr> + +</table> +. +<table> +<tr> +<td> +Hi +</td> +</tr> +</table> +```````````````````````````````` + + +There are problems, however, if the inner tags are indented +*and* separated by spaces, as then they will be interpreted as +an indented code block: + +```````````````````````````````` example +<table> + + <tr> + + <td> + Hi + </td> + + </tr> + +</table> +. +<table> + <tr> +<pre><code><td> + Hi +</td> +</code></pre> + </tr> +</table> +```````````````````````````````` + + +Fortunately, blank lines are usually not necessary and can be +deleted. The exception is inside `<pre>` tags, but as described +[above][HTML blocks], raw HTML blocks starting with `<pre>` +*can* contain blank lines. + +## Link reference definitions + +A [link reference definition](@) +consists of a [link label], optionally preceded by up to three spaces of +indentation, followed +by a colon (`:`), optional spaces or tabs (including up to one +[line ending]), a [link destination], +optional spaces or tabs (including up to one +[line ending]), and an optional [link +title], which if it is present must be separated +from the [link destination] by spaces or tabs. +No further character may occur. + +A [link reference definition] +does not correspond to a structural element of a document. Instead, it +defines a label which can be used in [reference links] +and reference-style [images] elsewhere in the document. [Link +reference definitions] can come either before or after the links that use +them. + +```````````````````````````````` example +[foo]: /url "title" + +[foo] +. +<p><a href="/url" title="title">foo</a></p> +```````````````````````````````` + + +```````````````````````````````` example + [foo]: + /url + 'the title' + +[foo] +. +<p><a href="/url" title="the title">foo</a></p> +```````````````````````````````` + + +```````````````````````````````` example +[Foo*bar\]]:my_(url) 'title (with parens)' + +[Foo*bar\]] +. +<p><a href="my_(url)" title="title (with parens)">Foo*bar]</a></p> +```````````````````````````````` + + +```````````````````````````````` example +[Foo bar]: +<my url> +'title' + +[Foo bar] +. +<p><a href="my%20url" title="title">Foo bar</a></p> +```````````````````````````````` + + +The title may extend over multiple lines: + +```````````````````````````````` example +[foo]: /url ' +title +line1 +line2 +' + +[foo] +. +<p><a href="/url" title=" +title +line1 +line2 +">foo</a></p> +```````````````````````````````` + + +However, it may not contain a [blank line]: + +```````````````````````````````` example +[foo]: /url 'title + +with blank line' + +[foo] +. +<p>[foo]: /url 'title</p> +<p>with blank line'</p> +<p>[foo]</p> +```````````````````````````````` + + +The title may be omitted: + +```````````````````````````````` example +[foo]: +/url + +[foo] +. +<p><a href="/url">foo</a></p> +```````````````````````````````` + + +The link destination may not be omitted: + +```````````````````````````````` example +[foo]: + +[foo] +. +<p>[foo]:</p> +<p>[foo]</p> +```````````````````````````````` + + However, an empty link destination may be specified using + angle brackets: + +```````````````````````````````` example +[foo]: <> + +[foo] +. +<p><a href="">foo</a></p> +```````````````````````````````` + +The title must be separated from the link destination by +spaces or tabs: + +```````````````````````````````` example +[foo]: <bar>(baz) + +[foo] +. +<p>[foo]: <bar>(baz)</p> +<p>[foo]</p> +```````````````````````````````` + + +Both title and destination can contain backslash escapes +and literal backslashes: + +```````````````````````````````` example +[foo]: /url\bar\*baz "foo\"bar\baz" + +[foo] +. +<p><a href="/url%5Cbar*baz" title="foo"bar\baz">foo</a></p> +```````````````````````````````` + + +A link can come before its corresponding definition: + +```````````````````````````````` example +[foo] + +[foo]: url +. +<p><a href="url">foo</a></p> +```````````````````````````````` + + +If there are several matching definitions, the first one takes +precedence: + +```````````````````````````````` example +[foo] + +[foo]: first +[foo]: second +. +<p><a href="first">foo</a></p> +```````````````````````````````` + + +As noted in the section on [Links], matching of labels is +case-insensitive (see [matches]). + +```````````````````````````````` example +[FOO]: /url + +[Foo] +. +<p><a href="/url">Foo</a></p> +```````````````````````````````` + + +```````````````````````````````` example +[ΑΓΩ]: /φου + +[αγω] +. +<p><a href="/%CF%86%CE%BF%CF%85">αγω</a></p> +```````````````````````````````` + + +Whether something is a [link reference definition] is +independent of whether the link reference it defines is +used in the document. Thus, for example, the following +document contains just a link reference definition, and +no visible content: + +```````````````````````````````` example +[foo]: /url +. +```````````````````````````````` + + +Here is another one: + +```````````````````````````````` example +[ +foo +]: /url +bar +. +<p>bar</p> +```````````````````````````````` + + +This is not a link reference definition, because there are +characters other than spaces or tabs after the title: + +```````````````````````````````` example +[foo]: /url "title" ok +. +<p>[foo]: /url "title" ok</p> +```````````````````````````````` + + +This is a link reference definition, but it has no title: + +```````````````````````````````` example +[foo]: /url +"title" ok +. +<p>"title" ok</p> +```````````````````````````````` + + +This is not a link reference definition, because it is indented +four spaces: + +```````````````````````````````` example + [foo]: /url "title" + +[foo] +. +<pre><code>[foo]: /url "title" +</code></pre> +<p>[foo]</p> +```````````````````````````````` + + +This is not a link reference definition, because it occurs inside +a code block: + +```````````````````````````````` example +``` +[foo]: /url +``` + +[foo] +. +<pre><code>[foo]: /url +</code></pre> +<p>[foo]</p> +```````````````````````````````` + + +A [link reference definition] cannot interrupt a paragraph. + +```````````````````````````````` example +Foo +[bar]: /baz + +[bar] +. +<p>Foo +[bar]: /baz</p> +<p>[bar]</p> +```````````````````````````````` + + +However, it can directly follow other block elements, such as headings +and thematic breaks, and it need not be followed by a blank line. + +```````````````````````````````` example +# [Foo] +[foo]: /url +> bar +. +<h1><a href="/url">Foo</a></h1> +<blockquote> +<p>bar</p> +</blockquote> +```````````````````````````````` + +```````````````````````````````` example +[foo]: /url +bar +=== +[foo] +. +<h1>bar</h1> +<p><a href="/url">foo</a></p> +```````````````````````````````` + +```````````````````````````````` example +[foo]: /url +=== +[foo] +. +<p>=== +<a href="/url">foo</a></p> +```````````````````````````````` + + +Several [link reference definitions] +can occur one after another, without intervening blank lines. + +```````````````````````````````` example +[foo]: /foo-url "foo" +[bar]: /bar-url + "bar" +[baz]: /baz-url + +[foo], +[bar], +[baz] +. +<p><a href="/foo-url" title="foo">foo</a>, +<a href="/bar-url" title="bar">bar</a>, +<a href="/baz-url">baz</a></p> +```````````````````````````````` + + +[Link reference definitions] can occur +inside block containers, like lists and block quotations. They +affect the entire document, not just the container in which they +are defined: + +```````````````````````````````` example +[foo] + +> [foo]: /url +. +<p><a href="/url">foo</a></p> +<blockquote> +</blockquote> +```````````````````````````````` + + +## Paragraphs + +A sequence of non-blank lines that cannot be interpreted as other +kinds of blocks forms a [paragraph](@). +The contents of the paragraph are the result of parsing the +paragraph's raw content as inlines. The paragraph's raw content +is formed by concatenating the lines and removing initial and final +spaces or tabs. + +A simple example with two paragraphs: + +```````````````````````````````` example +aaa + +bbb +. +<p>aaa</p> +<p>bbb</p> +```````````````````````````````` + + +Paragraphs can contain multiple lines, but no blank lines: + +```````````````````````````````` example +aaa +bbb + +ccc +ddd +. +<p>aaa +bbb</p> +<p>ccc +ddd</p> +```````````````````````````````` + + +Multiple blank lines between paragraphs have no effect: + +```````````````````````````````` example +aaa + + +bbb +. +<p>aaa</p> +<p>bbb</p> +```````````````````````````````` + + +Leading spaces or tabs are skipped: + +```````````````````````````````` example + aaa + bbb +. +<p>aaa +bbb</p> +```````````````````````````````` + + +Lines after the first may be indented any amount, since indented +code blocks cannot interrupt paragraphs. + +```````````````````````````````` example +aaa + bbb + ccc +. +<p>aaa +bbb +ccc</p> +```````````````````````````````` + + +However, the first line may be preceded by up to three spaces of indentation. +Four spaces of indentation is too many: + +```````````````````````````````` example + aaa +bbb +. +<p>aaa +bbb</p> +```````````````````````````````` + + +```````````````````````````````` example + aaa +bbb +. +<pre><code>aaa +</code></pre> +<p>bbb</p> +```````````````````````````````` + + +Final spaces or tabs are stripped before inline parsing, so a paragraph +that ends with two or more spaces will not end with a [hard line +break]: + +```````````````````````````````` example +aaa +bbb +. +<p>aaa<br /> +bbb</p> +```````````````````````````````` + + +## Blank lines + +[Blank lines] between block-level elements are ignored, +except for the role they play in determining whether a [list] +is [tight] or [loose]. + +Blank lines at the beginning and end of the document are also ignored. + +```````````````````````````````` example + + +aaa + + +# aaa + + +. +<p>aaa</p> +<h1>aaa</h1> +```````````````````````````````` + + + +# Container blocks + +A [container block](#container-blocks) is a block that has other +blocks as its contents. There are two basic kinds of container blocks: +[block quotes] and [list items]. +[Lists] are meta-containers for [list items]. + +We define the syntax for container blocks recursively. The general +form of the definition is: + +> If X is a sequence of blocks, then the result of +> transforming X in such-and-such a way is a container of type Y +> with these blocks as its content. + +So, we explain what counts as a block quote or list item by explaining +how these can be *generated* from their contents. This should suffice +to define the syntax, although it does not give a recipe for *parsing* +these constructions. (A recipe is provided below in the section entitled +[A parsing strategy](#appendix-a-parsing-strategy).) + +## Block quotes + +A [block quote marker](@), +optionally preceded by up to three spaces of indentation, +consists of (a) the character `>` together with a following space of +indentation, or (b) a single character `>` not followed by a space of +indentation. + +The following rules define [block quotes]: + +1. **Basic case.** If a string of lines *Ls* constitute a sequence + of blocks *Bs*, then the result of prepending a [block quote + marker] to the beginning of each line in *Ls* + is a [block quote](#block-quotes) containing *Bs*. + +2. **Laziness.** If a string of lines *Ls* constitute a [block + quote](#block-quotes) with contents *Bs*, then the result of deleting + the initial [block quote marker] from one or + more lines in which the next character other than a space or tab after the + [block quote marker] is [paragraph continuation + text] is a block quote with *Bs* as its content. + [Paragraph continuation text](@) is text + that will be parsed as part of the content of a paragraph, but does + not occur at the beginning of the paragraph. + +3. **Consecutiveness.** A document cannot contain two [block + quotes] in a row unless there is a [blank line] between them. + +Nothing else counts as a [block quote](#block-quotes). + +Here is a simple example: + +```````````````````````````````` example +> # Foo +> bar +> baz +. +<blockquote> +<h1>Foo</h1> +<p>bar +baz</p> +</blockquote> +```````````````````````````````` + + +The space or tab after the `>` characters can be omitted: + +```````````````````````````````` example +># Foo +>bar +> baz +. +<blockquote> +<h1>Foo</h1> +<p>bar +baz</p> +</blockquote> +```````````````````````````````` + + +The `>` characters can be preceded by up to three spaces of indentation: + +```````````````````````````````` example + > # Foo + > bar + > baz +. +<blockquote> +<h1>Foo</h1> +<p>bar +baz</p> +</blockquote> +```````````````````````````````` + + +Four spaces of indentation is too many: + +```````````````````````````````` example + > # Foo + > bar + > baz +. +<pre><code>> # Foo +> bar +> baz +</code></pre> +```````````````````````````````` + + +The Laziness clause allows us to omit the `>` before +[paragraph continuation text]: + +```````````````````````````````` example +> # Foo +> bar +baz +. +<blockquote> +<h1>Foo</h1> +<p>bar +baz</p> +</blockquote> +```````````````````````````````` + + +A block quote can contain some lazy and some non-lazy +continuation lines: + +```````````````````````````````` example +> bar +baz +> foo +. +<blockquote> +<p>bar +baz +foo</p> +</blockquote> +```````````````````````````````` + + +Laziness only applies to lines that would have been continuations of +paragraphs had they been prepended with [block quote markers]. +For example, the `> ` cannot be omitted in the second line of + +``` markdown +> foo +> --- +``` + +without changing the meaning: + +```````````````````````````````` example +> foo +--- +. +<blockquote> +<p>foo</p> +</blockquote> +<hr /> +```````````````````````````````` + + +Similarly, if we omit the `> ` in the second line of + +``` markdown +> - foo +> - bar +``` + +then the block quote ends after the first line: + +```````````````````````````````` example +> - foo +- bar +. +<blockquote> +<ul> +<li>foo</li> +</ul> +</blockquote> +<ul> +<li>bar</li> +</ul> +```````````````````````````````` + + +For the same reason, we can't omit the `> ` in front of +subsequent lines of an indented or fenced code block: + +```````````````````````````````` example +> foo + bar +. +<blockquote> +<pre><code>foo +</code></pre> +</blockquote> +<pre><code>bar +</code></pre> +```````````````````````````````` + + +```````````````````````````````` example +> ``` +foo +``` +. +<blockquote> +<pre><code></code></pre> +</blockquote> +<p>foo</p> +<pre><code></code></pre> +```````````````````````````````` + + +Note that in the following case, we have a [lazy +continuation line]: + +```````````````````````````````` example +> foo + - bar +. +<blockquote> +<p>foo +- bar</p> +</blockquote> +```````````````````````````````` + + +To see why, note that in + +```markdown +> foo +> - bar +``` + +the `- bar` is indented too far to start a list, and can't +be an indented code block because indented code blocks cannot +interrupt paragraphs, so it is [paragraph continuation text]. + +A block quote can be empty: + +```````````````````````````````` example +> +. +<blockquote> +</blockquote> +```````````````````````````````` + + +```````````````````````````````` example +> +> +> +. +<blockquote> +</blockquote> +```````````````````````````````` + + +A block quote can have initial or final blank lines: + +```````````````````````````````` example +> +> foo +> +. +<blockquote> +<p>foo</p> +</blockquote> +```````````````````````````````` + + +A blank line always separates block quotes: + +```````````````````````````````` example +> foo + +> bar +. +<blockquote> +<p>foo</p> +</blockquote> +<blockquote> +<p>bar</p> +</blockquote> +```````````````````````````````` + + +(Most current Markdown implementations, including John Gruber's +original `Markdown.pl`, will parse this example as a single block quote +with two paragraphs. But it seems better to allow the author to decide +whether two block quotes or one are wanted.) + +Consecutiveness means that if we put these block quotes together, +we get a single block quote: + +```````````````````````````````` example +> foo +> bar +. +<blockquote> +<p>foo +bar</p> +</blockquote> +```````````````````````````````` + + +To get a block quote with two paragraphs, use: + +```````````````````````````````` example +> foo +> +> bar +. +<blockquote> +<p>foo</p> +<p>bar</p> +</blockquote> +```````````````````````````````` + + +Block quotes can interrupt paragraphs: + +```````````````````````````````` example +foo +> bar +. +<p>foo</p> +<blockquote> +<p>bar</p> +</blockquote> +```````````````````````````````` + + +In general, blank lines are not needed before or after block +quotes: + +```````````````````````````````` example +> aaa +*** +> bbb +. +<blockquote> +<p>aaa</p> +</blockquote> +<hr /> +<blockquote> +<p>bbb</p> +</blockquote> +```````````````````````````````` + + +However, because of laziness, a blank line is needed between +a block quote and a following paragraph: + +```````````````````````````````` example +> bar +baz +. +<blockquote> +<p>bar +baz</p> +</blockquote> +```````````````````````````````` + + +```````````````````````````````` example +> bar + +baz +. +<blockquote> +<p>bar</p> +</blockquote> +<p>baz</p> +```````````````````````````````` + + +```````````````````````````````` example +> bar +> +baz +. +<blockquote> +<p>bar</p> +</blockquote> +<p>baz</p> +```````````````````````````````` + + +It is a consequence of the Laziness rule that any number +of initial `>`s may be omitted on a continuation line of a +nested block quote: + +```````````````````````````````` example +> > > foo +bar +. +<blockquote> +<blockquote> +<blockquote> +<p>foo +bar</p> +</blockquote> +</blockquote> +</blockquote> +```````````````````````````````` + + +```````````````````````````````` example +>>> foo +> bar +>>baz +. +<blockquote> +<blockquote> +<blockquote> +<p>foo +bar +baz</p> +</blockquote> +</blockquote> +</blockquote> +```````````````````````````````` + + +When including an indented code block in a block quote, +remember that the [block quote marker] includes +both the `>` and a following space of indentation. So *five spaces* are needed +after the `>`: + +```````````````````````````````` example +> code + +> not code +. +<blockquote> +<pre><code>code +</code></pre> +</blockquote> +<blockquote> +<p>not code</p> +</blockquote> +```````````````````````````````` + + + +## List items + +A [list marker](@) is a +[bullet list marker] or an [ordered list marker]. + +A [bullet list marker](@) +is a `-`, `+`, or `*` character. + +An [ordered list marker](@) +is a sequence of 1--9 arabic digits (`0-9`), followed by either a +`.` character or a `)` character. (The reason for the length +limit is that with 10 digits we start seeing integer overflows +in some browsers.) + +The following rules define [list items]: + +1. **Basic case.** If a sequence of lines *Ls* constitute a sequence of + blocks *Bs* starting with a character other than a space or tab, and *M* is + a list marker of width *W* followed by 1 ≤ *N* ≤ 4 spaces of indentation, + then the result of prepending *M* and the following spaces to the first line + of Ls*, and indenting subsequent lines of *Ls* by *W + N* spaces, is a + list item with *Bs* as its contents. The type of the list item + (bullet or ordered) is determined by the type of its list marker. + If the list item is ordered, then it is also assigned a start + number, based on the ordered list marker. + + Exceptions: + + 1. When the first list item in a [list] interrupts + a paragraph---that is, when it starts on a line that would + otherwise count as [paragraph continuation text]---then (a) + the lines *Ls* must not begin with a blank line, and (b) if + the list item is ordered, the start number must be 1. + 2. If any line is a [thematic break][thematic breaks] then + that line is not a list item. + +For example, let *Ls* be the lines + +```````````````````````````````` example +A paragraph +with two lines. + + indented code + +> A block quote. +. +<p>A paragraph +with two lines.</p> +<pre><code>indented code +</code></pre> +<blockquote> +<p>A block quote.</p> +</blockquote> +```````````````````````````````` + + +And let *M* be the marker `1.`, and *N* = 2. Then rule #1 says +that the following is an ordered list item with start number 1, +and the same contents as *Ls*: + +```````````````````````````````` example +1. A paragraph + with two lines. + + indented code + + > A block quote. +. +<ol> +<li> +<p>A paragraph +with two lines.</p> +<pre><code>indented code +</code></pre> +<blockquote> +<p>A block quote.</p> +</blockquote> +</li> +</ol> +```````````````````````````````` + + +The most important thing to notice is that the position of +the text after the list marker determines how much indentation +is needed in subsequent blocks in the list item. If the list +marker takes up two spaces of indentation, and there are three spaces between +the list marker and the next character other than a space or tab, then blocks +must be indented five spaces in order to fall under the list +item. + +Here are some examples showing how far content must be indented to be +put under the list item: + +```````````````````````````````` example +- one + + two +. +<ul> +<li>one</li> +</ul> +<p>two</p> +```````````````````````````````` + + +```````````````````````````````` example +- one + + two +. +<ul> +<li> +<p>one</p> +<p>two</p> +</li> +</ul> +```````````````````````````````` + + +```````````````````````````````` example + - one + + two +. +<ul> +<li>one</li> +</ul> +<pre><code> two +</code></pre> +```````````````````````````````` + + +```````````````````````````````` example + - one + + two +. +<ul> +<li> +<p>one</p> +<p>two</p> +</li> +</ul> +```````````````````````````````` + + +It is tempting to think of this in terms of columns: the continuation +blocks must be indented at least to the column of the first character other than +a space or tab after the list marker. However, that is not quite right. +The spaces of indentation after the list marker determine how much relative +indentation is needed. Which column this indentation reaches will depend on +how the list item is embedded in other constructions, as shown by +this example: + +```````````````````````````````` example + > > 1. one +>> +>> two +. +<blockquote> +<blockquote> +<ol> +<li> +<p>one</p> +<p>two</p> +</li> +</ol> +</blockquote> +</blockquote> +```````````````````````````````` + + +Here `two` occurs in the same column as the list marker `1.`, +but is actually contained in the list item, because there is +sufficient indentation after the last containing blockquote marker. + +The converse is also possible. In the following example, the word `two` +occurs far to the right of the initial text of the list item, `one`, but +it is not considered part of the list item, because it is not indented +far enough past the blockquote marker: + +```````````````````````````````` example +>>- one +>> + > > two +. +<blockquote> +<blockquote> +<ul> +<li>one</li> +</ul> +<p>two</p> +</blockquote> +</blockquote> +```````````````````````````````` + + +Note that at least one space or tab is needed between the list marker and +any following content, so these are not list items: + +```````````````````````````````` example +-one + +2.two +. +<p>-one</p> +<p>2.two</p> +```````````````````````````````` + + +A list item may contain blocks that are separated by more than +one blank line. + +```````````````````````````````` example +- foo + + + bar +. +<ul> +<li> +<p>foo</p> +<p>bar</p> +</li> +</ul> +```````````````````````````````` + + +A list item may contain any kind of block: + +```````````````````````````````` example +1. foo + + ``` + bar + ``` + + baz + + > bam +. +<ol> +<li> +<p>foo</p> +<pre><code>bar +</code></pre> +<p>baz</p> +<blockquote> +<p>bam</p> +</blockquote> +</li> +</ol> +```````````````````````````````` + + +A list item that contains an indented code block will preserve +empty lines within the code block verbatim. + +```````````````````````````````` example +- Foo + + bar + + + baz +. +<ul> +<li> +<p>Foo</p> +<pre><code>bar + + +baz +</code></pre> +</li> +</ul> +```````````````````````````````` + +Note that ordered list start numbers must be nine digits or less: + +```````````````````````````````` example +123456789. ok +. +<ol start="123456789"> +<li>ok</li> +</ol> +```````````````````````````````` + + +```````````````````````````````` example +1234567890. not ok +. +<p>1234567890. not ok</p> +```````````````````````````````` + + +A start number may begin with 0s: + +```````````````````````````````` example +0. ok +. +<ol start="0"> +<li>ok</li> +</ol> +```````````````````````````````` + + +```````````````````````````````` example +003. ok +. +<ol start="3"> +<li>ok</li> +</ol> +```````````````````````````````` + + +A start number may not be negative: + +```````````````````````````````` example +-1. not ok +. +<p>-1. not ok</p> +```````````````````````````````` + + + +2. **Item starting with indented code.** If a sequence of lines *Ls* + constitute a sequence of blocks *Bs* starting with an indented code + block, and *M* is a list marker of width *W* followed by + one space of indentation, then the result of prepending *M* and the + following space to the first line of *Ls*, and indenting subsequent lines + of *Ls* by *W + 1* spaces, is a list item with *Bs* as its contents. + If a line is empty, then it need not be indented. The type of the + list item (bullet or ordered) is determined by the type of its list + marker. If the list item is ordered, then it is also assigned a + start number, based on the ordered list marker. + +An indented code block will have to be preceded by four spaces of indentation +beyond the edge of the region where text will be included in the list item. +In the following case that is 6 spaces: + +```````````````````````````````` example +- foo + + bar +. +<ul> +<li> +<p>foo</p> +<pre><code>bar +</code></pre> +</li> +</ul> +```````````````````````````````` + + +And in this case it is 11 spaces: + +```````````````````````````````` example + 10. foo + + bar +. +<ol start="10"> +<li> +<p>foo</p> +<pre><code>bar +</code></pre> +</li> +</ol> +```````````````````````````````` + + +If the *first* block in the list item is an indented code block, +then by rule #2, the contents must be preceded by *one* space of indentation +after the list marker: + +```````````````````````````````` example + indented code + +paragraph + + more code +. +<pre><code>indented code +</code></pre> +<p>paragraph</p> +<pre><code>more code +</code></pre> +```````````````````````````````` + + +```````````````````````````````` example +1. indented code + + paragraph + + more code +. +<ol> +<li> +<pre><code>indented code +</code></pre> +<p>paragraph</p> +<pre><code>more code +</code></pre> +</li> +</ol> +```````````````````````````````` + + +Note that an additional space of indentation is interpreted as space +inside the code block: + +```````````````````````````````` example +1. indented code + + paragraph + + more code +. +<ol> +<li> +<pre><code> indented code +</code></pre> +<p>paragraph</p> +<pre><code>more code +</code></pre> +</li> +</ol> +```````````````````````````````` + + +Note that rules #1 and #2 only apply to two cases: (a) cases +in which the lines to be included in a list item begin with a +character other than a space or tab, and (b) cases in which +they begin with an indented code +block. In a case like the following, where the first block begins with +three spaces of indentation, the rules do not allow us to form a list item by +indenting the whole thing and prepending a list marker: + +```````````````````````````````` example + foo + +bar +. +<p>foo</p> +<p>bar</p> +```````````````````````````````` + + +```````````````````````````````` example +- foo + + bar +. +<ul> +<li>foo</li> +</ul> +<p>bar</p> +```````````````````````````````` + + +This is not a significant restriction, because when a block is preceded by up to +three spaces of indentation, the indentation can always be removed without +a change in interpretation, allowing rule #1 to be applied. So, in +the above case: + +```````````````````````````````` example +- foo + + bar +. +<ul> +<li> +<p>foo</p> +<p>bar</p> +</li> +</ul> +```````````````````````````````` + + +3. **Item starting with a blank line.** If a sequence of lines *Ls* + starting with a single [blank line] constitute a (possibly empty) + sequence of blocks *Bs*, and *M* is a list marker of width *W*, + then the result of prepending *M* to the first line of *Ls*, and + preceding subsequent lines of *Ls* by *W + 1* spaces of indentation, is a + list item with *Bs* as its contents. + If a line is empty, then it need not be indented. The type of the + list item (bullet or ordered) is determined by the type of its list + marker. If the list item is ordered, then it is also assigned a + start number, based on the ordered list marker. + +Here are some list items that start with a blank line but are not empty: + +```````````````````````````````` example +- + foo +- + ``` + bar + ``` +- + baz +. +<ul> +<li>foo</li> +<li> +<pre><code>bar +</code></pre> +</li> +<li> +<pre><code>baz +</code></pre> +</li> +</ul> +```````````````````````````````` + +When the list item starts with a blank line, the number of spaces +following the list marker doesn't change the required indentation: + +```````````````````````````````` example +- + foo +. +<ul> +<li>foo</li> +</ul> +```````````````````````````````` + + +A list item can begin with at most one blank line. +In the following example, `foo` is not part of the list +item: + +```````````````````````````````` example +- + + foo +. +<ul> +<li></li> +</ul> +<p>foo</p> +```````````````````````````````` + + +Here is an empty bullet list item: + +```````````````````````````````` example +- foo +- +- bar +. +<ul> +<li>foo</li> +<li></li> +<li>bar</li> +</ul> +```````````````````````````````` + + +It does not matter whether there are spaces or tabs following the [list marker]: + +```````````````````````````````` example +- foo +- +- bar +. +<ul> +<li>foo</li> +<li></li> +<li>bar</li> +</ul> +```````````````````````````````` + + +Here is an empty ordered list item: + +```````````````````````````````` example +1. foo +2. +3. bar +. +<ol> +<li>foo</li> +<li></li> +<li>bar</li> +</ol> +```````````````````````````````` + + +A list may start or end with an empty list item: + +```````````````````````````````` example +* +. +<ul> +<li></li> +</ul> +```````````````````````````````` + +However, an empty list item cannot interrupt a paragraph: + +```````````````````````````````` example +foo +* + +foo +1. +. +<p>foo +*</p> +<p>foo +1.</p> +```````````````````````````````` + + +4. **Indentation.** If a sequence of lines *Ls* constitutes a list item + according to rule #1, #2, or #3, then the result of preceding each line + of *Ls* by up to three spaces of indentation (the same for each line) also + constitutes a list item with the same contents and attributes. If a line is + empty, then it need not be indented. + +Indented one space: + +```````````````````````````````` example + 1. A paragraph + with two lines. + + indented code + + > A block quote. +. +<ol> +<li> +<p>A paragraph +with two lines.</p> +<pre><code>indented code +</code></pre> +<blockquote> +<p>A block quote.</p> +</blockquote> +</li> +</ol> +```````````````````````````````` + + +Indented two spaces: + +```````````````````````````````` example + 1. A paragraph + with two lines. + + indented code + + > A block quote. +. +<ol> +<li> +<p>A paragraph +with two lines.</p> +<pre><code>indented code +</code></pre> +<blockquote> +<p>A block quote.</p> +</blockquote> +</li> +</ol> +```````````````````````````````` + + +Indented three spaces: + +```````````````````````````````` example + 1. A paragraph + with two lines. + + indented code + + > A block quote. +. +<ol> +<li> +<p>A paragraph +with two lines.</p> +<pre><code>indented code +</code></pre> +<blockquote> +<p>A block quote.</p> +</blockquote> +</li> +</ol> +```````````````````````````````` + + +Four spaces indent gives a code block: + +```````````````````````````````` example + 1. A paragraph + with two lines. + + indented code + + > A block quote. +. +<pre><code>1. A paragraph + with two lines. + + indented code + + > A block quote. +</code></pre> +```````````````````````````````` + + + +5. **Laziness.** If a string of lines *Ls* constitute a [list + item](#list-items) with contents *Bs*, then the result of deleting + some or all of the indentation from one or more lines in which the + next character other than a space or tab after the indentation is + [paragraph continuation text] is a + list item with the same contents and attributes. The unindented + lines are called + [lazy continuation line](@)s. + +Here is an example with [lazy continuation lines]: + +```````````````````````````````` example + 1. A paragraph +with two lines. + + indented code + + > A block quote. +. +<ol> +<li> +<p>A paragraph +with two lines.</p> +<pre><code>indented code +</code></pre> +<blockquote> +<p>A block quote.</p> +</blockquote> +</li> +</ol> +```````````````````````````````` + + +Indentation can be partially deleted: + +```````````````````````````````` example + 1. A paragraph + with two lines. +. +<ol> +<li>A paragraph +with two lines.</li> +</ol> +```````````````````````````````` + + +These examples show how laziness can work in nested structures: + +```````````````````````````````` example +> 1. > Blockquote +continued here. +. +<blockquote> +<ol> +<li> +<blockquote> +<p>Blockquote +continued here.</p> +</blockquote> +</li> +</ol> +</blockquote> +```````````````````````````````` + + +```````````````````````````````` example +> 1. > Blockquote +> continued here. +. +<blockquote> +<ol> +<li> +<blockquote> +<p>Blockquote +continued here.</p> +</blockquote> +</li> +</ol> +</blockquote> +```````````````````````````````` + + + +6. **That's all.** Nothing that is not counted as a list item by rules + #1--5 counts as a [list item](#list-items). + +The rules for sublists follow from the general rules +[above][List items]. A sublist must be indented the same number +of spaces of indentation a paragraph would need to be in order to be included +in the list item. + +So, in this case we need two spaces indent: + +```````````````````````````````` example +- foo + - bar + - baz + - boo +. +<ul> +<li>foo +<ul> +<li>bar +<ul> +<li>baz +<ul> +<li>boo</li> +</ul> +</li> +</ul> +</li> +</ul> +</li> +</ul> +```````````````````````````````` + + +One is not enough: + +```````````````````````````````` example +- foo + - bar + - baz + - boo +. +<ul> +<li>foo</li> +<li>bar</li> +<li>baz</li> +<li>boo</li> +</ul> +```````````````````````````````` + + +Here we need four, because the list marker is wider: + +```````````````````````````````` example +10) foo + - bar +. +<ol start="10"> +<li>foo +<ul> +<li>bar</li> +</ul> +</li> +</ol> +```````````````````````````````` + + +Three is not enough: + +```````````````````````````````` example +10) foo + - bar +. +<ol start="10"> +<li>foo</li> +</ol> +<ul> +<li>bar</li> +</ul> +```````````````````````````````` + + +A list may be the first block in a list item: + +```````````````````````````````` example +- - foo +. +<ul> +<li> +<ul> +<li>foo</li> +</ul> +</li> +</ul> +```````````````````````````````` + + +```````````````````````````````` example +1. - 2. foo +. +<ol> +<li> +<ul> +<li> +<ol start="2"> +<li>foo</li> +</ol> +</li> +</ul> +</li> +</ol> +```````````````````````````````` + + +A list item can contain a heading: + +```````````````````````````````` example +- # Foo +- Bar + --- + baz +. +<ul> +<li> +<h1>Foo</h1> +</li> +<li> +<h2>Bar</h2> +baz</li> +</ul> +```````````````````````````````` + + +### Motivation + +John Gruber's Markdown spec says the following about list items: + +1. "List markers typically start at the left margin, but may be indented + by up to three spaces. List markers must be followed by one or more + spaces or a tab." + +2. "To make lists look nice, you can wrap items with hanging indents.... + But if you don't want to, you don't have to." + +3. "List items may consist of multiple paragraphs. Each subsequent + paragraph in a list item must be indented by either 4 spaces or one + tab." + +4. "It looks nice if you indent every line of the subsequent paragraphs, + but here again, Markdown will allow you to be lazy." + +5. "To put a blockquote within a list item, the blockquote's `>` + delimiters need to be indented." + +6. "To put a code block within a list item, the code block needs to be + indented twice — 8 spaces or two tabs." + +These rules specify that a paragraph under a list item must be indented +four spaces (presumably, from the left margin, rather than the start of +the list marker, but this is not said), and that code under a list item +must be indented eight spaces instead of the usual four. They also say +that a block quote must be indented, but not by how much; however, the +example given has four spaces indentation. Although nothing is said +about other kinds of block-level content, it is certainly reasonable to +infer that *all* block elements under a list item, including other +lists, must be indented four spaces. This principle has been called the +*four-space rule*. + +The four-space rule is clear and principled, and if the reference +implementation `Markdown.pl` had followed it, it probably would have +become the standard. However, `Markdown.pl` allowed paragraphs and +sublists to start with only two spaces indentation, at least on the +outer level. Worse, its behavior was inconsistent: a sublist of an +outer-level list needed two spaces indentation, but a sublist of this +sublist needed three spaces. It is not surprising, then, that different +implementations of Markdown have developed very different rules for +determining what comes under a list item. (Pandoc and python-Markdown, +for example, stuck with Gruber's syntax description and the four-space +rule, while discount, redcarpet, marked, PHP Markdown, and others +followed `Markdown.pl`'s behavior more closely.) + +Unfortunately, given the divergences between implementations, there +is no way to give a spec for list items that will be guaranteed not +to break any existing documents. However, the spec given here should +correctly handle lists formatted with either the four-space rule or +the more forgiving `Markdown.pl` behavior, provided they are laid out +in a way that is natural for a human to read. + +The strategy here is to let the width and indentation of the list marker +determine the indentation necessary for blocks to fall under the list +item, rather than having a fixed and arbitrary number. The writer can +think of the body of the list item as a unit which gets indented to the +right enough to fit the list marker (and any indentation on the list +marker). (The laziness rule, #5, then allows continuation lines to be +unindented if needed.) + +This rule is superior, we claim, to any rule requiring a fixed level of +indentation from the margin. The four-space rule is clear but +unnatural. It is quite unintuitive that + +``` markdown +- foo + + bar + + - baz +``` + +should be parsed as two lists with an intervening paragraph, + +``` html +<ul> +<li>foo</li> +</ul> +<p>bar</p> +<ul> +<li>baz</li> +</ul> +``` + +as the four-space rule demands, rather than a single list, + +``` html +<ul> +<li> +<p>foo</p> +<p>bar</p> +<ul> +<li>baz</li> +</ul> +</li> +</ul> +``` + +The choice of four spaces is arbitrary. It can be learned, but it is +not likely to be guessed, and it trips up beginners regularly. + +Would it help to adopt a two-space rule? The problem is that such +a rule, together with the rule allowing up to three spaces of indentation for +the initial list marker, allows text that is indented *less than* the +original list marker to be included in the list item. For example, +`Markdown.pl` parses + +``` markdown + - one + + two +``` + +as a single list item, with `two` a continuation paragraph: + +``` html +<ul> +<li> +<p>one</p> +<p>two</p> +</li> +</ul> +``` + +and similarly + +``` markdown +> - one +> +> two +``` + +as + +``` html +<blockquote> +<ul> +<li> +<p>one</p> +<p>two</p> +</li> +</ul> +</blockquote> +``` + +This is extremely unintuitive. + +Rather than requiring a fixed indent from the margin, we could require +a fixed indent (say, two spaces, or even one space) from the list marker (which +may itself be indented). This proposal would remove the last anomaly +discussed. Unlike the spec presented above, it would count the following +as a list item with a subparagraph, even though the paragraph `bar` +is not indented as far as the first paragraph `foo`: + +``` markdown + 10. foo + + bar +``` + +Arguably this text does read like a list item with `bar` as a subparagraph, +which may count in favor of the proposal. However, on this proposal indented +code would have to be indented six spaces after the list marker. And this +would break a lot of existing Markdown, which has the pattern: + +``` markdown +1. foo + + indented code +``` + +where the code is indented eight spaces. The spec above, by contrast, will +parse this text as expected, since the code block's indentation is measured +from the beginning of `foo`. + +The one case that needs special treatment is a list item that *starts* +with indented code. How much indentation is required in that case, since +we don't have a "first paragraph" to measure from? Rule #2 simply stipulates +that in such cases, we require one space indentation from the list marker +(and then the normal four spaces for the indented code). This will match the +four-space rule in cases where the list marker plus its initial indentation +takes four spaces (a common case), but diverge in other cases. + +## Lists + +A [list](@) is a sequence of one or more +list items [of the same type]. The list items +may be separated by any number of blank lines. + +Two list items are [of the same type](@) +if they begin with a [list marker] of the same type. +Two list markers are of the +same type if (a) they are bullet list markers using the same character +(`-`, `+`, or `*`) or (b) they are ordered list numbers with the same +delimiter (either `.` or `)`). + +A list is an [ordered list](@) +if its constituent list items begin with +[ordered list markers], and a +[bullet list](@) if its constituent list +items begin with [bullet list markers]. + +The [start number](@) +of an [ordered list] is determined by the list number of +its initial list item. The numbers of subsequent list items are +disregarded. + +A list is [loose](@) if any of its constituent +list items are separated by blank lines, or if any of its constituent +list items directly contain two block-level elements with a blank line +between them. Otherwise a list is [tight](@). +(The difference in HTML output is that paragraphs in a loose list are +wrapped in `<p>` tags, while paragraphs in a tight list are not.) + +Changing the bullet or ordered list delimiter starts a new list: + +```````````````````````````````` example +- foo +- bar ++ baz +. +<ul> +<li>foo</li> +<li>bar</li> +</ul> +<ul> +<li>baz</li> +</ul> +```````````````````````````````` + + +```````````````````````````````` example +1. foo +2. bar +3) baz +. +<ol> +<li>foo</li> +<li>bar</li> +</ol> +<ol start="3"> +<li>baz</li> +</ol> +```````````````````````````````` + + +In CommonMark, a list can interrupt a paragraph. That is, +no blank line is needed to separate a paragraph from a following +list: + +```````````````````````````````` example +Foo +- bar +- baz +. +<p>Foo</p> +<ul> +<li>bar</li> +<li>baz</li> +</ul> +```````````````````````````````` + +`Markdown.pl` does not allow this, through fear of triggering a list +via a numeral in a hard-wrapped line: + +``` markdown +The number of windows in my house is +14. The number of doors is 6. +``` + +Oddly, though, `Markdown.pl` *does* allow a blockquote to +interrupt a paragraph, even though the same considerations might +apply. + +In CommonMark, we do allow lists to interrupt paragraphs, for +two reasons. First, it is natural and not uncommon for people +to start lists without blank lines: + +``` markdown +I need to buy +- new shoes +- a coat +- a plane ticket +``` + +Second, we are attracted to a + +> [principle of uniformity](@): +> if a chunk of text has a certain +> meaning, it will continue to have the same meaning when put into a +> container block (such as a list item or blockquote). + +(Indeed, the spec for [list items] and [block quotes] presupposes +this principle.) This principle implies that if + +``` markdown + * I need to buy + - new shoes + - a coat + - a plane ticket +``` + +is a list item containing a paragraph followed by a nested sublist, +as all Markdown implementations agree it is (though the paragraph +may be rendered without `<p>` tags, since the list is "tight"), +then + +``` markdown +I need to buy +- new shoes +- a coat +- a plane ticket +``` + +by itself should be a paragraph followed by a nested sublist. + +Since it is well established Markdown practice to allow lists to +interrupt paragraphs inside list items, the [principle of +uniformity] requires us to allow this outside list items as +well. ([reStructuredText](http://docutils.sourceforge.net/rst.html) +takes a different approach, requiring blank lines before lists +even inside other list items.) + +In order to solve of unwanted lists in paragraphs with +hard-wrapped numerals, we allow only lists starting with `1` to +interrupt paragraphs. Thus, + +```````````````````````````````` example +The number of windows in my house is +14. The number of doors is 6. +. +<p>The number of windows in my house is +14. The number of doors is 6.</p> +```````````````````````````````` + +We may still get an unintended result in cases like + +```````````````````````````````` example +The number of windows in my house is +1. The number of doors is 6. +. +<p>The number of windows in my house is</p> +<ol> +<li>The number of doors is 6.</li> +</ol> +```````````````````````````````` + +but this rule should prevent most spurious list captures. + +There can be any number of blank lines between items: + +```````````````````````````````` example +- foo + +- bar + + +- baz +. +<ul> +<li> +<p>foo</p> +</li> +<li> +<p>bar</p> +</li> +<li> +<p>baz</p> +</li> +</ul> +```````````````````````````````` + +```````````````````````````````` example +- foo + - bar + - baz + + + bim +. +<ul> +<li>foo +<ul> +<li>bar +<ul> +<li> +<p>baz</p> +<p>bim</p> +</li> +</ul> +</li> +</ul> +</li> +</ul> +```````````````````````````````` + + +To separate consecutive lists of the same type, or to separate a +list from an indented code block that would otherwise be parsed +as a subparagraph of the final list item, you can insert a blank HTML +comment: + +```````````````````````````````` example +- foo +- bar + +<!-- --> + +- baz +- bim +. +<ul> +<li>foo</li> +<li>bar</li> +</ul> +<!-- --> +<ul> +<li>baz</li> +<li>bim</li> +</ul> +```````````````````````````````` + + +```````````````````````````````` example +- foo + + notcode + +- foo + +<!-- --> + + code +. +<ul> +<li> +<p>foo</p> +<p>notcode</p> +</li> +<li> +<p>foo</p> +</li> +</ul> +<!-- --> +<pre><code>code +</code></pre> +```````````````````````````````` + + +List items need not be indented to the same level. The following +list items will be treated as items at the same list level, +since none is indented enough to belong to the previous list +item: + +```````````````````````````````` example +- a + - b + - c + - d + - e + - f +- g +. +<ul> +<li>a</li> +<li>b</li> +<li>c</li> +<li>d</li> +<li>e</li> +<li>f</li> +<li>g</li> +</ul> +```````````````````````````````` + + +```````````````````````````````` example +1. a + + 2. b + + 3. c +. +<ol> +<li> +<p>a</p> +</li> +<li> +<p>b</p> +</li> +<li> +<p>c</p> +</li> +</ol> +```````````````````````````````` + +Note, however, that list items may not be preceded by more than +three spaces of indentation. Here `- e` is treated as a paragraph continuation +line, because it is indented more than three spaces: + +```````````````````````````````` example +- a + - b + - c + - d + - e +. +<ul> +<li>a</li> +<li>b</li> +<li>c</li> +<li>d +- e</li> +</ul> +```````````````````````````````` + +And here, `3. c` is treated as in indented code block, +because it is indented four spaces and preceded by a +blank line. + +```````````````````````````````` example +1. a + + 2. b + + 3. c +. +<ol> +<li> +<p>a</p> +</li> +<li> +<p>b</p> +</li> +</ol> +<pre><code>3. c +</code></pre> +```````````````````````````````` + + +This is a loose list, because there is a blank line between +two of the list items: + +```````````````````````````````` example +- a +- b + +- c +. +<ul> +<li> +<p>a</p> +</li> +<li> +<p>b</p> +</li> +<li> +<p>c</p> +</li> +</ul> +```````````````````````````````` + + +So is this, with a empty second item: + +```````````````````````````````` example +* a +* + +* c +. +<ul> +<li> +<p>a</p> +</li> +<li></li> +<li> +<p>c</p> +</li> +</ul> +```````````````````````````````` + + +These are loose lists, even though there are no blank lines between the items, +because one of the items directly contains two block-level elements +with a blank line between them: + +```````````````````````````````` example +- a +- b + + c +- d +. +<ul> +<li> +<p>a</p> +</li> +<li> +<p>b</p> +<p>c</p> +</li> +<li> +<p>d</p> +</li> +</ul> +```````````````````````````````` + + +```````````````````````````````` example +- a +- b + + [ref]: /url +- d +. +<ul> +<li> +<p>a</p> +</li> +<li> +<p>b</p> +</li> +<li> +<p>d</p> +</li> +</ul> +```````````````````````````````` + + +This is a tight list, because the blank lines are in a code block: + +```````````````````````````````` example +- a +- ``` + b + + + ``` +- c +. +<ul> +<li>a</li> +<li> +<pre><code>b + + +</code></pre> +</li> +<li>c</li> +</ul> +```````````````````````````````` + + +This is a tight list, because the blank line is between two +paragraphs of a sublist. So the sublist is loose while +the outer list is tight: + +```````````````````````````````` example +- a + - b + + c +- d +. +<ul> +<li>a +<ul> +<li> +<p>b</p> +<p>c</p> +</li> +</ul> +</li> +<li>d</li> +</ul> +```````````````````````````````` + + +This is a tight list, because the blank line is inside the +block quote: + +```````````````````````````````` example +* a + > b + > +* c +. +<ul> +<li>a +<blockquote> +<p>b</p> +</blockquote> +</li> +<li>c</li> +</ul> +```````````````````````````````` + + +This list is tight, because the consecutive block elements +are not separated by blank lines: + +```````````````````````````````` example +- a + > b + ``` + c + ``` +- d +. +<ul> +<li>a +<blockquote> +<p>b</p> +</blockquote> +<pre><code>c +</code></pre> +</li> +<li>d</li> +</ul> +```````````````````````````````` + + +A single-paragraph list is tight: + +```````````````````````````````` example +- a +. +<ul> +<li>a</li> +</ul> +```````````````````````````````` + + +```````````````````````````````` example +- a + - b +. +<ul> +<li>a +<ul> +<li>b</li> +</ul> +</li> +</ul> +```````````````````````````````` + + +This list is loose, because of the blank line between the +two block elements in the list item: + +```````````````````````````````` example +1. ``` + foo + ``` + + bar +. +<ol> +<li> +<pre><code>foo +</code></pre> +<p>bar</p> +</li> +</ol> +```````````````````````````````` + + +Here the outer list is loose, the inner list tight: + +```````````````````````````````` example +* foo + * bar + + baz +. +<ul> +<li> +<p>foo</p> +<ul> +<li>bar</li> +</ul> +<p>baz</p> +</li> +</ul> +```````````````````````````````` + + +```````````````````````````````` example +- a + - b + - c + +- d + - e + - f +. +<ul> +<li> +<p>a</p> +<ul> +<li>b</li> +<li>c</li> +</ul> +</li> +<li> +<p>d</p> +<ul> +<li>e</li> +<li>f</li> +</ul> +</li> +</ul> +```````````````````````````````` + + +# Inlines + +Inlines are parsed sequentially from the beginning of the character +stream to the end (left to right, in left-to-right languages). +Thus, for example, in + +```````````````````````````````` example +`hi`lo` +. +<p><code>hi</code>lo`</p> +```````````````````````````````` + +`hi` is parsed as code, leaving the backtick at the end as a literal +backtick. + + + +## Code spans + +A [backtick string](@) +is a string of one or more backtick characters (`` ` ``) that is neither +preceded nor followed by a backtick. + +A [code span](@) begins with a backtick string and ends with +a backtick string of equal length. The contents of the code span are +the characters between these two backtick strings, normalized in the +following ways: + +- First, [line endings] are converted to [spaces]. +- If the resulting string both begins *and* ends with a [space] + character, but does not consist entirely of [space] + characters, a single [space] character is removed from the + front and back. This allows you to include code that begins + or ends with backtick characters, which must be separated by + whitespace from the opening or closing backtick strings. + +This is a simple code span: + +```````````````````````````````` example +`foo` +. +<p><code>foo</code></p> +```````````````````````````````` + + +Here two backticks are used, because the code contains a backtick. +This example also illustrates stripping of a single leading and +trailing space: + +```````````````````````````````` example +`` foo ` bar `` +. +<p><code>foo ` bar</code></p> +```````````````````````````````` + + +This example shows the motivation for stripping leading and trailing +spaces: + +```````````````````````````````` example +` `` ` +. +<p><code>``</code></p> +```````````````````````````````` + +Note that only *one* space is stripped: + +```````````````````````````````` example +` `` ` +. +<p><code> `` </code></p> +```````````````````````````````` + +The stripping only happens if the space is on both +sides of the string: + +```````````````````````````````` example +` a` +. +<p><code> a</code></p> +```````````````````````````````` + +Only [spaces], and not [unicode whitespace] in general, are +stripped in this way: + +```````````````````````````````` example +` b ` +. +<p><code> b </code></p> +```````````````````````````````` + +No stripping occurs if the code span contains only spaces: + +```````````````````````````````` example +` ` +` ` +. +<p><code> </code> +<code> </code></p> +```````````````````````````````` + + +[Line endings] are treated like spaces: + +```````````````````````````````` example +`` +foo +bar +baz +`` +. +<p><code>foo bar baz</code></p> +```````````````````````````````` + +```````````````````````````````` example +`` +foo +`` +. +<p><code>foo </code></p> +```````````````````````````````` + + +Interior spaces are not collapsed: + +```````````````````````````````` example +`foo bar +baz` +. +<p><code>foo bar baz</code></p> +```````````````````````````````` + +Note that browsers will typically collapse consecutive spaces +when rendering `<code>` elements, so it is recommended that +the following CSS be used: + + code{white-space: pre-wrap;} + + +Note that backslash escapes do not work in code spans. All backslashes +are treated literally: + +```````````````````````````````` example +`foo\`bar` +. +<p><code>foo\</code>bar`</p> +```````````````````````````````` + + +Backslash escapes are never needed, because one can always choose a +string of *n* backtick characters as delimiters, where the code does +not contain any strings of exactly *n* backtick characters. + +```````````````````````````````` example +``foo`bar`` +. +<p><code>foo`bar</code></p> +```````````````````````````````` + +```````````````````````````````` example +` foo `` bar ` +. +<p><code>foo `` bar</code></p> +```````````````````````````````` + + +Code span backticks have higher precedence than any other inline +constructs except HTML tags and autolinks. Thus, for example, this is +not parsed as emphasized text, since the second `*` is part of a code +span: + +```````````````````````````````` example +*foo`*` +. +<p>*foo<code>*</code></p> +```````````````````````````````` + + +And this is not parsed as a link: + +```````````````````````````````` example +[not a `link](/foo`) +. +<p>[not a <code>link](/foo</code>)</p> +```````````````````````````````` + + +Code spans, HTML tags, and autolinks have the same precedence. +Thus, this is code: + +```````````````````````````````` example +`<a href="`">` +. +<p><code><a href="</code>">`</p> +```````````````````````````````` + + +But this is an HTML tag: + +```````````````````````````````` example +<a href="`">` +. +<p><a href="`">`</p> +```````````````````````````````` + + +And this is code: + +```````````````````````````````` example +`<http://foo.bar.`baz>` +. +<p><code><http://foo.bar.</code>baz>`</p> +```````````````````````````````` + + +But this is an autolink: + +```````````````````````````````` example +<http://foo.bar.`baz>` +. +<p><a href="http://foo.bar.%60baz">http://foo.bar.`baz</a>`</p> +```````````````````````````````` + + +When a backtick string is not closed by a matching backtick string, +we just have literal backticks: + +```````````````````````````````` example +```foo`` +. +<p>```foo``</p> +```````````````````````````````` + + +```````````````````````````````` example +`foo +. +<p>`foo</p> +```````````````````````````````` + +The following case also illustrates the need for opening and +closing backtick strings to be equal in length: + +```````````````````````````````` example +`foo``bar`` +. +<p>`foo<code>bar</code></p> +```````````````````````````````` + + +## Emphasis and strong emphasis + +John Gruber's original [Markdown syntax +description](http://daringfireball.net/projects/markdown/syntax#em) says: + +> Markdown treats asterisks (`*`) and underscores (`_`) as indicators of +> emphasis. Text wrapped with one `*` or `_` will be wrapped with an HTML +> `<em>` tag; double `*`'s or `_`'s will be wrapped with an HTML `<strong>` +> tag. + +This is enough for most users, but these rules leave much undecided, +especially when it comes to nested emphasis. The original +`Markdown.pl` test suite makes it clear that triple `***` and +`___` delimiters can be used for strong emphasis, and most +implementations have also allowed the following patterns: + +``` markdown +***strong emph*** +***strong** in emph* +***emph* in strong** +**in strong *emph*** +*in emph **strong*** +``` + +The following patterns are less widely supported, but the intent +is clear and they are useful (especially in contexts like bibliography +entries): + +``` markdown +*emph *with emph* in it* +**strong **with strong** in it** +``` + +Many implementations have also restricted intraword emphasis to +the `*` forms, to avoid unwanted emphasis in words containing +internal underscores. (It is best practice to put these in code +spans, but users often do not.) + +``` markdown +internal emphasis: foo*bar*baz +no emphasis: foo_bar_baz +``` + +The rules given below capture all of these patterns, while allowing +for efficient parsing strategies that do not backtrack. + +First, some definitions. A [delimiter run](@) is either +a sequence of one or more `*` characters that is not preceded or +followed by a non-backslash-escaped `*` character, or a sequence +of one or more `_` characters that is not preceded or followed by +a non-backslash-escaped `_` character. + +A [left-flanking delimiter run](@) is +a [delimiter run] that is (1) not followed by [Unicode whitespace], +and either (2a) not followed by a [Unicode punctuation character], or +(2b) followed by a [Unicode punctuation character] and +preceded by [Unicode whitespace] or a [Unicode punctuation character]. +For purposes of this definition, the beginning and the end of +the line count as Unicode whitespace. + +A [right-flanking delimiter run](@) is +a [delimiter run] that is (1) not preceded by [Unicode whitespace], +and either (2a) not preceded by a [Unicode punctuation character], or +(2b) preceded by a [Unicode punctuation character] and +followed by [Unicode whitespace] or a [Unicode punctuation character]. +For purposes of this definition, the beginning and the end of +the line count as Unicode whitespace. + +Here are some examples of delimiter runs. + + - left-flanking but not right-flanking: + + ``` + ***abc + _abc + **"abc" + _"abc" + ``` + + - right-flanking but not left-flanking: + + ``` + abc*** + abc_ + "abc"** + "abc"_ + ``` + + - Both left and right-flanking: + + ``` + abc***def + "abc"_"def" + ``` + + - Neither left nor right-flanking: + + ``` + abc *** def + a _ b + ``` + +(The idea of distinguishing left-flanking and right-flanking +delimiter runs based on the character before and the character +after comes from Roopesh Chander's +[vfmd](http://www.vfmd.org/vfmd-spec/specification/#procedure-for-identifying-emphasis-tags). +vfmd uses the terminology "emphasis indicator string" instead of "delimiter +run," and its rules for distinguishing left- and right-flanking runs +are a bit more complex than the ones given here.) + +The following rules define emphasis and strong emphasis: + +1. A single `*` character [can open emphasis](@) + iff (if and only if) it is part of a [left-flanking delimiter run]. + +2. A single `_` character [can open emphasis] iff + it is part of a [left-flanking delimiter run] + and either (a) not part of a [right-flanking delimiter run] + or (b) part of a [right-flanking delimiter run] + preceded by a [Unicode punctuation character]. + +3. A single `*` character [can close emphasis](@) + iff it is part of a [right-flanking delimiter run]. + +4. A single `_` character [can close emphasis] iff + it is part of a [right-flanking delimiter run] + and either (a) not part of a [left-flanking delimiter run] + or (b) part of a [left-flanking delimiter run] + followed by a [Unicode punctuation character]. + +5. A double `**` [can open strong emphasis](@) + iff it is part of a [left-flanking delimiter run]. + +6. A double `__` [can open strong emphasis] iff + it is part of a [left-flanking delimiter run] + and either (a) not part of a [right-flanking delimiter run] + or (b) part of a [right-flanking delimiter run] + preceded by a [Unicode punctuation character]. + +7. A double `**` [can close strong emphasis](@) + iff it is part of a [right-flanking delimiter run]. + +8. A double `__` [can close strong emphasis] iff + it is part of a [right-flanking delimiter run] + and either (a) not part of a [left-flanking delimiter run] + or (b) part of a [left-flanking delimiter run] + followed by a [Unicode punctuation character]. + +9. Emphasis begins with a delimiter that [can open emphasis] and ends + with a delimiter that [can close emphasis], and that uses the same + character (`_` or `*`) as the opening delimiter. The + opening and closing delimiters must belong to separate + [delimiter runs]. If one of the delimiters can both + open and close emphasis, then the sum of the lengths of the + delimiter runs containing the opening and closing delimiters + must not be a multiple of 3 unless both lengths are + multiples of 3. + +10. Strong emphasis begins with a delimiter that + [can open strong emphasis] and ends with a delimiter that + [can close strong emphasis], and that uses the same character + (`_` or `*`) as the opening delimiter. The + opening and closing delimiters must belong to separate + [delimiter runs]. If one of the delimiters can both open + and close strong emphasis, then the sum of the lengths of + the delimiter runs containing the opening and closing + delimiters must not be a multiple of 3 unless both lengths + are multiples of 3. + +11. A literal `*` character cannot occur at the beginning or end of + `*`-delimited emphasis or `**`-delimited strong emphasis, unless it + is backslash-escaped. + +12. A literal `_` character cannot occur at the beginning or end of + `_`-delimited emphasis or `__`-delimited strong emphasis, unless it + is backslash-escaped. + +Where rules 1--12 above are compatible with multiple parsings, +the following principles resolve ambiguity: + +13. The number of nestings should be minimized. Thus, for example, + an interpretation `<strong>...</strong>` is always preferred to + `<em><em>...</em></em>`. + +14. An interpretation `<em><strong>...</strong></em>` is always + preferred to `<strong><em>...</em></strong>`. + +15. When two potential emphasis or strong emphasis spans overlap, + so that the second begins before the first ends and ends after + the first ends, the first takes precedence. Thus, for example, + `*foo _bar* baz_` is parsed as `<em>foo _bar</em> baz_` rather + than `*foo <em>bar* baz</em>`. + +16. When there are two potential emphasis or strong emphasis spans + with the same closing delimiter, the shorter one (the one that + opens later) takes precedence. Thus, for example, + `**foo **bar baz**` is parsed as `**foo <strong>bar baz</strong>` + rather than `<strong>foo **bar baz</strong>`. + +17. Inline code spans, links, images, and HTML tags group more tightly + than emphasis. So, when there is a choice between an interpretation + that contains one of these elements and one that does not, the + former always wins. Thus, for example, `*[foo*](bar)` is + parsed as `*<a href="bar">foo*</a>` rather than as + `<em>[foo</em>](bar)`. + +These rules can be illustrated through a series of examples. + +Rule 1: + +```````````````````````````````` example +*foo bar* +. +<p><em>foo bar</em></p> +```````````````````````````````` + + +This is not emphasis, because the opening `*` is followed by +whitespace, and hence not part of a [left-flanking delimiter run]: + +```````````````````````````````` example +a * foo bar* +. +<p>a * foo bar*</p> +```````````````````````````````` + + +This is not emphasis, because the opening `*` is preceded +by an alphanumeric and followed by punctuation, and hence +not part of a [left-flanking delimiter run]: + +```````````````````````````````` example +a*"foo"* +. +<p>a*"foo"*</p> +```````````````````````````````` + + +Unicode nonbreaking spaces count as whitespace, too: + +```````````````````````````````` example +* a * +. +<p>* a *</p> +```````````````````````````````` + + +Intraword emphasis with `*` is permitted: + +```````````````````````````````` example +foo*bar* +. +<p>foo<em>bar</em></p> +```````````````````````````````` + + +```````````````````````````````` example +5*6*78 +. +<p>5<em>6</em>78</p> +```````````````````````````````` + + +Rule 2: + +```````````````````````````````` example +_foo bar_ +. +<p><em>foo bar</em></p> +```````````````````````````````` + + +This is not emphasis, because the opening `_` is followed by +whitespace: + +```````````````````````````````` example +_ foo bar_ +. +<p>_ foo bar_</p> +```````````````````````````````` + + +This is not emphasis, because the opening `_` is preceded +by an alphanumeric and followed by punctuation: + +```````````````````````````````` example +a_"foo"_ +. +<p>a_"foo"_</p> +```````````````````````````````` + + +Emphasis with `_` is not allowed inside words: + +```````````````````````````````` example +foo_bar_ +. +<p>foo_bar_</p> +```````````````````````````````` + + +```````````````````````````````` example +5_6_78 +. +<p>5_6_78</p> +```````````````````````````````` + + +```````````````````````````````` example +пристаням_стремятся_ +. +<p>пристаням_стремятся_</p> +```````````````````````````````` + + +Here `_` does not generate emphasis, because the first delimiter run +is right-flanking and the second left-flanking: + +```````````````````````````````` example +aa_"bb"_cc +. +<p>aa_"bb"_cc</p> +```````````````````````````````` + + +This is emphasis, even though the opening delimiter is +both left- and right-flanking, because it is preceded by +punctuation: + +```````````````````````````````` example +foo-_(bar)_ +. +<p>foo-<em>(bar)</em></p> +```````````````````````````````` + + +Rule 3: + +This is not emphasis, because the closing delimiter does +not match the opening delimiter: + +```````````````````````````````` example +_foo* +. +<p>_foo*</p> +```````````````````````````````` + + +This is not emphasis, because the closing `*` is preceded by +whitespace: + +```````````````````````````````` example +*foo bar * +. +<p>*foo bar *</p> +```````````````````````````````` + + +A line ending also counts as whitespace: + +```````````````````````````````` example +*foo bar +* +. +<p>*foo bar +*</p> +```````````````````````````````` + + +This is not emphasis, because the second `*` is +preceded by punctuation and followed by an alphanumeric +(hence it is not part of a [right-flanking delimiter run]: + +```````````````````````````````` example +*(*foo) +. +<p>*(*foo)</p> +```````````````````````````````` + + +The point of this restriction is more easily appreciated +with this example: + +```````````````````````````````` example +*(*foo*)* +. +<p><em>(<em>foo</em>)</em></p> +```````````````````````````````` + + +Intraword emphasis with `*` is allowed: + +```````````````````````````````` example +*foo*bar +. +<p><em>foo</em>bar</p> +```````````````````````````````` + + + +Rule 4: + +This is not emphasis, because the closing `_` is preceded by +whitespace: + +```````````````````````````````` example +_foo bar _ +. +<p>_foo bar _</p> +```````````````````````````````` + + +This is not emphasis, because the second `_` is +preceded by punctuation and followed by an alphanumeric: + +```````````````````````````````` example +_(_foo) +. +<p>_(_foo)</p> +```````````````````````````````` + + +This is emphasis within emphasis: + +```````````````````````````````` example +_(_foo_)_ +. +<p><em>(<em>foo</em>)</em></p> +```````````````````````````````` + + +Intraword emphasis is disallowed for `_`: + +```````````````````````````````` example +_foo_bar +. +<p>_foo_bar</p> +```````````````````````````````` + + +```````````````````````````````` example +_пристаням_стремятся +. +<p>_пристаням_стремятся</p> +```````````````````````````````` + + +```````````````````````````````` example +_foo_bar_baz_ +. +<p><em>foo_bar_baz</em></p> +```````````````````````````````` + + +This is emphasis, even though the closing delimiter is +both left- and right-flanking, because it is followed by +punctuation: + +```````````````````````````````` example +_(bar)_. +. +<p><em>(bar)</em>.</p> +```````````````````````````````` + + +Rule 5: + +```````````````````````````````` example +**foo bar** +. +<p><strong>foo bar</strong></p> +```````````````````````````````` + + +This is not strong emphasis, because the opening delimiter is +followed by whitespace: + +```````````````````````````````` example +** foo bar** +. +<p>** foo bar**</p> +```````````````````````````````` + + +This is not strong emphasis, because the opening `**` is preceded +by an alphanumeric and followed by punctuation, and hence +not part of a [left-flanking delimiter run]: + +```````````````````````````````` example +a**"foo"** +. +<p>a**"foo"**</p> +```````````````````````````````` + + +Intraword strong emphasis with `**` is permitted: + +```````````````````````````````` example +foo**bar** +. +<p>foo<strong>bar</strong></p> +```````````````````````````````` + + +Rule 6: + +```````````````````````````````` example +__foo bar__ +. +<p><strong>foo bar</strong></p> +```````````````````````````````` + + +This is not strong emphasis, because the opening delimiter is +followed by whitespace: + +```````````````````````````````` example +__ foo bar__ +. +<p>__ foo bar__</p> +```````````````````````````````` + + +A line ending counts as whitespace: +```````````````````````````````` example +__ +foo bar__ +. +<p>__ +foo bar__</p> +```````````````````````````````` + + +This is not strong emphasis, because the opening `__` is preceded +by an alphanumeric and followed by punctuation: + +```````````````````````````````` example +a__"foo"__ +. +<p>a__"foo"__</p> +```````````````````````````````` + + +Intraword strong emphasis is forbidden with `__`: + +```````````````````````````````` example +foo__bar__ +. +<p>foo__bar__</p> +```````````````````````````````` + + +```````````````````````````````` example +5__6__78 +. +<p>5__6__78</p> +```````````````````````````````` + + +```````````````````````````````` example +пристаням__стремятся__ +. +<p>пристаням__стремятся__</p> +```````````````````````````````` + + +```````````````````````````````` example +__foo, __bar__, baz__ +. +<p><strong>foo, <strong>bar</strong>, baz</strong></p> +```````````````````````````````` + + +This is strong emphasis, even though the opening delimiter is +both left- and right-flanking, because it is preceded by +punctuation: + +```````````````````````````````` example +foo-__(bar)__ +. +<p>foo-<strong>(bar)</strong></p> +```````````````````````````````` + + + +Rule 7: + +This is not strong emphasis, because the closing delimiter is preceded +by whitespace: + +```````````````````````````````` example +**foo bar ** +. +<p>**foo bar **</p> +```````````````````````````````` + + +(Nor can it be interpreted as an emphasized `*foo bar *`, because of +Rule 11.) + +This is not strong emphasis, because the second `**` is +preceded by punctuation and followed by an alphanumeric: + +```````````````````````````````` example +**(**foo) +. +<p>**(**foo)</p> +```````````````````````````````` + + +The point of this restriction is more easily appreciated +with these examples: + +```````````````````````````````` example +*(**foo**)* +. +<p><em>(<strong>foo</strong>)</em></p> +```````````````````````````````` + + +```````````````````````````````` example +**Gomphocarpus (*Gomphocarpus physocarpus*, syn. +*Asclepias physocarpa*)** +. +<p><strong>Gomphocarpus (<em>Gomphocarpus physocarpus</em>, syn. +<em>Asclepias physocarpa</em>)</strong></p> +```````````````````````````````` + + +```````````````````````````````` example +**foo "*bar*" foo** +. +<p><strong>foo "<em>bar</em>" foo</strong></p> +```````````````````````````````` + + +Intraword emphasis: + +```````````````````````````````` example +**foo**bar +. +<p><strong>foo</strong>bar</p> +```````````````````````````````` + + +Rule 8: + +This is not strong emphasis, because the closing delimiter is +preceded by whitespace: + +```````````````````````````````` example +__foo bar __ +. +<p>__foo bar __</p> +```````````````````````````````` + + +This is not strong emphasis, because the second `__` is +preceded by punctuation and followed by an alphanumeric: + +```````````````````````````````` example +__(__foo) +. +<p>__(__foo)</p> +```````````````````````````````` + + +The point of this restriction is more easily appreciated +with this example: + +```````````````````````````````` example +_(__foo__)_ +. +<p><em>(<strong>foo</strong>)</em></p> +```````````````````````````````` + + +Intraword strong emphasis is forbidden with `__`: + +```````````````````````````````` example +__foo__bar +. +<p>__foo__bar</p> +```````````````````````````````` + + +```````````````````````````````` example +__пристаням__стремятся +. +<p>__пристаням__стремятся</p> +```````````````````````````````` + + +```````````````````````````````` example +__foo__bar__baz__ +. +<p><strong>foo__bar__baz</strong></p> +```````````````````````````````` + + +This is strong emphasis, even though the closing delimiter is +both left- and right-flanking, because it is followed by +punctuation: + +```````````````````````````````` example +__(bar)__. +. +<p><strong>(bar)</strong>.</p> +```````````````````````````````` + + +Rule 9: + +Any nonempty sequence of inline elements can be the contents of an +emphasized span. + +```````````````````````````````` example +*foo [bar](/url)* +. +<p><em>foo <a href="/url">bar</a></em></p> +```````````````````````````````` + + +```````````````````````````````` example +*foo +bar* +. +<p><em>foo +bar</em></p> +```````````````````````````````` + + +In particular, emphasis and strong emphasis can be nested +inside emphasis: + +```````````````````````````````` example +_foo __bar__ baz_ +. +<p><em>foo <strong>bar</strong> baz</em></p> +```````````````````````````````` + + +```````````````````````````````` example +_foo _bar_ baz_ +. +<p><em>foo <em>bar</em> baz</em></p> +```````````````````````````````` + + +```````````````````````````````` example +__foo_ bar_ +. +<p><em><em>foo</em> bar</em></p> +```````````````````````````````` + + +```````````````````````````````` example +*foo *bar** +. +<p><em>foo <em>bar</em></em></p> +```````````````````````````````` + + +```````````````````````````````` example +*foo **bar** baz* +. +<p><em>foo <strong>bar</strong> baz</em></p> +```````````````````````````````` + +```````````````````````````````` example +*foo**bar**baz* +. +<p><em>foo<strong>bar</strong>baz</em></p> +```````````````````````````````` + +Note that in the preceding case, the interpretation + +``` markdown +<p><em>foo</em><em>bar<em></em>baz</em></p> +``` + + +is precluded by the condition that a delimiter that +can both open and close (like the `*` after `foo`) +cannot form emphasis if the sum of the lengths of +the delimiter runs containing the opening and +closing delimiters is a multiple of 3 unless +both lengths are multiples of 3. + + +For the same reason, we don't get two consecutive +emphasis sections in this example: + +```````````````````````````````` example +*foo**bar* +. +<p><em>foo**bar</em></p> +```````````````````````````````` + + +The same condition ensures that the following +cases are all strong emphasis nested inside +emphasis, even when the interior whitespace is +omitted: + + +```````````````````````````````` example +***foo** bar* +. +<p><em><strong>foo</strong> bar</em></p> +```````````````````````````````` + + +```````````````````````````````` example +*foo **bar*** +. +<p><em>foo <strong>bar</strong></em></p> +```````````````````````````````` + + +```````````````````````````````` example +*foo**bar*** +. +<p><em>foo<strong>bar</strong></em></p> +```````````````````````````````` + + +When the lengths of the interior closing and opening +delimiter runs are *both* multiples of 3, though, +they can match to create emphasis: + +```````````````````````````````` example +foo***bar***baz +. +<p>foo<em><strong>bar</strong></em>baz</p> +```````````````````````````````` + +```````````````````````````````` example +foo******bar*********baz +. +<p>foo<strong><strong><strong>bar</strong></strong></strong>***baz</p> +```````````````````````````````` + + +Indefinite levels of nesting are possible: + +```````````````````````````````` example +*foo **bar *baz* bim** bop* +. +<p><em>foo <strong>bar <em>baz</em> bim</strong> bop</em></p> +```````````````````````````````` + + +```````````````````````````````` example +*foo [*bar*](/url)* +. +<p><em>foo <a href="/url"><em>bar</em></a></em></p> +```````````````````````````````` + + +There can be no empty emphasis or strong emphasis: + +```````````````````````````````` example +** is not an empty emphasis +. +<p>** is not an empty emphasis</p> +```````````````````````````````` + + +```````````````````````````````` example +**** is not an empty strong emphasis +. +<p>**** is not an empty strong emphasis</p> +```````````````````````````````` + + + +Rule 10: + +Any nonempty sequence of inline elements can be the contents of an +strongly emphasized span. + +```````````````````````````````` example +**foo [bar](/url)** +. +<p><strong>foo <a href="/url">bar</a></strong></p> +```````````````````````````````` + + +```````````````````````````````` example +**foo +bar** +. +<p><strong>foo +bar</strong></p> +```````````````````````````````` + + +In particular, emphasis and strong emphasis can be nested +inside strong emphasis: + +```````````````````````````````` example +__foo _bar_ baz__ +. +<p><strong>foo <em>bar</em> baz</strong></p> +```````````````````````````````` + + +```````````````````````````````` example +__foo __bar__ baz__ +. +<p><strong>foo <strong>bar</strong> baz</strong></p> +```````````````````````````````` + + +```````````````````````````````` example +____foo__ bar__ +. +<p><strong><strong>foo</strong> bar</strong></p> +```````````````````````````````` + + +```````````````````````````````` example +**foo **bar**** +. +<p><strong>foo <strong>bar</strong></strong></p> +```````````````````````````````` + + +```````````````````````````````` example +**foo *bar* baz** +. +<p><strong>foo <em>bar</em> baz</strong></p> +```````````````````````````````` + + +```````````````````````````````` example +**foo*bar*baz** +. +<p><strong>foo<em>bar</em>baz</strong></p> +```````````````````````````````` + + +```````````````````````````````` example +***foo* bar** +. +<p><strong><em>foo</em> bar</strong></p> +```````````````````````````````` + + +```````````````````````````````` example +**foo *bar*** +. +<p><strong>foo <em>bar</em></strong></p> +```````````````````````````````` + + +Indefinite levels of nesting are possible: + +```````````````````````````````` example +**foo *bar **baz** +bim* bop** +. +<p><strong>foo <em>bar <strong>baz</strong> +bim</em> bop</strong></p> +```````````````````````````````` + + +```````````````````````````````` example +**foo [*bar*](/url)** +. +<p><strong>foo <a href="/url"><em>bar</em></a></strong></p> +```````````````````````````````` + + +There can be no empty emphasis or strong emphasis: + +```````````````````````````````` example +__ is not an empty emphasis +. +<p>__ is not an empty emphasis</p> +```````````````````````````````` + + +```````````````````````````````` example +____ is not an empty strong emphasis +. +<p>____ is not an empty strong emphasis</p> +```````````````````````````````` + + + +Rule 11: + +```````````````````````````````` example +foo *** +. +<p>foo ***</p> +```````````````````````````````` + + +```````````````````````````````` example +foo *\** +. +<p>foo <em>*</em></p> +```````````````````````````````` + + +```````````````````````````````` example +foo *_* +. +<p>foo <em>_</em></p> +```````````````````````````````` + + +```````````````````````````````` example +foo ***** +. +<p>foo *****</p> +```````````````````````````````` + + +```````````````````````````````` example +foo **\*** +. +<p>foo <strong>*</strong></p> +```````````````````````````````` + + +```````````````````````````````` example +foo **_** +. +<p>foo <strong>_</strong></p> +```````````````````````````````` + + +Note that when delimiters do not match evenly, Rule 11 determines +that the excess literal `*` characters will appear outside of the +emphasis, rather than inside it: + +```````````````````````````````` example +**foo* +. +<p>*<em>foo</em></p> +```````````````````````````````` + + +```````````````````````````````` example +*foo** +. +<p><em>foo</em>*</p> +```````````````````````````````` + + +```````````````````````````````` example +***foo** +. +<p>*<strong>foo</strong></p> +```````````````````````````````` + + +```````````````````````````````` example +****foo* +. +<p>***<em>foo</em></p> +```````````````````````````````` + + +```````````````````````````````` example +**foo*** +. +<p><strong>foo</strong>*</p> +```````````````````````````````` + + +```````````````````````````````` example +*foo**** +. +<p><em>foo</em>***</p> +```````````````````````````````` + + + +Rule 12: + +```````````````````````````````` example +foo ___ +. +<p>foo ___</p> +```````````````````````````````` + + +```````````````````````````````` example +foo _\__ +. +<p>foo <em>_</em></p> +```````````````````````````````` + + +```````````````````````````````` example +foo _*_ +. +<p>foo <em>*</em></p> +```````````````````````````````` + + +```````````````````````````````` example +foo _____ +. +<p>foo _____</p> +```````````````````````````````` + + +```````````````````````````````` example +foo __\___ +. +<p>foo <strong>_</strong></p> +```````````````````````````````` + + +```````````````````````````````` example +foo __*__ +. +<p>foo <strong>*</strong></p> +```````````````````````````````` + + +```````````````````````````````` example +__foo_ +. +<p>_<em>foo</em></p> +```````````````````````````````` + + +Note that when delimiters do not match evenly, Rule 12 determines +that the excess literal `_` characters will appear outside of the +emphasis, rather than inside it: + +```````````````````````````````` example +_foo__ +. +<p><em>foo</em>_</p> +```````````````````````````````` + + +```````````````````````````````` example +___foo__ +. +<p>_<strong>foo</strong></p> +```````````````````````````````` + + +```````````````````````````````` example +____foo_ +. +<p>___<em>foo</em></p> +```````````````````````````````` + + +```````````````````````````````` example +__foo___ +. +<p><strong>foo</strong>_</p> +```````````````````````````````` + + +```````````````````````````````` example +_foo____ +. +<p><em>foo</em>___</p> +```````````````````````````````` + + +Rule 13 implies that if you want emphasis nested directly inside +emphasis, you must use different delimiters: + +```````````````````````````````` example +**foo** +. +<p><strong>foo</strong></p> +```````````````````````````````` + + +```````````````````````````````` example +*_foo_* +. +<p><em><em>foo</em></em></p> +```````````````````````````````` + + +```````````````````````````````` example +__foo__ +. +<p><strong>foo</strong></p> +```````````````````````````````` + + +```````````````````````````````` example +_*foo*_ +. +<p><em><em>foo</em></em></p> +```````````````````````````````` + + +However, strong emphasis within strong emphasis is possible without +switching delimiters: + +```````````````````````````````` example +****foo**** +. +<p><strong><strong>foo</strong></strong></p> +```````````````````````````````` + + +```````````````````````````````` example +____foo____ +. +<p><strong><strong>foo</strong></strong></p> +```````````````````````````````` + + + +Rule 13 can be applied to arbitrarily long sequences of +delimiters: + +```````````````````````````````` example +******foo****** +. +<p><strong><strong><strong>foo</strong></strong></strong></p> +```````````````````````````````` + + +Rule 14: + +```````````````````````````````` example +***foo*** +. +<p><em><strong>foo</strong></em></p> +```````````````````````````````` + + +```````````````````````````````` example +_____foo_____ +. +<p><em><strong><strong>foo</strong></strong></em></p> +```````````````````````````````` + + +Rule 15: + +```````````````````````````````` example +*foo _bar* baz_ +. +<p><em>foo _bar</em> baz_</p> +```````````````````````````````` + + +```````````````````````````````` example +*foo __bar *baz bim__ bam* +. +<p><em>foo <strong>bar *baz bim</strong> bam</em></p> +```````````````````````````````` + + +Rule 16: + +```````````````````````````````` example +**foo **bar baz** +. +<p>**foo <strong>bar baz</strong></p> +```````````````````````````````` + + +```````````````````````````````` example +*foo *bar baz* +. +<p>*foo <em>bar baz</em></p> +```````````````````````````````` + + +Rule 17: + +```````````````````````````````` example +*[bar*](/url) +. +<p>*<a href="/url">bar*</a></p> +```````````````````````````````` + + +```````````````````````````````` example +_foo [bar_](/url) +. +<p>_foo <a href="/url">bar_</a></p> +```````````````````````````````` + + +```````````````````````````````` example +*<img src="foo" title="*"/> +. +<p>*<img src="foo" title="*"/></p> +```````````````````````````````` + + +```````````````````````````````` example +**<a href="**"> +. +<p>**<a href="**"></p> +```````````````````````````````` + + +```````````````````````````````` example +__<a href="__"> +. +<p>__<a href="__"></p> +```````````````````````````````` + + +```````````````````````````````` example +*a `*`* +. +<p><em>a <code>*</code></em></p> +```````````````````````````````` + + +```````````````````````````````` example +_a `_`_ +. +<p><em>a <code>_</code></em></p> +```````````````````````````````` + + +```````````````````````````````` example +**a<http://foo.bar/?q=**> +. +<p>**a<a href="http://foo.bar/?q=**">http://foo.bar/?q=**</a></p> +```````````````````````````````` + + +```````````````````````````````` example +__a<http://foo.bar/?q=__> +. +<p>__a<a href="http://foo.bar/?q=__">http://foo.bar/?q=__</a></p> +```````````````````````````````` + + + +## Links + +A link contains [link text] (the visible text), a [link destination] +(the URI that is the link destination), and optionally a [link title]. +There are two basic kinds of links in Markdown. In [inline links] the +destination and title are given immediately after the link text. In +[reference links] the destination and title are defined elsewhere in +the document. + +A [link text](@) consists of a sequence of zero or more +inline elements enclosed by square brackets (`[` and `]`). The +following rules apply: + +- Links may not contain other links, at any level of nesting. If + multiple otherwise valid link definitions appear nested inside each + other, the inner-most definition is used. + +- Brackets are allowed in the [link text] only if (a) they + are backslash-escaped or (b) they appear as a matched pair of brackets, + with an open bracket `[`, a sequence of zero or more inlines, and + a close bracket `]`. + +- Backtick [code spans], [autolinks], and raw [HTML tags] bind more tightly + than the brackets in link text. Thus, for example, + `` [foo`]` `` could not be a link text, since the second `]` + is part of a code span. + +- The brackets in link text bind more tightly than markers for + [emphasis and strong emphasis]. Thus, for example, `*[foo*](url)` is a link. + +A [link destination](@) consists of either + +- a sequence of zero or more characters between an opening `<` and a + closing `>` that contains no line endings or unescaped + `<` or `>` characters, or + +- a nonempty sequence of characters that does not start with `<`, + does not include [ASCII control characters][ASCII control character] + or [space] character, and includes parentheses only if (a) they are + backslash-escaped or (b) they are part of a balanced pair of + unescaped parentheses. + (Implementations may impose limits on parentheses nesting to + avoid performance issues, but at least three levels of nesting + should be supported.) + +A [link title](@) consists of either + +- a sequence of zero or more characters between straight double-quote + characters (`"`), including a `"` character only if it is + backslash-escaped, or + +- a sequence of zero or more characters between straight single-quote + characters (`'`), including a `'` character only if it is + backslash-escaped, or + +- a sequence of zero or more characters between matching parentheses + (`(...)`), including a `(` or `)` character only if it is + backslash-escaped. + +Although [link titles] may span multiple lines, they may not contain +a [blank line]. + +An [inline link](@) consists of a [link text] followed immediately +by a left parenthesis `(`, an optional [link destination], an optional +[link title], and a right parenthesis `)`. +These four components may be separated by spaces, tabs, and up to one line +ending. +If both [link destination] and [link title] are present, they *must* be +separated by spaces, tabs, and up to one line ending. + +The link's text consists of the inlines contained +in the [link text] (excluding the enclosing square brackets). +The link's URI consists of the link destination, excluding enclosing +`<...>` if present, with backslash-escapes in effect as described +above. The link's title consists of the link title, excluding its +enclosing delimiters, with backslash-escapes in effect as described +above. + +Here is a simple inline link: + +```````````````````````````````` example +[link](/uri "title") +. +<p><a href="/uri" title="title">link</a></p> +```````````````````````````````` + + +The title, the link text and even +the destination may be omitted: + +```````````````````````````````` example +[link](/uri) +. +<p><a href="/uri">link</a></p> +```````````````````````````````` + +```````````````````````````````` example +[](./target.md) +. +<p><a href="./target.md"></a></p> +```````````````````````````````` + + +```````````````````````````````` example +[link]() +. +<p><a href="">link</a></p> +```````````````````````````````` + + +```````````````````````````````` example +[link](<>) +. +<p><a href="">link</a></p> +```````````````````````````````` + + +```````````````````````````````` example +[]() +. +<p><a href=""></a></p> +```````````````````````````````` + +The destination can only contain spaces if it is +enclosed in pointy brackets: + +```````````````````````````````` example +[link](/my uri) +. +<p>[link](/my uri)</p> +```````````````````````````````` + +```````````````````````````````` example +[link](</my uri>) +. +<p><a href="/my%20uri">link</a></p> +```````````````````````````````` + +The destination cannot contain line endings, +even if enclosed in pointy brackets: + +```````````````````````````````` example +[link](foo +bar) +. +<p>[link](foo +bar)</p> +```````````````````````````````` + +```````````````````````````````` example +[link](<foo +bar>) +. +<p>[link](<foo +bar>)</p> +```````````````````````````````` + +The destination can contain `)` if it is enclosed +in pointy brackets: + +```````````````````````````````` example +[a](<b)c>) +. +<p><a href="b)c">a</a></p> +```````````````````````````````` + +Pointy brackets that enclose links must be unescaped: + +```````````````````````````````` example +[link](<foo\>) +. +<p>[link](<foo>)</p> +```````````````````````````````` + +These are not links, because the opening pointy bracket +is not matched properly: + +```````````````````````````````` example +[a](<b)c +[a](<b)c> +[a](<b>c) +. +<p>[a](<b)c +[a](<b)c> +[a](<b>c)</p> +```````````````````````````````` + +Parentheses inside the link destination may be escaped: + +```````````````````````````````` example +[link](\(foo\)) +. +<p><a href="(foo)">link</a></p> +```````````````````````````````` + +Any number of parentheses are allowed without escaping, as long as they are +balanced: + +```````````````````````````````` example +[link](foo(and(bar))) +. +<p><a href="foo(and(bar))">link</a></p> +```````````````````````````````` + +However, if you have unbalanced parentheses, you need to escape or use the +`<...>` form: + +```````````````````````````````` example +[link](foo(and(bar)) +. +<p>[link](foo(and(bar))</p> +```````````````````````````````` + + +```````````````````````````````` example +[link](foo\(and\(bar\)) +. +<p><a href="foo(and(bar)">link</a></p> +```````````````````````````````` + + +```````````````````````````````` example +[link](<foo(and(bar)>) +. +<p><a href="foo(and(bar)">link</a></p> +```````````````````````````````` + + +Parentheses and other symbols can also be escaped, as usual +in Markdown: + +```````````````````````````````` example +[link](foo\)\:) +. +<p><a href="foo):">link</a></p> +```````````````````````````````` + + +A link can contain fragment identifiers and queries: + +```````````````````````````````` example +[link](#fragment) + +[link](http://example.com#fragment) + +[link](http://example.com?foo=3#frag) +. +<p><a href="#fragment">link</a></p> +<p><a href="http://example.com#fragment">link</a></p> +<p><a href="http://example.com?foo=3#frag">link</a></p> +```````````````````````````````` + + +Note that a backslash before a non-escapable character is +just a backslash: + +```````````````````````````````` example +[link](foo\bar) +. +<p><a href="foo%5Cbar">link</a></p> +```````````````````````````````` + + +URL-escaping should be left alone inside the destination, as all +URL-escaped characters are also valid URL characters. Entity and +numerical character references in the destination will be parsed +into the corresponding Unicode code points, as usual. These may +be optionally URL-escaped when written as HTML, but this spec +does not enforce any particular policy for rendering URLs in +HTML or other formats. Renderers may make different decisions +about how to escape or normalize URLs in the output. + +```````````````````````````````` example +[link](foo%20bä) +. +<p><a href="foo%20b%C3%A4">link</a></p> +```````````````````````````````` + + +Note that, because titles can often be parsed as destinations, +if you try to omit the destination and keep the title, you'll +get unexpected results: + +```````````````````````````````` example +[link]("title") +. +<p><a href="%22title%22">link</a></p> +```````````````````````````````` + + +Titles may be in single quotes, double quotes, or parentheses: + +```````````````````````````````` example +[link](/url "title") +[link](/url 'title') +[link](/url (title)) +. +<p><a href="/url" title="title">link</a> +<a href="/url" title="title">link</a> +<a href="/url" title="title">link</a></p> +```````````````````````````````` + + +Backslash escapes and entity and numeric character references +may be used in titles: + +```````````````````````````````` example +[link](/url "title \""") +. +<p><a href="/url" title="title """>link</a></p> +```````````````````````````````` + + +Titles must be separated from the link using spaces, tabs, and up to one line +ending. +Other [Unicode whitespace] like non-breaking space doesn't work. + +```````````````````````````````` example +[link](/url "title") +. +<p><a href="/url%C2%A0%22title%22">link</a></p> +```````````````````````````````` + + +Nested balanced quotes are not allowed without escaping: + +```````````````````````````````` example +[link](/url "title "and" title") +. +<p>[link](/url "title "and" title")</p> +```````````````````````````````` + + +But it is easy to work around this by using a different quote type: + +```````````````````````````````` example +[link](/url 'title "and" title') +. +<p><a href="/url" title="title "and" title">link</a></p> +```````````````````````````````` + + +(Note: `Markdown.pl` did allow double quotes inside a double-quoted +title, and its test suite included a test demonstrating this. +But it is hard to see a good rationale for the extra complexity this +brings, since there are already many ways---backslash escaping, +entity and numeric character references, or using a different +quote type for the enclosing title---to write titles containing +double quotes. `Markdown.pl`'s handling of titles has a number +of other strange features. For example, it allows single-quoted +titles in inline links, but not reference links. And, in +reference links but not inline links, it allows a title to begin +with `"` and end with `)`. `Markdown.pl` 1.0.1 even allows +titles with no closing quotation mark, though 1.0.2b8 does not. +It seems preferable to adopt a simple, rational rule that works +the same way in inline links and link reference definitions.) + +Spaces, tabs, and up to one line ending is allowed around the destination and +title: + +```````````````````````````````` example +[link]( /uri + "title" ) +. +<p><a href="/uri" title="title">link</a></p> +```````````````````````````````` + + +But it is not allowed between the link text and the +following parenthesis: + +```````````````````````````````` example +[link] (/uri) +. +<p>[link] (/uri)</p> +```````````````````````````````` + + +The link text may contain balanced brackets, but not unbalanced ones, +unless they are escaped: + +```````````````````````````````` example +[link [foo [bar]]](/uri) +. +<p><a href="/uri">link [foo [bar]]</a></p> +```````````````````````````````` + + +```````````````````````````````` example +[link] bar](/uri) +. +<p>[link] bar](/uri)</p> +```````````````````````````````` + + +```````````````````````````````` example +[link [bar](/uri) +. +<p>[link <a href="/uri">bar</a></p> +```````````````````````````````` + + +```````````````````````````````` example +[link \[bar](/uri) +. +<p><a href="/uri">link [bar</a></p> +```````````````````````````````` + + +The link text may contain inline content: + +```````````````````````````````` example +[link *foo **bar** `#`*](/uri) +. +<p><a href="/uri">link <em>foo <strong>bar</strong> <code>#</code></em></a></p> +```````````````````````````````` + + +```````````````````````````````` example +[![moon](moon.jpg)](/uri) +. +<p><a href="/uri"><img src="moon.jpg" alt="moon" /></a></p> +```````````````````````````````` + + +However, links may not contain other links, at any level of nesting. + +```````````````````````````````` example +[foo [bar](/uri)](/uri) +. +<p>[foo <a href="/uri">bar</a>](/uri)</p> +```````````````````````````````` + + +```````````````````````````````` example +[foo *[bar [baz](/uri)](/uri)*](/uri) +. +<p>[foo <em>[bar <a href="/uri">baz</a>](/uri)</em>](/uri)</p> +```````````````````````````````` + + +```````````````````````````````` example +![[[foo](uri1)](uri2)](uri3) +. +<p><img src="uri3" alt="[foo](uri2)" /></p> +```````````````````````````````` + + +These cases illustrate the precedence of link text grouping over +emphasis grouping: + +```````````````````````````````` example +*[foo*](/uri) +. +<p>*<a href="/uri">foo*</a></p> +```````````````````````````````` + + +```````````````````````````````` example +[foo *bar](baz*) +. +<p><a href="baz*">foo *bar</a></p> +```````````````````````````````` + + +Note that brackets that *aren't* part of links do not take +precedence: + +```````````````````````````````` example +*foo [bar* baz] +. +<p><em>foo [bar</em> baz]</p> +```````````````````````````````` + + +These cases illustrate the precedence of HTML tags, code spans, +and autolinks over link grouping: + +```````````````````````````````` example +[foo <bar attr="](baz)"> +. +<p>[foo <bar attr="](baz)"></p> +```````````````````````````````` + + +```````````````````````````````` example +[foo`](/uri)` +. +<p>[foo<code>](/uri)</code></p> +```````````````````````````````` + + +```````````````````````````````` example +[foo<http://example.com/?search=](uri)> +. +<p>[foo<a href="http://example.com/?search=%5D(uri)">http://example.com/?search=](uri)</a></p> +```````````````````````````````` + + +There are three kinds of [reference link](@)s: +[full](#full-reference-link), [collapsed](#collapsed-reference-link), +and [shortcut](#shortcut-reference-link). + +A [full reference link](@) +consists of a [link text] immediately followed by a [link label] +that [matches] a [link reference definition] elsewhere in the document. + +A [link label](@) begins with a left bracket (`[`) and ends +with the first right bracket (`]`) that is not backslash-escaped. +Between these brackets there must be at least one character that is not a space, +tab, or line ending. +Unescaped square bracket characters are not allowed inside the +opening and closing square brackets of [link labels]. A link +label can have at most 999 characters inside the square +brackets. + +One label [matches](@) +another just in case their normalized forms are equal. To normalize a +label, strip off the opening and closing brackets, +perform the *Unicode case fold*, strip leading and trailing +spaces, tabs, and line endings, and collapse consecutive internal +spaces, tabs, and line endings to a single space. If there are multiple +matching reference link definitions, the one that comes first in the +document is used. (It is desirable in such cases to emit a warning.) + +The link's URI and title are provided by the matching [link +reference definition]. + +Here is a simple example: + +```````````````````````````````` example +[foo][bar] + +[bar]: /url "title" +. +<p><a href="/url" title="title">foo</a></p> +```````````````````````````````` + + +The rules for the [link text] are the same as with +[inline links]. Thus: + +The link text may contain balanced brackets, but not unbalanced ones, +unless they are escaped: + +```````````````````````````````` example +[link [foo [bar]]][ref] + +[ref]: /uri +. +<p><a href="/uri">link [foo [bar]]</a></p> +```````````````````````````````` + + +```````````````````````````````` example +[link \[bar][ref] + +[ref]: /uri +. +<p><a href="/uri">link [bar</a></p> +```````````````````````````````` + + +The link text may contain inline content: + +```````````````````````````````` example +[link *foo **bar** `#`*][ref] + +[ref]: /uri +. +<p><a href="/uri">link <em>foo <strong>bar</strong> <code>#</code></em></a></p> +```````````````````````````````` + + +```````````````````````````````` example +[![moon](moon.jpg)][ref] + +[ref]: /uri +. +<p><a href="/uri"><img src="moon.jpg" alt="moon" /></a></p> +```````````````````````````````` + + +However, links may not contain other links, at any level of nesting. + +```````````````````````````````` example +[foo [bar](/uri)][ref] + +[ref]: /uri +. +<p>[foo <a href="/uri">bar</a>]<a href="/uri">ref</a></p> +```````````````````````````````` + + +```````````````````````````````` example +[foo *bar [baz][ref]*][ref] + +[ref]: /uri +. +<p>[foo <em>bar <a href="/uri">baz</a></em>]<a href="/uri">ref</a></p> +```````````````````````````````` + + +(In the examples above, we have two [shortcut reference links] +instead of one [full reference link].) + +The following cases illustrate the precedence of link text grouping over +emphasis grouping: + +```````````````````````````````` example +*[foo*][ref] + +[ref]: /uri +. +<p>*<a href="/uri">foo*</a></p> +```````````````````````````````` + + +```````````````````````````````` example +[foo *bar][ref]* + +[ref]: /uri +. +<p><a href="/uri">foo *bar</a>*</p> +```````````````````````````````` + + +These cases illustrate the precedence of HTML tags, code spans, +and autolinks over link grouping: + +```````````````````````````````` example +[foo <bar attr="][ref]"> + +[ref]: /uri +. +<p>[foo <bar attr="][ref]"></p> +```````````````````````````````` + + +```````````````````````````````` example +[foo`][ref]` + +[ref]: /uri +. +<p>[foo<code>][ref]</code></p> +```````````````````````````````` + + +```````````````````````````````` example +[foo<http://example.com/?search=][ref]> + +[ref]: /uri +. +<p>[foo<a href="http://example.com/?search=%5D%5Bref%5D">http://example.com/?search=][ref]</a></p> +```````````````````````````````` + + +Matching is case-insensitive: + +```````````````````````````````` example +[foo][BaR] + +[bar]: /url "title" +. +<p><a href="/url" title="title">foo</a></p> +```````````````````````````````` + + +Unicode case fold is used: + +```````````````````````````````` example +[ẞ] + +[SS]: /url +. +<p><a href="/url">ẞ</a></p> +```````````````````````````````` + + +Consecutive internal spaces, tabs, and line endings are treated as one space for +purposes of determining matching: + +```````````````````````````````` example +[Foo + bar]: /url + +[Baz][Foo bar] +. +<p><a href="/url">Baz</a></p> +```````````````````````````````` + + +No spaces, tabs, or line endings are allowed between the [link text] and the +[link label]: + +```````````````````````````````` example +[foo] [bar] + +[bar]: /url "title" +. +<p>[foo] <a href="/url" title="title">bar</a></p> +```````````````````````````````` + + +```````````````````````````````` example +[foo] +[bar] + +[bar]: /url "title" +. +<p>[foo] +<a href="/url" title="title">bar</a></p> +```````````````````````````````` + + +This is a departure from John Gruber's original Markdown syntax +description, which explicitly allows whitespace between the link +text and the link label. It brings reference links in line with +[inline links], which (according to both original Markdown and +this spec) cannot have whitespace after the link text. More +importantly, it prevents inadvertent capture of consecutive +[shortcut reference links]. If whitespace is allowed between the +link text and the link label, then in the following we will have +a single reference link, not two shortcut reference links, as +intended: + +``` markdown +[foo] +[bar] + +[foo]: /url1 +[bar]: /url2 +``` + +(Note that [shortcut reference links] were introduced by Gruber +himself in a beta version of `Markdown.pl`, but never included +in the official syntax description. Without shortcut reference +links, it is harmless to allow space between the link text and +link label; but once shortcut references are introduced, it is +too dangerous to allow this, as it frequently leads to +unintended results.) + +When there are multiple matching [link reference definitions], +the first is used: + +```````````````````````````````` example +[foo]: /url1 + +[foo]: /url2 + +[bar][foo] +. +<p><a href="/url1">bar</a></p> +```````````````````````````````` + + +Note that matching is performed on normalized strings, not parsed +inline content. So the following does not match, even though the +labels define equivalent inline content: + +```````````````````````````````` example +[bar][foo\!] + +[foo!]: /url +. +<p>[bar][foo!]</p> +```````````````````````````````` + + +[Link labels] cannot contain brackets, unless they are +backslash-escaped: + +```````````````````````````````` example +[foo][ref[] + +[ref[]: /uri +. +<p>[foo][ref[]</p> +<p>[ref[]: /uri</p> +```````````````````````````````` + + +```````````````````````````````` example +[foo][ref[bar]] + +[ref[bar]]: /uri +. +<p>[foo][ref[bar]]</p> +<p>[ref[bar]]: /uri</p> +```````````````````````````````` + + +```````````````````````````````` example +[[[foo]]] + +[[[foo]]]: /url +. +<p>[[[foo]]]</p> +<p>[[[foo]]]: /url</p> +```````````````````````````````` + + +```````````````````````````````` example +[foo][ref\[] + +[ref\[]: /uri +. +<p><a href="/uri">foo</a></p> +```````````````````````````````` + + +Note that in this example `]` is not backslash-escaped: + +```````````````````````````````` example +[bar\\]: /uri + +[bar\\] +. +<p><a href="/uri">bar\</a></p> +```````````````````````````````` + + +A [link label] must contain at least one character that is not a space, tab, or +line ending: + +```````````````````````````````` example +[] + +[]: /uri +. +<p>[]</p> +<p>[]: /uri</p> +```````````````````````````````` + + +```````````````````````````````` example +[ + ] + +[ + ]: /uri +. +<p>[ +]</p> +<p>[ +]: /uri</p> +```````````````````````````````` + + +A [collapsed reference link](@) +consists of a [link label] that [matches] a +[link reference definition] elsewhere in the +document, followed by the string `[]`. +The contents of the first link label are parsed as inlines, +which are used as the link's text. The link's URI and title are +provided by the matching reference link definition. Thus, +`[foo][]` is equivalent to `[foo][foo]`. + +```````````````````````````````` example +[foo][] + +[foo]: /url "title" +. +<p><a href="/url" title="title">foo</a></p> +```````````````````````````````` + + +```````````````````````````````` example +[*foo* bar][] + +[*foo* bar]: /url "title" +. +<p><a href="/url" title="title"><em>foo</em> bar</a></p> +```````````````````````````````` + + +The link labels are case-insensitive: + +```````````````````````````````` example +[Foo][] + +[foo]: /url "title" +. +<p><a href="/url" title="title">Foo</a></p> +```````````````````````````````` + + + +As with full reference links, spaces, tabs, or line endings are not +allowed between the two sets of brackets: + +```````````````````````````````` example +[foo] +[] + +[foo]: /url "title" +. +<p><a href="/url" title="title">foo</a> +[]</p> +```````````````````````````````` + + +A [shortcut reference link](@) +consists of a [link label] that [matches] a +[link reference definition] elsewhere in the +document and is not followed by `[]` or a link label. +The contents of the first link label are parsed as inlines, +which are used as the link's text. The link's URI and title +are provided by the matching link reference definition. +Thus, `[foo]` is equivalent to `[foo][]`. + +```````````````````````````````` example +[foo] + +[foo]: /url "title" +. +<p><a href="/url" title="title">foo</a></p> +```````````````````````````````` + + +```````````````````````````````` example +[*foo* bar] + +[*foo* bar]: /url "title" +. +<p><a href="/url" title="title"><em>foo</em> bar</a></p> +```````````````````````````````` + + +```````````````````````````````` example +[[*foo* bar]] + +[*foo* bar]: /url "title" +. +<p>[<a href="/url" title="title"><em>foo</em> bar</a>]</p> +```````````````````````````````` + + +```````````````````````````````` example +[[bar [foo] + +[foo]: /url +. +<p>[[bar <a href="/url">foo</a></p> +```````````````````````````````` + + +The link labels are case-insensitive: + +```````````````````````````````` example +[Foo] + +[foo]: /url "title" +. +<p><a href="/url" title="title">Foo</a></p> +```````````````````````````````` + + +A space after the link text should be preserved: + +```````````````````````````````` example +[foo] bar + +[foo]: /url +. +<p><a href="/url">foo</a> bar</p> +```````````````````````````````` + + +If you just want bracketed text, you can backslash-escape the +opening bracket to avoid links: + +```````````````````````````````` example +\[foo] + +[foo]: /url "title" +. +<p>[foo]</p> +```````````````````````````````` + + +Note that this is a link, because a link label ends with the first +following closing bracket: + +```````````````````````````````` example +[foo*]: /url + +*[foo*] +. +<p>*<a href="/url">foo*</a></p> +```````````````````````````````` + + +Full and compact references take precedence over shortcut +references: + +```````````````````````````````` example +[foo][bar] + +[foo]: /url1 +[bar]: /url2 +. +<p><a href="/url2">foo</a></p> +```````````````````````````````` + +```````````````````````````````` example +[foo][] + +[foo]: /url1 +. +<p><a href="/url1">foo</a></p> +```````````````````````````````` + +Inline links also take precedence: + +```````````````````````````````` example +[foo]() + +[foo]: /url1 +. +<p><a href="">foo</a></p> +```````````````````````````````` + +```````````````````````````````` example +[foo](not a link) + +[foo]: /url1 +. +<p><a href="/url1">foo</a>(not a link)</p> +```````````````````````````````` + +In the following case `[bar][baz]` is parsed as a reference, +`[foo]` as normal text: + +```````````````````````````````` example +[foo][bar][baz] + +[baz]: /url +. +<p>[foo]<a href="/url">bar</a></p> +```````````````````````````````` + + +Here, though, `[foo][bar]` is parsed as a reference, since +`[bar]` is defined: + +```````````````````````````````` example +[foo][bar][baz] + +[baz]: /url1 +[bar]: /url2 +. +<p><a href="/url2">foo</a><a href="/url1">baz</a></p> +```````````````````````````````` + + +Here `[foo]` is not parsed as a shortcut reference, because it +is followed by a link label (even though `[bar]` is not defined): + +```````````````````````````````` example +[foo][bar][baz] + +[baz]: /url1 +[foo]: /url2 +. +<p>[foo]<a href="/url1">bar</a></p> +```````````````````````````````` + + + +## Images + +Syntax for images is like the syntax for links, with one +difference. Instead of [link text], we have an +[image description](@). The rules for this are the +same as for [link text], except that (a) an +image description starts with `![` rather than `[`, and +(b) an image description may contain links. +An image description has inline elements +as its contents. When an image is rendered to HTML, +this is standardly used as the image's `alt` attribute. + +```````````````````````````````` example +![foo](/url "title") +. +<p><img src="/url" alt="foo" title="title" /></p> +```````````````````````````````` + + +```````````````````````````````` example +![foo *bar*] + +[foo *bar*]: train.jpg "train & tracks" +. +<p><img src="train.jpg" alt="foo bar" title="train & tracks" /></p> +```````````````````````````````` + + +```````````````````````````````` example +![foo ![bar](/url)](/url2) +. +<p><img src="/url2" alt="foo bar" /></p> +```````````````````````````````` + + +```````````````````````````````` example +![foo [bar](/url)](/url2) +. +<p><img src="/url2" alt="foo bar" /></p> +```````````````````````````````` + + +Though this spec is concerned with parsing, not rendering, it is +recommended that in rendering to HTML, only the plain string content +of the [image description] be used. Note that in +the above example, the alt attribute's value is `foo bar`, not `foo +[bar](/url)` or `foo <a href="/url">bar</a>`. Only the plain string +content is rendered, without formatting. + +```````````````````````````````` example +![foo *bar*][] + +[foo *bar*]: train.jpg "train & tracks" +. +<p><img src="train.jpg" alt="foo bar" title="train & tracks" /></p> +```````````````````````````````` + + +```````````````````````````````` example +![foo *bar*][foobar] + +[FOOBAR]: train.jpg "train & tracks" +. +<p><img src="train.jpg" alt="foo bar" title="train & tracks" /></p> +```````````````````````````````` + + +```````````````````````````````` example +![foo](train.jpg) +. +<p><img src="train.jpg" alt="foo" /></p> +```````````````````````````````` + + +```````````````````````````````` example +My ![foo bar](/path/to/train.jpg "title" ) +. +<p>My <img src="/path/to/train.jpg" alt="foo bar" title="title" /></p> +```````````````````````````````` + + +```````````````````````````````` example +![foo](<url>) +. +<p><img src="url" alt="foo" /></p> +```````````````````````````````` + + +```````````````````````````````` example +![](/url) +. +<p><img src="/url" alt="" /></p> +```````````````````````````````` + + +Reference-style: + +```````````````````````````````` example +![foo][bar] + +[bar]: /url +. +<p><img src="/url" alt="foo" /></p> +```````````````````````````````` + + +```````````````````````````````` example +![foo][bar] + +[BAR]: /url +. +<p><img src="/url" alt="foo" /></p> +```````````````````````````````` + + +Collapsed: + +```````````````````````````````` example +![foo][] + +[foo]: /url "title" +. +<p><img src="/url" alt="foo" title="title" /></p> +```````````````````````````````` + + +```````````````````````````````` example +![*foo* bar][] + +[*foo* bar]: /url "title" +. +<p><img src="/url" alt="foo bar" title="title" /></p> +```````````````````````````````` + + +The labels are case-insensitive: + +```````````````````````````````` example +![Foo][] + +[foo]: /url "title" +. +<p><img src="/url" alt="Foo" title="title" /></p> +```````````````````````````````` + + +As with reference links, spaces, tabs, and line endings, are not allowed +between the two sets of brackets: + +```````````````````````````````` example +![foo] +[] + +[foo]: /url "title" +. +<p><img src="/url" alt="foo" title="title" /> +[]</p> +```````````````````````````````` + + +Shortcut: + +```````````````````````````````` example +![foo] + +[foo]: /url "title" +. +<p><img src="/url" alt="foo" title="title" /></p> +```````````````````````````````` + + +```````````````````````````````` example +![*foo* bar] + +[*foo* bar]: /url "title" +. +<p><img src="/url" alt="foo bar" title="title" /></p> +```````````````````````````````` + + +Note that link labels cannot contain unescaped brackets: + +```````````````````````````````` example +![[foo]] + +[[foo]]: /url "title" +. +<p>![[foo]]</p> +<p>[[foo]]: /url "title"</p> +```````````````````````````````` + + +The link labels are case-insensitive: + +```````````````````````````````` example +![Foo] + +[foo]: /url "title" +. +<p><img src="/url" alt="Foo" title="title" /></p> +```````````````````````````````` + + +If you just want a literal `!` followed by bracketed text, you can +backslash-escape the opening `[`: + +```````````````````````````````` example +!\[foo] + +[foo]: /url "title" +. +<p>![foo]</p> +```````````````````````````````` + + +If you want a link after a literal `!`, backslash-escape the +`!`: + +```````````````````````````````` example +\![foo] + +[foo]: /url "title" +. +<p>!<a href="/url" title="title">foo</a></p> +```````````````````````````````` + + +## Autolinks + +[Autolink](@)s are absolute URIs and email addresses inside +`<` and `>`. They are parsed as links, with the URL or email address +as the link label. + +A [URI autolink](@) consists of `<`, followed by an +[absolute URI] followed by `>`. It is parsed as +a link to the URI, with the URI as the link's label. + +An [absolute URI](@), +for these purposes, consists of a [scheme] followed by a colon (`:`) +followed by zero or more characters other [ASCII control +characters][ASCII control character], [space], `<`, and `>`. +If the URI includes these characters, they must be percent-encoded +(e.g. `%20` for a space). + +For purposes of this spec, a [scheme](@) is any sequence +of 2--32 characters beginning with an ASCII letter and followed +by any combination of ASCII letters, digits, or the symbols plus +("+"), period ("."), or hyphen ("-"). + +Here are some valid autolinks: + +```````````````````````````````` example +<http://foo.bar.baz> +. +<p><a href="http://foo.bar.baz">http://foo.bar.baz</a></p> +```````````````````````````````` + + +```````````````````````````````` example +<http://foo.bar.baz/test?q=hello&id=22&boolean> +. +<p><a href="http://foo.bar.baz/test?q=hello&id=22&boolean">http://foo.bar.baz/test?q=hello&id=22&boolean</a></p> +```````````````````````````````` + + +```````````````````````````````` example +<irc://foo.bar:2233/baz> +. +<p><a href="irc://foo.bar:2233/baz">irc://foo.bar:2233/baz</a></p> +```````````````````````````````` + + +Uppercase is also fine: + +```````````````````````````````` example +<MAILTO:FOO@BAR.BAZ> +. +<p><a href="MAILTO:FOO@BAR.BAZ">MAILTO:FOO@BAR.BAZ</a></p> +```````````````````````````````` + + +Note that many strings that count as [absolute URIs] for +purposes of this spec are not valid URIs, because their +schemes are not registered or because of other problems +with their syntax: + +```````````````````````````````` example +<a+b+c:d> +. +<p><a href="a+b+c:d">a+b+c:d</a></p> +```````````````````````````````` + + +```````````````````````````````` example +<made-up-scheme://foo,bar> +. +<p><a href="made-up-scheme://foo,bar">made-up-scheme://foo,bar</a></p> +```````````````````````````````` + + +```````````````````````````````` example +<http://../> +. +<p><a href="http://../">http://../</a></p> +```````````````````````````````` + + +```````````````````````````````` example +<localhost:5001/foo> +. +<p><a href="localhost:5001/foo">localhost:5001/foo</a></p> +```````````````````````````````` + + +Spaces are not allowed in autolinks: + +```````````````````````````````` example +<http://foo.bar/baz bim> +. +<p><http://foo.bar/baz bim></p> +```````````````````````````````` + + +Backslash-escapes do not work inside autolinks: + +```````````````````````````````` example +<http://example.com/\[\> +. +<p><a href="http://example.com/%5C%5B%5C">http://example.com/\[\</a></p> +```````````````````````````````` + + +An [email autolink](@) +consists of `<`, followed by an [email address], +followed by `>`. The link's label is the email address, +and the URL is `mailto:` followed by the email address. + +An [email address](@), +for these purposes, is anything that matches +the [non-normative regex from the HTML5 +spec](https://html.spec.whatwg.org/multipage/forms.html#e-mail-state-(type=email)): + + /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])? + (?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/ + +Examples of email autolinks: + +```````````````````````````````` example +<foo@bar.example.com> +. +<p><a href="mailto:foo@bar.example.com">foo@bar.example.com</a></p> +```````````````````````````````` + + +```````````````````````````````` example +<foo+special@Bar.baz-bar0.com> +. +<p><a href="mailto:foo+special@Bar.baz-bar0.com">foo+special@Bar.baz-bar0.com</a></p> +```````````````````````````````` + + +Backslash-escapes do not work inside email autolinks: + +```````````````````````````````` example +<foo\+@bar.example.com> +. +<p><foo+@bar.example.com></p> +```````````````````````````````` + + +These are not autolinks: + +```````````````````````````````` example +<> +. +<p><></p> +```````````````````````````````` + + +```````````````````````````````` example +< http://foo.bar > +. +<p>< http://foo.bar ></p> +```````````````````````````````` + + +```````````````````````````````` example +<m:abc> +. +<p><m:abc></p> +```````````````````````````````` + + +```````````````````````````````` example +<foo.bar.baz> +. +<p><foo.bar.baz></p> +```````````````````````````````` + + +```````````````````````````````` example +http://example.com +. +<p>http://example.com</p> +```````````````````````````````` + + +```````````````````````````````` example +foo@bar.example.com +. +<p>foo@bar.example.com</p> +```````````````````````````````` + + +## Raw HTML + +Text between `<` and `>` that looks like an HTML tag is parsed as a +raw HTML tag and will be rendered in HTML without escaping. +Tag and attribute names are not limited to current HTML tags, +so custom tags (and even, say, DocBook tags) may be used. + +Here is the grammar for tags: + +A [tag name](@) consists of an ASCII letter +followed by zero or more ASCII letters, digits, or +hyphens (`-`). + +An [attribute](@) consists of spaces, tabs, and up to one line ending, +an [attribute name], and an optional +[attribute value specification]. + +An [attribute name](@) +consists of an ASCII letter, `_`, or `:`, followed by zero or more ASCII +letters, digits, `_`, `.`, `:`, or `-`. (Note: This is the XML +specification restricted to ASCII. HTML5 is laxer.) + +An [attribute value specification](@) +consists of optional spaces, tabs, and up to one line ending, +a `=` character, optional spaces, tabs, and up to one line ending, +and an [attribute value]. + +An [attribute value](@) +consists of an [unquoted attribute value], +a [single-quoted attribute value], or a [double-quoted attribute value]. + +An [unquoted attribute value](@) +is a nonempty string of characters not +including spaces, tabs, line endings, `"`, `'`, `=`, `<`, `>`, or `` ` ``. + +A [single-quoted attribute value](@) +consists of `'`, zero or more +characters not including `'`, and a final `'`. + +A [double-quoted attribute value](@) +consists of `"`, zero or more +characters not including `"`, and a final `"`. + +An [open tag](@) consists of a `<` character, a [tag name], +zero or more [attributes], optional spaces, tabs, and up to one line ending, +an optional `/` character, and a `>` character. + +A [closing tag](@) consists of the string `</`, a +[tag name], optional spaces, tabs, and up to one line ending, and the character +`>`. + +An [HTML comment](@) consists of `<!--` + *text* + `-->`, +where *text* does not start with `>` or `->`, does not end with `-`, +and does not contain `--`. (See the +[HTML5 spec](http://www.w3.org/TR/html5/syntax.html#comments).) + +A [processing instruction](@) +consists of the string `<?`, a string +of characters not including the string `?>`, and the string +`?>`. + +A [declaration](@) consists of the string `<!`, an ASCII letter, zero or more +characters not including the character `>`, and the character `>`. + +A [CDATA section](@) consists of +the string `<![CDATA[`, a string of characters not including the string +`]]>`, and the string `]]>`. + +An [HTML tag](@) consists of an [open tag], a [closing tag], +an [HTML comment], a [processing instruction], a [declaration], +or a [CDATA section]. + +Here are some simple open tags: + +```````````````````````````````` example +<a><bab><c2c> +. +<p><a><bab><c2c></p> +```````````````````````````````` + + +Empty elements: + +```````````````````````````````` example +<a/><b2/> +. +<p><a/><b2/></p> +```````````````````````````````` + + +Whitespace is allowed: + +```````````````````````````````` example +<a /><b2 +data="foo" > +. +<p><a /><b2 +data="foo" ></p> +```````````````````````````````` + + +With attributes: + +```````````````````````````````` example +<a foo="bar" bam = 'baz <em>"</em>' +_boolean zoop:33=zoop:33 /> +. +<p><a foo="bar" bam = 'baz <em>"</em>' +_boolean zoop:33=zoop:33 /></p> +```````````````````````````````` + + +Custom tag names can be used: + +```````````````````````````````` example +Foo <responsive-image src="foo.jpg" /> +. +<p>Foo <responsive-image src="foo.jpg" /></p> +```````````````````````````````` + + +Illegal tag names, not parsed as HTML: + +```````````````````````````````` example +<33> <__> +. +<p><33> <__></p> +```````````````````````````````` + + +Illegal attribute names: + +```````````````````````````````` example +<a h*#ref="hi"> +. +<p><a h*#ref="hi"></p> +```````````````````````````````` + + +Illegal attribute values: + +```````````````````````````````` example +<a href="hi'> <a href=hi'> +. +<p><a href="hi'> <a href=hi'></p> +```````````````````````````````` + + +Illegal whitespace: + +```````````````````````````````` example +< a>< +foo><bar/ > +<foo bar=baz +bim!bop /> +. +<p>< a>< +foo><bar/ > +<foo bar=baz +bim!bop /></p> +```````````````````````````````` + + +Missing whitespace: + +```````````````````````````````` example +<a href='bar'title=title> +. +<p><a href='bar'title=title></p> +```````````````````````````````` + + +Closing tags: + +```````````````````````````````` example +</a></foo > +. +<p></a></foo ></p> +```````````````````````````````` + + +Illegal attributes in closing tag: + +```````````````````````````````` example +</a href="foo"> +. +<p></a href="foo"></p> +```````````````````````````````` + + +Comments: + +```````````````````````````````` example +foo <!-- this is a +comment - with hyphen --> +. +<p>foo <!-- this is a +comment - with hyphen --></p> +```````````````````````````````` + + +```````````````````````````````` example +foo <!-- not a comment -- two hyphens --> +. +<p>foo <!-- not a comment -- two hyphens --></p> +```````````````````````````````` + + +Not comments: + +```````````````````````````````` example +foo <!--> foo --> + +foo <!-- foo---> +. +<p>foo <!--> foo --></p> +<p>foo <!-- foo---></p> +```````````````````````````````` + + +Processing instructions: + +```````````````````````````````` example +foo <?php echo $a; ?> +. +<p>foo <?php echo $a; ?></p> +```````````````````````````````` + + +Declarations: + +```````````````````````````````` example +foo <!ELEMENT br EMPTY> +. +<p>foo <!ELEMENT br EMPTY></p> +```````````````````````````````` + + +CDATA sections: + +```````````````````````````````` example +foo <![CDATA[>&<]]> +. +<p>foo <![CDATA[>&<]]></p> +```````````````````````````````` + + +Entity and numeric character references are preserved in HTML +attributes: + +```````````````````````````````` example +foo <a href="ö"> +. +<p>foo <a href="ö"></p> +```````````````````````````````` + + +Backslash escapes do not work in HTML attributes: + +```````````````````````````````` example +foo <a href="\*"> +. +<p>foo <a href="\*"></p> +```````````````````````````````` + + +```````````````````````````````` example +<a href="\""> +. +<p><a href="""></p> +```````````````````````````````` + + +## Hard line breaks + +A line ending (not in a code span or HTML tag) that is preceded +by two or more spaces and does not occur at the end of a block +is parsed as a [hard line break](@) (rendered +in HTML as a `<br />` tag): + +```````````````````````````````` example +foo +baz +. +<p>foo<br /> +baz</p> +```````````````````````````````` + + +For a more visible alternative, a backslash before the +[line ending] may be used instead of two or more spaces: + +```````````````````````````````` example +foo\ +baz +. +<p>foo<br /> +baz</p> +```````````````````````````````` + + +More than two spaces can be used: + +```````````````````````````````` example +foo +baz +. +<p>foo<br /> +baz</p> +```````````````````````````````` + + +Leading spaces at the beginning of the next line are ignored: + +```````````````````````````````` example +foo + bar +. +<p>foo<br /> +bar</p> +```````````````````````````````` + + +```````````````````````````````` example +foo\ + bar +. +<p>foo<br /> +bar</p> +```````````````````````````````` + + +Hard line breaks can occur inside emphasis, links, and other constructs +that allow inline content: + +```````````````````````````````` example +*foo +bar* +. +<p><em>foo<br /> +bar</em></p> +```````````````````````````````` + + +```````````````````````````````` example +*foo\ +bar* +. +<p><em>foo<br /> +bar</em></p> +```````````````````````````````` + + +Hard line breaks do not occur inside code spans + +```````````````````````````````` example +`code +span` +. +<p><code>code span</code></p> +```````````````````````````````` + + +```````````````````````````````` example +`code\ +span` +. +<p><code>code\ span</code></p> +```````````````````````````````` + + +or HTML tags: + +```````````````````````````````` example +<a href="foo +bar"> +. +<p><a href="foo +bar"></p> +```````````````````````````````` + + +```````````````````````````````` example +<a href="foo\ +bar"> +. +<p><a href="foo\ +bar"></p> +```````````````````````````````` + + +Hard line breaks are for separating inline content within a block. +Neither syntax for hard line breaks works at the end of a paragraph or +other block element: + +```````````````````````````````` example +foo\ +. +<p>foo\</p> +```````````````````````````````` + + +```````````````````````````````` example +foo +. +<p>foo</p> +```````````````````````````````` + + +```````````````````````````````` example +### foo\ +. +<h3>foo\</h3> +```````````````````````````````` + + +```````````````````````````````` example +### foo +. +<h3>foo</h3> +```````````````````````````````` + + +## Soft line breaks + +A regular line ending (not in a code span or HTML tag) that is not +preceded by two or more spaces or a backslash is parsed as a +[softbreak](@). (A soft line break may be rendered in HTML either as a +[line ending] or as a space. The result will be the same in +browsers. In the examples here, a [line ending] will be used.) + +```````````````````````````````` example +foo +baz +. +<p>foo +baz</p> +```````````````````````````````` + + +Spaces at the end of the line and beginning of the next line are +removed: + +```````````````````````````````` example +foo + baz +. +<p>foo +baz</p> +```````````````````````````````` + + +A conforming parser may render a soft line break in HTML either as a +line ending or as a space. + +A renderer may also provide an option to render soft line breaks +as hard line breaks. + +## Textual content + +Any characters not given an interpretation by the above rules will +be parsed as plain textual content. + +```````````````````````````````` example +hello $.;'there +. +<p>hello $.;'there</p> +```````````````````````````````` + + +```````````````````````````````` example +Foo χρῆν +. +<p>Foo χρῆν</p> +```````````````````````````````` + + +Internal spaces are preserved verbatim: + +```````````````````````````````` example +Multiple spaces +. +<p>Multiple spaces</p> +```````````````````````````````` + + +<!-- END TESTS --> + +# Appendix: A parsing strategy + +In this appendix we describe some features of the parsing strategy +used in the CommonMark reference implementations. + +## Overview + +Parsing has two phases: + +1. In the first phase, lines of input are consumed and the block +structure of the document---its division into paragraphs, block quotes, +list items, and so on---is constructed. Text is assigned to these +blocks but not parsed. Link reference definitions are parsed and a +map of links is constructed. + +2. In the second phase, the raw text contents of paragraphs and headings +are parsed into sequences of Markdown inline elements (strings, +code spans, links, emphasis, and so on), using the map of link +references constructed in phase 1. + +At each point in processing, the document is represented as a tree of +**blocks**. The root of the tree is a `document` block. The `document` +may have any number of other blocks as **children**. These children +may, in turn, have other blocks as children. The last child of a block +is normally considered **open**, meaning that subsequent lines of input +can alter its contents. (Blocks that are not open are **closed**.) +Here, for example, is a possible document tree, with the open blocks +marked by arrows: + +``` tree +-> document + -> block_quote + paragraph + "Lorem ipsum dolor\nsit amet." + -> list (type=bullet tight=true bullet_char=-) + list_item + paragraph + "Qui *quodsi iracundia*" + -> list_item + -> paragraph + "aliquando id" +``` + +## Phase 1: block structure + +Each line that is processed has an effect on this tree. The line is +analyzed and, depending on its contents, the document may be altered +in one or more of the following ways: + +1. One or more open blocks may be closed. +2. One or more new blocks may be created as children of the + last open block. +3. Text may be added to the last (deepest) open block remaining + on the tree. + +Once a line has been incorporated into the tree in this way, +it can be discarded, so input can be read in a stream. + +For each line, we follow this procedure: + +1. First we iterate through the open blocks, starting with the +root document, and descending through last children down to the last +open block. Each block imposes a condition that the line must satisfy +if the block is to remain open. For example, a block quote requires a +`>` character. A paragraph requires a non-blank line. +In this phase we may match all or just some of the open +blocks. But we cannot close unmatched blocks yet, because we may have a +[lazy continuation line]. + +2. Next, after consuming the continuation markers for existing +blocks, we look for new block starts (e.g. `>` for a block quote). +If we encounter a new block start, we close any blocks unmatched +in step 1 before creating the new block as a child of the last +matched container block. + +3. Finally, we look at the remainder of the line (after block +markers like `>`, list markers, and indentation have been consumed). +This is text that can be incorporated into the last open +block (a paragraph, code block, heading, or raw HTML). + +Setext headings are formed when we see a line of a paragraph +that is a [setext heading underline]. + +Reference link definitions are detected when a paragraph is closed; +the accumulated text lines are parsed to see if they begin with +one or more reference link definitions. Any remainder becomes a +normal paragraph. + +We can see how this works by considering how the tree above is +generated by four lines of Markdown: + +``` markdown +> Lorem ipsum dolor +sit amet. +> - Qui *quodsi iracundia* +> - aliquando id +``` + +At the outset, our document model is just + +``` tree +-> document +``` + +The first line of our text, + +``` markdown +> Lorem ipsum dolor +``` + +causes a `block_quote` block to be created as a child of our +open `document` block, and a `paragraph` block as a child of +the `block_quote`. Then the text is added to the last open +block, the `paragraph`: + +``` tree +-> document + -> block_quote + -> paragraph + "Lorem ipsum dolor" +``` + +The next line, + +``` markdown +sit amet. +``` + +is a "lazy continuation" of the open `paragraph`, so it gets added +to the paragraph's text: + +``` tree +-> document + -> block_quote + -> paragraph + "Lorem ipsum dolor\nsit amet." +``` + +The third line, + +``` markdown +> - Qui *quodsi iracundia* +``` + +causes the `paragraph` block to be closed, and a new `list` block +opened as a child of the `block_quote`. A `list_item` is also +added as a child of the `list`, and a `paragraph` as a child of +the `list_item`. The text is then added to the new `paragraph`: + +``` tree +-> document + -> block_quote + paragraph + "Lorem ipsum dolor\nsit amet." + -> list (type=bullet tight=true bullet_char=-) + -> list_item + -> paragraph + "Qui *quodsi iracundia*" +``` + +The fourth line, + +``` markdown +> - aliquando id +``` + +causes the `list_item` (and its child the `paragraph`) to be closed, +and a new `list_item` opened up as child of the `list`. A `paragraph` +is added as a child of the new `list_item`, to contain the text. +We thus obtain the final tree: + +``` tree +-> document + -> block_quote + paragraph + "Lorem ipsum dolor\nsit amet." + -> list (type=bullet tight=true bullet_char=-) + list_item + paragraph + "Qui *quodsi iracundia*" + -> list_item + -> paragraph + "aliquando id" +``` + +## Phase 2: inline structure + +Once all of the input has been parsed, all open blocks are closed. + +We then "walk the tree," visiting every node, and parse raw +string contents of paragraphs and headings as inlines. At this +point we have seen all the link reference definitions, so we can +resolve reference links as we go. + +``` tree +document + block_quote + paragraph + str "Lorem ipsum dolor" + softbreak + str "sit amet." + list (type=bullet tight=true bullet_char=-) + list_item + paragraph + str "Qui " + emph + str "quodsi iracundia" + list_item + paragraph + str "aliquando id" +``` + +Notice how the [line ending] in the first paragraph has +been parsed as a `softbreak`, and the asterisks in the first list item +have become an `emph`. + +### An algorithm for parsing nested emphasis and links + +By far the trickiest part of inline parsing is handling emphasis, +strong emphasis, links, and images. This is done using the following +algorithm. + +When we're parsing inlines and we hit either + +- a run of `*` or `_` characters, or +- a `[` or `![` + +we insert a text node with these symbols as its literal content, and we +add a pointer to this text node to the [delimiter stack](@). + +The [delimiter stack] is a doubly linked list. Each +element contains a pointer to a text node, plus information about + +- the type of delimiter (`[`, `![`, `*`, `_`) +- the number of delimiters, +- whether the delimiter is "active" (all are active to start), and +- whether the delimiter is a potential opener, a potential closer, + or both (which depends on what sort of characters precede + and follow the delimiters). + +When we hit a `]` character, we call the *look for link or image* +procedure (see below). + +When we hit the end of the input, we call the *process emphasis* +procedure (see below), with `stack_bottom` = NULL. + +#### *look for link or image* + +Starting at the top of the delimiter stack, we look backwards +through the stack for an opening `[` or `![` delimiter. + +- If we don't find one, we return a literal text node `]`. + +- If we do find one, but it's not *active*, we remove the inactive + delimiter from the stack, and return a literal text node `]`. + +- If we find one and it's active, then we parse ahead to see if + we have an inline link/image, reference link/image, compact reference + link/image, or shortcut reference link/image. + + + If we don't, then we remove the opening delimiter from the + delimiter stack and return a literal text node `]`. + + + If we do, then + + * We return a link or image node whose children are the inlines + after the text node pointed to by the opening delimiter. + + * We run *process emphasis* on these inlines, with the `[` opener + as `stack_bottom`. + + * We remove the opening delimiter. + + * If we have a link (and not an image), we also set all + `[` delimiters before the opening delimiter to *inactive*. (This + will prevent us from getting links within links.) + +#### *process emphasis* + +Parameter `stack_bottom` sets a lower bound to how far we +descend in the [delimiter stack]. If it is NULL, we can +go all the way to the bottom. Otherwise, we stop before +visiting `stack_bottom`. + +Let `current_position` point to the element on the [delimiter stack] +just above `stack_bottom` (or the first element if `stack_bottom` +is NULL). + +We keep track of the `openers_bottom` for each delimiter +type (`*`, `_`), indexed to the length of the closing delimiter run +(modulo 3) and to whether the closing delimiter can also be an +opener. Initialize this to `stack_bottom`. + +Then we repeat the following until we run out of potential +closers: + +- Move `current_position` forward in the delimiter stack (if needed) + until we find the first potential closer with delimiter `*` or `_`. + (This will be the potential closer closest + to the beginning of the input -- the first one in parse order.) + +- Now, look back in the stack (staying above `stack_bottom` and + the `openers_bottom` for this delimiter type) for the + first matching potential opener ("matching" means same delimiter). + +- If one is found: + + + Figure out whether we have emphasis or strong emphasis: + if both closer and opener spans have length >= 2, we have + strong, otherwise regular. + + + Insert an emph or strong emph node accordingly, after + the text node corresponding to the opener. + + + Remove any delimiters between the opener and closer from + the delimiter stack. + + + Remove 1 (for regular emph) or 2 (for strong emph) delimiters + from the opening and closing text nodes. If they become empty + as a result, remove them and remove the corresponding element + of the delimiter stack. If the closing node is removed, reset + `current_position` to the next element in the stack. + +- If none is found: + + + Set `openers_bottom` to the element before `current_position`. + (We know that there are no openers for this kind of closer up to and + including this point, so this puts a lower bound on future searches.) + + + If the closer at `current_position` is not a potential opener, + remove it from the delimiter stack (since we know it can't + be a closer either). + + + Advance `current_position` to the next element in the stack. + +After we're done, we remove all delimiters above `stack_bottom` from the +delimiter stack. diff --git a/tests/test_cmark_spec/spec.sh b/tests/test_cmark_spec/spec.sh new file mode 100755 index 0000000..c851390 --- /dev/null +++ b/tests/test_cmark_spec/spec.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +set -e + +REPO="https://github.com/commonmark/CommonMark.git" +VERSION="0.30" + +function main { + echo "Cloning from repo: $REPO..." + git clone --quiet $REPO + + echo "Using version $VERSION..." + cd "CommonMark" + git checkout --quiet $VERSION + + echo "Dumping tests file..." + python3 "test/spec_tests.py" --dump-tests > "../commonmark.json" + + echo "Cleaning up..." + cd .. + rm -rf CommonMark + + echo "Done." +} + +main diff --git a/tests/test_cmark_spec/test_spec.py b/tests/test_cmark_spec/test_spec.py new file mode 100644 index 0000000..88d9fca --- /dev/null +++ b/tests/test_cmark_spec/test_spec.py @@ -0,0 +1,35 @@ +"""In this module tests are run against the full test set, +provided by https://github.com/commonmark/CommonMark.git. +""" +import json +from pathlib import Path + +import pytest + +from markdown_it import MarkdownIt + +SPEC_INPUT = Path(__file__).parent.joinpath("spec.md") +TESTS_INPUT = Path(__file__).parent.joinpath("commonmark.json") + + +def test_file(file_regression): + md = MarkdownIt("commonmark") + file_regression.check(md.render(SPEC_INPUT.read_text()), extension=".html") + + +@pytest.mark.parametrize("entry", json.loads(TESTS_INPUT.read_text())) +def test_spec(entry): + md = MarkdownIt("commonmark") + output = md.render(entry["markdown"]) + expected = entry["html"] + + if entry["example"] == 596: + # this doesn't have any bearing on the output + output = output.replace("mailto", "MAILTO") + if entry["example"] in [218, 239, 240]: + # this doesn't have any bearing on the output + output = output.replace( + "<blockquote></blockquote>", "<blockquote>\n</blockquote>" + ) + + assert output == expected diff --git a/tests/test_cmark_spec/test_spec/test_file.html b/tests/test_cmark_spec/test_spec/test_file.html new file mode 100644 index 0000000..1c2dc3c --- /dev/null +++ b/tests/test_cmark_spec/test_spec/test_file.html @@ -0,0 +1,7174 @@ +<hr /> +<p>title: CommonMark Spec +author: John MacFarlane +version: 0.30 +date: '2021-06-19' +license: '<a href="http://creativecommons.org/licenses/by-sa/4.0/">CC-BY-SA 4.0</a>' +...</p> +<h1>Introduction</h1> +<h2>What is Markdown?</h2> +<p>Markdown is a plain text format for writing structured documents, +based on conventions for indicating formatting in email +and usenet posts. It was developed by John Gruber (with +help from Aaron Swartz) and released in 2004 in the form of a +<a href="http://daringfireball.net/projects/markdown/syntax">syntax description</a> +and a Perl script (<code>Markdown.pl</code>) for converting Markdown to +HTML. In the next decade, dozens of implementations were +developed in many languages. Some extended the original +Markdown syntax with conventions for footnotes, tables, and +other document elements. Some allowed Markdown documents to be +rendered in formats other than HTML. Websites like Reddit, +StackOverflow, and GitHub had millions of people using Markdown. +And Markdown started to be used beyond the web, to author books, +articles, slide shows, letters, and lecture notes.</p> +<p>What distinguishes Markdown from many other lightweight markup +syntaxes, which are often easier to write, is its readability. +As Gruber writes:</p> +<blockquote> +<p>The overriding design goal for Markdown's formatting syntax is +to make it as readable as possible. The idea is that a +Markdown-formatted document should be publishable as-is, as +plain text, without looking like it's been marked up with tags +or formatting instructions. +(<a href="http://daringfireball.net/projects/markdown/">http://daringfireball.net/projects/markdown/</a>)</p> +</blockquote> +<p>The point can be illustrated by comparing a sample of +<a href="http://www.methods.co.nz/asciidoc/">AsciiDoc</a> with +an equivalent sample of Markdown. Here is a sample of +AsciiDoc from the AsciiDoc manual:</p> +<pre><code>1. List item one. ++ +List item one continued with a second paragraph followed by an +Indented block. ++ +................. +$ ls *.sh +$ mv *.sh ~/tmp +................. ++ +List item continued with a third paragraph. + +2. List item two continued with an open block. ++ +-- +This paragraph is part of the preceding list item. + +a. This list is nested and does not require explicit item +continuation. ++ +This paragraph is part of the preceding list item. + +b. List item b. + +This paragraph belongs to item two of the outer list. +-- +</code></pre> +<p>And here is the equivalent in Markdown:</p> +<pre><code>1. List item one. + + List item one continued with a second paragraph followed by an + Indented block. + + $ ls *.sh + $ mv *.sh ~/tmp + + List item continued with a third paragraph. + +2. List item two continued with an open block. + + This paragraph is part of the preceding list item. + + 1. This list is nested and does not require explicit item continuation. + + This paragraph is part of the preceding list item. + + 2. List item b. + + This paragraph belongs to item two of the outer list. +</code></pre> +<p>The AsciiDoc version is, arguably, easier to write. You don't need +to worry about indentation. But the Markdown version is much easier +to read. The nesting of list items is apparent to the eye in the +source, not just in the processed document.</p> +<h2>Why is a spec needed?</h2> +<p>John Gruber's <a href="http://daringfireball.net/projects/markdown/syntax">canonical description of Markdown's +syntax</a> +does not specify the syntax unambiguously. Here are some examples of +questions it does not answer:</p> +<ol> +<li> +<p>How much indentation is needed for a sublist? The spec says that +continuation paragraphs need to be indented four spaces, but is +not fully explicit about sublists. It is natural to think that +they, too, must be indented four spaces, but <code>Markdown.pl</code> does +not require that. This is hardly a "corner case," and divergences +between implementations on this issue often lead to surprises for +users in real documents. (See <a href="http://article.gmane.org/gmane.text.markdown.general/1997">this comment by John +Gruber</a>.)</p> +</li> +<li> +<p>Is a blank line needed before a block quote or heading? +Most implementations do not require the blank line. However, +this can lead to unexpected results in hard-wrapped text, and +also to ambiguities in parsing (note that some implementations +put the heading inside the blockquote, while others do not). +(John Gruber has also spoken <a href="http://article.gmane.org/gmane.text.markdown.general/2146">in favor of requiring the blank +lines</a>.)</p> +</li> +<li> +<p>Is a blank line needed before an indented code block? +(<code>Markdown.pl</code> requires it, but this is not mentioned in the +documentation, and some implementations do not require it.)</p> +<pre><code class="language-markdown">paragraph + code? +</code></pre> +</li> +<li> +<p>What is the exact rule for determining when list items get +wrapped in <code><p></code> tags? Can a list be partially "loose" and partially +"tight"? What should we do with a list like this?</p> +<pre><code class="language-markdown">1. one + +2. two +3. three +</code></pre> +<p>Or this?</p> +<pre><code class="language-markdown">1. one + - a + + - b +2. two +</code></pre> +<p>(There are some relevant comments by John Gruber +<a href="http://article.gmane.org/gmane.text.markdown.general/2554">here</a>.)</p> +</li> +<li> +<p>Can list markers be indented? Can ordered list markers be right-aligned?</p> +<pre><code class="language-markdown"> 8. item 1 + 9. item 2 +10. item 2a +</code></pre> +</li> +<li> +<p>Is this one list with a thematic break in its second item, +or two lists separated by a thematic break?</p> +<pre><code class="language-markdown">* a +* * * * * +* b +</code></pre> +</li> +<li> +<p>When list markers change from numbers to bullets, do we have +two lists or one? (The Markdown syntax description suggests two, +but the perl scripts and many other implementations produce one.)</p> +<pre><code class="language-markdown">1. fee +2. fie +- foe +- fum +</code></pre> +</li> +<li> +<p>What are the precedence rules for the markers of inline structure? +For example, is the following a valid link, or does the code span +take precedence ?</p> +<pre><code class="language-markdown">[a backtick (`)](/url) and [another backtick (`)](/url). +</code></pre> +</li> +<li> +<p>What are the precedence rules for markers of emphasis and strong +emphasis? For example, how should the following be parsed?</p> +<pre><code class="language-markdown">*foo *bar* baz* +</code></pre> +</li> +<li> +<p>What are the precedence rules between block-level and inline-level +structure? For example, how should the following be parsed?</p> +<pre><code class="language-markdown">- `a long code span can contain a hyphen like this + - and it can screw things up` +</code></pre> +</li> +<li> +<p>Can list items include section headings? (<code>Markdown.pl</code> does not +allow this, but does allow blockquotes to include headings.)</p> +<pre><code class="language-markdown">- # Heading +</code></pre> +</li> +<li> +<p>Can list items be empty?</p> +<pre><code class="language-markdown">* a +* +* b +</code></pre> +</li> +<li> +<p>Can link references be defined inside block quotes or list items?</p> +<pre><code class="language-markdown">> Blockquote [foo]. +> +> [foo]: /url +</code></pre> +</li> +<li> +<p>If there are multiple definitions for the same reference, which takes +precedence?</p> +<pre><code class="language-markdown">[foo]: /url1 +[foo]: /url2 + +[foo][] +</code></pre> +</li> +</ol> +<p>In the absence of a spec, early implementers consulted <code>Markdown.pl</code> +to resolve these ambiguities. But <code>Markdown.pl</code> was quite buggy, and +gave manifestly bad results in many cases, so it was not a +satisfactory replacement for a spec.</p> +<p>Because there is no unambiguous spec, implementations have diverged +considerably. As a result, users are often surprised to find that +a document that renders one way on one system (say, a GitHub wiki) +renders differently on another (say, converting to docbook using +pandoc). To make matters worse, because nothing in Markdown counts +as a "syntax error," the divergence often isn't discovered right away.</p> +<h2>About this document</h2> +<p>This document attempts to specify Markdown syntax unambiguously. +It contains many examples with side-by-side Markdown and +HTML. These are intended to double as conformance tests. An +accompanying script <code>spec_tests.py</code> can be used to run the tests +against any Markdown program:</p> +<pre><code>python test/spec_tests.py --spec spec.txt --program PROGRAM +</code></pre> +<p>Since this document describes how Markdown is to be parsed into +an abstract syntax tree, it would have made sense to use an abstract +representation of the syntax tree instead of HTML. But HTML is capable +of representing the structural distinctions we need to make, and the +choice of HTML for the tests makes it possible to run the tests against +an implementation without writing an abstract syntax tree renderer.</p> +<p>Note that not every feature of the HTML samples is mandated by +the spec. For example, the spec says what counts as a link +destination, but it doesn't mandate that non-ASCII characters in +the URL be percent-encoded. To use the automatic tests, +implementers will need to provide a renderer that conforms to +the expectations of the spec examples (percent-encoding +non-ASCII characters in URLs). But a conforming implementation +can use a different renderer and may choose not to +percent-encode non-ASCII characters in URLs.</p> +<p>This document is generated from a text file, <code>spec.txt</code>, written +in Markdown with a small extension for the side-by-side tests. +The script <code>tools/makespec.py</code> can be used to convert <code>spec.txt</code> into +HTML or CommonMark (which can then be converted into other formats).</p> +<p>In the examples, the <code>→</code> character is used to represent tabs.</p> +<h1>Preliminaries</h1> +<h2>Characters and lines</h2> +<p>Any sequence of [characters] is a valid CommonMark +document.</p> +<p>A <a href="@">character</a> is a Unicode code point. Although some +code points (for example, combining accents) do not correspond to +characters in an intuitive sense, all code points count as characters +for purposes of this spec.</p> +<p>This spec does not specify an encoding; it thinks of lines as composed +of [characters] rather than bytes. A conforming parser may be limited +to a certain encoding.</p> +<p>A <a href="@">line</a> is a sequence of zero or more [characters] +other than line feed (<code>U+000A</code>) or carriage return (<code>U+000D</code>), +followed by a [line ending] or by the end of file.</p> +<p>A <a href="@">line ending</a> is a line feed (<code>U+000A</code>), a carriage return +(<code>U+000D</code>) not followed by a line feed, or a carriage return and a +following line feed.</p> +<p>A line containing no characters, or a line containing only spaces +(<code>U+0020</code>) or tabs (<code>U+0009</code>), is called a <a href="@">blank line</a>.</p> +<p>The following definitions of character classes will be used in this spec:</p> +<p>A <a href="@">Unicode whitespace character</a> is +any code point in the Unicode <code>Zs</code> general category, or a tab (<code>U+0009</code>), +line feed (<code>U+000A</code>), form feed (<code>U+000C</code>), or carriage return (<code>U+000D</code>).</p> +<p><a href="@">Unicode whitespace</a> is a sequence of one or more +[Unicode whitespace characters].</p> +<p>A <a href="@">tab</a> is <code>U+0009</code>.</p> +<p>A <a href="@">space</a> is <code>U+0020</code>.</p> +<p>An <a href="@">ASCII control character</a> is a character between <code>U+0000–1F</code> (both +including) or <code>U+007F</code>.</p> +<p>An <a href="@">ASCII punctuation character</a> +is <code>!</code>, <code>"</code>, <code>#</code>, <code>$</code>, <code>%</code>, <code>&</code>, <code>'</code>, <code>(</code>, <code>)</code>, +<code>*</code>, <code>+</code>, <code>,</code>, <code>-</code>, <code>.</code>, <code>/</code> (U+0021–2F), +<code>:</code>, <code>;</code>, <code><</code>, <code>=</code>, <code>></code>, <code>?</code>, <code>@</code> (U+003A–0040), +<code>[</code>, <code>\</code>, <code>]</code>, <code>^</code>, <code>_</code>, <code>`</code> (U+005B–0060), +<code>{</code>, <code>|</code>, <code>}</code>, or <code>~</code> (U+007B–007E).</p> +<p>A <a href="@">Unicode punctuation character</a> is an [ASCII +punctuation character] or anything in +the general Unicode categories <code>Pc</code>, <code>Pd</code>, <code>Pe</code>, <code>Pf</code>, <code>Pi</code>, <code>Po</code>, or <code>Ps</code>.</p> +<h2>Tabs</h2> +<p>Tabs in lines are not expanded to [spaces]. However, +in contexts where spaces help to define block structure, +tabs behave as if they were replaced by spaces with a tab stop +of 4 characters.</p> +<p>Thus, for example, a tab can be used instead of four spaces +in an indented code block. (Note, however, that internal +tabs are passed through as literal tabs, not expanded to +spaces.)</p> +<pre><code class="language-example">→foo→baz→→bim +. +<pre><code>foo→baz→→bim +</code></pre> +</code></pre> +<pre><code class="language-example"> →foo→baz→→bim +. +<pre><code>foo→baz→→bim +</code></pre> +</code></pre> +<pre><code class="language-example"> a→a + ὐ→a +. +<pre><code>a→a +ὐ→a +</code></pre> +</code></pre> +<p>In the following example, a continuation paragraph of a list +item is indented with a tab; this has exactly the same effect +as indentation with four spaces would:</p> +<pre><code class="language-example"> - foo + +→bar +. +<ul> +<li> +<p>foo</p> +<p>bar</p> +</li> +</ul> +</code></pre> +<pre><code class="language-example">- foo + +→→bar +. +<ul> +<li> +<p>foo</p> +<pre><code> bar +</code></pre> +</li> +</ul> +</code></pre> +<p>Normally the <code>></code> that begins a block quote may be followed +optionally by a space, which is not considered part of the +content. In the following case <code>></code> is followed by a tab, +which is treated as if it were expanded into three spaces. +Since one of these spaces is considered part of the +delimiter, <code>foo</code> is considered to be indented six spaces +inside the block quote context, so we get an indented +code block starting with two spaces.</p> +<pre><code class="language-example">>→→foo +. +<blockquote> +<pre><code> foo +</code></pre> +</blockquote> +</code></pre> +<pre><code class="language-example">-→→foo +. +<ul> +<li> +<pre><code> foo +</code></pre> +</li> +</ul> +</code></pre> +<pre><code class="language-example"> foo +→bar +. +<pre><code>foo +bar +</code></pre> +</code></pre> +<pre><code class="language-example"> - foo + - bar +→ - baz +. +<ul> +<li>foo +<ul> +<li>bar +<ul> +<li>baz</li> +</ul> +</li> +</ul> +</li> +</ul> +</code></pre> +<pre><code class="language-example">#→Foo +. +<h1>Foo</h1> +</code></pre> +<pre><code class="language-example">*→*→*→ +. +<hr /> +</code></pre> +<h2>Insecure characters</h2> +<p>For security reasons, the Unicode character <code>U+0000</code> must be replaced +with the REPLACEMENT CHARACTER (<code>U+FFFD</code>).</p> +<h2>Backslash escapes</h2> +<p>Any ASCII punctuation character may be backslash-escaped:</p> +<pre><code class="language-example">\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\`\{\|\}\~ +. +<p>!&quot;#$%&amp;'()*+,-./:;&lt;=&gt;?@[\]^_`{|}~</p> +</code></pre> +<p>Backslashes before other characters are treated as literal +backslashes:</p> +<pre><code class="language-example">\→\A\a\ \3\φ\« +. +<p>\→\A\a\ \3\φ\«</p> +</code></pre> +<p>Escaped characters are treated as regular characters and do +not have their usual Markdown meanings:</p> +<pre><code class="language-example">\*not emphasized* +\<br/> not a tag +\[not a link](/foo) +\`not code` +1\. not a list +\* not a list +\# not a heading +\[foo]: /url "not a reference" +\&ouml; not a character entity +. +<p>*not emphasized* +&lt;br/&gt; not a tag +[not a link](/foo) +`not code` +1. not a list +* not a list +# not a heading +[foo]: /url &quot;not a reference&quot; +&amp;ouml; not a character entity</p> +</code></pre> +<p>If a backslash is itself escaped, the following character is not:</p> +<pre><code class="language-example">\\*emphasis* +. +<p>\<em>emphasis</em></p> +</code></pre> +<p>A backslash at the end of the line is a [hard line break]:</p> +<pre><code class="language-example">foo\ +bar +. +<p>foo<br /> +bar</p> +</code></pre> +<p>Backslash escapes do not work in code blocks, code spans, autolinks, or +raw HTML:</p> +<pre><code class="language-example">`` \[\` `` +. +<p><code>\[\`</code></p> +</code></pre> +<pre><code class="language-example"> \[\] +. +<pre><code>\[\] +</code></pre> +</code></pre> +<pre><code class="language-example">~~~ +\[\] +~~~ +. +<pre><code>\[\] +</code></pre> +</code></pre> +<pre><code class="language-example"><http://example.com?find=\*> +. +<p><a href="http://example.com?find=%5C*">http://example.com?find=\*</a></p> +</code></pre> +<pre><code class="language-example"><a href="/bar\/)"> +. +<a href="/bar\/)"> +</code></pre> +<p>But they work in all other contexts, including URLs and link titles, +link references, and [info strings] in [fenced code blocks]:</p> +<pre><code class="language-example">[foo](/bar\* "ti\*tle") +. +<p><a href="/bar*" title="ti*tle">foo</a></p> +</code></pre> +<pre><code class="language-example">[foo] + +[foo]: /bar\* "ti\*tle" +. +<p><a href="/bar*" title="ti*tle">foo</a></p> +</code></pre> +<pre><code class="language-example">``` foo\+bar +foo +``` +. +<pre><code class="language-foo+bar">foo +</code></pre> +</code></pre> +<h2>Entity and numeric character references</h2> +<p>Valid HTML entity references and numeric character references +can be used in place of the corresponding Unicode character, +with the following exceptions:</p> +<ul> +<li> +<p>Entity and character references are not recognized in code +blocks and code spans.</p> +</li> +<li> +<p>Entity and character references cannot stand in place of +special characters that define structural elements in +CommonMark. For example, although <code>&#42;</code> can be used +in place of a literal <code>*</code> character, <code>&#42;</code> cannot replace +<code>*</code> in emphasis delimiters, bullet list markers, or thematic +breaks.</p> +</li> +</ul> +<p>Conforming CommonMark parsers need not store information about +whether a particular character was represented in the source +using a Unicode character or an entity reference.</p> +<p><a href="@">Entity references</a> consist of <code>&</code> + any of the valid +HTML5 entity names + <code>;</code>. The +document <a href="https://html.spec.whatwg.org/entities.json">https://html.spec.whatwg.org/entities.json</a> +is used as an authoritative source for the valid entity +references and their corresponding code points.</p> +<pre><code class="language-example">&nbsp; &amp; &copy; &AElig; &Dcaron; +&frac34; &HilbertSpace; &DifferentialD; +&ClockwiseContourIntegral; &ngE; +. +<p> &amp; © Æ Ď +¾ ℋ ⅆ +∲ ≧̸</p> +</code></pre> +<p><a href="@">Decimal numeric character +references</a> +consist of <code>&#</code> + a string of 1--7 arabic digits + <code>;</code>. A +numeric character reference is parsed as the corresponding +Unicode character. Invalid Unicode code points will be replaced by +the REPLACEMENT CHARACTER (<code>U+FFFD</code>). For security reasons, +the code point <code>U+0000</code> will also be replaced by <code>U+FFFD</code>.</p> +<pre><code class="language-example">&#35; &#1234; &#992; &#0; +. +<p># Ӓ Ϡ �</p> +</code></pre> +<p><a href="@">Hexadecimal numeric character +references</a> consist of <code>&#</code> + +either <code>X</code> or <code>x</code> + a string of 1-6 hexadecimal digits + <code>;</code>. +They too are parsed as the corresponding Unicode character (this +time specified with a hexadecimal numeral instead of decimal).</p> +<pre><code class="language-example">&#X22; &#XD06; &#xcab; +. +<p>&quot; ആ ಫ</p> +</code></pre> +<p>Here are some nonentities:</p> +<pre><code class="language-example">&nbsp &x; &#; &#x; +&#87654321; +&#abcdef0; +&ThisIsNotDefined; &hi?; +. +<p>&amp;nbsp &amp;x; &amp;#; &amp;#x; +&amp;#87654321; +&amp;#abcdef0; +&amp;ThisIsNotDefined; &amp;hi?;</p> +</code></pre> +<p>Although HTML5 does accept some entity references +without a trailing semicolon (such as <code>&copy</code>), these are not +recognized here, because it makes the grammar too ambiguous:</p> +<pre><code class="language-example">&copy +. +<p>&amp;copy</p> +</code></pre> +<p>Strings that are not on the list of HTML5 named entities are not +recognized as entity references either:</p> +<pre><code class="language-example">&MadeUpEntity; +. +<p>&amp;MadeUpEntity;</p> +</code></pre> +<p>Entity and numeric character references are recognized in any +context besides code spans or code blocks, including +URLs, [link titles], and [fenced code block][] [info strings]:</p> +<pre><code class="language-example"><a href="&ouml;&ouml;.html"> +. +<a href="&ouml;&ouml;.html"> +</code></pre> +<pre><code class="language-example">[foo](/f&ouml;&ouml; "f&ouml;&ouml;") +. +<p><a href="/f%C3%B6%C3%B6" title="föö">foo</a></p> +</code></pre> +<pre><code class="language-example">[foo] + +[foo]: /f&ouml;&ouml; "f&ouml;&ouml;" +. +<p><a href="/f%C3%B6%C3%B6" title="föö">foo</a></p> +</code></pre> +<pre><code class="language-example">``` f&ouml;&ouml; +foo +``` +. +<pre><code class="language-föö">foo +</code></pre> +</code></pre> +<p>Entity and numeric character references are treated as literal +text in code spans and code blocks:</p> +<pre><code class="language-example">`f&ouml;&ouml;` +. +<p><code>f&amp;ouml;&amp;ouml;</code></p> +</code></pre> +<pre><code class="language-example"> f&ouml;f&ouml; +. +<pre><code>f&amp;ouml;f&amp;ouml; +</code></pre> +</code></pre> +<p>Entity and numeric character references cannot be used +in place of symbols indicating structure in CommonMark +documents.</p> +<pre><code class="language-example">&#42;foo&#42; +*foo* +. +<p>*foo* +<em>foo</em></p> +</code></pre> +<pre><code class="language-example">&#42; foo + +* foo +. +<p>* foo</p> +<ul> +<li>foo</li> +</ul> +</code></pre> +<pre><code class="language-example">foo&#10;&#10;bar +. +<p>foo + +bar</p> +</code></pre> +<pre><code class="language-example">&#9;foo +. +<p>→foo</p> +</code></pre> +<pre><code class="language-example">[a](url &quot;tit&quot;) +. +<p>[a](url &quot;tit&quot;)</p> +</code></pre> +<h1>Blocks and inlines</h1> +<p>We can think of a document as a sequence of +<a href="@">blocks</a>---structural elements like paragraphs, block +quotations, lists, headings, rules, and code blocks. Some blocks (like +block quotes and list items) contain other blocks; others (like +headings and paragraphs) contain <a href="@">inline</a> content---text, +links, emphasized text, images, code spans, and so on.</p> +<h2>Precedence</h2> +<p>Indicators of block structure always take precedence over indicators +of inline structure. So, for example, the following is a list with +two items, not a list with one item containing a code span:</p> +<pre><code class="language-example">- `one +- two` +. +<ul> +<li>`one</li> +<li>two`</li> +</ul> +</code></pre> +<p>This means that parsing can proceed in two steps: first, the block +structure of the document can be discerned; second, text lines inside +paragraphs, headings, and other block constructs can be parsed for inline +structure. The second step requires information about link reference +definitions that will be available only at the end of the first +step. Note that the first step requires processing lines in sequence, +but the second can be parallelized, since the inline parsing of +one block element does not affect the inline parsing of any other.</p> +<h2>Container blocks and leaf blocks</h2> +<p>We can divide blocks into two types: +<a href="#container-blocks">container blocks</a>, +which can contain other blocks, and <a href="#leaf-blocks">leaf blocks</a>, +which cannot.</p> +<h1>Leaf blocks</h1> +<p>This section describes the different kinds of leaf block that make up a +Markdown document.</p> +<h2>Thematic breaks</h2> +<p>A line consisting of optionally up to three spaces of indentation, followed by a +sequence of three or more matching <code>-</code>, <code>_</code>, or <code>*</code> characters, each followed +optionally by any number of spaces or tabs, forms a +<a href="@">thematic break</a>.</p> +<pre><code class="language-example">*** +--- +___ +. +<hr /> +<hr /> +<hr /> +</code></pre> +<p>Wrong characters:</p> +<pre><code class="language-example">+++ +. +<p>+++</p> +</code></pre> +<pre><code class="language-example">=== +. +<p>===</p> +</code></pre> +<p>Not enough characters:</p> +<pre><code class="language-example">-- +** +__ +. +<p>-- +** +__</p> +</code></pre> +<p>Up to three spaces of indentation are allowed:</p> +<pre><code class="language-example"> *** + *** + *** +. +<hr /> +<hr /> +<hr /> +</code></pre> +<p>Four spaces of indentation is too many:</p> +<pre><code class="language-example"> *** +. +<pre><code>*** +</code></pre> +</code></pre> +<pre><code class="language-example">Foo + *** +. +<p>Foo +***</p> +</code></pre> +<p>More than three characters may be used:</p> +<pre><code class="language-example">_____________________________________ +. +<hr /> +</code></pre> +<p>Spaces and tabs are allowed between the characters:</p> +<pre><code class="language-example"> - - - +. +<hr /> +</code></pre> +<pre><code class="language-example"> ** * ** * ** * ** +. +<hr /> +</code></pre> +<pre><code class="language-example">- - - - +. +<hr /> +</code></pre> +<p>Spaces and tabs are allowed at the end:</p> +<pre><code class="language-example">- - - - +. +<hr /> +</code></pre> +<p>However, no other characters may occur in the line:</p> +<pre><code class="language-example">_ _ _ _ a + +a------ + +---a--- +. +<p>_ _ _ _ a</p> +<p>a------</p> +<p>---a---</p> +</code></pre> +<p>It is required that all of the characters other than spaces or tabs be the same. +So, this is not a thematic break:</p> +<pre><code class="language-example"> *-* +. +<p><em>-</em></p> +</code></pre> +<p>Thematic breaks do not need blank lines before or after:</p> +<pre><code class="language-example">- foo +*** +- bar +. +<ul> +<li>foo</li> +</ul> +<hr /> +<ul> +<li>bar</li> +</ul> +</code></pre> +<p>Thematic breaks can interrupt a paragraph:</p> +<pre><code class="language-example">Foo +*** +bar +. +<p>Foo</p> +<hr /> +<p>bar</p> +</code></pre> +<p>If a line of dashes that meets the above conditions for being a +thematic break could also be interpreted as the underline of a [setext +heading], the interpretation as a +[setext heading] takes precedence. Thus, for example, +this is a setext heading, not a paragraph followed by a thematic break:</p> +<pre><code class="language-example">Foo +--- +bar +. +<h2>Foo</h2> +<p>bar</p> +</code></pre> +<p>When both a thematic break and a list item are possible +interpretations of a line, the thematic break takes precedence:</p> +<pre><code class="language-example">* Foo +* * * +* Bar +. +<ul> +<li>Foo</li> +</ul> +<hr /> +<ul> +<li>Bar</li> +</ul> +</code></pre> +<p>If you want a thematic break in a list item, use a different bullet:</p> +<pre><code class="language-example">- Foo +- * * * +. +<ul> +<li>Foo</li> +<li> +<hr /> +</li> +</ul> +</code></pre> +<h2>ATX headings</h2> +<p>An <a href="@">ATX heading</a> +consists of a string of characters, parsed as inline content, between an +opening sequence of 1--6 unescaped <code>#</code> characters and an optional +closing sequence of any number of unescaped <code>#</code> characters. +The opening sequence of <code>#</code> characters must be followed by spaces or tabs, or +by the end of line. The optional closing sequence of <code>#</code>s must be preceded by +spaces or tabs and may be followed by spaces or tabs only. The opening +<code>#</code> character may be preceded by up to three spaces of indentation. The raw +contents of the heading are stripped of leading and trailing space or tabs +before being parsed as inline content. The heading level is equal to the number +of <code>#</code> characters in the opening sequence.</p> +<p>Simple headings:</p> +<pre><code class="language-example"># foo +## foo +### foo +#### foo +##### foo +###### foo +. +<h1>foo</h1> +<h2>foo</h2> +<h3>foo</h3> +<h4>foo</h4> +<h5>foo</h5> +<h6>foo</h6> +</code></pre> +<p>More than six <code>#</code> characters is not a heading:</p> +<pre><code class="language-example">####### foo +. +<p>####### foo</p> +</code></pre> +<p>At least one space or tab is required between the <code>#</code> characters and the +heading's contents, unless the heading is empty. Note that many +implementations currently do not require the space. However, the +space was required by the +<a href="http://www.aaronsw.com/2002/atx/atx.py">original ATX implementation</a>, +and it helps prevent things like the following from being parsed as +headings:</p> +<pre><code class="language-example">#5 bolt + +#hashtag +. +<p>#5 bolt</p> +<p>#hashtag</p> +</code></pre> +<p>This is not a heading, because the first <code>#</code> is escaped:</p> +<pre><code class="language-example">\## foo +. +<p>## foo</p> +</code></pre> +<p>Contents are parsed as inlines:</p> +<pre><code class="language-example"># foo *bar* \*baz\* +. +<h1>foo <em>bar</em> *baz*</h1> +</code></pre> +<p>Leading and trailing spaces or tabs are ignored in parsing inline content:</p> +<pre><code class="language-example"># foo +. +<h1>foo</h1> +</code></pre> +<p>Up to three spaces of indentation are allowed:</p> +<pre><code class="language-example"> ### foo + ## foo + # foo +. +<h3>foo</h3> +<h2>foo</h2> +<h1>foo</h1> +</code></pre> +<p>Four spaces of indentation is too many:</p> +<pre><code class="language-example"> # foo +. +<pre><code># foo +</code></pre> +</code></pre> +<pre><code class="language-example">foo + # bar +. +<p>foo +# bar</p> +</code></pre> +<p>A closing sequence of <code>#</code> characters is optional:</p> +<pre><code class="language-example">## foo ## + ### bar ### +. +<h2>foo</h2> +<h3>bar</h3> +</code></pre> +<p>It need not be the same length as the opening sequence:</p> +<pre><code class="language-example"># foo ################################## +##### foo ## +. +<h1>foo</h1> +<h5>foo</h5> +</code></pre> +<p>Spaces or tabs are allowed after the closing sequence:</p> +<pre><code class="language-example">### foo ### +. +<h3>foo</h3> +</code></pre> +<p>A sequence of <code>#</code> characters with anything but spaces or tabs following it +is not a closing sequence, but counts as part of the contents of the +heading:</p> +<pre><code class="language-example">### foo ### b +. +<h3>foo ### b</h3> +</code></pre> +<p>The closing sequence must be preceded by a space or tab:</p> +<pre><code class="language-example"># foo# +. +<h1>foo#</h1> +</code></pre> +<p>Backslash-escaped <code>#</code> characters do not count as part +of the closing sequence:</p> +<pre><code class="language-example">### foo \### +## foo #\## +# foo \# +. +<h3>foo ###</h3> +<h2>foo ###</h2> +<h1>foo #</h1> +</code></pre> +<p>ATX headings need not be separated from surrounding content by blank +lines, and they can interrupt paragraphs:</p> +<pre><code class="language-example">**** +## foo +**** +. +<hr /> +<h2>foo</h2> +<hr /> +</code></pre> +<pre><code class="language-example">Foo bar +# baz +Bar foo +. +<p>Foo bar</p> +<h1>baz</h1> +<p>Bar foo</p> +</code></pre> +<p>ATX headings can be empty:</p> +<pre><code class="language-example">## +# +### ### +. +<h2></h2> +<h1></h1> +<h3></h3> +</code></pre> +<h2>Setext headings</h2> +<p>A <a href="@">setext heading</a> consists of one or more +lines of text, not interrupted by a blank line, of which the first line does not +have more than 3 spaces of indentation, followed by +a [setext heading underline]. The lines of text must be such +that, were they not followed by the setext heading underline, +they would be interpreted as a paragraph: they cannot be +interpretable as a [code fence], [ATX heading][ATX headings], +[block quote][block quotes], [thematic break][thematic breaks], +[list item][list items], or [HTML block][HTML blocks].</p> +<p>A <a href="@">setext heading underline</a> is a sequence of +<code>=</code> characters or a sequence of <code>-</code> characters, with no more than 3 +spaces of indentation and any number of trailing spaces or tabs. If a line +containing a single <code>-</code> can be interpreted as an +empty [list items], it should be interpreted this way +and not as a [setext heading underline].</p> +<p>The heading is a level 1 heading if <code>=</code> characters are used in +the [setext heading underline], and a level 2 heading if <code>-</code> +characters are used. The contents of the heading are the result +of parsing the preceding lines of text as CommonMark inline +content.</p> +<p>In general, a setext heading need not be preceded or followed by a +blank line. However, it cannot interrupt a paragraph, so when a +setext heading comes after a paragraph, a blank line is needed between +them.</p> +<p>Simple examples:</p> +<pre><code class="language-example">Foo *bar* +========= + +Foo *bar* +--------- +. +<h1>Foo <em>bar</em></h1> +<h2>Foo <em>bar</em></h2> +</code></pre> +<p>The content of the header may span more than one line:</p> +<pre><code class="language-example">Foo *bar +baz* +==== +. +<h1>Foo <em>bar +baz</em></h1> +</code></pre> +<p>The contents are the result of parsing the headings's raw +content as inlines. The heading's raw content is formed by +concatenating the lines and removing initial and final +spaces or tabs.</p> +<pre><code class="language-example"> Foo *bar +baz*→ +==== +. +<h1>Foo <em>bar +baz</em></h1> +</code></pre> +<p>The underlining can be any length:</p> +<pre><code class="language-example">Foo +------------------------- + +Foo += +. +<h2>Foo</h2> +<h1>Foo</h1> +</code></pre> +<p>The heading content can be preceded by up to three spaces of indentation, and +need not line up with the underlining:</p> +<pre><code class="language-example"> Foo +--- + + Foo +----- + + Foo + === +. +<h2>Foo</h2> +<h2>Foo</h2> +<h1>Foo</h1> +</code></pre> +<p>Four spaces of indentation is too many:</p> +<pre><code class="language-example"> Foo + --- + + Foo +--- +. +<pre><code>Foo +--- + +Foo +</code></pre> +<hr /> +</code></pre> +<p>The setext heading underline can be preceded by up to three spaces of +indentation, and may have trailing spaces or tabs:</p> +<pre><code class="language-example">Foo + ---- +. +<h2>Foo</h2> +</code></pre> +<p>Four spaces of indentation is too many:</p> +<pre><code class="language-example">Foo + --- +. +<p>Foo +---</p> +</code></pre> +<p>The setext heading underline cannot contain internal spaces or tabs:</p> +<pre><code class="language-example">Foo += = + +Foo +--- - +. +<p>Foo += =</p> +<p>Foo</p> +<hr /> +</code></pre> +<p>Trailing spaces or tabs in the content line do not cause a hard line break:</p> +<pre><code class="language-example">Foo +----- +. +<h2>Foo</h2> +</code></pre> +<p>Nor does a backslash at the end:</p> +<pre><code class="language-example">Foo\ +---- +. +<h2>Foo\</h2> +</code></pre> +<p>Since indicators of block structure take precedence over +indicators of inline structure, the following are setext headings:</p> +<pre><code class="language-example">`Foo +---- +` + +<a title="a lot +--- +of dashes"/> +. +<h2>`Foo</h2> +<p>`</p> +<h2>&lt;a title=&quot;a lot</h2> +<p>of dashes&quot;/&gt;</p> +</code></pre> +<p>The setext heading underline cannot be a [lazy continuation +line] in a list item or block quote:</p> +<pre><code class="language-example">> Foo +--- +. +<blockquote> +<p>Foo</p> +</blockquote> +<hr /> +</code></pre> +<pre><code class="language-example">> foo +bar +=== +. +<blockquote> +<p>foo +bar +===</p> +</blockquote> +</code></pre> +<pre><code class="language-example">- Foo +--- +. +<ul> +<li>Foo</li> +</ul> +<hr /> +</code></pre> +<p>A blank line is needed between a paragraph and a following +setext heading, since otherwise the paragraph becomes part +of the heading's content:</p> +<pre><code class="language-example">Foo +Bar +--- +. +<h2>Foo +Bar</h2> +</code></pre> +<p>But in general a blank line is not required before or after +setext headings:</p> +<pre><code class="language-example">--- +Foo +--- +Bar +--- +Baz +. +<hr /> +<h2>Foo</h2> +<h2>Bar</h2> +<p>Baz</p> +</code></pre> +<p>Setext headings cannot be empty:</p> +<pre><code class="language-example"> +==== +. +<p>====</p> +</code></pre> +<p>Setext heading text lines must not be interpretable as block +constructs other than paragraphs. So, the line of dashes +in these examples gets interpreted as a thematic break:</p> +<pre><code class="language-example">--- +--- +. +<hr /> +<hr /> +</code></pre> +<pre><code class="language-example">- foo +----- +. +<ul> +<li>foo</li> +</ul> +<hr /> +</code></pre> +<pre><code class="language-example"> foo +--- +. +<pre><code>foo +</code></pre> +<hr /> +</code></pre> +<pre><code class="language-example">> foo +----- +. +<blockquote> +<p>foo</p> +</blockquote> +<hr /> +</code></pre> +<p>If you want a heading with <code>> foo</code> as its literal text, you can +use backslash escapes:</p> +<pre><code class="language-example">\> foo +------ +. +<h2>&gt; foo</h2> +</code></pre> +<p><strong>Compatibility note:</strong> Most existing Markdown implementations +do not allow the text of setext headings to span multiple lines. +But there is no consensus about how to interpret</p> +<pre><code class="language-markdown">Foo +bar +--- +baz +</code></pre> +<p>One can find four different interpretations:</p> +<ol> +<li>paragraph "Foo", heading "bar", paragraph "baz"</li> +<li>paragraph "Foo bar", thematic break, paragraph "baz"</li> +<li>paragraph "Foo bar --- baz"</li> +<li>heading "Foo bar", paragraph "baz"</li> +</ol> +<p>We find interpretation 4 most natural, and interpretation 4 +increases the expressive power of CommonMark, by allowing +multiline headings. Authors who want interpretation 1 can +put a blank line after the first paragraph:</p> +<pre><code class="language-example">Foo + +bar +--- +baz +. +<p>Foo</p> +<h2>bar</h2> +<p>baz</p> +</code></pre> +<p>Authors who want interpretation 2 can put blank lines around +the thematic break,</p> +<pre><code class="language-example">Foo +bar + +--- + +baz +. +<p>Foo +bar</p> +<hr /> +<p>baz</p> +</code></pre> +<p>or use a thematic break that cannot count as a [setext heading +underline], such as</p> +<pre><code class="language-example">Foo +bar +* * * +baz +. +<p>Foo +bar</p> +<hr /> +<p>baz</p> +</code></pre> +<p>Authors who want interpretation 3 can use backslash escapes:</p> +<pre><code class="language-example">Foo +bar +\--- +baz +. +<p>Foo +bar +--- +baz</p> +</code></pre> +<h2>Indented code blocks</h2> +<p>An <a href="@">indented code block</a> is composed of one or more +[indented chunks] separated by blank lines. +An <a href="@">indented chunk</a> is a sequence of non-blank lines, +each preceded by four or more spaces of indentation. The contents of the code +block are the literal contents of the lines, including trailing +[line endings], minus four spaces of indentation. +An indented code block has no [info string].</p> +<p>An indented code block cannot interrupt a paragraph, so there must be +a blank line between a paragraph and a following indented code block. +(A blank line is not needed, however, between a code block and a following +paragraph.)</p> +<pre><code class="language-example"> a simple + indented code block +. +<pre><code>a simple + indented code block +</code></pre> +</code></pre> +<p>If there is any ambiguity between an interpretation of indentation +as a code block and as indicating that material belongs to a [list +item][list items], the list item interpretation takes precedence:</p> +<pre><code class="language-example"> - foo + + bar +. +<ul> +<li> +<p>foo</p> +<p>bar</p> +</li> +</ul> +</code></pre> +<pre><code class="language-example">1. foo + + - bar +. +<ol> +<li> +<p>foo</p> +<ul> +<li>bar</li> +</ul> +</li> +</ol> +</code></pre> +<p>The contents of a code block are literal text, and do not get parsed +as Markdown:</p> +<pre><code class="language-example"> <a/> + *hi* + + - one +. +<pre><code>&lt;a/&gt; +*hi* + +- one +</code></pre> +</code></pre> +<p>Here we have three chunks separated by blank lines:</p> +<pre><code class="language-example"> chunk1 + + chunk2 + + + + chunk3 +. +<pre><code>chunk1 + +chunk2 + + + +chunk3 +</code></pre> +</code></pre> +<p>Any initial spaces or tabs beyond four spaces of indentation will be included in +the content, even in interior blank lines:</p> +<pre><code class="language-example"> chunk1 + + chunk2 +. +<pre><code>chunk1 + + chunk2 +</code></pre> +</code></pre> +<p>An indented code block cannot interrupt a paragraph. (This +allows hanging indents and the like.)</p> +<pre><code class="language-example">Foo + bar + +. +<p>Foo +bar</p> +</code></pre> +<p>However, any non-blank line with fewer than four spaces of indentation ends +the code block immediately. So a paragraph may occur immediately +after indented code:</p> +<pre><code class="language-example"> foo +bar +. +<pre><code>foo +</code></pre> +<p>bar</p> +</code></pre> +<p>And indented code can occur immediately before and after other kinds of +blocks:</p> +<pre><code class="language-example"># Heading + foo +Heading +------ + foo +---- +. +<h1>Heading</h1> +<pre><code>foo +</code></pre> +<h2>Heading</h2> +<pre><code>foo +</code></pre> +<hr /> +</code></pre> +<p>The first line can be preceded by more than four spaces of indentation:</p> +<pre><code class="language-example"> foo + bar +. +<pre><code> foo +bar +</code></pre> +</code></pre> +<p>Blank lines preceding or following an indented code block +are not included in it:</p> +<pre><code class="language-example"> + + foo + + +. +<pre><code>foo +</code></pre> +</code></pre> +<p>Trailing spaces or tabs are included in the code block's content:</p> +<pre><code class="language-example"> foo +. +<pre><code>foo +</code></pre> +</code></pre> +<h2>Fenced code blocks</h2> +<p>A <a href="@">code fence</a> is a sequence +of at least three consecutive backtick characters (<code>`</code>) or +tildes (<code>~</code>). (Tildes and backticks cannot be mixed.) +A <a href="@">fenced code block</a> +begins with a code fence, preceded by up to three spaces of indentation.</p> +<p>The line with the opening code fence may optionally contain some text +following the code fence; this is trimmed of leading and trailing +spaces or tabs and called the <a href="@">info string</a>. If the [info string] comes +after a backtick fence, it may not contain any backtick +characters. (The reason for this restriction is that otherwise +some inline code would be incorrectly interpreted as the +beginning of a fenced code block.)</p> +<p>The content of the code block consists of all subsequent lines, until +a closing [code fence] of the same type as the code block +began with (backticks or tildes), and with at least as many backticks +or tildes as the opening code fence. If the leading code fence is +preceded by N spaces of indentation, then up to N spaces of indentation are +removed from each line of the content (if present). (If a content line is not +indented, it is preserved unchanged. If it is indented N spaces or less, all +of the indentation is removed.)</p> +<p>The closing code fence may be preceded by up to three spaces of indentation, and +may be followed only by spaces or tabs, which are ignored. If the end of the +containing block (or document) is reached and no closing code fence +has been found, the code block contains all of the lines after the +opening code fence until the end of the containing block (or +document). (An alternative spec would require backtracking in the +event that a closing code fence is not found. But this makes parsing +much less efficient, and there seems to be no real down side to the +behavior described here.)</p> +<p>A fenced code block may interrupt a paragraph, and does not require +a blank line either before or after.</p> +<p>The content of a code fence is treated as literal text, not parsed +as inlines. The first word of the [info string] is typically used to +specify the language of the code sample, and rendered in the <code>class</code> +attribute of the <code>code</code> tag. However, this spec does not mandate any +particular treatment of the [info string].</p> +<p>Here is a simple example with backticks:</p> +<pre><code class="language-example">``` +< + > +``` +. +<pre><code>&lt; + &gt; +</code></pre> +</code></pre> +<p>With tildes:</p> +<pre><code class="language-example">~~~ +< + > +~~~ +. +<pre><code>&lt; + &gt; +</code></pre> +</code></pre> +<p>Fewer than three backticks is not enough:</p> +<pre><code class="language-example">`` +foo +`` +. +<p><code>foo</code></p> +</code></pre> +<p>The closing code fence must use the same character as the opening +fence:</p> +<pre><code class="language-example">``` +aaa +~~~ +``` +. +<pre><code>aaa +~~~ +</code></pre> +</code></pre> +<pre><code class="language-example">~~~ +aaa +``` +~~~ +. +<pre><code>aaa +``` +</code></pre> +</code></pre> +<p>The closing code fence must be at least as long as the opening fence:</p> +<pre><code class="language-example">```` +aaa +``` +`````` +. +<pre><code>aaa +``` +</code></pre> +</code></pre> +<pre><code class="language-example">~~~~ +aaa +~~~ +~~~~ +. +<pre><code>aaa +~~~ +</code></pre> +</code></pre> +<p>Unclosed code blocks are closed by the end of the document +(or the enclosing [block quote][block quotes] or [list item][list items]):</p> +<pre><code class="language-example">``` +. +<pre><code></code></pre> +</code></pre> +<pre><code class="language-example">````` + +``` +aaa +. +<pre><code> +``` +aaa +</code></pre> +</code></pre> +<pre><code class="language-example">> ``` +> aaa + +bbb +. +<blockquote> +<pre><code>aaa +</code></pre> +</blockquote> +<p>bbb</p> +</code></pre> +<p>A code block can have all empty lines as its content:</p> +<pre><code class="language-example">``` + + +``` +. +<pre><code> + +</code></pre> +</code></pre> +<p>A code block can be empty:</p> +<pre><code class="language-example">``` +``` +. +<pre><code></code></pre> +</code></pre> +<p>Fences can be indented. If the opening fence is indented, +content lines will have equivalent opening indentation removed, +if present:</p> +<pre><code class="language-example"> ``` + aaa +aaa +``` +. +<pre><code>aaa +aaa +</code></pre> +</code></pre> +<pre><code class="language-example"> ``` +aaa + aaa +aaa + ``` +. +<pre><code>aaa +aaa +aaa +</code></pre> +</code></pre> +<pre><code class="language-example"> ``` + aaa + aaa + aaa + ``` +. +<pre><code>aaa + aaa +aaa +</code></pre> +</code></pre> +<p>Four spaces of indentation is too many:</p> +<pre><code class="language-example"> ``` + aaa + ``` +. +<pre><code>``` +aaa +``` +</code></pre> +</code></pre> +<p>Closing fences may be preceded by up to three spaces of indentation, and their +indentation need not match that of the opening fence:</p> +<pre><code class="language-example">``` +aaa + ``` +. +<pre><code>aaa +</code></pre> +</code></pre> +<pre><code class="language-example"> ``` +aaa + ``` +. +<pre><code>aaa +</code></pre> +</code></pre> +<p>This is not a closing fence, because it is indented 4 spaces:</p> +<pre><code class="language-example">``` +aaa + ``` +. +<pre><code>aaa + ``` +</code></pre> +</code></pre> +<p>Code fences (opening and closing) cannot contain internal spaces or tabs:</p> +<pre><code class="language-example">``` ``` +aaa +. +<p><code> </code> +aaa</p> +</code></pre> +<pre><code class="language-example">~~~~~~ +aaa +~~~ ~~ +. +<pre><code>aaa +~~~ ~~ +</code></pre> +</code></pre> +<p>Fenced code blocks can interrupt paragraphs, and can be followed +directly by paragraphs, without a blank line between:</p> +<pre><code class="language-example">foo +``` +bar +``` +baz +. +<p>foo</p> +<pre><code>bar +</code></pre> +<p>baz</p> +</code></pre> +<p>Other blocks can also occur before and after fenced code blocks +without an intervening blank line:</p> +<pre><code class="language-example">foo +--- +~~~ +bar +~~~ +# baz +. +<h2>foo</h2> +<pre><code>bar +</code></pre> +<h1>baz</h1> +</code></pre> +<p>An [info string] can be provided after the opening code fence. +Although this spec doesn't mandate any particular treatment of +the info string, the first word is typically used to specify +the language of the code block. In HTML output, the language is +normally indicated by adding a class to the <code>code</code> element consisting +of <code>language-</code> followed by the language name.</p> +<pre><code class="language-example">```ruby +def foo(x) + return 3 +end +``` +. +<pre><code class="language-ruby">def foo(x) + return 3 +end +</code></pre> +</code></pre> +<pre><code class="language-example">~~~~ ruby startline=3 $%@#$ +def foo(x) + return 3 +end +~~~~~~~ +. +<pre><code class="language-ruby">def foo(x) + return 3 +end +</code></pre> +</code></pre> +<pre><code class="language-example">````; +```` +. +<pre><code class="language-;"></code></pre> +</code></pre> +<p>[Info strings] for backtick code blocks cannot contain backticks:</p> +<pre><code class="language-example">``` aa ``` +foo +. +<p><code>aa</code> +foo</p> +</code></pre> +<p>[Info strings] for tilde code blocks can contain backticks and tildes:</p> +<pre><code class="language-example">~~~ aa ``` ~~~ +foo +~~~ +. +<pre><code class="language-aa">foo +</code></pre> +</code></pre> +<p>Closing code fences cannot have [info strings]:</p> +<pre><code class="language-example">``` +``` aaa +``` +. +<pre><code>``` aaa +</code></pre> +</code></pre> +<h2>HTML blocks</h2> +<p>An <a href="@">HTML block</a> is a group of lines that is treated +as raw HTML (and will not be escaped in HTML output).</p> +<p>There are seven kinds of [HTML block], which can be defined by their +start and end conditions. The block begins with a line that meets a +<a href="@">start condition</a> (after up to three optional spaces of indentation). +It ends with the first subsequent line that meets a matching +<a href="@">end condition</a>, or the last line of the document, or the last line of +the <a href="#container-blocks">container block</a> containing the current HTML +block, if no line is encountered that meets the [end condition]. If +the first line meets both the [start condition] and the [end +condition], the block will contain just that line.</p> +<ol> +<li> +<p><strong>Start condition:</strong> line begins with the string <code><pre</code>, +<code><script</code>, <code><style</code>, or <code><textarea</code> (case-insensitive), followed by a space, +a tab, the string <code>></code>, or the end of the line.<br /> +<strong>End condition:</strong> line contains an end tag +<code></pre></code>, <code></script></code>, <code></style></code>, or <code></textarea></code> (case-insensitive; it +need not match the start tag).</p> +</li> +<li> +<p><strong>Start condition:</strong> line begins with the string <code><!--</code>.<br /> +<strong>End condition:</strong> line contains the string <code>--></code>.</p> +</li> +<li> +<p><strong>Start condition:</strong> line begins with the string <code><?</code>.<br /> +<strong>End condition:</strong> line contains the string <code>?></code>.</p> +</li> +<li> +<p><strong>Start condition:</strong> line begins with the string <code><!</code> +followed by an ASCII letter.<br /> +<strong>End condition:</strong> line contains the character <code>></code>.</p> +</li> +<li> +<p><strong>Start condition:</strong> line begins with the string +<code><![CDATA[</code>.<br /> +<strong>End condition:</strong> line contains the string <code>]]></code>.</p> +</li> +<li> +<p><strong>Start condition:</strong> line begins the string <code><</code> or <code></</code> +followed by one of the strings (case-insensitive) <code>address</code>, +<code>article</code>, <code>aside</code>, <code>base</code>, <code>basefont</code>, <code>blockquote</code>, <code>body</code>, +<code>caption</code>, <code>center</code>, <code>col</code>, <code>colgroup</code>, <code>dd</code>, <code>details</code>, <code>dialog</code>, +<code>dir</code>, <code>div</code>, <code>dl</code>, <code>dt</code>, <code>fieldset</code>, <code>figcaption</code>, <code>figure</code>, +<code>footer</code>, <code>form</code>, <code>frame</code>, <code>frameset</code>, +<code>h1</code>, <code>h2</code>, <code>h3</code>, <code>h4</code>, <code>h5</code>, <code>h6</code>, <code>head</code>, <code>header</code>, <code>hr</code>, +<code>html</code>, <code>iframe</code>, <code>legend</code>, <code>li</code>, <code>link</code>, <code>main</code>, <code>menu</code>, <code>menuitem</code>, +<code>nav</code>, <code>noframes</code>, <code>ol</code>, <code>optgroup</code>, <code>option</code>, <code>p</code>, <code>param</code>, +<code>section</code>, <code>source</code>, <code>summary</code>, <code>table</code>, <code>tbody</code>, <code>td</code>, +<code>tfoot</code>, <code>th</code>, <code>thead</code>, <code>title</code>, <code>tr</code>, <code>track</code>, <code>ul</code>, followed +by a space, a tab, the end of the line, the string <code>></code>, or +the string <code>/></code>.<br /> +<strong>End condition:</strong> line is followed by a [blank line].</p> +</li> +<li> +<p><strong>Start condition:</strong> line begins with a complete [open tag] +(with any [tag name] other than <code>pre</code>, <code>script</code>, +<code>style</code>, or <code>textarea</code>) or a complete [closing tag], +followed by zero or more spaces and tabs, followed by the end of the line.<br /> +<strong>End condition:</strong> line is followed by a [blank line].</p> +</li> +</ol> +<p>HTML blocks continue until they are closed by their appropriate +[end condition], or the last line of the document or other <a href="#container-blocks">container +block</a>. This means any HTML <strong>within an HTML +block</strong> that might otherwise be recognised as a start condition will +be ignored by the parser and passed through as-is, without changing +the parser's state.</p> +<p>For instance, <code><pre></code> within an HTML block started by <code><table></code> will not affect +the parser state; as the HTML block was started in by start condition 6, it +will end at any blank line. This can be surprising:</p> +<pre><code class="language-example"><table><tr><td> +<pre> +**Hello**, + +_world_. +</pre> +</td></tr></table> +. +<table><tr><td> +<pre> +**Hello**, +<p><em>world</em>. +</pre></p> +</td></tr></table> +</code></pre> +<p>In this case, the HTML block is terminated by the blank line — the <code>**Hello**</code> +text remains verbatim — and regular parsing resumes, with a paragraph, +emphasised <code>world</code> and inline and block HTML following.</p> +<p>All types of [HTML blocks] except type 7 may interrupt +a paragraph. Blocks of type 7 may not interrupt a paragraph. +(This restriction is intended to prevent unwanted interpretation +of long tags inside a wrapped paragraph as starting HTML blocks.)</p> +<p>Some simple examples follow. Here are some basic HTML blocks +of type 6:</p> +<pre><code class="language-example"><table> + <tr> + <td> + hi + </td> + </tr> +</table> + +okay. +. +<table> + <tr> + <td> + hi + </td> + </tr> +</table> +<p>okay.</p> +</code></pre> +<pre><code class="language-example"> <div> + *hello* + <foo><a> +. + <div> + *hello* + <foo><a> +</code></pre> +<p>A block can also start with a closing tag:</p> +<pre><code class="language-example"></div> +*foo* +. +</div> +*foo* +</code></pre> +<p>Here we have two HTML blocks with a Markdown paragraph between them:</p> +<pre><code class="language-example"><DIV CLASS="foo"> + +*Markdown* + +</DIV> +. +<DIV CLASS="foo"> +<p><em>Markdown</em></p> +</DIV> +</code></pre> +<p>The tag on the first line can be partial, as long +as it is split where there would be whitespace:</p> +<pre><code class="language-example"><div id="foo" + class="bar"> +</div> +. +<div id="foo" + class="bar"> +</div> +</code></pre> +<pre><code class="language-example"><div id="foo" class="bar + baz"> +</div> +. +<div id="foo" class="bar + baz"> +</div> +</code></pre> +<p>An open tag need not be closed:</p> +<pre><code class="language-example"><div> +*foo* + +*bar* +. +<div> +*foo* +<p><em>bar</em></p> +</code></pre> +<p>A partial tag need not even be completed (garbage +in, garbage out):</p> +<pre><code class="language-example"><div id="foo" +*hi* +. +<div id="foo" +*hi* +</code></pre> +<pre><code class="language-example"><div class +foo +. +<div class +foo +</code></pre> +<p>The initial tag doesn't even need to be a valid +tag, as long as it starts like one:</p> +<pre><code class="language-example"><div *???-&&&-<--- +*foo* +. +<div *???-&&&-<--- +*foo* +</code></pre> +<p>In type 6 blocks, the initial tag need not be on a line by +itself:</p> +<pre><code class="language-example"><div><a href="bar">*foo*</a></div> +. +<div><a href="bar">*foo*</a></div> +</code></pre> +<pre><code class="language-example"><table><tr><td> +foo +</td></tr></table> +. +<table><tr><td> +foo +</td></tr></table> +</code></pre> +<p>Everything until the next blank line or end of document +gets included in the HTML block. So, in the following +example, what looks like a Markdown code block +is actually part of the HTML block, which continues until a blank +line or the end of the document is reached:</p> +<pre><code class="language-example"><div></div> +``` c +int x = 33; +``` +. +<div></div> +``` c +int x = 33; +``` +</code></pre> +<p>To start an [HTML block] with a tag that is <em>not</em> in the +list of block-level tags in (6), you must put the tag by +itself on the first line (and it must be complete):</p> +<pre><code class="language-example"><a href="foo"> +*bar* +</a> +. +<a href="foo"> +*bar* +</a> +</code></pre> +<p>In type 7 blocks, the [tag name] can be anything:</p> +<pre><code class="language-example"><Warning> +*bar* +</Warning> +. +<Warning> +*bar* +</Warning> +</code></pre> +<pre><code class="language-example"><i class="foo"> +*bar* +</i> +. +<i class="foo"> +*bar* +</i> +</code></pre> +<pre><code class="language-example"></ins> +*bar* +. +</ins> +*bar* +</code></pre> +<p>These rules are designed to allow us to work with tags that +can function as either block-level or inline-level tags. +The <code><del></code> tag is a nice example. We can surround content with +<code><del></code> tags in three different ways. In this case, we get a raw +HTML block, because the <code><del></code> tag is on a line by itself:</p> +<pre><code class="language-example"><del> +*foo* +</del> +. +<del> +*foo* +</del> +</code></pre> +<p>In this case, we get a raw HTML block that just includes +the <code><del></code> tag (because it ends with the following blank +line). So the contents get interpreted as CommonMark:</p> +<pre><code class="language-example"><del> + +*foo* + +</del> +. +<del> +<p><em>foo</em></p> +</del> +</code></pre> +<p>Finally, in this case, the <code><del></code> tags are interpreted +as [raw HTML] <em>inside</em> the CommonMark paragraph. (Because +the tag is not on a line by itself, we get inline HTML +rather than an [HTML block].)</p> +<pre><code class="language-example"><del>*foo*</del> +. +<p><del><em>foo</em></del></p> +</code></pre> +<p>HTML tags designed to contain literal content +(<code>pre</code>, <code>script</code>, <code>style</code>, <code>textarea</code>), comments, processing instructions, +and declarations are treated somewhat differently. +Instead of ending at the first blank line, these blocks +end at the first line containing a corresponding end tag. +As a result, these blocks can contain blank lines:</p> +<p>A pre tag (type 1):</p> +<pre><code class="language-example"><pre language="haskell"><code> +import Text.HTML.TagSoup + +main :: IO () +main = print $ parseTags tags +</code></pre> +okay +. +<pre language="haskell"><code> +import Text.HTML.TagSoup + +main :: IO () +main = print $ parseTags tags +</code></pre> +<p>okay</p> +</code></pre> +<p>A script tag (type 1):</p> +<pre><code class="language-example"><script type="text/javascript"> +// JavaScript example + +document.getElementById("demo").innerHTML = "Hello JavaScript!"; +</script> +okay +. +<script type="text/javascript"> +// JavaScript example + +document.getElementById("demo").innerHTML = "Hello JavaScript!"; +</script> +<p>okay</p> +</code></pre> +<p>A textarea tag (type 1):</p> +<pre><code class="language-example"><textarea> + +*foo* + +_bar_ + +</textarea> +. +<textarea> + +*foo* + +_bar_ + +</textarea> +</code></pre> +<p>A style tag (type 1):</p> +<pre><code class="language-example"><style + type="text/css"> +h1 {color:red;} + +p {color:blue;} +</style> +okay +. +<style + type="text/css"> +h1 {color:red;} + +p {color:blue;} +</style> +<p>okay</p> +</code></pre> +<p>If there is no matching end tag, the block will end at the +end of the document (or the enclosing [block quote][block quotes] +or [list item][list items]):</p> +<pre><code class="language-example"><style + type="text/css"> + +foo +. +<style + type="text/css"> + +foo +</code></pre> +<pre><code class="language-example">> <div> +> foo + +bar +. +<blockquote> +<div> +foo +</blockquote> +<p>bar</p> +</code></pre> +<pre><code class="language-example">- <div> +- foo +. +<ul> +<li> +<div> +</li> +<li>foo</li> +</ul> +</code></pre> +<p>The end tag can occur on the same line as the start tag:</p> +<pre><code class="language-example"><style>p{color:red;}</style> +*foo* +. +<style>p{color:red;}</style> +<p><em>foo</em></p> +</code></pre> +<pre><code class="language-example"><!-- foo -->*bar* +*baz* +. +<!-- foo -->*bar* +<p><em>baz</em></p> +</code></pre> +<p>Note that anything on the last line after the +end tag will be included in the [HTML block]:</p> +<pre><code class="language-example"><script> +foo +</script>1. *bar* +. +<script> +foo +</script>1. *bar* +</code></pre> +<p>A comment (type 2):</p> +<pre><code class="language-example"><!-- Foo + +bar + baz --> +okay +. +<!-- Foo + +bar + baz --> +<p>okay</p> +</code></pre> +<p>A processing instruction (type 3):</p> +<pre><code class="language-example"><?php + + echo '>'; + +?> +okay +. +<?php + + echo '>'; + +?> +<p>okay</p> +</code></pre> +<p>A declaration (type 4):</p> +<pre><code class="language-example"><!DOCTYPE html> +. +<!DOCTYPE html> +</code></pre> +<p>CDATA (type 5):</p> +<pre><code class="language-example"><![CDATA[ +function matchwo(a,b) +{ + if (a < b && a < 0) then { + return 1; + + } else { + + return 0; + } +} +]]> +okay +. +<![CDATA[ +function matchwo(a,b) +{ + if (a < b && a < 0) then { + return 1; + + } else { + + return 0; + } +} +]]> +<p>okay</p> +</code></pre> +<p>The opening tag can be preceded by up to three spaces of indentation, but not +four:</p> +<pre><code class="language-example"> <!-- foo --> + + <!-- foo --> +. + <!-- foo --> +<pre><code>&lt;!-- foo --&gt; +</code></pre> +</code></pre> +<pre><code class="language-example"> <div> + + <div> +. + <div> +<pre><code>&lt;div&gt; +</code></pre> +</code></pre> +<p>An HTML block of types 1--6 can interrupt a paragraph, and need not be +preceded by a blank line.</p> +<pre><code class="language-example">Foo +<div> +bar +</div> +. +<p>Foo</p> +<div> +bar +</div> +</code></pre> +<p>However, a following blank line is needed, except at the end of +a document, and except for blocks of types 1--5, [above][HTML +block]:</p> +<pre><code class="language-example"><div> +bar +</div> +*foo* +. +<div> +bar +</div> +*foo* +</code></pre> +<p>HTML blocks of type 7 cannot interrupt a paragraph:</p> +<pre><code class="language-example">Foo +<a href="bar"> +baz +. +<p>Foo +<a href="bar"> +baz</p> +</code></pre> +<p>This rule differs from John Gruber's original Markdown syntax +specification, which says:</p> +<blockquote> +<p>The only restrictions are that block-level HTML elements — +e.g. <code><div></code>, <code><table></code>, <code><pre></code>, <code><p></code>, etc. — must be separated from +surrounding content by blank lines, and the start and end tags of the +block should not be indented with spaces or tabs.</p> +</blockquote> +<p>In some ways Gruber's rule is more restrictive than the one given +here:</p> +<ul> +<li>It requires that an HTML block be preceded by a blank line.</li> +<li>It does not allow the start tag to be indented.</li> +<li>It requires a matching end tag, which it also does not allow to +be indented.</li> +</ul> +<p>Most Markdown implementations (including some of Gruber's own) do not +respect all of these restrictions.</p> +<p>There is one respect, however, in which Gruber's rule is more liberal +than the one given here, since it allows blank lines to occur inside +an HTML block. There are two reasons for disallowing them here. +First, it removes the need to parse balanced tags, which is +expensive and can require backtracking from the end of the document +if no matching end tag is found. Second, it provides a very simple +and flexible way of including Markdown content inside HTML tags: +simply separate the Markdown from the HTML using blank lines:</p> +<p>Compare:</p> +<pre><code class="language-example"><div> + +*Emphasized* text. + +</div> +. +<div> +<p><em>Emphasized</em> text.</p> +</div> +</code></pre> +<pre><code class="language-example"><div> +*Emphasized* text. +</div> +. +<div> +*Emphasized* text. +</div> +</code></pre> +<p>Some Markdown implementations have adopted a convention of +interpreting content inside tags as text if the open tag has +the attribute <code>markdown=1</code>. The rule given above seems a simpler and +more elegant way of achieving the same expressive power, which is also +much simpler to parse.</p> +<p>The main potential drawback is that one can no longer paste HTML +blocks into Markdown documents with 100% reliability. However, +<em>in most cases</em> this will work fine, because the blank lines in +HTML are usually followed by HTML block tags. For example:</p> +<pre><code class="language-example"><table> + +<tr> + +<td> +Hi +</td> + +</tr> + +</table> +. +<table> +<tr> +<td> +Hi +</td> +</tr> +</table> +</code></pre> +<p>There are problems, however, if the inner tags are indented +<em>and</em> separated by spaces, as then they will be interpreted as +an indented code block:</p> +<pre><code class="language-example"><table> + + <tr> + + <td> + Hi + </td> + + </tr> + +</table> +. +<table> + <tr> +<pre><code>&lt;td&gt; + Hi +&lt;/td&gt; +</code></pre> + </tr> +</table> +</code></pre> +<p>Fortunately, blank lines are usually not necessary and can be +deleted. The exception is inside <code><pre></code> tags, but as described +[above][HTML blocks], raw HTML blocks starting with <code><pre></code> +<em>can</em> contain blank lines.</p> +<h2>Link reference definitions</h2> +<p>A <a href="@">link reference definition</a> +consists of a [link label], optionally preceded by up to three spaces of +indentation, followed +by a colon (<code>:</code>), optional spaces or tabs (including up to one +[line ending]), a [link destination], +optional spaces or tabs (including up to one +[line ending]), and an optional [link +title], which if it is present must be separated +from the [link destination] by spaces or tabs. +No further character may occur.</p> +<p>A [link reference definition] +does not correspond to a structural element of a document. Instead, it +defines a label which can be used in [reference links] +and reference-style [images] elsewhere in the document. [Link +reference definitions] can come either before or after the links that use +them.</p> +<pre><code class="language-example">[foo]: /url "title" + +[foo] +. +<p><a href="/url" title="title">foo</a></p> +</code></pre> +<pre><code class="language-example"> [foo]: + /url + 'the title' + +[foo] +. +<p><a href="/url" title="the title">foo</a></p> +</code></pre> +<pre><code class="language-example">[Foo*bar\]]:my_(url) 'title (with parens)' + +[Foo*bar\]] +. +<p><a href="my_(url)" title="title (with parens)">Foo*bar]</a></p> +</code></pre> +<pre><code class="language-example">[Foo bar]: +<my url> +'title' + +[Foo bar] +. +<p><a href="my%20url" title="title">Foo bar</a></p> +</code></pre> +<p>The title may extend over multiple lines:</p> +<pre><code class="language-example">[foo]: /url ' +title +line1 +line2 +' + +[foo] +. +<p><a href="/url" title=" +title +line1 +line2 +">foo</a></p> +</code></pre> +<p>However, it may not contain a [blank line]:</p> +<pre><code class="language-example">[foo]: /url 'title + +with blank line' + +[foo] +. +<p>[foo]: /url 'title</p> +<p>with blank line'</p> +<p>[foo]</p> +</code></pre> +<p>The title may be omitted:</p> +<pre><code class="language-example">[foo]: +/url + +[foo] +. +<p><a href="/url">foo</a></p> +</code></pre> +<p>The link destination may not be omitted:</p> +<pre><code class="language-example">[foo]: + +[foo] +. +<p>[foo]:</p> +<p>[foo]</p> +</code></pre> +<p>However, an empty link destination may be specified using +angle brackets:</p> +<pre><code class="language-example">[foo]: <> + +[foo] +. +<p><a href="">foo</a></p> +</code></pre> +<p>The title must be separated from the link destination by +spaces or tabs:</p> +<pre><code class="language-example">[foo]: <bar>(baz) + +[foo] +. +<p>[foo]: <bar>(baz)</p> +<p>[foo]</p> +</code></pre> +<p>Both title and destination can contain backslash escapes +and literal backslashes:</p> +<pre><code class="language-example">[foo]: /url\bar\*baz "foo\"bar\baz" + +[foo] +. +<p><a href="/url%5Cbar*baz" title="foo&quot;bar\baz">foo</a></p> +</code></pre> +<p>A link can come before its corresponding definition:</p> +<pre><code class="language-example">[foo] + +[foo]: url +. +<p><a href="url">foo</a></p> +</code></pre> +<p>If there are several matching definitions, the first one takes +precedence:</p> +<pre><code class="language-example">[foo] + +[foo]: first +[foo]: second +. +<p><a href="first">foo</a></p> +</code></pre> +<p>As noted in the section on [Links], matching of labels is +case-insensitive (see [matches]).</p> +<pre><code class="language-example">[FOO]: /url + +[Foo] +. +<p><a href="/url">Foo</a></p> +</code></pre> +<pre><code class="language-example">[ΑΓΩ]: /φου + +[αγω] +. +<p><a href="/%CF%86%CE%BF%CF%85">αγω</a></p> +</code></pre> +<p>Whether something is a [link reference definition] is +independent of whether the link reference it defines is +used in the document. Thus, for example, the following +document contains just a link reference definition, and +no visible content:</p> +<pre><code class="language-example">[foo]: /url +. +</code></pre> +<p>Here is another one:</p> +<pre><code class="language-example">[ +foo +]: /url +bar +. +<p>bar</p> +</code></pre> +<p>This is not a link reference definition, because there are +characters other than spaces or tabs after the title:</p> +<pre><code class="language-example">[foo]: /url "title" ok +. +<p>[foo]: /url &quot;title&quot; ok</p> +</code></pre> +<p>This is a link reference definition, but it has no title:</p> +<pre><code class="language-example">[foo]: /url +"title" ok +. +<p>&quot;title&quot; ok</p> +</code></pre> +<p>This is not a link reference definition, because it is indented +four spaces:</p> +<pre><code class="language-example"> [foo]: /url "title" + +[foo] +. +<pre><code>[foo]: /url &quot;title&quot; +</code></pre> +<p>[foo]</p> +</code></pre> +<p>This is not a link reference definition, because it occurs inside +a code block:</p> +<pre><code class="language-example">``` +[foo]: /url +``` + +[foo] +. +<pre><code>[foo]: /url +</code></pre> +<p>[foo]</p> +</code></pre> +<p>A [link reference definition] cannot interrupt a paragraph.</p> +<pre><code class="language-example">Foo +[bar]: /baz + +[bar] +. +<p>Foo +[bar]: /baz</p> +<p>[bar]</p> +</code></pre> +<p>However, it can directly follow other block elements, such as headings +and thematic breaks, and it need not be followed by a blank line.</p> +<pre><code class="language-example"># [Foo] +[foo]: /url +> bar +. +<h1><a href="/url">Foo</a></h1> +<blockquote> +<p>bar</p> +</blockquote> +</code></pre> +<pre><code class="language-example">[foo]: /url +bar +=== +[foo] +. +<h1>bar</h1> +<p><a href="/url">foo</a></p> +</code></pre> +<pre><code class="language-example">[foo]: /url +=== +[foo] +. +<p>=== +<a href="/url">foo</a></p> +</code></pre> +<p>Several [link reference definitions] +can occur one after another, without intervening blank lines.</p> +<pre><code class="language-example">[foo]: /foo-url "foo" +[bar]: /bar-url + "bar" +[baz]: /baz-url + +[foo], +[bar], +[baz] +. +<p><a href="/foo-url" title="foo">foo</a>, +<a href="/bar-url" title="bar">bar</a>, +<a href="/baz-url">baz</a></p> +</code></pre> +<p>[Link reference definitions] can occur +inside block containers, like lists and block quotations. They +affect the entire document, not just the container in which they +are defined:</p> +<pre><code class="language-example">[foo] + +> [foo]: /url +. +<p><a href="/url">foo</a></p> +<blockquote> +</blockquote> +</code></pre> +<h2>Paragraphs</h2> +<p>A sequence of non-blank lines that cannot be interpreted as other +kinds of blocks forms a <a href="@">paragraph</a>. +The contents of the paragraph are the result of parsing the +paragraph's raw content as inlines. The paragraph's raw content +is formed by concatenating the lines and removing initial and final +spaces or tabs.</p> +<p>A simple example with two paragraphs:</p> +<pre><code class="language-example">aaa + +bbb +. +<p>aaa</p> +<p>bbb</p> +</code></pre> +<p>Paragraphs can contain multiple lines, but no blank lines:</p> +<pre><code class="language-example">aaa +bbb + +ccc +ddd +. +<p>aaa +bbb</p> +<p>ccc +ddd</p> +</code></pre> +<p>Multiple blank lines between paragraphs have no effect:</p> +<pre><code class="language-example">aaa + + +bbb +. +<p>aaa</p> +<p>bbb</p> +</code></pre> +<p>Leading spaces or tabs are skipped:</p> +<pre><code class="language-example"> aaa + bbb +. +<p>aaa +bbb</p> +</code></pre> +<p>Lines after the first may be indented any amount, since indented +code blocks cannot interrupt paragraphs.</p> +<pre><code class="language-example">aaa + bbb + ccc +. +<p>aaa +bbb +ccc</p> +</code></pre> +<p>However, the first line may be preceded by up to three spaces of indentation. +Four spaces of indentation is too many:</p> +<pre><code class="language-example"> aaa +bbb +. +<p>aaa +bbb</p> +</code></pre> +<pre><code class="language-example"> aaa +bbb +. +<pre><code>aaa +</code></pre> +<p>bbb</p> +</code></pre> +<p>Final spaces or tabs are stripped before inline parsing, so a paragraph +that ends with two or more spaces will not end with a [hard line +break]:</p> +<pre><code class="language-example">aaa +bbb +. +<p>aaa<br /> +bbb</p> +</code></pre> +<h2>Blank lines</h2> +<p>[Blank lines] between block-level elements are ignored, +except for the role they play in determining whether a [list] +is [tight] or [loose].</p> +<p>Blank lines at the beginning and end of the document are also ignored.</p> +<pre><code class="language-example"> + +aaa + + +# aaa + + +. +<p>aaa</p> +<h1>aaa</h1> +</code></pre> +<h1>Container blocks</h1> +<p>A <a href="#container-blocks">container block</a> is a block that has other +blocks as its contents. There are two basic kinds of container blocks: +[block quotes] and [list items]. +[Lists] are meta-containers for [list items].</p> +<p>We define the syntax for container blocks recursively. The general +form of the definition is:</p> +<blockquote> +<p>If X is a sequence of blocks, then the result of +transforming X in such-and-such a way is a container of type Y +with these blocks as its content.</p> +</blockquote> +<p>So, we explain what counts as a block quote or list item by explaining +how these can be <em>generated</em> from their contents. This should suffice +to define the syntax, although it does not give a recipe for <em>parsing</em> +these constructions. (A recipe is provided below in the section entitled +<a href="#appendix-a-parsing-strategy">A parsing strategy</a>.)</p> +<h2>Block quotes</h2> +<p>A <a href="@">block quote marker</a>, +optionally preceded by up to three spaces of indentation, +consists of (a) the character <code>></code> together with a following space of +indentation, or (b) a single character <code>></code> not followed by a space of +indentation.</p> +<p>The following rules define [block quotes]:</p> +<ol> +<li> +<p><strong>Basic case.</strong> If a string of lines <em>Ls</em> constitute a sequence +of blocks <em>Bs</em>, then the result of prepending a [block quote +marker] to the beginning of each line in <em>Ls</em> +is a <a href="#block-quotes">block quote</a> containing <em>Bs</em>.</p> +</li> +<li> +<p><strong>Laziness.</strong> If a string of lines <em>Ls</em> constitute a <a href="#block-quotes">block +quote</a> with contents <em>Bs</em>, then the result of deleting +the initial [block quote marker] from one or +more lines in which the next character other than a space or tab after the +[block quote marker] is [paragraph continuation +text] is a block quote with <em>Bs</em> as its content. +<a href="@">Paragraph continuation text</a> is text +that will be parsed as part of the content of a paragraph, but does +not occur at the beginning of the paragraph.</p> +</li> +<li> +<p><strong>Consecutiveness.</strong> A document cannot contain two [block +quotes] in a row unless there is a [blank line] between them.</p> +</li> +</ol> +<p>Nothing else counts as a <a href="#block-quotes">block quote</a>.</p> +<p>Here is a simple example:</p> +<pre><code class="language-example">> # Foo +> bar +> baz +. +<blockquote> +<h1>Foo</h1> +<p>bar +baz</p> +</blockquote> +</code></pre> +<p>The space or tab after the <code>></code> characters can be omitted:</p> +<pre><code class="language-example">># Foo +>bar +> baz +. +<blockquote> +<h1>Foo</h1> +<p>bar +baz</p> +</blockquote> +</code></pre> +<p>The <code>></code> characters can be preceded by up to three spaces of indentation:</p> +<pre><code class="language-example"> > # Foo + > bar + > baz +. +<blockquote> +<h1>Foo</h1> +<p>bar +baz</p> +</blockquote> +</code></pre> +<p>Four spaces of indentation is too many:</p> +<pre><code class="language-example"> > # Foo + > bar + > baz +. +<pre><code>&gt; # Foo +&gt; bar +&gt; baz +</code></pre> +</code></pre> +<p>The Laziness clause allows us to omit the <code>></code> before +[paragraph continuation text]:</p> +<pre><code class="language-example">> # Foo +> bar +baz +. +<blockquote> +<h1>Foo</h1> +<p>bar +baz</p> +</blockquote> +</code></pre> +<p>A block quote can contain some lazy and some non-lazy +continuation lines:</p> +<pre><code class="language-example">> bar +baz +> foo +. +<blockquote> +<p>bar +baz +foo</p> +</blockquote> +</code></pre> +<p>Laziness only applies to lines that would have been continuations of +paragraphs had they been prepended with [block quote markers]. +For example, the <code>> </code> cannot be omitted in the second line of</p> +<pre><code class="language-markdown">> foo +> --- +</code></pre> +<p>without changing the meaning:</p> +<pre><code class="language-example">> foo +--- +. +<blockquote> +<p>foo</p> +</blockquote> +<hr /> +</code></pre> +<p>Similarly, if we omit the <code>> </code> in the second line of</p> +<pre><code class="language-markdown">> - foo +> - bar +</code></pre> +<p>then the block quote ends after the first line:</p> +<pre><code class="language-example">> - foo +- bar +. +<blockquote> +<ul> +<li>foo</li> +</ul> +</blockquote> +<ul> +<li>bar</li> +</ul> +</code></pre> +<p>For the same reason, we can't omit the <code>> </code> in front of +subsequent lines of an indented or fenced code block:</p> +<pre><code class="language-example">> foo + bar +. +<blockquote> +<pre><code>foo +</code></pre> +</blockquote> +<pre><code>bar +</code></pre> +</code></pre> +<pre><code class="language-example">> ``` +foo +``` +. +<blockquote> +<pre><code></code></pre> +</blockquote> +<p>foo</p> +<pre><code></code></pre> +</code></pre> +<p>Note that in the following case, we have a [lazy +continuation line]:</p> +<pre><code class="language-example">> foo + - bar +. +<blockquote> +<p>foo +- bar</p> +</blockquote> +</code></pre> +<p>To see why, note that in</p> +<pre><code class="language-markdown">> foo +> - bar +</code></pre> +<p>the <code>- bar</code> is indented too far to start a list, and can't +be an indented code block because indented code blocks cannot +interrupt paragraphs, so it is [paragraph continuation text].</p> +<p>A block quote can be empty:</p> +<pre><code class="language-example">> +. +<blockquote> +</blockquote> +</code></pre> +<pre><code class="language-example">> +> +> +. +<blockquote> +</blockquote> +</code></pre> +<p>A block quote can have initial or final blank lines:</p> +<pre><code class="language-example">> +> foo +> +. +<blockquote> +<p>foo</p> +</blockquote> +</code></pre> +<p>A blank line always separates block quotes:</p> +<pre><code class="language-example">> foo + +> bar +. +<blockquote> +<p>foo</p> +</blockquote> +<blockquote> +<p>bar</p> +</blockquote> +</code></pre> +<p>(Most current Markdown implementations, including John Gruber's +original <code>Markdown.pl</code>, will parse this example as a single block quote +with two paragraphs. But it seems better to allow the author to decide +whether two block quotes or one are wanted.)</p> +<p>Consecutiveness means that if we put these block quotes together, +we get a single block quote:</p> +<pre><code class="language-example">> foo +> bar +. +<blockquote> +<p>foo +bar</p> +</blockquote> +</code></pre> +<p>To get a block quote with two paragraphs, use:</p> +<pre><code class="language-example">> foo +> +> bar +. +<blockquote> +<p>foo</p> +<p>bar</p> +</blockquote> +</code></pre> +<p>Block quotes can interrupt paragraphs:</p> +<pre><code class="language-example">foo +> bar +. +<p>foo</p> +<blockquote> +<p>bar</p> +</blockquote> +</code></pre> +<p>In general, blank lines are not needed before or after block +quotes:</p> +<pre><code class="language-example">> aaa +*** +> bbb +. +<blockquote> +<p>aaa</p> +</blockquote> +<hr /> +<blockquote> +<p>bbb</p> +</blockquote> +</code></pre> +<p>However, because of laziness, a blank line is needed between +a block quote and a following paragraph:</p> +<pre><code class="language-example">> bar +baz +. +<blockquote> +<p>bar +baz</p> +</blockquote> +</code></pre> +<pre><code class="language-example">> bar + +baz +. +<blockquote> +<p>bar</p> +</blockquote> +<p>baz</p> +</code></pre> +<pre><code class="language-example">> bar +> +baz +. +<blockquote> +<p>bar</p> +</blockquote> +<p>baz</p> +</code></pre> +<p>It is a consequence of the Laziness rule that any number +of initial <code>></code>s may be omitted on a continuation line of a +nested block quote:</p> +<pre><code class="language-example">> > > foo +bar +. +<blockquote> +<blockquote> +<blockquote> +<p>foo +bar</p> +</blockquote> +</blockquote> +</blockquote> +</code></pre> +<pre><code class="language-example">>>> foo +> bar +>>baz +. +<blockquote> +<blockquote> +<blockquote> +<p>foo +bar +baz</p> +</blockquote> +</blockquote> +</blockquote> +</code></pre> +<p>When including an indented code block in a block quote, +remember that the [block quote marker] includes +both the <code>></code> and a following space of indentation. So <em>five spaces</em> are needed +after the <code>></code>:</p> +<pre><code class="language-example">> code + +> not code +. +<blockquote> +<pre><code>code +</code></pre> +</blockquote> +<blockquote> +<p>not code</p> +</blockquote> +</code></pre> +<h2>List items</h2> +<p>A <a href="@">list marker</a> is a +[bullet list marker] or an [ordered list marker].</p> +<p>A <a href="@">bullet list marker</a> +is a <code>-</code>, <code>+</code>, or <code>*</code> character.</p> +<p>An <a href="@">ordered list marker</a> +is a sequence of 1--9 arabic digits (<code>0-9</code>), followed by either a +<code>.</code> character or a <code>)</code> character. (The reason for the length +limit is that with 10 digits we start seeing integer overflows +in some browsers.)</p> +<p>The following rules define [list items]:</p> +<ol> +<li> +<p><strong>Basic case.</strong> If a sequence of lines <em>Ls</em> constitute a sequence of +blocks <em>Bs</em> starting with a character other than a space or tab, and <em>M</em> is +a list marker of width <em>W</em> followed by 1 ≤ <em>N</em> ≤ 4 spaces of indentation, +then the result of prepending <em>M</em> and the following spaces to the first line +of Ls*, and indenting subsequent lines of <em>Ls</em> by <em>W + N</em> spaces, is a +list item with <em>Bs</em> as its contents. The type of the list item +(bullet or ordered) is determined by the type of its list marker. +If the list item is ordered, then it is also assigned a start +number, based on the ordered list marker.</p> +<p>Exceptions:</p> +<ol> +<li>When the first list item in a [list] interrupts +a paragraph---that is, when it starts on a line that would +otherwise count as [paragraph continuation text]---then (a) +the lines <em>Ls</em> must not begin with a blank line, and (b) if +the list item is ordered, the start number must be 1.</li> +<li>If any line is a [thematic break][thematic breaks] then +that line is not a list item.</li> +</ol> +</li> +</ol> +<p>For example, let <em>Ls</em> be the lines</p> +<pre><code class="language-example">A paragraph +with two lines. + + indented code + +> A block quote. +. +<p>A paragraph +with two lines.</p> +<pre><code>indented code +</code></pre> +<blockquote> +<p>A block quote.</p> +</blockquote> +</code></pre> +<p>And let <em>M</em> be the marker <code>1.</code>, and <em>N</em> = 2. Then rule #1 says +that the following is an ordered list item with start number 1, +and the same contents as <em>Ls</em>:</p> +<pre><code class="language-example">1. A paragraph + with two lines. + + indented code + + > A block quote. +. +<ol> +<li> +<p>A paragraph +with two lines.</p> +<pre><code>indented code +</code></pre> +<blockquote> +<p>A block quote.</p> +</blockquote> +</li> +</ol> +</code></pre> +<p>The most important thing to notice is that the position of +the text after the list marker determines how much indentation +is needed in subsequent blocks in the list item. If the list +marker takes up two spaces of indentation, and there are three spaces between +the list marker and the next character other than a space or tab, then blocks +must be indented five spaces in order to fall under the list +item.</p> +<p>Here are some examples showing how far content must be indented to be +put under the list item:</p> +<pre><code class="language-example">- one + + two +. +<ul> +<li>one</li> +</ul> +<p>two</p> +</code></pre> +<pre><code class="language-example">- one + + two +. +<ul> +<li> +<p>one</p> +<p>two</p> +</li> +</ul> +</code></pre> +<pre><code class="language-example"> - one + + two +. +<ul> +<li>one</li> +</ul> +<pre><code> two +</code></pre> +</code></pre> +<pre><code class="language-example"> - one + + two +. +<ul> +<li> +<p>one</p> +<p>two</p> +</li> +</ul> +</code></pre> +<p>It is tempting to think of this in terms of columns: the continuation +blocks must be indented at least to the column of the first character other than +a space or tab after the list marker. However, that is not quite right. +The spaces of indentation after the list marker determine how much relative +indentation is needed. Which column this indentation reaches will depend on +how the list item is embedded in other constructions, as shown by +this example:</p> +<pre><code class="language-example"> > > 1. one +>> +>> two +. +<blockquote> +<blockquote> +<ol> +<li> +<p>one</p> +<p>two</p> +</li> +</ol> +</blockquote> +</blockquote> +</code></pre> +<p>Here <code>two</code> occurs in the same column as the list marker <code>1.</code>, +but is actually contained in the list item, because there is +sufficient indentation after the last containing blockquote marker.</p> +<p>The converse is also possible. In the following example, the word <code>two</code> +occurs far to the right of the initial text of the list item, <code>one</code>, but +it is not considered part of the list item, because it is not indented +far enough past the blockquote marker:</p> +<pre><code class="language-example">>>- one +>> + > > two +. +<blockquote> +<blockquote> +<ul> +<li>one</li> +</ul> +<p>two</p> +</blockquote> +</blockquote> +</code></pre> +<p>Note that at least one space or tab is needed between the list marker and +any following content, so these are not list items:</p> +<pre><code class="language-example">-one + +2.two +. +<p>-one</p> +<p>2.two</p> +</code></pre> +<p>A list item may contain blocks that are separated by more than +one blank line.</p> +<pre><code class="language-example">- foo + + + bar +. +<ul> +<li> +<p>foo</p> +<p>bar</p> +</li> +</ul> +</code></pre> +<p>A list item may contain any kind of block:</p> +<pre><code class="language-example">1. foo + + ``` + bar + ``` + + baz + + > bam +. +<ol> +<li> +<p>foo</p> +<pre><code>bar +</code></pre> +<p>baz</p> +<blockquote> +<p>bam</p> +</blockquote> +</li> +</ol> +</code></pre> +<p>A list item that contains an indented code block will preserve +empty lines within the code block verbatim.</p> +<pre><code class="language-example">- Foo + + bar + + + baz +. +<ul> +<li> +<p>Foo</p> +<pre><code>bar + + +baz +</code></pre> +</li> +</ul> +</code></pre> +<p>Note that ordered list start numbers must be nine digits or less:</p> +<pre><code class="language-example">123456789. ok +. +<ol start="123456789"> +<li>ok</li> +</ol> +</code></pre> +<pre><code class="language-example">1234567890. not ok +. +<p>1234567890. not ok</p> +</code></pre> +<p>A start number may begin with 0s:</p> +<pre><code class="language-example">0. ok +. +<ol start="0"> +<li>ok</li> +</ol> +</code></pre> +<pre><code class="language-example">003. ok +. +<ol start="3"> +<li>ok</li> +</ol> +</code></pre> +<p>A start number may not be negative:</p> +<pre><code class="language-example">-1. not ok +. +<p>-1. not ok</p> +</code></pre> +<ol start="2"> +<li><strong>Item starting with indented code.</strong> If a sequence of lines <em>Ls</em> +constitute a sequence of blocks <em>Bs</em> starting with an indented code +block, and <em>M</em> is a list marker of width <em>W</em> followed by +one space of indentation, then the result of prepending <em>M</em> and the +following space to the first line of <em>Ls</em>, and indenting subsequent lines +of <em>Ls</em> by <em>W + 1</em> spaces, is a list item with <em>Bs</em> as its contents. +If a line is empty, then it need not be indented. The type of the +list item (bullet or ordered) is determined by the type of its list +marker. If the list item is ordered, then it is also assigned a +start number, based on the ordered list marker.</li> +</ol> +<p>An indented code block will have to be preceded by four spaces of indentation +beyond the edge of the region where text will be included in the list item. +In the following case that is 6 spaces:</p> +<pre><code class="language-example">- foo + + bar +. +<ul> +<li> +<p>foo</p> +<pre><code>bar +</code></pre> +</li> +</ul> +</code></pre> +<p>And in this case it is 11 spaces:</p> +<pre><code class="language-example"> 10. foo + + bar +. +<ol start="10"> +<li> +<p>foo</p> +<pre><code>bar +</code></pre> +</li> +</ol> +</code></pre> +<p>If the <em>first</em> block in the list item is an indented code block, +then by rule #2, the contents must be preceded by <em>one</em> space of indentation +after the list marker:</p> +<pre><code class="language-example"> indented code + +paragraph + + more code +. +<pre><code>indented code +</code></pre> +<p>paragraph</p> +<pre><code>more code +</code></pre> +</code></pre> +<pre><code class="language-example">1. indented code + + paragraph + + more code +. +<ol> +<li> +<pre><code>indented code +</code></pre> +<p>paragraph</p> +<pre><code>more code +</code></pre> +</li> +</ol> +</code></pre> +<p>Note that an additional space of indentation is interpreted as space +inside the code block:</p> +<pre><code class="language-example">1. indented code + + paragraph + + more code +. +<ol> +<li> +<pre><code> indented code +</code></pre> +<p>paragraph</p> +<pre><code>more code +</code></pre> +</li> +</ol> +</code></pre> +<p>Note that rules #1 and #2 only apply to two cases: (a) cases +in which the lines to be included in a list item begin with a +character other than a space or tab, and (b) cases in which +they begin with an indented code +block. In a case like the following, where the first block begins with +three spaces of indentation, the rules do not allow us to form a list item by +indenting the whole thing and prepending a list marker:</p> +<pre><code class="language-example"> foo + +bar +. +<p>foo</p> +<p>bar</p> +</code></pre> +<pre><code class="language-example">- foo + + bar +. +<ul> +<li>foo</li> +</ul> +<p>bar</p> +</code></pre> +<p>This is not a significant restriction, because when a block is preceded by up to +three spaces of indentation, the indentation can always be removed without +a change in interpretation, allowing rule #1 to be applied. So, in +the above case:</p> +<pre><code class="language-example">- foo + + bar +. +<ul> +<li> +<p>foo</p> +<p>bar</p> +</li> +</ul> +</code></pre> +<ol start="3"> +<li><strong>Item starting with a blank line.</strong> If a sequence of lines <em>Ls</em> +starting with a single [blank line] constitute a (possibly empty) +sequence of blocks <em>Bs</em>, and <em>M</em> is a list marker of width <em>W</em>, +then the result of prepending <em>M</em> to the first line of <em>Ls</em>, and +preceding subsequent lines of <em>Ls</em> by <em>W + 1</em> spaces of indentation, is a +list item with <em>Bs</em> as its contents. +If a line is empty, then it need not be indented. The type of the +list item (bullet or ordered) is determined by the type of its list +marker. If the list item is ordered, then it is also assigned a +start number, based on the ordered list marker.</li> +</ol> +<p>Here are some list items that start with a blank line but are not empty:</p> +<pre><code class="language-example">- + foo +- + ``` + bar + ``` +- + baz +. +<ul> +<li>foo</li> +<li> +<pre><code>bar +</code></pre> +</li> +<li> +<pre><code>baz +</code></pre> +</li> +</ul> +</code></pre> +<p>When the list item starts with a blank line, the number of spaces +following the list marker doesn't change the required indentation:</p> +<pre><code class="language-example">- + foo +. +<ul> +<li>foo</li> +</ul> +</code></pre> +<p>A list item can begin with at most one blank line. +In the following example, <code>foo</code> is not part of the list +item:</p> +<pre><code class="language-example">- + + foo +. +<ul> +<li></li> +</ul> +<p>foo</p> +</code></pre> +<p>Here is an empty bullet list item:</p> +<pre><code class="language-example">- foo +- +- bar +. +<ul> +<li>foo</li> +<li></li> +<li>bar</li> +</ul> +</code></pre> +<p>It does not matter whether there are spaces or tabs following the [list marker]:</p> +<pre><code class="language-example">- foo +- +- bar +. +<ul> +<li>foo</li> +<li></li> +<li>bar</li> +</ul> +</code></pre> +<p>Here is an empty ordered list item:</p> +<pre><code class="language-example">1. foo +2. +3. bar +. +<ol> +<li>foo</li> +<li></li> +<li>bar</li> +</ol> +</code></pre> +<p>A list may start or end with an empty list item:</p> +<pre><code class="language-example">* +. +<ul> +<li></li> +</ul> +</code></pre> +<p>However, an empty list item cannot interrupt a paragraph:</p> +<pre><code class="language-example">foo +* + +foo +1. +. +<p>foo +*</p> +<p>foo +1.</p> +</code></pre> +<ol start="4"> +<li><strong>Indentation.</strong> If a sequence of lines <em>Ls</em> constitutes a list item +according to rule #1, #2, or #3, then the result of preceding each line +of <em>Ls</em> by up to three spaces of indentation (the same for each line) also +constitutes a list item with the same contents and attributes. If a line is +empty, then it need not be indented.</li> +</ol> +<p>Indented one space:</p> +<pre><code class="language-example"> 1. A paragraph + with two lines. + + indented code + + > A block quote. +. +<ol> +<li> +<p>A paragraph +with two lines.</p> +<pre><code>indented code +</code></pre> +<blockquote> +<p>A block quote.</p> +</blockquote> +</li> +</ol> +</code></pre> +<p>Indented two spaces:</p> +<pre><code class="language-example"> 1. A paragraph + with two lines. + + indented code + + > A block quote. +. +<ol> +<li> +<p>A paragraph +with two lines.</p> +<pre><code>indented code +</code></pre> +<blockquote> +<p>A block quote.</p> +</blockquote> +</li> +</ol> +</code></pre> +<p>Indented three spaces:</p> +<pre><code class="language-example"> 1. A paragraph + with two lines. + + indented code + + > A block quote. +. +<ol> +<li> +<p>A paragraph +with two lines.</p> +<pre><code>indented code +</code></pre> +<blockquote> +<p>A block quote.</p> +</blockquote> +</li> +</ol> +</code></pre> +<p>Four spaces indent gives a code block:</p> +<pre><code class="language-example"> 1. A paragraph + with two lines. + + indented code + + > A block quote. +. +<pre><code>1. A paragraph + with two lines. + + indented code + + &gt; A block quote. +</code></pre> +</code></pre> +<ol start="5"> +<li><strong>Laziness.</strong> If a string of lines <em>Ls</em> constitute a <a href="#list-items">list +item</a> with contents <em>Bs</em>, then the result of deleting +some or all of the indentation from one or more lines in which the +next character other than a space or tab after the indentation is +[paragraph continuation text] is a +list item with the same contents and attributes. The unindented +lines are called +<a href="@">lazy continuation line</a>s.</li> +</ol> +<p>Here is an example with [lazy continuation lines]:</p> +<pre><code class="language-example"> 1. A paragraph +with two lines. + + indented code + + > A block quote. +. +<ol> +<li> +<p>A paragraph +with two lines.</p> +<pre><code>indented code +</code></pre> +<blockquote> +<p>A block quote.</p> +</blockquote> +</li> +</ol> +</code></pre> +<p>Indentation can be partially deleted:</p> +<pre><code class="language-example"> 1. A paragraph + with two lines. +. +<ol> +<li>A paragraph +with two lines.</li> +</ol> +</code></pre> +<p>These examples show how laziness can work in nested structures:</p> +<pre><code class="language-example">> 1. > Blockquote +continued here. +. +<blockquote> +<ol> +<li> +<blockquote> +<p>Blockquote +continued here.</p> +</blockquote> +</li> +</ol> +</blockquote> +</code></pre> +<pre><code class="language-example">> 1. > Blockquote +> continued here. +. +<blockquote> +<ol> +<li> +<blockquote> +<p>Blockquote +continued here.</p> +</blockquote> +</li> +</ol> +</blockquote> +</code></pre> +<ol start="6"> +<li><strong>That's all.</strong> Nothing that is not counted as a list item by rules +#1--5 counts as a <a href="#list-items">list item</a>.</li> +</ol> +<p>The rules for sublists follow from the general rules +[above][List items]. A sublist must be indented the same number +of spaces of indentation a paragraph would need to be in order to be included +in the list item.</p> +<p>So, in this case we need two spaces indent:</p> +<pre><code class="language-example">- foo + - bar + - baz + - boo +. +<ul> +<li>foo +<ul> +<li>bar +<ul> +<li>baz +<ul> +<li>boo</li> +</ul> +</li> +</ul> +</li> +</ul> +</li> +</ul> +</code></pre> +<p>One is not enough:</p> +<pre><code class="language-example">- foo + - bar + - baz + - boo +. +<ul> +<li>foo</li> +<li>bar</li> +<li>baz</li> +<li>boo</li> +</ul> +</code></pre> +<p>Here we need four, because the list marker is wider:</p> +<pre><code class="language-example">10) foo + - bar +. +<ol start="10"> +<li>foo +<ul> +<li>bar</li> +</ul> +</li> +</ol> +</code></pre> +<p>Three is not enough:</p> +<pre><code class="language-example">10) foo + - bar +. +<ol start="10"> +<li>foo</li> +</ol> +<ul> +<li>bar</li> +</ul> +</code></pre> +<p>A list may be the first block in a list item:</p> +<pre><code class="language-example">- - foo +. +<ul> +<li> +<ul> +<li>foo</li> +</ul> +</li> +</ul> +</code></pre> +<pre><code class="language-example">1. - 2. foo +. +<ol> +<li> +<ul> +<li> +<ol start="2"> +<li>foo</li> +</ol> +</li> +</ul> +</li> +</ol> +</code></pre> +<p>A list item can contain a heading:</p> +<pre><code class="language-example">- # Foo +- Bar + --- + baz +. +<ul> +<li> +<h1>Foo</h1> +</li> +<li> +<h2>Bar</h2> +baz</li> +</ul> +</code></pre> +<h3>Motivation</h3> +<p>John Gruber's Markdown spec says the following about list items:</p> +<ol> +<li> +<p>"List markers typically start at the left margin, but may be indented +by up to three spaces. List markers must be followed by one or more +spaces or a tab."</p> +</li> +<li> +<p>"To make lists look nice, you can wrap items with hanging indents.... +But if you don't want to, you don't have to."</p> +</li> +<li> +<p>"List items may consist of multiple paragraphs. Each subsequent +paragraph in a list item must be indented by either 4 spaces or one +tab."</p> +</li> +<li> +<p>"It looks nice if you indent every line of the subsequent paragraphs, +but here again, Markdown will allow you to be lazy."</p> +</li> +<li> +<p>"To put a blockquote within a list item, the blockquote's <code>></code> +delimiters need to be indented."</p> +</li> +<li> +<p>"To put a code block within a list item, the code block needs to be +indented twice — 8 spaces or two tabs."</p> +</li> +</ol> +<p>These rules specify that a paragraph under a list item must be indented +four spaces (presumably, from the left margin, rather than the start of +the list marker, but this is not said), and that code under a list item +must be indented eight spaces instead of the usual four. They also say +that a block quote must be indented, but not by how much; however, the +example given has four spaces indentation. Although nothing is said +about other kinds of block-level content, it is certainly reasonable to +infer that <em>all</em> block elements under a list item, including other +lists, must be indented four spaces. This principle has been called the +<em>four-space rule</em>.</p> +<p>The four-space rule is clear and principled, and if the reference +implementation <code>Markdown.pl</code> had followed it, it probably would have +become the standard. However, <code>Markdown.pl</code> allowed paragraphs and +sublists to start with only two spaces indentation, at least on the +outer level. Worse, its behavior was inconsistent: a sublist of an +outer-level list needed two spaces indentation, but a sublist of this +sublist needed three spaces. It is not surprising, then, that different +implementations of Markdown have developed very different rules for +determining what comes under a list item. (Pandoc and python-Markdown, +for example, stuck with Gruber's syntax description and the four-space +rule, while discount, redcarpet, marked, PHP Markdown, and others +followed <code>Markdown.pl</code>'s behavior more closely.)</p> +<p>Unfortunately, given the divergences between implementations, there +is no way to give a spec for list items that will be guaranteed not +to break any existing documents. However, the spec given here should +correctly handle lists formatted with either the four-space rule or +the more forgiving <code>Markdown.pl</code> behavior, provided they are laid out +in a way that is natural for a human to read.</p> +<p>The strategy here is to let the width and indentation of the list marker +determine the indentation necessary for blocks to fall under the list +item, rather than having a fixed and arbitrary number. The writer can +think of the body of the list item as a unit which gets indented to the +right enough to fit the list marker (and any indentation on the list +marker). (The laziness rule, #5, then allows continuation lines to be +unindented if needed.)</p> +<p>This rule is superior, we claim, to any rule requiring a fixed level of +indentation from the margin. The four-space rule is clear but +unnatural. It is quite unintuitive that</p> +<pre><code class="language-markdown">- foo + + bar + + - baz +</code></pre> +<p>should be parsed as two lists with an intervening paragraph,</p> +<pre><code class="language-html"><ul> +<li>foo</li> +</ul> +<p>bar</p> +<ul> +<li>baz</li> +</ul> +</code></pre> +<p>as the four-space rule demands, rather than a single list,</p> +<pre><code class="language-html"><ul> +<li> +<p>foo</p> +<p>bar</p> +<ul> +<li>baz</li> +</ul> +</li> +</ul> +</code></pre> +<p>The choice of four spaces is arbitrary. It can be learned, but it is +not likely to be guessed, and it trips up beginners regularly.</p> +<p>Would it help to adopt a two-space rule? The problem is that such +a rule, together with the rule allowing up to three spaces of indentation for +the initial list marker, allows text that is indented <em>less than</em> the +original list marker to be included in the list item. For example, +<code>Markdown.pl</code> parses</p> +<pre><code class="language-markdown"> - one + + two +</code></pre> +<p>as a single list item, with <code>two</code> a continuation paragraph:</p> +<pre><code class="language-html"><ul> +<li> +<p>one</p> +<p>two</p> +</li> +</ul> +</code></pre> +<p>and similarly</p> +<pre><code class="language-markdown">> - one +> +> two +</code></pre> +<p>as</p> +<pre><code class="language-html"><blockquote> +<ul> +<li> +<p>one</p> +<p>two</p> +</li> +</ul> +</blockquote> +</code></pre> +<p>This is extremely unintuitive.</p> +<p>Rather than requiring a fixed indent from the margin, we could require +a fixed indent (say, two spaces, or even one space) from the list marker (which +may itself be indented). This proposal would remove the last anomaly +discussed. Unlike the spec presented above, it would count the following +as a list item with a subparagraph, even though the paragraph <code>bar</code> +is not indented as far as the first paragraph <code>foo</code>:</p> +<pre><code class="language-markdown"> 10. foo + + bar +</code></pre> +<p>Arguably this text does read like a list item with <code>bar</code> as a subparagraph, +which may count in favor of the proposal. However, on this proposal indented +code would have to be indented six spaces after the list marker. And this +would break a lot of existing Markdown, which has the pattern:</p> +<pre><code class="language-markdown">1. foo + + indented code +</code></pre> +<p>where the code is indented eight spaces. The spec above, by contrast, will +parse this text as expected, since the code block's indentation is measured +from the beginning of <code>foo</code>.</p> +<p>The one case that needs special treatment is a list item that <em>starts</em> +with indented code. How much indentation is required in that case, since +we don't have a "first paragraph" to measure from? Rule #2 simply stipulates +that in such cases, we require one space indentation from the list marker +(and then the normal four spaces for the indented code). This will match the +four-space rule in cases where the list marker plus its initial indentation +takes four spaces (a common case), but diverge in other cases.</p> +<h2>Lists</h2> +<p>A <a href="@">list</a> is a sequence of one or more +list items [of the same type]. The list items +may be separated by any number of blank lines.</p> +<p>Two list items are <a href="@">of the same type</a> +if they begin with a [list marker] of the same type. +Two list markers are of the +same type if (a) they are bullet list markers using the same character +(<code>-</code>, <code>+</code>, or <code>*</code>) or (b) they are ordered list numbers with the same +delimiter (either <code>.</code> or <code>)</code>).</p> +<p>A list is an <a href="@">ordered list</a> +if its constituent list items begin with +[ordered list markers], and a +<a href="@">bullet list</a> if its constituent list +items begin with [bullet list markers].</p> +<p>The <a href="@">start number</a> +of an [ordered list] is determined by the list number of +its initial list item. The numbers of subsequent list items are +disregarded.</p> +<p>A list is <a href="@">loose</a> if any of its constituent +list items are separated by blank lines, or if any of its constituent +list items directly contain two block-level elements with a blank line +between them. Otherwise a list is <a href="@">tight</a>. +(The difference in HTML output is that paragraphs in a loose list are +wrapped in <code><p></code> tags, while paragraphs in a tight list are not.)</p> +<p>Changing the bullet or ordered list delimiter starts a new list:</p> +<pre><code class="language-example">- foo +- bar ++ baz +. +<ul> +<li>foo</li> +<li>bar</li> +</ul> +<ul> +<li>baz</li> +</ul> +</code></pre> +<pre><code class="language-example">1. foo +2. bar +3) baz +. +<ol> +<li>foo</li> +<li>bar</li> +</ol> +<ol start="3"> +<li>baz</li> +</ol> +</code></pre> +<p>In CommonMark, a list can interrupt a paragraph. That is, +no blank line is needed to separate a paragraph from a following +list:</p> +<pre><code class="language-example">Foo +- bar +- baz +. +<p>Foo</p> +<ul> +<li>bar</li> +<li>baz</li> +</ul> +</code></pre> +<p><code>Markdown.pl</code> does not allow this, through fear of triggering a list +via a numeral in a hard-wrapped line:</p> +<pre><code class="language-markdown">The number of windows in my house is +14. The number of doors is 6. +</code></pre> +<p>Oddly, though, <code>Markdown.pl</code> <em>does</em> allow a blockquote to +interrupt a paragraph, even though the same considerations might +apply.</p> +<p>In CommonMark, we do allow lists to interrupt paragraphs, for +two reasons. First, it is natural and not uncommon for people +to start lists without blank lines:</p> +<pre><code class="language-markdown">I need to buy +- new shoes +- a coat +- a plane ticket +</code></pre> +<p>Second, we are attracted to a</p> +<blockquote> +<p><a href="@">principle of uniformity</a>: +if a chunk of text has a certain +meaning, it will continue to have the same meaning when put into a +container block (such as a list item or blockquote).</p> +</blockquote> +<p>(Indeed, the spec for [list items] and [block quotes] presupposes +this principle.) This principle implies that if</p> +<pre><code class="language-markdown"> * I need to buy + - new shoes + - a coat + - a plane ticket +</code></pre> +<p>is a list item containing a paragraph followed by a nested sublist, +as all Markdown implementations agree it is (though the paragraph +may be rendered without <code><p></code> tags, since the list is "tight"), +then</p> +<pre><code class="language-markdown">I need to buy +- new shoes +- a coat +- a plane ticket +</code></pre> +<p>by itself should be a paragraph followed by a nested sublist.</p> +<p>Since it is well established Markdown practice to allow lists to +interrupt paragraphs inside list items, the [principle of +uniformity] requires us to allow this outside list items as +well. (<a href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> +takes a different approach, requiring blank lines before lists +even inside other list items.)</p> +<p>In order to solve of unwanted lists in paragraphs with +hard-wrapped numerals, we allow only lists starting with <code>1</code> to +interrupt paragraphs. Thus,</p> +<pre><code class="language-example">The number of windows in my house is +14. The number of doors is 6. +. +<p>The number of windows in my house is +14. The number of doors is 6.</p> +</code></pre> +<p>We may still get an unintended result in cases like</p> +<pre><code class="language-example">The number of windows in my house is +1. The number of doors is 6. +. +<p>The number of windows in my house is</p> +<ol> +<li>The number of doors is 6.</li> +</ol> +</code></pre> +<p>but this rule should prevent most spurious list captures.</p> +<p>There can be any number of blank lines between items:</p> +<pre><code class="language-example">- foo + +- bar + + +- baz +. +<ul> +<li> +<p>foo</p> +</li> +<li> +<p>bar</p> +</li> +<li> +<p>baz</p> +</li> +</ul> +</code></pre> +<pre><code class="language-example">- foo + - bar + - baz + + + bim +. +<ul> +<li>foo +<ul> +<li>bar +<ul> +<li> +<p>baz</p> +<p>bim</p> +</li> +</ul> +</li> +</ul> +</li> +</ul> +</code></pre> +<p>To separate consecutive lists of the same type, or to separate a +list from an indented code block that would otherwise be parsed +as a subparagraph of the final list item, you can insert a blank HTML +comment:</p> +<pre><code class="language-example">- foo +- bar + +<!-- --> + +- baz +- bim +. +<ul> +<li>foo</li> +<li>bar</li> +</ul> +<!-- --> +<ul> +<li>baz</li> +<li>bim</li> +</ul> +</code></pre> +<pre><code class="language-example">- foo + + notcode + +- foo + +<!-- --> + + code +. +<ul> +<li> +<p>foo</p> +<p>notcode</p> +</li> +<li> +<p>foo</p> +</li> +</ul> +<!-- --> +<pre><code>code +</code></pre> +</code></pre> +<p>List items need not be indented to the same level. The following +list items will be treated as items at the same list level, +since none is indented enough to belong to the previous list +item:</p> +<pre><code class="language-example">- a + - b + - c + - d + - e + - f +- g +. +<ul> +<li>a</li> +<li>b</li> +<li>c</li> +<li>d</li> +<li>e</li> +<li>f</li> +<li>g</li> +</ul> +</code></pre> +<pre><code class="language-example">1. a + + 2. b + + 3. c +. +<ol> +<li> +<p>a</p> +</li> +<li> +<p>b</p> +</li> +<li> +<p>c</p> +</li> +</ol> +</code></pre> +<p>Note, however, that list items may not be preceded by more than +three spaces of indentation. Here <code>- e</code> is treated as a paragraph continuation +line, because it is indented more than three spaces:</p> +<pre><code class="language-example">- a + - b + - c + - d + - e +. +<ul> +<li>a</li> +<li>b</li> +<li>c</li> +<li>d +- e</li> +</ul> +</code></pre> +<p>And here, <code>3. c</code> is treated as in indented code block, +because it is indented four spaces and preceded by a +blank line.</p> +<pre><code class="language-example">1. a + + 2. b + + 3. c +. +<ol> +<li> +<p>a</p> +</li> +<li> +<p>b</p> +</li> +</ol> +<pre><code>3. c +</code></pre> +</code></pre> +<p>This is a loose list, because there is a blank line between +two of the list items:</p> +<pre><code class="language-example">- a +- b + +- c +. +<ul> +<li> +<p>a</p> +</li> +<li> +<p>b</p> +</li> +<li> +<p>c</p> +</li> +</ul> +</code></pre> +<p>So is this, with a empty second item:</p> +<pre><code class="language-example">* a +* + +* c +. +<ul> +<li> +<p>a</p> +</li> +<li></li> +<li> +<p>c</p> +</li> +</ul> +</code></pre> +<p>These are loose lists, even though there are no blank lines between the items, +because one of the items directly contains two block-level elements +with a blank line between them:</p> +<pre><code class="language-example">- a +- b + + c +- d +. +<ul> +<li> +<p>a</p> +</li> +<li> +<p>b</p> +<p>c</p> +</li> +<li> +<p>d</p> +</li> +</ul> +</code></pre> +<pre><code class="language-example">- a +- b + + [ref]: /url +- d +. +<ul> +<li> +<p>a</p> +</li> +<li> +<p>b</p> +</li> +<li> +<p>d</p> +</li> +</ul> +</code></pre> +<p>This is a tight list, because the blank lines are in a code block:</p> +<pre><code class="language-example">- a +- ``` + b + + + ``` +- c +. +<ul> +<li>a</li> +<li> +<pre><code>b + + +</code></pre> +</li> +<li>c</li> +</ul> +</code></pre> +<p>This is a tight list, because the blank line is between two +paragraphs of a sublist. So the sublist is loose while +the outer list is tight:</p> +<pre><code class="language-example">- a + - b + + c +- d +. +<ul> +<li>a +<ul> +<li> +<p>b</p> +<p>c</p> +</li> +</ul> +</li> +<li>d</li> +</ul> +</code></pre> +<p>This is a tight list, because the blank line is inside the +block quote:</p> +<pre><code class="language-example">* a + > b + > +* c +. +<ul> +<li>a +<blockquote> +<p>b</p> +</blockquote> +</li> +<li>c</li> +</ul> +</code></pre> +<p>This list is tight, because the consecutive block elements +are not separated by blank lines:</p> +<pre><code class="language-example">- a + > b + ``` + c + ``` +- d +. +<ul> +<li>a +<blockquote> +<p>b</p> +</blockquote> +<pre><code>c +</code></pre> +</li> +<li>d</li> +</ul> +</code></pre> +<p>A single-paragraph list is tight:</p> +<pre><code class="language-example">- a +. +<ul> +<li>a</li> +</ul> +</code></pre> +<pre><code class="language-example">- a + - b +. +<ul> +<li>a +<ul> +<li>b</li> +</ul> +</li> +</ul> +</code></pre> +<p>This list is loose, because of the blank line between the +two block elements in the list item:</p> +<pre><code class="language-example">1. ``` + foo + ``` + + bar +. +<ol> +<li> +<pre><code>foo +</code></pre> +<p>bar</p> +</li> +</ol> +</code></pre> +<p>Here the outer list is loose, the inner list tight:</p> +<pre><code class="language-example">* foo + * bar + + baz +. +<ul> +<li> +<p>foo</p> +<ul> +<li>bar</li> +</ul> +<p>baz</p> +</li> +</ul> +</code></pre> +<pre><code class="language-example">- a + - b + - c + +- d + - e + - f +. +<ul> +<li> +<p>a</p> +<ul> +<li>b</li> +<li>c</li> +</ul> +</li> +<li> +<p>d</p> +<ul> +<li>e</li> +<li>f</li> +</ul> +</li> +</ul> +</code></pre> +<h1>Inlines</h1> +<p>Inlines are parsed sequentially from the beginning of the character +stream to the end (left to right, in left-to-right languages). +Thus, for example, in</p> +<pre><code class="language-example">`hi`lo` +. +<p><code>hi</code>lo`</p> +</code></pre> +<p><code>hi</code> is parsed as code, leaving the backtick at the end as a literal +backtick.</p> +<h2>Code spans</h2> +<p>A <a href="@">backtick string</a> +is a string of one or more backtick characters (<code>`</code>) that is neither +preceded nor followed by a backtick.</p> +<p>A <a href="@">code span</a> begins with a backtick string and ends with +a backtick string of equal length. The contents of the code span are +the characters between these two backtick strings, normalized in the +following ways:</p> +<ul> +<li>First, [line endings] are converted to [spaces].</li> +<li>If the resulting string both begins <em>and</em> ends with a [space] +character, but does not consist entirely of [space] +characters, a single [space] character is removed from the +front and back. This allows you to include code that begins +or ends with backtick characters, which must be separated by +whitespace from the opening or closing backtick strings.</li> +</ul> +<p>This is a simple code span:</p> +<pre><code class="language-example">`foo` +. +<p><code>foo</code></p> +</code></pre> +<p>Here two backticks are used, because the code contains a backtick. +This example also illustrates stripping of a single leading and +trailing space:</p> +<pre><code class="language-example">`` foo ` bar `` +. +<p><code>foo ` bar</code></p> +</code></pre> +<p>This example shows the motivation for stripping leading and trailing +spaces:</p> +<pre><code class="language-example">` `` ` +. +<p><code>``</code></p> +</code></pre> +<p>Note that only <em>one</em> space is stripped:</p> +<pre><code class="language-example">` `` ` +. +<p><code> `` </code></p> +</code></pre> +<p>The stripping only happens if the space is on both +sides of the string:</p> +<pre><code class="language-example">` a` +. +<p><code> a</code></p> +</code></pre> +<p>Only [spaces], and not [unicode whitespace] in general, are +stripped in this way:</p> +<pre><code class="language-example">` b ` +. +<p><code> b </code></p> +</code></pre> +<p>No stripping occurs if the code span contains only spaces:</p> +<pre><code class="language-example">` ` +` ` +. +<p><code> </code> +<code> </code></p> +</code></pre> +<p>[Line endings] are treated like spaces:</p> +<pre><code class="language-example">`` +foo +bar +baz +`` +. +<p><code>foo bar baz</code></p> +</code></pre> +<pre><code class="language-example">`` +foo +`` +. +<p><code>foo </code></p> +</code></pre> +<p>Interior spaces are not collapsed:</p> +<pre><code class="language-example">`foo bar +baz` +. +<p><code>foo bar baz</code></p> +</code></pre> +<p>Note that browsers will typically collapse consecutive spaces +when rendering <code><code></code> elements, so it is recommended that +the following CSS be used:</p> +<pre><code>code{white-space: pre-wrap;} +</code></pre> +<p>Note that backslash escapes do not work in code spans. All backslashes +are treated literally:</p> +<pre><code class="language-example">`foo\`bar` +. +<p><code>foo\</code>bar`</p> +</code></pre> +<p>Backslash escapes are never needed, because one can always choose a +string of <em>n</em> backtick characters as delimiters, where the code does +not contain any strings of exactly <em>n</em> backtick characters.</p> +<pre><code class="language-example">``foo`bar`` +. +<p><code>foo`bar</code></p> +</code></pre> +<pre><code class="language-example">` foo `` bar ` +. +<p><code>foo `` bar</code></p> +</code></pre> +<p>Code span backticks have higher precedence than any other inline +constructs except HTML tags and autolinks. Thus, for example, this is +not parsed as emphasized text, since the second <code>*</code> is part of a code +span:</p> +<pre><code class="language-example">*foo`*` +. +<p>*foo<code>*</code></p> +</code></pre> +<p>And this is not parsed as a link:</p> +<pre><code class="language-example">[not a `link](/foo`) +. +<p>[not a <code>link](/foo</code>)</p> +</code></pre> +<p>Code spans, HTML tags, and autolinks have the same precedence. +Thus, this is code:</p> +<pre><code class="language-example">`<a href="`">` +. +<p><code>&lt;a href=&quot;</code>&quot;&gt;`</p> +</code></pre> +<p>But this is an HTML tag:</p> +<pre><code class="language-example"><a href="`">` +. +<p><a href="`">`</p> +</code></pre> +<p>And this is code:</p> +<pre><code class="language-example">`<http://foo.bar.`baz>` +. +<p><code>&lt;http://foo.bar.</code>baz&gt;`</p> +</code></pre> +<p>But this is an autolink:</p> +<pre><code class="language-example"><http://foo.bar.`baz>` +. +<p><a href="http://foo.bar.%60baz">http://foo.bar.`baz</a>`</p> +</code></pre> +<p>When a backtick string is not closed by a matching backtick string, +we just have literal backticks:</p> +<pre><code class="language-example">```foo`` +. +<p>```foo``</p> +</code></pre> +<pre><code class="language-example">`foo +. +<p>`foo</p> +</code></pre> +<p>The following case also illustrates the need for opening and +closing backtick strings to be equal in length:</p> +<pre><code class="language-example">`foo``bar`` +. +<p>`foo<code>bar</code></p> +</code></pre> +<h2>Emphasis and strong emphasis</h2> +<p>John Gruber's original <a href="http://daringfireball.net/projects/markdown/syntax#em">Markdown syntax +description</a> says:</p> +<blockquote> +<p>Markdown treats asterisks (<code>*</code>) and underscores (<code>_</code>) as indicators of +emphasis. Text wrapped with one <code>*</code> or <code>_</code> will be wrapped with an HTML +<code><em></code> tag; double <code>*</code>'s or <code>_</code>'s will be wrapped with an HTML <code><strong></code> +tag.</p> +</blockquote> +<p>This is enough for most users, but these rules leave much undecided, +especially when it comes to nested emphasis. The original +<code>Markdown.pl</code> test suite makes it clear that triple <code>***</code> and +<code>___</code> delimiters can be used for strong emphasis, and most +implementations have also allowed the following patterns:</p> +<pre><code class="language-markdown">***strong emph*** +***strong** in emph* +***emph* in strong** +**in strong *emph*** +*in emph **strong*** +</code></pre> +<p>The following patterns are less widely supported, but the intent +is clear and they are useful (especially in contexts like bibliography +entries):</p> +<pre><code class="language-markdown">*emph *with emph* in it* +**strong **with strong** in it** +</code></pre> +<p>Many implementations have also restricted intraword emphasis to +the <code>*</code> forms, to avoid unwanted emphasis in words containing +internal underscores. (It is best practice to put these in code +spans, but users often do not.)</p> +<pre><code class="language-markdown">internal emphasis: foo*bar*baz +no emphasis: foo_bar_baz +</code></pre> +<p>The rules given below capture all of these patterns, while allowing +for efficient parsing strategies that do not backtrack.</p> +<p>First, some definitions. A <a href="@">delimiter run</a> is either +a sequence of one or more <code>*</code> characters that is not preceded or +followed by a non-backslash-escaped <code>*</code> character, or a sequence +of one or more <code>_</code> characters that is not preceded or followed by +a non-backslash-escaped <code>_</code> character.</p> +<p>A <a href="@">left-flanking delimiter run</a> is +a [delimiter run] that is (1) not followed by [Unicode whitespace], +and either (2a) not followed by a [Unicode punctuation character], or +(2b) followed by a [Unicode punctuation character] and +preceded by [Unicode whitespace] or a [Unicode punctuation character]. +For purposes of this definition, the beginning and the end of +the line count as Unicode whitespace.</p> +<p>A <a href="@">right-flanking delimiter run</a> is +a [delimiter run] that is (1) not preceded by [Unicode whitespace], +and either (2a) not preceded by a [Unicode punctuation character], or +(2b) preceded by a [Unicode punctuation character] and +followed by [Unicode whitespace] or a [Unicode punctuation character]. +For purposes of this definition, the beginning and the end of +the line count as Unicode whitespace.</p> +<p>Here are some examples of delimiter runs.</p> +<ul> +<li> +<p>left-flanking but not right-flanking:</p> +<pre><code>***abc + _abc +**"abc" + _"abc" +</code></pre> +</li> +<li> +<p>right-flanking but not left-flanking:</p> +<pre><code> abc*** + abc_ +"abc"** +"abc"_ +</code></pre> +</li> +<li> +<p>Both left and right-flanking:</p> +<pre><code> abc***def +"abc"_"def" +</code></pre> +</li> +<li> +<p>Neither left nor right-flanking:</p> +<pre><code>abc *** def +a _ b +</code></pre> +</li> +</ul> +<p>(The idea of distinguishing left-flanking and right-flanking +delimiter runs based on the character before and the character +after comes from Roopesh Chander's +<a href="http://www.vfmd.org/vfmd-spec/specification/#procedure-for-identifying-emphasis-tags">vfmd</a>. +vfmd uses the terminology "emphasis indicator string" instead of "delimiter +run," and its rules for distinguishing left- and right-flanking runs +are a bit more complex than the ones given here.)</p> +<p>The following rules define emphasis and strong emphasis:</p> +<ol> +<li> +<p>A single <code>*</code> character <a href="@">can open emphasis</a> +iff (if and only if) it is part of a [left-flanking delimiter run].</p> +</li> +<li> +<p>A single <code>_</code> character [can open emphasis] iff +it is part of a [left-flanking delimiter run] +and either (a) not part of a [right-flanking delimiter run] +or (b) part of a [right-flanking delimiter run] +preceded by a [Unicode punctuation character].</p> +</li> +<li> +<p>A single <code>*</code> character <a href="@">can close emphasis</a> +iff it is part of a [right-flanking delimiter run].</p> +</li> +<li> +<p>A single <code>_</code> character [can close emphasis] iff +it is part of a [right-flanking delimiter run] +and either (a) not part of a [left-flanking delimiter run] +or (b) part of a [left-flanking delimiter run] +followed by a [Unicode punctuation character].</p> +</li> +<li> +<p>A double <code>**</code> <a href="@">can open strong emphasis</a> +iff it is part of a [left-flanking delimiter run].</p> +</li> +<li> +<p>A double <code>__</code> [can open strong emphasis] iff +it is part of a [left-flanking delimiter run] +and either (a) not part of a [right-flanking delimiter run] +or (b) part of a [right-flanking delimiter run] +preceded by a [Unicode punctuation character].</p> +</li> +<li> +<p>A double <code>**</code> <a href="@">can close strong emphasis</a> +iff it is part of a [right-flanking delimiter run].</p> +</li> +<li> +<p>A double <code>__</code> [can close strong emphasis] iff +it is part of a [right-flanking delimiter run] +and either (a) not part of a [left-flanking delimiter run] +or (b) part of a [left-flanking delimiter run] +followed by a [Unicode punctuation character].</p> +</li> +<li> +<p>Emphasis begins with a delimiter that [can open emphasis] and ends +with a delimiter that [can close emphasis], and that uses the same +character (<code>_</code> or <code>*</code>) as the opening delimiter. The +opening and closing delimiters must belong to separate +[delimiter runs]. If one of the delimiters can both +open and close emphasis, then the sum of the lengths of the +delimiter runs containing the opening and closing delimiters +must not be a multiple of 3 unless both lengths are +multiples of 3.</p> +</li> +<li> +<p>Strong emphasis begins with a delimiter that +[can open strong emphasis] and ends with a delimiter that +[can close strong emphasis], and that uses the same character +(<code>_</code> or <code>*</code>) as the opening delimiter. The +opening and closing delimiters must belong to separate +[delimiter runs]. If one of the delimiters can both open +and close strong emphasis, then the sum of the lengths of +the delimiter runs containing the opening and closing +delimiters must not be a multiple of 3 unless both lengths +are multiples of 3.</p> +</li> +<li> +<p>A literal <code>*</code> character cannot occur at the beginning or end of +<code>*</code>-delimited emphasis or <code>**</code>-delimited strong emphasis, unless it +is backslash-escaped.</p> +</li> +<li> +<p>A literal <code>_</code> character cannot occur at the beginning or end of +<code>_</code>-delimited emphasis or <code>__</code>-delimited strong emphasis, unless it +is backslash-escaped.</p> +</li> +</ol> +<p>Where rules 1--12 above are compatible with multiple parsings, +the following principles resolve ambiguity:</p> +<ol start="13"> +<li> +<p>The number of nestings should be minimized. Thus, for example, +an interpretation <code><strong>...</strong></code> is always preferred to +<code><em><em>...</em></em></code>.</p> +</li> +<li> +<p>An interpretation <code><em><strong>...</strong></em></code> is always +preferred to <code><strong><em>...</em></strong></code>.</p> +</li> +<li> +<p>When two potential emphasis or strong emphasis spans overlap, +so that the second begins before the first ends and ends after +the first ends, the first takes precedence. Thus, for example, +<code>*foo _bar* baz_</code> is parsed as <code><em>foo _bar</em> baz_</code> rather +than <code>*foo <em>bar* baz</em></code>.</p> +</li> +<li> +<p>When there are two potential emphasis or strong emphasis spans +with the same closing delimiter, the shorter one (the one that +opens later) takes precedence. Thus, for example, +<code>**foo **bar baz**</code> is parsed as <code>**foo <strong>bar baz</strong></code> +rather than <code><strong>foo **bar baz</strong></code>.</p> +</li> +<li> +<p>Inline code spans, links, images, and HTML tags group more tightly +than emphasis. So, when there is a choice between an interpretation +that contains one of these elements and one that does not, the +former always wins. Thus, for example, <code>*[foo*](bar)</code> is +parsed as <code>*<a href="bar">foo*</a></code> rather than as +<code><em>[foo</em>](bar)</code>.</p> +</li> +</ol> +<p>These rules can be illustrated through a series of examples.</p> +<p>Rule 1:</p> +<pre><code class="language-example">*foo bar* +. +<p><em>foo bar</em></p> +</code></pre> +<p>This is not emphasis, because the opening <code>*</code> is followed by +whitespace, and hence not part of a [left-flanking delimiter run]:</p> +<pre><code class="language-example">a * foo bar* +. +<p>a * foo bar*</p> +</code></pre> +<p>This is not emphasis, because the opening <code>*</code> is preceded +by an alphanumeric and followed by punctuation, and hence +not part of a [left-flanking delimiter run]:</p> +<pre><code class="language-example">a*"foo"* +. +<p>a*&quot;foo&quot;*</p> +</code></pre> +<p>Unicode nonbreaking spaces count as whitespace, too:</p> +<pre><code class="language-example">* a * +. +<p>* a *</p> +</code></pre> +<p>Intraword emphasis with <code>*</code> is permitted:</p> +<pre><code class="language-example">foo*bar* +. +<p>foo<em>bar</em></p> +</code></pre> +<pre><code class="language-example">5*6*78 +. +<p>5<em>6</em>78</p> +</code></pre> +<p>Rule 2:</p> +<pre><code class="language-example">_foo bar_ +. +<p><em>foo bar</em></p> +</code></pre> +<p>This is not emphasis, because the opening <code>_</code> is followed by +whitespace:</p> +<pre><code class="language-example">_ foo bar_ +. +<p>_ foo bar_</p> +</code></pre> +<p>This is not emphasis, because the opening <code>_</code> is preceded +by an alphanumeric and followed by punctuation:</p> +<pre><code class="language-example">a_"foo"_ +. +<p>a_&quot;foo&quot;_</p> +</code></pre> +<p>Emphasis with <code>_</code> is not allowed inside words:</p> +<pre><code class="language-example">foo_bar_ +. +<p>foo_bar_</p> +</code></pre> +<pre><code class="language-example">5_6_78 +. +<p>5_6_78</p> +</code></pre> +<pre><code class="language-example">пристаням_стремятся_ +. +<p>пристаням_стремятся_</p> +</code></pre> +<p>Here <code>_</code> does not generate emphasis, because the first delimiter run +is right-flanking and the second left-flanking:</p> +<pre><code class="language-example">aa_"bb"_cc +. +<p>aa_&quot;bb&quot;_cc</p> +</code></pre> +<p>This is emphasis, even though the opening delimiter is +both left- and right-flanking, because it is preceded by +punctuation:</p> +<pre><code class="language-example">foo-_(bar)_ +. +<p>foo-<em>(bar)</em></p> +</code></pre> +<p>Rule 3:</p> +<p>This is not emphasis, because the closing delimiter does +not match the opening delimiter:</p> +<pre><code class="language-example">_foo* +. +<p>_foo*</p> +</code></pre> +<p>This is not emphasis, because the closing <code>*</code> is preceded by +whitespace:</p> +<pre><code class="language-example">*foo bar * +. +<p>*foo bar *</p> +</code></pre> +<p>A line ending also counts as whitespace:</p> +<pre><code class="language-example">*foo bar +* +. +<p>*foo bar +*</p> +</code></pre> +<p>This is not emphasis, because the second <code>*</code> is +preceded by punctuation and followed by an alphanumeric +(hence it is not part of a [right-flanking delimiter run]:</p> +<pre><code class="language-example">*(*foo) +. +<p>*(*foo)</p> +</code></pre> +<p>The point of this restriction is more easily appreciated +with this example:</p> +<pre><code class="language-example">*(*foo*)* +. +<p><em>(<em>foo</em>)</em></p> +</code></pre> +<p>Intraword emphasis with <code>*</code> is allowed:</p> +<pre><code class="language-example">*foo*bar +. +<p><em>foo</em>bar</p> +</code></pre> +<p>Rule 4:</p> +<p>This is not emphasis, because the closing <code>_</code> is preceded by +whitespace:</p> +<pre><code class="language-example">_foo bar _ +. +<p>_foo bar _</p> +</code></pre> +<p>This is not emphasis, because the second <code>_</code> is +preceded by punctuation and followed by an alphanumeric:</p> +<pre><code class="language-example">_(_foo) +. +<p>_(_foo)</p> +</code></pre> +<p>This is emphasis within emphasis:</p> +<pre><code class="language-example">_(_foo_)_ +. +<p><em>(<em>foo</em>)</em></p> +</code></pre> +<p>Intraword emphasis is disallowed for <code>_</code>:</p> +<pre><code class="language-example">_foo_bar +. +<p>_foo_bar</p> +</code></pre> +<pre><code class="language-example">_пристаням_стремятся +. +<p>_пристаням_стремятся</p> +</code></pre> +<pre><code class="language-example">_foo_bar_baz_ +. +<p><em>foo_bar_baz</em></p> +</code></pre> +<p>This is emphasis, even though the closing delimiter is +both left- and right-flanking, because it is followed by +punctuation:</p> +<pre><code class="language-example">_(bar)_. +. +<p><em>(bar)</em>.</p> +</code></pre> +<p>Rule 5:</p> +<pre><code class="language-example">**foo bar** +. +<p><strong>foo bar</strong></p> +</code></pre> +<p>This is not strong emphasis, because the opening delimiter is +followed by whitespace:</p> +<pre><code class="language-example">** foo bar** +. +<p>** foo bar**</p> +</code></pre> +<p>This is not strong emphasis, because the opening <code>**</code> is preceded +by an alphanumeric and followed by punctuation, and hence +not part of a [left-flanking delimiter run]:</p> +<pre><code class="language-example">a**"foo"** +. +<p>a**&quot;foo&quot;**</p> +</code></pre> +<p>Intraword strong emphasis with <code>**</code> is permitted:</p> +<pre><code class="language-example">foo**bar** +. +<p>foo<strong>bar</strong></p> +</code></pre> +<p>Rule 6:</p> +<pre><code class="language-example">__foo bar__ +. +<p><strong>foo bar</strong></p> +</code></pre> +<p>This is not strong emphasis, because the opening delimiter is +followed by whitespace:</p> +<pre><code class="language-example">__ foo bar__ +. +<p>__ foo bar__</p> +</code></pre> +<p>A line ending counts as whitespace:</p> +<pre><code class="language-example">__ +foo bar__ +. +<p>__ +foo bar__</p> +</code></pre> +<p>This is not strong emphasis, because the opening <code>__</code> is preceded +by an alphanumeric and followed by punctuation:</p> +<pre><code class="language-example">a__"foo"__ +. +<p>a__&quot;foo&quot;__</p> +</code></pre> +<p>Intraword strong emphasis is forbidden with <code>__</code>:</p> +<pre><code class="language-example">foo__bar__ +. +<p>foo__bar__</p> +</code></pre> +<pre><code class="language-example">5__6__78 +. +<p>5__6__78</p> +</code></pre> +<pre><code class="language-example">пристаням__стремятся__ +. +<p>пристаням__стремятся__</p> +</code></pre> +<pre><code class="language-example">__foo, __bar__, baz__ +. +<p><strong>foo, <strong>bar</strong>, baz</strong></p> +</code></pre> +<p>This is strong emphasis, even though the opening delimiter is +both left- and right-flanking, because it is preceded by +punctuation:</p> +<pre><code class="language-example">foo-__(bar)__ +. +<p>foo-<strong>(bar)</strong></p> +</code></pre> +<p>Rule 7:</p> +<p>This is not strong emphasis, because the closing delimiter is preceded +by whitespace:</p> +<pre><code class="language-example">**foo bar ** +. +<p>**foo bar **</p> +</code></pre> +<p>(Nor can it be interpreted as an emphasized <code>*foo bar *</code>, because of +Rule 11.)</p> +<p>This is not strong emphasis, because the second <code>**</code> is +preceded by punctuation and followed by an alphanumeric:</p> +<pre><code class="language-example">**(**foo) +. +<p>**(**foo)</p> +</code></pre> +<p>The point of this restriction is more easily appreciated +with these examples:</p> +<pre><code class="language-example">*(**foo**)* +. +<p><em>(<strong>foo</strong>)</em></p> +</code></pre> +<pre><code class="language-example">**Gomphocarpus (*Gomphocarpus physocarpus*, syn. +*Asclepias physocarpa*)** +. +<p><strong>Gomphocarpus (<em>Gomphocarpus physocarpus</em>, syn. +<em>Asclepias physocarpa</em>)</strong></p> +</code></pre> +<pre><code class="language-example">**foo "*bar*" foo** +. +<p><strong>foo &quot;<em>bar</em>&quot; foo</strong></p> +</code></pre> +<p>Intraword emphasis:</p> +<pre><code class="language-example">**foo**bar +. +<p><strong>foo</strong>bar</p> +</code></pre> +<p>Rule 8:</p> +<p>This is not strong emphasis, because the closing delimiter is +preceded by whitespace:</p> +<pre><code class="language-example">__foo bar __ +. +<p>__foo bar __</p> +</code></pre> +<p>This is not strong emphasis, because the second <code>__</code> is +preceded by punctuation and followed by an alphanumeric:</p> +<pre><code class="language-example">__(__foo) +. +<p>__(__foo)</p> +</code></pre> +<p>The point of this restriction is more easily appreciated +with this example:</p> +<pre><code class="language-example">_(__foo__)_ +. +<p><em>(<strong>foo</strong>)</em></p> +</code></pre> +<p>Intraword strong emphasis is forbidden with <code>__</code>:</p> +<pre><code class="language-example">__foo__bar +. +<p>__foo__bar</p> +</code></pre> +<pre><code class="language-example">__пристаням__стремятся +. +<p>__пристаням__стремятся</p> +</code></pre> +<pre><code class="language-example">__foo__bar__baz__ +. +<p><strong>foo__bar__baz</strong></p> +</code></pre> +<p>This is strong emphasis, even though the closing delimiter is +both left- and right-flanking, because it is followed by +punctuation:</p> +<pre><code class="language-example">__(bar)__. +. +<p><strong>(bar)</strong>.</p> +</code></pre> +<p>Rule 9:</p> +<p>Any nonempty sequence of inline elements can be the contents of an +emphasized span.</p> +<pre><code class="language-example">*foo [bar](/url)* +. +<p><em>foo <a href="/url">bar</a></em></p> +</code></pre> +<pre><code class="language-example">*foo +bar* +. +<p><em>foo +bar</em></p> +</code></pre> +<p>In particular, emphasis and strong emphasis can be nested +inside emphasis:</p> +<pre><code class="language-example">_foo __bar__ baz_ +. +<p><em>foo <strong>bar</strong> baz</em></p> +</code></pre> +<pre><code class="language-example">_foo _bar_ baz_ +. +<p><em>foo <em>bar</em> baz</em></p> +</code></pre> +<pre><code class="language-example">__foo_ bar_ +. +<p><em><em>foo</em> bar</em></p> +</code></pre> +<pre><code class="language-example">*foo *bar** +. +<p><em>foo <em>bar</em></em></p> +</code></pre> +<pre><code class="language-example">*foo **bar** baz* +. +<p><em>foo <strong>bar</strong> baz</em></p> +</code></pre> +<pre><code class="language-example">*foo**bar**baz* +. +<p><em>foo<strong>bar</strong>baz</em></p> +</code></pre> +<p>Note that in the preceding case, the interpretation</p> +<pre><code class="language-markdown"><p><em>foo</em><em>bar<em></em>baz</em></p> +</code></pre> +<p>is precluded by the condition that a delimiter that +can both open and close (like the <code>*</code> after <code>foo</code>) +cannot form emphasis if the sum of the lengths of +the delimiter runs containing the opening and +closing delimiters is a multiple of 3 unless +both lengths are multiples of 3.</p> +<p>For the same reason, we don't get two consecutive +emphasis sections in this example:</p> +<pre><code class="language-example">*foo**bar* +. +<p><em>foo**bar</em></p> +</code></pre> +<p>The same condition ensures that the following +cases are all strong emphasis nested inside +emphasis, even when the interior whitespace is +omitted:</p> +<pre><code class="language-example">***foo** bar* +. +<p><em><strong>foo</strong> bar</em></p> +</code></pre> +<pre><code class="language-example">*foo **bar*** +. +<p><em>foo <strong>bar</strong></em></p> +</code></pre> +<pre><code class="language-example">*foo**bar*** +. +<p><em>foo<strong>bar</strong></em></p> +</code></pre> +<p>When the lengths of the interior closing and opening +delimiter runs are <em>both</em> multiples of 3, though, +they can match to create emphasis:</p> +<pre><code class="language-example">foo***bar***baz +. +<p>foo<em><strong>bar</strong></em>baz</p> +</code></pre> +<pre><code class="language-example">foo******bar*********baz +. +<p>foo<strong><strong><strong>bar</strong></strong></strong>***baz</p> +</code></pre> +<p>Indefinite levels of nesting are possible:</p> +<pre><code class="language-example">*foo **bar *baz* bim** bop* +. +<p><em>foo <strong>bar <em>baz</em> bim</strong> bop</em></p> +</code></pre> +<pre><code class="language-example">*foo [*bar*](/url)* +. +<p><em>foo <a href="/url"><em>bar</em></a></em></p> +</code></pre> +<p>There can be no empty emphasis or strong emphasis:</p> +<pre><code class="language-example">** is not an empty emphasis +. +<p>** is not an empty emphasis</p> +</code></pre> +<pre><code class="language-example">**** is not an empty strong emphasis +. +<p>**** is not an empty strong emphasis</p> +</code></pre> +<p>Rule 10:</p> +<p>Any nonempty sequence of inline elements can be the contents of an +strongly emphasized span.</p> +<pre><code class="language-example">**foo [bar](/url)** +. +<p><strong>foo <a href="/url">bar</a></strong></p> +</code></pre> +<pre><code class="language-example">**foo +bar** +. +<p><strong>foo +bar</strong></p> +</code></pre> +<p>In particular, emphasis and strong emphasis can be nested +inside strong emphasis:</p> +<pre><code class="language-example">__foo _bar_ baz__ +. +<p><strong>foo <em>bar</em> baz</strong></p> +</code></pre> +<pre><code class="language-example">__foo __bar__ baz__ +. +<p><strong>foo <strong>bar</strong> baz</strong></p> +</code></pre> +<pre><code class="language-example">____foo__ bar__ +. +<p><strong><strong>foo</strong> bar</strong></p> +</code></pre> +<pre><code class="language-example">**foo **bar**** +. +<p><strong>foo <strong>bar</strong></strong></p> +</code></pre> +<pre><code class="language-example">**foo *bar* baz** +. +<p><strong>foo <em>bar</em> baz</strong></p> +</code></pre> +<pre><code class="language-example">**foo*bar*baz** +. +<p><strong>foo<em>bar</em>baz</strong></p> +</code></pre> +<pre><code class="language-example">***foo* bar** +. +<p><strong><em>foo</em> bar</strong></p> +</code></pre> +<pre><code class="language-example">**foo *bar*** +. +<p><strong>foo <em>bar</em></strong></p> +</code></pre> +<p>Indefinite levels of nesting are possible:</p> +<pre><code class="language-example">**foo *bar **baz** +bim* bop** +. +<p><strong>foo <em>bar <strong>baz</strong> +bim</em> bop</strong></p> +</code></pre> +<pre><code class="language-example">**foo [*bar*](/url)** +. +<p><strong>foo <a href="/url"><em>bar</em></a></strong></p> +</code></pre> +<p>There can be no empty emphasis or strong emphasis:</p> +<pre><code class="language-example">__ is not an empty emphasis +. +<p>__ is not an empty emphasis</p> +</code></pre> +<pre><code class="language-example">____ is not an empty strong emphasis +. +<p>____ is not an empty strong emphasis</p> +</code></pre> +<p>Rule 11:</p> +<pre><code class="language-example">foo *** +. +<p>foo ***</p> +</code></pre> +<pre><code class="language-example">foo *\** +. +<p>foo <em>*</em></p> +</code></pre> +<pre><code class="language-example">foo *_* +. +<p>foo <em>_</em></p> +</code></pre> +<pre><code class="language-example">foo ***** +. +<p>foo *****</p> +</code></pre> +<pre><code class="language-example">foo **\*** +. +<p>foo <strong>*</strong></p> +</code></pre> +<pre><code class="language-example">foo **_** +. +<p>foo <strong>_</strong></p> +</code></pre> +<p>Note that when delimiters do not match evenly, Rule 11 determines +that the excess literal <code>*</code> characters will appear outside of the +emphasis, rather than inside it:</p> +<pre><code class="language-example">**foo* +. +<p>*<em>foo</em></p> +</code></pre> +<pre><code class="language-example">*foo** +. +<p><em>foo</em>*</p> +</code></pre> +<pre><code class="language-example">***foo** +. +<p>*<strong>foo</strong></p> +</code></pre> +<pre><code class="language-example">****foo* +. +<p>***<em>foo</em></p> +</code></pre> +<pre><code class="language-example">**foo*** +. +<p><strong>foo</strong>*</p> +</code></pre> +<pre><code class="language-example">*foo**** +. +<p><em>foo</em>***</p> +</code></pre> +<p>Rule 12:</p> +<pre><code class="language-example">foo ___ +. +<p>foo ___</p> +</code></pre> +<pre><code class="language-example">foo _\__ +. +<p>foo <em>_</em></p> +</code></pre> +<pre><code class="language-example">foo _*_ +. +<p>foo <em>*</em></p> +</code></pre> +<pre><code class="language-example">foo _____ +. +<p>foo _____</p> +</code></pre> +<pre><code class="language-example">foo __\___ +. +<p>foo <strong>_</strong></p> +</code></pre> +<pre><code class="language-example">foo __*__ +. +<p>foo <strong>*</strong></p> +</code></pre> +<pre><code class="language-example">__foo_ +. +<p>_<em>foo</em></p> +</code></pre> +<p>Note that when delimiters do not match evenly, Rule 12 determines +that the excess literal <code>_</code> characters will appear outside of the +emphasis, rather than inside it:</p> +<pre><code class="language-example">_foo__ +. +<p><em>foo</em>_</p> +</code></pre> +<pre><code class="language-example">___foo__ +. +<p>_<strong>foo</strong></p> +</code></pre> +<pre><code class="language-example">____foo_ +. +<p>___<em>foo</em></p> +</code></pre> +<pre><code class="language-example">__foo___ +. +<p><strong>foo</strong>_</p> +</code></pre> +<pre><code class="language-example">_foo____ +. +<p><em>foo</em>___</p> +</code></pre> +<p>Rule 13 implies that if you want emphasis nested directly inside +emphasis, you must use different delimiters:</p> +<pre><code class="language-example">**foo** +. +<p><strong>foo</strong></p> +</code></pre> +<pre><code class="language-example">*_foo_* +. +<p><em><em>foo</em></em></p> +</code></pre> +<pre><code class="language-example">__foo__ +. +<p><strong>foo</strong></p> +</code></pre> +<pre><code class="language-example">_*foo*_ +. +<p><em><em>foo</em></em></p> +</code></pre> +<p>However, strong emphasis within strong emphasis is possible without +switching delimiters:</p> +<pre><code class="language-example">****foo**** +. +<p><strong><strong>foo</strong></strong></p> +</code></pre> +<pre><code class="language-example">____foo____ +. +<p><strong><strong>foo</strong></strong></p> +</code></pre> +<p>Rule 13 can be applied to arbitrarily long sequences of +delimiters:</p> +<pre><code class="language-example">******foo****** +. +<p><strong><strong><strong>foo</strong></strong></strong></p> +</code></pre> +<p>Rule 14:</p> +<pre><code class="language-example">***foo*** +. +<p><em><strong>foo</strong></em></p> +</code></pre> +<pre><code class="language-example">_____foo_____ +. +<p><em><strong><strong>foo</strong></strong></em></p> +</code></pre> +<p>Rule 15:</p> +<pre><code class="language-example">*foo _bar* baz_ +. +<p><em>foo _bar</em> baz_</p> +</code></pre> +<pre><code class="language-example">*foo __bar *baz bim__ bam* +. +<p><em>foo <strong>bar *baz bim</strong> bam</em></p> +</code></pre> +<p>Rule 16:</p> +<pre><code class="language-example">**foo **bar baz** +. +<p>**foo <strong>bar baz</strong></p> +</code></pre> +<pre><code class="language-example">*foo *bar baz* +. +<p>*foo <em>bar baz</em></p> +</code></pre> +<p>Rule 17:</p> +<pre><code class="language-example">*[bar*](/url) +. +<p>*<a href="/url">bar*</a></p> +</code></pre> +<pre><code class="language-example">_foo [bar_](/url) +. +<p>_foo <a href="/url">bar_</a></p> +</code></pre> +<pre><code class="language-example">*<img src="foo" title="*"/> +. +<p>*<img src="foo" title="*"/></p> +</code></pre> +<pre><code class="language-example">**<a href="**"> +. +<p>**<a href="**"></p> +</code></pre> +<pre><code class="language-example">__<a href="__"> +. +<p>__<a href="__"></p> +</code></pre> +<pre><code class="language-example">*a `*`* +. +<p><em>a <code>*</code></em></p> +</code></pre> +<pre><code class="language-example">_a `_`_ +. +<p><em>a <code>_</code></em></p> +</code></pre> +<pre><code class="language-example">**a<http://foo.bar/?q=**> +. +<p>**a<a href="http://foo.bar/?q=**">http://foo.bar/?q=**</a></p> +</code></pre> +<pre><code class="language-example">__a<http://foo.bar/?q=__> +. +<p>__a<a href="http://foo.bar/?q=__">http://foo.bar/?q=__</a></p> +</code></pre> +<h2>Links</h2> +<p>A link contains [link text] (the visible text), a [link destination] +(the URI that is the link destination), and optionally a [link title]. +There are two basic kinds of links in Markdown. In [inline links] the +destination and title are given immediately after the link text. In +[reference links] the destination and title are defined elsewhere in +the document.</p> +<p>A <a href="@">link text</a> consists of a sequence of zero or more +inline elements enclosed by square brackets (<code>[</code> and <code>]</code>). The +following rules apply:</p> +<ul> +<li> +<p>Links may not contain other links, at any level of nesting. If +multiple otherwise valid link definitions appear nested inside each +other, the inner-most definition is used.</p> +</li> +<li> +<p>Brackets are allowed in the [link text] only if (a) they +are backslash-escaped or (b) they appear as a matched pair of brackets, +with an open bracket <code>[</code>, a sequence of zero or more inlines, and +a close bracket <code>]</code>.</p> +</li> +<li> +<p>Backtick [code spans], [autolinks], and raw [HTML tags] bind more tightly +than the brackets in link text. Thus, for example, +<code>[foo`]`</code> could not be a link text, since the second <code>]</code> +is part of a code span.</p> +</li> +<li> +<p>The brackets in link text bind more tightly than markers for +[emphasis and strong emphasis]. Thus, for example, <code>*[foo*](url)</code> is a link.</p> +</li> +</ul> +<p>A <a href="@">link destination</a> consists of either</p> +<ul> +<li> +<p>a sequence of zero or more characters between an opening <code><</code> and a +closing <code>></code> that contains no line endings or unescaped +<code><</code> or <code>></code> characters, or</p> +</li> +<li> +<p>a nonempty sequence of characters that does not start with <code><</code>, +does not include [ASCII control characters][ASCII control character] +or [space] character, and includes parentheses only if (a) they are +backslash-escaped or (b) they are part of a balanced pair of +unescaped parentheses. +(Implementations may impose limits on parentheses nesting to +avoid performance issues, but at least three levels of nesting +should be supported.)</p> +</li> +</ul> +<p>A <a href="@">link title</a> consists of either</p> +<ul> +<li> +<p>a sequence of zero or more characters between straight double-quote +characters (<code>"</code>), including a <code>"</code> character only if it is +backslash-escaped, or</p> +</li> +<li> +<p>a sequence of zero or more characters between straight single-quote +characters (<code>'</code>), including a <code>'</code> character only if it is +backslash-escaped, or</p> +</li> +<li> +<p>a sequence of zero or more characters between matching parentheses +(<code>(...)</code>), including a <code>(</code> or <code>)</code> character only if it is +backslash-escaped.</p> +</li> +</ul> +<p>Although [link titles] may span multiple lines, they may not contain +a [blank line].</p> +<p>An <a href="@">inline link</a> consists of a [link text] followed immediately +by a left parenthesis <code>(</code>, an optional [link destination], an optional +[link title], and a right parenthesis <code>)</code>. +These four components may be separated by spaces, tabs, and up to one line +ending. +If both [link destination] and [link title] are present, they <em>must</em> be +separated by spaces, tabs, and up to one line ending.</p> +<p>The link's text consists of the inlines contained +in the [link text] (excluding the enclosing square brackets). +The link's URI consists of the link destination, excluding enclosing +<code><...></code> if present, with backslash-escapes in effect as described +above. The link's title consists of the link title, excluding its +enclosing delimiters, with backslash-escapes in effect as described +above.</p> +<p>Here is a simple inline link:</p> +<pre><code class="language-example">[link](/uri "title") +. +<p><a href="/uri" title="title">link</a></p> +</code></pre> +<p>The title, the link text and even +the destination may be omitted:</p> +<pre><code class="language-example">[link](/uri) +. +<p><a href="/uri">link</a></p> +</code></pre> +<pre><code class="language-example">[](./target.md) +. +<p><a href="./target.md"></a></p> +</code></pre> +<pre><code class="language-example">[link]() +. +<p><a href="">link</a></p> +</code></pre> +<pre><code class="language-example">[link](<>) +. +<p><a href="">link</a></p> +</code></pre> +<pre><code class="language-example">[]() +. +<p><a href=""></a></p> +</code></pre> +<p>The destination can only contain spaces if it is +enclosed in pointy brackets:</p> +<pre><code class="language-example">[link](/my uri) +. +<p>[link](/my uri)</p> +</code></pre> +<pre><code class="language-example">[link](</my uri>) +. +<p><a href="/my%20uri">link</a></p> +</code></pre> +<p>The destination cannot contain line endings, +even if enclosed in pointy brackets:</p> +<pre><code class="language-example">[link](foo +bar) +. +<p>[link](foo +bar)</p> +</code></pre> +<pre><code class="language-example">[link](<foo +bar>) +. +<p>[link](<foo +bar>)</p> +</code></pre> +<p>The destination can contain <code>)</code> if it is enclosed +in pointy brackets:</p> +<pre><code class="language-example">[a](<b)c>) +. +<p><a href="b)c">a</a></p> +</code></pre> +<p>Pointy brackets that enclose links must be unescaped:</p> +<pre><code class="language-example">[link](<foo\>) +. +<p>[link](&lt;foo&gt;)</p> +</code></pre> +<p>These are not links, because the opening pointy bracket +is not matched properly:</p> +<pre><code class="language-example">[a](<b)c +[a](<b)c> +[a](<b>c) +. +<p>[a](&lt;b)c +[a](&lt;b)c&gt; +[a](<b>c)</p> +</code></pre> +<p>Parentheses inside the link destination may be escaped:</p> +<pre><code class="language-example">[link](\(foo\)) +. +<p><a href="(foo)">link</a></p> +</code></pre> +<p>Any number of parentheses are allowed without escaping, as long as they are +balanced:</p> +<pre><code class="language-example">[link](foo(and(bar))) +. +<p><a href="foo(and(bar))">link</a></p> +</code></pre> +<p>However, if you have unbalanced parentheses, you need to escape or use the +<code><...></code> form:</p> +<pre><code class="language-example">[link](foo(and(bar)) +. +<p>[link](foo(and(bar))</p> +</code></pre> +<pre><code class="language-example">[link](foo\(and\(bar\)) +. +<p><a href="foo(and(bar)">link</a></p> +</code></pre> +<pre><code class="language-example">[link](<foo(and(bar)>) +. +<p><a href="foo(and(bar)">link</a></p> +</code></pre> +<p>Parentheses and other symbols can also be escaped, as usual +in Markdown:</p> +<pre><code class="language-example">[link](foo\)\:) +. +<p><a href="foo):">link</a></p> +</code></pre> +<p>A link can contain fragment identifiers and queries:</p> +<pre><code class="language-example">[link](#fragment) + +[link](http://example.com#fragment) + +[link](http://example.com?foo=3#frag) +. +<p><a href="#fragment">link</a></p> +<p><a href="http://example.com#fragment">link</a></p> +<p><a href="http://example.com?foo=3#frag">link</a></p> +</code></pre> +<p>Note that a backslash before a non-escapable character is +just a backslash:</p> +<pre><code class="language-example">[link](foo\bar) +. +<p><a href="foo%5Cbar">link</a></p> +</code></pre> +<p>URL-escaping should be left alone inside the destination, as all +URL-escaped characters are also valid URL characters. Entity and +numerical character references in the destination will be parsed +into the corresponding Unicode code points, as usual. These may +be optionally URL-escaped when written as HTML, but this spec +does not enforce any particular policy for rendering URLs in +HTML or other formats. Renderers may make different decisions +about how to escape or normalize URLs in the output.</p> +<pre><code class="language-example">[link](foo%20b&auml;) +. +<p><a href="foo%20b%C3%A4">link</a></p> +</code></pre> +<p>Note that, because titles can often be parsed as destinations, +if you try to omit the destination and keep the title, you'll +get unexpected results:</p> +<pre><code class="language-example">[link]("title") +. +<p><a href="%22title%22">link</a></p> +</code></pre> +<p>Titles may be in single quotes, double quotes, or parentheses:</p> +<pre><code class="language-example">[link](/url "title") +[link](/url 'title') +[link](/url (title)) +. +<p><a href="/url" title="title">link</a> +<a href="/url" title="title">link</a> +<a href="/url" title="title">link</a></p> +</code></pre> +<p>Backslash escapes and entity and numeric character references +may be used in titles:</p> +<pre><code class="language-example">[link](/url "title \"&quot;") +. +<p><a href="/url" title="title &quot;&quot;">link</a></p> +</code></pre> +<p>Titles must be separated from the link using spaces, tabs, and up to one line +ending. +Other [Unicode whitespace] like non-breaking space doesn't work.</p> +<pre><code class="language-example">[link](/url "title") +. +<p><a href="/url%C2%A0%22title%22">link</a></p> +</code></pre> +<p>Nested balanced quotes are not allowed without escaping:</p> +<pre><code class="language-example">[link](/url "title "and" title") +. +<p>[link](/url &quot;title &quot;and&quot; title&quot;)</p> +</code></pre> +<p>But it is easy to work around this by using a different quote type:</p> +<pre><code class="language-example">[link](/url 'title "and" title') +. +<p><a href="/url" title="title &quot;and&quot; title">link</a></p> +</code></pre> +<p>(Note: <code>Markdown.pl</code> did allow double quotes inside a double-quoted +title, and its test suite included a test demonstrating this. +But it is hard to see a good rationale for the extra complexity this +brings, since there are already many ways---backslash escaping, +entity and numeric character references, or using a different +quote type for the enclosing title---to write titles containing +double quotes. <code>Markdown.pl</code>'s handling of titles has a number +of other strange features. For example, it allows single-quoted +titles in inline links, but not reference links. And, in +reference links but not inline links, it allows a title to begin +with <code>"</code> and end with <code>)</code>. <code>Markdown.pl</code> 1.0.1 even allows +titles with no closing quotation mark, though 1.0.2b8 does not. +It seems preferable to adopt a simple, rational rule that works +the same way in inline links and link reference definitions.)</p> +<p>Spaces, tabs, and up to one line ending is allowed around the destination and +title:</p> +<pre><code class="language-example">[link]( /uri + "title" ) +. +<p><a href="/uri" title="title">link</a></p> +</code></pre> +<p>But it is not allowed between the link text and the +following parenthesis:</p> +<pre><code class="language-example">[link] (/uri) +. +<p>[link] (/uri)</p> +</code></pre> +<p>The link text may contain balanced brackets, but not unbalanced ones, +unless they are escaped:</p> +<pre><code class="language-example">[link [foo [bar]]](/uri) +. +<p><a href="/uri">link [foo [bar]]</a></p> +</code></pre> +<pre><code class="language-example">[link] bar](/uri) +. +<p>[link] bar](/uri)</p> +</code></pre> +<pre><code class="language-example">[link [bar](/uri) +. +<p>[link <a href="/uri">bar</a></p> +</code></pre> +<pre><code class="language-example">[link \[bar](/uri) +. +<p><a href="/uri">link [bar</a></p> +</code></pre> +<p>The link text may contain inline content:</p> +<pre><code class="language-example">[link *foo **bar** `#`*](/uri) +. +<p><a href="/uri">link <em>foo <strong>bar</strong> <code>#</code></em></a></p> +</code></pre> +<pre><code class="language-example">[![moon](moon.jpg)](/uri) +. +<p><a href="/uri"><img src="moon.jpg" alt="moon" /></a></p> +</code></pre> +<p>However, links may not contain other links, at any level of nesting.</p> +<pre><code class="language-example">[foo [bar](/uri)](/uri) +. +<p>[foo <a href="/uri">bar</a>](/uri)</p> +</code></pre> +<pre><code class="language-example">[foo *[bar [baz](/uri)](/uri)*](/uri) +. +<p>[foo <em>[bar <a href="/uri">baz</a>](/uri)</em>](/uri)</p> +</code></pre> +<pre><code class="language-example">![[[foo](uri1)](uri2)](uri3) +. +<p><img src="uri3" alt="[foo](uri2)" /></p> +</code></pre> +<p>These cases illustrate the precedence of link text grouping over +emphasis grouping:</p> +<pre><code class="language-example">*[foo*](/uri) +. +<p>*<a href="/uri">foo*</a></p> +</code></pre> +<pre><code class="language-example">[foo *bar](baz*) +. +<p><a href="baz*">foo *bar</a></p> +</code></pre> +<p>Note that brackets that <em>aren't</em> part of links do not take +precedence:</p> +<pre><code class="language-example">*foo [bar* baz] +. +<p><em>foo [bar</em> baz]</p> +</code></pre> +<p>These cases illustrate the precedence of HTML tags, code spans, +and autolinks over link grouping:</p> +<pre><code class="language-example">[foo <bar attr="](baz)"> +. +<p>[foo <bar attr="](baz)"></p> +</code></pre> +<pre><code class="language-example">[foo`](/uri)` +. +<p>[foo<code>](/uri)</code></p> +</code></pre> +<pre><code class="language-example">[foo<http://example.com/?search=](uri)> +. +<p>[foo<a href="http://example.com/?search=%5D(uri)">http://example.com/?search=](uri)</a></p> +</code></pre> +<p>There are three kinds of <a href="@">reference link</a>s: +<a href="#full-reference-link">full</a>, <a href="#collapsed-reference-link">collapsed</a>, +and <a href="#shortcut-reference-link">shortcut</a>.</p> +<p>A <a href="@">full reference link</a> +consists of a [link text] immediately followed by a [link label] +that [matches] a [link reference definition] elsewhere in the document.</p> +<p>A <a href="@">link label</a> begins with a left bracket (<code>[</code>) and ends +with the first right bracket (<code>]</code>) that is not backslash-escaped. +Between these brackets there must be at least one character that is not a space, +tab, or line ending. +Unescaped square bracket characters are not allowed inside the +opening and closing square brackets of [link labels]. A link +label can have at most 999 characters inside the square +brackets.</p> +<p>One label <a href="@">matches</a> +another just in case their normalized forms are equal. To normalize a +label, strip off the opening and closing brackets, +perform the <em>Unicode case fold</em>, strip leading and trailing +spaces, tabs, and line endings, and collapse consecutive internal +spaces, tabs, and line endings to a single space. If there are multiple +matching reference link definitions, the one that comes first in the +document is used. (It is desirable in such cases to emit a warning.)</p> +<p>The link's URI and title are provided by the matching [link +reference definition].</p> +<p>Here is a simple example:</p> +<pre><code class="language-example">[foo][bar] + +[bar]: /url "title" +. +<p><a href="/url" title="title">foo</a></p> +</code></pre> +<p>The rules for the [link text] are the same as with +[inline links]. Thus:</p> +<p>The link text may contain balanced brackets, but not unbalanced ones, +unless they are escaped:</p> +<pre><code class="language-example">[link [foo [bar]]][ref] + +[ref]: /uri +. +<p><a href="/uri">link [foo [bar]]</a></p> +</code></pre> +<pre><code class="language-example">[link \[bar][ref] + +[ref]: /uri +. +<p><a href="/uri">link [bar</a></p> +</code></pre> +<p>The link text may contain inline content:</p> +<pre><code class="language-example">[link *foo **bar** `#`*][ref] + +[ref]: /uri +. +<p><a href="/uri">link <em>foo <strong>bar</strong> <code>#</code></em></a></p> +</code></pre> +<pre><code class="language-example">[![moon](moon.jpg)][ref] + +[ref]: /uri +. +<p><a href="/uri"><img src="moon.jpg" alt="moon" /></a></p> +</code></pre> +<p>However, links may not contain other links, at any level of nesting.</p> +<pre><code class="language-example">[foo [bar](/uri)][ref] + +[ref]: /uri +. +<p>[foo <a href="/uri">bar</a>]<a href="/uri">ref</a></p> +</code></pre> +<pre><code class="language-example">[foo *bar [baz][ref]*][ref] + +[ref]: /uri +. +<p>[foo <em>bar <a href="/uri">baz</a></em>]<a href="/uri">ref</a></p> +</code></pre> +<p>(In the examples above, we have two [shortcut reference links] +instead of one [full reference link].)</p> +<p>The following cases illustrate the precedence of link text grouping over +emphasis grouping:</p> +<pre><code class="language-example">*[foo*][ref] + +[ref]: /uri +. +<p>*<a href="/uri">foo*</a></p> +</code></pre> +<pre><code class="language-example">[foo *bar][ref]* + +[ref]: /uri +. +<p><a href="/uri">foo *bar</a>*</p> +</code></pre> +<p>These cases illustrate the precedence of HTML tags, code spans, +and autolinks over link grouping:</p> +<pre><code class="language-example">[foo <bar attr="][ref]"> + +[ref]: /uri +. +<p>[foo <bar attr="][ref]"></p> +</code></pre> +<pre><code class="language-example">[foo`][ref]` + +[ref]: /uri +. +<p>[foo<code>][ref]</code></p> +</code></pre> +<pre><code class="language-example">[foo<http://example.com/?search=][ref]> + +[ref]: /uri +. +<p>[foo<a href="http://example.com/?search=%5D%5Bref%5D">http://example.com/?search=][ref]</a></p> +</code></pre> +<p>Matching is case-insensitive:</p> +<pre><code class="language-example">[foo][BaR] + +[bar]: /url "title" +. +<p><a href="/url" title="title">foo</a></p> +</code></pre> +<p>Unicode case fold is used:</p> +<pre><code class="language-example">[ẞ] + +[SS]: /url +. +<p><a href="/url">ẞ</a></p> +</code></pre> +<p>Consecutive internal spaces, tabs, and line endings are treated as one space for +purposes of determining matching:</p> +<pre><code class="language-example">[Foo + bar]: /url + +[Baz][Foo bar] +. +<p><a href="/url">Baz</a></p> +</code></pre> +<p>No spaces, tabs, or line endings are allowed between the [link text] and the +[link label]:</p> +<pre><code class="language-example">[foo] [bar] + +[bar]: /url "title" +. +<p>[foo] <a href="/url" title="title">bar</a></p> +</code></pre> +<pre><code class="language-example">[foo] +[bar] + +[bar]: /url "title" +. +<p>[foo] +<a href="/url" title="title">bar</a></p> +</code></pre> +<p>This is a departure from John Gruber's original Markdown syntax +description, which explicitly allows whitespace between the link +text and the link label. It brings reference links in line with +[inline links], which (according to both original Markdown and +this spec) cannot have whitespace after the link text. More +importantly, it prevents inadvertent capture of consecutive +[shortcut reference links]. If whitespace is allowed between the +link text and the link label, then in the following we will have +a single reference link, not two shortcut reference links, as +intended:</p> +<pre><code class="language-markdown">[foo] +[bar] + +[foo]: /url1 +[bar]: /url2 +</code></pre> +<p>(Note that [shortcut reference links] were introduced by Gruber +himself in a beta version of <code>Markdown.pl</code>, but never included +in the official syntax description. Without shortcut reference +links, it is harmless to allow space between the link text and +link label; but once shortcut references are introduced, it is +too dangerous to allow this, as it frequently leads to +unintended results.)</p> +<p>When there are multiple matching [link reference definitions], +the first is used:</p> +<pre><code class="language-example">[foo]: /url1 + +[foo]: /url2 + +[bar][foo] +. +<p><a href="/url1">bar</a></p> +</code></pre> +<p>Note that matching is performed on normalized strings, not parsed +inline content. So the following does not match, even though the +labels define equivalent inline content:</p> +<pre><code class="language-example">[bar][foo\!] + +[foo!]: /url +. +<p>[bar][foo!]</p> +</code></pre> +<p>[Link labels] cannot contain brackets, unless they are +backslash-escaped:</p> +<pre><code class="language-example">[foo][ref[] + +[ref[]: /uri +. +<p>[foo][ref[]</p> +<p>[ref[]: /uri</p> +</code></pre> +<pre><code class="language-example">[foo][ref[bar]] + +[ref[bar]]: /uri +. +<p>[foo][ref[bar]]</p> +<p>[ref[bar]]: /uri</p> +</code></pre> +<pre><code class="language-example">[[[foo]]] + +[[[foo]]]: /url +. +<p>[[[foo]]]</p> +<p>[[[foo]]]: /url</p> +</code></pre> +<pre><code class="language-example">[foo][ref\[] + +[ref\[]: /uri +. +<p><a href="/uri">foo</a></p> +</code></pre> +<p>Note that in this example <code>]</code> is not backslash-escaped:</p> +<pre><code class="language-example">[bar\\]: /uri + +[bar\\] +. +<p><a href="/uri">bar\</a></p> +</code></pre> +<p>A [link label] must contain at least one character that is not a space, tab, or +line ending:</p> +<pre><code class="language-example">[] + +[]: /uri +. +<p>[]</p> +<p>[]: /uri</p> +</code></pre> +<pre><code class="language-example">[ + ] + +[ + ]: /uri +. +<p>[ +]</p> +<p>[ +]: /uri</p> +</code></pre> +<p>A <a href="@">collapsed reference link</a> +consists of a [link label] that [matches] a +[link reference definition] elsewhere in the +document, followed by the string <code>[]</code>. +The contents of the first link label are parsed as inlines, +which are used as the link's text. The link's URI and title are +provided by the matching reference link definition. Thus, +<code>[foo][]</code> is equivalent to <code>[foo][foo]</code>.</p> +<pre><code class="language-example">[foo][] + +[foo]: /url "title" +. +<p><a href="/url" title="title">foo</a></p> +</code></pre> +<pre><code class="language-example">[*foo* bar][] + +[*foo* bar]: /url "title" +. +<p><a href="/url" title="title"><em>foo</em> bar</a></p> +</code></pre> +<p>The link labels are case-insensitive:</p> +<pre><code class="language-example">[Foo][] + +[foo]: /url "title" +. +<p><a href="/url" title="title">Foo</a></p> +</code></pre> +<p>As with full reference links, spaces, tabs, or line endings are not +allowed between the two sets of brackets:</p> +<pre><code class="language-example">[foo] +[] + +[foo]: /url "title" +. +<p><a href="/url" title="title">foo</a> +[]</p> +</code></pre> +<p>A <a href="@">shortcut reference link</a> +consists of a [link label] that [matches] a +[link reference definition] elsewhere in the +document and is not followed by <code>[]</code> or a link label. +The contents of the first link label are parsed as inlines, +which are used as the link's text. The link's URI and title +are provided by the matching link reference definition. +Thus, <code>[foo]</code> is equivalent to <code>[foo][]</code>.</p> +<pre><code class="language-example">[foo] + +[foo]: /url "title" +. +<p><a href="/url" title="title">foo</a></p> +</code></pre> +<pre><code class="language-example">[*foo* bar] + +[*foo* bar]: /url "title" +. +<p><a href="/url" title="title"><em>foo</em> bar</a></p> +</code></pre> +<pre><code class="language-example">[[*foo* bar]] + +[*foo* bar]: /url "title" +. +<p>[<a href="/url" title="title"><em>foo</em> bar</a>]</p> +</code></pre> +<pre><code class="language-example">[[bar [foo] + +[foo]: /url +. +<p>[[bar <a href="/url">foo</a></p> +</code></pre> +<p>The link labels are case-insensitive:</p> +<pre><code class="language-example">[Foo] + +[foo]: /url "title" +. +<p><a href="/url" title="title">Foo</a></p> +</code></pre> +<p>A space after the link text should be preserved:</p> +<pre><code class="language-example">[foo] bar + +[foo]: /url +. +<p><a href="/url">foo</a> bar</p> +</code></pre> +<p>If you just want bracketed text, you can backslash-escape the +opening bracket to avoid links:</p> +<pre><code class="language-example">\[foo] + +[foo]: /url "title" +. +<p>[foo]</p> +</code></pre> +<p>Note that this is a link, because a link label ends with the first +following closing bracket:</p> +<pre><code class="language-example">[foo*]: /url + +*[foo*] +. +<p>*<a href="/url">foo*</a></p> +</code></pre> +<p>Full and compact references take precedence over shortcut +references:</p> +<pre><code class="language-example">[foo][bar] + +[foo]: /url1 +[bar]: /url2 +. +<p><a href="/url2">foo</a></p> +</code></pre> +<pre><code class="language-example">[foo][] + +[foo]: /url1 +. +<p><a href="/url1">foo</a></p> +</code></pre> +<p>Inline links also take precedence:</p> +<pre><code class="language-example">[foo]() + +[foo]: /url1 +. +<p><a href="">foo</a></p> +</code></pre> +<pre><code class="language-example">[foo](not a link) + +[foo]: /url1 +. +<p><a href="/url1">foo</a>(not a link)</p> +</code></pre> +<p>In the following case <code>[bar][baz]</code> is parsed as a reference, +<code>[foo]</code> as normal text:</p> +<pre><code class="language-example">[foo][bar][baz] + +[baz]: /url +. +<p>[foo]<a href="/url">bar</a></p> +</code></pre> +<p>Here, though, <code>[foo][bar]</code> is parsed as a reference, since +<code>[bar]</code> is defined:</p> +<pre><code class="language-example">[foo][bar][baz] + +[baz]: /url1 +[bar]: /url2 +. +<p><a href="/url2">foo</a><a href="/url1">baz</a></p> +</code></pre> +<p>Here <code>[foo]</code> is not parsed as a shortcut reference, because it +is followed by a link label (even though <code>[bar]</code> is not defined):</p> +<pre><code class="language-example">[foo][bar][baz] + +[baz]: /url1 +[foo]: /url2 +. +<p>[foo]<a href="/url1">bar</a></p> +</code></pre> +<h2>Images</h2> +<p>Syntax for images is like the syntax for links, with one +difference. Instead of [link text], we have an +<a href="@">image description</a>. The rules for this are the +same as for [link text], except that (a) an +image description starts with <code>![</code> rather than <code>[</code>, and +(b) an image description may contain links. +An image description has inline elements +as its contents. When an image is rendered to HTML, +this is standardly used as the image's <code>alt</code> attribute.</p> +<pre><code class="language-example">![foo](/url "title") +. +<p><img src="/url" alt="foo" title="title" /></p> +</code></pre> +<pre><code class="language-example">![foo *bar*] + +[foo *bar*]: train.jpg "train & tracks" +. +<p><img src="train.jpg" alt="foo bar" title="train &amp; tracks" /></p> +</code></pre> +<pre><code class="language-example">![foo ![bar](/url)](/url2) +. +<p><img src="/url2" alt="foo bar" /></p> +</code></pre> +<pre><code class="language-example">![foo [bar](/url)](/url2) +. +<p><img src="/url2" alt="foo bar" /></p> +</code></pre> +<p>Though this spec is concerned with parsing, not rendering, it is +recommended that in rendering to HTML, only the plain string content +of the [image description] be used. Note that in +the above example, the alt attribute's value is <code>foo bar</code>, not <code>foo [bar](/url)</code> or <code>foo <a href="/url">bar</a></code>. Only the plain string +content is rendered, without formatting.</p> +<pre><code class="language-example">![foo *bar*][] + +[foo *bar*]: train.jpg "train & tracks" +. +<p><img src="train.jpg" alt="foo bar" title="train &amp; tracks" /></p> +</code></pre> +<pre><code class="language-example">![foo *bar*][foobar] + +[FOOBAR]: train.jpg "train & tracks" +. +<p><img src="train.jpg" alt="foo bar" title="train &amp; tracks" /></p> +</code></pre> +<pre><code class="language-example">![foo](train.jpg) +. +<p><img src="train.jpg" alt="foo" /></p> +</code></pre> +<pre><code class="language-example">My ![foo bar](/path/to/train.jpg "title" ) +. +<p>My <img src="/path/to/train.jpg" alt="foo bar" title="title" /></p> +</code></pre> +<pre><code class="language-example">![foo](<url>) +. +<p><img src="url" alt="foo" /></p> +</code></pre> +<pre><code class="language-example">![](/url) +. +<p><img src="/url" alt="" /></p> +</code></pre> +<p>Reference-style:</p> +<pre><code class="language-example">![foo][bar] + +[bar]: /url +. +<p><img src="/url" alt="foo" /></p> +</code></pre> +<pre><code class="language-example">![foo][bar] + +[BAR]: /url +. +<p><img src="/url" alt="foo" /></p> +</code></pre> +<p>Collapsed:</p> +<pre><code class="language-example">![foo][] + +[foo]: /url "title" +. +<p><img src="/url" alt="foo" title="title" /></p> +</code></pre> +<pre><code class="language-example">![*foo* bar][] + +[*foo* bar]: /url "title" +. +<p><img src="/url" alt="foo bar" title="title" /></p> +</code></pre> +<p>The labels are case-insensitive:</p> +<pre><code class="language-example">![Foo][] + +[foo]: /url "title" +. +<p><img src="/url" alt="Foo" title="title" /></p> +</code></pre> +<p>As with reference links, spaces, tabs, and line endings, are not allowed +between the two sets of brackets:</p> +<pre><code class="language-example">![foo] +[] + +[foo]: /url "title" +. +<p><img src="/url" alt="foo" title="title" /> +[]</p> +</code></pre> +<p>Shortcut:</p> +<pre><code class="language-example">![foo] + +[foo]: /url "title" +. +<p><img src="/url" alt="foo" title="title" /></p> +</code></pre> +<pre><code class="language-example">![*foo* bar] + +[*foo* bar]: /url "title" +. +<p><img src="/url" alt="foo bar" title="title" /></p> +</code></pre> +<p>Note that link labels cannot contain unescaped brackets:</p> +<pre><code class="language-example">![[foo]] + +[[foo]]: /url "title" +. +<p>![[foo]]</p> +<p>[[foo]]: /url &quot;title&quot;</p> +</code></pre> +<p>The link labels are case-insensitive:</p> +<pre><code class="language-example">![Foo] + +[foo]: /url "title" +. +<p><img src="/url" alt="Foo" title="title" /></p> +</code></pre> +<p>If you just want a literal <code>!</code> followed by bracketed text, you can +backslash-escape the opening <code>[</code>:</p> +<pre><code class="language-example">!\[foo] + +[foo]: /url "title" +. +<p>![foo]</p> +</code></pre> +<p>If you want a link after a literal <code>!</code>, backslash-escape the +<code>!</code>:</p> +<pre><code class="language-example">\![foo] + +[foo]: /url "title" +. +<p>!<a href="/url" title="title">foo</a></p> +</code></pre> +<h2>Autolinks</h2> +<p><a href="@">Autolink</a>s are absolute URIs and email addresses inside +<code><</code> and <code>></code>. They are parsed as links, with the URL or email address +as the link label.</p> +<p>A <a href="@">URI autolink</a> consists of <code><</code>, followed by an +[absolute URI] followed by <code>></code>. It is parsed as +a link to the URI, with the URI as the link's label.</p> +<p>An <a href="@">absolute URI</a>, +for these purposes, consists of a [scheme] followed by a colon (<code>:</code>) +followed by zero or more characters other [ASCII control +characters][ASCII control character], [space], <code><</code>, and <code>></code>. +If the URI includes these characters, they must be percent-encoded +(e.g. <code>%20</code> for a space).</p> +<p>For purposes of this spec, a <a href="@">scheme</a> is any sequence +of 2--32 characters beginning with an ASCII letter and followed +by any combination of ASCII letters, digits, or the symbols plus +("+"), period ("."), or hyphen ("-").</p> +<p>Here are some valid autolinks:</p> +<pre><code class="language-example"><http://foo.bar.baz> +. +<p><a href="http://foo.bar.baz">http://foo.bar.baz</a></p> +</code></pre> +<pre><code class="language-example"><http://foo.bar.baz/test?q=hello&id=22&boolean> +. +<p><a href="http://foo.bar.baz/test?q=hello&amp;id=22&amp;boolean">http://foo.bar.baz/test?q=hello&amp;id=22&amp;boolean</a></p> +</code></pre> +<pre><code class="language-example"><irc://foo.bar:2233/baz> +. +<p><a href="irc://foo.bar:2233/baz">irc://foo.bar:2233/baz</a></p> +</code></pre> +<p>Uppercase is also fine:</p> +<pre><code class="language-example"><MAILTO:FOO@BAR.BAZ> +. +<p><a href="MAILTO:FOO@BAR.BAZ">MAILTO:FOO@BAR.BAZ</a></p> +</code></pre> +<p>Note that many strings that count as [absolute URIs] for +purposes of this spec are not valid URIs, because their +schemes are not registered or because of other problems +with their syntax:</p> +<pre><code class="language-example"><a+b+c:d> +. +<p><a href="a+b+c:d">a+b+c:d</a></p> +</code></pre> +<pre><code class="language-example"><made-up-scheme://foo,bar> +. +<p><a href="made-up-scheme://foo,bar">made-up-scheme://foo,bar</a></p> +</code></pre> +<pre><code class="language-example"><http://../> +. +<p><a href="http://../">http://../</a></p> +</code></pre> +<pre><code class="language-example"><localhost:5001/foo> +. +<p><a href="localhost:5001/foo">localhost:5001/foo</a></p> +</code></pre> +<p>Spaces are not allowed in autolinks:</p> +<pre><code class="language-example"><http://foo.bar/baz bim> +. +<p>&lt;http://foo.bar/baz bim&gt;</p> +</code></pre> +<p>Backslash-escapes do not work inside autolinks:</p> +<pre><code class="language-example"><http://example.com/\[\> +. +<p><a href="http://example.com/%5C%5B%5C">http://example.com/\[\</a></p> +</code></pre> +<p>An <a href="@">email autolink</a> +consists of <code><</code>, followed by an [email address], +followed by <code>></code>. The link's label is the email address, +and the URL is <code>mailto:</code> followed by the email address.</p> +<p>An <a href="@">email address</a>, +for these purposes, is anything that matches +the <a href="https://html.spec.whatwg.org/multipage/forms.html#e-mail-state-(type=email)">non-normative regex from the HTML5 +spec</a>:</p> +<pre><code>/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])? +(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/ +</code></pre> +<p>Examples of email autolinks:</p> +<pre><code class="language-example"><foo@bar.example.com> +. +<p><a href="mailto:foo@bar.example.com">foo@bar.example.com</a></p> +</code></pre> +<pre><code class="language-example"><foo+special@Bar.baz-bar0.com> +. +<p><a href="mailto:foo+special@Bar.baz-bar0.com">foo+special@Bar.baz-bar0.com</a></p> +</code></pre> +<p>Backslash-escapes do not work inside email autolinks:</p> +<pre><code class="language-example"><foo\+@bar.example.com> +. +<p>&lt;foo+@bar.example.com&gt;</p> +</code></pre> +<p>These are not autolinks:</p> +<pre><code class="language-example"><> +. +<p>&lt;&gt;</p> +</code></pre> +<pre><code class="language-example">< http://foo.bar > +. +<p>&lt; http://foo.bar &gt;</p> +</code></pre> +<pre><code class="language-example"><m:abc> +. +<p>&lt;m:abc&gt;</p> +</code></pre> +<pre><code class="language-example"><foo.bar.baz> +. +<p>&lt;foo.bar.baz&gt;</p> +</code></pre> +<pre><code class="language-example">http://example.com +. +<p>http://example.com</p> +</code></pre> +<pre><code class="language-example">foo@bar.example.com +. +<p>foo@bar.example.com</p> +</code></pre> +<h2>Raw HTML</h2> +<p>Text between <code><</code> and <code>></code> that looks like an HTML tag is parsed as a +raw HTML tag and will be rendered in HTML without escaping. +Tag and attribute names are not limited to current HTML tags, +so custom tags (and even, say, DocBook tags) may be used.</p> +<p>Here is the grammar for tags:</p> +<p>A <a href="@">tag name</a> consists of an ASCII letter +followed by zero or more ASCII letters, digits, or +hyphens (<code>-</code>).</p> +<p>An <a href="@">attribute</a> consists of spaces, tabs, and up to one line ending, +an [attribute name], and an optional +[attribute value specification].</p> +<p>An <a href="@">attribute name</a> +consists of an ASCII letter, <code>_</code>, or <code>:</code>, followed by zero or more ASCII +letters, digits, <code>_</code>, <code>.</code>, <code>:</code>, or <code>-</code>. (Note: This is the XML +specification restricted to ASCII. HTML5 is laxer.)</p> +<p>An <a href="@">attribute value specification</a> +consists of optional spaces, tabs, and up to one line ending, +a <code>=</code> character, optional spaces, tabs, and up to one line ending, +and an [attribute value].</p> +<p>An <a href="@">attribute value</a> +consists of an [unquoted attribute value], +a [single-quoted attribute value], or a [double-quoted attribute value].</p> +<p>An <a href="@">unquoted attribute value</a> +is a nonempty string of characters not +including spaces, tabs, line endings, <code>"</code>, <code>'</code>, <code>=</code>, <code><</code>, <code>></code>, or <code>`</code>.</p> +<p>A <a href="@">single-quoted attribute value</a> +consists of <code>'</code>, zero or more +characters not including <code>'</code>, and a final <code>'</code>.</p> +<p>A <a href="@">double-quoted attribute value</a> +consists of <code>"</code>, zero or more +characters not including <code>"</code>, and a final <code>"</code>.</p> +<p>An <a href="@">open tag</a> consists of a <code><</code> character, a [tag name], +zero or more [attributes], optional spaces, tabs, and up to one line ending, +an optional <code>/</code> character, and a <code>></code> character.</p> +<p>A <a href="@">closing tag</a> consists of the string <code></</code>, a +[tag name], optional spaces, tabs, and up to one line ending, and the character +<code>></code>.</p> +<p>An <a href="@">HTML comment</a> consists of <code><!--</code> + <em>text</em> + <code>--></code>, +where <em>text</em> does not start with <code>></code> or <code>-></code>, does not end with <code>-</code>, +and does not contain <code>--</code>. (See the +<a href="http://www.w3.org/TR/html5/syntax.html#comments">HTML5 spec</a>.)</p> +<p>A <a href="@">processing instruction</a> +consists of the string <code><?</code>, a string +of characters not including the string <code>?></code>, and the string +<code>?></code>.</p> +<p>A <a href="@">declaration</a> consists of the string <code><!</code>, an ASCII letter, zero or more +characters not including the character <code>></code>, and the character <code>></code>.</p> +<p>A <a href="@">CDATA section</a> consists of +the string <code><![CDATA[</code>, a string of characters not including the string +<code>]]></code>, and the string <code>]]></code>.</p> +<p>An <a href="@">HTML tag</a> consists of an [open tag], a [closing tag], +an [HTML comment], a [processing instruction], a [declaration], +or a [CDATA section].</p> +<p>Here are some simple open tags:</p> +<pre><code class="language-example"><a><bab><c2c> +. +<p><a><bab><c2c></p> +</code></pre> +<p>Empty elements:</p> +<pre><code class="language-example"><a/><b2/> +. +<p><a/><b2/></p> +</code></pre> +<p>Whitespace is allowed:</p> +<pre><code class="language-example"><a /><b2 +data="foo" > +. +<p><a /><b2 +data="foo" ></p> +</code></pre> +<p>With attributes:</p> +<pre><code class="language-example"><a foo="bar" bam = 'baz <em>"</em>' +_boolean zoop:33=zoop:33 /> +. +<p><a foo="bar" bam = 'baz <em>"</em>' +_boolean zoop:33=zoop:33 /></p> +</code></pre> +<p>Custom tag names can be used:</p> +<pre><code class="language-example">Foo <responsive-image src="foo.jpg" /> +. +<p>Foo <responsive-image src="foo.jpg" /></p> +</code></pre> +<p>Illegal tag names, not parsed as HTML:</p> +<pre><code class="language-example"><33> <__> +. +<p>&lt;33&gt; &lt;__&gt;</p> +</code></pre> +<p>Illegal attribute names:</p> +<pre><code class="language-example"><a h*#ref="hi"> +. +<p>&lt;a h*#ref=&quot;hi&quot;&gt;</p> +</code></pre> +<p>Illegal attribute values:</p> +<pre><code class="language-example"><a href="hi'> <a href=hi'> +. +<p>&lt;a href=&quot;hi'&gt; &lt;a href=hi'&gt;</p> +</code></pre> +<p>Illegal whitespace:</p> +<pre><code class="language-example">< a>< +foo><bar/ > +<foo bar=baz +bim!bop /> +. +<p>&lt; a&gt;&lt; +foo&gt;&lt;bar/ &gt; +&lt;foo bar=baz +bim!bop /&gt;</p> +</code></pre> +<p>Missing whitespace:</p> +<pre><code class="language-example"><a href='bar'title=title> +. +<p>&lt;a href='bar'title=title&gt;</p> +</code></pre> +<p>Closing tags:</p> +<pre><code class="language-example"></a></foo > +. +<p></a></foo ></p> +</code></pre> +<p>Illegal attributes in closing tag:</p> +<pre><code class="language-example"></a href="foo"> +. +<p>&lt;/a href=&quot;foo&quot;&gt;</p> +</code></pre> +<p>Comments:</p> +<pre><code class="language-example">foo <!-- this is a +comment - with hyphen --> +. +<p>foo <!-- this is a +comment - with hyphen --></p> +</code></pre> +<pre><code class="language-example">foo <!-- not a comment -- two hyphens --> +. +<p>foo &lt;!-- not a comment -- two hyphens --&gt;</p> +</code></pre> +<p>Not comments:</p> +<pre><code class="language-example">foo <!--> foo --> + +foo <!-- foo---> +. +<p>foo &lt;!--&gt; foo --&gt;</p> +<p>foo &lt;!-- foo---&gt;</p> +</code></pre> +<p>Processing instructions:</p> +<pre><code class="language-example">foo <?php echo $a; ?> +. +<p>foo <?php echo $a; ?></p> +</code></pre> +<p>Declarations:</p> +<pre><code class="language-example">foo <!ELEMENT br EMPTY> +. +<p>foo <!ELEMENT br EMPTY></p> +</code></pre> +<p>CDATA sections:</p> +<pre><code class="language-example">foo <![CDATA[>&<]]> +. +<p>foo <![CDATA[>&<]]></p> +</code></pre> +<p>Entity and numeric character references are preserved in HTML +attributes:</p> +<pre><code class="language-example">foo <a href="&ouml;"> +. +<p>foo <a href="&ouml;"></p> +</code></pre> +<p>Backslash escapes do not work in HTML attributes:</p> +<pre><code class="language-example">foo <a href="\*"> +. +<p>foo <a href="\*"></p> +</code></pre> +<pre><code class="language-example"><a href="\""> +. +<p>&lt;a href=&quot;&quot;&quot;&gt;</p> +</code></pre> +<h2>Hard line breaks</h2> +<p>A line ending (not in a code span or HTML tag) that is preceded +by two or more spaces and does not occur at the end of a block +is parsed as a <a href="@">hard line break</a> (rendered +in HTML as a <code><br /></code> tag):</p> +<pre><code class="language-example">foo +baz +. +<p>foo<br /> +baz</p> +</code></pre> +<p>For a more visible alternative, a backslash before the +[line ending] may be used instead of two or more spaces:</p> +<pre><code class="language-example">foo\ +baz +. +<p>foo<br /> +baz</p> +</code></pre> +<p>More than two spaces can be used:</p> +<pre><code class="language-example">foo +baz +. +<p>foo<br /> +baz</p> +</code></pre> +<p>Leading spaces at the beginning of the next line are ignored:</p> +<pre><code class="language-example">foo + bar +. +<p>foo<br /> +bar</p> +</code></pre> +<pre><code class="language-example">foo\ + bar +. +<p>foo<br /> +bar</p> +</code></pre> +<p>Hard line breaks can occur inside emphasis, links, and other constructs +that allow inline content:</p> +<pre><code class="language-example">*foo +bar* +. +<p><em>foo<br /> +bar</em></p> +</code></pre> +<pre><code class="language-example">*foo\ +bar* +. +<p><em>foo<br /> +bar</em></p> +</code></pre> +<p>Hard line breaks do not occur inside code spans</p> +<pre><code class="language-example">`code +span` +. +<p><code>code span</code></p> +</code></pre> +<pre><code class="language-example">`code\ +span` +. +<p><code>code\ span</code></p> +</code></pre> +<p>or HTML tags:</p> +<pre><code class="language-example"><a href="foo +bar"> +. +<p><a href="foo +bar"></p> +</code></pre> +<pre><code class="language-example"><a href="foo\ +bar"> +. +<p><a href="foo\ +bar"></p> +</code></pre> +<p>Hard line breaks are for separating inline content within a block. +Neither syntax for hard line breaks works at the end of a paragraph or +other block element:</p> +<pre><code class="language-example">foo\ +. +<p>foo\</p> +</code></pre> +<pre><code class="language-example">foo +. +<p>foo</p> +</code></pre> +<pre><code class="language-example">### foo\ +. +<h3>foo\</h3> +</code></pre> +<pre><code class="language-example">### foo +. +<h3>foo</h3> +</code></pre> +<h2>Soft line breaks</h2> +<p>A regular line ending (not in a code span or HTML tag) that is not +preceded by two or more spaces or a backslash is parsed as a +<a href="@">softbreak</a>. (A soft line break may be rendered in HTML either as a +[line ending] or as a space. The result will be the same in +browsers. In the examples here, a [line ending] will be used.)</p> +<pre><code class="language-example">foo +baz +. +<p>foo +baz</p> +</code></pre> +<p>Spaces at the end of the line and beginning of the next line are +removed:</p> +<pre><code class="language-example">foo + baz +. +<p>foo +baz</p> +</code></pre> +<p>A conforming parser may render a soft line break in HTML either as a +line ending or as a space.</p> +<p>A renderer may also provide an option to render soft line breaks +as hard line breaks.</p> +<h2>Textual content</h2> +<p>Any characters not given an interpretation by the above rules will +be parsed as plain textual content.</p> +<pre><code class="language-example">hello $.;'there +. +<p>hello $.;'there</p> +</code></pre> +<pre><code class="language-example">Foo χρῆν +. +<p>Foo χρῆν</p> +</code></pre> +<p>Internal spaces are preserved verbatim:</p> +<pre><code class="language-example">Multiple spaces +. +<p>Multiple spaces</p> +</code></pre> +<!-- END TESTS --> +<h1>Appendix: A parsing strategy</h1> +<p>In this appendix we describe some features of the parsing strategy +used in the CommonMark reference implementations.</p> +<h2>Overview</h2> +<p>Parsing has two phases:</p> +<ol> +<li> +<p>In the first phase, lines of input are consumed and the block +structure of the document---its division into paragraphs, block quotes, +list items, and so on---is constructed. Text is assigned to these +blocks but not parsed. Link reference definitions are parsed and a +map of links is constructed.</p> +</li> +<li> +<p>In the second phase, the raw text contents of paragraphs and headings +are parsed into sequences of Markdown inline elements (strings, +code spans, links, emphasis, and so on), using the map of link +references constructed in phase 1.</p> +</li> +</ol> +<p>At each point in processing, the document is represented as a tree of +<strong>blocks</strong>. The root of the tree is a <code>document</code> block. The <code>document</code> +may have any number of other blocks as <strong>children</strong>. These children +may, in turn, have other blocks as children. The last child of a block +is normally considered <strong>open</strong>, meaning that subsequent lines of input +can alter its contents. (Blocks that are not open are <strong>closed</strong>.) +Here, for example, is a possible document tree, with the open blocks +marked by arrows:</p> +<pre><code class="language-tree">-> document + -> block_quote + paragraph + "Lorem ipsum dolor\nsit amet." + -> list (type=bullet tight=true bullet_char=-) + list_item + paragraph + "Qui *quodsi iracundia*" + -> list_item + -> paragraph + "aliquando id" +</code></pre> +<h2>Phase 1: block structure</h2> +<p>Each line that is processed has an effect on this tree. The line is +analyzed and, depending on its contents, the document may be altered +in one or more of the following ways:</p> +<ol> +<li>One or more open blocks may be closed.</li> +<li>One or more new blocks may be created as children of the +last open block.</li> +<li>Text may be added to the last (deepest) open block remaining +on the tree.</li> +</ol> +<p>Once a line has been incorporated into the tree in this way, +it can be discarded, so input can be read in a stream.</p> +<p>For each line, we follow this procedure:</p> +<ol> +<li> +<p>First we iterate through the open blocks, starting with the +root document, and descending through last children down to the last +open block. Each block imposes a condition that the line must satisfy +if the block is to remain open. For example, a block quote requires a +<code>></code> character. A paragraph requires a non-blank line. +In this phase we may match all or just some of the open +blocks. But we cannot close unmatched blocks yet, because we may have a +[lazy continuation line].</p> +</li> +<li> +<p>Next, after consuming the continuation markers for existing +blocks, we look for new block starts (e.g. <code>></code> for a block quote). +If we encounter a new block start, we close any blocks unmatched +in step 1 before creating the new block as a child of the last +matched container block.</p> +</li> +<li> +<p>Finally, we look at the remainder of the line (after block +markers like <code>></code>, list markers, and indentation have been consumed). +This is text that can be incorporated into the last open +block (a paragraph, code block, heading, or raw HTML).</p> +</li> +</ol> +<p>Setext headings are formed when we see a line of a paragraph +that is a [setext heading underline].</p> +<p>Reference link definitions are detected when a paragraph is closed; +the accumulated text lines are parsed to see if they begin with +one or more reference link definitions. Any remainder becomes a +normal paragraph.</p> +<p>We can see how this works by considering how the tree above is +generated by four lines of Markdown:</p> +<pre><code class="language-markdown">> Lorem ipsum dolor +sit amet. +> - Qui *quodsi iracundia* +> - aliquando id +</code></pre> +<p>At the outset, our document model is just</p> +<pre><code class="language-tree">-> document +</code></pre> +<p>The first line of our text,</p> +<pre><code class="language-markdown">> Lorem ipsum dolor +</code></pre> +<p>causes a <code>block_quote</code> block to be created as a child of our +open <code>document</code> block, and a <code>paragraph</code> block as a child of +the <code>block_quote</code>. Then the text is added to the last open +block, the <code>paragraph</code>:</p> +<pre><code class="language-tree">-> document + -> block_quote + -> paragraph + "Lorem ipsum dolor" +</code></pre> +<p>The next line,</p> +<pre><code class="language-markdown">sit amet. +</code></pre> +<p>is a "lazy continuation" of the open <code>paragraph</code>, so it gets added +to the paragraph's text:</p> +<pre><code class="language-tree">-> document + -> block_quote + -> paragraph + "Lorem ipsum dolor\nsit amet." +</code></pre> +<p>The third line,</p> +<pre><code class="language-markdown">> - Qui *quodsi iracundia* +</code></pre> +<p>causes the <code>paragraph</code> block to be closed, and a new <code>list</code> block +opened as a child of the <code>block_quote</code>. A <code>list_item</code> is also +added as a child of the <code>list</code>, and a <code>paragraph</code> as a child of +the <code>list_item</code>. The text is then added to the new <code>paragraph</code>:</p> +<pre><code class="language-tree">-> document + -> block_quote + paragraph + "Lorem ipsum dolor\nsit amet." + -> list (type=bullet tight=true bullet_char=-) + -> list_item + -> paragraph + "Qui *quodsi iracundia*" +</code></pre> +<p>The fourth line,</p> +<pre><code class="language-markdown">> - aliquando id +</code></pre> +<p>causes the <code>list_item</code> (and its child the <code>paragraph</code>) to be closed, +and a new <code>list_item</code> opened up as child of the <code>list</code>. A <code>paragraph</code> +is added as a child of the new <code>list_item</code>, to contain the text. +We thus obtain the final tree:</p> +<pre><code class="language-tree">-> document + -> block_quote + paragraph + "Lorem ipsum dolor\nsit amet." + -> list (type=bullet tight=true bullet_char=-) + list_item + paragraph + "Qui *quodsi iracundia*" + -> list_item + -> paragraph + "aliquando id" +</code></pre> +<h2>Phase 2: inline structure</h2> +<p>Once all of the input has been parsed, all open blocks are closed.</p> +<p>We then "walk the tree," visiting every node, and parse raw +string contents of paragraphs and headings as inlines. At this +point we have seen all the link reference definitions, so we can +resolve reference links as we go.</p> +<pre><code class="language-tree">document + block_quote + paragraph + str "Lorem ipsum dolor" + softbreak + str "sit amet." + list (type=bullet tight=true bullet_char=-) + list_item + paragraph + str "Qui " + emph + str "quodsi iracundia" + list_item + paragraph + str "aliquando id" +</code></pre> +<p>Notice how the [line ending] in the first paragraph has +been parsed as a <code>softbreak</code>, and the asterisks in the first list item +have become an <code>emph</code>.</p> +<h3>An algorithm for parsing nested emphasis and links</h3> +<p>By far the trickiest part of inline parsing is handling emphasis, +strong emphasis, links, and images. This is done using the following +algorithm.</p> +<p>When we're parsing inlines and we hit either</p> +<ul> +<li>a run of <code>*</code> or <code>_</code> characters, or</li> +<li>a <code>[</code> or <code>![</code></li> +</ul> +<p>we insert a text node with these symbols as its literal content, and we +add a pointer to this text node to the <a href="@">delimiter stack</a>.</p> +<p>The [delimiter stack] is a doubly linked list. Each +element contains a pointer to a text node, plus information about</p> +<ul> +<li>the type of delimiter (<code>[</code>, <code>![</code>, <code>*</code>, <code>_</code>)</li> +<li>the number of delimiters,</li> +<li>whether the delimiter is "active" (all are active to start), and</li> +<li>whether the delimiter is a potential opener, a potential closer, +or both (which depends on what sort of characters precede +and follow the delimiters).</li> +</ul> +<p>When we hit a <code>]</code> character, we call the <em>look for link or image</em> +procedure (see below).</p> +<p>When we hit the end of the input, we call the <em>process emphasis</em> +procedure (see below), with <code>stack_bottom</code> = NULL.</p> +<h4><em>look for link or image</em></h4> +<p>Starting at the top of the delimiter stack, we look backwards +through the stack for an opening <code>[</code> or <code>![</code> delimiter.</p> +<ul> +<li> +<p>If we don't find one, we return a literal text node <code>]</code>.</p> +</li> +<li> +<p>If we do find one, but it's not <em>active</em>, we remove the inactive +delimiter from the stack, and return a literal text node <code>]</code>.</p> +</li> +<li> +<p>If we find one and it's active, then we parse ahead to see if +we have an inline link/image, reference link/image, compact reference +link/image, or shortcut reference link/image.</p> +<ul> +<li> +<p>If we don't, then we remove the opening delimiter from the +delimiter stack and return a literal text node <code>]</code>.</p> +</li> +<li> +<p>If we do, then</p> +<ul> +<li> +<p>We return a link or image node whose children are the inlines +after the text node pointed to by the opening delimiter.</p> +</li> +<li> +<p>We run <em>process emphasis</em> on these inlines, with the <code>[</code> opener +as <code>stack_bottom</code>.</p> +</li> +<li> +<p>We remove the opening delimiter.</p> +</li> +<li> +<p>If we have a link (and not an image), we also set all +<code>[</code> delimiters before the opening delimiter to <em>inactive</em>. (This +will prevent us from getting links within links.)</p> +</li> +</ul> +</li> +</ul> +</li> +</ul> +<h4><em>process emphasis</em></h4> +<p>Parameter <code>stack_bottom</code> sets a lower bound to how far we +descend in the [delimiter stack]. If it is NULL, we can +go all the way to the bottom. Otherwise, we stop before +visiting <code>stack_bottom</code>.</p> +<p>Let <code>current_position</code> point to the element on the [delimiter stack] +just above <code>stack_bottom</code> (or the first element if <code>stack_bottom</code> +is NULL).</p> +<p>We keep track of the <code>openers_bottom</code> for each delimiter +type (<code>*</code>, <code>_</code>), indexed to the length of the closing delimiter run +(modulo 3) and to whether the closing delimiter can also be an +opener. Initialize this to <code>stack_bottom</code>.</p> +<p>Then we repeat the following until we run out of potential +closers:</p> +<ul> +<li> +<p>Move <code>current_position</code> forward in the delimiter stack (if needed) +until we find the first potential closer with delimiter <code>*</code> or <code>_</code>. +(This will be the potential closer closest +to the beginning of the input -- the first one in parse order.)</p> +</li> +<li> +<p>Now, look back in the stack (staying above <code>stack_bottom</code> and +the <code>openers_bottom</code> for this delimiter type) for the +first matching potential opener ("matching" means same delimiter).</p> +</li> +<li> +<p>If one is found:</p> +<ul> +<li> +<p>Figure out whether we have emphasis or strong emphasis: +if both closer and opener spans have length >= 2, we have +strong, otherwise regular.</p> +</li> +<li> +<p>Insert an emph or strong emph node accordingly, after +the text node corresponding to the opener.</p> +</li> +<li> +<p>Remove any delimiters between the opener and closer from +the delimiter stack.</p> +</li> +<li> +<p>Remove 1 (for regular emph) or 2 (for strong emph) delimiters +from the opening and closing text nodes. If they become empty +as a result, remove them and remove the corresponding element +of the delimiter stack. If the closing node is removed, reset +<code>current_position</code> to the next element in the stack.</p> +</li> +</ul> +</li> +<li> +<p>If none is found:</p> +<ul> +<li> +<p>Set <code>openers_bottom</code> to the element before <code>current_position</code>. +(We know that there are no openers for this kind of closer up to and +including this point, so this puts a lower bound on future searches.)</p> +</li> +<li> +<p>If the closer at <code>current_position</code> is not a potential opener, +remove it from the delimiter stack (since we know it can't +be a closer either).</p> +</li> +<li> +<p>Advance <code>current_position</code> to the next element in the stack.</p> +</li> +</ul> +</li> +</ul> +<p>After we're done, we remove all delimiters above <code>stack_bottom</code> from the +delimiter stack.</p> diff --git a/tests/test_linkify.py b/tests/test_linkify.py new file mode 100644 index 0000000..96d506d --- /dev/null +++ b/tests/test_linkify.py @@ -0,0 +1,19 @@ +from markdown_it import MarkdownIt + + +def test_token_levels(): + mdit = MarkdownIt(options_update={"linkify": True}).enable("linkify") + tokens = mdit.parse("www.python.org") + inline = tokens[1] + assert inline.type == "inline" + link_open = inline.children[0] + assert link_open.type == "link_open" + link_text = inline.children[1] + assert link_text.type == "text" + link_close = inline.children[2] + assert link_close.type == "link_close" + + # Assert that linkify tokens have correct nesting levels + assert link_open.level == 0 + assert link_text.level == 1 + assert link_close.level == 0 diff --git a/tests/test_port/fixtures/commonmark_extras.md b/tests/test_port/fixtures/commonmark_extras.md new file mode 100644 index 0000000..168b039 --- /dev/null +++ b/tests/test_port/fixtures/commonmark_extras.md @@ -0,0 +1,696 @@ +Issue commonmark/cmark#383: +. +*****Hello*world**** +. +<p>**<em><strong>Hello<em>world</em></strong></em></p> +. + +Issue #246. Double escaping in ALT +. +![&](#) +. +<p><img src="#" alt="&" /></p> +. + +Strip markdown in ALT tags +. +![*strip* [markdown __in__ alt](#)](#) +. +<p><img src="#" alt="strip markdown in alt" /></p> +. + +Issue #55: +. +![test] + +![test](foo bar) +. +<p>![test]</p> +<p>![test](foo bar)</p> +. + + +Reference labels: 'i̇θωkå'.toUpperCase() is 'İΘΩKÅ', but these should still be equivalent +. +[İϴΩKÅ] + +[i̇θωkå]: /url +. +<p><a href="/url">İϴΩKÅ</a></p> +. + + +Reference labels: support ligatures (equivalent according to unicode case folding) +. +[fffifl] + +[fffifl]: /url +. +<p><a href="/url">fffifl</a></p> +. + + +Issue #35. `<` should work as punctuation +. +an **(:**<br /> +. +<p>an <strong>(:</strong><br /></p> +. + + +Should unescape only needed things in link destinations/titles: +. +[test](<\f\o\o\>\\>) + +[test](foo "\\\"\b\a\r") +. +<p><a href="%5Cf%5Co%5Co%3E%5C">test</a></p> +<p><a href="foo" title="\"\b\a\r">test</a></p> +. + + +Not a closing tag +. +</ 123> +. +<p></ 123></p> +. + + + +Escaping entities in links: +. +[](<"> "&ö") + +[](<\"> "\&\ö") + +[](<\\"> "\\"\\ö") +. +<p><a href="%22" title="&ö"></a></p> +<p><a href="&quot;" title="&amp;&ouml;"></a></p> +<p><a href="%5C%22" title="\"\ö"></a></p> +. + + +Checking combination of replaceEntities and unescapeMd: +. +~~~ &&bad;\&\\& +just a funny little fence +~~~ +. +<pre><code class="&&bad;&amp;\&">just a funny little fence +</code></pre> +. + +Underscore between punctuation chars should be able to close emphasis. + +. +_(hai)_. +. +<p><em>(hai)</em>.</p> +. + +Regression test, should not match emphasis markers in different link tags: +. +[*b]() [c*]() +. +<p><a href="">*b</a> <a href="">c*</a></p> +. + +Those are two separate blockquotes: +. + - > foo + > bar +. +<ul> +<li> +<blockquote> +<p>foo</p> +</blockquote> +</li> +</ul> +<blockquote> +<p>bar</p> +</blockquote> +. + +Blockquote should terminate itself after paragraph continuation +. +- list + > blockquote +blockquote continuation + - next list item +. +<ul> +<li>list +<blockquote> +<p>blockquote +blockquote continuation</p> +</blockquote> +<ul> +<li>next list item</li> +</ul> +</li> +</ul> +. + +Regression test (code block + regular paragraph) +. +> foo +> bar +. +<blockquote> +<pre><code>foo +</code></pre> +<p>bar</p> +</blockquote> +. + +Blockquotes inside indented lists should terminate correctly +. + - a + > b + ``` + c + ``` + - d +. +<ul> +<li>a +<blockquote> +<p>b</p> +</blockquote> +<pre><code>c +</code></pre> +</li> +<li>d</li> +</ul> +. + +Don't output empty class here: +. +```  +test +``` +. +<pre><code>test +</code></pre> +. + +Setext header text supports lazy continuations: +. + - foo +bar + === +. +<ul> +<li> +<h1>foo +bar</h1> +</li> +</ul> +. + +But setext header underline doesn't: +. + - foo + bar + === +. +<ul> +<li>foo +bar +===</li> +</ul> +. + +Tabs should be stripped from the beginning of the line +. + foo + bar + baz +. +<p>foo +bar +baz</p> +. + +Tabs should not cause hardbreak, EOL tabs aren't stripped in commonmark 0.27 +. +foo1 +foo2 +bar +. +<p>foo1 +foo2<br /> +bar</p> +. + +List item terminating quote should not be paragraph continuation +. +1. foo + > quote +2. bar +. +<ol> +<li>foo +<blockquote> +<p>quote</p> +</blockquote> +</li> +<li>bar</li> +</ol> +. + +Escaped space is not allowed in link destination, commonmark/CommonMark#493. +. +[link](a\ b) +. +<p>[link](a\ b)</p> +. + +Link destination cannot contain '<' +. +[](<foo<bar>) + +[](<foo\<bar>) +. +<p>[](<foo<bar>)</p> +<p><a href="foo%3Cbar"></a></p> +. + +Link title cannot contain '(' when opened with it +. +[](url (xxx()) + +[](url (xxx\()) +. +<p>[](url (xxx())</p> +<p><a href="url" title="xxx("></a></p> +. + +Allow EOL in processing instructions, commonmark/commonmark.js#196. +. +a <? +?> +. +<p>a <? +?></p> +. + +Allow meta tag in an inline context, commonmark/commonmark-spec#527. +. +City: +<span itemprop="contentLocation" itemscope itemtype="https://schema.org/City"> + <meta itemprop="name" content="Springfield"> +</span> +. +<p>City: +<span itemprop="contentLocation" itemscope itemtype="https://schema.org/City"> +<meta itemprop="name" content="Springfield"> +</span></p> +. + +Coverage. Directive can terminate paragraph. +. +a +<?php +. +<p>a</p> +<?php +. + + +Coverage. Nested email autolink (silent mode) +. +*<foo@bar.com>* +. +<p><em><a href="mailto:foo@bar.com">foo@bar.com</a></em></p> +. + + +Coverage. Unpaired nested backtick (silent mode) +. +*`foo* +. +<p><em>`foo</em></p> +. + + +Coverage. Should continue scanning after closing "```" despite cache +. +```aaa``bbb``ccc```ddd``eee`` +. +<p><code>aaa``bbb``ccc</code>ddd<code>eee</code></p> +. + + +Coverage. Entities. +. +*&* + +* * + +*&* +. +<p><em>&</em></p> +<p><em> </em></p> +<p><em>&</em></p> +. + + +Coverage. Escape. +. +*\a* +. +<p><em>\a</em></p> +. + + +Coverage. parseLinkDestination +. +[foo](< +bar>) + +[foo](<bar) +. +<p>[foo](< +bar>)</p> +<p>[foo](<bar)</p> +. + + +Coverage. parseLinkTitle +. +[foo](bar "ba) + +[foo](bar "ba\ +z") +. +<p>[foo](bar "ba)</p> +<p><a href="bar" title="ba\ +z">foo</a></p> +. + + +Coverage. Image +. +![test]( x ) +. +<p><img src="x" alt="test" /></p> +. +. +![test][foo] + +[bar]: 123 +. +<p>![test][foo]</p> +. +. +![test][[[ + +[bar]: 123 +. +<p>![test][[[</p> +. +. +![test]( +. +<p>![test](</p> +. + + +Coverage. Link +. +[test]( +. +<p>[test](</p> +. + + +Coverage. Reference +. +[ +test\ +]: 123 +foo +bar +. +<p>foo +bar</p> +. +. +[ +test +] +. +<p>[ +test +]</p> +. +. +> [foo]: bar +[foo] +. +<blockquote></blockquote> +<p><a href="bar">foo</a></p> +. + +Coverage. Tabs in blockquotes. +. +> test + + > test + + > test + +> --- +> test + + > --- + > test + + > --- + > test + +> test + + > test + + > test + +> --- +> test + + > --- + > test + + > --- + > test +. +<blockquote> +<pre><code> test +</code></pre> +</blockquote> +<blockquote> +<pre><code> test +</code></pre> +</blockquote> +<blockquote> +<pre><code>test +</code></pre> +</blockquote> +<blockquote> +<hr /> +<pre><code> test +</code></pre> +</blockquote> +<blockquote> +<hr /> +<pre><code> test +</code></pre> +</blockquote> +<blockquote> +<hr /> +<pre><code>test +</code></pre> +</blockquote> +<blockquote> +<pre><code> test +</code></pre> +</blockquote> +<blockquote> +<pre><code> test +</code></pre> +</blockquote> +<blockquote> +<pre><code> test +</code></pre> +</blockquote> +<blockquote> +<hr /> +<pre><code> test +</code></pre> +</blockquote> +<blockquote> +<hr /> +<pre><code> test +</code></pre> +</blockquote> +<blockquote> +<hr /> +<pre><code> test +</code></pre> +</blockquote> +. + +Coverage. Tabs in lists. +. +1. foo + + bar +. +<ol> +<li> +<p>foo</p> +<pre><code> bar +</code></pre> +</li> +</ol> +. + +Coverage. Various tags not interrupting blockquotes because of indentation: +. +> foo + - - - - + +> foo + # not a heading +. +<blockquote> +<p>foo +- - - -</p> +</blockquote> +<blockquote> +<p>foo +# not a heading</p> +</blockquote> +. + +Coverage, entities with code > 10FFFF. Made this way for compatibility with commonmark.js. +. +� + +� +. +<p>�</p> +<p>&#x1100000;</p> +. + +Issue #696. Blockquotes should remember their level. +. +>>> foo +bar +>>> baz +. +<blockquote> +<blockquote> +<blockquote> +<p>foo +bar +baz</p> +</blockquote> +</blockquote> +</blockquote> +. + +Issue #696. Blockquotes should stop when outdented from a list. +. +1. >>> foo + bar +baz + >>> foo + >>> bar + >>> baz +. +<ol> +<li> +<blockquote> +<blockquote> +<blockquote> +<p>foo +bar +baz +foo</p> +</blockquote> +</blockquote> +</blockquote> +</li> +</ol> +<blockquote> +<blockquote> +<blockquote> +<p>bar +baz</p> +</blockquote> +</blockquote> +</blockquote> +. + +Newline in image description +. +There is a newline in this image ![here +it is](https://github.com/executablebooks/) +. +<p>There is a newline in this image <img src="https://github.com/executablebooks/" alt="here +it is" /></p> +. + +Issue #772. Header rule should not interfere with html tags. +. +<!-- +== +--> + +<pre> +== +</pre> +. +<!-- +== +--> +<pre> +== +</pre> +. + +Issue #205. Space in link destination generates IndexError +. +[Contact](http:// mail.com) + +[Contact](mailto: mail@mail.com) +. +<p>[Contact](http:// mail.com)</p> +<p>[Contact](mailto: mail@mail.com)</p> +. + +Issue #204. Combination of blockquotes, list and newlines causes an IndexError +. +> QUOTE ++ UNORDERED LIST ITEM + > INDENTED QUOTE + + + +. +<blockquote> +<p>QUOTE</p> +</blockquote> +<ul> +<li>UNORDERED LIST ITEM +<blockquote> +<p>INDENTED QUOTE</p> +</blockquote> +</li> +</ul> +. diff --git a/tests/test_port/fixtures/commonmark_spec.md b/tests/test_port/fixtures/commonmark_spec.md new file mode 100644 index 0000000..c437019 --- /dev/null +++ b/tests/test_port/fixtures/commonmark_spec.md @@ -0,0 +1,7834 @@ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 355 + +. + foo baz bim +. +<pre><code>foo baz bim +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 362 + +. + foo baz bim +. +<pre><code>foo baz bim +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 369 + +. + a a + ὐ a +. +<pre><code>a a +ὐ a +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 382 + +. + - foo + + bar +. +<ul> +<li> +<p>foo</p> +<p>bar</p> +</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 395 + +. +- foo + + bar +. +<ul> +<li> +<p>foo</p> +<pre><code> bar +</code></pre> +</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 418 + +. +> foo +. +<blockquote> +<pre><code> foo +</code></pre> +</blockquote> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 427 + +. +- foo +. +<ul> +<li> +<pre><code> foo +</code></pre> +</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 439 + +. + foo + bar +. +<pre><code>foo +bar +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 448 + +. + - foo + - bar + - baz +. +<ul> +<li>foo +<ul> +<li>bar +<ul> +<li>baz</li> +</ul> +</li> +</ul> +</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 466 + +. +# Foo +. +<h1>Foo</h1> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 472 + +. +* * * +. +<hr /> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 489 + +. +\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\`\{\|\}\~ +. +<p>!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 499 + +. +\ \A\a\ \3\φ\« +. +<p>\ \A\a\ \3\φ\«</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 509 + +. +\*not emphasized* +\<br/> not a tag +\[not a link](/foo) +\`not code` +1\. not a list +\* not a list +\# not a heading +\[foo]: /url "not a reference" +\ö not a character entity +. +<p>*not emphasized* +<br/> not a tag +[not a link](/foo) +`not code` +1. not a list +* not a list +# not a heading +[foo]: /url "not a reference" +&ouml; not a character entity</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 534 + +. +\\*emphasis* +. +<p>\<em>emphasis</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 543 + +. +foo\ +bar +. +<p>foo<br /> +bar</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 555 + +. +`` \[\` `` +. +<p><code>\[\`</code></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 562 + +. + \[\] +. +<pre><code>\[\] +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 570 + +. +~~~ +\[\] +~~~ +. +<pre><code>\[\] +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 580 + +. +<http://example.com?find=\*> +. +<p><a href="http://example.com?find=%5C*">http://example.com?find=\*</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 587 + +. +<a href="/bar\/)"> +. +<a href="/bar\/)"> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 597 + +. +[foo](/bar\* "ti\*tle") +. +<p><a href="/bar*" title="ti*tle">foo</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 604 + +. +[foo] + +[foo]: /bar\* "ti\*tle" +. +<p><a href="/bar*" title="ti*tle">foo</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 613 + +. +``` foo\+bar +foo +``` +. +<pre><code class="language-foo+bar">foo +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 649 + +. + & © Æ Ď +¾ ℋ ⅆ +∲ ≧̸ +. +<p> & © Æ Ď +¾ ℋ ⅆ +∲ ≧̸</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 668 + +. +# Ӓ Ϡ � +. +<p># Ӓ Ϡ �</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 681 + +. +" ആ ಫ +. +<p>" ആ ಫ</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 690 + +. +  &x; &#; &#x; +� +&#abcdef0; +&ThisIsNotDefined; &hi?; +. +<p>&nbsp &x; &#; &#x; +&#87654321; +&#abcdef0; +&ThisIsNotDefined; &hi?;</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 707 + +. +© +. +<p>&copy</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 717 + +. +&MadeUpEntity; +. +<p>&MadeUpEntity;</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 728 + +. +<a href="öö.html"> +. +<a href="öö.html"> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 735 + +. +[foo](/föö "föö") +. +<p><a href="/f%C3%B6%C3%B6" title="föö">foo</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 742 + +. +[foo] + +[foo]: /föö "föö" +. +<p><a href="/f%C3%B6%C3%B6" title="föö">foo</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 751 + +. +``` föö +foo +``` +. +<pre><code class="language-föö">foo +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 764 + +. +`föö` +. +<p><code>f&ouml;&ouml;</code></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 771 + +. + föfö +. +<pre><code>f&ouml;f&ouml; +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 783 + +. +*foo* +*foo* +. +<p>*foo* +<em>foo</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 791 + +. +* foo + +* foo +. +<p>* foo</p> +<ul> +<li>foo</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 802 + +. +foo bar +. +<p>foo + +bar</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 810 + +. +	foo +. +<p> foo</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 817 + +. +[a](url "tit") +. +<p>[a](url "tit")</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 840 + +. +- `one +- two` +. +<ul> +<li>`one</li> +<li>two`</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 879 + +. +*** +--- +___ +. +<hr /> +<hr /> +<hr /> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 892 + +. ++++ +. +<p>+++</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 899 + +. +=== +. +<p>===</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 908 + +. +-- +** +__ +. +<p>-- +** +__</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 921 + +. + *** + *** + *** +. +<hr /> +<hr /> +<hr /> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 934 + +. + *** +. +<pre><code>*** +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 942 + +. +Foo + *** +. +<p>Foo +***</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 953 + +. +_____________________________________ +. +<hr /> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 962 + +. + - - - +. +<hr /> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 969 + +. + ** * ** * ** * ** +. +<hr /> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 976 + +. +- - - - +. +<hr /> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 985 + +. +- - - - +. +<hr /> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 994 + +. +_ _ _ _ a + +a------ + +---a--- +. +<p>_ _ _ _ a</p> +<p>a------</p> +<p>---a---</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1010 + +. + *-* +. +<p><em>-</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1019 + +. +- foo +*** +- bar +. +<ul> +<li>foo</li> +</ul> +<hr /> +<ul> +<li>bar</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1036 + +. +Foo +*** +bar +. +<p>Foo</p> +<hr /> +<p>bar</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1053 + +. +Foo +--- +bar +. +<h2>Foo</h2> +<p>bar</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1066 + +. +* Foo +* * * +* Bar +. +<ul> +<li>Foo</li> +</ul> +<hr /> +<ul> +<li>Bar</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1083 + +. +- Foo +- * * * +. +<ul> +<li>Foo</li> +<li> +<hr /> +</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1112 + +. +# foo +## foo +### foo +#### foo +##### foo +###### foo +. +<h1>foo</h1> +<h2>foo</h2> +<h3>foo</h3> +<h4>foo</h4> +<h5>foo</h5> +<h6>foo</h6> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1131 + +. +####### foo +. +<p>####### foo</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1146 + +. +#5 bolt + +#hashtag +. +<p>#5 bolt</p> +<p>#hashtag</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1158 + +. +\## foo +. +<p>## foo</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1167 + +. +# foo *bar* \*baz\* +. +<h1>foo <em>bar</em> *baz*</h1> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1176 + +. +# foo +. +<h1>foo</h1> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1185 + +. + ### foo + ## foo + # foo +. +<h3>foo</h3> +<h2>foo</h2> +<h1>foo</h1> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1198 + +. + # foo +. +<pre><code># foo +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1206 + +. +foo + # bar +. +<p>foo +# bar</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1217 + +. +## foo ## + ### bar ### +. +<h2>foo</h2> +<h3>bar</h3> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1228 + +. +# foo ################################## +##### foo ## +. +<h1>foo</h1> +<h5>foo</h5> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1239 + +. +### foo ### +. +<h3>foo</h3> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1250 + +. +### foo ### b +. +<h3>foo ### b</h3> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1259 + +. +# foo# +. +<h1>foo#</h1> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1269 + +. +### foo \### +## foo #\## +# foo \# +. +<h3>foo ###</h3> +<h2>foo ###</h2> +<h1>foo #</h1> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1283 + +. +**** +## foo +**** +. +<hr /> +<h2>foo</h2> +<hr /> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1294 + +. +Foo bar +# baz +Bar foo +. +<p>Foo bar</p> +<h1>baz</h1> +<p>Bar foo</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1307 + +. +## +# +### ### +. +<h2></h2> +<h1></h1> +<h3></h3> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1350 + +. +Foo *bar* +========= + +Foo *bar* +--------- +. +<h1>Foo <em>bar</em></h1> +<h2>Foo <em>bar</em></h2> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1364 + +. +Foo *bar +baz* +==== +. +<h1>Foo <em>bar +baz</em></h1> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1378 + +. + Foo *bar +baz* +==== +. +<h1>Foo <em>bar +baz</em></h1> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1390 + +. +Foo +------------------------- + +Foo += +. +<h2>Foo</h2> +<h1>Foo</h1> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1405 + +. + Foo +--- + + Foo +----- + + Foo + === +. +<h2>Foo</h2> +<h2>Foo</h2> +<h1>Foo</h1> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1423 + +. + Foo + --- + + Foo +--- +. +<pre><code>Foo +--- + +Foo +</code></pre> +<hr /> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1442 + +. +Foo + ---- +. +<h2>Foo</h2> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1452 + +. +Foo + --- +. +<p>Foo +---</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1463 + +. +Foo += = + +Foo +--- - +. +<p>Foo += =</p> +<p>Foo</p> +<hr /> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1479 + +. +Foo +----- +. +<h2>Foo</h2> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1489 + +. +Foo\ +---- +. +<h2>Foo\</h2> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1500 + +. +`Foo +---- +` + +<a title="a lot +--- +of dashes"/> +. +<h2>`Foo</h2> +<p>`</p> +<h2><a title="a lot</h2> +<p>of dashes"/></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1519 + +. +> Foo +--- +. +<blockquote> +<p>Foo</p> +</blockquote> +<hr /> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1530 + +. +> foo +bar +=== +. +<blockquote> +<p>foo +bar +===</p> +</blockquote> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1543 + +. +- Foo +--- +. +<ul> +<li>Foo</li> +</ul> +<hr /> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1558 + +. +Foo +Bar +--- +. +<h2>Foo +Bar</h2> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1571 + +. +--- +Foo +--- +Bar +--- +Baz +. +<hr /> +<h2>Foo</h2> +<h2>Bar</h2> +<p>Baz</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1588 + +. + +==== +. +<p>====</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1600 + +. +--- +--- +. +<hr /> +<hr /> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1609 + +. +- foo +----- +. +<ul> +<li>foo</li> +</ul> +<hr /> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1620 + +. + foo +--- +. +<pre><code>foo +</code></pre> +<hr /> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1630 + +. +> foo +----- +. +<blockquote> +<p>foo</p> +</blockquote> +<hr /> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1644 + +. +\> foo +------ +. +<h2>> foo</h2> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1675 + +. +Foo + +bar +--- +baz +. +<p>Foo</p> +<h2>bar</h2> +<p>baz</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1691 + +. +Foo +bar + +--- + +baz +. +<p>Foo +bar</p> +<hr /> +<p>baz</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1709 + +. +Foo +bar +* * * +baz +. +<p>Foo +bar</p> +<hr /> +<p>baz</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1724 + +. +Foo +bar +\--- +baz +. +<p>Foo +bar +--- +baz</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1752 + +. + a simple + indented code block +. +<pre><code>a simple + indented code block +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1766 + +. + - foo + + bar +. +<ul> +<li> +<p>foo</p> +<p>bar</p> +</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1780 + +. +1. foo + + - bar +. +<ol> +<li> +<p>foo</p> +<ul> +<li>bar</li> +</ul> +</li> +</ol> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1800 + +. + <a/> + *hi* + + - one +. +<pre><code><a/> +*hi* + +- one +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1816 + +. + chunk1 + + chunk2 + + + + chunk3 +. +<pre><code>chunk1 + +chunk2 + + + +chunk3 +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1839 + +. + chunk1 + + chunk2 +. +<pre><code>chunk1 + + chunk2 +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1854 + +. +Foo + bar + +. +<p>Foo +bar</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1868 + +. + foo +bar +. +<pre><code>foo +</code></pre> +<p>bar</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1881 + +. +# Heading + foo +Heading +------ + foo +---- +. +<h1>Heading</h1> +<pre><code>foo +</code></pre> +<h2>Heading</h2> +<pre><code>foo +</code></pre> +<hr /> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1901 + +. + foo + bar +. +<pre><code> foo +bar +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1914 + +. + + + foo + + +. +<pre><code>foo +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1928 + +. + foo +. +<pre><code>foo +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1983 + +. +``` +< + > +``` +. +<pre><code>< + > +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 1997 + +. +~~~ +< + > +~~~ +. +<pre><code>< + > +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2010 + +. +`` +foo +`` +. +<p><code>foo</code></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2021 + +. +``` +aaa +~~~ +``` +. +<pre><code>aaa +~~~ +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2033 + +. +~~~ +aaa +``` +~~~ +. +<pre><code>aaa +``` +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2047 + +. +```` +aaa +``` +`````` +. +<pre><code>aaa +``` +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2059 + +. +~~~~ +aaa +~~~ +~~~~ +. +<pre><code>aaa +~~~ +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2074 + +. +``` +. +<pre><code></code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2081 + +. +````` + +``` +aaa +. +<pre><code> +``` +aaa +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2094 + +. +> ``` +> aaa + +bbb +. +<blockquote> +<pre><code>aaa +</code></pre> +</blockquote> +<p>bbb</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2110 + +. +``` + + +``` +. +<pre><code> + +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2124 + +. +``` +``` +. +<pre><code></code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2136 + +. + ``` + aaa +aaa +``` +. +<pre><code>aaa +aaa +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2148 + +. + ``` +aaa + aaa +aaa + ``` +. +<pre><code>aaa +aaa +aaa +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2162 + +. + ``` + aaa + aaa + aaa + ``` +. +<pre><code>aaa + aaa +aaa +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2178 + +. + ``` + aaa + ``` +. +<pre><code>``` +aaa +``` +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2193 + +. +``` +aaa + ``` +. +<pre><code>aaa +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2203 + +. + ``` +aaa + ``` +. +<pre><code>aaa +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2215 + +. +``` +aaa + ``` +. +<pre><code>aaa + ``` +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2229 + +. +``` ``` +aaa +. +<p><code> </code> +aaa</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2238 + +. +~~~~~~ +aaa +~~~ ~~ +. +<pre><code>aaa +~~~ ~~ +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2252 + +. +foo +``` +bar +``` +baz +. +<p>foo</p> +<pre><code>bar +</code></pre> +<p>baz</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2269 + +. +foo +--- +~~~ +bar +~~~ +# baz +. +<h2>foo</h2> +<pre><code>bar +</code></pre> +<h1>baz</h1> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2291 + +. +```ruby +def foo(x) + return 3 +end +``` +. +<pre><code class="language-ruby">def foo(x) + return 3 +end +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2305 + +. +~~~~ ruby startline=3 $%@#$ +def foo(x) + return 3 +end +~~~~~~~ +. +<pre><code class="language-ruby">def foo(x) + return 3 +end +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2319 + +. +````; +```` +. +<pre><code class="language-;"></code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2329 + +. +``` aa ``` +foo +. +<p><code>aa</code> +foo</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2340 + +. +~~~ aa ``` ~~~ +foo +~~~ +. +<pre><code class="language-aa">foo +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2352 + +. +``` +``` aaa +``` +. +<pre><code>``` aaa +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2431 + +. +<table><tr><td> +<pre> +**Hello**, + +_world_. +</pre> +</td></tr></table> +. +<table><tr><td> +<pre> +**Hello**, +<p><em>world</em>. +</pre></p> +</td></tr></table> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2460 + +. +<table> + <tr> + <td> + hi + </td> + </tr> +</table> + +okay. +. +<table> + <tr> + <td> + hi + </td> + </tr> +</table> +<p>okay.</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2482 + +. + <div> + *hello* + <foo><a> +. + <div> + *hello* + <foo><a> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2495 + +. +</div> +*foo* +. +</div> +*foo* +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2506 + +. +<DIV CLASS="foo"> + +*Markdown* + +</DIV> +. +<DIV CLASS="foo"> +<p><em>Markdown</em></p> +</DIV> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2522 + +. +<div id="foo" + class="bar"> +</div> +. +<div id="foo" + class="bar"> +</div> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2533 + +. +<div id="foo" class="bar + baz"> +</div> +. +<div id="foo" class="bar + baz"> +</div> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2545 + +. +<div> +*foo* + +*bar* +. +<div> +*foo* +<p><em>bar</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2561 + +. +<div id="foo" +*hi* +. +<div id="foo" +*hi* +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2570 + +. +<div class +foo +. +<div class +foo +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2582 + +. +<div *???-&&&-<--- +*foo* +. +<div *???-&&&-<--- +*foo* +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2594 + +. +<div><a href="bar">*foo*</a></div> +. +<div><a href="bar">*foo*</a></div> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2601 + +. +<table><tr><td> +foo +</td></tr></table> +. +<table><tr><td> +foo +</td></tr></table> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2618 + +. +<div></div> +``` c +int x = 33; +``` +. +<div></div> +``` c +int x = 33; +``` +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2635 + +. +<a href="foo"> +*bar* +</a> +. +<a href="foo"> +*bar* +</a> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2648 + +. +<Warning> +*bar* +</Warning> +. +<Warning> +*bar* +</Warning> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2659 + +. +<i class="foo"> +*bar* +</i> +. +<i class="foo"> +*bar* +</i> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2670 + +. +</ins> +*bar* +. +</ins> +*bar* +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2685 + +. +<del> +*foo* +</del> +. +<del> +*foo* +</del> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2700 + +. +<del> + +*foo* + +</del> +. +<del> +<p><em>foo</em></p> +</del> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2718 + +. +<del>*foo*</del> +. +<p><del><em>foo</em></del></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2734 + +. +<pre language="haskell"><code> +import Text.HTML.TagSoup + +main :: IO () +main = print $ parseTags tags +</code></pre> +okay +. +<pre language="haskell"><code> +import Text.HTML.TagSoup + +main :: IO () +main = print $ parseTags tags +</code></pre> +<p>okay</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2755 + +. +<script type="text/javascript"> +// JavaScript example + +document.getElementById("demo").innerHTML = "Hello JavaScript!"; +</script> +okay +. +<script type="text/javascript"> +// JavaScript example + +document.getElementById("demo").innerHTML = "Hello JavaScript!"; +</script> +<p>okay</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2774 + +. +<textarea> + +*foo* + +_bar_ + +</textarea> +. +<textarea> + +*foo* + +_bar_ + +</textarea> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2794 + +. +<style + type="text/css"> +h1 {color:red;} + +p {color:blue;} +</style> +okay +. +<style + type="text/css"> +h1 {color:red;} + +p {color:blue;} +</style> +<p>okay</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2817 + +. +<style + type="text/css"> + +foo +. +<style + type="text/css"> + +foo +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2830 + +. +> <div> +> foo + +bar +. +<blockquote> +<div> +foo +</blockquote> +<p>bar</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2844 + +. +- <div> +- foo +. +<ul> +<li> +<div> +</li> +<li>foo</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2859 + +. +<style>p{color:red;}</style> +*foo* +. +<style>p{color:red;}</style> +<p><em>foo</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2868 + +. +<!-- foo -->*bar* +*baz* +. +<!-- foo -->*bar* +<p><em>baz</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2880 + +. +<script> +foo +</script>1. *bar* +. +<script> +foo +</script>1. *bar* +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2893 + +. +<!-- Foo + +bar + baz --> +okay +. +<!-- Foo + +bar + baz --> +<p>okay</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2911 + +. +<?php + + echo '>'; + +?> +okay +. +<?php + + echo '>'; + +?> +<p>okay</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2930 + +. +<!DOCTYPE html> +. +<!DOCTYPE html> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2939 + +. +<![CDATA[ +function matchwo(a,b) +{ + if (a < b && a < 0) then { + return 1; + + } else { + + return 0; + } +} +]]> +okay +. +<![CDATA[ +function matchwo(a,b) +{ + if (a < b && a < 0) then { + return 1; + + } else { + + return 0; + } +} +]]> +<p>okay</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2973 + +. + <!-- foo --> + + <!-- foo --> +. + <!-- foo --> +<pre><code><!-- foo --> +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2984 + +. + <div> + + <div> +. + <div> +<pre><code><div> +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 2998 + +. +Foo +<div> +bar +</div> +. +<p>Foo</p> +<div> +bar +</div> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3015 + +. +<div> +bar +</div> +*foo* +. +<div> +bar +</div> +*foo* +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3030 + +. +Foo +<a href="bar"> +baz +. +<p>Foo +<a href="bar"> +baz</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3071 + +. +<div> + +*Emphasized* text. + +</div> +. +<div> +<p><em>Emphasized</em> text.</p> +</div> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3084 + +. +<div> +*Emphasized* text. +</div> +. +<div> +*Emphasized* text. +</div> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3106 + +. +<table> + +<tr> + +<td> +Hi +</td> + +</tr> + +</table> +. +<table> +<tr> +<td> +Hi +</td> +</tr> +</table> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3133 + +. +<table> + + <tr> + + <td> + Hi + </td> + + </tr> + +</table> +. +<table> + <tr> +<pre><code><td> + Hi +</td> +</code></pre> + </tr> +</table> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3182 + +. +[foo]: /url "title" + +[foo] +. +<p><a href="/url" title="title">foo</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3191 + +. + [foo]: + /url + 'the title' + +[foo] +. +<p><a href="/url" title="the title">foo</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3202 + +. +[Foo*bar\]]:my_(url) 'title (with parens)' + +[Foo*bar\]] +. +<p><a href="my_(url)" title="title (with parens)">Foo*bar]</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3211 + +. +[Foo bar]: +<my url> +'title' + +[Foo bar] +. +<p><a href="my%20url" title="title">Foo bar</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3224 + +. +[foo]: /url ' +title +line1 +line2 +' + +[foo] +. +<p><a href="/url" title=" +title +line1 +line2 +">foo</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3243 + +. +[foo]: /url 'title + +with blank line' + +[foo] +. +<p>[foo]: /url 'title</p> +<p>with blank line'</p> +<p>[foo]</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3258 + +. +[foo]: +/url + +[foo] +. +<p><a href="/url">foo</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3270 + +. +[foo]: + +[foo] +. +<p>[foo]:</p> +<p>[foo]</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3282 + +. +[foo]: <> + +[foo] +. +<p><a href="">foo</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3293 + +. +[foo]: <bar>(baz) + +[foo] +. +<p>[foo]: <bar>(baz)</p> +<p>[foo]</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3306 + +. +[foo]: /url\bar\*baz "foo\"bar\baz" + +[foo] +. +<p><a href="/url%5Cbar*baz" title="foo"bar\baz">foo</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3317 + +. +[foo] + +[foo]: url +. +<p><a href="url">foo</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3329 + +. +[foo] + +[foo]: first +[foo]: second +. +<p><a href="first">foo</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3342 + +. +[FOO]: /url + +[Foo] +. +<p><a href="/url">Foo</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3351 + +. +[ΑΓΩ]: /φου + +[αγω] +. +<p><a href="/%CF%86%CE%BF%CF%85">αγω</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3366 + +. +[foo]: /url +. +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3374 + +. +[ +foo +]: /url +bar +. +<p>bar</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3387 + +. +[foo]: /url "title" ok +. +<p>[foo]: /url "title" ok</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3396 + +. +[foo]: /url +"title" ok +. +<p>"title" ok</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3407 + +. + [foo]: /url "title" + +[foo] +. +<pre><code>[foo]: /url "title" +</code></pre> +<p>[foo]</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3421 + +. +``` +[foo]: /url +``` + +[foo] +. +<pre><code>[foo]: /url +</code></pre> +<p>[foo]</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3436 + +. +Foo +[bar]: /baz + +[bar] +. +<p>Foo +[bar]: /baz</p> +<p>[bar]</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3451 + +. +# [Foo] +[foo]: /url +> bar +. +<h1><a href="/url">Foo</a></h1> +<blockquote> +<p>bar</p> +</blockquote> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3462 + +. +[foo]: /url +bar +=== +[foo] +. +<h1>bar</h1> +<p><a href="/url">foo</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3472 + +. +[foo]: /url +=== +[foo] +. +<p>=== +<a href="/url">foo</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3485 + +. +[foo]: /foo-url "foo" +[bar]: /bar-url + "bar" +[baz]: /baz-url + +[foo], +[bar], +[baz] +. +<p><a href="/foo-url" title="foo">foo</a>, +<a href="/bar-url" title="bar">bar</a>, +<a href="/baz-url">baz</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3506 + +. +[foo] + +> [foo]: /url +. +<p><a href="/url">foo</a></p> +<blockquote> +</blockquote> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3528 + +. +aaa + +bbb +. +<p>aaa</p> +<p>bbb</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3540 + +. +aaa +bbb + +ccc +ddd +. +<p>aaa +bbb</p> +<p>ccc +ddd</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3556 + +. +aaa + + +bbb +. +<p>aaa</p> +<p>bbb</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3569 + +. + aaa + bbb +. +<p>aaa +bbb</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3581 + +. +aaa + bbb + ccc +. +<p>aaa +bbb +ccc</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3595 + +. + aaa +bbb +. +<p>aaa +bbb</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3604 + +. + aaa +bbb +. +<pre><code>aaa +</code></pre> +<p>bbb</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3618 + +. +aaa +bbb +. +<p>aaa<br /> +bbb</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3635 + +. + + +aaa + + +# aaa + + +. +<p>aaa</p> +<h1>aaa</h1> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3703 + +. +> # Foo +> bar +> baz +. +<blockquote> +<h1>Foo</h1> +<p>bar +baz</p> +</blockquote> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3718 + +. +># Foo +>bar +> baz +. +<blockquote> +<h1>Foo</h1> +<p>bar +baz</p> +</blockquote> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3733 + +. + > # Foo + > bar + > baz +. +<blockquote> +<h1>Foo</h1> +<p>bar +baz</p> +</blockquote> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3748 + +. + > # Foo + > bar + > baz +. +<pre><code>> # Foo +> bar +> baz +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3763 + +. +> # Foo +> bar +baz +. +<blockquote> +<h1>Foo</h1> +<p>bar +baz</p> +</blockquote> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3779 + +. +> bar +baz +> foo +. +<blockquote> +<p>bar +baz +foo</p> +</blockquote> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3803 + +. +> foo +--- +. +<blockquote> +<p>foo</p> +</blockquote> +<hr /> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3823 + +. +> - foo +- bar +. +<blockquote> +<ul> +<li>foo</li> +</ul> +</blockquote> +<ul> +<li>bar</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3841 + +. +> foo + bar +. +<blockquote> +<pre><code>foo +</code></pre> +</blockquote> +<pre><code>bar +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3854 + +. +> ``` +foo +``` +. +<blockquote> +<pre><code></code></pre> +</blockquote> +<p>foo</p> +<pre><code></code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3870 + +. +> foo + - bar +. +<blockquote> +<p>foo +- bar</p> +</blockquote> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3894 + +. +> +. +<blockquote> +</blockquote> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3902 + +. +> +> +> +. +<blockquote> +</blockquote> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3914 + +. +> +> foo +> +. +<blockquote> +<p>foo</p> +</blockquote> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3927 + +. +> foo + +> bar +. +<blockquote> +<p>foo</p> +</blockquote> +<blockquote> +<p>bar</p> +</blockquote> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3949 + +. +> foo +> bar +. +<blockquote> +<p>foo +bar</p> +</blockquote> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3962 + +. +> foo +> +> bar +. +<blockquote> +<p>foo</p> +<p>bar</p> +</blockquote> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3976 + +. +foo +> bar +. +<p>foo</p> +<blockquote> +<p>bar</p> +</blockquote> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 3990 + +. +> aaa +*** +> bbb +. +<blockquote> +<p>aaa</p> +</blockquote> +<hr /> +<blockquote> +<p>bbb</p> +</blockquote> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4008 + +. +> bar +baz +. +<blockquote> +<p>bar +baz</p> +</blockquote> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4019 + +. +> bar + +baz +. +<blockquote> +<p>bar</p> +</blockquote> +<p>baz</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4031 + +. +> bar +> +baz +. +<blockquote> +<p>bar</p> +</blockquote> +<p>baz</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4047 + +. +> > > foo +bar +. +<blockquote> +<blockquote> +<blockquote> +<p>foo +bar</p> +</blockquote> +</blockquote> +</blockquote> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4062 + +. +>>> foo +> bar +>>baz +. +<blockquote> +<blockquote> +<blockquote> +<p>foo +bar +baz</p> +</blockquote> +</blockquote> +</blockquote> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4084 + +. +> code + +> not code +. +<blockquote> +<pre><code>code +</code></pre> +</blockquote> +<blockquote> +<p>not code</p> +</blockquote> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4138 + +. +A paragraph +with two lines. + + indented code + +> A block quote. +. +<p>A paragraph +with two lines.</p> +<pre><code>indented code +</code></pre> +<blockquote> +<p>A block quote.</p> +</blockquote> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4160 + +. +1. A paragraph + with two lines. + + indented code + + > A block quote. +. +<ol> +<li> +<p>A paragraph +with two lines.</p> +<pre><code>indented code +</code></pre> +<blockquote> +<p>A block quote.</p> +</blockquote> +</li> +</ol> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4193 + +. +- one + + two +. +<ul> +<li>one</li> +</ul> +<p>two</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4205 + +. +- one + + two +. +<ul> +<li> +<p>one</p> +<p>two</p> +</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4219 + +. + - one + + two +. +<ul> +<li>one</li> +</ul> +<pre><code> two +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4232 + +. + - one + + two +. +<ul> +<li> +<p>one</p> +<p>two</p> +</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4254 + +. + > > 1. one +>> +>> two +. +<blockquote> +<blockquote> +<ol> +<li> +<p>one</p> +<p>two</p> +</li> +</ol> +</blockquote> +</blockquote> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4281 + +. +>>- one +>> + > > two +. +<blockquote> +<blockquote> +<ul> +<li>one</li> +</ul> +<p>two</p> +</blockquote> +</blockquote> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4300 + +. +-one + +2.two +. +<p>-one</p> +<p>2.two</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4313 + +. +- foo + + + bar +. +<ul> +<li> +<p>foo</p> +<p>bar</p> +</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4330 + +. +1. foo + + ``` + bar + ``` + + baz + + > bam +. +<ol> +<li> +<p>foo</p> +<pre><code>bar +</code></pre> +<p>baz</p> +<blockquote> +<p>bam</p> +</blockquote> +</li> +</ol> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4358 + +. +- Foo + + bar + + + baz +. +<ul> +<li> +<p>Foo</p> +<pre><code>bar + + +baz +</code></pre> +</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4380 + +. +123456789. ok +. +<ol start="123456789"> +<li>ok</li> +</ol> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4389 + +. +1234567890. not ok +. +<p>1234567890. not ok</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4398 + +. +0. ok +. +<ol start="0"> +<li>ok</li> +</ol> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4407 + +. +003. ok +. +<ol start="3"> +<li>ok</li> +</ol> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4418 + +. +-1. not ok +. +<p>-1. not ok</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4441 + +. +- foo + + bar +. +<ul> +<li> +<p>foo</p> +<pre><code>bar +</code></pre> +</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4458 + +. + 10. foo + + bar +. +<ol start="10"> +<li> +<p>foo</p> +<pre><code>bar +</code></pre> +</li> +</ol> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4477 + +. + indented code + +paragraph + + more code +. +<pre><code>indented code +</code></pre> +<p>paragraph</p> +<pre><code>more code +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4492 + +. +1. indented code + + paragraph + + more code +. +<ol> +<li> +<pre><code>indented code +</code></pre> +<p>paragraph</p> +<pre><code>more code +</code></pre> +</li> +</ol> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4514 + +. +1. indented code + + paragraph + + more code +. +<ol> +<li> +<pre><code> indented code +</code></pre> +<p>paragraph</p> +<pre><code>more code +</code></pre> +</li> +</ol> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4541 + +. + foo + +bar +. +<p>foo</p> +<p>bar</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4551 + +. +- foo + + bar +. +<ul> +<li>foo</li> +</ul> +<p>bar</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4568 + +. +- foo + + bar +. +<ul> +<li> +<p>foo</p> +<p>bar</p> +</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4595 + +. +- + foo +- + ``` + bar + ``` +- + baz +. +<ul> +<li>foo</li> +<li> +<pre><code>bar +</code></pre> +</li> +<li> +<pre><code>baz +</code></pre> +</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4621 + +. +- + foo +. +<ul> +<li>foo</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4635 + +. +- + + foo +. +<ul> +<li></li> +</ul> +<p>foo</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4649 + +. +- foo +- +- bar +. +<ul> +<li>foo</li> +<li></li> +<li>bar</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4664 + +. +- foo +- +- bar +. +<ul> +<li>foo</li> +<li></li> +<li>bar</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4679 + +. +1. foo +2. +3. bar +. +<ol> +<li>foo</li> +<li></li> +<li>bar</li> +</ol> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4694 + +. +* +. +<ul> +<li></li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4704 + +. +foo +* + +foo +1. +. +<p>foo +*</p> +<p>foo +1.</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4726 + +. + 1. A paragraph + with two lines. + + indented code + + > A block quote. +. +<ol> +<li> +<p>A paragraph +with two lines.</p> +<pre><code>indented code +</code></pre> +<blockquote> +<p>A block quote.</p> +</blockquote> +</li> +</ol> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4750 + +. + 1. A paragraph + with two lines. + + indented code + + > A block quote. +. +<ol> +<li> +<p>A paragraph +with two lines.</p> +<pre><code>indented code +</code></pre> +<blockquote> +<p>A block quote.</p> +</blockquote> +</li> +</ol> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4774 + +. + 1. A paragraph + with two lines. + + indented code + + > A block quote. +. +<ol> +<li> +<p>A paragraph +with two lines.</p> +<pre><code>indented code +</code></pre> +<blockquote> +<p>A block quote.</p> +</blockquote> +</li> +</ol> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4798 + +. + 1. A paragraph + with two lines. + + indented code + + > A block quote. +. +<pre><code>1. A paragraph + with two lines. + + indented code + + > A block quote. +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4828 + +. + 1. A paragraph +with two lines. + + indented code + + > A block quote. +. +<ol> +<li> +<p>A paragraph +with two lines.</p> +<pre><code>indented code +</code></pre> +<blockquote> +<p>A block quote.</p> +</blockquote> +</li> +</ol> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4852 + +. + 1. A paragraph + with two lines. +. +<ol> +<li>A paragraph +with two lines.</li> +</ol> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4865 + +. +> 1. > Blockquote +continued here. +. +<blockquote> +<ol> +<li> +<blockquote> +<p>Blockquote +continued here.</p> +</blockquote> +</li> +</ol> +</blockquote> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4882 + +. +> 1. > Blockquote +> continued here. +. +<blockquote> +<ol> +<li> +<blockquote> +<p>Blockquote +continued here.</p> +</blockquote> +</li> +</ol> +</blockquote> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4910 + +. +- foo + - bar + - baz + - boo +. +<ul> +<li>foo +<ul> +<li>bar +<ul> +<li>baz +<ul> +<li>boo</li> +</ul> +</li> +</ul> +</li> +</ul> +</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4936 + +. +- foo + - bar + - baz + - boo +. +<ul> +<li>foo</li> +<li>bar</li> +<li>baz</li> +<li>boo</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4953 + +. +10) foo + - bar +. +<ol start="10"> +<li>foo +<ul> +<li>bar</li> +</ul> +</li> +</ol> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4969 + +. +10) foo + - bar +. +<ol start="10"> +<li>foo</li> +</ol> +<ul> +<li>bar</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4984 + +. +- - foo +. +<ul> +<li> +<ul> +<li>foo</li> +</ul> +</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 4997 + +. +1. - 2. foo +. +<ol> +<li> +<ul> +<li> +<ol start="2"> +<li>foo</li> +</ol> +</li> +</ul> +</li> +</ol> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5016 + +. +- # Foo +- Bar + --- + baz +. +<ul> +<li> +<h1>Foo</h1> +</li> +<li> +<h2>Bar</h2> +baz</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5252 + +. +- foo +- bar ++ baz +. +<ul> +<li>foo</li> +<li>bar</li> +</ul> +<ul> +<li>baz</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5267 + +. +1. foo +2. bar +3) baz +. +<ol> +<li>foo</li> +<li>bar</li> +</ol> +<ol start="3"> +<li>baz</li> +</ol> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5286 + +. +Foo +- bar +- baz +. +<p>Foo</p> +<ul> +<li>bar</li> +<li>baz</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5363 + +. +The number of windows in my house is +14. The number of doors is 6. +. +<p>The number of windows in my house is +14. The number of doors is 6.</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5373 + +. +The number of windows in my house is +1. The number of doors is 6. +. +<p>The number of windows in my house is</p> +<ol> +<li>The number of doors is 6.</li> +</ol> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5387 + +. +- foo + +- bar + + +- baz +. +<ul> +<li> +<p>foo</p> +</li> +<li> +<p>bar</p> +</li> +<li> +<p>baz</p> +</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5408 + +. +- foo + - bar + - baz + + + bim +. +<ul> +<li>foo +<ul> +<li>bar +<ul> +<li> +<p>baz</p> +<p>bim</p> +</li> +</ul> +</li> +</ul> +</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5438 + +. +- foo +- bar + +<!-- --> + +- baz +- bim +. +<ul> +<li>foo</li> +<li>bar</li> +</ul> +<!-- --> +<ul> +<li>baz</li> +<li>bim</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5459 + +. +- foo + + notcode + +- foo + +<!-- --> + + code +. +<ul> +<li> +<p>foo</p> +<p>notcode</p> +</li> +<li> +<p>foo</p> +</li> +</ul> +<!-- --> +<pre><code>code +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5490 + +. +- a + - b + - c + - d + - e + - f +- g +. +<ul> +<li>a</li> +<li>b</li> +<li>c</li> +<li>d</li> +<li>e</li> +<li>f</li> +<li>g</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5511 + +. +1. a + + 2. b + + 3. c +. +<ol> +<li> +<p>a</p> +</li> +<li> +<p>b</p> +</li> +<li> +<p>c</p> +</li> +</ol> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5535 + +. +- a + - b + - c + - d + - e +. +<ul> +<li>a</li> +<li>b</li> +<li>c</li> +<li>d +- e</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5555 + +. +1. a + + 2. b + + 3. c +. +<ol> +<li> +<p>a</p> +</li> +<li> +<p>b</p> +</li> +</ol> +<pre><code>3. c +</code></pre> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5578 + +. +- a +- b + +- c +. +<ul> +<li> +<p>a</p> +</li> +<li> +<p>b</p> +</li> +<li> +<p>c</p> +</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5600 + +. +* a +* + +* c +. +<ul> +<li> +<p>a</p> +</li> +<li></li> +<li> +<p>c</p> +</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5622 + +. +- a +- b + + c +- d +. +<ul> +<li> +<p>a</p> +</li> +<li> +<p>b</p> +<p>c</p> +</li> +<li> +<p>d</p> +</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5644 + +. +- a +- b + + [ref]: /url +- d +. +<ul> +<li> +<p>a</p> +</li> +<li> +<p>b</p> +</li> +<li> +<p>d</p> +</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5667 + +. +- a +- ``` + b + + + ``` +- c +. +<ul> +<li>a</li> +<li> +<pre><code>b + + +</code></pre> +</li> +<li>c</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5693 + +. +- a + - b + + c +- d +. +<ul> +<li>a +<ul> +<li> +<p>b</p> +<p>c</p> +</li> +</ul> +</li> +<li>d</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5717 + +. +* a + > b + > +* c +. +<ul> +<li>a +<blockquote> +<p>b</p> +</blockquote> +</li> +<li>c</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5737 + +. +- a + > b + ``` + c + ``` +- d +. +<ul> +<li>a +<blockquote> +<p>b</p> +</blockquote> +<pre><code>c +</code></pre> +</li> +<li>d</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5760 + +. +- a +. +<ul> +<li>a</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5769 + +. +- a + - b +. +<ul> +<li>a +<ul> +<li>b</li> +</ul> +</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5786 + +. +1. ``` + foo + ``` + + bar +. +<ol> +<li> +<pre><code>foo +</code></pre> +<p>bar</p> +</li> +</ol> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5805 + +. +* foo + * bar + + baz +. +<ul> +<li> +<p>foo</p> +<ul> +<li>bar</li> +</ul> +<p>baz</p> +</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5823 + +. +- a + - b + - c + +- d + - e + - f +. +<ul> +<li> +<p>a</p> +<ul> +<li>b</li> +<li>c</li> +</ul> +</li> +<li> +<p>d</p> +<ul> +<li>e</li> +<li>f</li> +</ul> +</li> +</ul> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5857 + +. +`hi`lo` +. +<p><code>hi</code>lo`</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5889 + +. +`foo` +. +<p><code>foo</code></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5900 + +. +`` foo ` bar `` +. +<p><code>foo ` bar</code></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5910 + +. +` `` ` +. +<p><code>``</code></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5918 + +. +` `` ` +. +<p><code> `` </code></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5927 + +. +` a` +. +<p><code> a</code></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5936 + +. +` b ` +. +<p><code> b </code></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5944 + +. +` ` +` ` +. +<p><code> </code> +<code> </code></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5955 + +. +`` +foo +bar +baz +`` +. +<p><code>foo bar baz</code></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5965 + +. +`` +foo +`` +. +<p><code>foo </code></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5976 + +. +`foo bar +baz` +. +<p><code>foo bar baz</code></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 5993 + +. +`foo\`bar` +. +<p><code>foo\</code>bar`</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6004 + +. +``foo`bar`` +. +<p><code>foo`bar</code></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6010 + +. +` foo `` bar ` +. +<p><code>foo `` bar</code></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6022 + +. +*foo`*` +. +<p>*foo<code>*</code></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6031 + +. +[not a `link](/foo`) +. +<p>[not a <code>link](/foo</code>)</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6041 + +. +`<a href="`">` +. +<p><code><a href="</code>">`</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6050 + +. +<a href="`">` +. +<p><a href="`">`</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6059 + +. +`<http://foo.bar.`baz>` +. +<p><code><http://foo.bar.</code>baz>`</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6068 + +. +<http://foo.bar.`baz>` +. +<p><a href="http://foo.bar.%60baz">http://foo.bar.`baz</a>`</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6078 + +. +```foo`` +. +<p>```foo``</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6085 + +. +`foo +. +<p>`foo</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6094 + +. +`foo``bar`` +. +<p>`foo<code>bar</code></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6311 + +. +*foo bar* +. +<p><em>foo bar</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6321 + +. +a * foo bar* +. +<p>a * foo bar*</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6332 + +. +a*"foo"* +. +<p>a*"foo"*</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6341 + +. +* a * +. +<p>* a *</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6350 + +. +foo*bar* +. +<p>foo<em>bar</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6357 + +. +5*6*78 +. +<p>5<em>6</em>78</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6366 + +. +_foo bar_ +. +<p><em>foo bar</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6376 + +. +_ foo bar_ +. +<p>_ foo bar_</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6386 + +. +a_"foo"_ +. +<p>a_"foo"_</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6395 + +. +foo_bar_ +. +<p>foo_bar_</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6402 + +. +5_6_78 +. +<p>5_6_78</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6409 + +. +пристаням_стремятся_ +. +<p>пристаням_стремятся_</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6419 + +. +aa_"bb"_cc +. +<p>aa_"bb"_cc</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6430 + +. +foo-_(bar)_ +. +<p>foo-<em>(bar)</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6442 + +. +_foo* +. +<p>_foo*</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6452 + +. +*foo bar * +. +<p>*foo bar *</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6461 + +. +*foo bar +* +. +<p>*foo bar +*</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6474 + +. +*(*foo) +. +<p>*(*foo)</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6484 + +. +*(*foo*)* +. +<p><em>(<em>foo</em>)</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6493 + +. +*foo*bar +. +<p><em>foo</em>bar</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6506 + +. +_foo bar _ +. +<p>_foo bar _</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6516 + +. +_(_foo) +. +<p>_(_foo)</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6525 + +. +_(_foo_)_ +. +<p><em>(<em>foo</em>)</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6534 + +. +_foo_bar +. +<p>_foo_bar</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6541 + +. +_пристаням_стремятся +. +<p>_пристаням_стремятся</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6548 + +. +_foo_bar_baz_ +. +<p><em>foo_bar_baz</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6559 + +. +_(bar)_. +. +<p><em>(bar)</em>.</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6568 + +. +**foo bar** +. +<p><strong>foo bar</strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6578 + +. +** foo bar** +. +<p>** foo bar**</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6589 + +. +a**"foo"** +. +<p>a**"foo"**</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6598 + +. +foo**bar** +. +<p>foo<strong>bar</strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6607 + +. +__foo bar__ +. +<p><strong>foo bar</strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6617 + +. +__ foo bar__ +. +<p>__ foo bar__</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6625 + +. +__ +foo bar__ +. +<p>__ +foo bar__</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6637 + +. +a__"foo"__ +. +<p>a__"foo"__</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6646 + +. +foo__bar__ +. +<p>foo__bar__</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6653 + +. +5__6__78 +. +<p>5__6__78</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6660 + +. +пристаням__стремятся__ +. +<p>пристаням__стремятся__</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6667 + +. +__foo, __bar__, baz__ +. +<p><strong>foo, <strong>bar</strong>, baz</strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6678 + +. +foo-__(bar)__ +. +<p>foo-<strong>(bar)</strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6691 + +. +**foo bar ** +. +<p>**foo bar **</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6704 + +. +**(**foo) +. +<p>**(**foo)</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6714 + +. +*(**foo**)* +. +<p><em>(<strong>foo</strong>)</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6721 + +. +**Gomphocarpus (*Gomphocarpus physocarpus*, syn. +*Asclepias physocarpa*)** +. +<p><strong>Gomphocarpus (<em>Gomphocarpus physocarpus</em>, syn. +<em>Asclepias physocarpa</em>)</strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6730 + +. +**foo "*bar*" foo** +. +<p><strong>foo "<em>bar</em>" foo</strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6739 + +. +**foo**bar +. +<p><strong>foo</strong>bar</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6751 + +. +__foo bar __ +. +<p>__foo bar __</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6761 + +. +__(__foo) +. +<p>__(__foo)</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6771 + +. +_(__foo__)_ +. +<p><em>(<strong>foo</strong>)</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6780 + +. +__foo__bar +. +<p>__foo__bar</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6787 + +. +__пристаням__стремятся +. +<p>__пристаням__стремятся</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6794 + +. +__foo__bar__baz__ +. +<p><strong>foo__bar__baz</strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6805 + +. +__(bar)__. +. +<p><strong>(bar)</strong>.</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6817 + +. +*foo [bar](/url)* +. +<p><em>foo <a href="/url">bar</a></em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6824 + +. +*foo +bar* +. +<p><em>foo +bar</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6836 + +. +_foo __bar__ baz_ +. +<p><em>foo <strong>bar</strong> baz</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6843 + +. +_foo _bar_ baz_ +. +<p><em>foo <em>bar</em> baz</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6850 + +. +__foo_ bar_ +. +<p><em><em>foo</em> bar</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6857 + +. +*foo *bar** +. +<p><em>foo <em>bar</em></em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6864 + +. +*foo **bar** baz* +. +<p><em>foo <strong>bar</strong> baz</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6870 + +. +*foo**bar**baz* +. +<p><em>foo<strong>bar</strong>baz</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6894 + +. +*foo**bar* +. +<p><em>foo**bar</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6907 + +. +***foo** bar* +. +<p><em><strong>foo</strong> bar</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6914 + +. +*foo **bar*** +. +<p><em>foo <strong>bar</strong></em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6921 + +. +*foo**bar*** +. +<p><em>foo<strong>bar</strong></em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6932 + +. +foo***bar***baz +. +<p>foo<em><strong>bar</strong></em>baz</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6938 + +. +foo******bar*********baz +. +<p>foo<strong><strong><strong>bar</strong></strong></strong>***baz</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6947 + +. +*foo **bar *baz* bim** bop* +. +<p><em>foo <strong>bar <em>baz</em> bim</strong> bop</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6954 + +. +*foo [*bar*](/url)* +. +<p><em>foo <a href="/url"><em>bar</em></a></em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6963 + +. +** is not an empty emphasis +. +<p>** is not an empty emphasis</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6970 + +. +**** is not an empty strong emphasis +. +<p>**** is not an empty strong emphasis</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6983 + +. +**foo [bar](/url)** +. +<p><strong>foo <a href="/url">bar</a></strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 6990 + +. +**foo +bar** +. +<p><strong>foo +bar</strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7002 + +. +__foo _bar_ baz__ +. +<p><strong>foo <em>bar</em> baz</strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7009 + +. +__foo __bar__ baz__ +. +<p><strong>foo <strong>bar</strong> baz</strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7016 + +. +____foo__ bar__ +. +<p><strong><strong>foo</strong> bar</strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7023 + +. +**foo **bar**** +. +<p><strong>foo <strong>bar</strong></strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7030 + +. +**foo *bar* baz** +. +<p><strong>foo <em>bar</em> baz</strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7037 + +. +**foo*bar*baz** +. +<p><strong>foo<em>bar</em>baz</strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7044 + +. +***foo* bar** +. +<p><strong><em>foo</em> bar</strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7051 + +. +**foo *bar*** +. +<p><strong>foo <em>bar</em></strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7060 + +. +**foo *bar **baz** +bim* bop** +. +<p><strong>foo <em>bar <strong>baz</strong> +bim</em> bop</strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7069 + +. +**foo [*bar*](/url)** +. +<p><strong>foo <a href="/url"><em>bar</em></a></strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7078 + +. +__ is not an empty emphasis +. +<p>__ is not an empty emphasis</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7085 + +. +____ is not an empty strong emphasis +. +<p>____ is not an empty strong emphasis</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7095 + +. +foo *** +. +<p>foo ***</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7102 + +. +foo *\** +. +<p>foo <em>*</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7109 + +. +foo *_* +. +<p>foo <em>_</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7116 + +. +foo ***** +. +<p>foo *****</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7123 + +. +foo **\*** +. +<p>foo <strong>*</strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7130 + +. +foo **_** +. +<p>foo <strong>_</strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7141 + +. +**foo* +. +<p>*<em>foo</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7148 + +. +*foo** +. +<p><em>foo</em>*</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7155 + +. +***foo** +. +<p>*<strong>foo</strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7162 + +. +****foo* +. +<p>***<em>foo</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7169 + +. +**foo*** +. +<p><strong>foo</strong>*</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7176 + +. +*foo**** +. +<p><em>foo</em>***</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7186 + +. +foo ___ +. +<p>foo ___</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7193 + +. +foo _\__ +. +<p>foo <em>_</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7200 + +. +foo _*_ +. +<p>foo <em>*</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7207 + +. +foo _____ +. +<p>foo _____</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7214 + +. +foo __\___ +. +<p>foo <strong>_</strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7221 + +. +foo __*__ +. +<p>foo <strong>*</strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7228 + +. +__foo_ +. +<p>_<em>foo</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7239 + +. +_foo__ +. +<p><em>foo</em>_</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7246 + +. +___foo__ +. +<p>_<strong>foo</strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7253 + +. +____foo_ +. +<p>___<em>foo</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7260 + +. +__foo___ +. +<p><strong>foo</strong>_</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7267 + +. +_foo____ +. +<p><em>foo</em>___</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7277 + +. +**foo** +. +<p><strong>foo</strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7284 + +. +*_foo_* +. +<p><em><em>foo</em></em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7291 + +. +__foo__ +. +<p><strong>foo</strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7298 + +. +_*foo*_ +. +<p><em><em>foo</em></em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7308 + +. +****foo**** +. +<p><strong><strong>foo</strong></strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7315 + +. +____foo____ +. +<p><strong><strong>foo</strong></strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7326 + +. +******foo****** +. +<p><strong><strong><strong>foo</strong></strong></strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7335 + +. +***foo*** +. +<p><em><strong>foo</strong></em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7342 + +. +_____foo_____ +. +<p><em><strong><strong>foo</strong></strong></em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7351 + +. +*foo _bar* baz_ +. +<p><em>foo _bar</em> baz_</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7358 + +. +*foo __bar *baz bim__ bam* +. +<p><em>foo <strong>bar *baz bim</strong> bam</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7367 + +. +**foo **bar baz** +. +<p>**foo <strong>bar baz</strong></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7374 + +. +*foo *bar baz* +. +<p>*foo <em>bar baz</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7383 + +. +*[bar*](/url) +. +<p>*<a href="/url">bar*</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7390 + +. +_foo [bar_](/url) +. +<p>_foo <a href="/url">bar_</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7397 + +. +*<img src="foo" title="*"/> +. +<p>*<img src="foo" title="*"/></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7404 + +. +**<a href="**"> +. +<p>**<a href="**"></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7411 + +. +__<a href="__"> +. +<p>__<a href="__"></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7418 + +. +*a `*`* +. +<p><em>a <code>*</code></em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7425 + +. +_a `_`_ +. +<p><em>a <code>_</code></em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7432 + +. +**a<http://foo.bar/?q=**> +. +<p>**a<a href="http://foo.bar/?q=**">http://foo.bar/?q=**</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7439 + +. +__a<http://foo.bar/?q=__> +. +<p>__a<a href="http://foo.bar/?q=__">http://foo.bar/?q=__</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7527 + +. +[link](/uri "title") +. +<p><a href="/uri" title="title">link</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7537 + +. +[link](/uri) +. +<p><a href="/uri">link</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7543 + +. +[](./target.md) +. +<p><a href="./target.md"></a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7550 + +. +[link]() +. +<p><a href="">link</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7557 + +. +[link](<>) +. +<p><a href="">link</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7564 + +. +[]() +. +<p><a href=""></a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7573 + +. +[link](/my uri) +. +<p>[link](/my uri)</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7579 + +. +[link](</my uri>) +. +<p><a href="/my%20uri">link</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7588 + +. +[link](foo +bar) +. +<p>[link](foo +bar)</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7596 + +. +[link](<foo +bar>) +. +<p>[link](<foo +bar>)</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7607 + +. +[a](<b)c>) +. +<p><a href="b)c">a</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7615 + +. +[link](<foo\>) +. +<p>[link](<foo>)</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7624 + +. +[a](<b)c +[a](<b)c> +[a](<b>c) +. +<p>[a](<b)c +[a](<b)c> +[a](<b>c)</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7636 + +. +[link](\(foo\)) +. +<p><a href="(foo)">link</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7645 + +. +[link](foo(and(bar))) +. +<p><a href="foo(and(bar))">link</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7654 + +. +[link](foo(and(bar)) +. +<p>[link](foo(and(bar))</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7661 + +. +[link](foo\(and\(bar\)) +. +<p><a href="foo(and(bar)">link</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7668 + +. +[link](<foo(and(bar)>) +. +<p><a href="foo(and(bar)">link</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7678 + +. +[link](foo\)\:) +. +<p><a href="foo):">link</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7687 + +. +[link](#fragment) + +[link](http://example.com#fragment) + +[link](http://example.com?foo=3#frag) +. +<p><a href="#fragment">link</a></p> +<p><a href="http://example.com#fragment">link</a></p> +<p><a href="http://example.com?foo=3#frag">link</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7703 + +. +[link](foo\bar) +. +<p><a href="foo%5Cbar">link</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7719 + +. +[link](foo%20bä) +. +<p><a href="foo%20b%C3%A4">link</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7730 + +. +[link]("title") +. +<p><a href="%22title%22">link</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7739 + +. +[link](/url "title") +[link](/url 'title') +[link](/url (title)) +. +<p><a href="/url" title="title">link</a> +<a href="/url" title="title">link</a> +<a href="/url" title="title">link</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7753 + +. +[link](/url "title \""") +. +<p><a href="/url" title="title """>link</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7764 + +. +[link](/url "title") +. +<p><a href="/url%C2%A0%22title%22">link</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7773 + +. +[link](/url "title "and" title") +. +<p>[link](/url "title "and" title")</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7782 + +. +[link](/url 'title "and" title') +. +<p><a href="/url" title="title "and" title">link</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7807 + +. +[link]( /uri + "title" ) +. +<p><a href="/uri" title="title">link</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7818 + +. +[link] (/uri) +. +<p>[link] (/uri)</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7828 + +. +[link [foo [bar]]](/uri) +. +<p><a href="/uri">link [foo [bar]]</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7835 + +. +[link] bar](/uri) +. +<p>[link] bar](/uri)</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7842 + +. +[link [bar](/uri) +. +<p>[link <a href="/uri">bar</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7849 + +. +[link \[bar](/uri) +. +<p><a href="/uri">link [bar</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7858 + +. +[link *foo **bar** `#`*](/uri) +. +<p><a href="/uri">link <em>foo <strong>bar</strong> <code>#</code></em></a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7865 + +. +[![moon](moon.jpg)](/uri) +. +<p><a href="/uri"><img src="moon.jpg" alt="moon" /></a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7874 + +. +[foo [bar](/uri)](/uri) +. +<p>[foo <a href="/uri">bar</a>](/uri)</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7881 + +. +[foo *[bar [baz](/uri)](/uri)*](/uri) +. +<p>[foo <em>[bar <a href="/uri">baz</a>](/uri)</em>](/uri)</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7888 + +. +![[[foo](uri1)](uri2)](uri3) +. +<p><img src="uri3" alt="[foo](uri2)" /></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7898 + +. +*[foo*](/uri) +. +<p>*<a href="/uri">foo*</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7905 + +. +[foo *bar](baz*) +. +<p><a href="baz*">foo *bar</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7915 + +. +*foo [bar* baz] +. +<p><em>foo [bar</em> baz]</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7925 + +. +[foo <bar attr="](baz)"> +. +<p>[foo <bar attr="](baz)"></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7932 + +. +[foo`](/uri)` +. +<p>[foo<code>](/uri)</code></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7939 + +. +[foo<http://example.com/?search=](uri)> +. +<p>[foo<a href="http://example.com/?search=%5D(uri)">http://example.com/?search=](uri)</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7977 + +. +[foo][bar] + +[bar]: /url "title" +. +<p><a href="/url" title="title">foo</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 7992 + +. +[link [foo [bar]]][ref] + +[ref]: /uri +. +<p><a href="/uri">link [foo [bar]]</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8001 + +. +[link \[bar][ref] + +[ref]: /uri +. +<p><a href="/uri">link [bar</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8012 + +. +[link *foo **bar** `#`*][ref] + +[ref]: /uri +. +<p><a href="/uri">link <em>foo <strong>bar</strong> <code>#</code></em></a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8021 + +. +[![moon](moon.jpg)][ref] + +[ref]: /uri +. +<p><a href="/uri"><img src="moon.jpg" alt="moon" /></a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8032 + +. +[foo [bar](/uri)][ref] + +[ref]: /uri +. +<p>[foo <a href="/uri">bar</a>]<a href="/uri">ref</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8041 + +. +[foo *bar [baz][ref]*][ref] + +[ref]: /uri +. +<p>[foo <em>bar <a href="/uri">baz</a></em>]<a href="/uri">ref</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8056 + +. +*[foo*][ref] + +[ref]: /uri +. +<p>*<a href="/uri">foo*</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8065 + +. +[foo *bar][ref]* + +[ref]: /uri +. +<p><a href="/uri">foo *bar</a>*</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8077 + +. +[foo <bar attr="][ref]"> + +[ref]: /uri +. +<p>[foo <bar attr="][ref]"></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8086 + +. +[foo`][ref]` + +[ref]: /uri +. +<p>[foo<code>][ref]</code></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8095 + +. +[foo<http://example.com/?search=][ref]> + +[ref]: /uri +. +<p>[foo<a href="http://example.com/?search=%5D%5Bref%5D">http://example.com/?search=][ref]</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8106 + +. +[foo][BaR] + +[bar]: /url "title" +. +<p><a href="/url" title="title">foo</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8117 + +. +[ẞ] + +[SS]: /url +. +<p><a href="/url">ẞ</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8129 + +. +[Foo + bar]: /url + +[Baz][Foo bar] +. +<p><a href="/url">Baz</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8142 + +. +[foo] [bar] + +[bar]: /url "title" +. +<p>[foo] <a href="/url" title="title">bar</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8151 + +. +[foo] +[bar] + +[bar]: /url "title" +. +<p>[foo] +<a href="/url" title="title">bar</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8192 + +. +[foo]: /url1 + +[foo]: /url2 + +[bar][foo] +. +<p><a href="/url1">bar</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8207 + +. +[bar][foo\!] + +[foo!]: /url +. +<p>[bar][foo!]</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8219 + +. +[foo][ref[] + +[ref[]: /uri +. +<p>[foo][ref[]</p> +<p>[ref[]: /uri</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8229 + +. +[foo][ref[bar]] + +[ref[bar]]: /uri +. +<p>[foo][ref[bar]]</p> +<p>[ref[bar]]: /uri</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8239 + +. +[[[foo]]] + +[[[foo]]]: /url +. +<p>[[[foo]]]</p> +<p>[[[foo]]]: /url</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8249 + +. +[foo][ref\[] + +[ref\[]: /uri +. +<p><a href="/uri">foo</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8260 + +. +[bar\\]: /uri + +[bar\\] +. +<p><a href="/uri">bar\</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8272 + +. +[] + +[]: /uri +. +<p>[]</p> +<p>[]: /uri</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8282 + +. +[ + ] + +[ + ]: /uri +. +<p>[ +]</p> +<p>[ +]: /uri</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8305 + +. +[foo][] + +[foo]: /url "title" +. +<p><a href="/url" title="title">foo</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8314 + +. +[*foo* bar][] + +[*foo* bar]: /url "title" +. +<p><a href="/url" title="title"><em>foo</em> bar</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8325 + +. +[Foo][] + +[foo]: /url "title" +. +<p><a href="/url" title="title">Foo</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8338 + +. +[foo] +[] + +[foo]: /url "title" +. +<p><a href="/url" title="title">foo</a> +[]</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8358 + +. +[foo] + +[foo]: /url "title" +. +<p><a href="/url" title="title">foo</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8367 + +. +[*foo* bar] + +[*foo* bar]: /url "title" +. +<p><a href="/url" title="title"><em>foo</em> bar</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8376 + +. +[[*foo* bar]] + +[*foo* bar]: /url "title" +. +<p>[<a href="/url" title="title"><em>foo</em> bar</a>]</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8385 + +. +[[bar [foo] + +[foo]: /url +. +<p>[[bar <a href="/url">foo</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8396 + +. +[Foo] + +[foo]: /url "title" +. +<p><a href="/url" title="title">Foo</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8407 + +. +[foo] bar + +[foo]: /url +. +<p><a href="/url">foo</a> bar</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8419 + +. +\[foo] + +[foo]: /url "title" +. +<p>[foo]</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8431 + +. +[foo*]: /url + +*[foo*] +. +<p>*<a href="/url">foo*</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8443 + +. +[foo][bar] + +[foo]: /url1 +[bar]: /url2 +. +<p><a href="/url2">foo</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8452 + +. +[foo][] + +[foo]: /url1 +. +<p><a href="/url1">foo</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8462 + +. +[foo]() + +[foo]: /url1 +. +<p><a href="">foo</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8470 + +. +[foo](not a link) + +[foo]: /url1 +. +<p><a href="/url1">foo</a>(not a link)</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8481 + +. +[foo][bar][baz] + +[baz]: /url +. +<p>[foo]<a href="/url">bar</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8493 + +. +[foo][bar][baz] + +[baz]: /url1 +[bar]: /url2 +. +<p><a href="/url2">foo</a><a href="/url1">baz</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8506 + +. +[foo][bar][baz] + +[baz]: /url1 +[foo]: /url2 +. +<p>[foo]<a href="/url1">bar</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8529 + +. +![foo](/url "title") +. +<p><img src="/url" alt="foo" title="title" /></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8536 + +. +![foo *bar*] + +[foo *bar*]: train.jpg "train & tracks" +. +<p><img src="train.jpg" alt="foo bar" title="train & tracks" /></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8545 + +. +![foo ![bar](/url)](/url2) +. +<p><img src="/url2" alt="foo bar" /></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8552 + +. +![foo [bar](/url)](/url2) +. +<p><img src="/url2" alt="foo bar" /></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8566 + +. +![foo *bar*][] + +[foo *bar*]: train.jpg "train & tracks" +. +<p><img src="train.jpg" alt="foo bar" title="train & tracks" /></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8575 + +. +![foo *bar*][foobar] + +[FOOBAR]: train.jpg "train & tracks" +. +<p><img src="train.jpg" alt="foo bar" title="train & tracks" /></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8584 + +. +![foo](train.jpg) +. +<p><img src="train.jpg" alt="foo" /></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8591 + +. +My ![foo bar](/path/to/train.jpg "title" ) +. +<p>My <img src="/path/to/train.jpg" alt="foo bar" title="title" /></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8598 + +. +![foo](<url>) +. +<p><img src="url" alt="foo" /></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8605 + +. +![](/url) +. +<p><img src="/url" alt="" /></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8614 + +. +![foo][bar] + +[bar]: /url +. +<p><img src="/url" alt="foo" /></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8623 + +. +![foo][bar] + +[BAR]: /url +. +<p><img src="/url" alt="foo" /></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8634 + +. +![foo][] + +[foo]: /url "title" +. +<p><img src="/url" alt="foo" title="title" /></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8643 + +. +![*foo* bar][] + +[*foo* bar]: /url "title" +. +<p><img src="/url" alt="foo bar" title="title" /></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8654 + +. +![Foo][] + +[foo]: /url "title" +. +<p><img src="/url" alt="Foo" title="title" /></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8666 + +. +![foo] +[] + +[foo]: /url "title" +. +<p><img src="/url" alt="foo" title="title" /> +[]</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8679 + +. +![foo] + +[foo]: /url "title" +. +<p><img src="/url" alt="foo" title="title" /></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8688 + +. +![*foo* bar] + +[*foo* bar]: /url "title" +. +<p><img src="/url" alt="foo bar" title="title" /></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8699 + +. +![[foo]] + +[[foo]]: /url "title" +. +<p>![[foo]]</p> +<p>[[foo]]: /url "title"</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8711 + +. +![Foo] + +[foo]: /url "title" +. +<p><img src="/url" alt="Foo" title="title" /></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8723 + +. +!\[foo] + +[foo]: /url "title" +. +<p>![foo]</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8735 + +. +\![foo] + +[foo]: /url "title" +. +<p>!<a href="/url" title="title">foo</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8768 + +. +<http://foo.bar.baz> +. +<p><a href="http://foo.bar.baz">http://foo.bar.baz</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8775 + +. +<http://foo.bar.baz/test?q=hello&id=22&boolean> +. +<p><a href="http://foo.bar.baz/test?q=hello&id=22&boolean">http://foo.bar.baz/test?q=hello&id=22&boolean</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8782 + +. +<irc://foo.bar:2233/baz> +. +<p><a href="irc://foo.bar:2233/baz">irc://foo.bar:2233/baz</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8791 + +. +<MAILTO:FOO@BAR.BAZ> +. +<p><a href="MAILTO:FOO@BAR.BAZ">MAILTO:FOO@BAR.BAZ</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8803 + +. +<a+b+c:d> +. +<p><a href="a+b+c:d">a+b+c:d</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8810 + +. +<made-up-scheme://foo,bar> +. +<p><a href="made-up-scheme://foo,bar">made-up-scheme://foo,bar</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8817 + +. +<http://../> +. +<p><a href="http://../">http://../</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8824 + +. +<localhost:5001/foo> +. +<p><a href="localhost:5001/foo">localhost:5001/foo</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8833 + +. +<http://foo.bar/baz bim> +. +<p><http://foo.bar/baz bim></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8842 + +. +<http://example.com/\[\> +. +<p><a href="http://example.com/%5C%5B%5C">http://example.com/\[\</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8864 + +. +<foo@bar.example.com> +. +<p><a href="mailto:foo@bar.example.com">foo@bar.example.com</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8871 + +. +<foo+special@Bar.baz-bar0.com> +. +<p><a href="mailto:foo+special@Bar.baz-bar0.com">foo+special@Bar.baz-bar0.com</a></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8880 + +. +<foo\+@bar.example.com> +. +<p><foo+@bar.example.com></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8889 + +. +<> +. +<p><></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8896 + +. +< http://foo.bar > +. +<p>< http://foo.bar ></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8903 + +. +<m:abc> +. +<p><m:abc></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8910 + +. +<foo.bar.baz> +. +<p><foo.bar.baz></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8917 + +. +http://example.com +. +<p>http://example.com</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 8924 + +. +foo@bar.example.com +. +<p>foo@bar.example.com</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9005 + +. +<a><bab><c2c> +. +<p><a><bab><c2c></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9014 + +. +<a/><b2/> +. +<p><a/><b2/></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9023 + +. +<a /><b2 +data="foo" > +. +<p><a /><b2 +data="foo" ></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9034 + +. +<a foo="bar" bam = 'baz <em>"</em>' +_boolean zoop:33=zoop:33 /> +. +<p><a foo="bar" bam = 'baz <em>"</em>' +_boolean zoop:33=zoop:33 /></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9045 + +. +Foo <responsive-image src="foo.jpg" /> +. +<p>Foo <responsive-image src="foo.jpg" /></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9054 + +. +<33> <__> +. +<p><33> <__></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9063 + +. +<a h*#ref="hi"> +. +<p><a h*#ref="hi"></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9072 + +. +<a href="hi'> <a href=hi'> +. +<p><a href="hi'> <a href=hi'></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9081 + +. +< a>< +foo><bar/ > +<foo bar=baz +bim!bop /> +. +<p>< a>< +foo><bar/ > +<foo bar=baz +bim!bop /></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9096 + +. +<a href='bar'title=title> +. +<p><a href='bar'title=title></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9105 + +. +</a></foo > +. +<p></a></foo ></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9114 + +. +</a href="foo"> +. +<p></a href="foo"></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9123 + +. +foo <!-- this is a +comment - with hyphen --> +. +<p>foo <!-- this is a +comment - with hyphen --></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9132 + +. +foo <!-- not a comment -- two hyphens --> +. +<p>foo <!-- not a comment -- two hyphens --></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9141 + +. +foo <!--> foo --> + +foo <!-- foo---> +. +<p>foo <!--> foo --></p> +<p>foo <!-- foo---></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9153 + +. +foo <?php echo $a; ?> +. +<p>foo <?php echo $a; ?></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9162 + +. +foo <!ELEMENT br EMPTY> +. +<p>foo <!ELEMENT br EMPTY></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9171 + +. +foo <![CDATA[>&<]]> +. +<p>foo <![CDATA[>&<]]></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9181 + +. +foo <a href="ö"> +. +<p>foo <a href="ö"></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9190 + +. +foo <a href="\*"> +. +<p>foo <a href="\*"></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9197 + +. +<a href="\""> +. +<p><a href="""></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9211 + +. +foo +baz +. +<p>foo<br /> +baz</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9223 + +. +foo\ +baz +. +<p>foo<br /> +baz</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9234 + +. +foo +baz +. +<p>foo<br /> +baz</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9245 + +. +foo + bar +. +<p>foo<br /> +bar</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9254 + +. +foo\ + bar +. +<p>foo<br /> +bar</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9266 + +. +*foo +bar* +. +<p><em>foo<br /> +bar</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9275 + +. +*foo\ +bar* +. +<p><em>foo<br /> +bar</em></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9286 + +. +`code +span` +. +<p><code>code span</code></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9294 + +. +`code\ +span` +. +<p><code>code\ span</code></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9304 + +. +<a href="foo +bar"> +. +<p><a href="foo +bar"></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9313 + +. +<a href="foo\ +bar"> +. +<p><a href="foo\ +bar"></p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9326 + +. +foo\ +. +<p>foo\</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9333 + +. +foo +. +<p>foo</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9340 + +. +### foo\ +. +<h3>foo\</h3> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9347 + +. +### foo +. +<h3>foo</h3> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9362 + +. +foo +baz +. +<p>foo +baz</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9374 + +. +foo + baz +. +<p>foo +baz</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9394 + +. +hello $.;'there +. +<p>hello $.;'there</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9401 + +. +Foo χρῆν +. +<p>Foo χρῆν</p> +. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +src line: 9410 + +. +Multiple spaces +. +<p>Multiple spaces</p> +. + diff --git a/tests/test_port/fixtures/fatal.md b/tests/test_port/fixtures/fatal.md new file mode 100644 index 0000000..7b2afcf --- /dev/null +++ b/tests/test_port/fixtures/fatal.md @@ -0,0 +1,41 @@ +Should not throw exception on invalid chars in URL (`*` not allowed in path) [malformed URI] +. +[foo](<%test>) +. +<p><a href="%25test">foo</a></p> +. + + +Should not throw exception on broken utf-8 sequence in URL [malformed URI] +. +[foo](%C3) +. +<p><a href="%C3">foo</a></p> +. + + +Should not throw exception on broken utf-16 surrogates sequence in URL [malformed URI] +. +[foo](�) +. +<p><a href="&#xD800;">foo</a></p> +. + + +Should not hang comments regexp +. +foo <!--- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -> + +foo <!-------------------------------------------------------------------> +. +<p>foo <!— xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -></p> +<p>foo <!-------------------------------------------------------------------></p> +. + + +Should not hang cdata regexp +. +foo <![CDATA[ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ]> +. +<p>foo <![CDATA[ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ]></p> +. diff --git a/tests/test_port/fixtures/issue-fixes.md b/tests/test_port/fixtures/issue-fixes.md new file mode 100644 index 0000000..0c693b0 --- /dev/null +++ b/tests/test_port/fixtures/issue-fixes.md @@ -0,0 +1,38 @@ +#31 empty lines after certain lists raises exception: +. +> a + +- b + + +. +<blockquote> +<p>a</p> +</blockquote> +<ul> +<li>b</li> +</ul> +. + +#50 blank lines after block quotes +. +> A Block Quote + +> Another Block Quote + + +. +<blockquote> +<p>A Block Quote</p> +</blockquote> +<blockquote> +<p>Another Block Quote</p> +</blockquote> +. + +#80 UnicodeError with codepoints larger than 0xFFFF +. +💬 +. +<p>💬</p> +. diff --git a/tests/test_port/fixtures/linkify.md b/tests/test_port/fixtures/linkify.md new file mode 100644 index 0000000..9edb78f --- /dev/null +++ b/tests/test_port/fixtures/linkify.md @@ -0,0 +1,99 @@ +linkify +. +url http://www.youtube.com/watch?v=5Jt5GEr4AYg. +. +<p>url <a href="http://www.youtube.com/watch?v=5Jt5GEr4AYg">http://www.youtube.com/watch?v=5Jt5GEr4AYg</a>.</p> +. + + +don't touch text in links +. +[https://example.com](https://example.com) +. +<p><a href="https://example.com">https://example.com</a></p> +. + + +don't touch text in autolinks +. +<https://example.com> +. +<p><a href="https://example.com">https://example.com</a></p> +. + + +don't touch text in html <a> tags +. +<a href="https://example.com">https://example.com</a> +. +<p><a href="https://example.com">https://example.com</a></p> +. + + +match links without protocol +. +www.example.org +. +<p><a href="http://www.example.org">www.example.org</a></p> +. + + +emails +. +test@example.com + +mailto:test@example.com +. +<p><a href="mailto:test@example.com">test@example.com</a></p> +<p><a href="mailto:test@example.com">mailto:test@example.com</a></p> +. + + +typorgapher should not break href +. +http://example.com/(c) +. +<p><a href="http://example.com/(c)">http://example.com/(c)</a></p> +. + +before line +. +before +github.com +. +<p>before +<a href="http://github.com">github.com</a></p> +. + +after line +. +github.com +after +. +<p><a href="http://github.com">github.com</a> +after</p> +. + +before after lines +. +before +github.com +after +. +<p>before +<a href="http://github.com">github.com</a> +after</p> +. + +before after lines with blank line +. +before + +github.com + +after +. +<p>before</p> +<p><a href="http://github.com">github.com</a></p> +<p>after</p> +.
\ No newline at end of file diff --git a/tests/test_port/fixtures/normalize.md b/tests/test_port/fixtures/normalize.md new file mode 100644 index 0000000..4a00508 --- /dev/null +++ b/tests/test_port/fixtures/normalize.md @@ -0,0 +1,39 @@ + +Encode link destination, decode text inside it: + +. +<http://example.com/α%CE%B2γ%CE%B4> +. +<p><a href="http://example.com/%CE%B1%CE%B2%CE%B3%CE%B4">http://example.com/αβγδ</a></p> +. + +. +[foo](http://example.com/α%CE%B2γ%CE%B4) +. +<p><a href="http://example.com/%CE%B1%CE%B2%CE%B3%CE%B4">foo</a></p> +. + + +Keep %25 as is because decoding it may break urls, #720 +. +<https://www.google.com/search?q=hello%2E%252Ehello> +. +<p><a href="https://www.google.com/search?q=hello%2E%252Ehello">https://www.google.com/search?q=hello.%252Ehello</a></p> +. + + +Don't encode domains in unknown schemas: + +. +[](skype:γγγ) +. +<p><a href="skype:%CE%B3%CE%B3%CE%B3"></a></p> +. + + +Square brackets are allowed +. +[foo](https://bar]baz.org) +. +<p><a href="https://bar%5Dbaz.org">foo</a></p> +. diff --git a/tests/test_port/fixtures/proto.md b/tests/test_port/fixtures/proto.md new file mode 100644 index 0000000..87fdccf --- /dev/null +++ b/tests/test_port/fixtures/proto.md @@ -0,0 +1,16 @@ +. +[__proto__] + +[__proto__]: blah +. +<p><a href="blah"><strong>proto</strong></a></p> +. + + +. +[hasOwnProperty] + +[hasOwnProperty]: blah +. +<p><a href="blah">hasOwnProperty</a></p> +. diff --git a/tests/test_port/fixtures/punycode.md b/tests/test_port/fixtures/punycode.md new file mode 100644 index 0000000..c726e82 --- /dev/null +++ b/tests/test_port/fixtures/punycode.md @@ -0,0 +1,77 @@ +Should decode punycode: + +. +<http://xn--n3h.net/> +. +<p><a href="http://xn--n3h.net/">http://☃.net/</a></p> +. + +. +<http://☃.net/> +. +<p><a href="http://xn--n3h.net/">http://☃.net/</a></p> +. + +Invalid punycode: + +. +<http://xn--xn.com/> +. +<p><a href="http://xn--xn.com/">http://xn--xn.com/</a></p> +. + +Invalid punycode (non-ascii): + +. +<http://xn--γ.com/> +. +<p><a href="http://xn--xn---emd.com/">http://xn--γ.com/</a></p> +. + +Two slashes should start a domain: + +. +[](//☃.net/) +. +<p><a href="//xn--n3h.net/"></a></p> +. + +Should auto-add protocol to autolinks: + +. +test google.com foo +. +<p>test <a href="http://google.com">google.com</a> foo</p> +. + +Should support IDN in autolinks: + +. +test http://xn--n3h.net/ foo +. +<p>test <a href="http://xn--n3h.net/">http://☃.net/</a> foo</p> +. + +. +test http://☃.net/ foo +. +<p>test <a href="http://xn--n3h.net/">http://☃.net/</a> foo</p> +. + +. +test //xn--n3h.net/ foo +. +<p>test <a href="//xn--n3h.net/">//☃.net/</a> foo</p> +. + +. +test xn--n3h.net foo +. +<p>test <a href="http://xn--n3h.net">☃.net</a> foo</p> +. + +. +test xn--n3h@xn--n3h.net foo +. +<p>test <a href="mailto:xn--n3h@xn--n3h.net">xn--n3h@☃.net</a> foo</p> +. diff --git a/tests/test_port/fixtures/smartquotes.md b/tests/test_port/fixtures/smartquotes.md new file mode 100644 index 0000000..70378b8 --- /dev/null +++ b/tests/test_port/fixtures/smartquotes.md @@ -0,0 +1,166 @@ +Should parse nested quotes: +. +"foo 'bar' baz" + +'foo 'bar' baz' +. +<p>“foo ‘bar’ baz”</p> +<p>‘foo ‘bar’ baz’</p> +. + + +Should not overlap quotes: +. +'foo "bar' baz" +. +<p>‘foo "bar’ baz"</p> +. + + +Should match quotes on the same level: +. +"foo *bar* baz" +. +<p>“foo <em>bar</em> baz”</p> +. + + +Should handle adjacent nested quotes: +. +'"double in single"' + +"'single in double'" +. +<p>‘“double in single”’</p> +<p>“‘single in double’”</p> +. + + + +Should not match quotes on different levels: +. +*"foo* bar" + +"foo *bar"* + +*"foo* bar *baz"* +. +<p><em>"foo</em> bar"</p> +<p>"foo <em>bar"</em></p> +<p><em>"foo</em> bar <em>baz"</em></p> +. + +Smartquotes should not overlap with other tags: +. +*foo "bar* *baz" quux* +. +<p><em>foo "bar</em> <em>baz" quux</em></p> +. + + +Should try and find matching quote in this case: +. +"foo "bar 'baz" +. +<p>"foo “bar 'baz”</p> +. + + +Should not touch 'inches' in quotes: +. +"Monitor 21"" and "Monitor"" +. +<p>“Monitor 21"” and “Monitor”"</p> +. + + +Should render an apostrophe as a rsquo: +. +This isn't and can't be the best approach to implement this... +. +<p>This isn’t and can’t be the best approach to implement this…</p> +. + + +Apostrophe could end the word, that's why original smartypants replaces all of them as rsquo: +. +users' stuff +. +<p>users’ stuff</p> +. + +Quotes between punctuation chars: + +. +"(hai)". +. +<p>“(hai)”.</p> +. + +Quotes at the start/end of the tokens: +. +"*foo* bar" + +"foo *bar*" + +"*foo bar*" +. +<p>“<em>foo</em> bar”</p> +<p>“foo <em>bar</em>”</p> +<p>“<em>foo bar</em>”</p> +. + +Should treat softbreak as a space: +. +"this" +and "that". + +"this" and +"that". +. +<p>“this” +and “that”.</p> +<p>“this” and +“that”.</p> +. + +Should treat hardbreak as a space: +. +"this"\ +and "that". + +"this" and\ +"that". +. +<p>“this”<br /> +and “that”.</p> +<p>“this” and<br /> +“that”.</p> +. + +Should allow quotes adjacent to other punctuation characters, #643: +. +The dog---"'man's' best friend" +. +<p>The dog—“‘man’s’ best friend”</p> +. + +Should parse quotes adjacent to code block, #677: +. +"test `code`" + +"`code` test" +. +<p>“test <code>code</code>”</p> +<p>“<code>code</code> test”</p> +. + +Should parse quotes adjacent to inline html, #677: +. +"test <br>" + +"<br> test" +. +<p>“test <br>”</p> +<p>“<br> test”</p> +.
\ No newline at end of file diff --git a/tests/test_port/fixtures/strikethrough.md b/tests/test_port/fixtures/strikethrough.md new file mode 100644 index 0000000..ca15b6f --- /dev/null +++ b/tests/test_port/fixtures/strikethrough.md @@ -0,0 +1,136 @@ +. +~~Strikeout~~ +. +<p><s>Strikeout</s></p> +. + +. +x ~~~~foo~~ bar~~ +. +<p>x <s><s>foo</s> bar</s></p> +. + +. +x ~~foo ~~bar~~~~ +. +<p>x <s>foo <s>bar</s></s></p> +. + +. +x ~~~~foo~~~~ +. +<p>x <s><s>foo</s></s></p> +. + +. +x ~~a ~~foo~~~~~~~~~~~bar~~ b~~ + +x ~~a ~~foo~~~~~~~~~~~~bar~~ b~~ +. +<p>x <s>a <s>foo</s></s>~~~<s><s>bar</s> b</s></p> +<p>x <s>a <s>foo</s></s>~~~~<s><s>bar</s> b</s></p> +. + + +Strikeouts have the same priority as emphases: +. +**~~test**~~ + +~~**test~~** +. +<p><strong>~~test</strong>~~</p> +<p><s>**test</s>**</p> +. + + +Strikeouts have the same priority as emphases with respect to links: +. +[~~link]()~~ + +~~[link~~]() +. +<p><a href="">~~link</a>~~</p> +<p>~~<a href="">link~~</a></p> +. + + +Strikeouts have the same priority as emphases with respect to backticks: +. +~~`code~~` + +`~~code`~~ +. +<p>~~<code>code~~</code></p> +<p><code>~~code</code>~~</p> +. + + +Nested strikeouts: +. +~~foo ~~bar~~ baz~~ + +~~f **o ~~o b~~ a** r~~ +. +<p><s>foo <s>bar</s> baz</s></p> +<p><s>f <strong>o <s>o b</s> a</strong> r</s></p> +. + + +Should not have a whitespace between text and "~~": +. +foo ~~ bar ~~ baz +. +<p>foo ~~ bar ~~ baz</p> +. + + +Should parse strikethrough within link tags: +. +[~~foo~~]() +. +<p><a href=""><s>foo</s></a></p> +. + + +Newline should be considered a whitespace: +. +~~test +~~ + +~~ +test~~ + +~~ +test +~~ +. +<p>~~test +~~</p> +<p>~~ +test~~</p> +<p>~~ +test +~~</p> +. + +From CommonMark test suite, replacing `**` with our marker: + +. +a~~"foo"~~ +. +<p>a~~"foo"~~</p> +. + +Coverage: single tilde +. +~a~ +. +<p>~a~</p> +. + +Regression test for #742: +. +-~~~~;~~~~~~ +. +<p>-<s><s>;</s></s>~~</p> +. diff --git a/tests/test_port/fixtures/tables.md b/tests/test_port/fixtures/tables.md new file mode 100644 index 0000000..cf83708 --- /dev/null +++ b/tests/test_port/fixtures/tables.md @@ -0,0 +1,896 @@ +Simple: +. +| Heading 1 | Heading 2 +| --------- | --------- +| Cell 1 | Cell 2 +| Cell 3 | Cell 4 +. +<table> +<thead> +<tr> +<th>Heading 1</th> +<th>Heading 2</th> +</tr> +</thead> +<tbody> +<tr> +<td>Cell 1</td> +<td>Cell 2</td> +</tr> +<tr> +<td>Cell 3</td> +<td>Cell 4</td> +</tr> +</tbody> +</table> +. + + +Column alignment: +. +| Header 1 | Header 2 | Header 3 | Header 4 | +| :------: | -------: | :------- | -------- | +| Cell 1 | Cell 2 | Cell 3 | Cell 4 | +| Cell 5 | Cell 6 | Cell 7 | Cell 8 | +. +<table> +<thead> +<tr> +<th style="text-align:center">Header 1</th> +<th style="text-align:right">Header 2</th> +<th style="text-align:left">Header 3</th> +<th>Header 4</th> +</tr> +</thead> +<tbody> +<tr> +<td style="text-align:center">Cell 1</td> +<td style="text-align:right">Cell 2</td> +<td style="text-align:left">Cell 3</td> +<td>Cell 4</td> +</tr> +<tr> +<td style="text-align:center">Cell 5</td> +<td style="text-align:right">Cell 6</td> +<td style="text-align:left">Cell 7</td> +<td>Cell 8</td> +</tr> +</tbody> +</table> +. + + +Nested emphases: +. +Header 1|Header 2|Header 3|Header 4 +:-------|:------:|-------:|-------- +Cell 1 |Cell 2 |Cell 3 |Cell 4 +*Cell 5*|Cell 6 |Cell 7 |Cell 8 +. +<table> +<thead> +<tr> +<th style="text-align:left">Header 1</th> +<th style="text-align:center">Header 2</th> +<th style="text-align:right">Header 3</th> +<th>Header 4</th> +</tr> +</thead> +<tbody> +<tr> +<td style="text-align:left">Cell 1</td> +<td style="text-align:center">Cell 2</td> +<td style="text-align:right">Cell 3</td> +<td>Cell 4</td> +</tr> +<tr> +<td style="text-align:left"><em>Cell 5</em></td> +<td style="text-align:center">Cell 6</td> +<td style="text-align:right">Cell 7</td> +<td>Cell 8</td> +</tr> +</tbody> +</table> +. + + +Nested tables inside blockquotes: +. +> foo|foo +> ---|--- +> bar|bar +baz|baz +. +<blockquote> +<table> +<thead> +<tr> +<th>foo</th> +<th>foo</th> +</tr> +</thead> +<tbody> +<tr> +<td>bar</td> +<td>bar</td> +</tr> +</tbody> +</table> +</blockquote> +<p>baz|baz</p> +. + + +Minimal one-column: +. +| foo +|---- +| test2 +. +<table> +<thead> +<tr> +<th>foo</th> +</tr> +</thead> +<tbody> +<tr> +<td>test2</td> +</tr> +</tbody> +</table> +. + + +This is parsed as one big table: +. +- foo|foo +---|--- +bar|bar +. +<table> +<thead> +<tr> +<th>- foo</th> +<th>foo</th> +</tr> +</thead> +<tbody> +<tr> +<td>bar</td> +<td>bar</td> +</tr> +</tbody> +</table> +. + + +Second line should not contain symbols except "-", ":", "|" and " ": +. +foo|foo +-----|-----s +bar|bar +. +<p>foo|foo +-----|-----s +bar|bar</p> +. + + +Second line should contain "|" symbol: +. +foo|foo +-----:----- +bar|bar +. +<p>foo|foo +-----:----- +bar|bar</p> +. + + +Second line should not have empty columns in the middle: +. +foo|foo +-----||----- +bar|bar +. +<p>foo|foo +-----||----- +bar|bar</p> +. + + +Wrong alignment symbol position: +. +foo|foo +-----|-::- +bar|bar +. +<p>foo|foo +-----|-::- +bar|bar</p> +. + + +Title line should contain "|" symbol: +. +foo +-----|----- +bar|bar +. +<p>foo +-----|----- +bar|bar</p> +. + + +Allow tabs as a separator on 2nd line +. +| foo | bar | +| --- | --- | +| baz | quux | +. +<table> +<thead> +<tr> +<th>foo</th> +<th>bar</th> +</tr> +</thead> +<tbody> +<tr> +<td>baz</td> +<td>quux</td> +</tr> +</tbody> +</table> +. + + +Should terminate paragraph: +. +paragraph +foo|foo +---|--- +bar|bar +. +<p>paragraph</p> +<table> +<thead> +<tr> +<th>foo</th> +<th>foo</th> +</tr> +</thead> +<tbody> +<tr> +<td>bar</td> +<td>bar</td> +</tr> +</tbody> +</table> +. + + +Table no longer terminated via row without "|" symbol: +. +foo|foo +---|--- +paragraph +. +<table> +<thead> +<tr> +<th>foo</th> +<th>foo</th> +</tr> +</thead> +<tbody> +<tr> +<td>paragraph</td> +<td></td> +</tr> +</tbody> +</table> +. + + +Delimiter escaping (deprecated): +. +| Heading 1 \\\\| Heading 2 +| --------- | --------- +| Cell\|1\|| Cell\|2 +\| Cell\\\|3 \\| Cell\|4 +. +<p>| Heading 1 \\| Heading 2 +| --------- | --------- +| Cell|1|| Cell|2 +| Cell\|3 \| Cell|4</p> +. + +Pipes inside backticks DO split cells, unless `\` escaped: +. +| Heading 1 | Heading 2 +| --------- | --------- +| `Cell\|1` | Cell 2 +| `Cell|3` | Cell 4 +. +<table> +<thead> +<tr> +<th>Heading 1</th> +<th>Heading 2</th> +</tr> +</thead> +<tbody> +<tr> +<td><code>Cell|1</code></td> +<td>Cell 2</td> +</tr> +<tr> +<td>`Cell</td> +<td>3`</td> +</tr> +</tbody> +</table> +. + +Unclosed backticks don't count +. +| Heading 1 | Heading 2 +| --------- | --------- +| Cell 1 | Cell 2 +| `Cell 3| Cell 4 +. +<table> +<thead> +<tr> +<th>Heading 1</th> +<th>Heading 2</th> +</tr> +</thead> +<tbody> +<tr> +<td>Cell 1</td> +<td>Cell 2</td> +</tr> +<tr> +<td>`Cell 3</td> +<td>Cell 4</td> +</tr> +</tbody> +</table> +. + +Another complicated backticks case +. +| Heading 1 | Heading 2 +| --------- | --------- +| Cell 1 | Cell 2 +| \\\`|\\\` +. +<table> +<thead> +<tr> +<th>Heading 1</th> +<th>Heading 2</th> +</tr> +</thead> +<tbody> +<tr> +<td>Cell 1</td> +<td>Cell 2</td> +</tr> +<tr> +<td>\`</td> +<td>\`</td> +</tr> +</tbody> +</table> +. + +`\` in tables should not count as escaped backtick +. +# | 1 | 2 +--|--|-- +x | `\` | `x` +. +<table> +<thead> +<tr> +<th>#</th> +<th>1</th> +<th>2</th> +</tr> +</thead> +<tbody> +<tr> +<td>x</td> +<td><code>\</code></td> +<td><code>x</code></td> +</tr> +</tbody> +</table> +. + +Tables should handle escaped backticks +. +# | 1 | 2 +--|--|-- +x | \`\` | `x` +. +<table> +<thead> +<tr> +<th>#</th> +<th>1</th> +<th>2</th> +</tr> +</thead> +<tbody> +<tr> +<td>x</td> +<td>``</td> +<td><code>x</code></td> +</tr> +</tbody> +</table> +. + + +An amount of rows might be different across table (issue #171), but header and alignment rows must be equal (#697): +. +| 1 | 2 | +| :-----: | :-----: | +| 3 | 4 | 5 | 6 | +. +<table> +<thead> +<tr> +<th style="text-align:center">1</th> +<th style="text-align:center">2</th> +</tr> +</thead> +<tbody> +<tr> +<td style="text-align:center">3</td> +<td style="text-align:center">4</td> +</tr> +</tbody> +</table> +. + + +An amount of rows might be different across the table #2: +. +| 1 | 2 | 3 | 4 | +| :-----: | :-----: | :-----: | :-----: | +| 5 | 6 | +. +<table> +<thead> +<tr> +<th style="text-align:center">1</th> +<th style="text-align:center">2</th> +<th style="text-align:center">3</th> +<th style="text-align:center">4</th> +</tr> +</thead> +<tbody> +<tr> +<td style="text-align:center">5</td> +<td style="text-align:center">6</td> +<td style="text-align:center"></td> +<td style="text-align:center"></td> +</tr> +</tbody> +</table> +. + + +Allow one-column tables (issue #171): +. +| foo | +:-----: +| bar | +. +<table> +<thead> +<tr> +<th style="text-align:center">foo</th> +</tr> +</thead> +<tbody> +<tr> +<td style="text-align:center">bar</td> +</tr> +</tbody> +</table> +. + + +Allow indented tables (issue #325): +. + | Col1a | Col2a | + | ----- | ----- | + | Col1b | Col2b | +. +<table> +<thead> +<tr> +<th>Col1a</th> +<th>Col2a</th> +</tr> +</thead> +<tbody> +<tr> +<td>Col1b</td> +<td>Col2b</td> +</tr> +</tbody> +</table> +. + + +Tables should not be indented more than 4 spaces (1st line): +. + | Col1a | Col2a | + | ----- | ----- | + | Col1b | Col2b | +. +<pre><code>| Col1a | Col2a | +</code></pre> +<p>| ----- | ----- | +| Col1b | Col2b |</p> +. + + +Tables should not be indented more than 4 spaces (2nd line): +. + | Col1a | Col2a | + | ----- | ----- | + | Col1b | Col2b | +. +<p>| Col1a | Col2a | +| ----- | ----- | +| Col1b | Col2b |</p> +. + + +Tables should not be indented more than 4 spaces (3rd line): +. + | Col1a | Col2a | + | ----- | ----- | + | Col1b | Col2b | +. +<table> +<thead> +<tr> +<th>Col1a</th> +<th>Col2a</th> +</tr> +</thead> +</table> +<pre><code>| Col1b | Col2b | +</code></pre> +. + + +Allow tables with empty body: +. + | Col1a | Col2a | + | ----- | ----- | +. +<table> +<thead> +<tr> +<th>Col1a</th> +<th>Col2a</th> +</tr> +</thead> +</table> +. + + +Align row should be at least as large as any actual rows: +. +Col1a | Col1b | Col1c +----- | ----- +Col2a | Col2b | Col2c +. +<p>Col1a | Col1b | Col1c +----- | ----- +Col2a | Col2b | Col2c</p> +. + +Escaped pipes inside backticks don't split cells: +. +| Heading 1 | Heading 2 +| --------- | --------- +| Cell 1 | Cell 2 +| `Cell 3\|` | Cell 4 +. +<table> +<thead> +<tr> +<th>Heading 1</th> +<th>Heading 2</th> +</tr> +</thead> +<tbody> +<tr> +<td>Cell 1</td> +<td>Cell 2</td> +</tr> +<tr> +<td><code>Cell 3|</code></td> +<td>Cell 4</td> +</tr> +</tbody> +</table> +. + +Escape before escaped Pipes inside backticks don't split cells: +. +| Heading 1 | Heading 2 +| --------- | --------- +| Cell 1 | Cell 2 +| `Cell 3\\|` | Cell 4 +. +<table> +<thead> +<tr> +<th>Heading 1</th> +<th>Heading 2</th> +</tr> +</thead> +<tbody> +<tr> +<td>Cell 1</td> +<td>Cell 2</td> +</tr> +<tr> +<td><code>Cell 3\|</code></td> +<td>Cell 4</td> +</tr> +</tbody> +</table> +. + +Regression test for #721, table in a list indented with tabs: +. +- Level 1 + + - Level 2 + + | Column 1 | Column 2 | + | -------- | -------- | + | abcdefgh | ijklmnop | +. +<ul> +<li> +<p>Level 1</p> +<ul> +<li> +<p>Level 2</p> +<table> +<thead> +<tr> +<th>Column 1</th> +<th>Column 2</th> +</tr> +</thead> +<tbody> +<tr> +<td>abcdefgh</td> +<td>ijklmnop</td> +</tr> +</tbody> +</table> +</li> +</ul> +</li> +</ul> +. + +Table without any columns is not a table, #724 +. +| +| +| +. +<p>| +| +|</p> +. + +GFM 4.10 Tables (extension), Example 198 +. +| foo | bar | +| --- | --- | +| baz | bim | +. +<table> +<thead> +<tr> +<th>foo</th> +<th>bar</th> +</tr> +</thead> +<tbody> +<tr> +<td>baz</td> +<td>bim</td> +</tr> +</tbody> +</table> +. + +GFM 4.10 Tables (extension), Example 199 +. +| abc | defghi | +:-: | -----------: +bar | baz +. +<table> +<thead> +<tr> +<th style="text-align:center">abc</th> +<th style="text-align:right">defghi</th> +</tr> +</thead> +<tbody> +<tr> +<td style="text-align:center">bar</td> +<td style="text-align:right">baz</td> +</tr> +</tbody> +</table> +. + +GFM 4.10 Tables (extension), Example 200 +. +| f\|oo | +| ------ | +| b `\|` az | +| b **\|** im | +. +<table> +<thead> +<tr> +<th>f|oo</th> +</tr> +</thead> +<tbody> +<tr> +<td>b <code>|</code> az</td> +</tr> +<tr> +<td>b <strong>|</strong> im</td> +</tr> +</tbody> +</table> +. + +GFM 4.10 Tables (extension), Example 201 +. +| abc | def | +| --- | --- | +| bar | baz | +> bar +. +<table> +<thead> +<tr> +<th>abc</th> +<th>def</th> +</tr> +</thead> +<tbody> +<tr> +<td>bar</td> +<td>baz</td> +</tr> +</tbody> +</table> +<blockquote> +<p>bar</p> +</blockquote> +. + +GFM 4.10 Tables (extension), Example 202 +. +| abc | def | +| --- | --- | +| bar | baz | +bar + +bar +. +<table> +<thead> +<tr> +<th>abc</th> +<th>def</th> +</tr> +</thead> +<tbody> +<tr> +<td>bar</td> +<td>baz</td> +</tr> +<tr> +<td>bar</td> +<td></td> +</tr> +</tbody> +</table> +<p>bar</p> +. + +GFM 4.10 Tables (extension), Example 203 +. +| abc | def | +| --- | +| bar | +. +<p>| abc | def | +| --- | +| bar |</p> +. + +GFM 4.10 Tables (extension), Example 204 +. +| abc | def | +| --- | --- | +| bar | +| bar | baz | boo | +. +<table> +<thead> +<tr> +<th>abc</th> +<th>def</th> +</tr> +</thead> +<tbody> +<tr> +<td>bar</td> +<td></td> +</tr> +<tr> +<td>bar</td> +<td>baz</td> +</tr> +</tbody> +</table> +. + +GFM 4.10 Tables (extension), Example 205 +. +| abc | def | +| --- | --- | +. +<table> +<thead> +<tr> +<th>abc</th> +<th>def</th> +</tr> +</thead> +</table> +. + +A list takes precedence in case of ambiguity +. +a | b +- | - +1 | 2 +. +<p>a | b</p> +<ul> +<li>| - +1 | 2</li> +</ul> +. diff --git a/tests/test_port/fixtures/typographer.md b/tests/test_port/fixtures/typographer.md new file mode 100644 index 0000000..39154ed --- /dev/null +++ b/tests/test_port/fixtures/typographer.md @@ -0,0 +1,115 @@ +. +(bad) +. +<p>(bad)</p> +. + +copyright (Lower) +. +(c) +. +<p>©</p> +. + +copyright (Upper) +. +(C) +. +<p>©</p> +. + +copyright +. +(c) (C) +. +<p>© ©</p> +. + + +reserved +. +(r) (R) +. +<p>® ®</p> +. + + +trademark +. +(tm) (TM) +. +<p>™ ™</p> +. + + +paragraph +. +(p) (P) +. +<p>§ §</p> +. + + +plus-minus +. ++-5 +. +<p>±5</p> +. + + +ellipsis +. +test.. test... test..... test?..... test!.... +. +<p>test… test… test… test?.. test!..</p> +. + + +dupes +. +!!!!!! ???? ,, +. +<p>!!! ??? ,</p> +. + + +dupes-ellipsis +. +!... ?... ,... !!!!!!.... ????.... ,,... +. +<p>!.. ?.. ,… !!!.. ???.. ,…</p> +. + + +dashes +. +---markdownit --- super--- + +markdownit---awesome + +abc ---- + +--markdownit -- super-- + +markdownit--awesome +. +<p>—markdownit — super—</p> +<p>markdownit—awesome</p> +<p>abc ----</p> +<p>–markdownit – super–</p> +<p>markdownit–awesome</p> +. + +regression tests for #624 +. +1---2---3 + +1--2--3 + +1 -- -- 3 +. +<p>1—2—3</p> +<p>1–2–3</p> +<p>1 – – 3</p> +. diff --git a/tests/test_port/fixtures/xss.md b/tests/test_port/fixtures/xss.md new file mode 100644 index 0000000..7c0512e --- /dev/null +++ b/tests/test_port/fixtures/xss.md @@ -0,0 +1,128 @@ +. +[normal link](javascript) +. +<p><a href="javascript">normal link</a></p> +. + + +Should not allow some protocols in links and images +. +[xss link](javascript:alert(1)) + +[xss link](JAVASCRIPT:alert(1)) + +[xss link](vbscript:alert(1)) + +[xss link](VBSCRIPT:alert(1)) + +[xss link](file:///123) +. +<p>[xss link](javascript:alert(1))</p> +<p>[xss link](JAVASCRIPT:alert(1))</p> +<p>[xss link](vbscript:alert(1))</p> +<p>[xss link](VBSCRIPT:alert(1))</p> +<p>[xss link](file:///123)</p> +. + + +. +[xss link]("><script>alert("xss")</script>) + +[xss link](Javascript:alert(1)) + +[xss link](&#74;avascript:alert(1)) + +[xss link](\Javascript:alert(1)) +. +<p><a href="%22%3E%3Cscript%3Ealert(%22xss%22)%3C/script%3E">xss link</a></p> +<p>[xss link](Javascript:alert(1))</p> +<p><a href="&#74;avascript:alert(1)">xss link</a></p> +<p><a href="&#74;avascript:alert(1)">xss link</a></p> +. + +. +[xss link](<javascript:alert(1)>) +. +<p>[xss link](<javascript:alert(1)>)</p> +. + +. +[xss link](javascript:alert(1)) +. +<p>[xss link](javascript:alert(1))</p> +. + + +Should not allow data-uri except some whitelisted mimes +. +![](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7) +. +<p><img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt=""></p> +. + +. +[xss link](data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K) +. +<p>[xss link](data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K)</p> +. + +. +[normal link](/javascript:link) +. +<p><a href="/javascript:link">normal link</a></p> +. + + +Image parser use the same code base as link. +. +![xss link](javascript:alert(1)) +. +<p>![xss link](javascript:alert(1))</p> +. + + +Autolinks +. +<javascript:alert(1)> + +<javascript:alert(1)> +. +<p><javascript:alert(1)></p> +<p><javascript:alert(1)></p> +. + + +Linkifier +. +javascript:alert(1) + +javascript:alert(1) +. +<p>javascript:alert(1)</p> +<p>javascript:alert(1)</p> +. + + +References +. +[test]: javascript:alert(1) +. +<p>[test]: javascript:alert(1)</p> +. + + +Make sure we decode entities before split: +. +```js custom-class +test1 +``` + +```jscustom-class +test2 +``` +. +<pre><code class="js">test1 +</code></pre> +<pre><code class="js">test2 +</code></pre> +. diff --git a/tests/test_port/test_fixtures.py b/tests/test_port/test_fixtures.py new file mode 100644 index 0000000..5117c5e --- /dev/null +++ b/tests/test_port/test_fixtures.py @@ -0,0 +1,114 @@ +from pathlib import Path + +import pytest + +from markdown_it import MarkdownIt +from markdown_it.utils import read_fixture_file + +FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures") + + +@pytest.mark.parametrize( + "line,title,input,expected", + read_fixture_file(FIXTURE_PATH.joinpath("linkify.md")), +) +def test_linkify(line, title, input, expected): + md = MarkdownIt().enable("linkify") + md.options["linkify"] = True + text = md.render(input) + assert text.rstrip() == expected.rstrip() + + # if not install linkify-it-py + md.linkify = None + with pytest.raises(ModuleNotFoundError): + md.render(input) + + +@pytest.mark.parametrize( + "line,title,input,expected", + read_fixture_file(FIXTURE_PATH.joinpath("smartquotes.md")), +) +def test_smartquotes(line, title, input, expected): + md = MarkdownIt().enable("replacements").enable("smartquotes") + md.options["typographer"] = True + text = md.render(input) + assert text.rstrip() == expected.rstrip() + + +@pytest.mark.parametrize( + "line,title,input,expected", + read_fixture_file(FIXTURE_PATH.joinpath("typographer.md")), +) +def test_typographer(line, title, input, expected): + md = MarkdownIt().enable("replacements") + md.options["typographer"] = True + text = md.render(input) + assert text.rstrip() == expected.rstrip() + + +@pytest.mark.parametrize( + "line,title,input,expected", read_fixture_file(FIXTURE_PATH.joinpath("tables.md")) +) +def test_table(line, title, input, expected): + md = MarkdownIt().enable("table") + text = md.render(input) + try: + assert text.rstrip() == expected.rstrip() + except AssertionError: + print(text) + raise + + +@pytest.mark.parametrize( + "line,title,input,expected", + read_fixture_file(FIXTURE_PATH.joinpath("commonmark_extras.md")), +) +def test_commonmark_extras(line, title, input, expected): + md = MarkdownIt("commonmark") + md.options["langPrefix"] = "" + text = md.render(input) + if text.rstrip() != expected.rstrip(): + print(text) + assert text.rstrip() == expected.rstrip() + + +@pytest.mark.parametrize( + "line,title,input,expected", + read_fixture_file(FIXTURE_PATH.joinpath("normalize.md")), +) +def test_normalize_url(line, title, input, expected): + md = MarkdownIt("commonmark") + text = md.render(input) + assert text.rstrip() == expected.rstrip() + + +@pytest.mark.parametrize( + "line,title,input,expected", read_fixture_file(FIXTURE_PATH.joinpath("fatal.md")) +) +def test_fatal(line, title, input, expected): + md = MarkdownIt("commonmark").enable("replacements") + md.options["typographer"] = True + text = md.render(input) + if text.rstrip() != expected.rstrip(): + print(text) + assert text.rstrip() == expected.rstrip() + + +@pytest.mark.parametrize( + "line,title,input,expected", + read_fixture_file(FIXTURE_PATH.joinpath("strikethrough.md")), +) +def test_strikethrough(line, title, input, expected): + md = MarkdownIt().enable("strikethrough") + text = md.render(input) + assert text.rstrip() == expected.rstrip() + + +@pytest.mark.parametrize( + "line,title,input,expected", + read_fixture_file(FIXTURE_PATH.joinpath("issue-fixes.md")), +) +def test_issue_fixes(line, title, input, expected): + md = MarkdownIt() + text = md.render(input) + assert text.rstrip() == expected.rstrip() diff --git a/tests/test_port/test_misc.py b/tests/test_port/test_misc.py new file mode 100644 index 0000000..62b5bf8 --- /dev/null +++ b/tests/test_port/test_misc.py @@ -0,0 +1,44 @@ +from markdown_it import MarkdownIt, presets + + +def test_highlight_arguments(): + def highlight_func(str_, lang, attrs): + assert lang == "a" + assert attrs == "b c d" + return "<pre><code>==" + str_ + "==</code></pre>" + + conf = presets.commonmark.make() + conf["options"]["highlight"] = highlight_func + md = MarkdownIt(config=conf) + assert md.render("``` a b c d \nhl\n```") == "<pre><code>==hl\n==</code></pre>\n" + + +def test_ordered_list_info(): + def type_filter(tokens, type_): + return [t for t in tokens if t.type == type_] + + md = MarkdownIt() + + tokens = md.parse("1. Foo\n2. Bar\n20. Fuzz") + assert len(type_filter(tokens, "ordered_list_open")) == 1 + tokens = type_filter(tokens, "list_item_open") + assert len(tokens) == 3 + assert tokens[0].info == "1" + assert tokens[0].markup == "." + assert tokens[1].info == "2" + assert tokens[1].markup == "." + assert tokens[2].info == "20" + assert tokens[2].markup == "." + + tokens = md.parse(" 1. Foo\n2. Bar\n 20. Fuzz\n 199. Flp") + assert len(type_filter(tokens, "ordered_list_open")) == 1 + tokens = type_filter(tokens, "list_item_open") + assert len(tokens) == 4 + assert tokens[0].info == "1" + assert tokens[0].markup == "." + assert tokens[1].info == "2" + assert tokens[1].markup == "." + assert tokens[2].info == "20" + assert tokens[2].markup == "." + assert tokens[3].info == "199" + assert tokens[3].markup == "." diff --git a/tests/test_port/test_no_end_newline.py b/tests/test_port/test_no_end_newline.py new file mode 100644 index 0000000..5e7cf82 --- /dev/null +++ b/tests/test_port/test_no_end_newline.py @@ -0,0 +1,27 @@ +import pytest + +from markdown_it import MarkdownIt + + +@pytest.mark.parametrize( + "input,expected", + [ + ("#", "<h1></h1>\n"), + ("###", "<h3></h3>\n"), + ("` `", "<p><code> </code></p>\n"), + ("``````", "<pre><code></code></pre>\n"), + ("-", "<ul>\n<li></li>\n</ul>\n"), + ("1.", "<ol>\n<li></li>\n</ol>\n"), + (">", "<blockquote></blockquote>\n"), + ("---", "<hr />\n"), + ("<h1></h1>", "<h1></h1>"), + ("p", "<p>p</p>\n"), + ("[reference]: /url", ""), + (" indented code block", "<pre><code>indented code block\n</code></pre>\n"), + ("> test\n>", "<blockquote>\n<p>test</p>\n</blockquote>\n"), + ], +) +def test_no_end_newline(input, expected): + md = MarkdownIt() + text = md.render(input) + assert text == expected diff --git a/tests/test_port/test_references.py b/tests/test_port/test_references.py new file mode 100644 index 0000000..32e389d --- /dev/null +++ b/tests/test_port/test_references.py @@ -0,0 +1,53 @@ +from markdown_it import MarkdownIt + + +def test_ref_definitions(): + + md = MarkdownIt() + src = "[a]: abc\n\n[b]: xyz\n\n[b]: ijk" + env = {} + tokens = md.parse(src, env) + assert tokens == [] + assert env == { + "references": { + "A": {"title": "", "href": "abc", "map": [0, 1]}, + "B": {"title": "", "href": "xyz", "map": [2, 3]}, + }, + "duplicate_refs": [{"href": "ijk", "label": "B", "map": [4, 5], "title": ""}], + } + + +def test_use_existing_env(data_regression): + md = MarkdownIt() + src = "[a]\n\n[c]: ijk" + env = { + "references": { + "A": {"title": "", "href": "abc", "map": [0, 1]}, + "B": {"title": "", "href": "xyz", "map": [2, 3]}, + } + } + tokens = md.parse(src, env) + data_regression.check([token.as_dict() for token in tokens]) + assert env == { + "references": { + "A": {"title": "", "href": "abc", "map": [0, 1]}, + "B": {"title": "", "href": "xyz", "map": [2, 3]}, + "C": {"title": "", "href": "ijk", "map": [2, 3]}, + } + } + + +def test_store_labels(data_regression): + md = MarkdownIt() + md.options["store_labels"] = True + src = "[a]\n\n![a]\n\n[a]: ijk" + tokens = md.parse(src) + data_regression.check([token.as_dict() for token in tokens]) + + +def test_inline_definitions(data_regression): + md = MarkdownIt() + md.options["inline_definitions"] = True + src = '[a]: url "title"\n- [a]: url "title"' + tokens = md.parse(src) + data_regression.check([token.as_dict() for token in tokens]) diff --git a/tests/test_port/test_references/test_inline_definitions.yml b/tests/test_port/test_references/test_inline_definitions.yml new file mode 100644 index 0000000..5ec210b --- /dev/null +++ b/tests/test_port/test_references/test_inline_definitions.yml @@ -0,0 +1,94 @@ +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 0 + map: + - 0 + - 1 + markup: '' + meta: + id: A + label: a + title: title + url: url + nesting: 0 + tag: '' + type: definition +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 0 + map: + - 1 + - 2 + markup: '-' + meta: {} + nesting: 1 + tag: ul + type: bullet_list_open +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 1 + map: + - 1 + - 2 + markup: '-' + meta: {} + nesting: 1 + tag: li + type: list_item_open +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 2 + map: + - 1 + - 2 + markup: '' + meta: + id: A + label: a + title: title + url: url + nesting: 0 + tag: '' + type: definition +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 1 + map: null + markup: '-' + meta: {} + nesting: -1 + tag: li + type: list_item_close +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 0 + map: null + markup: '-' + meta: {} + nesting: -1 + tag: ul + type: bullet_list_close diff --git a/tests/test_port/test_references/test_store_labels.yml b/tests/test_port/test_references/test_store_labels.yml new file mode 100644 index 0000000..79f6f74 --- /dev/null +++ b/tests/test_port/test_references/test_store_labels.yml @@ -0,0 +1,159 @@ +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 0 + map: + - 0 + - 1 + markup: '' + meta: {} + nesting: 1 + tag: p + type: paragraph_open +- attrs: null + block: true + children: + - attrs: + - - href + - ijk + block: false + children: null + content: '' + hidden: false + info: '' + level: 0 + map: null + markup: '' + meta: + label: A + nesting: 1 + tag: a + type: link_open + - attrs: null + block: false + children: null + content: a + hidden: false + info: '' + level: 1 + map: null + markup: '' + meta: {} + nesting: 0 + tag: '' + type: text + - attrs: null + block: false + children: null + content: '' + hidden: false + info: '' + level: 0 + map: null + markup: '' + meta: {} + nesting: -1 + tag: a + type: link_close + content: '[a]' + hidden: false + info: '' + level: 1 + map: + - 0 + - 1 + markup: '' + meta: {} + nesting: 0 + tag: '' + type: inline +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 0 + map: null + markup: '' + meta: {} + nesting: -1 + tag: p + type: paragraph_close +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 0 + map: + - 2 + - 3 + markup: '' + meta: {} + nesting: 1 + tag: p + type: paragraph_open +- attrs: null + block: true + children: + - attrs: + - - src + - ijk + - - alt + - '' + block: false + children: + - attrs: null + block: false + children: null + content: a + hidden: false + info: '' + level: 0 + map: null + markup: '' + meta: {} + nesting: 0 + tag: '' + type: text + content: a + hidden: false + info: '' + level: 0 + map: null + markup: '' + meta: + label: A + nesting: 0 + tag: img + type: image + content: '![a]' + hidden: false + info: '' + level: 1 + map: + - 2 + - 3 + markup: '' + meta: {} + nesting: 0 + tag: '' + type: inline +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 0 + map: null + markup: '' + meta: {} + nesting: -1 + tag: p + type: paragraph_close diff --git a/tests/test_port/test_references/test_use_existing_env.yml b/tests/test_port/test_references/test_use_existing_env.yml new file mode 100644 index 0000000..1a72337 --- /dev/null +++ b/tests/test_port/test_references/test_use_existing_env.yml @@ -0,0 +1,84 @@ +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 0 + map: + - 0 + - 1 + markup: '' + meta: {} + nesting: 1 + tag: p + type: paragraph_open +- attrs: null + block: true + children: + - attrs: + - - href + - abc + block: false + children: null + content: '' + hidden: false + info: '' + level: 0 + map: null + markup: '' + meta: {} + nesting: 1 + tag: a + type: link_open + - attrs: null + block: false + children: null + content: a + hidden: false + info: '' + level: 1 + map: null + markup: '' + meta: {} + nesting: 0 + tag: '' + type: text + - attrs: null + block: false + children: null + content: '' + hidden: false + info: '' + level: 0 + map: null + markup: '' + meta: {} + nesting: -1 + tag: a + type: link_close + content: '[a]' + hidden: false + info: '' + level: 1 + map: + - 0 + - 1 + markup: '' + meta: {} + nesting: 0 + tag: '' + type: inline +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 0 + map: null + markup: '' + meta: {} + nesting: -1 + tag: p + type: paragraph_close diff --git a/tests/test_tree.py b/tests/test_tree.py new file mode 100644 index 0000000..7a7d605 --- /dev/null +++ b/tests/test_tree.py @@ -0,0 +1,93 @@ +from markdown_it import MarkdownIt +from markdown_it.tree import SyntaxTreeNode + +EXAMPLE_MARKDOWN = """ +## Heading here + +Some paragraph text and **emphasis here** and more text here. +""" + + +def test_tree_to_tokens_conversion(): + tokens = MarkdownIt().parse(EXAMPLE_MARKDOWN) + tokens_after_roundtrip = SyntaxTreeNode(tokens).to_tokens() + assert tokens == tokens_after_roundtrip + + +def test_property_passthrough(): + tokens = MarkdownIt().parse(EXAMPLE_MARKDOWN) + heading_open = tokens[0] + tree = SyntaxTreeNode(tokens) + heading_node = tree.children[0] + assert heading_open.tag == heading_node.tag + assert tuple(heading_open.map) == heading_node.map + assert heading_open.level == heading_node.level + assert heading_open.content == heading_node.content + assert heading_open.markup == heading_node.markup + assert heading_open.info == heading_node.info + assert heading_open.meta == heading_node.meta + assert heading_open.block == heading_node.block + assert heading_open.hidden == heading_node.hidden + + +def test_type(): + tokens = MarkdownIt().parse(EXAMPLE_MARKDOWN) + tree = SyntaxTreeNode(tokens) + # Root type is "root" + assert tree.type == "root" + # "_open" suffix must be stripped from nested token type + assert tree.children[0].type == "heading" + assert tree[0].type == "heading" + # For unnested tokens, node type must remain same as token type + assert tree.children[0].children[0].type == "inline" + + +def test_sibling_traverse(): + tokens = MarkdownIt().parse(EXAMPLE_MARKDOWN) + tree = SyntaxTreeNode(tokens) + paragraph_inline_node = tree.children[1].children[0] + text_node = paragraph_inline_node.children[0] + assert text_node.type == "text" + strong_node = text_node.next_sibling + assert strong_node.type == "strong" + another_text_node = strong_node.next_sibling + assert another_text_node.type == "text" + assert another_text_node.next_sibling is None + assert another_text_node.previous_sibling.previous_sibling == text_node + assert text_node.previous_sibling is None + + +def test_pretty(file_regression): + md = MarkdownIt("commonmark") + tokens = md.parse( + """ +# Header + +Here's some text and an image ![title](image.png) + +1. a **list** + +> a *quote* + """ + ) + node = SyntaxTreeNode(tokens) + file_regression.check(node.pretty(indent=2, show_text=True), extension=".xml") + + +def test_walk(): + tokens = MarkdownIt().parse(EXAMPLE_MARKDOWN) + tree = SyntaxTreeNode(tokens) + expected_node_types = ( + "root", + "heading", + "inline", + "text", + "paragraph", + "inline", + "text", + "strong", + "text", + "text", + ) + for node, expected_type in zip(tree.walk(), expected_node_types): + assert node.type == expected_type diff --git a/tests/test_tree/test_pretty.xml b/tests/test_tree/test_pretty.xml new file mode 100644 index 0000000..41d399e --- /dev/null +++ b/tests/test_tree/test_pretty.xml @@ -0,0 +1,30 @@ +<root> + <heading> + <inline> + <text> + Header + <paragraph> + <inline> + <text> + Here's some text and an image + <image src='image.png' alt=''> + <text> + title + <ordered_list> + <list_item> + <paragraph> + <inline> + <text> + a + <strong> + <text> + list + <text> + <blockquote> + <paragraph> + <inline> + <text> + a + <em> + <text> + quote
\ No newline at end of file |