tiptap_rusty_parser/lib.rs
1//! # tiptap-rusty-parser
2//!
3//! Fast, schema-agnostic parser and manipulator for Tiptap / ProseMirror
4//! `JSONContent` documents.
5//!
6//! - **Parse / serialize** via [`Document`] (faithful roundtrip, unknown fields
7//! preserved).
8//! - **Query** with predicate closures: [`Node::find`], [`Node::find_all`],
9//! [`Node::walk`], [`Node::descendants`].
10//! - **Query language**: compile `type == heading && attrs.level > 1` once,
11//! match without allocating: [`Query::parse`], [`Query::find_paths`].
12//! - **Select** by type/mark/attr: [`Node::by_type`], [`Node::by_mark`],
13//! [`Node::by_attr`].
14//! - **Address** by index path: [`Node::node_at`], [`Node::path_to`]; or by flat
15//! ProseMirror integer position: [`Node::resolve`], [`Node::pos_before`], [`ResolvedPos`].
16//! - **Mutate** in place: marks, attrs, children, text, and bulk
17//! [`Node::replace_all`].
18//! - **Normalize** to a canonical form (merge adjacent text, drop empties):
19//! [`Node::normalize`], [`NormalizeOptions`].
20//! - **Range-edit** a block's inline content (insert/delete/replace text, mark
21//! ranges): [`Node::insert_text`], [`Node::add_mark_range`], [`Position`], [`Range`].
22//! - **Restructure** the block tree (split/join/wrap/lift/retype):
23//! [`Node::split_block`], [`Node::join_blocks`], [`Node::wrap`], [`Node::lift`], [`BlockRange`].
24//! - **Diff / apply / invert** structural change lists between two trees
25//! (undo-capable): [`Node::diff`], [`apply`], [`invert`].
26//! - **Edit by flat position**: apply a batch of [`PosEdit`]s addressed by
27//! ProseMirror integer positions, recovering an invertible patch:
28//! [`Node::apply_pos_edits`], [`PosContent`].
29//! - **Map positions through edits**: carry a position/range across a batch with
30//! [`Node::apply_pos_edits_mapped`], [`PosMap`], [`Assoc`].
31//! - **Transact**: mutate in place while recording a replayable/invertible
32//! change log: [`Node::transform`], [`Transform`].
33//! - **Operate on change lists**: [`compose`], [`compact`], and carry a path
34//! through edits with [`map_path`].
35//! - **Extract** text: [`Node::text_content`], [`Node::word_count`].
36//! - **Validate** (opt-in) against a schema, incl. ProseMirror content
37//! expressions: [`Node::validate`], [`Schema`], [`ContentExpr`].
38//! - **Source map** JSON text: node path ↔ byte span, for editors and debuggers:
39//! [`SourceMap::pretty`], [`SourceMap::span`], [`SourceMap::path_at`].
40//! - **Render** to HTML: [`Node::to_html`], [`HtmlOptions`].
41//! - **Build** nodes ergonomically: [`Node::element`], [`Node::text`], [`doc`].
42//!
43//! ```
44//! use tiptap_rusty_parser::{Document, Mark, Node};
45//!
46//! let mut doc = Document::from_json_str(
47//! r#"{"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"hi"}]}]}"#,
48//! )
49//! .unwrap();
50//!
51//! // Bold every text node.
52//! doc.replace_all(
53//! |n| n.node_type.as_deref() == Some("text"),
54//! |n| { n.add_mark(Mark::new("bold")); },
55//! );
56//!
57//! // Append a new paragraph.
58//! doc.push_child(Node::element("paragraph").with_text("bye"));
59//!
60//! assert_eq!(doc.find_all(|n| n.node_type.as_deref() == Some("paragraph")).len(), 2);
61//! ```
62
63mod block;
64mod builder;
65mod change_ops;
66mod content;
67mod diff;
68mod document;
69mod error;
70mod html;
71mod mutate;
72mod node;
73mod normalize;
74mod path;
75mod pos;
76mod pos_edit;
77mod pos_map;
78mod query;
79mod query_lang;
80mod range;
81mod schema;
82mod select;
83mod source_map;
84mod text;
85mod text_diff;
86mod transform;
87
88pub use block::{BlockError, BlockRange};
89pub use builder::doc;
90pub use change_ops::{compact, compose, map_path, rebase_change, unmap_path};
91pub use content::{ContentExpr, ContentRule, ParseExprError};
92pub use diff::{apply, diff, invert, ApplyError, Change};
93pub use document::Document;
94pub use error::{ParseError, Result};
95pub use html::{to_html, HtmlOptions, SelfClosingStyle, UnknownMarkPolicy, UnknownNodePolicy};
96pub use node::{Mark, Node};
97pub use normalize::NormalizeOptions;
98pub use pos::{LeafPolicy, PosError, PosRange, ResolvedPos, TextPoint};
99pub use pos_edit::{PosContent, PosEdit, PosEditError};
100pub use pos_map::{Assoc, PosMap};
101pub use query::Descendants;
102pub use query_lang::{Query, QueryError, QueryErrorKind};
103pub use range::{Position, Range, RangeError};
104pub use schema::{MarkSpec, NodeSpec, Schema, Violation, ViolationKind};
105pub use source_map::{SourceMap, SourceMapError};
106pub use text_diff::{diff_text, DiffGranularity, DiffOptions, SegKind, TextSegment};
107pub use transform::Transform;