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
#![deny(missing_docs)]
use cursive_core::theme;
use cursive_core::utils::markup::{StyledIndexedSpan, StyledString};
use cursive_core::utils::span::IndexedCow;
use cursive_core::reexports::enumset::EnumSet;
use unicode_width::UnicodeWidthStr;
pub fn translate_effects(
font_style: syntect::highlighting::FontStyle,
) -> EnumSet<theme::Effect> {
let mut effects = EnumSet::new();
for &(style, effect) in &[
(syntect::highlighting::FontStyle::BOLD, theme::Effect::Bold),
(
syntect::highlighting::FontStyle::UNDERLINE,
theme::Effect::Underline,
),
(
syntect::highlighting::FontStyle::ITALIC,
theme::Effect::Italic,
),
] {
if font_style.contains(style) {
effects.insert(effect);
}
}
effects
}
pub fn translate_color(color: syntect::highlighting::Color) -> theme::Color {
theme::Color::Rgb(color.r, color.g, color.b)
}
pub fn translate_style(style: syntect::highlighting::Style) -> theme::Style {
let front = translate_color(style.foreground);
let back = translate_color(style.background);
theme::Style {
color: (front, back).into(),
effects: translate_effects(style.font_style),
}
}
pub fn parse<S: Into<String>>(
input: S,
highlighter: &mut syntect::easy::HighlightLines,
syntax_set: &syntect::parsing::SyntaxSet,
) -> Result<StyledString, syntect::Error> {
let input = input.into();
let mut spans = Vec::new();
for line in input.split_inclusive('\n') {
for (style, text) in highlighter.highlight_line(line, syntax_set)? {
spans.push(StyledIndexedSpan {
content: IndexedCow::from_str(text, &input),
attr: translate_style(style),
width: text.width(),
});
}
}
Ok(StyledString::with_spans(input, spans))
}