diff options
| author | A Farzat <a@farzat.xyz> | 2026-03-08 15:16:30 +0300 |
|---|---|---|
| committer | A Farzat <a@farzat.xyz> | 2026-03-08 16:16:39 +0300 |
| commit | b6a88532c1b8d8f011f0f80809d69e13e4057df6 (patch) | |
| tree | 302b93672d98faea2c23fbe3b0dbc5b5c0811006 | |
| parent | 7c72d848131dbfcef47663bc6dd3e7c87225b7e4 (diff) | |
| download | oreilly-epub-b6a88532c1b8d8f011f0f80809d69e13e4057df6.tar.gz oreilly-epub-b6a88532c1b8d8f011f0f80809d69e13e4057df6.zip | |
Create a function to modify OPF contents
The main purpose for now is to add the description.
| -rw-r--r-- | src/xml.rs | 46 |
1 files changed, 45 insertions, 1 deletions
@@ -1,6 +1,6 @@ use anyhow::{Context, Result}; use ogrim::{Document, xml}; -use quick_xml::events::{BytesStart, Event}; +use quick_xml::events::{BytesEnd, BytesStart, BytesText, Event}; use quick_xml::{Reader, Writer}; use relative_path::{RelativePath, RelativePathBuf}; use std::collections::HashMap; @@ -116,6 +116,50 @@ pub fn build_epub_chapter<R: BufRead, W: Write>( Ok(()) } +/// Processes the fragment and outputs a complete, EPUB-ready XHTML document. +pub fn write_modified_opf<R: BufRead, W: Write>( + opf_input: R, + mut out: &mut W, + description: &str, +) -> Result<()> { + // Setup the XML Reader and Writer. + let mut reader = Reader::from_reader(opf_input); + // Preserve spacing for easier diffs. + reader.config_mut().trim_text(false); + let mut writer = Writer::new(&mut out); + + // Loop through the XML events and check tags. + let mut buffer = Vec::new(); + let mut desc_found = false; + loop { + match reader.read_event_into(&mut buffer) { + Ok(Event::Start(tag_data)) => { + // Simply record if dc:description found. + if tag_data.name().as_ref() == b"dc:description" { + desc_found = true; + } + // Then pass through unmodified. + writer.write_event(Event::Start(tag_data))?; + } + Ok(Event::End(tag_data)) => { + // Write description if end of metadata is reached without finding one. + if tag_data.name().as_ref() == b"metadata" && !desc_found { + writer.write_event(Event::Start(BytesStart::new("dc:description")))?; + writer.write_event(Event::Text(BytesText::new(description)))?; + writer.write_event(Event::End(BytesEnd::new("dc:description")))?; + } + // Pass through unmodified. + writer.write_event(Event::End(tag_data))?; + } + Ok(Event::Eof) => break, + Ok(tag_data) => writer.write_event(tag_data)?, // Pass through text, comments, etc. unmodified. + Err(e) => anyhow::bail!(e), + } + } + + Ok(()) +} + /// Helper function add link elements for stylesheets to an xml Document. fn make_stylesheet_links( doc: &mut Document, |
