How to use
- Paste the Markdown into the left box. The preview on the right shows the formatted result as you type: headings, bold, lists, tables, code, links.
- Click Copy for Google Docs (or press Ctrl+Enter in the input box). The formatted text and a plain-text copy both go on the clipboard.
- Open your document (Copy & open Google Doc ↗ copies and opens a new one in a single click) and press Ctrl+V (⌘+V on a Mac). Word, Gmail, Outlook, Teams and Notion accept the same paste.
- Need the code instead? Copy HTML or Download .html give you the fragment the preview is made of.
How formatting travels through the clipboard
When you copy text from a web page and paste it into Google Docs, the headings and bold come with it. When you copy Markdown from a chat window and paste it, they do not. The difference is not the editor, it is the clipboard: the first copy carried an HTML flavour alongside the plain text; the second carried only text, and Markdown's ** and # are just characters to Docs. Docs' own Paste from Markdown option exists for exactly this and is worth switching on if your account offers it.
This tool converts the Markdown to HTML in your browser, shows you that HTML rendered, and on Copy for Google Docs writes both the HTML and a plain-text version to the clipboard. Any editor that understands formatted paste (Google Docs, Microsoft Word, Gmail, Outlook, Teams, Notion, Confluence) reads the HTML and applies its native styles. A plain text box, a terminal or a code editor takes the text version. The HTML is deliberately simple: semantic tags, a monospace font on code, a border on tables, nothing else, so the destination's own styles apply rather than fighting inline ones.
Example
Load sample inserts a deploy checklist with 1 heading, 3 lists (one nested, one of tasks), 1 table, 1 code block and 3 links. The preview shows it formatted; the HTML that goes on the clipboard begins:
<h2>Deploy checklist</h2>
<p>Run the <strong>full test suite</strong> before tagging a release: <code style="font-family:Consolas,'Courier New',monospace">npm test</code> takes about <em>two minutes</em>.</p>Pasted into Google Docs, that is a Heading 2, a paragraph with a bold phrase, monospace npm test and an italic phrase, then a numbered list with a nested bulleted list, a three-column table with a header row, an indented quote, a monospace command and a two-item list beginning with ☑ and ☐. The table is <table border="1" style="border-collapse:collapse"> and the code block is <pre style="font-family:Consolas,'Courier New',monospace;white-space:pre-wrap">, which is what makes Docs keep the border and the font.
Options explained
- Copy for Google Docs puts the formatted result on the clipboard as HTML plus plain text. Ctrl+Enter in the input box does the same. If your browser cannot write HTML to the clipboard directly (older Firefox), the tool selects the preview and copies that instead, which carries the same formatting.
- Copy & open Google Doc ↗ does what Copy for Google Docs does, then opens
docs.new(a new blank Google Doc) in another tab, so all that is left is Ctrl+V. Google does not let any site open a document with text already in it, so the paste is the one step it cannot do for you. Nothing is sent to Google; the content only travels through your clipboard. With the input empty it just opens a blank doc. - Copy HTML copies the HTML fragment as text, for a CMS field, an email template or a page.
- Download .html saves the fragment wrapped in a minimal page (
<meta charset="utf-8">and a title) asdocument.html, which Word opens directly. - Load sample inserts the checklist shown above; Clear empties the input and the preview.
- The preview is the exact fragment the clipboard gets, styled only enough to read. Its scrollbar and resize handle are the page's; they are not part of the copy.
Edge cases and common errors
- Nested lists nest in the HTML, so they nest in Docs:
- a / (two spaces) - b / (four) 1. cgives<ul><li>a <ul><li>b <ol><li>c</li></ol></li></ul></li></ul>. - Tight and loose lists follow Markdown: items with no blank line between them paste as plain list items (
<ul><li>a</li><li>b</li></ul>); items separated by blank lines carry a paragraph each (<ul><li><p>a</p></li><li><p>b</p></li></ul>), which Docs shows with extra spacing. - Task lists become
<ul><li>☑ done</li><li>☐ todo</li></ul>: a character, not a checkbox, because HTML on the clipboard cannot create Docs checkboxes. - Code keeps its characters and gets the monospace font through
<code style="font-family:Consolas,'Courier New',monospace">; the language name after the opening fence is not carried over. Syntax colouring is not applied. Docs has nowhere to keep it. - Images are passed as their address:
<p><img src="https://example.com/logo.png" alt="Logo"></p>. Whether the destination fetches and shows the picture is up to that application; Docs generally does for a public URL, an email draft may not. - Links with a
javascript:ordata:address are dropped, keeping only their text, so a pasted document can never carry a script:<p>click and <a href="https://example.com">ok</a></p>. - HTML typed into the Markdown is text, not markup.
<b>typed</b>is escaped and shows as those characters:<p><b>typed</b> & <script>x</script></p>. If you have HTML already, paste it into the destination directly. - Headings map to Heading 1–6 in Docs, from
#through######; a#######with seven hashes is a paragraph, as in Markdown. - The clipboard needs a user action. Browsers only allow a clipboard write from a click or a key press, which is why there is no automatic copy on paste. If a browser extension blocks clipboard access, select the preview by hand and press Ctrl+C: the selection carries the formatting too.
- Empty input shows the empty preview and disables the buttons. Half a megabyte of Markdown renders in well under a second; typing is debounced so keystrokes never wait on it.
Do the same thing in code
Shell (pandoc)
pandoc -f gfm -t html notes.md -o notes.html # the same kind of fragment
pandoc -f gfm -o notes.docx notes.md # straight to WordPython
import markdown
html = markdown.markdown(text, extensions=["tables", "fenced_code"])JavaScript (browser)
import { marked } from "marked";
const html = marked.parse(text);
await navigator.clipboard.write([
new ClipboardItem({
"text/html": new Blob([html], { type: "text/html" }),
"text/plain": new Blob([text], { type: "text/plain" }),
}),
]);When the destination is a chat box rather than a document, formatting is the problem, not the goal: Markdown to Plain Text removes it while keeping the structure, or rewrites it as Slack, WhatsApp or Google Chat markup. Text that came out of an AI assistant with curly quotes and em dashes can go through the AI Text Cleaner first.