Skip to content

Commit

Permalink
Refactor colorization code again (#17)
Browse files Browse the repository at this point in the history
  • Loading branch information
pemistahl committed Mar 15, 2021
1 parent 6f91d0c commit d496350
Show file tree
Hide file tree
Showing 6 changed files with 398 additions and 233 deletions.
106 changes: 43 additions & 63 deletions src/ast/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

use crate::ast::{Expression, Quantifier};
use crate::char::GraphemeCluster;
use crate::regexp::RegExpConfig;
use crate::regexp::{Component, RegExpConfig};
use itertools::Itertools;
use std::collections::BTreeSet;
use std::fmt::{Display, Formatter, Result};
Expand Down Expand Up @@ -52,33 +52,22 @@ fn format_alternation(
options: &[Expression],
config: &RegExpConfig,
) -> Result {
let left_parenthesis = if config.is_capturing_group_enabled() {
"("
} else {
"(?:"
};
let pipe = if config.is_output_colorized {
"\u{1b}[1;31m|\u{1b}[0m"
} else {
"|"
};
let alternation_str = options
.iter()
.map(|option| {
if option.precedence() < expr.precedence() && !option.is_single_codepoint() {
if config.is_output_colorized {
format!(
"\u{1b}[1;32m{}\u{1b}[0m{}\u{1b}[1;32m)\u{1b}[0m",
left_parenthesis, option
)
if config.is_capturing_group_enabled() {
Component::CapturedParenthesizedExpression(option.to_string())
.to_repr(config.is_output_colorized)
} else {
format!("{}{})", left_parenthesis, option)
Component::UncapturedParenthesizedExpression(option.to_string())
.to_repr(config.is_output_colorized)
}
} else {
format!("{}", option)
}
})
.join(pipe);
.join(&Component::Pipe.to_repr(config.is_output_colorized));

write!(f, "{}", alternation_str)
}
Expand Down Expand Up @@ -138,31 +127,22 @@ fn format_character_class(
char_class_strs.push((*c).to_string());
}
} else {
let frmt = if config.is_output_colorized {
format!(
"{}\u{1b}[1;36m-\u{1b}[0m{}",
subset.first().unwrap(),
subset.last().unwrap()
)
} else {
format!("{}-{}", subset.first().unwrap(), subset.last().unwrap())
};

char_class_strs.push(frmt);
char_class_strs.push(format!(
"{}{}{}",
subset.first().unwrap(),
Component::Hyphen.to_repr(config.is_output_colorized),
subset.last().unwrap()
));
}
}

let joined_classes = char_class_strs.join("");

if config.is_output_colorized {
write!(
f,
"\u{1b}[1;36m[\u{1b}[0m{}\u{1b}[1;36m]\u{1b}[0m",
joined_classes,
)
} else {
write!(f, "[{}]", joined_classes)
}
write!(
f,
"{}{}{}",
Component::LeftBracket.to_repr(config.is_output_colorized),
char_class_strs.join(""),
Component::RightBracket.to_repr(config.is_output_colorized)
)
}

fn format_concatenation(
Expand All @@ -172,22 +152,16 @@ fn format_concatenation(
expr2: &Expression,
config: &RegExpConfig,
) -> Result {
let left_parenthesis = if config.is_capturing_group_enabled() {
"("
} else {
"(?:"
};
let expr_strs = vec![expr1, expr2]
.iter()
.map(|&it| {
if it.precedence() < expr.precedence() && !it.is_single_codepoint() {
if config.is_output_colorized {
format!(
"\u{1b}[1;32m{}\u{1b}[0m{}\u{1b}[1;32m)\u{1b}[0m",
left_parenthesis, it
)
if config.is_capturing_group_enabled() {
Component::CapturedParenthesizedExpression(it.to_string())
.to_repr(config.is_output_colorized)
} else {
format!("{}{})", left_parenthesis, it)
Component::UncapturedParenthesizedExpression(it.to_string())
.to_repr(config.is_output_colorized)
}
} else {
format!("{}", it)
Expand Down Expand Up @@ -243,24 +217,30 @@ fn format_repetition(
quantifier: &Quantifier,
config: &RegExpConfig,
) -> Result {
let left_parenthesis = if config.is_capturing_group_enabled() {
"("
} else {
"(?:"
};
if expr1.precedence() < expr.precedence() && !expr1.is_single_codepoint() {
if config.is_output_colorized {
if config.is_capturing_group_enabled() {
write!(
f,
"\u{1b}[1;32m{}\u{1b}[0m{}\u{1b}[1;32m)\u{1b}[0m\u{1b}[1;35m{}\u{1b}[0m",
left_parenthesis, expr1, quantifier
"{}{}",
Component::CapturedParenthesizedExpression(expr1.to_string())
.to_repr(config.is_output_colorized),
Component::Quantifier(quantifier.clone()).to_repr(config.is_output_colorized)
)
} else {
write!(f, "{}{}){}", left_parenthesis, expr1, quantifier)
write!(
f,
"{}{}",
Component::UncapturedParenthesizedExpression(expr1.to_string())
.to_repr(config.is_output_colorized),
Component::Quantifier(quantifier.clone()).to_repr(config.is_output_colorized)
)
}
} else if config.is_output_colorized {
write!(f, "{}\u{1b}[1;35m{}\u{1b}[0m", expr1, quantifier)
} else {
write!(f, "{}{}", expr1, quantifier)
write!(
f,
"{}{}",
expr1,
Component::Quantifier(quantifier.clone()).to_repr(config.is_output_colorized)
)
}
}
95 changes: 45 additions & 50 deletions src/char/grapheme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@
* limitations under the License.
*/

use crate::regexp::RegExpConfig;
use crate::regexp::{Component, RegExpConfig};
use itertools::Itertools;
use std::fmt::{Display, Formatter, Result};

const CHARS_TO_ESCAPE: [&str; 14] = [
"(", ")", "[", "]", "{", "}", "+", "*", "-", ".", "?", "|", "^", "$",
];

const CHAR_CLASSES: [&str; 6] = ["\\d", "\\s", "\\w", "\\D", "\\S", "\\W"];

#[derive(Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
pub struct Grapheme {
pub(crate) chars: Vec<String>,
Expand Down Expand Up @@ -162,65 +164,58 @@ impl Display for Grapheme {
|| (self.chars.len() == 1 && self.chars[0].matches('\\').count() == 1);
let is_range = self.min < self.max;
let is_repetition = self.min > 1;
let value = if self.repetitions.is_empty() {
let mut value = if self.repetitions.is_empty() {
self.value()
} else {
self.repetitions.iter().map(|it| it.to_string()).join("")
};
let left_parenthesis = if self.config.is_capturing_group_enabled() {
"("
} else {
"(?:"
};
let char_classes = vec!["\\d", "\\s", "\\w", "\\D", "\\S", "\\W"];
let colored_value = if self.config.is_output_colorized && char_classes.contains(&&*value) {
format!("\u{1b}[103;30m{}\u{1b}[0m", value)
} else {
value
};
value = Component::CharClass(value.clone())
.to_repr(self.config.is_output_colorized && CHAR_CLASSES.contains(&&*value));

if !is_range && is_repetition && is_single_char {
if self.config.is_output_colorized {
write!(f, "{}\u{1b}[104;37m{{{}}}\u{1b}[0m", colored_value, self.min)
} else {
write!(f, "{}{{{}}}", colored_value, self.min)
}
write!(
f,
"{}{}",
value,
Component::Repetition(self.min).to_repr(self.config.is_output_colorized)
)
} else if !is_range && is_repetition && !is_single_char {
if self.config.is_output_colorized {
write!(
f,
"\u{1b}[1;32m{}\u{1b}[0m{}\u{1b}[1;32m)\u{1b}[0m\u{1b}[104;37m{{{}}}\u{1b}[0m",
left_parenthesis, colored_value, self.min
)
} else {
write!(f, "{}{}){{{}}}", left_parenthesis, colored_value, self.min)
}
write!(
f,
"{}{}",
if self.config.is_capturing_group_enabled() {
Component::CapturedParenthesizedExpression(value)
.to_repr(self.config.is_output_colorized)
} else {
Component::UncapturedParenthesizedExpression(value)
.to_repr(self.config.is_output_colorized)
},
Component::Repetition(self.min).to_repr(self.config.is_output_colorized)
)
} else if is_range && is_single_char {
if self.config.is_output_colorized {
write!(
f,
"{}\u{1b}[104;37m{{{},{}}}\u{1b}[0m",
colored_value, self.min, self.max
)
} else {
write!(f, "{}{{{},{}}}", colored_value, self.min, self.max)
}
write!(
f,
"{}{}",
value,
Component::RepetitionRange(self.min, self.max)
.to_repr(self.config.is_output_colorized)
)
} else if is_range && !is_single_char {
if self.config.is_output_colorized {
write!(
f,
"\u{1b}[1;32m{}\u{1b}[0m{}\u{1b}[1;32m)\u{1b}[0m\u{1b}[104;37m{{{},{}}}\u{1b}[0m",
left_parenthesis, colored_value, self.min, self.max
)
} else {
write!(
f,
"{}{}){{{},{}}}",
left_parenthesis, colored_value, self.min, self.max
)
}
write!(
f,
"{}{}",
if self.config.is_capturing_group_enabled() {
Component::CapturedParenthesizedExpression(value)
.to_repr(self.config.is_output_colorized)
} else {
Component::UncapturedParenthesizedExpression(value)
.to_repr(self.config.is_output_colorized)
},
Component::RepetitionRange(self.min, self.max)
.to_repr(self.config.is_output_colorized)
)
} else {
write!(f, "{}", colored_value)
write!(f, "{}", value)
}
}
}
Loading

0 comments on commit d496350

Please sign in to comment.