{"id":17551473,"url":"https://github.com/taufik-nurrohman/markdown","last_synced_at":"2025-04-24T02:21:51.734Z","repository":{"id":186323827,"uuid":"674990425","full_name":"taufik-nurrohman/markdown","owner":"taufik-nurrohman","description":"Obviously, a Markdown parser.","archived":false,"fork":false,"pushed_at":"2024-11-18T02:07:36.000Z","size":1162,"stargazers_count":11,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-17T17:23:33.414Z","etag":null,"topics":["commonmark","converter","extra","markdown","parsedown","parser","php"],"latest_commit_sha":null,"homepage":"https://github.com/mecha-cms/x.markdown","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/taufik-nurrohman.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-08-05T12:08:24.000Z","updated_at":"2024-11-18T02:07:39.000Z","dependencies_parsed_at":"2024-01-11T08:51:10.018Z","dependency_job_id":"d059d5a8-2951-430d-a72b-326caf4b5582","html_url":"https://github.com/taufik-nurrohman/markdown","commit_stats":null,"previous_names":["taufik-nurrohman/markdown"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taufik-nurrohman%2Fmarkdown","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taufik-nurrohman%2Fmarkdown/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taufik-nurrohman%2Fmarkdown/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taufik-nurrohman%2Fmarkdown/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/taufik-nurrohman","download_url":"https://codeload.github.com/taufik-nurrohman/markdown/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250546363,"owners_count":21448313,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["commonmark","converter","extra","markdown","parsedown","parser","php"],"created_at":"2024-10-21T04:46:04.001Z","updated_at":"2025-04-24T02:21:51.711Z","avatar_url":"https://github.com/taufik-nurrohman.png","language":"PHP","funding_links":["https://github.com/sponsors/taufik-nurrohman"],"categories":[],"sub_categories":[],"readme":"PHP Markdown Parser\n===================\n\n![from.php] ![to.php]\n\n[from.php]: https://img.shields.io/github/size/taufik-nurrohman/markdown/from.php?branch=main\u0026color=%234f5d95\u0026label=from.php\u0026labelColor=%231f2328\u0026style=flat-square\n[to.php]: https://img.shields.io/github/size/taufik-nurrohman/markdown/to.php?branch=main\u0026color=%234f5d95\u0026label=to.php\u0026labelColor=%231f2328\u0026style=flat-square\n\nWith 90% compliance to [CommonMark 0.31.2](https://spec.commonmark.org/0.31.2) specifications.\n\nMotivation\n----------\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://github.com/taufik-nurrohman/markdown/assets/1669261/0a488f4a-0450-4e0a-8137-196a4b0657b0\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://github.com/taufik-nurrohman/markdown/assets/1669261/164b592d-e8db-4e28-be5d-467522f65f0d\"\u003e\n  \u003cimg alt=\"Why?\" src=\"https://github.com/taufik-nurrohman/markdown/assets/1669261/164b592d-e8db-4e28-be5d-467522f65f0d\"\u003e\n\u003c/picture\u003e\n\nI appreciate the [Parsedown](https://github.com/erusev/parsedown) project for its simplicity and speed. It uses only a\nsingle class file to convert Markdown syntax to HTML. However, given the decrease in Parsedown project activity over\ntime, I assume that it is now in the state of “feature complete”. It still has some bugs to fix, and with\n[the recent release of PHP version 8.1](https://www.php.net/releases/8.1/en.php), some of the PHP syntax there has\nbecome obsolete.\n\nThere is actually [a draft for Parsedown version 2.0](https://github.com/erusev/parsedown/tree/2.0.x), but it is no\nlonger made as a single class file. It’s broken down into components. The goal, I think, is to make it easy to add\nfunctionality without breaking what’s already in the core. For others, it may be of great use, but I see it as a form of\nsimilarity to the features provided by\n[CommonMark](https://github.com/thephpleague/commonmark/blob/2.4/docs/2.4/customization/extensions.md). Because of that,\nif I want to upgrade, it might be more optimal to just switch to CommonMark.\n\nI’m not into things like that. As someone who needs a function to convert Markdown syntax to HTML, that kind of\nflexibility is completely unnecessary to me. I just want to convert Markdown syntax to HTML for once and then move on.\nIt was fulfilled by [Parsedown version 1.8](https://github.com/erusev/parsedown/tree/1.8.x-beta), but it seems that it\nis no longer being actively maintained.\n\nThe goal of this project is to use it in my [Markdown extension for Mecha](https://github.com/mecha-cms/x.markdown) in\nthe future. Previously, I wanted to develop this converter directly into the extension, but my friend advised me to\ncreate this project separately as it might have potential to be used by other developers beyond the\n[Mecha CMS](https://github.com/mecha-cms) developers.\n\nUsage\n-----\n\nThis converter can be installed using [Composer](https://packagist.org/packages/taufik-nurrohman/markdown), but it\ndoesn’t need any other dependencies and just uses Composer’s ability to automatically include files. Those of you who\ndon’t use Composer should be able to include the `from.php` and `to.php` files directly into your application without\nany problems.\n\n### Using Composer\n\nFrom the command line interface, navigate to your project folder then run this command:\n\n~~~ sh\ncomposer require taufik-nurrohman/markdown\n~~~\n\nRequire the generated auto-loader file in your application:\n\n~~~ php\n\u003c?php\n\nuse function x\\markdown\\from as from_markdown;\nuse function x\\markdown\\to as to_markdown;\n\nrequire 'vendor/autoload.php';\n\necho from_markdown('# asdf {#asdf}'); // Returns `'\u003ch1 id=\"asdf\"\u003easdf\u003c/h1\u003e'`\n~~~\n\n### Using File\n\nRequire the `from.php` and `to.php` files in your application:\n\n~~~ php\n\u003c?php\n\nuse function x\\markdown\\from as from_markdown;\nuse function x\\markdown\\to as to_markdown;\n\nrequire 'from.php';\nrequire 'to.php';\n\necho from_markdown('# asdf {#asdf}'); // Returns `'\u003ch1 id=\"asdf\"\u003easdf\u003c/h1\u003e'`\n~~~\n\nThe `to.php` file is optional and is used to convert HTML to Markdown. If you just want to convert Markdown to HTML, you\ndon’t need to include this file. This feature is experimental and is provided as a complementary feature, as there is\nfunction `json_encode()` besides function `json_decode()`. The Markdown result may not satisfy everyone, but it can be\ndiscussed further.\n\nOptions\n-------\n\n~~~ php\n/**\n * Convert Markdown string to HTML string.\n *\n * @param null|string $value Your Markdown string.\n * @param bool $block If this option is set to `false`, Markdown block syntax will be ignored.\n * @return null|string\n */\nfrom(?string $value, bool $block = true): ?string;\n~~~\n\n~~~ php\n/**\n * Convert HTML string to Markdown string.\n *\n * @param null|string $value Your HTML string.\n * @param bool $block If this option is set to `false`, HTML block syntax will be stripped out.\n * @return null|string\n */\nto(?string $value, bool $block = true): ?string;\n~~~\n\nDialect\n-------\n\nFrom time to time, the history of Mecha slowly forms my Markdown writing style. The Markdown extension used by Mecha\n[was first](https://github.com/mecha-cms/mecha/tree/v1.2.2) built with\n[Michel Fortin’s Markdown converter](https://michelf.ca/projects/php-markdown) (which I believe is the very first port\nof a PHP-based Markdown converter originally written in Perl by\n[John Gruber](https://daringfireball.net/projects/markdown)). Until the release of\n[Mecha version 1.2.3](https://github.com/mecha-cms/mecha/tree/v1.2.3), I decided to switch to\n[Parsedown](https://github.com/erusev/parsedown) because it was quite popular at the time. It can also do the conversion\nprocess much faster. Emanuil Rusev’s way of detecting the block type\n[by reading the first character](https://github.com/erusev/parsedown/tree/1.7.4#questions) is, in my opinion, very\nclever and efficient.\n\n### Attributes\n\nMy Markdown converter supports a more extensive attribute syntax, including a mix of `.class` and `#id` attribute\nsyntax, and a mix of `key=value` attribute syntax:\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eMarkdown\u003c/th\u003e\n      \u003cth\u003eHTML\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e# asdf {#asdf}\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;h1 id=\"asdf\"\u0026gt;asdf\u0026lt;/h1\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e# asdf {#asdf.asdf}\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;h1 class=\"asdf\" id=\"asdf\"\u0026gt;asdf\u0026lt;/h1\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e# asdf {#asdf.asdf asdf=asdf}\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;h1 asdf=\"asdf\" class=\"asdf\" id=\"asdf\"\u0026gt;asdf\u0026lt;/h1\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\nInline attributes always win over native syntax attributes and pre-defined attributes:\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eMarkdown\u003c/th\u003e\n      \u003cth\u003eHTML\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e[asdf](asdf) {href=x}\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;a href=\"x\"\u0026gt;asdf\u0026lt;/a\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e[asdf]\u0026#10;\u0026#10;[asdf]: asdf {href=x}\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;a href=\"x\"\u0026gt;asdf\u0026lt;/a\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e[asdf] {.x href=x}\u0026#10;\u0026#10;[asdf]: asdf {.asdf}\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;a class=\"x\" href=\"x\"\u0026gt;asdf\u0026lt;/a\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n### Emphasis\n\nCommonMark’s [emphasis (and strong emphasis) specifications][commonmark/em] almost drove me crazy! 🤯\n\nImplementing that level of strictness would slow the project down even more towards a stable release. I actually\nunderstand [the parsing strategy][commonmark/appendix] very well, but turning it into a minimal PHP code just feels so\nhard for me. In order to speed up the completion of the project, I decided to reduce the strictness of the emphasis (and\nstrong emphasis) specifications.\n\nThey will not completely follow the CommonMark’s emphasis (and strong emphasis) specifications, but I promise that the\nHTML results will still make sense, especially for those who have never read the specifications.\n\n[commonmark/appendix]: https://spec.commonmark.org/0.31.2#appendix-a-parsing-strategy\n[commonmark/em]: https://spec.commonmark.org/0.31.2#emphasis-and-strong-emphasis\n\n**Rule 1:** The same type of emphasis can be nested only if one or both sides of the child emphasis begin and/or end\nwith white-space or punctuation.\n\nThis will create nested emphasis:\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eMarkdown\u003c/th\u003e\n      \u003cth\u003eHTML\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e*asdf *asdf* asdf*\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;em\u0026gt;asdf \u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt; asdf\u0026lt;/em\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e**asdf* asdf asdf*\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;em\u0026gt;\u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt; asdf asdf\u0026lt;/em\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e*asdf asdf *asdf**\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;em\u0026gt;asdf asdf \u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt;\u0026lt;/em\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eMarkdown\u003c/th\u003e\n      \u003cth\u003eHTML\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e**asdf **asdf** asdf**\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;strong\u0026gt;asdf \u0026lt;strong\u0026gt;asdf\u0026lt;/strong\u0026gt; asdf\u0026lt;/strong\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e****asdf** asdf asdf**\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;strong\u0026gt;\u0026lt;strong\u0026gt;asdf\u0026lt;/strong\u0026gt; asdf asdf\u0026lt;/strong\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e**asdf asdf **asdf****\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;strong\u0026gt;asdf asdf \u0026lt;strong\u0026gt;asdf\u0026lt;/strong\u0026gt;\u0026lt;/strong\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\nThis will not:\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eMarkdown\u003c/th\u003e\n      \u003cth\u003eHTML\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e*asdf*asdf*asdf*\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt;asdf\u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e**asdf*asdf asdf*\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;**asdf\u0026lt;em\u0026gt;asdf asdf\u0026lt;/em\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e*asdf asdf*asdf**\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;em\u0026gt;asdf asdf\u0026lt;/em\u0026gt;asdf**\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eMarkdown\u003c/th\u003e\n      \u003cth\u003eHTML\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e**asdf**asdf**asdf**\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;strong\u0026gt;asdf\u0026lt;/strong\u0026gt;asdf\u0026lt;strong\u0026gt;asdf\u0026lt;/strong\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e****asdf**asdf asdf**\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;****asdf\u0026lt;strong\u0026gt;asdf asdf\u0026lt;/strong\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e**asdf asdf**asdf****\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;strong\u0026gt;asdf asdf\u0026lt;/strong\u0026gt;asdf****\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n**Rule 2:** For conditions where the emphasis types are different, **Rule 1** does not apply.\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eMarkdown\u003c/th\u003e\n      \u003cth\u003eHTML\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e*asdf**asdf**asdf*\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;em\u0026gt;asdf\u0026lt;strong\u0026gt;asdf\u0026lt;/strong\u0026gt;asdf\u0026lt;/em\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e*asdf **asdf** asdf*\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;em\u0026gt;asdf \u0026lt;strong\u0026gt;asdf\u0026lt;/strong\u0026gt; asdf\u0026lt;/em\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e***asdf**asdf asdf*\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;em\u0026gt;\u0026lt;strong\u0026gt;asdf\u0026lt;/strong\u0026gt;asdf asdf\u0026lt;/em\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e***asdf** asdf asdf*\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;em\u0026gt;\u0026lt;strong\u0026gt;asdf\u0026lt;/strong\u0026gt; asdf asdf\u0026lt;/em\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e*asdf asdf**asdf***\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;em\u0026gt;asdf asdf\u0026lt;strong\u0026gt;asdf\u0026lt;/strong\u0026gt;\u0026lt;/em\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e*asdf asdf **asdf***\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;em\u0026gt;asdf asdf \u0026lt;strong\u0026gt;asdf\u0026lt;/strong\u0026gt;\u0026lt;/em\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eMarkdown\u003c/th\u003e\n      \u003cth\u003eHTML\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e**asdf*asdf*asdf**\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;strong\u0026gt;asdf\u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt;asdf\u0026lt;/strong\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e**asdf *asdf* asdf**\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;strong\u0026gt;asdf \u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt; asdf\u0026lt;/strong\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e***asdf*asdf asdf**\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;strong\u0026gt;\u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt;asdf asdf\u0026lt;/strong\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e***asdf* asdf asdf**\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;strong\u0026gt;\u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt; asdf asdf\u0026lt;/strong\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e**asdf asdf*asdf***\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;strong\u0026gt;asdf asdf\u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt;\u0026lt;/strong\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e**asdf asdf *asdf***\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;strong\u0026gt;asdf asdf \u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt;\u0026lt;/strong\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n**Rule 3:** For conditions where the emphasis markers are different, **Rule 1** does not apply.\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eMarkdown\u003c/th\u003e\n      \u003cth\u003eHTML\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e_asdf*asdf*asdf_\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;em\u0026gt;asdf\u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt;asdf\u0026lt;/em\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e*asdf_asdf_asdf*\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;em\u0026gt;asdf_asdf_asdf\u0026lt;/em\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e*asdf _asdf_ asdf*\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;em\u0026gt;asdf \u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt; asdf\u0026lt;/em\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e_*asdf*asdf asdf_\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;em\u0026gt;\u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt;asdf asdf\u0026lt;/em\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e*_asdf_asdf asdf*\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;em\u0026gt;_asdf_asdf asdf\u0026lt;/em\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e*_asdf_ asdf asdf*\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;em\u0026gt;\u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt; asdf asdf\u0026lt;/em\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e_asdf asdf*asdf*_\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;em\u0026gt;asdf asdf\u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt;\u0026lt;/em\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e*asdf asdf_asdf_*\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;em\u0026gt;asdf asdf_asdf_\u0026lt;/em\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e*asdf asdf _asdf_*\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;em\u0026gt;asdf asdf \u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt;\u0026lt;/em\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n**Rule 4:** The opening delimiter must not be followed by a white-space and the closing delimiter must not be preceded\nby a white-space in order for it to be a valid emphasis token.\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eMarkdown\u003c/th\u003e\n      \u003cth\u003eHTML\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e*asdf*\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e* asdf *\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;ul\u0026gt;\u0026lt;li\u0026gt;asdf *\u0026lt;/li\u0026gt;\u0026lt;/ul\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e* asdf*\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;ul\u0026gt;\u0026lt;li\u0026gt;asdf*\u0026lt;/li\u0026gt;\u0026lt;/ul\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e*asdf *\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;*asdf *\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n**Rule 5:** The emphasis token cannot be empty.\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eMarkdown\u003c/th\u003e\n      \u003cth\u003eHTML\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e**\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;**\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e****\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;hr /\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n### Links\n\nRelative links and absolute links with the server’s host name will be treated as internal links, otherwise they will be\ntreated as external links and will automatically get `rel=\"nofollow\"` and `target=\"_blank\"` attributes.\n\n### Notes\n\nNotes follow the [Markdown Extra’s notes syntax](https://michelf.ca/projects/php-markdown/extra#footnotes) but with\nslightly different HTML output to match [Mecha](https://github.com/mecha-cms)’s common naming style. Multi-line notes\ndon’t have to be indented by four spaces as required by Markdown Extra. A space or tab is enough to continue the note.\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eMarkdown\u003c/th\u003e\n      \u003cth\u003eHTML\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003easdf [^1]\u0026#10;\u0026#10;[^1]: asdf\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;asdf \u0026lt;sup id=\"from:1\"\u0026gt;\u0026lt;a href=\"#to:1\" role=\"doc-noteref\"\u0026gt;1\u0026lt;/a\u0026gt;\u0026lt;/sup\u0026gt;\u0026lt;/p\u0026gt;\u0026lt;div role=\"doc-endnotes\"\u0026gt;\u0026lt;hr /\u0026gt;\u0026lt;ol\u0026gt;\u0026lt;li id=\"to:1\" role=\"doc-endnote\"\u0026gt;\u0026lt;p\u0026gt;asdf\u0026amp;#160;\u0026lt;a href=\"#from:1\" role=\"doc-backlink\"\u0026gt;\u0026amp;#8617;\u0026lt;/a\u0026gt;\u0026lt;/p\u0026gt;\u0026lt;/li\u0026gt;\u0026lt;/ol\u0026gt;\u0026lt;/div\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003easdf [^1]\u0026#10;\u0026#10;[^1]:\u0026#10;\u0026#10;  asdf\u0026#10;  ====\u0026#10;\u0026#10;  asdf\u0026#10;  asdf\u0026#10;\u0026#10;      asdf\u0026#10;\u0026#10;  asdf\u0026#10;  asdf\u0026#10;\u0026#10;asdf\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;asdf \u0026lt;sup id=\"from:1\"\u0026gt;\u0026lt;a href=\"#to:1\" role=\"doc-noteref\"\u0026gt;1\u0026lt;/a\u0026gt;\u0026lt;/sup\u0026gt;\u0026lt;/p\u0026gt;\u0026lt;p\u0026gt;asdf\u0026lt;/p\u0026gt;\u0026lt;div role=\"doc-endnotes\"\u0026gt;\u0026lt;hr /\u0026gt;\u0026lt;ol\u0026gt;\u0026lt;li id=\"to:1\" role=\"doc-endnote\"\u0026gt;\u0026lt;h1\u0026gt;asdf\u0026lt;/h1\u0026gt;\u0026lt;p\u0026gt;asdf asdf\u0026lt;/p\u0026gt;\u0026lt;pre\u0026gt;\u0026lt;code\u0026gt;asdf\u0026lt;/code\u0026gt;\u0026lt;/pre\u0026gt;\u0026lt;p\u0026gt;asdf asdf\u0026amp;#160;\u0026lt;a href=\"#from:1\" role=\"doc-backlink\"\u0026gt;\u0026amp;#8617;\u0026lt;/a\u0026gt;\u0026lt;/p\u0026gt;\u0026lt;/li\u0026gt;\u0026lt;/ol\u0026gt;\u0026lt;/div\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n### Soft Break\n\nSoft breaks are collapsed to spaces in non-critical parts such as in paragraphs and list items:\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eMarkdown\u003c/th\u003e\n      \u003cth\u003eHTML\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003easdf asdf asdf asdf\u0026#10;asdf asdf asdf asdf\u0026#10;\u0026#10;asdf asdf asdf asdf\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;asdf asdf asdf asdf asdf asdf asdf asdf\u0026lt;/p\u0026gt;\u0026lt;p\u0026gt;asdf asdf asdf asdf\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n### Code Block\n\nI try to avoid conflict between different Markdown dialects and try to support whatever dialect you are using. For\nexample, since I originally used Markdown Extra, I am used to adding info string with a dot prefix to the fenced code\nblock syntax. This is not supported by Parsedown (or rather, Parsedown doesn’t care about the pattern of the given info\nstring and simply appends `language-` prefix to it, since CommonMark also doesn’t give implementors special rules for\nprocessing info string in fenced code block syntax).\n\nHere’s how the code block results compare across each Markdown converter:\n\n#### Markdown Extra\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eMarkdown\u003c/th\u003e\n      \u003cth\u003eHTML\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e~~~ asdf\u0026#10;asdf\u0026#10;~~~\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;pre\u0026gt;\u0026lt;code class=\"asdf\"\u0026gt;asdf\u0026#10;\u0026lt;/code\u0026gt;\u0026lt;/pre\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e~~~ .asdf\u0026#10;asdf\u0026#10;~~~\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;pre\u0026gt;\u0026lt;code class=\"asdf\"\u0026gt;asdf\u0026#10;\u0026lt;/code\u0026gt;\u0026lt;/pre\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e~~~ asdf asdf\u0026#10;asdf\u0026#10;~~~\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cem\u003eInvalid.\u003c/em\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e~~~ .asdf.asdf\u0026#10;asdf\u0026#10;~~~\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cem\u003eInvalid.\u003c/em\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e~~~ {#asdf.asdf}\u0026#10;asdf\u0026#10;~~~\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;pre\u0026gt;\u0026lt;code class=\"asdf\" id=\"asdf\"\u0026gt;asdf\u0026#10;\u0026lt;/code\u0026gt;\u0026lt;/pre\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e~~~ {#asdf.asdf asdf=asdf}\u0026#10;asdf\u0026#10;~~~\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cem\u003eInvalid.\u003c/em\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n#### Parsedown Extra\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eMarkdown\u003c/th\u003e\n      \u003cth\u003eHTML\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e~~~ asdf\u0026#10;asdf\u0026#10;~~~\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;pre\u0026gt;\u0026lt;code class=\"language-asdf\"\u0026gt;asdf\u0026lt;/code\u0026gt;\u0026lt;/pre\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e~~~ .asdf\u0026#10;asdf\u0026#10;~~~\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;pre\u0026gt;\u0026lt;code class=\"language-.asdf\"\u0026gt;asdf\u0026lt;/code\u0026gt;\u0026lt;/pre\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e~~~ asdf asdf\u0026#10;asdf\u0026#10;~~~\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;pre\u0026gt;\u0026lt;code class=\"language-asdf\"\u0026gt;asdf\u0026lt;/code\u0026gt;\u0026lt;/pre\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e~~~ .asdf.asdf\u0026#10;asdf\u0026#10;~~~\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;pre\u0026gt;\u0026lt;code class=\"language-.asdf.asdf\"\u0026gt;asdf\u0026lt;/code\u0026gt;\u0026lt;/pre\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e~~~ {#asdf.asdf}\u0026#10;asdf\u0026#10;~~~\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;pre\u0026gt;\u0026lt;code class=\"language-{#asdf.asdf}\"\u0026gt;asdf\u0026lt;/code\u0026gt;\u0026lt;/pre\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e~~~ {#asdf.asdf asdf=asdf}\u0026#10;asdf\u0026#10;~~~\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;pre\u0026gt;\u0026lt;code class=\"language-{#asdf.asdf\"\u0026gt;asdf\u0026lt;/code\u0026gt;\u0026lt;/pre\u0026gt;\u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n#### Mine\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eMarkdown\u003c/th\u003e\n      \u003cth\u003eHTML\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e~~~ asdf\u0026#10;asdf\u0026#10;~~~\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;pre\u0026gt;\u0026lt;code class=\"language-asdf\"\u0026gt;asdf\u0026lt;/code\u0026gt;\u0026lt;/pre\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e~~~ .asdf\u0026#10;asdf\u0026#10;~~~\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;pre\u0026gt;\u0026lt;code class=\"asdf\"\u0026gt;asdf\u0026lt;/code\u0026gt;\u0026lt;/pre\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e~~~ asdf asdf\u0026#10;asdf\u0026#10;~~~\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;pre\u0026gt;\u0026lt;code class=\"language-asdf\"\u0026gt;asdf\u0026lt;/code\u0026gt;\u0026lt;/pre\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e~~~ .asdf.asdf\u0026#10;asdf\u0026#10;~~~\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;pre\u0026gt;\u0026lt;code class=\"asdf\"\u0026gt;asdf\u0026lt;/code\u0026gt;\u0026lt;/pre\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e~~~ {#asdf.asdf}\u0026#10;asdf\u0026#10;~~~\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;pre\u0026gt;\u0026lt;code class=\"asdf\" id=\"asdf\"\u0026gt;asdf\u0026lt;/code\u0026gt;\u0026lt;/pre\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e~~~ {#asdf.asdf asdf=asdf}\u0026#10;asdf\u0026#10;~~~\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;pre\u0026gt;\u0026lt;code asdf=\"asdf\" class=\"asdf\" id=\"asdf\"\u0026gt;asdf\u0026lt;/code\u0026gt;\u0026lt;/pre\u0026gt;\u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n### HTML Block\n\nCommonMark doesn’t care about the DOM and therefore also doesn’t care if a HTML element is perfectly balanced or not.\nUnlike the original Markdown syntax specification which doesn’t allow you to convert Markdown syntax inside a HTML\nblock, the CommonMark specification doesn’t limit such a case. It cares about blank lines around the lines that look\nlike a HTML block tag, as specified in [Section 4.6](https://spec.commonmark.org/0.31.2#html-blocks), type 6.\n\nAny text that comes after the opening and/or closing of a HTML block is treated as raw text and is not processed as\nMarkdown syntax. A blank line is required to end the raw HTML block state:\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eMarkdown\u003c/th\u003e\n      \u003cth\u003eHTML\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;div\u0026gt; asdf asdf \u0026#42;asdf\u0026#42; asdf\u0026#10;\u0026lt;/div\u0026gt; asdf asdf \u0026#42;asdf\u0026#42; asdf\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;div\u0026gt; asdf asdf \u0026#42;asdf\u0026#42; asdf\u0026#10;\u0026lt;/div\u0026gt; asdf asdf \u0026#42;asdf\u0026#42; asdf\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;div\u0026gt;\u0026#10;asdf asdf \u0026#42;asdf\u0026#42; asdf\u0026#10;\u0026#10;\u0026lt;/div\u0026gt;\u0026#10;asdf asdf \u0026#42;asdf\u0026#42; asdf\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;div\u0026gt;\u0026#10;asdf asdf \u0026#42;asdf\u0026#42; asdf\u0026lt;/div\u0026gt;\u0026#10;asdf asdf \u0026#42;asdf\u0026#42; asdf\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;div\u0026gt;\u0026#10;\u0026#10;asdf asdf \u0026#42;asdf\u0026#42; asdf\u0026#10;\u0026#10;\u0026lt;/div\u0026gt;\u0026#10;\u0026#10;asdf asdf \u0026#42;asdf\u0026#42; asdf\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;div\u0026gt;\u0026lt;p\u0026gt;asdf asdf \u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt; asdf\u0026lt;/p\u0026gt;\u0026lt;/div\u0026gt;\u0026lt;p\u0026gt;asdf asdf \u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt; asdf\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\nException for types 1, 2, 3, 4, and 5. A line break is enough to end the raw HTML block state:\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eMarkdown\u003c/th\u003e\n      \u003cth\u003eHTML\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;!-- asdf asdf \u0026#42;asdf\u0026#42; asdf --\u0026gt; asdf asdf \u0026#42;asdf\u0026#42; asdf\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;!-- asdf asdf \u0026#42;asdf\u0026#42; asdf --\u0026gt; asdf asdf \u0026#42;asdf\u0026#42; asdf\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;!-- asdf asdf \u0026#42;asdf\u0026#42; asdf --\u0026gt;\u0026#10;asdf asdf \u0026#42;asdf\u0026#42; asdf\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;!-- asdf asdf \u0026#42;asdf\u0026#42; asdf --\u0026gt;\u0026lt;p\u0026gt;asdf asdf \u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt; asdf\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;!-- asdf asdf \u0026#42;asdf\u0026#42; asdf --\u0026gt;\u0026#10;\u0026#10;asdf asdf \u0026#42;asdf\u0026#42; asdf\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;!-- asdf asdf \u0026#42;asdf\u0026#42; asdf --\u0026gt;\u0026lt;p\u0026gt;asdf asdf \u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt; asdf\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\nThe examples below will generate a predictable HTML code, but not because this converter cares about the existing HTML\ntag balance:\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eMarkdown\u003c/th\u003e\n      \u003cth\u003eHTML\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;nav\u0026gt;\u0026#10;\u0026lt;ul\u0026gt;\u0026#10;\u0026lt;li\u0026gt;\u0026#10;\u0026lt;a\u0026gt;asdf\u0026lt;/a\u0026gt;\u0026#10;\u0026lt;/li\u0026gt;\u0026#10;\u0026lt;li\u0026gt;\u0026#10;\u0026lt;a\u0026gt;asdf\u0026lt;/a\u0026gt;\u0026#10;\u0026lt;/li\u0026gt;\u0026#10;\u0026lt;li\u0026gt;\u0026#10;\u0026lt;a\u0026gt;asdf\u0026lt;/a\u0026gt;\u0026#10;\u0026lt;/li\u0026gt;\u0026#10;\u0026lt;/ul\u0026gt;\u0026#10;\u0026lt;/nav\u0026gt;\u0026#10;\u0026#10;asdf asdf \u0026#42;asdf\u0026#42; asdf\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;nav\u0026gt;\u0026#10;\u0026lt;ul\u0026gt;\u0026#10;\u0026lt;li\u0026gt;\u0026#10;\u0026lt;a\u0026gt;asdf\u0026lt;/a\u0026gt;\u0026#10;\u0026lt;/li\u0026gt;\u0026#10;\u0026lt;li\u0026gt;\u0026#10;\u0026lt;a\u0026gt;asdf\u0026lt;/a\u0026gt;\u0026#10;\u0026lt;/li\u0026gt;\u0026#10;\u0026lt;li\u0026gt;\u0026#10;\u0026lt;a\u0026gt;asdf\u0026lt;/a\u0026gt;\u0026#10;\u0026lt;/li\u0026gt;\u0026#10;\u0026lt;/ul\u0026gt;\u0026#10;\u0026lt;/nav\u0026gt;\u0026lt;p\u0026gt;asdf asdf \u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt; asdf\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;nav\u0026gt;\u0026#10;  \u0026lt;ul\u0026gt;\u0026#10;    \u0026lt;li\u0026gt;\u0026#10;      \u0026lt;a\u0026gt;asdf\u0026lt;/a\u0026gt;\u0026#10;    \u0026lt;/li\u0026gt;\u0026#10;    \u0026lt;li\u0026gt;\u0026#10;      \u0026lt;a\u0026gt;asdf\u0026lt;/a\u0026gt;\u0026#10;    \u0026lt;/li\u0026gt;\u0026#10;    \u0026lt;li\u0026gt;\u0026#10;      \u0026lt;a\u0026gt;asdf\u0026lt;/a\u0026gt;\u0026#10;    \u0026lt;/li\u0026gt;\u0026#10;  \u0026lt;/ul\u0026gt;\u0026#10;\u0026lt;/nav\u0026gt;\u0026#10;\u0026#10;asdf asdf \u0026#42;asdf\u0026#42; asdf\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;nav\u0026gt;\u0026#10;  \u0026lt;ul\u0026gt;\u0026#10;    \u0026lt;li\u0026gt;\u0026#10;      \u0026lt;a\u0026gt;asdf\u0026lt;/a\u0026gt;\u0026#10;    \u0026lt;/li\u0026gt;\u0026#10;    \u0026lt;li\u0026gt;\u0026#10;      \u0026lt;a\u0026gt;asdf\u0026lt;/a\u0026gt;\u0026#10;    \u0026lt;/li\u0026gt;\u0026#10;    \u0026lt;li\u0026gt;\u0026#10;      \u0026lt;a\u0026gt;asdf\u0026lt;/a\u0026gt;\u0026#10;    \u0026lt;/li\u0026gt;\u0026#10;  \u0026lt;/ul\u0026gt;\u0026#10;\u0026lt;/nav\u0026gt;\u0026lt;p\u0026gt;asdf asdf \u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt; asdf\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\nYou will understand why when you add a number of blank lines at any point in the HTML block:\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eMarkdown\u003c/th\u003e\n      \u003cth\u003eHTML\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;nav\u0026gt;\u0026#10;\u0026lt;ul\u0026gt;\u0026#10;\u0026lt;li\u0026gt;\u0026#10;\u0026lt;a\u0026gt;\u0026#10;\u0026#10;asdf\u0026lt;/a\u0026gt;\u0026#10;\u0026lt;/li\u0026gt;\u0026#10;\u0026#10;\u0026lt;li\u0026gt;\u0026#10;\u0026lt;a\u0026gt;asdf\u0026lt;/a\u0026gt;\u0026#10;\u0026lt;/li\u0026gt;\u0026#10;\u0026lt;li\u0026gt;\u0026#10;\u0026lt;a\u0026gt;asdf\u0026lt;/a\u0026gt;\u0026#10;\u0026lt;/li\u0026gt;\u0026#10;\u0026lt;/ul\u0026gt;\u0026#10;\u0026lt;/nav\u0026gt;\u0026#10;\u0026#10;asdf asdf \u0026#42;asdf\u0026#42; asdf\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;nav\u0026gt;\u0026#10;\u0026lt;ul\u0026gt;\u0026#10;\u0026lt;li\u0026gt;\u0026#10;\u0026lt;a\u0026gt;\u0026lt;p\u0026gt;asdf\u0026lt;/a\u0026gt;\u0026lt;/p\u0026gt;\u0026lt;/li\u0026gt;\u0026lt;li\u0026gt;\u0026#10;\u0026lt;a\u0026gt;asdf\u0026lt;/a\u0026gt;\u0026#10;\u0026lt;/li\u0026gt;\u0026#10;\u0026lt;li\u0026gt;\u0026#10;\u0026lt;a\u0026gt;asdf\u0026lt;/a\u0026gt;\u0026#10;\u0026lt;/li\u0026gt;\u0026#10;\u0026lt;/ul\u0026gt;\u0026#10;\u0026lt;/nav\u0026gt;\u0026lt;p\u0026gt;asdf asdf \u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt; asdf\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;nav\u0026gt;\u0026#10;  \u0026lt;ul\u0026gt;\u0026#10;    \u0026lt;li\u0026gt;\u0026#10;      \u0026lt;a\u0026gt;\u0026#10;\u0026#10;      asdf\u0026lt;/a\u0026gt;\u0026#10;    \u0026lt;/li\u0026gt;\u0026#10;\u0026#10;    \u0026lt;li\u0026gt;\u0026#10;      \u0026lt;a\u0026gt;asdf\u0026lt;/a\u0026gt;\u0026#10;    \u0026lt;/li\u0026gt;\u0026#10;    \u0026lt;li\u0026gt;\u0026#10;      \u0026lt;a\u0026gt;asdf\u0026lt;/a\u0026gt;\u0026#10;    \u0026lt;/li\u0026gt;\u0026#10;  \u0026lt;/ul\u0026gt;\u0026#10;\u0026lt;/nav\u0026gt;\u0026#10;\u0026#10;asdf asdf \u0026#42;asdf\u0026#42; asdf\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;nav\u0026gt;\u0026#10;  \u0026lt;ul\u0026gt;\u0026#10;    \u0026lt;li\u0026gt;\u0026#10;      \u0026lt;a\u0026gt;\u0026lt;pre\u0026gt;\u0026lt;code\u0026gt;  asdf\u0026amp;lt;/a\u0026amp;gt;\u0026#10;\u0026amp;lt;/li\u0026amp;gt;\u0026#10;\u0026#10;\u0026amp;lt;li\u0026amp;gt;\u0026#10;  \u0026amp;lt;a\u0026amp;gt;asdf\u0026amp;lt;/a\u0026amp;gt;\u0026#10;\u0026amp;lt;/li\u0026amp;gt;\u0026#10;\u0026amp;lt;li\u0026amp;gt;\u0026#10;  \u0026amp;lt;a\u0026amp;gt;asdf\u0026amp;lt;/a\u0026amp;gt;\u0026#10;\u0026amp;lt;/li\u0026amp;gt;\u0026lt;/code\u0026gt;\u0026lt;/pre\u0026gt;\u0026lt;/ul\u0026gt;\u0026#10;\u0026lt;/nav\u0026gt;\u0026lt;p\u0026gt;asdf asdf \u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt; asdf\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\nMarkdown Extra features the `markdown` attribute on HTML to allow you to convert Markdown syntax to HTML in a HTML\nblock. In this converter, the feature will not work. For now, I have no plans to add such feature to avoid DOM parsing\ntasks as much as possible. This also ensured me to avoid on using [PHP `dom`](https://www.php.net/book.dom).\n\nHowever, if you add a blank line, it’s as if the feature works (although the `markdown` attribute is still there, it\ndoesn’t affect the HTML when rendered in the browser window). If you’re used to adding a blank line after the opening\nHTML block tag and before the closing HTML block tag, you should be okay.\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eMarkdown\u003c/th\u003e\n      \u003cth\u003eHTML\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;div markdown=\"1\"\u0026gt;\u0026#10;asdf asdf \u0026#42;asdf\u0026#42; asdf\u0026#10;\u0026lt;/div\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;div markdown=\"1\"\u0026gt;\u0026#10;asdf asdf \u0026#42;asdf\u0026#42; asdf\u0026#10;\u0026lt;/div\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;div markdown=\"1\"\u0026gt;\u0026#10;\u0026#10;asdf asdf \u0026#42;asdf\u0026#42; asdf\u0026#10;\u0026lt;/div\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;div markdown=\"1\"\u0026gt;\u0026lt;p\u0026gt;asdf asdf \u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt; asdf\u0026lt;/p\u0026gt;\u0026lt;/div\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\nOpening an inline HTML element will not trigger the raw HTML block state unless the opening and closing tags stand alone\non a single line. This is explained in [Section 4.6](https://spec.commonmark.org/0.31.2#html-blocks), type 7:\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eMarkdown\u003c/th\u003e\n      \u003cth\u003eHTML\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;span\u0026gt;asdf \u0026#42;asdf\u0026#42;\u0026lt;/span\u0026gt; asdf \u0026#42;asdf\u0026#42; asdf\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;span\u0026gt;asdf \u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt;\u0026lt;/span\u0026gt; asdf \u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt; asdf\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;span\u0026gt;\u0026#10;asdf \u0026#42;asdf\u0026#42;\u0026#10;\u0026lt;/span\u0026gt;\u0026#10;asdf \u0026#42;asdf\u0026#42; asdf\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;span\u0026gt;\u0026#10;asdf \u0026#42;asdf\u0026#42;\u0026#10;\u0026lt;/span\u0026gt;\u0026#10;asdf \u0026#42;asdf\u0026#42; asdf\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\nSince CommonMark doesn’t care about HTML structure, the examples below will also conform to the specification, even if\nthey result in broken HTML. However, these are very rarely intentionally written by hand, so such cases are very\nunlikely to occur:\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eMarkdown\u003c/th\u003e\n      \u003cth\u003eHTML\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;h1\u0026gt;\u0026#10;\u0026#10;asdf asdf \u0026#42;asdf\u0026#42; asdf\u0026#10;\u0026#10;\u0026lt;/h1\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;h1\u0026gt;\u0026lt;p\u0026gt;asdf asdf \u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt; asdf\u0026lt;/p\u0026gt;\u0026lt;/h1\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026#10;\u0026#10;asdf asdf \u0026#42;asdf\u0026#42; asdf\u0026#10;\u0026#10;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;p\u0026gt;asdf asdf \u0026lt;em\u0026gt;asdf\u0026lt;/em\u0026gt; asdf\u0026lt;/p\u0026gt;\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n### Image Block\n\nMarkdown was initiated before the HTML5 era. When the `\u003cfigure\u003e` element was introduced, people started using it as a\nfeature to display an image with a caption. Most Markdown converters will convert image syntax that stands alone on a\nsingle line as an image element wrapped in a paragraph element in the output. My converter would instead wrap it in a\nfigure element. Because for now, it seems like a figure element would be more desirable in this situation.\n\nParagraphs that appear below it will be taken as the image caption if you prepend a number of spaces less than 4.\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eMarkdown\u003c/th\u003e\n      \u003cth\u003eHTML\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e![asdf](asdf.jpg)\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;figure\u0026gt;\u0026lt;img alt=\"asdf\" src=\"asdf.jpg\" /\u0026gt;\u0026lt;/figure\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e![asdf](asdf.jpg)\u0026#10; asdf\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;figure\u0026gt;\u0026lt;img alt=\"asdf\" src=\"asdf.jpg\" /\u0026gt;\u0026lt;figcaption\u0026gt;asdf\u0026lt;/figcaption\u0026gt;\u0026lt;/figure\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e![asdf](asdf.jpg)\u0026#10; asdf\u0026#10;\u0026#10; asdf\u0026#10;\u0026#10;asdf\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;figure\u0026gt;\u0026lt;img alt=\"asdf\" src=\"asdf.jpg\" /\u0026gt;\u0026lt;figcaption\u0026gt;\u0026lt;p\u0026gt;asdf\u0026lt;/p\u0026gt;\u0026lt;p\u0026gt;asdf\u0026lt;/p\u0026gt;\u0026lt;/figcaption\u0026gt;\u0026lt;/figure\u0026gt;\u0026lt;p\u0026gt;asdf\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e![asdf](asdf.jpg) asdf\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;p\u0026gt;\u0026lt;img alt=\"asdf\" src=\"asdf.jpg\" /\u0026gt; asdf\u0026lt;/p\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\nFYI, this pattern should also be valid for average Markdown files. And so it will be gracefully degraded when parsed by\nother Markdown converters.\n\n### List Block\n\nList blocks follow the CommonMark specifications with one exception: if the next ordered list item uses a number that is\nless than the number of the previous ordered list item, a new list block will be created. This is different from the\noriginal specification, which does not care about the literal value of the number.\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eMarkdown\u003c/th\u003e\n      \u003cth\u003eHTML\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e1. asdf\u0026#10;2. asdf\u0026#10;3. asdf\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;ol\u0026gt;\u0026lt;li\u0026gt;asdf\u0026lt;/li\u0026gt;\u0026lt;li\u0026gt;asdf\u0026lt;/li\u0026gt;\u0026lt;li\u0026gt;asdf\u0026lt;/li\u0026gt;\u0026lt;/ol\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e1. asdf\u0026#10;1. asdf\u0026#10;1. asdf\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;ol\u0026gt;\u0026lt;li\u0026gt;asdf\u0026lt;/li\u0026gt;\u0026lt;li\u0026gt;asdf\u0026lt;/li\u0026gt;\u0026lt;li\u0026gt;asdf\u0026lt;/li\u0026gt;\u0026lt;/ol\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e1. asdf\u0026#10;2. asdf\u0026#10;1. asdf\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;ol\u0026gt;\u0026lt;li\u0026gt;asdf\u0026lt;/li\u0026gt;\u0026lt;li\u0026gt;asdf\u0026lt;/li\u0026gt;\u0026lt;/ol\u0026gt;\u0026lt;ol\u0026gt;\u0026lt;li\u0026gt;asdf\u0026lt;/li\u0026gt;\u0026lt;/ol\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n### Table Block\n\nTable blocks follow the [Markdown Extra’s table block syntax](https://michelf.ca/projects/php-markdown/extra#table).\nHowever, there are a few additional features and rules:\n\n - The actual number of columns follows the number of columns in the table header separator. If you have columns in\n   table header and/or table data with a number that exceeds the actual number of columns, the excess columns will be\n   discarded. If you have columns in table header and/or table data with a number that is less than the actual number of\n   columns, several empty columns will be added automatically to the right side.\n - Literal pipe characters in table columns must be escaped. Exceptions are those that appear in code span and attribute\n   values of raw HTML tags.\n - Header-less table is supported, but may not be compatible with other Markdown converters. Consider using this feature\n   as rarely as possible, unless you have no plans to switch to other Markdown converters in the future.\n - Table caption is supported and can be created using the same syntax as the image block’s caption syntax.\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eMarkdown\u003c/th\u003e\n      \u003cth\u003eHTML\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003easdf | asdf\u0026#10;---- | ----\u0026#10;asdf | asdf\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;table\u0026gt;\u0026lt;thead\u0026gt;\u0026lt;tr\u0026gt;\u0026lt;th\u0026gt;asdf\u0026lt;/th\u0026gt;\u0026lt;th\u0026gt;asdf\u0026lt;/th\u0026gt;\u0026lt;/tr\u0026gt;\u0026lt;/thead\u0026gt;\u0026lt;tbody\u0026gt;\u0026lt;tr\u0026gt;\u0026lt;td\u0026gt;asdf\u0026lt;/td\u0026gt;\u0026lt;td\u0026gt;asdf\u0026lt;/td\u0026gt;\u0026lt;/tr\u0026gt;\u0026lt;/tbody\u0026gt;\u0026lt;/table\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003easdf | asdf\u0026#10;---- | ----\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;table\u0026gt;\u0026lt;thead\u0026gt;\u0026lt;tr\u0026gt;\u0026lt;th\u0026gt;asdf\u0026lt;/th\u0026gt;\u0026lt;th\u0026gt;asdf\u0026lt;/th\u0026gt;\u0026lt;/tr\u0026gt;\u0026lt;/thead\u0026gt;\u0026lt;/table\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e---- | ----\u0026#10;asdf | asdf\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode\u003e\u0026lt;table\u0026gt;\u0026lt;tbody\u0026gt;\u0026lt;tr\u0026gt;\u0026lt;td\u0026gt;asdf\u0026lt;/td\u0026gt;\u0026lt;td\u0026gt;asdf\u0026lt;/td\u0026gt;\u0026lt;/tr\u0026gt;\u0026lt;/tbody\u0026gt;\u0026lt;/table\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\nXSS\n---\n\nThis converter is intended only to convert Markdown syntax to HTML based on the\n[CommonMark](https://spec.commonmark.org/0.31.2) specification. It doesn’t care about your user input. I have no\nintention of adding any special security features in the future, sorry. The attribute syntax feature may be a security\nrisk for you if you want to use this converter on your comment entries, for example:\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eMarkdown\u003c/th\u003e\n      \u003cth\u003eHTML\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode class=\"language-markdown\"\u003e![asdf](asdf.asdf) {onerror=\"alert('Yo!')\"}\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003cpre\u003e\u003ccode class=\"language-html\"\u003e\u0026lt;img alt=\"asdf\" onerror=\"alert(\u0026amp;apos;Yo!\u0026amp;apos;)\" src=\"asdf.asdf\" /\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\nThere should be many specialized PHP applications already that have specific tasks to deal with XSS, so consider\npost-processing the generated HTML markup before putting it out to the web:\n\n - [ezyang/htmlpurifier](https://github.com/ezyang/htmlpurifier)\n - [voku/anti-xss](https://github.com/voku/anti-xss)\n\nTests\n-----\n\nClone this repository into the root of your web server that supports PHP and then you can open the `test/from.php` and\n`test/to.php` file with your browser to see the result and the performance of this converter in various cases.\n\nTweaks\n------\n\nNot all Markdown dialects are supported for various reasons. Some of the modification methods below can be implemented\nto add features that you might find in other Markdown converters.\n\nYour Markdown content is represented as variable `$value`. If you modify the content before the function\n`from_markdown()` is called, it means that you modify the Markdown content before it is converted. If you modify the\ncontent after the function `from_markdown()` is called, it means that you modify the results of the Markdown conversion.\n\n### Globally Reusable Functions\n\nTo make `from_markdown()` and `to_markdown()` functions reusable globally, use this method:\n\n~~~ php\n\u003c?php\n\nrequire 'from.php';\nrequire 'to.php';\n\n// Or, if you are using Composer…\n// require 'vendor/autoload.php';\n\nfunction from_markdown(...$v) {\n    return x\\markdown\\from(...$v);\n}\n\nfunction to_markdown(...$v) {\n    return x\\markdown\\to(...$v);\n}\n~~~\n\n### XHTML to HTML5\n\nThis converter escapes invalid HTML elements and takes care of HTML special characters that you put in the Markdown\nattribute syntax, so it is safe to replace `' /\u003e'` with `'\u003e'` directly from the results of the Markdown conversion:\n\n~~~ php\n$value = from_markdown($value);\n\n$value = strtr($value, [' /\u003e' =\u003e '\u003e']);\n\necho $value;\n~~~\n\n### Strike\n\nThis method allows you to add strike-through syntax, as you may have already noticed in the\n[GFM specification](https://github.github.com/gfm):\n\n~~~ php\n$value = from_markdown($value);\n\n$value = preg_replace('/((?\u003c![~])[~]{1,2}(?![~]))([^~]+)\\1/', '\u003cdel\u003e$2\u003c/del\u003e', $value);\n\necho $value;\n~~~\n\n### Task List\n\nI am against the task list feature because it promotes bad practices to abuse the form input element. Although from the\npresentation side it displays a check box interface correctly, I still believe that input elements should ideally be\nused inside a form element. There are several Unicode symbols that are more suitable and easier to read from the\nMarkdown source like \u0026#x2610; and \u0026#x2612;, which means that this feature can actually be made using the existing list\nfeature:\n\n~~~ md\n- ☒ asdf\n- ☐ asdf\n- ☐ asdf\n~~~\n\nIn case you need it, or don’t want to update your existing task list syntax in your Markdown files, here’s the hack:\n\n~~~ php\n$value = from_markdown($value);\n\n$value = strtr($value, [\n    '\u003cli\u003e\u003cp\u003e[ ] ' =\u003e '\u003cli\u003e\u003cp\u003e\u0026#x2610; ',\n    '\u003cli\u003e\u003cp\u003e[x] ' =\u003e '\u003cli\u003e\u003cp\u003e\u0026#x2612; ',\n    '\u003cli\u003e[ ] ' =\u003e '\u003cli\u003e\u0026#x2610; ',\n    '\u003cli\u003e[x] ' =\u003e '\u003cli\u003e\u0026#x2612; '\n]);\n\necho $value;\n~~~\n\n### Pre-Defined Abbreviations, Notes, and References\n\nBy inserting abbreviations, notes, and references at the end of the Markdown content, it will be as if you had\npre-defined abbreviations, notes, and references feature. This should be placed at the end of the Markdown content,\nbecause according to the [link reference definitions](https://spec.commonmark.org/0.31.2#example-204) specification, the\nfirst declared reference always takes precedence:\n\n~~~ php\n$abbreviations = [\n    'CSS' =\u003e 'Cascading Style Sheet',\n    'HTML' =\u003e 'Hyper Text Markup Language',\n    'JS' =\u003e 'JavaScript'\n];\n\n$references = [\n    'mecha-cms' =\u003e ['https://github.com/mecha-cms', 'Mecha CMS', []],\n    'taufik-nurrohman' =\u003e ['https://github.com/taufik-nurrohman', 'Taufik Nurrohman', []],\n];\n\n$suffix = \"\";\n\nif (!empty($abbreviations)) {\n    foreach ($abbreviations as $k =\u003e $v) {\n        $k = strtr($k, [\n            '[' =\u003e '\\[',\n            ']' =\u003e '\\]'\n        ]);\n        $v = trim(preg_replace('/\\s+/', ' ', $v));\n        $suffix .= \"\\n*[\" . $k . ']: ' . $v;\n    }\n}\n\nif (!empty($references)) {\n    foreach ($references as $k =\u003e $v) {\n        [$link, $title, $attributes] = $v;\n        $k = strtr($k, [\n            '[' =\u003e '\\[',\n            ']' =\u003e '\\]'\n        ]);\n        if (\"\" === $link || false !== strpos($link, ' ')) {\n            $link = '\u003c' . $link . '\u003e';\n        }\n        $reference = '[' . $k . ']: ' . $link;\n        if (!empty($title)) {\n            $reference .= \" '\" . strtr($title, [\"'\" =\u003e \"\\\\'\"]) . \"'\";\n        }\n        if (!empty($attributes)) {\n            foreach ($attributes as $kk =\u003e \u0026$vv) {\n                // `{.asdf}`\n                if ('class' === $kk) {\n                    $vv = '.' . trim(preg_replace('/\\s+/', '.', $vv));\n                    continue;\n                }\n                // `{#asdf}`\n                if ('id' === $kk) {\n                    $vv = '#' . $vv;\n                    continue;\n                }\n                // `{asdf}`\n                if (true === $vv) {\n                    $vv = $kk;\n                    continue;\n                }\n                // `{asdf=\"\"}`\n                if (\"\" === $vv) {\n                    $vv = $kk . '=\"\"';\n                    continue;\n                }\n                // `{asdf='asdf'}`\n                $vv = $kk . \"='\" . strtr($vv, [\"'\" =\u003e \"\\\\'\"]) . \"'\";\n            }\n            unset($vv);\n            sort($attributes);\n            $attributes = trim(strtr(implode(' ', $attributes), [\n                ' #' =\u003e '#',\n                ' .' =\u003e '.'\n            ]));\n            $reference .= ' {' . $attributes . '}';\n        }\n        $suffix .= \"\\n\" . $reference;\n    }\n}\n\n$value = from_markdown($value . \"\\n\" . $suffix);\n\necho $value;\n~~~\n\n### Pre-Defined Header’s ID\n\nAdd an automatic `id` attribute to headers level 2 through 6 if it’s not set, and then prepend an anchor element that\npoints to it:\n\n~~~ php\n$value = from_markdown($value);\n\nif ($value \u0026\u0026 false !== strpos($value, '\u003c/h')) {\n    $value = preg_replace_callback('/\u003c(h[2-6])(\\s(?\u003e\"[^\"]*\"|\\'[^\\']*\\'|[^\u003e])*)?\u003e([\\s\\S]+?)\u003c\\/\\1\u003e/', static function ($m) {\n        if (!empty($m[2]) \u0026\u0026 false !== strpos($m[2], 'id=') \u0026\u0026 preg_match('/\\bid=(\"[^\"]+\"|\\'[^\\']+\\'|[^\\/\u003e\\s]+)/', $m[2], $n)) {\n            if ('\"' === $n[1][0] \u0026\u0026 '\"' === substr($n[1], -1)) {\n                $id = substr($n[1], 1, -1);\n            } else if (\"'\" === $n[1][0] \u0026\u0026 \"'\" === substr($n[1], -1)) {\n                $id = substr($n[1], 1, -1);\n            } else {\n                $id = $n[1];\n            }\n            $m[3] = '\u003ca href=\"#' . htmlspecialchars($id) . '\" style=\"text-decoration: none;\"\u003e⚓\u003c/a\u003e ' . $m[3];\n            return '\u003c' . $m[1] . $m[2] . '\u003e' . $m[3] . '\u003c/' . $m[1] . '\u003e';\n        }\n        $id = trim(preg_replace('/[^a-z\\x{4e00}-\\x{9fa5}\\d]+/u', '-', strtolower($m[3])), '-');\n        $m[3] = '\u003ca href=\"#' . htmlspecialchars($id) . '\" style=\"text-decoration: none;\"\u003e⚓\u003c/a\u003e ' . $m[3];\n        return '\u003c' . $m[1] . ($m[2] ?? \"\") . ' id=\"' . htmlspecialchars($id) . '\"\u003e' . $m[3] . '\u003c/' . $m[1] . '\u003e';\n    }, $value);\n}\n\necho $value;\n~~~\n\n### Idea: Embed Syntax\n\nThe [CommonMark specification for automatic links](https://spec.commonmark.org/0.31.2#autolinks) doesn’t limit specific\ntypes of URL protocols. It just specifies the pattern so we can take advantage of the automatic link syntax to render it\nas a kind of “embed” syntax, which you can then turn it into a chunk of HTML elements.\n\nI’m sure this idea has never been done before and that’s why I want to be the first to mention it. But I’m not going to\nintegrate this feature directly into my converter to keep it slim. I just want to give you a couple of ideas.\n\nBe aware that these tweaks are very naive, as they will directly convert the “embed” syntax without taking the block\ntype into account. You may need to use [this filter](https://github.com/taufik-nurrohman/markdown-filter) to replace the\n“embed” syntax only in certain block types, e.g. to ignore the “embed” syntax inside a fenced code block syntax.\n\n#### YouTube Video Embed\n\nAn embed syntax to display a YouTube video by video ID.\n\n~~~ md\n\u003cyoutube:dQw4w9WgXcQ\u003e\n~~~\n\n~~~ php\n$value = preg_replace('/^[ ]{0,3}\u003cyoutube:([^\u003e]+)\u003e\\s*$/m', '\u003ciframe src=\"https://www.youtube.com/embed/$1\"\u003e\u003c/iframe\u003e', $value);\n\n$value = from_markdown($value);\n\necho $value;\n~~~\n\n#### GitHub Gist Embed\n\nAn embed syntax to display a GitHub gist by gist ID.\n\n~~~ md\n\u003cgist:9c96049ca6c66e30e50793f5aef4818b\u003e\n~~~\n\n~~~ php\n$value = preg_replace('/^[ ]{0,3}\u003cgist:([^\u003e]+)\u003e\\s*$/m', '\u003cscript src=\"https://gist.github.com/taufik-nurrohman/$1.js\"\u003e\u003c/script\u003e', $value);\n\n$value = from_markdown($value);\n\necho $value;\n~~~\n\n#### Form Embed\n\nAn embed syntax to display a HTML form that was generated from the server side with a reference ID of `18a4596d42c` and\na `title` parameter to customize the HTML form title.\n\n~~~ md\n\u003cform:18a4596d42c?title=Form+Title\u003e\n~~~\n\n~~~ php\n$value = preg_replace_callback('/^[ ]{0,3}\u003cform:([^#\u003e?]+)([?][^#\u003e]*)?([#][^\u003e]*)?\u003e\\s*$/m', static function ($m) {\n    $path = $m[1];\n    $value = \"\";\n    parse_str(substr($m[2] ?? \"\", 1), $state);\n    $value .= '\u003cform action=\"/form/' . $path . '\" method=\"post\"\u003e';\n    if (!empty($state['title'])) {\n        $value .= '\u003ch1\u003e' . $state['title'] . '\u003c/h1\u003e';\n    }\n    // … etc.\n    // Be careful not to include blank line(s), or the raw HTML block state will end before the HTML form is complete!\n    $value .= '\u003c/form\u003e';\n    return $value;\n}, $value);\n\n$value = from_markdown($value);\n\necho $value;\n~~~\n\n### Idea: Note Block\n\nSeveral people have discussed this feature, and I think I like\n[this answer](https://stackoverflow.com/a/41449789/1163000) the most. The syntax is compatible with native Markdown\nsyntax, which is nice to look at directly through the Markdown source, even when it gets rendered to HTML:\n\n~~~ md\n------------------------------\n\n  **NOTE:** asdf asdf asdf\n\n------------------------------\n~~~\n\n~~~ md\n------------------------------\n\n  **NOTE:**\n\n  asdf asdf asdf asdf\n  asdf asdf asdf asdf\n\n  asdf asdf asdf asdf\n\n------------------------------\n~~~\n\nMost Markdown converters will render the syntax above to this HTML, which is still acceptable to be treated as a note\nblock from its presentation, despite its broken semantic:\n\n~~~ html\n\u003chr /\u003e\u003cp\u003e\u003cstrong\u003eNOTE:\u003c/strong\u003e asdf asdf asdf\u003c/p\u003e\u003chr /\u003e\n~~~\n\n~~~ html\n\u003chr /\u003e\u003cp\u003e\u003cstrong\u003eNOTE:\u003c/strong\u003e\u003c/p\u003e\u003cp\u003easdf asdf asdf asdf asdf asdf asdf asdf\u003c/p\u003e\u003cp\u003easdf asdf asdf asdf\u003c/p\u003e\u003chr /\u003e\n~~~\n\nWith regular expressions, you can improve its [semantic](https://w3c.github.io/aria#note):\n\n~~~ php\n$value = from_markdown($value);\n\n$value = preg_replace_callback('/\u003chr\\s*\\/?\u003e(\u003cp\u003e\u003cstrong\u003eNOTE:\u003c\\/strong\u003e[\\s\\S]*?\u003c\\/p\u003e)\u003chr\\s*\\/?\u003e/', static function ($m) {\n    return '\u003cdiv role=\"note\"\u003e' . $m[1] . '\u003c/div\u003e';\n}, $value);\n\necho $value;\n~~~\n\nLicense\n-------\n\nThis library is licensed under the [MIT License](LICENSE). Please consider\n[donating 💰](https://github.com/sponsors/taufik-nurrohman) if you benefit financially from this library.\n\nLinks\n-----\n\n - Autumn image sample by [@blmiers2](https://www.flickr.com/photos/41304517@N00/6250498399)\n - Emoticon image sample by [@emoticons4u](https://web.archive.org/web/20090117060451/http://emoticons4u.com) (web archive)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftaufik-nurrohman%2Fmarkdown","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftaufik-nurrohman%2Fmarkdown","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftaufik-nurrohman%2Fmarkdown/lists"}