What Is RTF?
RTF (Rich Text Format) is a document format developed by Microsoft in 1987, originally as a cross-platform exchange format between different word processors and operating systems. Unlike plain text, RTF preserves text formatting — fonts, sizes, bold/italic/underline, colors, paragraph alignment, indentation, and even embedded images. Unlike binary formats (DOC, DOCX), RTF is entirely plain text — you can open an RTF file in any text editor and read the raw markup.
RTF was designed with interoperability as the primary goal: it was Microsoft's answer to the question "how do we transfer formatted text between Word on DOS, Word on Mac, and third-party word processors?" That design philosophy — plain text with embedded markup — made RTF extraordinarily durable. Despite being largely superseded by DOCX for document exchange, RTF remains:
- The interchange format for macOS TextEdit and iOS Notes
- The format used internally by Windows Clipboard for rich text
- A universal import/export target supported by every major word processor
- The default format for WordPad (still shipped with Windows)
- Widely used in legal technology, court systems, and legacy enterprise software
File Structure
RTF files are pure ASCII text (extended to include binary blobs for embedded objects). The fundamental structure is a hierarchy of groups enclosed in braces {}, with control words prefixed by backslash \.
RTF Preamble
Every valid RTF file starts with:
{\rtf1\ansi\deff0
{— opens the root group (the entire document)\rtf1— identifies the file as RTF version 1\ansi— character set (ANSI; alternatives:\mac,\pc,\pca)\deff0— default font is font #0 from the font table
Font Table
{\fonttbl
{\f0\froman\fcharset0 Times New Roman;}
{\f1\fswiss\fcharset0 Arial;}
{\f2\fmodern\fcharset0 Courier New;}
}
Each font entry: \f = font number, \froman/\fswiss/\fmodern/\fnil = font family, \fcharset = character set encoding.
Color Table
{\colortbl
; ← color 0: auto (default)
\red255\green0\blue0; ← color 1: red
\red0\green0\blue255; ← color 2: blue
}
Colors are referenced by index: \cf1 = color 1 (foreground), \highlight2 = color 2 (background highlight).
Document Body
After the tables, the document body contains paragraphs separated by \par:
\pard\sb240\sa120
{\b\fs28 Chapter One\par}
\pard\sb0\sa120\fi720
This is a paragraph with a first-line indent. The text continues
normally until the {\i italic phrase} and then resumes.\par
Control Words Reference
Control words are the RTF markup primitives. Each is a backslash followed by letters, optionally followed by a numeric parameter and a delimiter (space or non-letter):
Character Formatting
| Control Word | Effect |
|---|---|
\b |
Bold on (toggle) |
\b0 |
Bold off |
\i |
Italic on |
\ul |
Underline on |
\ulnone |
Underline off |
\strike |
Strikethrough |
\scaps |
Small caps |
\fs24 |
Font size 24 half-points (= 12pt) |
\f1 |
Use font #1 from font table |
\cf2 |
Foreground color #2 |
\highlight3 |
Background highlight color #3 |
\super |
Superscript |
\sub |
Subscript |
Note: Font size in RTF is in half-points. \fs24 = 12pt, \fs28 = 14pt, \fs72 = 36pt.
Paragraph Formatting
| Control Word | Effect |
|---|---|
\pard |
Reset to default paragraph formatting |
\ql |
Left-align (default) |
\qr |
Right-align |
\qc |
Center |
\qj |
Justify |
\sb240 |
Space before: 240 twips (= 12pt) |
\sa120 |
Space after: 120 twips (= 6pt) |
\li720 |
Left indent: 720 twips (= 0.5 inch) |
\ri0 |
Right indent: 0 |
\fi720 |
First-line indent: 720 twips |
\fi-720\li720 |
Hanging indent |
\sl276\slmult1 |
Line spacing: 1.15× (276/240) |
Twips: The RTF unit is the twip = 1/20 of a point = 1/1440 of an inch. A standard 1-inch margin = 1440 twips.
Section and Page Control
| Control Word | Effect |
|---|---|
\sect |
Section break |
\page |
Page break |
\landscape |
Landscape orientation |
\paperw12240 |
Paper width: 12240 twips (8.5 inches) |
\paperh15840 |
Paper height: 15840 twips (11 inches) |
\margl1800 |
Left margin: 1800 twips (1.25 inches) |
Embedded Images
RTF can embed binary image data as hexadecimal strings:
{\pict\wmetafile8\picw2267\pich2267\picwgoal1247\pichgoal1247
010009000003b000000000800300000000000008030000...}
Or PNG/JPEG directly:
{\pict\pngblip\picw200\pich150\picwgoal2834\pichgoal2126
89504e470d0a1a0a...}
The \pict destination introduces a picture. Format control words: \wmetafile (WMF), \emfblip (EMF), \pngblip (PNG), \jpegblip (JPEG).
RTF Compatibility Across Applications
RTF has no single spec authority — Microsoft published the spec through version 1.9.1 (Word 2007), and applications implement varying subsets:
| Application | RTF Support |
|---|---|
| Microsoft Word | Full (also writes proprietary extensions) |
| LibreOffice Writer | Very good (some Word extensions ignored) |
| Google Docs | Good import; export loses some features |
| Apple Pages | Good import/export |
| macOS TextEdit | Basic (no tables, no complex formatting) |
| WordPad (Windows) | Basic (no footnotes, headers, tables) |
| Notepad++ | Opens as text (no formatting rendered) |
Common Compatibility Issues
Word-specific control words: \trowd/\trrh/\cellx (table structure) is standard RTF, but Word adds private extensions like \tblind that LibreOffice ignores.
Fonts: RTF embeds font names but not font files. If the target system lacks the font, substitution occurs. Always check output on the target platform.
Images: JPEG images embedded in RTF can have color space issues when rendered by non-Microsoft RTF parsers.
Revision tracking: \revtbl, \author, \time control words for tracked changes work fully only in Word.
Converting RTF Files
With FFmpeg / Pandoc
# RTF to DOCX
pandoc input.rtf -o output.docx
# RTF to PDF
pandoc input.rtf -o output.pdf
# RTF to plain text (strip all formatting)
pandoc input.rtf -t plain -o output.txt
# RTF to HTML
pandoc input.rtf -t html -o output.html
# RTF to Markdown
pandoc input.rtf -t markdown -o output.md
Python (striprtf)
from striprtf.striprtf import rtf_to_text
with open('document.rtf', 'r', encoding='utf-8', errors='ignore') as f:
rtf_content = f.read()
text = rtf_to_text(rtf_content)
print(text)
LibreOffice command-line
# Convert RTF to PDF via LibreOffice headless
soffice --headless --convert-to pdf input.rtf
# Convert RTF to DOCX
soffice --headless --convert-to docx input.rtf
# Convert directory of RTFs to PDFs
soffice --headless --convert-to pdf *.rtf
Reading RTF structure manually
import re
def parse_rtf_basic(rtf_text):
"""Extract plain text from RTF by stripping control words."""
# Remove RTF groups and control words
text = re.sub(r'\{[^{}]*\}', '', rtf_text) # remove simple groups
text = re.sub(r'\\[a-z]+\d*\s?', '', text) # remove control words
text = re.sub(r'\\[^a-z]', '', text) # remove control symbols
return text.strip()
RTF vs DOCX vs ODF
| Feature | RTF | DOCX | ODT |
|---|---|---|---|
| File type | Plain text | ZIP of XMLs | ZIP of XMLs |
| Human-readable | Yes (with effort) | No | No |
| Max image quality | Good | Excellent | Excellent |
| Revision tracking | Limited | Full | Full |
| Tables | Yes (complex) | Full | Full |
| Macros/VBA | No | Yes (DOCX) | Yes (ODT) |
| Compatibility | Universal | Near-universal | Good |
| File size (text doc) | Small-Medium | Small | Small |
| Long-term archival | Good | Good | Excellent (ISO) |
When to Use RTF
Use RTF when:
- Maximum compatibility is required across all word processors (even legacy)
- Sharing documents with legal software, court filing systems, or old enterprise applications
- Creating simple formatted documents without complex features
- You need human-readable document source (for debugging, scripting, or text processing)
Avoid RTF when:
- Complex tables, footnotes, or tracking changes are needed
- File size is critical (RTF images are hex-encoded = 2× binary size)
- Collaborating in modern cloud workflows (use DOCX or Google Docs format)
- Long-term archival (prefer ODT/ISO 26300 or PDF/A)
RTF's ASCII-based design means it can always be opened in a text editor, scripted with regex, and processed without specialized libraries — a property that ensures its continued relevance 35+ years after its creation.
Related conversions
Document conversions that follow this topic naturally: