Class: SyntaxHighlighter

Inherits:
Object
  • Object
show all
Defined in:
lib/glimmer/libui/syntax_highlighter.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(language:, theme:) ⇒ SyntaxHighlighter

Returns a new instance of SyntaxHighlighter.



16
17
18
19
# File 'lib/glimmer/libui/syntax_highlighter.rb', line 16

def initialize(language:, theme:)
  @language = language
  @theme = theme
end

Instance Attribute Details

#languageObject (readonly)

Returns the value of attribute language.



14
15
16
# File 'lib/glimmer/libui/syntax_highlighter.rb', line 14

def language
  @language
end

#themeObject (readonly)

Returns the value of attribute theme.



14
15
16
# File 'lib/glimmer/libui/syntax_highlighter.rb', line 14

def theme
  @theme
end

Class Method Details

.languagesObject



3
4
5
6
# File 'lib/glimmer/libui/syntax_highlighter.rb', line 3

def languages
  require 'rouge'
  Rouge::Lexer.all.map {|lexer| lexer.tag}.sort
end

.lexersObject



8
9
10
11
# File 'lib/glimmer/libui/syntax_highlighter.rb', line 8

def lexers
  require 'rouge'
  Rouge::Lexer.all.sort_by(&:title)
end

Instance Method Details

#lexerObject



21
22
23
24
25
26
27
# File 'lib/glimmer/libui/syntax_highlighter.rb', line 21

def lexer
  require 'rouge'
  require 'glimmer-dsl-libui/ext/rouge/theme/glimmer'
  # TODO Try to use Rouge::Lexer.find_fancy('guess', code) in the future to guess the language or otherwise detect it from file extension
  @lexer ||= Rouge::Lexer.find_fancy(language)
  @lexer ||= Rouge::Lexer.find_fancy('ruby') # default to Ruby if no lexer is found
end

#syntax_highlighting(text) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/glimmer/libui/syntax_highlighter.rb', line 29

def syntax_highlighting(text)
  return [] if text.to_s.strip.empty?
  @syntax_highlighting ||= {} # TODO consider memoizing/remembering the last value only to avoid wasting memory
  unless @syntax_highlighting.keys.include?(text)
    lex = lexer.lex(text).to_a
    text_size = 0
    @syntax_highlighting[text] = lex.map do |pair|
      token_type = pair.first
      token_text = pair.last
      token_style = Rouge::Theme.find(theme).new.style_for(token_type)
      {token_type: token_type, token_text: token_text, token_style: token_style}
    end.each do |hash|
      hash[:token_index] = text_size # TODO do we really need this? Also, consider renaming to something like token_character_index to clarify it is not the index of the token itself yet its first character
      text_size += hash[:token_text].size
    end
  end
  @syntax_highlighting[text]
end