|
1 | | -use std::{collections::HashMap, fs::File, io::BufReader}; |
| 1 | +use std::{collections::HashMap, fs, fs::File, io::BufReader}; |
2 | 2 |
|
3 | 3 | use anyhow::{Context, Result}; |
4 | 4 | use roxmltree::{Document as XmlDocument, Node, NodeType}; |
@@ -51,6 +51,38 @@ impl Parser for OdtParser { |
51 | 51 | } |
52 | 52 | } |
53 | 53 |
|
| 54 | +pub struct FodtParser; |
| 55 | + |
| 56 | +impl Parser for FodtParser { |
| 57 | + fn name(&self) -> &'static str { |
| 58 | + "Flat OpenDocument Text Files" |
| 59 | + } |
| 60 | + |
| 61 | + fn extensions(&self) -> &[&str] { |
| 62 | + &["fodt"] |
| 63 | + } |
| 64 | + |
| 65 | + fn supported_flags(&self) -> ParserFlags { |
| 66 | + ParserFlags::SUPPORTS_TOC |
| 67 | + } |
| 68 | + |
| 69 | + fn parse(&self, context: &ParserContext) -> Result<Document> { |
| 70 | + let content_str = fs::read_to_string(&context.file_path) |
| 71 | + .with_context(|| format!("Failed to open FODT file '{}'", context.file_path))?; |
| 72 | + let xml_doc = XmlDocument::parse(&content_str).context("Invalid FODT document")?; |
| 73 | + let mut buffer = DocumentBuffer::new(); |
| 74 | + let mut id_positions = HashMap::new(); |
| 75 | + traverse(xml_doc.root(), &mut buffer, &mut id_positions); |
| 76 | + let title = extract_title_from_path(&context.file_path); |
| 77 | + let toc_items = build_toc_from_buffer(&buffer); |
| 78 | + let mut document = Document::new().with_title(title); |
| 79 | + document.set_buffer(buffer); |
| 80 | + document.id_positions = id_positions; |
| 81 | + document.toc_items = toc_items; |
| 82 | + Ok(document) |
| 83 | + } |
| 84 | +} |
| 85 | + |
54 | 86 | fn traverse(node: Node, buffer: &mut DocumentBuffer, id_positions: &mut HashMap<String, usize>) { |
55 | 87 | if node.node_type() == NodeType::Element { |
56 | 88 | let tag_name = node.tag_name().name(); |
|
0 commit comments