Skip to main content
L
Loopaloo
Buy Us a Coffee
All ToolsImage ProcessingAudio ProcessingVideo ProcessingDocument & TextPDF ToolsCSV & Data AnalysisConverters & EncodersWeb ToolsMath & ScienceGames
Guides & BlogAboutContact
Buy Us a Coffee
L
Loopaloo

Free online tools for developers, designers, and content creators. Your files are processed in your browser and are never uploaded - no accounts required. A few network utilities (like What's My IP and Currency Converter) call public APIs to do their job and say so on their pages.

support@loopaloo.com

Tool Categories

  • Image Tools
  • Audio Tools
  • Video Tools
  • Document & Text
  • PDF Tools
  • CSV & Data
  • Converters
  • Web Tools
  • Math & Science
  • Games

Company

  • About Us
  • Contact
  • Blog
  • FAQ

Legal

  • Privacy Policy
  • Terms of Service
  • Disclaimer

Support

Buy Us a Coffee

© 2026 Loopaloo. All rights reserved. Built with privacy in mind.

Privacy|Terms|Disclaimer
  1. Home
  2. Document & Text
  3. HTML ↔ Markdown Converter
Add to favorites

HTML ↔ Markdown Converter

HTML to Markdown and back, built on a real HTML tree and a CommonMark parser rather than regular expressions, with GitHub tables, a live preview, and a report of everything Markdown could not carry

Text processed locallyMore document & textJump to full guide

Related reading

  • HTML Entities and Special Characters: A Complete Reference for Web Developers10 min read

Initializing in your browser…

You might also like

Markdown Editor & Preview

Markdown editor with a live preview from a real CommonMark 0.31.2 parser, scored 580 of 652 against the specification, plus GitHub tables, task lists and strikethrough, a document outline, and .md and .html export

Markdown Table Generator

Build or paste a Markdown table and see it read back cell by cell, with column widths measured in display columns so CJK text, emoji and accents line up, and pipes escaped in the right order

Image Format Converter

Convert between the formats a browser can really write, then open the output and name the format its first bytes say it is. AVIF, BMP and GIF are disabled because a canvas returns a PNG for all three.

HTML ↔ Markdown Converter: a worked example

You are moving a page into a static site and the HTML has a nested list, a table and some prose that happens to contain asterisks.

HTML

<ul><li>one<ul><li>one a</li></ul></li><li>two</li></ul>
<p>keep *these* asterisks</p>
What HTML ↔ Markdown Converter produces

Markdown

- one

  - one a
- two

keep \*these\* asterisks

The previous converter gave `- oneone a` for that list, because it matched the open and close tags with a lazy pattern and the inner list closed the outer one; and it left the asterisks unescaped, so converting back produced emphasis the document never had. This one builds a real tree and escapes what Markdown would read as syntax, which is what lets the round trip come back with the same document: 21 of 21 corpus documents now come through where 10 did.

What this converter does

Convert HTML to Markdown and Markdown back to HTML. The question a converter has to answer is whether the Markdown means the same as the HTML, and the way to answer it is to convert back and compare: HTML to Markdown, Markdown to HTML, and the two documents held up against each other. Measured that way on a 21 document corpus on 2026-09-03, the version this replaces came through with everything asked of it on 10 of them; this one manages 21, and 18 of the 18 that CAN round trip come back with the same shape. The other three hold something Markdown has no syntax for, and the tool says which.

How it works

The version this replaces parsed HTML with one regular expression per element: `md.replace(/<h1[^>]*>([\s\S]*?)<\/h1>/gi, ...)` and so on down to h6, finishing by stripping whatever tags were left. That cannot work, and the failures are not subtle ones. A lazy match between an open tag and a close tag takes the FIRST close tag, so an element nested inside another of the same name closes the outer one. `[^>]*` says a `>` inside an attribute value ends the tag, so a `title="a > b"` loses its second half. And a `<pre>` was treated as prose and reflowed, which stops code being code.

What that produced, measured on the corpus: a nested list came out as `- oneone a`, a list with `start="5"` came out starting at 1, a block quote holding two paragraphs came out as `> ` followed by two loose lines, a table came out as `ABC123` with no table syntax at all, `caf&eacute;` came out with the entity still in it, an image lost its title, a link whose URL held a space came out broken, and nothing at all was escaped, so HTML text saying `*not emphasis*` became emphasis on the way back.

This version builds a TREE. The tokenizer knows a `>` inside an attribute is not a tag boundary, that a comment holding markup is not markup, that a `<script>` holds raw text so a close tag inside a string is not a close tag, and that HTML closes an open `<p>` when another starts. Every character reference is decoded to the character it names. Every character that would be read as Markdown syntax is escaped, so the round trip does not invent emphasis. A code span holding a backtick gets a longer fence, which CommonMark section 6.1 requires. A destination holding a space gets the angle bracket form. A `<pre>` keeps every character it had.

The other direction goes through the same CommonMark 0.31.2 parser the Markdown Editor uses, which scores 580 of the specification's own 652 examples, rather than through a second set of patterns. That means reference links, setext headings, tight and loose lists and hard line breaks all work, and it means a `javascript:` destination is refused and reported rather than turned into a working link.

**Where Markdown cannot carry something, the tool says so instead of guessing.** A table cell spanning two columns has no Markdown syntax, so that table stays HTML and the page names it. A `<span>`, a `<kbd>`, a `<video>`: there is no syntax for any of them, and the three ways of handling one (keep the HTML, keep only its text, drop it) all lose something, so it is a setting rather than a silent default. Two switches that used to be offered, "preserve links" and "preserve images", were never read by any code in the file and are gone.

How to use

  1. 1Paste HTML on the left, or switch direction to paste Markdown
  2. 2Press Convert, or watch the preview, which renders the CONVERTED document so a loss shows
  3. 3Open Options to choose the heading style, the delimiters, the bullet marker and what happens to an element Markdown cannot express
  4. 4Read the panel naming anything the conversion could not carry
  5. 5Copy or download the result

Key features

  • A real HTML tree, so nesting, attributes holding brackets, comments and script bodies are all read correctly
  • Markdown syntax escaped, so converting back does not invent emphasis the document never had
  • Tables with per-column alignment, and a table with a spanning cell kept as HTML and reported
  • Every character reference decoded; ordered lists honour their start attribute
  • Code spans and fenced blocks that survive a backtick inside them
  • The other direction through a CommonMark 0.31.2 parser, so reference links and setext headings work
  • A script destination refused and reported rather than turned into a link
  • A stated choice for an element Markdown cannot express, rather than a silent one
  • Scored by round trip: 21 of 21 corpus documents come through, against 10 before

When to reach for this

  • Moving content out of a CMS

    Convert exported HTML into Markdown for a static site, and see straight away what the conversion could not carry rather than finding out later.

  • Turning a web page into notes

    Paste a page and get Markdown whose lists nest properly, whose tables are tables, and whose code blocks still look like code.

  • Checking a Markdown document renders

    Switch direction to see the HTML a CommonMark parser produces from your Markdown, including the reference links and the destinations it refuses.

Frequently asked questions

Why did my nested list come out wrong before?

Because the converter matched `<ul>...</ul>` with a lazy pattern, and a lazy match stops at the FIRST close tag: the inner list closed the outer one. Measured, `<ul><li>one<ul><li>one a</li></ul></li><li>two</li></ul>` came out as `- oneone a`. This version builds a tree, so nesting is nesting.

What happens to an element Markdown has no syntax for?

You choose, because every answer loses something. Keeping the HTML is faithful but leaves markup in your Markdown; keeping only the text loses the element; dropping it loses the text as well. The default keeps the HTML, and the page lists every element it did that for.

Are tables supported?

Yes, in GitHub table syntax, with per-column alignment taken from the header cells. A cell that spans two columns or two rows cannot be written in that syntax at all, so a table containing one is kept as HTML and named on the page rather than silently flattened.

Why is my text full of backslashes?

Because it contained characters Markdown reads as syntax. HTML text saying `*not emphasis*` is text, and writing it into Markdown unescaped turns it into emphasis the moment anything renders it. The escaping is what makes the round trip come back with the same document.

Does it use Turndown or marked?

No, and it no longer uses regular expressions either. The HTML side is a tokenizer and a tree written for this project; the Markdown side is the CommonMark 0.31.2 parser the Markdown Editor uses, which reproduces 580 of the specification's own 652 examples. Everything runs in your browser.

Related tools and how they differ

  • Markdown Editor & Preview: Live Markdown editor with split preview, GFM tables, task lists, and .md/.html export; use it to write and render whole documents, not convert HTML.
  • Markdown Table Generator: Generates a single GFM table via a grid editor with alignment markers and pipe escaping; use it when you just need clean table syntax.
  • Code Syntax Highlighter: Renders syntax-colored snippets in 7 themes and exports HTML or PNG; use it for sharable code images, not HTML-to-Markdown conversion.

Further reading

  • HTML Entities and Special Characters: A Complete Reference for Web Developers10 min read

Private by design

Your text is processed locally in the browser. Nothing you paste or open is transmitted or logged.