1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
//! TTML2 / IMSC 1.1 timed-text subtitle parser.
//!
//! Parses W3C Timed Text Markup Language 2 (TTML2) documents and validates them
//! against IMSC 1.1 Text Profile and Image Profile constraints. Parse a document,
//! then validate it separately — the two passes are independent so callers can
//! inspect a non-conformant document before deciding whether to reject it.
//!
//! ## Round-trip guarantee
//!
//! Parsing, serializing, and re-parsing yields a semantically equal document
//! (`parse → serialize → re-parse → equal`). But the serialized XML is **not**
//! byte-identical to the input: comments, processing instructions, and XML
//! declarations are not stored; attribute order is deterministic but not
//! preserved; namespace prefixes are generated by the serializer;
//! `other_attributes` (custom attributes not explicitly modeled) are not
//! re-emitted; and foreign/unknown child elements (allowed by TTML2 §7.2)
//! are silently dropped during parsing, never re-emitted. See
//! [`README.md §Round-Trip Guarantee`] for the full verified list.
//!
//! ## From-scratch authoring
//!
//! All element types implement `Default`. Construct a document from nothing:
//!
//! ```
//! use ttml_subtitle::{Document, InlineContent};
//!
//! let mut doc = Document::default();
//! doc.tt.xml_lang = Some("en".into());
//!
//! let mut body = ttml_subtitle::BodyElement::default();
//! let mut div = ttml_subtitle::DivElement::default();
//! let mut p = ttml_subtitle::PElement::default();
//! p.begin = Some("0s".into());
//! p.end = Some("5s".into());
//! p.content.push(InlineContent::Text("Hello".into()));
//! div.paragraphs.push(p);
//! body.divs.push(div);
//! doc.tt.body = Some(body);
//!
//! let xml = doc.to_xml();
//! assert!(xml.contains("Hello"));
//! ```
//!
//! Spec citations:
//! - W3C TTML2 Recommendation (08 Nov 2018): `ttml2-syntax.md` in this crate's `docs/`.
//! - W3C IMSC 1.1 Recommendation (08 Nov 2018, edited 27 Apr 2020): `imsc11-profiles.md` in this crate's `docs/`.
//!
//! ```
//! use ttml_subtitle::Document;
//!
//! let xml = r#"<?xml version="1.0" encoding="UTF-8"?>
//! <tt xml:lang="en" xmlns="http://www.w3.org/ns/ttml"
//! xmlns:ttp="http://www.w3.org/ns/ttml#parameter"
//! ttp:contentProfiles="http://www.w3.org/ns/ttml/profile/imsc1.1/text">
//! <body><div><p begin="0s" end="5s">Hello</p></div></body>
//! </tt>"#;
//!
//! let doc = Document::parse_str(xml).unwrap();
//! let body = doc.tt.body.as_ref().unwrap();
//! assert_eq!(body.divs[0].paragraphs[0].begin.as_deref(), Some("0s"));
//! ```
extern crate alloc;
pub use ;
pub use ;
pub use TimeExpression;
pub use ;
/// Parse a TTML document from a string.
///
/// This is a convenience wrapper around [`Document::parse_str`].