1#![deny(missing_docs)]
8
9use cursive_core::style;
10use cursive_core::utils::markup::{StyledIndexedSpan, StyledString};
11use cursive_core::utils::span::IndexedCow;
12
13use unicode_width::UnicodeWidthStr;
14
15pub fn translate_effects(font_style: syntect::highlighting::FontStyle) -> style::Effects {
17 let mut effects = style::Effects::empty();
18
19 for &(style, effect) in &[
20 (syntect::highlighting::FontStyle::BOLD, style::Effect::Bold),
21 (
22 syntect::highlighting::FontStyle::UNDERLINE,
23 style::Effect::Underline,
24 ),
25 (
26 syntect::highlighting::FontStyle::ITALIC,
27 style::Effect::Italic,
28 ),
29 ] {
30 if font_style.contains(style) {
31 effects.insert(effect);
32 }
33 }
34
35 effects
36}
37
38pub fn translate_color(color: syntect::highlighting::Color) -> style::Color {
40 style::Color::Rgb(color.r, color.g, color.b)
41}
42
43pub fn translate_style(style: syntect::highlighting::Style) -> style::Style {
45 let front = translate_color(style.foreground);
46 let back = translate_color(style.background);
47
48 style::Style {
49 color: (front, back).into(),
50 effects: translate_effects(style.font_style),
51 }
52}
53
54pub fn parse<S: Into<String>>(
56 input: S,
57 highlighter: &mut syntect::easy::HighlightLines,
58 syntax_set: &syntect::parsing::SyntaxSet,
59) -> Result<StyledString, syntect::Error> {
60 let input = input.into();
61 let mut spans = Vec::new();
62
63 for line in input.split_inclusive('\n') {
64 for (style, text) in highlighter.highlight_line(line, syntax_set)? {
65 spans.push(StyledIndexedSpan {
66 content: IndexedCow::from_str(text, &input),
67 attr: translate_style(style),
68 width: text.width(),
69 });
70 }
71 }
72
73 Ok(StyledString::with_spans(input, spans))
74}