This repository has been archived by the owner on May 12, 2018. It is now read-only.
forked from github-linguist/linguist
/
lexer.rb
167 lines (147 loc) · 4.03 KB
/
lexer.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
require 'pygments'
require 'yaml'
module Linguist
# Mirror of Pygments Lexer structure.
#
# name - Proper lexer name (JavaScript, Ruby, Python)
# aliases - Aliases for lookup (js, javascript)
# filenames - Filename globs (*.js)
# mimetypes - Mime types (application/javascript)
class Lexer < Struct.new(:name, :aliases, :filenames, :mimetypes)
@lexers = []
@index = {}
@name_index = {}
@alias_index = {}
@mimetypes_index = {}
# Internal: Create a new Lexer object
#
# name - Name of Lexer
# attrs - A hash of attributes
#
# Returns a Lexer object
def self.create(name, attrs)
name = name
aliases = attrs['aliases'] || []
filenames = attrs['filenames'] || []
mimetypes = attrs['mimetypes'] || []
@lexers << lexer = new(name, aliases, filenames, mimetypes)
# All Lexer names should be unique. Warn if there is a duplicate.
if @name_index.key?(lexer.name)
warn "Duplicate lexer name: #{lexer.name}"
end
@index[lexer.name] = @name_index[lexer.name] = lexer
lexer.aliases.each do |name|
# All Lexer aliases should be unique. Warn if there is a duplicate.
if @alias_index.key?(name)
warn "Duplicate alias: #{name}"
end
@index[name] = @alias_index[name] = lexer
end
lexer.mimetypes.each do |type|
# All Lexer mimetypes should be unique. Warn if there is a duplicate.
if @mimetypes_index.key?(name)
warn "Duplicate mimetype: #{name}"
end
@mimetypes_index[type] = lexer
end
end
# Public: Get all Lexers
#
# Returns an Array of Lexers
def self.all
@lexers
end
# Public: Look up Lexer by name or alias.
#
# name - A String name or alias
#
# Lexer['Ruby']
# => #<Lexer name="Ruby">
#
# Returns the Lexer or nil if none was found.
def self.[](name)
@index[name]
end
# Public: Look up Lexer by its proper name.
#
# name - The String name of the Lexer
#
# Examples
#
# Lexer.find_by_name('Ruby')
# # => #<Lexer name="Ruby">
#
# Returns the Lexer or nil if none was found.
def self.find_by_name(name)
@name_index[name]
end
# Public: Look up Lexer by one of its aliases.
#
# name - A String alias of the Lexer
#
# Examples
#
# Lexer.find_by_alias('rb')
# # => #<Lexer name="Ruby">
#
# Returns the Lexer or nil if none was found.
def self.find_by_alias(name)
@alias_index[name]
end
# Public: Look up Lexer by one of it's mime types.
#
# type - A mime type String.
#
# Examples
#
# Lexer.find_by_mimetype('application/x-ruby')
# # => #<Lexer name="Ruby">
#
# Returns the Lexer or nil if none was found.
def self.find_by_mimetype(type)
@mimetypes_index[type]
end
# Public: Return a alias of the Lexer to pass to Pygments.
#
# The alias we choose is arbitrary.
#
# Returns the alias String
def to_s
aliases.first
end
# Public: Highlight syntax of text
#
# text - String of code to be highlighted
#
# Returns html String
def colorize(text)
Pygments.highlight(text, :lexer => aliases.first, :options => {:stripnl => false})
end
# Public: Highlight syntax of text without the outer highlight div
# wrapper.
#
# text - String of code to be highlighted
#
# Returns html String
def colorize_without_wrapper(text)
if text = colorize(text)
text[%r{<div class="highlight"><pre>(.*?)</pre>\s*</div>}m, 1]
else
''
end
end
def ==(other)
eql?(other)
end
def eql?(other)
equal?(other)
end
# Load lexers from lexers.yml
#
# `bin/pygments-lexers` dumps a YAML list of all the available
# Pygments lexers.
YAML.load_file(File.expand_path("../lexers.yml", __FILE__)).each do |name, attrs|
Lexer.create(name, attrs)
end
end
end