scrivener-rtf 0.1.0

Pure Rust RTF parser and generator, optimized for Scrivener workflows
Documentation

scrivener-rtf

Crates.io Documentation License: MIT

A pure Rust RTF (Rich Text Format) parser and generator, optimized for Scrivener workflows.

Features

  • 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

Installation

Add this to your Cargo.toml:

[dependencies]
scrivener-rtf = "0.1"

Usage

Parsing RTF

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);

Generating RTF

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!}

Writing to File

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();

API Overview

Main Types

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

Parsing Functions

Function Description
parse Parse RTF bytes into a Document
parse_str Parse RTF from a string
parse_file Parse an RTF file from disk

Generation Methods

Method Description
Document::to_rtf() Convert document to RTF string
Document::write_to() Write document to any Write implementation

Supported RTF Features

  • ✅ 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

Scrivener Compatibility

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

Documentation

Full API documentation is available at docs.rs/scrivener-rtf.

License

This project is licensed under the MIT License.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.