Google Docs to Markdown

Paste formatted text copied from Google Docs, Word or a web page and get Markdown with its structure intact.

Paste from Google Docs (Ctrl+V)Nothing pasted yet

The box keeps the formatting of your paste; the Markdown on the right is read from that formatting.

Lists

How to use

  1. In Google Docs (or Word, Notion, Confluence, a web page), select the text you want and copy it with Ctrl+C.
  2. Click the left box and paste with Ctrl+V. The box shows the paste with its formatting; the Markdown appears on the right at once.
  3. Read the line under the Markdown: it lists what was unwrapped, dropped or approximated (redirect links, underline, a table with no header row).
  4. Copy Markdown (or Ctrl+Enter in the box) and paste into your README, wiki, issue or note. Download .md saves a file.

What a Google Docs copy really contains

Copy a paragraph in Google Docs and the clipboard holds two things: the plain words, and an HTML version of them that Docs generates on the fly. That HTML is not the tidy <strong> and <h2>a web page would use. Bold is a <span style="font-weight:700">; the whole copy sits inside a <b> tag whose style says not bold; every link goes through a google.com/url?q= redirect; a nested list is a second list placed beside the parent item with an aria-level attribute; and one bold phrase can arrive as three spans. A converter that only looks at tag names sees none of it.

This tool reads the inline styles as well as the tags, so it produces the Markdown you would have written by hand: # headings, **bold**, *italic*, ~~strikethrough~~, `code` for Courier New, real link addresses, nested bullets and numbers, tables with a header row. It says what it had to approximate. The reverse trip is Markdown to Google Docs; when the paste is going into a chat rather than a README, Markdown to Plain Text takes the result from here.

Example

Load sample fills the box with what Docs puts on the clipboard for a short launch plan: 2headings, a paragraph with bold, italic, monospace and a link, a nested list, and a table. Abridged, the HTML looks like:

<b style="font-weight:normal;" id="docs-internal-guid-…">
  <h1 dir="ltr" style="…"><span style="font-size:20pt;font-family:Arial;font-weight:400;…">Q3 launch plan</span></h1>
  <p dir="ltr" style="…">
    <span style="font-size:11pt;font-weight:400;…">We ship on </span>
    <span style="font-size:11pt;font-weight:700;…">14 October</span>
    …
    <a href="https://www.google.com/url?q=https://example.com/wiki/billing-v2&amp;sa=D&amp;source=editors&amp;ust=…&amp;usg=…">
      <span style="…text-decoration:underline;…">rollout page</span>
    </a>
  </p>
  …
</b>

The Markdown it becomes:

# Q3 launch plan

We ship on **14 October**. The *only* blocker is the `billing-v2` flag, see the [rollout page](https://example.com/wiki/billing-v2).

## Checklist

- Freeze the release branch
  - Notify **#eng-release**
- Run the migration on staging

| Owner | Status |
| --- | --- |
| Priya | On track |

The status line for the sample reads: Google Docs redirect links were unwrapped to their real addresses. The table had no header row, so its first row became the header (Markdown tables need one).

Options explained

Edge cases and common errors

Do the same thing in code

In Google Docs itself

Tools → Preferences → tick "Enable Markdown"
Select text → right-click → Copy as Markdown
File → Download → Markdown (.md)         # the whole document

Shell (pandoc, from a downloaded .docx)

pandoc -f docx -t gfm --wrap=none document.docx -o document.md

JavaScript (browser)

// Read the HTML flavour of a paste, then convert it (turndown is the usual library).
box.addEventListener("paste", (e) => {
  const html = e.clipboardData.getData("text/html");
  const markdown = new TurndownService({ headingStyle: "atx" }).turndown(html);
});

None of those read Docs' inline styles: pandoc works from the .docx, not the clipboard, and turndown sees the font-weight:700 span as plain text unless you add a rule for it. For raw HTML source rather than a paste, use HTML to Markdown, which runs the same converter on text you type.

Google Docs to Markdown FAQ

Google Docs can copy as Markdown itself, so why use this?

It can, since July 2024: Tools → Preferences → Enable Markdown, then select text and right-click → Copy as Markdown, or File → Download → Markdown for a whole document. If that option is available to you, it is the shortest route. This page is for when it is not (an account or Workspace policy without it), for text copied from Word, Notion, Confluence or a web page, which Docs cannot help with, and for seeing the Markdown before it lands somewhere.

Why does the output have no headings or bold when I paste?

Because the paste carried no formatting. A copy from the document body carries an HTML version of the text with the styles in it; a copy from a plain-text field, a terminal, or a “paste without formatting” action carries only the words. The status line says so when that happens. Copy again from the document itself, and paste with a normal Ctrl+V, not Ctrl+Shift+V.

Do tables, nested lists and links survive?

Yes. Tables become Markdown tables; Docs marks header cells bold rather than as headers, so the first row is promoted and its bold removed. Nested lists keep their depth, whether the paste nests them properly or the Docs way (a list beside an item, with aria-level). Links are unwrapped from the google.com/url redirect Docs puts around every address, so the Markdown points at the real page.

What gets lost?

Anything Markdown cannot say: underline, colours, font sizes, alignment, and Docs’ Title and Subtitle styles (they arrive as large text, not as headings, so they become paragraphs; add a # yourself). Images are kept as links to the address Docs provides. Comments, footnotes and suggestions are not part of what Docs copies, so they never reach this page.

Is my document uploaded anywhere?

No. The paste goes into a box on this page and JavaScript in the page reads it; there is no server. Nothing you paste leaves your browser, and reloading the page discards it.

Runs entirely in your browser: this page is a static file with no server behind it, so nothing you paste can be uploaded. Last reviewed by Parthesh Gupta. Implements GitHub Flavored Markdown.