RTF describes a formatted document (fonts, colors, paragraphs, lists, tables, images, headers and footers) as plain ASCII text with control words like \b (bold) and \par (end of paragraph) grouped by braces. Almost every word processor reads and writes it, which made it the traditional exchange format between Microsoft Word, LibreOffice, Apple TextEdit and others. It’s still used for clipboard rich text on Windows and macOS, for Outlook rich-text email, for document templates generated by programs, and in legal and medical systems.
RTF is verbose and the spec is large; each program supports a different subset, so complex layouts don’t survive a round trip. For modern documents use DOCX or ODT; for simple formatted text Markdown or HTML are easier to generate and parse.
An RTF file is one group {...} that starts with \rtf1. Inside are control words, control symbols, nested groups and plain text. The text is 7-bit ASCII; other characters are escaped.
{\rtf1\ansi\ansicpg1252\deff0
{\fonttbl{\f0\fswiss Arial;}{\f1\fmodern Courier New;}}
{\colortbl;\red0\green0\blue0;\red200\green0\blue0;}
{\info{\title Example}{\author Ann}}
\pard\fs24 Hello, {\b bold} and {\i italic} text.\par
\pard\cf2 Red text, caf\'e9 (code page) and 荤? (Unicode euro).\par
{\f1 Monospaced}\par
}
The header comes before the first text: \rtf1, the character set (\ansi, \mac, \pc), the default code page (\ansicpgN), the default font (\deffN) and these destination groups:
Group
Contents
{\fonttbl ...}
fonts: \f0 number, family (\froman, \fswiss, \fmodern), charset (\fcharset204 for Cyrillic), name
{\colortbl ...}
colors as \redN\greenN\blueN;; index 0 (empty) is “auto”; \cfN and \highlightN refer to them
To extract plain text: track the group stack, skip destinations you don’t handle (font table, color table, stylesheet, info, pictures, any group starting with {\*), turn \par and \line into newlines, \tab into tabs, decode \'hh with the current code page (from \ansicpg or the font’s \fcharset), decode \uN and skip the next N fallback characters (from \uc, default 1). Libraries like striprtf do exactly this.