mirror of
https://github.com/YGGverse/Yoda.git
synced 2025-01-15 17:20:08 +00:00
draft highlight tag implementation
This commit is contained in:
parent
ac1b896fc0
commit
70dfac115f
@ -69,14 +69,22 @@ impl Reader {
|
||||
// Is inline code
|
||||
if let Some(code) = Code::inline_from(line) {
|
||||
// Append value to buffer
|
||||
match syntax.highlight(&code.value, &tag.code.text_tag, None) {
|
||||
Ok(highlight) => {
|
||||
for (text_tag, entity) in highlight {
|
||||
buffer.insert_with_tags(&mut buffer.end_iter(), &entity, &[&text_tag]);
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
buffer.insert_with_tags(
|
||||
&mut buffer.end_iter(),
|
||||
&match syntax.auto_highlight(&code.value, None) {
|
||||
Ok(highlight) => highlight,
|
||||
Err(_) => code.value.to_string(), // @TODO handle
|
||||
},
|
||||
&code.value,
|
||||
&[&tag.code.text_tag],
|
||||
);
|
||||
} // @TODO handle
|
||||
}
|
||||
|
||||
// Append new line
|
||||
buffer.insert(&mut buffer.end_iter(), NEW_LINE);
|
||||
|
||||
// Skip other actions for this line
|
||||
@ -119,15 +127,25 @@ impl Reader {
|
||||
None => None,
|
||||
};
|
||||
|
||||
// Insert multiline code buffer into main buffer
|
||||
// Insert multiline code into main buffer
|
||||
match syntax.highlight(&this.value, &tag.code.text_tag, alt) {
|
||||
Ok(highlight) => {
|
||||
for (text_tag, entity) in highlight {
|
||||
buffer.insert_with_tags(
|
||||
&mut buffer.end_iter(),
|
||||
&match syntax.auto_highlight(&this.value, alt) {
|
||||
Ok(highlight) => highlight,
|
||||
Err(_) => this.value.to_string(), // @TODO handle
|
||||
},
|
||||
&entity,
|
||||
&[&text_tag],
|
||||
);
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
buffer.insert_with_tags(
|
||||
&mut buffer.end_iter(),
|
||||
&this.value,
|
||||
&[&tag.code.text_tag],
|
||||
);
|
||||
} // @TODO handle
|
||||
}
|
||||
|
||||
// Reset
|
||||
multiline = None;
|
||||
|
@ -1,8 +1,13 @@
|
||||
use gtk::{
|
||||
gdk::RGBA,
|
||||
pango::{Style, Underline},
|
||||
prelude::TextTagExt,
|
||||
TextTag,
|
||||
};
|
||||
use syntect::{
|
||||
easy::HighlightLines,
|
||||
highlighting::ThemeSet,
|
||||
highlighting::{Color, FontStyle, ThemeSet},
|
||||
parsing::{SyntaxReference, SyntaxSet},
|
||||
util::as_24_bit_terminal_escaped,
|
||||
Error,
|
||||
};
|
||||
|
||||
@ -21,28 +26,92 @@ impl Syntax {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn auto_highlight(&self, source: &str, alt: Option<&String>) -> Result<String, Error> {
|
||||
if let Some(name) = alt {
|
||||
if let Some(syntax_reference) = self.syntax_set.find_syntax_by_name(name) {
|
||||
return self.highlight(source, syntax_reference);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(syntax_reference) = self.syntax_set.find_syntax_by_first_line(source) {
|
||||
return self.highlight(source, syntax_reference);
|
||||
}
|
||||
|
||||
Ok(source.to_string())
|
||||
}
|
||||
|
||||
pub fn highlight(
|
||||
&self,
|
||||
source_code: &str,
|
||||
source_tag: &TextTag,
|
||||
alt: Option<&String>,
|
||||
) -> Result<Vec<(TextTag, String)>, Error> {
|
||||
if let Some(name) = alt {
|
||||
if let Some(reference) = self.syntax_set.find_syntax_by_extension(name) {
|
||||
return self.syntect_buffer(source_code, source_tag, reference);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(reference) = self.syntax_set.find_syntax_by_first_line(source_code) {
|
||||
return self.syntect_buffer(source_code, source_tag, reference);
|
||||
}
|
||||
|
||||
Ok(self.default_buffer(source_code, source_tag))
|
||||
}
|
||||
|
||||
fn default_buffer(&self, source: &str, source_tag: &TextTag) -> Vec<(TextTag, String)> {
|
||||
// Init new line buffer
|
||||
let mut buffer = Vec::new();
|
||||
|
||||
// Create new tag from source preset
|
||||
let mut tag = TextTag::new(None);
|
||||
tag.clone_from(source_tag);
|
||||
|
||||
// Append
|
||||
buffer.push((tag, source.to_string()));
|
||||
buffer
|
||||
}
|
||||
|
||||
fn syntect_buffer(
|
||||
&self,
|
||||
source: &str,
|
||||
source_tag: &TextTag,
|
||||
syntax_reference: &SyntaxReference,
|
||||
) -> Result<String, Error> {
|
||||
) -> Result<Vec<(TextTag, String)>, Error> {
|
||||
// Init new line buffer
|
||||
let mut buffer = Vec::new();
|
||||
|
||||
// Apply syntect decorator
|
||||
let ranges = HighlightLines::new(syntax_reference, &self.theme_set.themes[DEFAULT_THEME])
|
||||
.highlight_line(&source, &self.syntax_set)?;
|
||||
|
||||
Ok(as_24_bit_terminal_escaped(&ranges[..], true))
|
||||
// Build tags
|
||||
for (style, entity) in ranges {
|
||||
// Create new tag from source preset
|
||||
let mut tag = TextTag::new(None);
|
||||
tag.clone_from(source_tag);
|
||||
|
||||
// Tuneup using syntect conversion
|
||||
tag.set_background_rgba(Some(&color_to_rgba(style.background)));
|
||||
tag.set_foreground_rgba(Some(&color_to_rgba(style.foreground)));
|
||||
tag.set_style(font_style_to_style(style.font_style));
|
||||
tag.set_underline(font_style_to_underline(style.font_style));
|
||||
|
||||
// Append
|
||||
buffer.push((tag, entity.to_string()));
|
||||
}
|
||||
|
||||
Ok(buffer)
|
||||
}
|
||||
}
|
||||
|
||||
// Tools
|
||||
|
||||
fn color_to_rgba(color: Color) -> RGBA {
|
||||
RGBA::new(
|
||||
color.r.into(),
|
||||
color.g.into(),
|
||||
color.b.into(),
|
||||
color.a.into(),
|
||||
)
|
||||
}
|
||||
|
||||
fn font_style_to_style(font_style: FontStyle) -> Style {
|
||||
match font_style {
|
||||
FontStyle::ITALIC => Style::Italic,
|
||||
_ => Style::Normal,
|
||||
}
|
||||
}
|
||||
|
||||
fn font_style_to_underline(font_style: FontStyle) -> Underline {
|
||||
match font_style {
|
||||
FontStyle::UNDERLINE => Underline::Single,
|
||||
_ => Underline::None,
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user