1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
use {
super::*,
crate::{
CompoundStyle,
ATTRIBUTES,
},
};
/// Read a Minimad CompoundStyle from a string.
///
/// May contain attributes and from 0 to 2 colors, the first encountered
/// one being the foreground.
///
/// Examples:
/// * `#ab00c1 strikeout`
/// * `"red yellow bold italic"`
/// * `""`
/// * `"gray(2) gray(20)"`
/// * `""`
pub fn parse_compound_style(s: &str) -> Result<CompoundStyle, ParseStyleTokenError> {
let tokens = parse_style_tokens(s)?;
Ok(tokens.as_slice().into())
}
impl From<&[StyleToken]> for CompoundStyle {
fn from(tokens: &[StyleToken]) -> Self {
let mut style = Self::default();
// first encountered color or None is considered as the foreground
// and the following one(s) as the background
let mut fg_set = false;
for token in tokens {
match token {
StyleToken::Color(c) => {
if fg_set {
style.set_bg(*c);
} else {
style.set_fg(*c);
fg_set = true;
}
}
StyleToken::None => {
if !fg_set {
fg_set = true;
}
}
StyleToken::Attribute(attribute) => {
style.add_attr(*attribute);
}
StyleToken::Char(_) => {
// not of use for compound styles
}
StyleToken::Align(_) => {
// not of use for compound styles
}
StyleToken::Dimension(_) => {
// not of use for compound styles
}
}
}
style
}
}
impl PushStyleTokens for CompoundStyle {
fn push_style_tokens(&self, tokens: &mut Vec<StyleToken>) {
if let Some(fg) = self.get_fg() {
tokens.push(StyleToken::Color(fg));
} else if self.get_bg().is_some() {
tokens.push(StyleToken::None);
}
if let Some(bg) = self.get_bg() {
tokens.push(StyleToken::Color(bg));
}
for &attr in ATTRIBUTES {
if self.has_attr(attr) {
tokens.push(StyleToken::Attribute(attr));
}
}
}
}