A little help goes a long way. Find a tool/

Developer FIELD NOTES · 3 MIN READ

Markdown to HTML and Back: How Two-Way Conversion Works

Both conversion directions compared: escape-first rendering, the reverse pattern walk, and what survives a Markdown-HTML round trip.

Markdown is what you write; HTML is what the browser renders. Most converters handle that one direction and stop — but content has a habit of traveling the other way too: exported CMS pages, scraped documentation, HTML emails destined for a Markdown-based static site. A bidirectional converter makes the bridge two-way, and the two directions are surprisingly different engineering problems.

Markdown → HTML: escape first, format second

The forward pass runs through a fixed order of steps, and the first one is the safety-critical move: every <, >, and & in your input is escaped into entities before any formatting applies. Paste a snippet containing raw <b>bold</b> and it comes out as visible text — <b>bold</b> — not markup. Your Markdown is treated as text to format, never as HTML to inject. (The entity encodings doing that work are detailed in How HTML Entities Work.)

Only then do the formatting rules fire, in order: fenced code blocks, inline backticks, headings # through ######, bold and italic stars, images before links (so ![alt](src) doesn't get mangled into an anchor), dash and digit lists, blockquotes, and finally paragraph wrapping — blank lines split blocks, and single newlines inside a block become <br>. A small document:

# Title

Hello **world** and `code`.

comes out as:

<h1>Title</h1>
<p>Hello <strong>world</strong> and <code>code</code>.</p>

HTML → Markdown: a priority queue of patterns

The reverse direction is a different game: HTML is far larger than Markdown's vocabulary, so the converter processes a prioritized list of patterns and lets the rest fall through. Fenced <pre> blocks become triple-backtick fences (with entities decoded inside), headings become # rows, blockquotes gain a > per line, images map to ![alt](src) and anchors to [text](href), lists regain their dashes, and <strong>/<em> collapse back to asterisks. Ordered lists are renumbered from 1, so <ol start="5"> numbering does not carry over. Anything the pattern list doesn't recognize — <div> wrappers, attribute-bearing spans — ends with its tags stripped and its text kept:

<h2 class="x">T</h2><p title="y">Body</p>
→
## T

Body

What survives the round trip

Feed HTML through the converter and the Markdown back through again, and the supported subset is stable: headings, paragraphs, bold, italic (star form), links, images, code, blockquotes, horizontal rules, flat lists. The things that don't survive are just as important to know:

  • Attributes vanish. Markdown syntax has no slots for class, title, or id, so HTML→Markdown drops them by design.
  • Nested lists lose their indentation. A two-space-indented - nested line under a list item is not parsed as a sublist — it stays literal text after the list closes. Flatten nested lists before converting.
  • GFM tables aren't parsed. Pipe-table input renders as a paragraph with <br> line breaks, and HTML tables come back as bare cell text.
  • Underscore italics stay literal. The forward pass converts *star* to <em> but leaves _under_score_ untouched — a deliberate ambiguity dodge, since underscores appear inside identifiers and URLs.

Why bidirectional beats two one-way tools

Round-tripping is the killer use case. Migrating a blog from an HTML CMS to a Markdown static-site generator, pulling reference docs into a wiki, or cleaning scraped pages all need the HTML→Markdown direction — and then the edited result usually needs converting forward again to check how it renders. Having both modes in one tool means you paste, flip, edit, and flip back without changing context or re-uploading. The concepts and flavors behind the syntax itself are covered in Markdown Explained.

Try it yourself

Convert in both directions with the Markdown to HTML Converter (Two-Way) — try the Title example above, then reverse it. For pure Markdown→HTML rendering, the Markdown to HTML tool stays in one mode; the Markdown Table Generator builds the pipe tables this converter intentionally leaves alone; and the HTML Entity Encoder & Decoder shows the escaped &-forms the forward pass relies on.

Frequently asked questions

How is this different from a one-way Markdown to HTML converter?
A one-way tool renders Markdown for publishing and stops. This one keeps both directions in the same place, so a round-trip workflow — export HTML, convert to Markdown, edit, convert back to check — never leaves the page. The forward pass is the same either way; the difference is that the reverse direction exists at all.
Will my Markdown survive a trip to HTML and back?
The supported subset round-trips cleanly: headings, paragraphs, bold, italic (star form), links, images, code, blockquotes, and flat lists. Nested list indentation, GFM tables, and underscore italics are not part of that subset and will not come back intact.
Why did my HTML attributes disappear?
Markdown syntax has no slots for class, id, or title attributes, so the HTML-to-Markdown pass strips tags down to their text and structure. What comes back is the content, not the styling hooks.
Can I paste raw HTML into the Markdown side?
You can, but it will not render as markup: the converter escapes every < and & before formatting, so your HTML appears as literal text in the output. That escape-first design means input is always treated as content, never as code to inject.
Are nested lists supported?
Not in the indentation sense. A two-space-indented dash under a list item stays literal text after the list closes, so flatten nested lists into separate top-level items before converting. Inline formatting inside list items — bold, code, links — converts fine.