use std::cell::Cell;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Theme {
Gold,
Crimson,
Mono,
}
struct Palette {
initial: &'static str,
border: &'static str,
rubric: &'static str,
rubric_alt: &'static str,
gloss: &'static str,
}
const RESET: &str = "\x1b[0m";
impl Theme {
fn palette(self) -> Palette {
match self {
Theme::Gold => Palette {
initial: "\x1b[1;33m", border: "\x1b[33m", rubric: "\x1b[1;31m", rubric_alt: "\x1b[1;34m", gloss: "\x1b[2;36m", },
Theme::Crimson => Palette {
initial: "\x1b[1;31m",
border: "\x1b[31m",
rubric: "\x1b[1;33m",
rubric_alt: "\x1b[1;34m",
gloss: "\x1b[2;36m",
},
Theme::Mono => Palette {
initial: "",
border: "",
rubric: "",
rubric_alt: "",
gloss: "",
},
}
}
}
pub(crate) struct Style {
enabled: bool,
theme: Theme,
pilcrow_n: Cell<usize>,
}
impl Style {
pub(crate) fn new(enabled: bool, theme: Theme) -> Self {
Style {
enabled,
theme,
pilcrow_n: Cell::new(0),
}
}
fn paint(&self, code: &str, s: &str) -> String {
if self.enabled && !code.is_empty() {
format!("{code}{s}{RESET}")
} else {
s.to_string()
}
}
pub(crate) fn initial(&self, s: &str) -> String {
self.paint(self.theme.palette().initial, s)
}
pub(crate) fn border(&self, s: &str) -> String {
self.paint(self.theme.palette().border, s)
}
pub(crate) fn rubric(&self, s: &str) -> String {
self.paint(self.theme.palette().rubric, s)
}
pub(crate) fn gloss(&self, s: &str) -> String {
self.paint(self.theme.palette().gloss, s)
}
pub(crate) fn pilcrow(&self, s: &str) -> String {
let n = self.pilcrow_n.get();
self.pilcrow_n.set(n + 1);
let palette = self.theme.palette();
let code = if n % 2 == 0 {
palette.rubric
} else {
palette.rubric_alt
};
self.paint(code, s)
}
}