Convert HTML back into Markdown. Use it when you move content out of a CMS and into files, so it can live in git next to your code. Turndown does the conversion in this tab, with your choice of bullet, emphasis and heading style.
<h2>Release notes</h2>
<p>Shipped <strong>2.4.0</strong> on 10 September.</p>
<ul>
<li>Store credit at checkout</li>
<li>Partial refunds <em>(beta)</em></li>
</ul>
<table>
<thead><tr><th>Change</th><th>Impact</th></tr></thead>
<tbody><tr><td>New pricing API</td><td>breaking</td></tr></tbody>
</table>
<blockquote><p>Upgrade before the 30th.</p></blockquote>
<pre><code>npm i checkout-sdk@2.4.0</code></pre> ## Release notes
Shipped **2.4.0** on 10 September.
- Store credit at checkout
- Partial refunds _(beta)_
| Change | Impact |
| --- | --- |
| New pricing API | breaking |
> Upgrade before the 30th.
```
npm i checkout-sdk@2.4.0
``` Headings, emphasis, links, images, lists, blockquotes, code blocks, strikethrough and simple tables all convert cleanly.
A div with classes or a styled span loses its tag and keeps its text. An element with no text, such as an iframe or an embed, disappears. Save those embeds separately before you convert.
A plain grid becomes a pipe table. Markdown has no rowspan or colspan, so a table that uses them stays as raw HTML, which is valid Markdown.
HTML has several ways to write what Markdown writes one way. For example, both b and strong become **bold**. Convert back and forth and the text survives, but attributes and wrappers do not.
The HTML is parsed into a detached document that is never attached to this page, so nothing in it renders and no script in it runs. However, the text inside script and style tags comes through as plain text, so cut the page down to the article before you paste it.
A typical migration exports the posts as HTML, converts them to
Markdown and commits them as files. Plan time for cleanup
afterwards. Editors like WordPress leave shortcodes such as
[gallery], empty paragraphs and inline styles behind,
and none of that has a Markdown equivalent.
// npm i turndown turndown-plugin-gfm
const TurndownService = require("turndown");
const { gfm } = require("turndown-plugin-gfm");
const td = new TurndownService({
headingStyle: "atx", // # Heading rather than underlines
codeBlockStyle: "fenced",
bulletListMarker: "-",
emDelimiter: "_",
});
td.use(gfm); // tables, strikethrough, task lists
// Strip the chrome a CMS export drags along
td.remove(["script", "style", "nav", "footer"]);
console.log(td.turndown(html)); # pip install markdownify
from markdownify import markdownify as md
print(md(html, heading_style="ATX", bullets="-", strip=["script", "style"]))
# For a scraped page, cut it down to the article first
# pip install beautifulsoup4
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, "html.parser")
article = soup.select_one("article") or soup.body
print(md(str(article), heading_style="ATX")) # pandoc handles almost any pair of formats
pandoc -f html -t gfm article.html -o article.md
# Keep it readable: no line wrapping
pandoc -f html -t gfm --wrap=none article.html -o article.md
# A whole export directory
for f in export/*.html; do
pandoc -f html -t gfm --wrap=none "$f" -o "${f%.html}.md"
done The usual reason to convert HTML to Markdown is leaving a CMS: export the posts, convert them, and commit them as files so you no longer need a database to hold text. Plan time for cleanup. A long-running WordPress site contains shortcodes, inline styles and several generations of embed markup, and none of that has a Markdown equivalent.
This tool follows the specifications below. Read them when you need the exact normative wording, for example to settle an edge case between two implementations.
Wrapper tags such as a div with classes or a styled span are removed and their text is kept. An element with no text, such as an iframe, disappears. The one case kept as raw HTML is a table with rowspan or colspan, since raw HTML is valid Markdown.
Yes. Bullets takes a dash, asterisk or plus, Emphasis takes an underscore or asterisk, and Headings switches between # ATX and underlined headings. Match whatever your linter expects, since all of them parse the same way.
Yes, into GitHub-style pipe tables, as long as the HTML table is a plain grid. A table with rowspan or colspan has no Markdown equivalent, so the tool keeps it as HTML.
Close, but not byte for byte. Markdown has one way to write a heading, while HTML has several ways to produce the same result. Attributes, wrapper elements and whitespace are lost on the way, so the text survives and the original markup does not.
Yes. The HTML is parsed in a detached document that never renders, so its scripts do not execute. However, the text inside script and style tags comes through as plain text, so cut the page down to the article first.
Markdown to HTML does the reverse, and the Markdown editor gives you a live preview while you clean up the result. Entities left in the text can be unwrapped with the HTML decoder.