[](https://crates.io/crates/text-document)
[](https://docs.rs/text-document)
[](#license)
[](https://github.com/jacquetc/text-document/actions/workflows/ci.yml)
[](https://codecov.io/gh/jacquetc/text-document)

# text-document
A text document structure and management for Rust
This model is thought as a backend for a text UI. [`TextDocument`] can't be modified directly by the user, only for setting the whole document with `set_plain_text(...)`.
The user must use a [`TextCursor`] using `document.create_cursor()` to make any change.
# Document structure
## Elements
- [`Frame`]: contains Block elements and other Frame elements, formatable with FrameFormat
- [`Block`]: contains Text elements or Image elements, formatable with BlockFormat
- [`Text`]: contains the actuel text, formatable with TextFormat
- [`Image`]: represent the position of an image, formatable with ImageFormat
All these items are encapsulated in its corresponding [`Element`] for ease of storage.
## The simpler plain text
```raw
Frame
|- Block
|- Text
|- Block
|- Text
```
## The more complex rich text
```raw
Frame
|- Block
|- Text --> I really lo
|- Text --> ve (imagine it Formatted in bold)
|- Text --> Rust
|- Image
|- Text
|- Frame
|- Block
|- Text
|- Text
|- Text
|- Block
|- Text
|- Text
|- Text
|- Block
|- Image
```
# Signaling changes
Each modififcation is signaled using callbacks. [`TextDocument`] offers different ways to make your code aware of any change:
- [`TextDocument::add_text_change_callback()`]
Give the number of removed characters and number of added characters with the reference of a cursor position.
- [`TextDocument::add_element_change_callback()`]
Give the modified element with the reason. If two direct children elements changed at the same time.
# Examples
```rust
use text_document::{TextDocument, ChangeReason, MoveMode};
let mut document = TextDocument::new();
document.add_text_change_callback(|position, removed_characters, added_characters|{
println!("position: {}, removed_characters: {}, added_characters: {}", position, removed_characters, added_characters);
} );
document.add_element_change_callback(|element, reason|{
assert_eq!(element.uuid(), 0);
assert_eq!(reason, ChangeReason::ChildrenChanged );
} );
document.set_plain_text("beginningend").unwrap();
let mut cursor = document.create_cursor();
cursor.set_position(9, MoveMode::MoveAnchor);
cursor.insert_plain_text("new\nplain_text\ntest");
```
## License
Licensed under either of
* Apache License, Version 2.0
([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
* MIT license
([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
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.