oxedyne/fe2o3/fe2o3_file/src/office/odf/mod.rs
3.7 KiB, 19 runs
created by r1870400018:22904, which is this file's identity for as long as the history lasts, whatever it is later renamed to
download · who wrote it · its history
| 1 | //! OpenDocument: `.odt`, `.ods` and `.odp`, which are one format wearing three media types. |
| 2 | //! |
| 3 | //! # Simpler than OOXML, and in one specific way |
| 4 | //! |
| 5 | //! There are no relationship parts. An OOXML package says what its parts are in |
| 6 | //! `[Content_Types].xml` and how they refer to one another in a `.rels` file beside each one; an |
| 7 | //! OpenDocument package has a single `META-INF/manifest.xml` listing every member, and the content |
| 8 | //! refers to things by path. That removes the whole class of bug where a body names an `r:id` that |
| 9 | //! the relationships part does not declare. |
| 10 | //! |
| 11 | //! It is also one `content.xml` rather than one part per sheet or per slide, which makes a large |
| 12 | //! spreadsheet a single large part -- the trade the other way. |
| 13 | //! |
| 14 | //! # `mimetype` is the one rule that must not be broken |
| 15 | //! |
| 16 | //! The first member of the archive must be named `mimetype`, must hold the media type as plain text, |
| 17 | //! and must be **stored uncompressed**. That is what lets a reader name the file from its opening |
| 18 | //! bytes, which is what [`oxedyne_fe2o3_stds::media`] now does. A package that writes it anywhere |
| 19 | //! else, or deflates it, is a file every reader calls a ZIP. |
| 20 | //! |
| 21 | //! [`Zip::set_first`](crate::zip::Zip::set_first) exists for this and is used by all three writers |
| 22 | //! here. It is not a detail that can be left to whoever writes the next one. |
| 23 | //! |
| 24 | //! # The vocabulary is flat where OOXML's is nested |
| 25 | //! |
| 26 | //! A paragraph is `<text:p>` and a heading is `<text:h text:outline-level="2">` -- the level is an |
| 27 | //! attribute rather than a style name, so nothing has to resolve a style to know a heading is one. |
| 28 | //! That is the reverse of WordprocessingML and it is the easier direction. |
| 29 | //! |
| 30 | //! [Written with AI entirely](https://need2know.ai/entirely-ai/code)\ |
| 31 | //! Anthropic Claude |
| 32 | |
| 33 | pub mod pkg; |
| 34 | pub mod sheet; |
| 35 | pub mod slides; |
| 36 | pub mod text; |
| 37 | |
| 38 | //// The namespace URIs, each fixed by the OpenDocument specification. |
| 39 | // |
| 40 | // A prefix does not always name its own URI: `fo:` is XSL formatting objects, `draw:` is drawing, |
| 41 | // `svg:` is OpenDocument's compatible form of somebody else's, and `xlink:` is W3C's own. |
| 42 | pub const NS_OFFICE: &str = "urn:oasis:names:tc:opendocument:xmlns:office:1.0"; |
| 43 | pub const NS_TEXT: &str = "urn:oasis:names:tc:opendocument:xmlns:text:1.0"; |
| 44 | pub const NS_TABLE: &str = "urn:oasis:names:tc:opendocument:xmlns:table:1.0"; |
| 45 | pub const NS_STYLE: &str = "urn:oasis:names:tc:opendocument:xmlns:style:1.0"; |
| 46 | pub const NS_FO: &str = "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"; |
| 47 | pub const NS_DRAW: &str = "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"; |
| 48 | pub const NS_PRES: &str = "urn:oasis:names:tc:opendocument:xmlns:presentation:1.0"; |
| 49 | pub const NS_SVG: &str = "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"; |
| 50 | pub const NS_XLINK: &str = "http://www.w3.org/1999/xlink"; |
| 51 | pub const NS_MANIFEST: &str = "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"; |
| 52 | |
| 53 | /// The `of:` namespace, which is what a formula's `of:=` prefix refers to. |
| 54 | /// |
| 55 | /// **A `.ods` that writes `table:formula="of:=..."` without binding this is a spreadsheet whose every |
| 56 | /// formula fails.** LibreOffice does not ignore the unbound prefix -- it fails to parse the formula, |
| 57 | /// RECALCULATES the cell, and writes `Err:510` over the value that was stored there. So the missing |
| 58 | /// declaration does not merely lose the formula; it destroys the number beside it, which is the one |
| 59 | /// thing this crate promises not to do. |
| 60 | /// |
| 61 | /// The URI is `...xmlns:of:1.2` and not `...formula:1.0`, which is the plausible guess and is wrong. |
| 62 | pub const NS_OF: &str = "urn:oasis:names:tc:opendocument:xmlns:of:1.2"; |
| 63 | |
| 64 | // The `number:` namespace, which carries a data style -- what makes a number a date. |
| 65 | pub const NS_NUMBER: &str = "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"; |