Class: Rouge::Guessers::Modeline

Inherits:
Rouge::Guesser show all
Includes:
Util
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 included from Util

#get_source, #test_glob

Methods inherited from Rouge::Guesser

#collect_best, guess

Constructor Details

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

Returns a new instance of Modeline.



21
22
23
24
# File 'lib/rouge/guessers/modeline.rb', line 21

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

Instance Method Details

#filter(lexers) ⇒ Object



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

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

  source_text = get_source(@source)

  lines = source_text.split(/\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