use std::io::{self, Seek, Write};
use crate::markdown::{build_heading_slugs, render_chapter};
use crate::model::Book;
use super::Exporter;
#[derive(Debug, Clone, Default)]
pub struct MarkdownConfig {
pub line_width: usize,
}
#[derive(Debug, Clone, Default)]
pub struct MarkdownExporter {
config: MarkdownConfig,
}
impl MarkdownExporter {
pub fn new() -> Self {
Self::default()
}
pub fn with_config(config: MarkdownConfig) -> Self {
Self { config }
}
}
impl Exporter for MarkdownExporter {
fn export<W: Write + Seek>(&self, book: &mut Book, writer: &mut W) -> io::Result<()> {
let _ = self.config;
let resolved = book.resolve_links()?;
let spine: Vec<_> = book.spine().to_vec();
let chapters: Vec<_> = spine
.iter()
.map(|e| Ok((e.id, book.load_chapter_cached(e.id)?)))
.collect::<io::Result<Vec<_>>>()?;
let heading_slugs = build_heading_slugs(&chapters, &resolved);
let mut first = true;
for (chapter_id, chapter) in &chapters {
if !first {
writeln!(writer)?;
writeln!(writer, "---")?;
writeln!(writer)?;
}
first = false;
let result = render_chapter(chapter, *chapter_id, &resolved, &heading_slugs);
write!(writer, "{}", result.content)?;
if !result.footnotes.is_empty() {
writeln!(writer)?;
for note in &result.footnotes {
writeln!(writer, "[^{}]: {}", note.number, note.content)?;
}
}
}
Ok(())
}
}