use regex::Regex;
use std::sync::LazyLock;
static DEFAULT_GLOBAL_ESCAPE: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r#"[\\`*_~\[\]]"#).expect("default global escape regex is valid"));
static DEFAULT_LINE_START_ESCAPE: LazyLock<Regex> = LazyLock::new(|| {
Regex::new(r#"(?m)^(\s*?)((?:\+\s)|(?:[=>-])|(?:#{1,6}\s))|(?:(\d+)(\.\s))"#)
.expect("default line-start escape regex is valid")
});
static DOCTYPE_REPLACEMENT: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r#"(?im)^<!DOCTYPE.*>"#).expect("doctype regex is valid"));
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum CodeBlockStyle {
Fenced,
Indented,
}
#[derive(Clone, Debug)]
pub struct Options {
pub code_fence: String,
pub bullet_marker: String,
pub indent: String,
pub code_block_style: CodeBlockStyle,
pub em_delimiter: String,
pub strong_delimiter: String,
pub strike_delimiter: String,
pub ignore: Vec<String>,
pub block_elements: Vec<String>,
pub max_consecutive_newlines: usize,
pub line_start_escape: (Regex, String),
pub global_escape: (Regex, String),
pub text_replace: Vec<(Regex, String)>,
pub keep_data_images: bool,
pub use_link_reference_definitions: bool,
pub use_inline_links: bool,
}
impl Default for Options {
#[inline]
fn default() -> Self {
Self {
code_fence: "```".to_owned(),
bullet_marker: "*".to_owned(),
indent: " ".to_owned(),
code_block_style: CodeBlockStyle::Fenced,
em_delimiter: "_".to_owned(),
strong_delimiter: "**".to_owned(),
strike_delimiter: "~~".to_owned(),
ignore: Vec::new(),
block_elements: Vec::new(),
max_consecutive_newlines: 3,
line_start_escape: (DEFAULT_LINE_START_ESCAPE.clone(), "$1$3\\$2$4".to_owned()),
global_escape: (DEFAULT_GLOBAL_ESCAPE.clone(), r#"\$0"#.to_owned()),
text_replace: Vec::new(),
keep_data_images: false,
use_link_reference_definitions: false,
use_inline_links: true,
}
}
}
impl Options {
pub(crate) fn add_default_text_replacements(&mut self) {
self.text_replace
.push((DOCTYPE_REPLACEMENT.clone(), String::new()));
}
}