diff --git a/.gitignore b/.gitignore index f916a17a..14d5f023 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,6 @@ Cargo.lock # VS Code .vscode/ + +# macOS +.DS_Store diff --git a/src/html.rs b/src/html.rs index 45a50914..01d2f13d 100644 --- a/src/html.rs +++ b/src/html.rs @@ -5,6 +5,7 @@ use crate::easy::{HighlightLines, HighlightFile}; use crate::highlighting::{Color, FontStyle, Style, Theme}; use crate::util::LinesWithEndings; use crate::escape::Escape; + use std::io::{self, BufRead}; use std::path::Path; @@ -40,7 +41,7 @@ pub struct ClassedHTMLGenerator<'a> { syntax_set: &'a SyntaxSet, open_spans: isize, parse_state: ParseState, - html: String + html: String, } impl<'a> ClassedHTMLGenerator<'a> { @@ -52,7 +53,7 @@ impl<'a> ClassedHTMLGenerator<'a> { syntax_set, open_spans, parse_state, - html + html, } } @@ -221,22 +222,36 @@ pub fn tokens_to_classed_spans(line: &str, let mut cur_index = 0; let mut stack = ScopeStack::new(); let mut span_delta = 0; + + // check and skip emty inner tags + let mut span_empty = false; + let mut span_start = 0; + for &(i, ref op) in ops { if i > cur_index { + span_empty = false; write!(s, "{}", Escape(&line[cur_index..i])).unwrap(); cur_index = i } stack.apply_with_hook(op, |basic_op, _| { match basic_op { BasicScopeStackOp::Push(scope) => { + span_start = s.len(); + span_empty = true; s.push_str(""); span_delta += 1; } BasicScopeStackOp::Pop => { - s.push_str(""); + if span_empty == false { + s.push_str(""); + } + else { + s.truncate(span_start); + } span_delta -= 1; + span_empty = false; } } }); @@ -451,4 +466,20 @@ mod tests { let html = html_generator.finalize(); assert_eq!(html, "x + y\n"); } -} \ No newline at end of file + + #[test] + fn test_classed_html_generator_no_empty_span() { + let code = "// Rust source +fn main() { + println!(\"Hello World!\"); +}"; + let syntax_set = SyntaxSet::load_defaults_newlines(); + let syntax = syntax_set.find_syntax_by_extension("rs").unwrap(); + let mut html_generator = ClassedHTMLGenerator::new(&syntax, &syntax_set); + for line in code.lines() { + html_generator.parse_html_for_line(&line); + } + let html = html_generator.finalize(); + assert_eq!(html, "// Rust source\nfn main() {\n println!("Hello World!");\n}\n"); + } +}