ass_editor/lib.rs
1//! High-performance, ergonomic editor layer for ASS subtitles
2//!
3//! `ass-editor` provides an interactive editing interface built on top of `ass-core`,
4//! featuring zero-copy efficiency, incremental updates, and multi-document support.
5//! Designed for building subtitle editors, conversion tools, and automation scripts.
6//!
7//! # Key Features
8//!
9//! ## ๐ Interactive Editing
10//! - **Undo/redo**: Full history management with configurable depth
11//! - **Multi-document sessions**: Manage multiple files with shared resources
12//! - **Incremental parsing**: <1ms edits, <5ms re-parses via ass-core's streaming parser
13//! - **Fluent APIs**: Ergonomic builders and method chaining for all operations
14//!
15//! ## โก High Performance
16//! - **Zero-copy editing**: Direct manipulation of ass-core's zero-copy spans
17//! - **Memory efficient**: ~1.2x input size including undo history with arena pooling
18//! - **SIMD acceleration**: Optional SIMD features for parsing performance
19//! - **Thread-safe**: Optional multi-threading support with Arc/Mutex
20//!
21//! ## ๐ Advanced Features
22//! - **Search indexing**: FST-based trie indexing for fast regex queries across large scripts
23//! - **Plugin system**: Extensible architecture with syntax highlighting and auto-completion
24//! - **Format support**: Import/export SRT, WebVTT with configurable conversion options
25//! - **Karaoke support**: Generate, split, adjust, and apply karaoke timing with syllable detection
26//!
27//! # Quick Start
28//!
29//! ```
30//! use ass_editor::{EditorDocument, Position, Range};
31//!
32//! // Create a new document with ASS content
33//! let mut doc = EditorDocument::from_content(r#"
34//! [Script Info]
35//! Title: My Subtitle
36//!
37//! [V4+ Styles]
38//! Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
39//! Style: Default,Arial,20,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,0,0,0,100,100,0,0,1,2,0,2,10,10,10,1
40//!
41//! [Events]
42//! Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
43//! Dialogue: 0,0:00:00.00,0:00:05.00,Default,,0,0,0,,Hello World
44//! "#).unwrap();
45//!
46//! // Basic text editing with position-based operations
47//! let pos = Position::new(doc.text().len() - 11); // Before "Hello World"
48//! doc.insert(pos, "Welcome! ").unwrap();
49//!
50//! // Range-based operations
51//! let range = Range::new(Position::new(pos.offset), Position::new(pos.offset + 8));
52//! doc.replace(range, "Hi").unwrap();
53//!
54//! // Undo/redo support
55//! assert!(doc.can_undo());
56//! doc.undo().unwrap();
57//! assert!(doc.can_redo());
58//! doc.redo().unwrap();
59//!
60//! println!("Final text contains: {}", doc.text().contains("Hi World"));
61//! ```
62//!
63//! # Advanced Usage Examples
64//!
65//! ## Style Management
66//!
67//! ```
68//! # use ass_editor::{EditorDocument, StyleBuilder};
69//! let mut doc = EditorDocument::new();
70//!
71//! // Create styles with builder pattern
72//! let style = StyleBuilder::new()
73//! .font("Arial")
74//! .size(24)
75//! .color("&H00FFFFFF")
76//! .bold(true);
77//!
78//! // Apply styles to document
79//! doc.styles().create("Title", style).unwrap();
80//! ```
81//!
82//! ## Karaoke Timing
83//!
84//! ```
85//! # use ass_editor::{EditorDocument, Position, Range, commands::karaoke_commands::*};
86//! let mut doc = EditorDocument::from_content("Karaoke text here").unwrap();
87//! let range = Range::new(Position::new(0), Position::new(17));
88//!
89//! // Generate karaoke with automatic syllable detection
90//! doc.karaoke()
91//! .in_range(range)
92//! .generate(50) // 50 centiseconds per syllable
93//! .karaoke_type(KaraokeType::Fill)
94//! .execute()
95//! .unwrap();
96//!
97//! // Adjust timing
98//! doc.karaoke()
99//! .in_range(range)
100//! .adjust()
101//! .scale(1.5) // Make 50% longer
102//! .unwrap();
103//! ```
104//!
105//! ## Multi-Document Sessions
106//!
107//! ```
108//! # #[cfg(feature = "std")]
109//! # {
110//! # use ass_editor::{EditorSessionManager, SessionConfig};
111//! let mut manager = EditorSessionManager::new();
112//!
113//! manager.create_session("subtitle1.ass".to_string()).unwrap();
114//! manager.create_session("subtitle2.ass".to_string()).unwrap();
115//!
116//! // Switch between sessions with <100ยตs overhead
117//! manager.switch_session("subtitle1.ass").unwrap();
118//! // Edit session1...
119//!
120//! manager.switch_session("subtitle2.ass").unwrap();
121//! // Edit session2 with shared plugins and memory pools...
122//! # }
123//! ```
124//!
125//! # Feature Flags
126//!
127//! ass-editor uses a two-tier feature system for maximum flexibility:
128//!
129//! ## Main Flavors
130//! - **`default`**: Enables `full` for complete desktop functionality
131//! - **`minimal`**: Core editing features - no_std compatible with alloc
132//! - **`full`**: All features including std, analysis, plugins, formats, search, concurrency
133//!
134//! ## Optional Features
135//! - **`simd`**: SIMD acceleration for parsing performance
136//! - **`nostd`**: No-standard library support for embedded/WASM
137//! - **`dev-benches`**: Development benchmarking
138//!
139//! ## Usage Examples
140//!
141//! ```toml
142//! # Full-featured desktop editor (default)
143//! ass-editor = "0.1"
144//!
145//! # Minimal editor for lightweight integrations
146//! ass-editor = { version = "0.1", default-features = false, features = ["minimal"] }
147//!
148//! # Maximum performance with SIMD
149//! ass-editor = { version = "0.1", features = ["full", "simd"] }
150//!
151//! # WASM/embedded build
152//! ass-editor = { version = "0.1", default-features = false, features = ["minimal", "nostd"] }
153//! ```
154
155#![cfg_attr(not(feature = "std"), no_std)]
156#![cfg_attr(docsrs, feature(doc_cfg))]
157
158#[cfg(not(feature = "std"))]
159extern crate alloc;
160
161pub mod commands;
162pub mod core;
163pub mod events;
164pub mod extensions;
165pub mod utils;
166
167#[cfg(feature = "std")]
168pub mod sessions;
169
170#[cfg(feature = "std")]
171pub mod formats;
172
173// Re-export ass-core types as first-class citizens
174pub use ass_core::parser::ast::{Event, EventType, ScriptInfo, Section, SectionType, Span, Style};
175pub use ass_core::parser::Script;
176
177// Public API exports
178pub use commands::{
179 BatchCommand, CommandResult, DeleteTextCommand, DocumentCommandExt, EditorCommand,
180 InsertTextCommand, ReplaceTextCommand, TextCommand,
181};
182pub use core::{
183 DocumentPosition, EditorDocument, EditorError, EventAccessor, EventBuilder, EventInfo,
184 EventQuery, EventSortCriteria, EventSortOptions, HistoryEntry, HistoryStats, OwnedEvent,
185 Position, PositionBuilder, Range, Result, Selection, StyleBuilder, UndoManager, UndoStack,
186 UndoStackConfig,
187};
188// Re-export the fluent EventFilter directly
189pub use core::fluent::EventFilter;
190// Re-export the events EventFilter with a specific name to avoid conflict
191pub use events::{
192 DocumentEvent, EventChannel, EventChannelConfig, EventFilter as DocumentEventFilter,
193 EventHandler, EventStats,
194};
195pub use extensions::{
196 EditorContext, EditorExtension, ExtensionCapability, ExtensionCommand, ExtensionContext,
197 ExtensionInfo, ExtensionManager, ExtensionResult, ExtensionState, MessageLevel,
198};
199
200pub use utils::{
201 LazyValidator, ValidationIssue, ValidationResult, ValidationSeverity, ValidatorConfig,
202};
203
204#[cfg(feature = "std")]
205pub use sessions::{EditorSession, EditorSessionManager, SessionConfig, SessionStats};
206
207#[cfg(feature = "std")]
208pub use formats::{
209 Format, FormatExporter, FormatImporter, FormatInfo, FormatOptions, FormatRegistry, FormatResult,
210};