Paste a ChatGPT or Claude answer into most CMS editors and the formatting
arrives as literal asterisks and pound signs — because LLMs speak markdown
and the web speaks HTML. The translation is mechanical but fiddly to do by
hand: every ## needs to become a real <h2>, every fenced block a
<pre><code>, every pipe table a proper <table> with <thead> and
<tbody>. This converter does that translation with a live preview, emits
semantic HTML rather than styled <div> soup, and escapes anything
dangerous on the way through.
What each markdown pattern becomes
| Markdown | Rendered HTML |
|---|---|
# Title | <h1 id="title">Title</h1> |
**bold** | <strong>bold</strong> |
*italic* or _italic_ | <em>italic</em> |
`code` | <code>code</code> |
```python … ``` | <pre><code class="language-python">…</code></pre> |
> quote | <blockquote><p>quote</p></blockquote> |
- item | <ul><li>item</li></ul> |
1. item | <ol><li>item</li></ol> |
[text](url) | <a href="url">text</a> |
 | <img src="src" alt="alt"> |
--- | <hr> |
| pipe table | <table> with <thead> and <tbody> |
The element choices matter: <strong> and <em> (not <b>/<i>) carry
semantic emphasis for screen readers and SEO; the language-* class on
code blocks is the convention highlight.js and Prism both key on; and
heading ids make sections deep-linkable.
How the conversion runs
The parser works in ordered passes, which is what keeps code intact:
- Protect fenced code blocks — their contents are lifted out first so nothing inside triple backticks is ever reinterpreted as markdown.
- Escape raw angle brackets in prose, so pasted
<script>or<span>arrives as visible text, not live markup. - Convert block structure — headings, lists, blockquotes, tables, horizontal rules.
- Convert inline elements — bold, italic, links, images, inline code.
- Restore the protected code blocks, escaped and wrapped in
<pre><code>.
This ordering mirrors how the reference implementations behave and avoids the classic single-regex-pass bugs (bold markers inside code, lists inside quotes).
Worked example
Input:
## Results
The fix cut latency by **41%**:
- p50: 120ms → 71ms
- p99: `840ms` → 490ms
Output:
<h2 id="results">Results</h2>
<p>The fix cut latency by <strong>41%</strong>:</p>
<ul>
<li>p50: 120ms → 71ms</li>
<li>p99: <code>840ms</code> → 490ms</li>
</ul>
Copy from the source view — the preview shows the rendered result, but the source view holds the markup you actually paste into a CMS or template.
Flavor differences worth knowing
“Markdown” is a family, not one spec. The original 2004 syntax was loose;
CommonMark nailed down the ambiguities, and
GitHub Flavored Markdown (GFM) added
tables, strikethrough, and task lists on top. LLMs overwhelmingly emit
GFM-style output — pipe tables especially — which is why this tool follows
the GFM conventions for tables and fenced code. Edge cases where flavors
disagree (indented code blocks, “loose” vs “tight” lists, setext headings
underlined with ===) are rare in LLM output; if you feed the converter
hand-written 2004-style markdown, prefer fenced code over four-space
indentation for predictable results.
Safety: what happens to raw HTML in the input
LLMs occasionally mix HTML into markdown (<br>, <sup>, stray <div>s
copied from a website). This converter treats prose HTML as text: angle
brackets are escaped, so <script>alert(1)</script> in a paragraph becomes
visible characters, never an executing tag. That makes the output safe to
drop into pages that don’t run their own sanitizer. Inside fenced code
blocks, HTML is preserved verbatim (escaped, inside <pre><code>), since
showing markup is usually the point of the block. If you want raw HTML
passed through live, that is deliberately unsupported here — use a build
pipeline with an explicit sanitizer (DOMPurify or equivalent) instead.
When to use this vs. a markdown library
If you control a build pipeline, use a library — marked, markdown-it,
or remark — and get plugins, caching, and full spec coverage. This tool
is for the moments without a build step: publishing an LLM answer to a CMS
that only accepts HTML, converting a README excerpt for an email template,
producing a snippet for a documentation platform, or checking quickly what
a piece of markdown should render as. One paste, one copy, no toolchain.
Heading IDs and deep links
With heading IDs enabled, each heading is slugified the same way GitHub
does it — lowercase, punctuation stripped, spaces to hyphens — so
## Query Parameters becomes <h2 id="query-parameters">. Anchors like
page.html#query-parameters then work out of the box, and tables of
contents generated elsewhere line up with your section IDs.
References
Everything converts locally in your browser — pasted content is never uploaded or stored.