aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA Farzat <a@farzat.xyz>2026-03-08 15:16:30 +0300
committerA Farzat <a@farzat.xyz>2026-03-08 16:16:39 +0300
commitb6a88532c1b8d8f011f0f80809d69e13e4057df6 (patch)
tree302b93672d98faea2c23fbe3b0dbc5b5c0811006
parent7c72d848131dbfcef47663bc6dd3e7c87225b7e4 (diff)
downloadoreilly-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.rs46
1 files changed, 45 insertions, 1 deletions
diff --git a/src/xml.rs b/src/xml.rs
index 7902aa6..277f12a 100644
--- a/src/xml.rs
+++ b/src/xml.rs
@@ -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,