From 15d5dfdb33c94ccfd7843f2be35bac2d74abe03e Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sun, 9 Aug 2015 23:08:28 -0700 Subject: [PATCH] Fix diff syntax highlighting Refactored HTML parser to avoid duplication of newline parsing. Closes #2235 --- lib/rouge/formatters/html_gitlab.rb | 41 +++++++++++++++-------------- spec/helpers/blob_helper_spec.rb | 16 +++++++++++ spec/helpers/events_helper_spec.rb | 2 +- 3 files changed, 38 insertions(+), 21 deletions(-) diff --git a/lib/rouge/formatters/html_gitlab.rb b/lib/rouge/formatters/html_gitlab.rb index 3f92212243d..6762ca47c32 100644 --- a/lib/rouge/formatters/html_gitlab.rb +++ b/lib/rouge/formatters/html_gitlab.rb @@ -93,16 +93,27 @@ module Rouge end def process_tokens(tokens) - num_lines = 0 - last_val = '' - rendered = '' + rendered = [] + current_line = '' tokens.each do |tok, val| - last_val = val - num_lines += val.scan(/\n/).size - rendered << span(tok, val) + # In the case of multi-line values (e.g. comments), we need to apply + # styling to each line since span elements are inline. + val.lines.each do |line| + stripped = line.chomp + current_line << span(tok, stripped) + + if line.end_with?("\n") + rendered << current_line + current_line = '' + end + end end + # Add leftover text + rendered << current_line if current_line.present? + + num_lines = rendered.size numbers = (@linenostart..num_lines + @linenostart - 1).to_a { numbers: numbers, code: rendered } @@ -117,9 +128,8 @@ module Rouge numbers.join("\n") end - def wrap_lines(rendered) + def wrap_lines(lines) if @lineanchors - lines = rendered.split("\n") lines = lines.each_with_index.map do |line, index| number = index + @linenostart @@ -136,24 +146,17 @@ module Rouge lines.join("\n") else if @linenos == 'inline' - lines = rendered.split("\n") lines = lines.each_with_index.map do |line, index| number = index + @linenostart "#{number}#{line}" end lines.join("\n") else - rendered + lines.join("\n") end end end - def wrap_values(val, element) - lines = val.split("\n") - lines = lines.map{ |x| "#{x}" } - lines.join("\n") - end - def span(tok, val) # http://stackoverflow.com/a/1600584/2587286 val = CGI.escapeHTML(val) @@ -161,13 +164,11 @@ module Rouge if tok.shortname.empty? val else - # In the case of multi-line values (e.g. comments), we need to apply - # styling to each line since span elements are inline. if @inline_theme rules = @inline_theme.style_for(tok).rendered_rules - wrap_values(val, "style=\"#{rules.to_a.join(';')}\"") + "" else - wrap_values(val, "class=\"#{tok.shortname}\"") + "#{val}" end end end diff --git a/spec/helpers/blob_helper_spec.rb b/spec/helpers/blob_helper_spec.rb index 76009c36099..b8bba36439a 100644 --- a/spec/helpers/blob_helper_spec.rb +++ b/spec/helpers/blob_helper_spec.rb @@ -47,5 +47,21 @@ describe BlobHelper do expect(lines[1].text).to eq(' This is line 2.') expect(lines[2].text).to eq(' """') end + + context 'diff highlighting' do + let(:blob_name) { 'test.diff' } + let(:blob_content) { "+aaa\n+bbb\n- ccc\n ddd\n"} + let(:expected) do + %q(+aaa ++bbb +- ccc + ddd) + end + + it 'should highlight each line properly' do + result = highlight(blob_name, blob_content, nowrap: true, continue: false) + expect(result).to eq(expected) + end + end end end diff --git a/spec/helpers/events_helper_spec.rb b/spec/helpers/events_helper_spec.rb index b392371deb4..da58ab98462 100644 --- a/spec/helpers/events_helper_spec.rb +++ b/spec/helpers/events_helper_spec.rb @@ -58,7 +58,7 @@ describe EventsHelper do expected = '
' \
       "def test\n" \
       "  \'hello world\'\n" \
-      "end\n" \
+      "end" \
       '
' expect(event_note(input)).to eq(expected) end