text-document-io 0.0.11

Import/export for text-document: plain text, Markdown, HTML, LaTeX, DOCX
Documentation

crates.io API quality codecov license

text-document

A rich text document model for Rust, inspired by Qt's QTextDocument/QTextCursor API.

Built on Qleany-generated Clean Architecture with redb (embedded ACID database), full undo/redo, and multi-cursor support.

Features

  • Rich text model: Frames, Blocks, InlineElements with InlineContent::Text | Image
  • Multi-cursor editing: Qt-style cursors with automatic position adjustment
  • Full undo/redo: Snapshot-based, with composite grouping (begin_edit_block / end_edit_block)
  • Import/Export: Plain text, Markdown, HTML, LaTeX, DOCX
  • Search: Find, find all, regex, replace (undoable)
  • Formatting: Character format (bold, italic, underline, ...), block format (alignment, heading_level, ...), frame format
  • Event system: Callback-based (on_change) and polling-based (poll_events)
  • Thread-safe: Send + Sync throughout, Arc<Mutex<...>> interior mutability
  • Resources: Image and stylesheet storage with base64 encoding

Quick start

use text_document::{TextDocument, MoveMode, MoveOperation};

let doc = TextDocument::new();
doc.set_plain_text("Hello world").unwrap();

// Cursor-based editing
let cursor = doc.cursor();
cursor.move_position(MoveOperation::EndOfWord, MoveMode::KeepAnchor, 1);
cursor.insert_text("Goodbye").unwrap(); // replaces "Hello"

// Multiple cursors
let c1 = doc.cursor();
let c2 = doc.cursor_at(5);
c1.insert_text("A").unwrap();
// c2's position is automatically adjusted

// Undo
doc.undo().unwrap();

// Search
use text_document::FindOptions;
let matches = doc.find_all("world", &FindOptions::default()).unwrap();

// Export
let html = doc.to_html().unwrap();
let markdown = doc.to_markdown().unwrap();

CLI

A command-line tool for format conversion and text processing:

# Convert between formats (detected by file extension)
text-document convert README.md output.html
text-document convert article.html article.tex

# Show document statistics
text-document stats manuscript.md

# Find text (grep-like output)
text-document find paper.md "TODO" --case-sensitive

# Find and replace
text-document replace draft.md "colour" "color" --output fixed.md

# Print to stdout in a different format
text-document cat notes.html --format plain

Supported formats:

Extension Import Export
.txt yes yes
.md yes yes
.html/.htm yes yes
.tex/.latex - yes
.docx - yes

Document structure

Root
 +-- Document
     +-- Frame (root frame)
     |   +-- Block
     |   |   +-- InlineElement (Text "Hello ")
     |   |   +-- InlineElement (Text "world" with bold)
     |   |   +-- InlineElement (Image { name, width, height })
     |   +-- Block
     |       +-- InlineElement (Text "Second paragraph")
     +-- List (style: Decimal, indent: 1)
     +-- Resource (image data, stylesheets)
  • Frame: contains Blocks and child Frames. child_order interleaves them.
  • Block: a paragraph. Contains InlineElements. Has document_position for O(log n) lookup.
  • InlineElement: either Text(String), Image { name, width, height, quality }, or Empty.
  • List: styling for list items (Disc, Decimal, LowerAlpha, ...). Blocks reference lists via weak relationship.
  • Resource: binary data (images, stylesheets) stored as base64.

All format fields are Option<T>None means "inherit from parent/default", Some(value) means "explicitly set".

Architecture

Generated by Qleany v1.5.1, following Clean Architecture with Package by Feature (Vertical Slice):

crates/
+-- public_api/       # TextDocument, TextCursor, DocumentEvent (the public crate)
+-- cli/              # Command-line tool
+-- frontend/         # AppContext, commands, event hub client
+-- common/           # Entities, database (redb), events, undo/redo, repositories
+-- macros/           # #[uow_action] proc macro
+-- direct_access/    # Entity CRUD controllers + DTOs
+-- document_editing/ # 11 use cases (insert, delete, block, image, frame, list, fragment, ...)
+-- document_formatting/ # 4 use cases (set/merge text format, block format, frame format)
+-- document_io/      # 8 use cases (import/export plain text, markdown, HTML, LaTeX, DOCX)
+-- document_search/  # 3 use cases (find, find_all, replace)
+-- document_inspection/ # 4 use cases (stats, text at position, block at position, extract fragment)
+-- test_harness/       # Shared test setup utilities

Data flow: TextDocument / TextCursor -> frontend::commands -> controllers -> use cases -> UoW -> repositories -> redb

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.