From Markdown to HTML in real time
Markdown lets you write formatted documents with plain-text conventions: # for headings, **bold**, - lists and backticks for code. Browsers, however, only understand HTML. This Markdown to HTML converter translates your text into clean, semantic HTML using the widely used marked parser, and updates the output as you type.
Example
# Project Title
A short description of **what it does** and _who it is for_.
- [x] Fast
- [ ] ~~Slow~~
| Option | Default |
|--------|:-------:|
| `gfm` | on |<h1>Project Title</h1>
<p>A short description of <strong>what it does</strong> and <em>who it is for</em>.</p>
<ul>
<li><input checked="" disabled="" type="checkbox"> Fast</li>
<li><input disabled="" type="checkbox"> <del>Slow</del></li>
</ul>
<table>
<thead>
<tr>
<th>Option</th>
<th align="center">Default</th>
</tr>
</thead>
<tbody><tr>
<td><code>gfm</code></td>
<td align="center">on</td>
</tr>
</tbody></table>
GitHub Flavored Markdown
The original Markdown from 2004 had no tables or task lists. GitHub Flavored Markdown (GFM), a superset of the CommonMark specification, added them, and it is now what most people mean by "Markdown". With the GFM option on, the converter supports:
- Tables with pipes and a separator row; colons in the separator set column alignment (
:---,:---:,---:). - Task lists –
- [ ]and- [x]become disabled checkboxes. - Strikethrough –
~~text~~becomes<del>. - Autolinks – bare URLs such as
https://example.combecome links. - Fenced code blocks – triple backticks with a language name produce
<pre><code class="language-bash">, the class that highlighters like Prism and highlight.js look for.
Turn GFM off to follow the original, stricter rules, for example when you need output that matches an older Markdown processor.
The line breaks option
In standard Markdown, a single newline inside a paragraph is treated as a space; you need a blank line for a new paragraph, or two trailing spaces for a hard break. GitHub comments and many chat apps instead turn every newline into a line break. Enable the line breaks option to reproduce that behavior: line one and line two on consecutive lines become line one<br>line two.
What you get (and what you do not)
- The output is an HTML fragment without
<html>,<head>or CSS, ready to insert into a template, CMS or email. - Headings do not get automatic
idattributes; add them if you need anchor links. - Footnotes, math and diagram syntax are extensions of specific platforms and are not converted.
- Raw HTML inside your Markdown is passed through unchanged, as the Markdown specification requires. If the Markdown comes from untrusted users, sanitize the resulting HTML before publishing it.
Typical uses
- Publishing a README or changelog on a website that expects HTML.
- Writing blog posts in Markdown and pasting HTML into a CMS that has no Markdown support.
- Creating HTML emails from simple Markdown drafts.
- Checking exactly which HTML a Markdown construct produces while debugging a static site generator.
To see the rendered page rather than the code, open the same text in the Markdown viewer, or write with a live preview in the Markdown editor. Converting in the other direction? Use HTML to Markdown. Everything runs in your browser.
Convert Markdown to HTML in Python
Python has no Markdown parser in the standard library; the common choice is the markdown package (Python-Markdown), where markdown.markdown(text) returns an HTML fragment. What catches people is that only the basic syntax is enabled by default. Tables and fenced code blocks come out as plain paragraphs until you turn on the tables and fenced_code extensions. The output has no <html> or <body> wrapper, and raw HTML in the source, including <script>, is passed through unchanged, so sanitize the result when the Markdown comes from users.
# pip install markdown
import markdown
text = """# Project Title
A short description of **what this project does** and _who it is for_.
| Option | Default |
|--------|---------|
| debug | false |
```bash
npm install my-project
```
"""
html = markdown.markdown(text, extensions=["tables", "fenced_code"])
print(html)
Paste the same Markdown above to compare: with those two extensions the tags match what this page generates.