Class: Rouge::Guessers::Modeline

Inherits:
Rouge::Guesser show all
Defined in:
lib/rouge/guessers/modeline.rb

Constant Summary collapse

EMACS_MODELINE =
jneen

regexen stolen from linguist

/-\*-\s*(?:(?!mode)[\w-]+\s*:\s*(?:[\w+-]+)\s*;?\s*)*(?:mode\s*:)?\s*([\w+-]+)\s*(?:;\s*(?!mode)[\w-]+\s*:\s*[\w+-]+\s*)*;?\s*-\*-/i
VIM_MODELINE_1 =
/(?:vim|vi|ex):\s*(?:ft|filetype|syntax)=(\w+)\s?/i
VIM_MODELINE_2 =
/(?:vim|vi|Vim|ex):\s*se(?:t)?.*\s(?:ft|filetype|syntax)=(\w+)\s?.*:/i
MODELINES =
[EMACS_MODELINE, VIM_MODELINE_1, VIM_MODELINE_2]

Instance Method Summary collapse

Methods inherited from Rouge::Guesser

#collect_best, guess

Constructor Details

#initialize(source, opts = {}) ⇒ Modeline

Returns a new instance of Modeline.



19
20
21
22
# File 'lib/rouge/guessers/modeline.rb', line 19

def initialize(source, opts={})
  @source = source
  @lines = opts[:lines] || 5
end

Instance Method Details

#filter(lexers) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/rouge/guessers/modeline.rb', line 24

def filter(lexers)
  # don't bother reading the stream if we've already decided
  return lexers if lexers.size == 1

  source_text = @source
  source_text = source_text.read if source_text.respond_to? :read

  lines = source_text.split(/\r?\n/)

  search_space = (lines.first(@lines) + lines.last(@lines)).join("\n")

  matches = MODELINES.map { |re| re.match(search_space) }.compact
  return lexers unless matches.any?
  
  match_set = Set.new(matches.map { |m| m[1] })
  lexers.select { |l| match_set.include?(l.tag) || l.aliases.any? { |a| match_set.include?(a) } }
end