highlight: Fix HTML rendering of empty lines
This commit is contained in:
parent
92e9f984ed
commit
14b7af3436
2 changed files with 51 additions and 15 deletions
|
|
@ -122,6 +122,37 @@ fn test_highlighting_multiline_scopes_to_html() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_highlighting_empty_lines() {
|
||||
let source = vec![
|
||||
"class A {",
|
||||
"",
|
||||
" b(c) {",
|
||||
"",
|
||||
" d(e)",
|
||||
"",
|
||||
" }",
|
||||
"",
|
||||
"}",
|
||||
]
|
||||
.join("\n");
|
||||
|
||||
assert_eq!(
|
||||
&to_html(&source, get_language("javascript"), &JS_SHEET,).unwrap(),
|
||||
&[
|
||||
"<span class=Keyword>class</span> <span class=Constructor>A</span> <span class=PunctuationBracket>{</span>\n".to_string(),
|
||||
"\n".to_string(),
|
||||
" <span class=Function>b</span><span class=PunctuationBracket>(</span><span class=Variable>c</span><span class=PunctuationBracket>)</span> <span class=PunctuationBracket>{</span>\n".to_string(),
|
||||
"\n".to_string(),
|
||||
" <span class=Function>d</span><span class=PunctuationBracket>(</span><span class=Variable>e</span><span class=PunctuationBracket>)</span>\n".to_string(),
|
||||
"\n".to_string(),
|
||||
" <span class=PunctuationBracket>}</span>\n".to_string(),
|
||||
"\n".to_string(),
|
||||
"<span class=PunctuationBracket>}</span>\n".to_string(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
fn test_language_for_injection_string<'a>(
|
||||
string: &str,
|
||||
) -> Option<(Language, &'a PropertySheet<Properties>)> {
|
||||
|
|
|
|||
|
|
@ -781,17 +781,19 @@ where
|
|||
renderer.end_scope();
|
||||
}
|
||||
HighlightEvent::Source(src) => {
|
||||
renderer.render_line(src, &scopes);
|
||||
renderer.add_text(src, &scopes);
|
||||
}
|
||||
};
|
||||
}
|
||||
renderer.flush();
|
||||
if !renderer.current_line.is_empty() {
|
||||
renderer.finish_line();
|
||||
}
|
||||
Ok(renderer.result)
|
||||
}
|
||||
|
||||
struct HtmlRenderer<'a, F: Fn(Scope) -> &'a str> {
|
||||
result: Vec<String>,
|
||||
buffer: String,
|
||||
current_line: String,
|
||||
attribute_callback: F,
|
||||
}
|
||||
|
||||
|
|
@ -802,37 +804,40 @@ where
|
|||
fn new(attribute_callback: F) -> Self {
|
||||
HtmlRenderer {
|
||||
result: Vec::new(),
|
||||
buffer: String::new(),
|
||||
current_line: String::new(),
|
||||
attribute_callback,
|
||||
}
|
||||
}
|
||||
|
||||
fn start_scope(&mut self, s: Scope) {
|
||||
write!(&mut self.buffer, "<span {}>", (self.attribute_callback)(s),).unwrap();
|
||||
write!(
|
||||
&mut self.current_line,
|
||||
"<span {}>",
|
||||
(self.attribute_callback)(s),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn end_scope(&mut self) {
|
||||
write!(&mut self.buffer, "</span>").unwrap();
|
||||
write!(&mut self.current_line, "</span>").unwrap();
|
||||
}
|
||||
|
||||
fn flush(&mut self) {
|
||||
if !self.buffer.is_empty() {
|
||||
self.buffer.push('\n');
|
||||
self.result.push(self.buffer.clone());
|
||||
self.buffer.clear();
|
||||
}
|
||||
fn finish_line(&mut self) {
|
||||
self.current_line.push('\n');
|
||||
self.result.push(self.current_line.clone());
|
||||
self.current_line.clear();
|
||||
}
|
||||
|
||||
fn render_line(&mut self, src: &str, scopes: &Vec<Scope>) {
|
||||
fn add_text(&mut self, src: &str, scopes: &Vec<Scope>) {
|
||||
let mut multiline = false;
|
||||
for line in src.split('\n') {
|
||||
let line = line.trim_end_matches('\r');
|
||||
if multiline {
|
||||
scopes.iter().for_each(|_| self.end_scope());
|
||||
self.flush();
|
||||
self.finish_line();
|
||||
scopes.iter().for_each(|scope| self.start_scope(*scope));
|
||||
}
|
||||
write!(&mut self.buffer, "{}", escape::Escape(line)).unwrap();
|
||||
write!(&mut self.current_line, "{}", escape::Escape(line)).unwrap();
|
||||
multiline = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue