How to convert a blog post from markdown to html
- Step 1Paste the draft or drop the .md file — Paste your post's Markdown or drop the
.mdfile into the input. One file per run; if your post is split across files, merge them first with md-merger. - Step 2Turn Full document OFF for CMS pasting — For pasting into WordPress/Ghost/Medium-import, turn Full document OFF so you get just the body HTML. Leave it ON only when you want a complete, openable preview page to hand to an editor.
- Step 3Run the conversion — marked parses the draft locally and renders HTML instantly. Nothing uploads.
- Step 4Spot-check images and embeds — Confirm images converted to
<img>(relative paths are kept as-is — upload them to your media library and fix thesrcafter pasting) and that any embed HTML you wrote survived. marked does not sanitize, so embeds pass through. - Step 5Paste into the CMS HTML block — WordPress: Block editor → add a Custom HTML block → paste. Ghost: insert an HTML card → paste. The CMS then sanitizes/wraps the HTML per its own rules.
- Step 6Fix heading anchors if your post needs them — marked does not add
ids to headings, so a manual 'jump to section' menu will not work from this output alone. Most CMS themes auto-generate heading ids on render — rely on that, or add ids after pasting.
Blog elements and how they convert
Verified against marked 14.1.4. These are the elements a typical post uses.
| Element | Markdown | HTML output | Notes |
|---|---|---|---|
| Subheading | ## Section | <h2>Section</h2> | No id — theme must add for anchors |
| Pull quote | > quote | <blockquote><p>quote</p></blockquote> | Styled by your theme's CSS |
| Code snippet | ` js ` | <pre><code class="language-js"> | Class only; add highlight.js for colour |
| Comparison table | GFM pipe table | <table> with <thead>/<tbody> | Fully supported |
| Image |  | <img src="img.png" alt="alt"> | Path kept verbatim — re-point after upload |
| Embed | <iframe …youtube…> | passed through verbatim | Not sanitized |
| Footnote | claim[^1] | broken <a href="1">^1</a> | Not supported by core marked |
Which mode for which target
The single option (fullDocument) decides the wrapper.
| Target | Recommended mode | Why |
|---|---|---|
| WordPress Custom HTML block | Full document OFF (fragment) | WordPress wants body HTML; a full page would nest documents |
| Ghost HTML card | Full document OFF (fragment) | Ghost injects the fragment into the post template |
| Email to an editor | Full document ON | Self-contained .html opens in any browser with the built-in stylesheet |
| Static-site partial | Full document OFF (fragment) | Your layout already provides <head> and CSS |
Tier limits (markdown family)
Per-file limits. Character cap is independent of byte size.
| Plan | Max file size | Max characters | Files per run |
|---|---|---|---|
| Free | 1 MB | 500,000 | 1 |
| Pro | 10 MB | 5,000,000 | 10 |
| Pro + Media | 50 MB | 20,000,000 | 50 |
| Developer | 500 MB | unlimited | unlimited |
Cookbook
Real blog-draft snippets and the HTML they produce, plus the CMS gotchas worth knowing before you paste.
Heading, intro, and pull quote
The opening of a typical post — H2, a paragraph, and a blockquote pull-quote — converts to clean semantic HTML your theme can style.
Input: ## Why we switched We moved off the old stack. > It cut our build time in half. Output (fragment): <h2>Why we switched</h2> <p>We moved off the old stack.</p> <blockquote> <p>It cut our build time in half.</p> </blockquote>
Code snippet keeps its language class
Tech-blog posts lean on fenced code. The block keeps a language class so your site's highlighter can colour it — but no colouring is baked in here.
Input: ```js const x = 1; ``` Output: <pre><code class="language-js">const x = 1; </code></pre> (Add highlight.js/Prism on your site to colour it.)
Comparison table for a 'X vs Y' post
GFM pipe tables convert to full HTML tables — exactly what a comparison post needs. In full-document mode the built-in stylesheet adds borders; in fragment mode your theme styles it.
Input: | Plan | Price | |------|-------| | Free | $0 | | Pro | $9 | Output: <table> <thead><tr><th>Plan</th><th>Price</th></tr></thead> <tbody> <tr><td>Free</td><td>$0</td></tr> <tr><td>Pro</td><td>$9</td></tr> </tbody> </table>
YouTube embed passes through
If you pasted an embed iframe into the draft, marked leaves it untouched so the video still embeds after pasting into the CMS.
Input: Watch the demo: <iframe src="https://www.youtube.com/embed/abc" width="560" height="315"></iframe> Output (verbatim — not sanitized): <p>Watch the demo:</p> <iframe src="https://www.youtube.com/embed/abc" width="560" height="315"></iframe>
Images need their src re-pointed after upload
Local image paths are kept exactly. After pasting into the CMS, upload the images to the media library and update each src — the converter cannot know your CMS upload URLs.
Input:  Output: <p><img src="./assets/q3-chart.png" alt="chart"></p> After CMS upload, change src to e.g. https://cdn.example.com/uploads/q3-chart.png (Or pre-rewrite paths with md-image-path-rewriter.)
Edge cases and what actually happens
Full document ON breaks CMS pasting
AvoidableIf you leave Full document ON and paste the result into a WordPress Custom HTML block, you get a whole <html> document nested inside the post — most editors strip the <head> and you end up with stray text. For CMS targets, turn Full document OFF so you paste a clean body fragment.
Heading anchors don't work from this output
By designmarked does not add id attributes, so a hand-built 'jump to section' menu in your post won't scroll. Most CMS themes add heading ids when they render the page, so in practice this usually self-resolves after publishing — but the raw HTML from this tool has no ids.
Embeds and <script> are not sanitized
Not sanitizedmarked passes inline HTML through verbatim, including <iframe>, <script>, and tracking pixels. That is convenient for legit embeds, but your CMS will likely strip <script> on its own for security. Don't rely on inline <script> surviving the CMS paste.
Image paths stay local
Preserved becomes <img src="./img/x.png">. After pasting, the images won't load until you upload them and fix each src. To batch-rewrite paths to your CDN before converting, use md-image-path-rewriter.
Footnotes render as broken links
Not supportedLong-form posts often use footnotes (claim[^1]). marked has no footnote support, so [^1] becomes a broken reference link. Convert footnotes to inline links or an end-of-post references list before converting.
Smart quotes / typography are not applied
Expectedmarked does not transform straight quotes into curly quotes or -- into en-dashes (no SmartyPants by default). What you typed is what you get. If you want typographic quotes, your CMS or theme typically applies them on render; or clean the source first.
Front matter is rendered as text
Leaks into outputIf your draft starts with YAML front matter (--- … ---), marked does not strip it — it ends up in the HTML as a paragraph or <hr>+text. Remove front matter before converting, or run the draft through md-frontmatter-builder workflows that keep body and metadata separate.
Emoji shortcodes stay literal
Not supported:tada: and other GitHub-style shortcodes are not expanded — they appear as literal text. Unicode emoji you typed directly survive. Strip or normalise emoji with md-emoji-remover if your house style bans them.
Draft exceeds the free character cap
400 rejectedA very long post over 500,000 characters / 1 MB is rejected on Free before conversion with a character-count error. Even long-form posts are rarely this big; if you batch-converted a whole book chapter you might hit it. Pro raises the cap to 5,000,000 / 10 MB.
No syntax colouring in code blocks
By designCode fences get class="language-*" but no colour spans. On your blog, your theme's highlighter (Prism/highlight.js) colours them; the raw HTML here is plain monospace.
Frequently asked questions
Should I use full-document or fragment mode for WordPress?
Fragment — turn the Full document option OFF. WordPress's Custom HTML block (and Ghost's HTML card) want body HTML, not a complete <html> page. Full-document mode is for when you want a standalone preview file to send to an editor.
Will my code blocks be syntax-highlighted in the output?
Not in this output — code fences get a class="language-js" hook but no colour markup. On your published blog, your theme's highlighter (Prism or highlight.js) applies the colours using that class. The HTML from this tool is plain monospace, which keeps it portable.
Do my images work after pasting into the CMS?
Not until you upload them. Relative paths like ./img/x.png are preserved verbatim, so they won't resolve from the CMS. Upload the images to your media library and update each <img src>, or pre-rewrite paths to your CDN with md-image-path-rewriter before converting.
Can I keep YouTube and Twitter embeds in the conversion?
Yes — marked passes inline HTML (including <iframe> embeds) through verbatim. Note your CMS may then sanitize or replace embed HTML with its own embed handling, so test after pasting.
Why do my footnotes look broken?
Core marked does not support footnote syntax. text[^1] is parsed as a reference link and produces a broken <a href="1">^1</a>. Convert footnotes to inline links or a references section before converting.
Does it convert GFM tables for comparison posts?
Yes. GFM pipe tables become full <table> elements with <thead> and <tbody> — exactly what a 'X vs Y' comparison post needs. In full-document mode the built-in stylesheet adds borders; in fragment mode your theme styles the table.
Are my draft posts uploaded anywhere?
No. The conversion runs in your browser via marked. An unpublished or embargoed draft never leaves your machine. Only an anonymous processed-file counter is stored for dashboard stats, never the content.
Will it turn straight quotes into curly quotes?
No — marked does not apply SmartyPants-style typography by default. Your characters pass through as typed. Curly quotes and en-dashes are usually applied by your CMS or theme on render, or you can clean the source beforehand.
What about front matter at the top of my draft?
marked does not strip YAML front matter — it leaks into the HTML as text or an <hr>. Remove the --- block before converting. For metadata workflows, md-frontmatter-builder handles front matter separately from the body.
Can I get a GitHub-styled preview instead of the plain one?
Yes — use md-to-github-html for GitHub's Primer CSS look. This tool's full-document mode uses a simpler readable stylesheet aimed at general blog/preview use.
How long a post can I convert?
Free allows 1 MB / 500,000 characters per file; Pro 10 MB / 5,000,000; Pro + Media 50 MB / 20,000,000; Developer 500 MB / unlimited. The character cap is separate from byte size, so a multibyte post can hit the char limit first.
What file name does the download use?
The output keeps your input's base name with a .html extension — my-post.md becomes my-post.html. .markdown, .mdx, and .txt inputs are handled the same way.
Privacy first
All Markdown processing runs locally in your browser using JavaScript. No file is ever uploaded to JAD Apps servers — only metadata counters are saved for signed-in dashboard stats.