Moon Markdown is designed around one renderer and several ways to use it. The
same MoonBit render(markdown) core is shared by the CLI and the browser UI, so
the output stays consistent across entry points.
Then open http://127.0.0.1:8080/web/. The page loads the generated MoonBit
JavaScript from _build/js/debug/build/web/web.js. Run moon build --target js
again after changing MoonBit source code.
Part 2: Project Details
Status
Moon Markdown currently provides a reusable library API, a CLI file converter,
and a local browser UI. The parser intentionally covers a small syntax surface
first, with predictable HTML escaping and tests for each supported feature.
Supported Syntax
Category
Syntax
Example
ATX Headings
# through ######
## Section → <h2>Section</h2>
Setext Headings
Underline with = or -
Rendered as plain text (not yet supported)
Paragraphs
Consecutive non-empty lines
Wrapped in <p>…</p>
Hard line break
Two trailing spaces or backslash at end of line
Inserts <br>
Emphasis
*italic* or _italic_
<em>italic</em>
Strong
**bold** or __bold__
<strong>bold</strong>
Strong+Emphasis
***both*** or ___both___
<strong><em>both</em></strong>
Inline code
`code` or ``code with ticks`` `
<code>code</code>
Links (inline)
[label](url)
<a href="url">label</a>
Links (reference)
[label][ref] with [ref]: url
Resolved to inline link
Links (shortcut)
[ref] with [ref]: url
Resolved to inline link
Links (autolink)
<https://example.com><user@example.com>
<a href="…">…</a> or mailto:
Images (inline)

<img alt="alt" src="src">
Images (reference)
![alt][ref] with [ref]: src
Resolved to inline image
Blockquotes
> line
<blockquote>…</blockquote>
Nested blockquotes
> > line
Nested <blockquote> elements
Unordered lists
-, *, +
<ul><li>…</li></ul>
Ordered lists
1., 1)
<ol><li>…</li></ol>
Task lists
- [x] done- [ ] todo
Checkbox <input type="checkbox" disabled>
Indented code blocks
4 spaces or tab
<pre><code>…</code></pre>
Fenced code blocks
``` or ~~~
<pre><code>…</code></pre>
Horizontal rules
---, ***, ___
<hr>
Pipe tables
| cell | cell | with separator row
<table><tr><td>…</td></tr></table>
HTML escaping
&, <, >, "
&<>"
Backslash escaping
\*literal\*
Characters preserved as-is
Strikethrough
~~text~~
Not yet supported
Footnotes
[^1]
Not yet supported
Example Walkthrough: example.md → output.html
The repository includes example.md and output.html as a comprehensive
input/output pair that exercises every supported syntax feature.
Run the conversion:
moon run cli --target js example.md output.html
1. Headings
ATX headings from level 1 to 6 are fully supported. The renderer also strips
trailing # characters from closing heading hashes.
Setext headings (=== and --- underlines) are parsed as plain paragraphs
because they are not yet supported.
2. Paragraphs and Line Breaks
A paragraph continues across multiple source lines until an empty line is
encountered. Trailing whitespace or backslash at end of line produces a hard
line break:
Note: Nested lists (second-level indentation) and loose lists (paragraphs inside
list items) are not yet fully supported; the renderer produces a best-effort
structure that may differ from CommonMark expectations.
8. Code Blocks
Indented code blocks (4 spaces / tab) and fenced code blocks (with ``` or
~~~ delimiters) are both supported. Code content is HTML-escaped.
Input:
function indentedCodeBlock() {
return "<escaped>";
}
Text content is HTML-escaped by default. This includes plain text, inline code,
link labels, image alt text, link URLs, and image sources, so input like <tag>
is rendered as <tag>.
Code block contents are also escaped, but inline markup is not expanded inside
code blocks.
License
Moon Markdown is licensed under the Apache License 2.0.
Moon Markdown
English | 简体中文
Moon Markdown is a small Markdown to HTML renderer written in MoonBit.
It focuses on a practical, small Markdown subset that is easy to embed in MoonBit tools, examples, documentation generators, and learning projects.
Live Demo: moonbit.submergepsc.asia
Part 1: Use Moon Markdown
Moon Markdown is designed around one renderer and several ways to use it. The same MoonBit
render(markdown)core is shared by the CLI and the browser UI, so the output stays consistent across entry points.The easiest way to try it is the live demo at moonbit.submergepsc.asia. The demo provides:
CLI
Use the CLI package to convert Markdown files from the command line.
Render a Markdown file to stdout:
Render a Markdown file into an HTML file:
Run the included input/output fixture:
Library API
Import the package and call
render(markdown)with a Markdown string:renderreturns an HTML string:Local Development
For local development, clone the repository and run the standard MoonBit checks:
After this package is published to mooncakes.io, installation instructions will be updated with the real package command.
To run the web UI locally:
Then open
http://127.0.0.1:8080/web/. The page loads the generated MoonBit JavaScript from_build/js/debug/build/web/web.js. Runmoon build --target jsagain after changing MoonBit source code.Part 2: Project Details
Status
Moon Markdown currently provides a reusable library API, a CLI file converter, and a local browser UI. The parser intentionally covers a small syntax surface first, with predictable HTML escaping and tests for each supported feature.
Supported Syntax
#through######## Section→<h2>Section</h2>=or-<p>…</p><br>*italic*or_italic_<em>italic</em>**bold**or__bold__<strong>bold</strong>***both***or___both___<strong><em>both</em></strong>`code`or``code withticks`` `<code>code</code>[label](url)<a href="url">label</a>[label][ref]with[ref]: url[ref]with[ref]: url<https://example.com><user@example.com><a href="…">…</a>ormailto:<img alt="alt" src="src">![alt][ref]with[ref]: src> line<blockquote>…</blockquote>> > line<blockquote>elements-,*,+<ul><li>…</li></ul>1.,1)<ol><li>…</li></ol>- [x] done- [ ] todo<input type="checkbox" disabled><pre><code>…</code></pre>```or~~~<pre><code>…</code></pre>---,***,___<hr>| cell | cell |with separator row<table><tr><td>…</td></tr></table>&,<,>,"&<>"\*literal\*~~text~~[^1]Example Walkthrough:
example.md→output.htmlThe repository includes
example.mdandoutput.htmlas a comprehensive input/output pair that exercises every supported syntax feature.Run the conversion:
1. Headings
ATX headings from level 1 to 6 are fully supported. The renderer also strips trailing
#characters from closing heading hashes.Input:
Output:
Headings can contain inline markup:
Input:
Output:
Setext headings (
===and---underlines) are parsed as plain paragraphs because they are not yet supported.2. Paragraphs and Line Breaks
A paragraph continues across multiple source lines until an empty line is encountered. Trailing whitespace or backslash at end of line produces a hard line break:
Input:
Output:
Backslash breaks work the same way:
Input:
Output:
3. Inline Text Styles
Bold, italic, bold-italic, inline code, and escaped punctuation are all supported. Both
*and_delimiters work.Input:
Output:
Double-backtick code spans allow literal backticks inside code:
Input:
Output:
Backslash escaping prevents markup interpretation:
Input:
Output:
HTML entities and special characters pass through as-is after escaping:
&<>"', plus Unicode characters, CJK text, and emoji.4. Links
Inline links, autolinks, reference links, collapsed reference links, and shortcut reference links are all resolved.
Input:
Output:
Link text can contain inline code:
Input:
Output:
Reference link definitions are stripped from output and do not appear in the rendered HTML.
5. Images
Both inline and reference-style images are supported. Images can be wrapped in links.
Input:
Output:
6. Blockquotes
Blockquotes support multiple paragraphs and nesting up to two levels deep. Inline formatting and lists work inside blockquotes.
Input:
Output:
7. Lists
Unordered lists use
-,*, or+markers. Ordered lists use1.format and can start from any number. Task lists render with disabled checkboxes.Input:
Output:
Note: Nested lists (second-level indentation) and loose lists (paragraphs inside list items) are not yet fully supported; the renderer produces a best-effort structure that may differ from CommonMark expectations.
8. Code Blocks
Indented code blocks (4 spaces / tab) and fenced code blocks (with
```or~~~delimiters) are both supported. Code content is HTML-escaped.Input:
Output:
Fenced blocks with
~~~can contain literal```inside:Input:
Output:
9. Tables
Pipe-delimited tables with separator rows produce
<table>elements. Cells may contain inline markup (bold, code, links). Escaped pipe characters\|are kept as literal pipes inside cells.Input:
Output:
10. Horizontal Rules
Three or more of
-,*, or_on their own line produce<hr>.Input:
Output:
11. Edge Cases
The renderer handles several edge cases gracefully:
Consecutive inline markers produce separate elements:
Unclosed markers are treated as literal text.
Empty link/image targets produce
href=""andsrc="":Nested brackets in link text are resolved correctly:
Trailing backslash at EOF produces a final
<br>:Escaping
Text content is HTML-escaped by default. This includes plain text, inline code, link labels, image alt text, link URLs, and image sources, so input like
<tag>is rendered as<tag>.Code block contents are also escaped, but inline markup is not expanded inside code blocks.
License
Moon Markdown is licensed under the Apache License 2.0.