A pure Rust RTF (Rich Text Format) parser and generator, optimized for Scrivener workflows.
- Parse RTF documents into an Abstract Syntax Tree (AST) representation
- Generate RTF from the AST
- Full Unicode support including surrogate pairs for emoji
- Extract document properties (fonts, colors, styles)
- Zero unsafe code - memory safe by design
- No external dependencies on system RTF libraries
Add this to your Cargo.toml:
[dependencies]
scrivener-rtf = "0.1"use scrivener_rtf::{parse, parse_str, parse_file};
// Parse RTF from bytes
let doc = parse(b"{\\rtf1 Hello, World!}").unwrap();
// Parse RTF from string
let doc = parse_str("{\\rtf1 Hello}").unwrap();
// Parse RTF from file
let doc = parse_file("document.rtf").unwrap();
// Access document structure
for group in &doc.groups {
for content in &group.content {
match content {
scrivener_rtf::Content::Text(text) => println!("Text: {}", text),
scrivener_rtf::Content::ControlWord(name, param) => {
println!("Control: \\{}{:?}", name, param)
}
_ => {}
}
}
}
// Access document properties
println!("Fonts: {:?}", doc.properties.font_table);
println!("Colors: {:?}", doc.properties.color_table);use scrivener_rtf::{Document, Group, Content, DocumentProperties};
let doc = Document {
groups: vec![Group {
content: vec![
Content::ControlWord("rtf".into(), Some(1)),
Content::ControlWord("ansi".into(), None),
Content::Text("Hello, World!".into()),
],
is_destination: false,
}],
properties: DocumentProperties::default(),
};
let rtf = doc.to_rtf();
println!("{}", rtf); // {\\rtf1 \\ansi Hello, World!}use std::fs::File;
use scrivener_rtf::{Document, Group, Content, DocumentProperties};
let doc = Document { /* ... */ };
let mut output = File::create("output.rtf").unwrap();
doc.write_to(&mut output).unwrap();| Type | Description |
|---|---|
Document |
Root node of a parsed RTF file |
Group |
A { ... } group in RTF |
Content |
Content within a group (text, control words, nested groups) |
DocumentProperties |
Extracted header properties |
Font |
Font table entry |
Color |
Color table entry |
Style |
Stylesheet entry |
| Function | Description |
|---|---|
parse |
Parse RTF bytes into a Document |
parse_str |
Parse RTF from a string |
parse_file |
Parse an RTF file from disk |
| Method | Description |
|---|---|
Document::to_rtf() |
Convert document to RTF string |
Document::write_to() |
Write document to any Write implementation |
- ✅ Group structure (
{ ... }) - ✅ Control words with parameters (
\fs24,\cf1) - ✅ Control symbols (
\~,\-,\_) - ✅ Destination groups (
\*\generator) - ✅ Font table (
\fonttbl) - ✅ Color table (
\colortbl) - ✅ Stylesheet (
\stylesheet) - ✅ Unicode escapes (
\uN) - ✅ Surrogate pairs for emoji
This library is designed to work with RTF files produced by Scrivener, handling:
- Scrivener-specific destination groups
- Unicode content in annotations and notes
- Style definitions used in Scrivener projects
Full API documentation is available at docs.rs/scrivener-rtf.
This project is licensed under the MIT License.
Contributions are welcome! Please feel free to submit a Pull Request.