markdown
The markdown module provides bidirectional conversion between Markdown and HTML. It supports common Markdown syntax including headings, emphasis, code blocks, lists, links, images, and GitHub Flavored Markdown (GFM) extensions like tables, task lists, and autolinks.
import "markdown" for Markdown
Markdown Class
Markdown
Markdown to HTML converter
Static Methods
Converts Markdown text to HTML.
- text (String) - Markdown text
- Returns: HTML string
var html = Markdown.toHtml("# Hello World")
System.print(html) // <h1>Hello World</h1>
Converts Markdown text to HTML with options.
- text (String) - Markdown text
- options (Map) - Conversion options
- Returns: HTML string
Converts HTML to Markdown text.
- html (String) - HTML string
- Returns: Markdown text
var md = Markdown.fromHtml("<h1>Hello World</h1>")
System.print(md) // # Hello World
Converts HTML to Markdown text with options.
- html (String) - HTML string
- options (Map) - Conversion options
- Returns: Markdown text
Options
toHtml Options
| Option | Type | Default | Description |
|---|---|---|---|
safeMode |
Bool | false |
Escape HTML in input to prevent XSS |
fromHtml Options
| Option | Type | Default | Description |
|---|---|---|---|
stripUnknown |
Bool | true |
Strip unknown HTML tags, keeping their content |
Supported Syntax
Headings
# Heading 1
## Heading 2
### Heading 3
#### Heading 4
##### Heading 5
###### Heading 6
Converts to <h1> through <h6> tags.
Emphasis
*italic* or _italic_
**bold** or __bold__
~~strikethrough~~
Converts to <em>, <strong>, and <del> tags.
Code
Inline `code` here
```
Code block
Multiple lines
```
```javascript
const x = 1;
```
Inline code uses <code>, blocks use <pre><code>. Language identifiers after the opening fence add a class="language-{lang}" attribute to the code element for syntax highlighting integration.
Lists
Unordered:
- Item 1
- Item 2
* Also works
+ And this
Ordered:
1. First
2. Second
3. Third
Creates <ul> and <ol> with <li> items.
Task Lists (GFM)
- [ ] Unchecked task
- [x] Checked task
- [X] Also checked
Creates <ul class="task-list"> with checkbox inputs. Checkboxes are rendered as disabled to indicate they are display-only.
Tables (GFM)
| Header 1 | Header 2 | Header 3 |
|----------|:--------:|---------:|
| Left | Center | Right |
| Cell | Cell | Cell |
Creates HTML tables with <thead> and <tbody>. Column alignment is specified in the separator row using colons: :--- for left, :---: for center, ---: for right.
Autolinks (GFM)
Visit https://example.com for more info.
Email me at user@example.com
Bare URLs starting with http:// or https:// and email addresses are automatically converted to clickable links.
Links and Images
[Link text](https://example.com)

Creates <a href="..."> and <img src="..." alt="...">.
Blockquotes
> This is a quote
> Multiple lines
Creates <blockquote> with <p> content.
Horizontal Rule
---
***
___
Creates <hr> tag.
Paragraphs
Text separated by blank lines becomes <p> elements.
HTML to Markdown Conversions
The fromHtml method converts the following HTML elements to Markdown:
| HTML | Markdown |
|---|---|
<h1> to <h6> |
# to ###### |
<strong>, <b> |
**text** |
<em>, <i> |
*text* |
<code> |
`text` |
<pre><code> |
Fenced code block |
<a href="url"> |
[text](url) |
<img src="url" alt=""> |
 |
<ul><li> |
- item |
<ol><li> |
1. item |
<blockquote> |
> text |
<hr> |
--- |
<del>, <s> |
~~text~~ |
<table> |
GFM table syntax |
Container tags (<div>, <span>, <section>, etc.) are stripped but their content is preserved. Script and style tags are removed entirely.
Examples
Basic Conversion
import "markdown" for Markdown
var md = "
# Welcome
This is a **Markdown** document with:
- Lists
- *Emphasis*
- `Code`
Visit [Wren](https://wren.io) for more.
"
var html = Markdown.toHtml(md)
System.print(html)
Safe Mode for User Content
import "markdown" for Markdown
var userInput = "# Title\n<script>alert('xss')</script>\nContent here."
var safeHtml = Markdown.toHtml(userInput, {"safeMode": true})
System.print(safeHtml)
Rendering a Blog Post
import "markdown" for Markdown
import "io" for File
var postContent = File.read("post.md")
var html = Markdown.toHtml(postContent)
var page = "<html>
<head><title>Blog</title></head>
<body>
<article>
%(html)
</article>
</body>
</html>"
File.write("post.html", page)
Code Blocks with Language Classes
import "markdown" for Markdown
var md = "
```wren
System.print(\"Hello, World!\")
```
"
var html = Markdown.toHtml(md)
System.print(html)
// <pre><code class="language-wren">System.print("Hello, World!")</code></pre>
Tables
import "markdown" for Markdown
var md = "
| Name | Age | City |
|-------|----:|:----------|
| Alice | 30 | New York |
| Bob | 25 | London |
"
var html = Markdown.toHtml(md)
System.print(html)
Task Lists
import "markdown" for Markdown
var md = "
## Project Tasks
- [x] Design database schema
- [x] Implement API endpoints
- [ ] Write unit tests
- [ ] Deploy to production
"
var html = Markdown.toHtml(md)
System.print(html)
Combining with Templates
import "markdown" for Markdown
import "jinja" for Environment, DictLoader
var env = Environment.new(DictLoader.new({
"base": "<html><body></body></html>"
}))
var md = "# Hello\n\nThis is **Markdown**."
var content = Markdown.toHtml(md)
var html = env.getTemplate("base").render({"content": content})
System.print(html)
Converting HTML to Markdown
import "markdown" for Markdown
var html = "
<html>
<body>
<h1>Article Title</h1>
<p>This is <strong>important</strong> content.</p>
<ul>
<li>First item</li>
<li>Second item</li>
</ul>
</body>
</html>
"
var md = Markdown.fromHtml(html)
System.print(md)
// # Article Title
//
// This is **important** content.
//
// - First item
// - Second item
Cleaning HTML for Plain Text
import "markdown" for Markdown
var webContent = "<div><script>alert('xss')</script><p>Safe <b>content</b></p></div>"
var clean = Markdown.fromHtml(webContent)
System.print(clean) // Safe **content**
When rendering user-provided Markdown, always use safeMode: true to prevent cross-site scripting (XSS) attacks. Safe mode escapes HTML entities in the input text.
Language identifiers after code fences (e.g., ```wren) are added as class="language-{lang}" to the code element. This is compatible with syntax highlighters like Prism.js or highlight.js.