use std::borrow::Cow;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum LinkMode {
#[default]
Protocol,
TextOnly,
}
pub trait StitchHandler: Send + Sync {
fn handle<'a>(&self, text: &'a str) -> Cow<'a, str>;
fn name(&self) -> &str;
fn priority(&self) -> i32 {
100
}
}
pub mod priority {
pub const SINGLE_TILDE: i32 = 0;
pub const COMPARISON_OPERATORS: i32 = 5;
pub const HTML_TAGS: i32 = 10;
pub const SETEXT_HEADINGS: i32 = 15;
pub const LINKS: i32 = 20;
pub const BOLD_ITALIC: i32 = 30;
pub const BOLD: i32 = 35;
pub const ITALIC_DOUBLE_UNDERSCORE: i32 = 40;
pub const ITALIC_SINGLE_ASTERISK: i32 = 41;
pub const ITALIC_SINGLE_UNDERSCORE: i32 = 42;
pub const INLINE_CODE: i32 = 50;
pub const STRIKETHROUGH: i32 = 60;
pub const KATEX: i32 = 70;
pub const INLINE_KATEX: i32 = 75;
pub const DEFAULT: i32 = 100;
}
pub struct StitchOptions {
pub bold: bool,
pub italic: bool,
pub bold_italic: bool,
pub inline_code: bool,
pub strikethrough: bool,
pub links: bool,
pub images: bool,
pub katex: bool,
pub inline_katex: bool,
pub setext_headings: bool,
pub html_tags: bool,
pub single_tilde: bool,
pub comparison_operators: bool,
pub link_mode: LinkMode,
pub handlers: Vec<Box<dyn StitchHandler>>,
}
impl std::fmt::Debug for StitchOptions {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("StitchOptions")
.field("bold", &self.bold)
.field("italic", &self.italic)
.field("bold_italic", &self.bold_italic)
.field("inline_code", &self.inline_code)
.field("strikethrough", &self.strikethrough)
.field("links", &self.links)
.field("images", &self.images)
.field("katex", &self.katex)
.field("inline_katex", &self.inline_katex)
.field("setext_headings", &self.setext_headings)
.field("html_tags", &self.html_tags)
.field("single_tilde", &self.single_tilde)
.field("comparison_operators", &self.comparison_operators)
.field("link_mode", &self.link_mode)
.field("handlers", &format!("[{} custom]", self.handlers.len()))
.finish()
}
}
impl Default for StitchOptions {
fn default() -> Self {
Self {
bold: true,
italic: true,
bold_italic: true,
inline_code: true,
strikethrough: true,
links: true,
images: true,
katex: true,
inline_katex: false,
setext_headings: true,
html_tags: true,
single_tilde: true,
comparison_operators: true,
link_mode: LinkMode::Protocol,
handlers: Vec::new(),
}
}
}
impl StitchOptions {
pub fn bold(mut self, enabled: bool) -> Self {
self.bold = enabled;
self
}
pub fn italic(mut self, enabled: bool) -> Self {
self.italic = enabled;
self
}
pub fn bold_italic(mut self, enabled: bool) -> Self {
self.bold_italic = enabled;
self
}
pub fn inline_code(mut self, enabled: bool) -> Self {
self.inline_code = enabled;
self
}
pub fn strikethrough(mut self, enabled: bool) -> Self {
self.strikethrough = enabled;
self
}
pub fn links(mut self, enabled: bool) -> Self {
self.links = enabled;
self
}
pub fn images(mut self, enabled: bool) -> Self {
self.images = enabled;
self
}
pub fn katex(mut self, enabled: bool) -> Self {
self.katex = enabled;
self
}
pub fn setext_headings(mut self, enabled: bool) -> Self {
self.setext_headings = enabled;
self
}
pub fn html_tags(mut self, enabled: bool) -> Self {
self.html_tags = enabled;
self
}
pub fn single_tilde(mut self, enabled: bool) -> Self {
self.single_tilde = enabled;
self
}
pub fn comparison_operators(mut self, enabled: bool) -> Self {
self.comparison_operators = enabled;
self
}
pub fn inline_katex(mut self, enabled: bool) -> Self {
self.inline_katex = enabled;
self
}
pub fn link_mode(mut self, mode: LinkMode) -> Self {
self.link_mode = mode;
self
}
pub fn handler(mut self, handler: Box<dyn StitchHandler>) -> Self {
self.handlers.push(handler);
self
}
}