100% Local · Free · No Sign-up

Convert RTF (Rich Text) to Clean Markdown

A dependency-free scanner walks your .rtf document group by group, tracking \b/\i/\ul as state and skipping the font, colour and stylesheet tables entirely. What comes out is clean CommonMark with emphasis, paragraphs and list items intact — produced without uploading the file anywhere.
Convert RTF (Rich Text) to Clean MarkdownDrag & drop · .rtf

Processing happens 100% in your browser — nothing is uploaded.

Tables and headings are not reconstructed

RTF encodes tables as a flat run of \cell and \row control words with column geometry declared separately, so cell text is emitted as running paragraphs and a warning tells you a table was present. Heading levels are visual in RTF rather than semantic, so headings arrive as bold paragraphs — promote them with # yourself. If a .docx of the same document exists, convert that instead.
100% Local Processing — Your files never leave your device

How to convert RTF to Markdown

  1. Drop: drag your .rtf file onto the dropzone, or paste the raw RTF markup into the editor.
  2. Process: the scanner strips machine destinations locally and maps emphasis, paragraphs and list items to Markdown.
  3. Copy: copy the CommonMark output or download it as a .md file.

Why Convert RTF to Markdown with MD Convert?

  • Toggle formatting, handled properly

    Word and WordPad emit `\b bold\b0`, not `{\b bold}`. Formatting is tracked as state across brace groups exactly as the RTF 1.9.1 spec requires, so bold, italic and underline survive on real documents instead of being stripped with the rest of the control words.

  • Font, colour and stylesheet bloat removed

    Destinations are skipped with a brace counter, not a regex, so nested groups like {\fonttbl{\f0\froman Times;}} disappear completely rather than leaking font names and colour definitions into the top of your output.

  • Codepage-correct text

    The declared \ansicpg is honoured and \uNNNN escapes have their ANSI fallback characters skipped, so Windows-1252 smart quotes, apostrophes, en/em dashes and ellipses decode to real Unicode instead of mojibake.

  • 100% local, zero dependencies

    The parser is plain JavaScript with nothing to download and no server round-trip. Legal filings, clinical notes and archived correspondence are converted inside your tab and never transmitted.

RTF to Markdown: Before and After

Toggle-style runs (\b … \b0) become emphasis, the pre-rendered bullet glyph in \pntext becomes a real Markdown list item, Windows-1252 smart quotes decode correctly, and the font, colour and generator tables are removed entirely.

Input · text
{\rtf1\ansi\ansicpg1252\deff0
{\fonttbl{\f0\froman Times New Roman;}{\f1\fswiss Arial;}}
{\colortbl ;\red255\green0\blue0;}
{\*\generator Riched20 10.0.19041;}
\pard\fs24 Findings were \b conclusive\b0  and
\i replicable\i0 , per the \ul appendix\ulnone .\par
{\pntext\f1\'B7\tab}\pard Sample size: 240\par
{\pntext\f1\'B7\tab}\pard Effect held at \'93p < .01\'94\par}
Output · Markdown
Findings were **conclusive** and _replicable_, per the <u>appendix</u>.

- Sample size: 240
- Effect held at "p < .01"

Understanding the RTF Format: Microsoft RTF Specification 1.9.1

Format
Rich Text Format (RTF)
Media type
application/rtf
Parser used
Custom RTF scanner (no dependencies)

RTF is a plain-text markup language from 1987 that encodes a formatted document as ASCII control words inside brace-delimited groups. A document opens with `{\rtf1\ansi\ansicpg1252`, declares its font and colour tables, and then emits text interleaved with instructions: `\b` turns bold on, `\b0` turns it off, `\par` ends a paragraph, `\ul` underlines, `\tab` inserts a tab. Because it is text rather than a binary container, RTF outlived the applications that produced it — which is exactly why it still shows up in legal archives, court filings, clinical notes and anything exported from WordPad or a 1990s document management system.

Two spec details dominate the conversion. First, formatting is *stateful*: `\b` applies until it is switched off or until the enclosing group closes, and group nesting saves and restores that state. Second, non-ASCII characters are escaped twice over — `\'hh` is a raw byte to be interpreted through the document's `\ansicpg` codepage, and `\uNNNN` is a Unicode codepoint followed by a fallback character that must be skipped, with the skip count set by `\ucN`.

Getting either detail wrong produces output that looks plausible and is quietly damaged. Ignore state and every `\b bold\b0` run loses its emphasis, because Word and WordPad almost never use the `{\b …}` group form that a naive regex looks for. Ignore the codepage and Windows-1252 smart quotes, en dashes and ellipses turn into control characters or Latin-1 mojibake — precisely the characters most likely to appear in prose.

A scanner, not a pile of regular expressions

The obvious way to convert RTF is to delete everything that looks like a control word and keep what is left. It half-works, and the half that fails is instructive. A font table is `{\fonttbl{\f0\froman Times New Roman;}}` — a group inside a group — and a regular expression cannot reliably match across the inner braces, so font names, colour definitions and generator strings leak into the top of your output as garbage text. This converter instead walks the document character by character with a brace counter, so an unwanted destination is skipped as a whole subtree regardless of how deeply it nests.

The same walk maintains a formatting stack. Entering a group pushes the current bold/italic/underline state; leaving it pops the state back, exactly as the specification requires. Emphasis markers are then emitted around text runs as the state changes, and closed at every paragraph boundary so an unbalanced `**` cannot escape into the rest of the document. This is what makes toggle-based formatting work, and toggle-based formatting is what real word processors emit.

Destinations that carry machine data rather than document text — `\fonttbl`, `\colortbl`, `\stylesheet`, `\listtable`, `\info`, `\pict`, `\object`, `\themedata`, and anything marked ignorable with `{\*` — are dropped wholesale. Page headers and footers are dropped too: they repeat on every page and add nothing to a Markdown document, which has no pages.

Bold, italic, underline and the list-item problem

Bold maps to `**`, italic to `_`, and underline to `<u>…</u>`. That last one is a deliberate compromise: Markdown has no underline syntax, and mapping underline to italic or bold would misrepresent the document. GFM renders inline HTML, so `<u>` keeps the author's intent visible without inventing semantics. If your target renderer forbids raw HTML, a find-and-replace across the output is trivial — and, more importantly, obvious.

Lists are the subtler case. RTF does not necessarily say "this paragraph is a list item". Word pre-renders the bullet glyph or number into a `{\pntext …}` or `{\listtext …}` group so that readers without list support still see something, and the actual list definition lives in a separate `\listtable` keyed by an override index. Reconstructing that table faithfully is a large job for a marginal payoff, so the converter takes the reliable signal instead: a paragraph preceded by one of those pre-rendered marker groups is a list item, and it is emitted as `- `. The glyph itself is discarded so you do not end up with `- • text`.

The consequence is honest and worth stating: nesting depth is not reconstructed, and ordered lists come out as bullets rather than as `1.` numbering. You get a flat, correctly-marked list — indentation is a two-second edit, whereas recovering list membership by hand from a wall of paragraphs is not.

Encoding: codepages, Unicode escapes and mojibake

RTF predates Unicode, so its default character model is a byte plus a codepage. The document header declares one — `\ansicpg1252` for Western Windows text — and every `\'hh` escape is a byte to be interpreted in that codepage. The awkward part is the 0x80–0x9F range, where Windows-1252 and Latin-1 disagree completely: `\'93` and `\'94` are the opening and closing curly double quotes in CP1252 and unprintable control characters in Latin-1. Decode them as Latin-1 and every quotation mark in the document becomes junk.

This converter reads the declared codepage and maps that range through the correct Windows-1252 table, so smart quotes, apostrophes, en and em dashes, ellipses and the euro sign survive. Modern producers also emit `\uNNNN` for anything outside the codepage, immediately followed by a fallback character for old readers; the fallback must be discarded or it appears twice. The `\ucN` count that controls how many fallback characters to skip is tracked, and escapes such as `\endash`, `\emdash`, `\lquote`, `\bullet` and non-breaking spaces are mapped to their Unicode equivalents.

The output is UTF-8 Markdown. Because everything happens in the browser, there is no server-side locale or default encoding to second-guess the file — a common source of corruption when a document is round-tripped through a conversion API.

When RTF is the wrong source file

RTF can express tables, and this converter does not reconstruct them. RTF table markup is a flat sequence of `\cell` and `\row` control words with column geometry declared in `\trowd` definitions, so rebuilding a grid means reconstructing layout arithmetic rather than reading structure. Instead of inventing a table, the converter emits the cell text as running paragraphs and raises a warning that says a table was present — you know to check, rather than discovering later that a grid quietly flattened.

If the same document exists as .docx, convert that instead. DOCX is XML with real semantic elements for headings, lists and tables, so heading levels, nested list depth and table structure all survive; RTF has visual formatting where DOCX has structure. Similarly, if the RTF came out of a PDF or a scan, the text layer is the limiting factor, not the RTF.

Where RTF is the right source, this is a strong path: it is a text format, so conversion is fast and deterministic, there is no heavyweight dependency to load, and nothing about the document leaves your machine. That last point is why the tool exists in this shape — the documents still living in RTF in 2026 are disproportionately the ones nobody should be uploading to a random converter.

Known limitations of RTF to Markdown conversion

Being explicit about what a converter cannot do saves you a wasted upload. These are the boundaries of what is recoverable from RTF programmatically:

  • Tables are not reconstructed. Cell text is emitted as consecutive paragraphs and a warning reports that a table was found.
  • Embedded images and OLE objects (`\pict`, `\object`) are binary payloads and are omitted; a warning names them when present.
  • Heading levels cannot be recovered. RTF marks headings with styles and font sizes rather than semantic levels, so headings arrive as bold paragraphs. Promote them to `#` manually.
  • List nesting depth and ordered-list numbering are flattened to single-level `-` bullets.
  • Underline becomes inline `<u>` HTML because Markdown has no underline syntax.
  • Page headers, footers, footnote frames and revision-tracking metadata are discarded.
  • Codepages other than Windows-1252 fall back to a byte-for-byte reading; documents in a legacy East Asian or Cyrillic codepage may need re-saving as UTF-8 RTF first.

Who Converts RTF to Markdown?

  • Legal / records analyst

    Pulls text out of archived .rtf filings for a knowledge base without sending privileged documents to a web service.

  • Obsidian / Notion writer

    Migrates a decade of WordPad and TextEdit notes into a Markdown vault with bold, italic and lists intact.

  • Developer

    Normalises RTF payloads exported from a legacy CMS or clipboard capture into Markdown for a static site.

  • Researcher

    Converts interview transcripts and old field notes into plain, greppable Markdown files.

How You Can Verify the Privacy Claim

Browser-only

Zero server upload

Conversion runs inside your browser tab. Open DevTools, switch to the Network panel, and convert a file: for every format except URL to Markdown you will see no request carrying your document — because there is no endpoint to send it to.

Web Worker

Off the main thread

Heavy parsing is dispatched to a Web Worker, so a 500-page PDF or a large spreadsheet never freezes the interface. Everything is plain JavaScript — no native plugin, no WebAssembly toolchain, nothing to install.

No account

Nothing to sign up for

No login, no quota, no paywall, and no tracking tied to your files. Analytics are cookieless and aggregate only. Read the privacy policy for the full data-flow breakdown, including the one proxied exception.

The parsers doing the work

No proprietary black box: each format is handled by a widely audited open-source library, running client-side at the version pinned in our lockfile.

RTF to Markdown — FAQ

Which formatting survives the conversion to Markdown?

Bold becomes **, italic becomes _, underline becomes <u> inline HTML (Markdown has no underline syntax), paragraph breaks become blank lines, \line becomes a hard break, and list items become - bullets. Font families, sizes, colours, alignment, tab stops and page geometry are dropped because Markdown cannot express any of them.

Why did my bulleted list come out flat instead of nested?

RTF does not label a paragraph as a list item. Word pre-renders the bullet glyph into a {\pntext …} or {\listtext …} group and keeps the real list definition in a separate \listtable keyed by an override index. The converter uses the pre-rendered marker as the signal that the paragraph is a list item and emits a single-level - bullet, discarding the glyph. Nesting depth and ordered numbering are not reconstructed, so re-indent by hand if depth matters.

Are smart quotes and accented characters handled correctly?

Yes. RTF stores non-ASCII text as \'hh bytes interpreted through the document's declared codepage, and the 0x80-0x9F range is where Windows-1252 and Latin-1 disagree — \'93 is a curly opening quote in CP1252 and a control character in Latin-1. That range is mapped through the correct CP1252 table, and \uNNNN escapes are decoded with their fallback characters skipped per \ucN.

Is my RTF file uploaded to a server?

No. The parser is plain JavaScript running in your browser tab with no external dependency to fetch and no API call to make. The file is read through the File API, transformed in memory, and gone when you close the page — which is the point, given how much of what is still stored as RTF is legal, medical or archival material.

How large an RTF file can it handle, and does it work offline?

RTF is plain text, so parsing is a single linear pass and multi-megabyte documents convert in well under a second; the limit is your device's memory, not an upload quota. Because there is no network call in the conversion path, it also works offline once the page has been loaded, and on machines whose firewall blocks outbound requests.