Commit ca82a46a authored by Mark Chao's avatar Mark Chao

Make Highlight accept language param

This replaces the repository param.
This allows more flexiblity as sometimes we have highlight content
not related to repository. Sometimes we know ahead of time the language
of the content. Lastly language determination seems better fit as a
logic in the Blob class.
`repository` param is only used to determine the language, which seems
to be the responsiblity of Blob.
parent 8fa377b0
...@@ -63,7 +63,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController ...@@ -63,7 +63,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
format.html do format.html do
usage_data_json = JSON.pretty_generate(Gitlab::UsageData.data) usage_data_json = JSON.pretty_generate(Gitlab::UsageData.data)
render html: Gitlab::Highlight.highlight('payload.json', usage_data_json) render html: Gitlab::Highlight.highlight('payload.json', usage_data_json, language: 'json')
end end
format.json { render json: Gitlab::UsageData.to_json } format.json { render json: Gitlab::UsageData.to_json }
end end
......
...@@ -92,7 +92,7 @@ class Projects::BlobController < Projects::ApplicationController ...@@ -92,7 +92,7 @@ class Projects::BlobController < Projects::ApplicationController
apply_diff_view_cookie! apply_diff_view_cookie!
@blob.load_all_data! @blob.load_all_data!
@lines = Gitlab::Highlight.highlight(@blob.path, @blob.data, repository: @repository).lines @lines = @blob.present.highlight.lines
@form = UnfoldForm.new(params) @form = UnfoldForm.new(params)
......
# frozen_string_literal: true # frozen_string_literal: true
module BlobHelper module BlobHelper
def highlight(blob_name, blob_content, repository: nil, plain: false) def highlight(file_name, file_content, language: nil, plain: false)
plain ||= blob_content.length > Blob::MAXIMUM_TEXT_HIGHLIGHT_SIZE plain ||= file_content.length > Blob::MAXIMUM_TEXT_HIGHLIGHT_SIZE
highlighted = Gitlab::Highlight.highlight(blob_name, blob_content, plain: plain, repository: repository) highlighted = Gitlab::Highlight.highlight(file_name, file_content, plain: plain, language: language)
raw %(<pre class="code highlight"><code>#{highlighted}</code></pre>) raw %(<pre class="code highlight"><code>#{highlighted}</code></pre>)
end end
......
...@@ -4,4 +4,6 @@ ...@@ -4,4 +4,6 @@
- blob.data.each_line.each_with_index do |_, index| - blob.data.each_line.each_with_index do |_, index|
%span.diff-line-num= index + 1 %span.diff-line-num= index + 1
.blob-content{ data: { blob_id: blob.id } } .blob-content{ data: { blob_id: blob.id } }
= highlight(blob.path, blob.data, repository: nil, plain: blob.no_highlighting?) %pre.code.highlight
%code
= blob.present.highlight
= render 'shared/file_highlight', blob: viewer.blob, repository: @repository = render 'shared/file_highlight', blob: viewer.blob
...@@ -15,14 +15,14 @@ ...@@ -15,14 +15,14 @@
.col-md-2.text-center .col-md-2.text-center
Markdown Markdown
.col-md-10.code.js-syntax-highlight .col-md-10.code.js-syntax-highlight
= highlight('.md', badge.to_markdown) = highlight('.md', badge.to_markdown, language: 'markdown')
.row .row
%hr %hr
.row .row
.col-md-2.text-center .col-md-2.text-center
HTML HTML
.col-md-10.code.js-syntax-highlight .col-md-10.code.js-syntax-highlight
= highlight('.html', badge.to_html) = highlight('.html', badge.to_html, language: 'html')
.row .row
%hr %hr
.row .row
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
.blob-content .blob-content
- snippet_chunks.each do |chunk| - snippet_chunks.each do |chunk|
- unless chunk[:data].empty? - unless chunk[:data].empty?
= highlight(snippet.file_name, chunk[:data], repository: nil, plain: snippet.blob.no_highlighting?) = highlight(snippet.file_name, chunk[:data], plain: snippet.blob.no_highlighting?)
- else - else
.file-content.code .file-content.code
.nothing-here-block Empty file .nothing-here-block Empty file
- repository = nil unless local_assigns.key?(:repository)
.file-content.code.js-syntax-highlight .file-content.code.js-syntax-highlight
.line-numbers .line-numbers
- if blob.data.present? - if blob.data.present?
...@@ -13,4 +11,6 @@ ...@@ -13,4 +11,6 @@
= link_icon = link_icon
= i = i
.blob-content{ data: { blob_id: blob.id } } .blob-content{ data: { blob_id: blob.id } }
= highlight(blob.path, blob.data, repository: repository, plain: blob.no_highlighting?) %pre.code.highlight
%code
= blob.present.highlight
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
%li %li
.code.js-syntax-highlight.sherlock-code .code.js-syntax-highlight.sherlock-code
:preserve :preserve
#{highlight("#{@query.id}.sql", @query.formatted_query)} #{highlight("#{@query.id}.sql", @query.formatted_query, language: 'sql')}
.card .card
.card-header .card-header
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
= t('sherlock.milliseconds') = t('sherlock.milliseconds')
%td %td
.code.js-syntax-highlight.sherlock-code .code.js-syntax-highlight.sherlock-code
= highlight("#{query.id}.sql", query.formatted_query) = highlight("#{query.id}.sql", query.formatted_query, language: 'sql')
%td %td
= link_to(t('sherlock.view'), = link_to(t('sherlock.view'),
sherlock_transaction_query_path(@transaction, query), sherlock_transaction_query_path(@transaction, query),
......
...@@ -43,8 +43,7 @@ module Gitlab ...@@ -43,8 +43,7 @@ module Gitlab
def highlighted_lines def highlighted_lines
@blob.load_all_data! @blob.load_all_data!
@highlighted_lines ||= @highlighted_lines ||= @blob.present.highlight.lines
Gitlab::Highlight.highlight(@blob.path, @blob.data, repository: repository).lines
end end
def project def project
......
...@@ -3,6 +3,7 @@ module Gitlab ...@@ -3,6 +3,7 @@ module Gitlab
class File class File
include Gitlab::Routing include Gitlab::Routing
include IconsHelper include IconsHelper
include Gitlab::Utils::StrongMemoize
CONTEXT_LINES = 3 CONTEXT_LINES = 3
...@@ -30,11 +31,8 @@ module Gitlab ...@@ -30,11 +31,8 @@ module Gitlab
end end
def highlight_lines! def highlight_lines!
their_file = lines.reject { |line| line.type == 'new' }.map(&:text).join("\n") their_highlight = Gitlab::Highlight.highlight(their_path, their_lines, language: their_language).lines
our_file = lines.reject { |line| line.type == 'old' }.map(&:text).join("\n") our_highlight = Gitlab::Highlight.highlight(our_path, our_lines, language: our_language).lines
their_highlight = Gitlab::Highlight.highlight(their_path, their_file, repository: repository).lines
our_highlight = Gitlab::Highlight.highlight(our_path, our_file, repository: repository).lines
lines.each do |line| lines.each do |line|
line.rich_text = line.rich_text =
...@@ -182,6 +180,34 @@ module Gitlab ...@@ -182,6 +180,34 @@ module Gitlab
raw_line[:line_new], parent_file: self) raw_line[:line_new], parent_file: self)
end end
end end
def their_language
strong_memoize(:their_language) do
repository.gitattribute(their_path, 'gitlab-language')
end
end
def our_language
strong_memoize(:our_language) do
if our_path == their_path
their_language
else
repository.gitattribute(our_path, 'gitlab-language')
end
end
end
def their_lines
strong_memoize(:their_lines) do
lines.reject { |line| line.type == 'new' }.map(&:text).join("\n")
end
end
def our_lines
strong_memoize(:our_lines) do
lines.reject { |line| line.type == 'old' }.map(&:text).join("\n")
end
end
end end
end end
end end
...@@ -79,7 +79,7 @@ module Gitlab ...@@ -79,7 +79,7 @@ module Gitlab
return [] unless blob return [] unless blob
blob.load_all_data! blob.load_all_data!
Gitlab::Highlight.highlight(blob.path, blob.data, repository: repository).lines blob.present.highlight.lines
end end
end end
end end
......
...@@ -5,16 +5,16 @@ module Gitlab ...@@ -5,16 +5,16 @@ module Gitlab
TIMEOUT_BACKGROUND = 30.seconds TIMEOUT_BACKGROUND = 30.seconds
TIMEOUT_FOREGROUND = 3.seconds TIMEOUT_FOREGROUND = 3.seconds
def self.highlight(blob_name, blob_content, repository: nil, plain: false) def self.highlight(blob_name, blob_content, language: nil, plain: false)
new(blob_name, blob_content, repository: repository) new(blob_name, blob_content, language: language)
.highlight(blob_content, continue: false, plain: plain) .highlight(blob_content, continue: false, plain: plain)
end end
attr_reader :blob_name attr_reader :blob_name
def initialize(blob_name, blob_content, repository: nil) def initialize(blob_name, blob_content, language: nil)
@formatter = Rouge::Formatters::HTMLGitlab @formatter = Rouge::Formatters::HTMLGitlab
@repository = repository @language = language
@blob_name = blob_name @blob_name = blob_name
@blob_content = blob_content @blob_content = blob_content
end end
...@@ -36,11 +36,9 @@ module Gitlab ...@@ -36,11 +36,9 @@ module Gitlab
private private
def custom_language def custom_language
language_name = @repository && @repository.gitattribute(@blob_name, 'gitlab-language') return nil unless @language
return nil unless language_name Rouge::Lexer.find_fancy(@language)
Rouge::Lexer.find_fancy(language_name)
end end
def highlight_text(text, continue: true, plain: false) def highlight_text(text, continue: true, plain: false)
......
...@@ -5,36 +5,17 @@ describe Gitlab::Highlight do ...@@ -5,36 +5,17 @@ describe Gitlab::Highlight do
let(:project) { create(:project, :repository) } let(:project) { create(:project, :repository) }
let(:repository) { project.repository } let(:repository) { project.repository }
let(:commit) { project.commit(sample_commit.id) }
describe 'custom highlighting from .gitattributes' do
let(:branch) { 'gitattributes' }
let(:blob) { repository.blob_at_branch(branch, path) }
describe 'language provided' do
let(:highlighter) do let(:highlighter) do
described_class.new(blob.path, blob.data, repository: repository) described_class.new('foo.erb', 'bar', language: 'erb?parent=json')
end end
before do it 'sets correct lexer' do
project.change_head('gitattributes')
end
describe 'basic language selection' do
let(:path) { 'custom-highlighting/test.gitlab-custom' }
it 'highlights as ruby' do
expect(highlighter.lexer.tag).to eq 'ruby'
end
end
describe 'cgi options' do
let(:path) { 'custom-highlighting/test.gitlab-cgi' }
it 'highlights as json with erb' do
expect(highlighter.lexer.tag).to eq 'erb' expect(highlighter.lexer.tag).to eq 'erb'
expect(highlighter.lexer.parent.tag).to eq 'json' expect(highlighter.lexer.parent.tag).to eq 'json'
end end
end end
end
describe '#highlight' do describe '#highlight' do
describe 'with CRLF' do describe 'with CRLF' do
...@@ -42,7 +23,7 @@ describe Gitlab::Highlight do ...@@ -42,7 +23,7 @@ describe Gitlab::Highlight do
let(:path) { 'files/whitespace' } let(:path) { 'files/whitespace' }
let(:blob) { repository.blob_at_branch(branch, path) } let(:blob) { repository.blob_at_branch(branch, path) }
let(:lines) do let(:lines) do
described_class.highlight(blob.path, blob.data, repository: repository).lines described_class.highlight(blob.path, blob.data).lines
end end
it 'strips extra LFs' do it 'strips extra LFs' do
......
...@@ -29,6 +29,8 @@ describe 'projects/blob/_viewer.html.haml' do ...@@ -29,6 +29,8 @@ describe 'projects/blob/_viewer.html.haml' do
controller.params[:namespace_id] = project.namespace.to_param controller.params[:namespace_id] = project.namespace.to_param
controller.params[:project_id] = project.to_param controller.params[:project_id] = project.to_param
controller.params[:id] = File.join('master', blob.path) controller.params[:id] = File.join('master', blob.path)
allow(project.repository).to receive(:gitattribute).and_return(nil)
end end
def render_view def render_view
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment