Documents

The contents of a page is stored as a Document object. For example, the following "Hello world!" document:

image

May be created and manipulated in Rust:

let document = doc![
    DocGroup({"tag": "h1"}, ["Hello world!"]),
    DocGroup({"tag": "p"}, ["This is a document."]),
];

// Convert this document to Markdown.
let markdown = edit_common::markdown::doc_to_markdown(&document)?;

Text and Groups

Documents are composed of text and groups. Text is a unicode string modeled by the DocString type. Groups are similar to HTML elements, having a set of "attributes" and then a vector of children which can be either text or other groups.

In Rust, enum DocElement models these two types:

type DocSpan = Vec<DocElement>;

type Attrs = HashMap<String, String>;

enum DocElement {
    DocText(DocString),
    DocGroup(Attrs, DocSpan),
}

You can use the oatie::macros::doc! macro to conveniently create DocSpan objects:

doc![
    DocGroup({"tag": "h1"}, ["Title"]),
    DocGroup({"tag": "bullet"}, [
        DocGroup({"tag": "p"}, ["Groups can be nested."]),
        DocGroup({"tag": "p"}, ["With multiple elements."]),
    ]),
]

Documents and Operations

Documents can have operations performed on them to result in a new, modified document.

Schema

Documents have no enforced structure other than being a collection of text and groups. To define which types in a document are valid and what they are allowed to contain, the oatie::schema::RtfSchema defines which groups can contain what other groups, which can contain text content, and which can be found in the root. See oatie::validate::validate_doc_span for how to validate a document tree.