mod assets;
pub mod docx;
mod file;
mod heading;
mod lang;
pub mod markdown;
pub mod scrub;
mod vocab;
pub use assets::{MAX_IMAGE_BYTES, unique_id};
pub use file::{ReadError, read_image, read_manuscript};
use serde::Serialize;
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct ImportWarning {
pub kind: WarningKind,
pub location: usize,
#[serde(skip_serializing_if = "Option::is_none")]
pub section: Option<usize>,
pub message: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub detail: Option<WarningDetail>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
#[serde(tag = "kind", rename_all = "kebab-case")]
pub enum WarningDetail {
Image {
#[serde(skip_serializing_if = "Option::is_none")]
name: Option<String>,
},
Footnote { label: String },
FrontMatterKey { key: String },
Fence { name: String },
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)]
#[serde(rename_all = "kebab-case")]
pub enum WarningKind {
NoTitle,
NoChapters,
TextBeforeFirstChapter,
TitlePageReplaced,
TableOfContentsRemoved,
TableFlattened,
TableSimplified,
TextBoxSkipped,
ImageUnsupported,
ImageMissing,
TrackedChangesAccepted,
LineBreaksJoined,
PageBreaksIgnored,
SceneBreaksFromBlankLines,
DamagedFile,
FootnoteMissing,
FootnoteUnused,
VerseNotClosed,
FrontMatterKeyIgnored,
ListFlattened,
EndMarkRemoved,
ImagePositionDropped,
}
pub(crate) fn attribution_text(line: &str) -> Option<&str> {
let text = line
.strip_prefix(['—', '―', '–', '-'])?
.trim_start_matches(['—', '―', '–', '-'])
.trim();
(!text.is_empty()).then_some(text)
}
pub(crate) fn is_dedication(text: &str) -> bool {
let l = text.to_lowercase();
vocab::DEDICATION_STARTS.iter().any(|p| l.starts_with(p))
}
pub use setzer_model::asset::Asset;
#[derive(Debug, Clone, PartialEq)]
pub struct Imported {
pub book: setzer_model::Book,
pub assets: Vec<Asset>,
pub warnings: Vec<ImportWarning>,
}
#[derive(Debug, thiserror::Error)]
pub enum ImportError {
#[error("the file is empty")]
Empty,
#[error("this is not a Word document (.docx): {0}")]
NotDocx(String),
}