highlight.rb 2.02 KB
Newer Older
1 2
module Gitlab
  class Highlight
http://jneen.net/'s avatar
http://jneen.net/ committed
3 4
    def self.highlight(blob_name, blob_content, repository: nil, plain: false)
      new(blob_name, blob_content, repository: repository).
5
        highlight(blob_content, continue: false, plain: plain)
6 7
    end

8 9 10 11
    def self.highlight_lines(repository, ref, file_name)
      blob = repository.blob_at(ref, file_name)
      return [] unless blob

12
      blob.load_all_data!(repository)
13
      highlight(file_name, blob.data, repository: repository).lines.map!(&:html_safe)
14 15
    end

16 17
    attr_reader :blob_name

18
    def initialize(blob_name, blob_content, repository: nil)
19
      @formatter = Rouge::Formatters::HTMLGitlab
20
      @repository = repository
21
      @blob_name = blob_name
22
      @blob_content = blob_content
23 24
    end

25
    def highlight(text, continue: true, plain: false)
26 27 28
      highlighted_text = highlight_text(text, continue: continue, plain: plain)
      highlighted_text = link_dependencies(text, highlighted_text) if blob_name
      highlighted_text
29 30
    end

31 32
    def lexer
      @lexer ||= custom_language || begin
33 34
        Rouge::Lexer.guess(filename: @blob_name, source: @blob_content).new
      rescue Rouge::Guesser::Ambiguous => e
35 36 37 38
        e.alternatives.sort_by(&:tag).first
      end
    end

39 40
    private

41
    def custom_language
42
      language_name = @repository && @repository.gitattribute(@blob_name, 'gitlab-language')
43

44
      return nil unless language_name
45

46
      Rouge::Lexer.find_fancy(language_name)
47
    end
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69

    def highlight_text(text, continue: true, plain: false)
      if plain
        highlight_plain(text)
      else
        highlight_rich(text, continue: continue)
      end
    end

    def highlight_plain(text)
      @formatter.format(Rouge::Lexers::PlainText.lex(text)).html_safe
    end

    def highlight_rich(text, continue: true)
      @formatter.format(lexer.lex(text, continue: continue), tag: lexer.tag).html_safe
    rescue
      highlight_plain(text)
    end

    def link_dependencies(text, highlighted_text)
      Gitlab::DependencyLinker.link(blob_name, text, highlighted_text)
    end
70 71
  end
end