1
1
# frozen_string_literal: true
2
2
3
+ require 'singleton'
4
+
3
5
module Pygments
4
6
class Lexer < Struct . new ( :name , :aliases , :filenames , :mimetypes )
5
- @lexers = [ ]
6
- @index = { }
7
- @name_index = { }
8
- @alias_index = { }
9
- @extname_index = { }
10
- @mimetypes_index = { }
11
-
12
- # Internal: Create a new Lexer object
13
- #
14
- # hash - A hash of attributes
15
- #
16
- # Returns a Lexer object
17
- def self . create ( hash )
18
- lexer = new ( hash [ :name ] , hash [ :aliases ] , hash [ :filenames ] , hash [ :mimetypes ] )
19
-
20
- @lexers << lexer
21
-
22
- @index [ lexer . name . downcase ] = @name_index [ lexer . name ] = lexer
23
-
24
- lexer . aliases . each do |name |
25
- @alias_index [ name ] = lexer
26
- @index [ name . downcase ] ||= lexer
27
- end
28
-
29
- lexer . filenames . each do |filename |
30
- extnames = [ ]
31
-
32
- extname = File . extname ( filename )
33
- if ( m = extname . match ( /\[ (.+)\] / ) )
34
- m [ 1 ] . scan ( /./ ) . each do |s |
35
- extnames << extname . sub ( m [ 0 ] , s )
36
- end
37
- elsif extname != ''
38
- extnames << extname
39
- end
40
-
41
- extnames . each do |the_extname |
42
- @extname_index [ the_extname ] = lexer
43
- @index [ the_extname . downcase . sub ( /^\. / , '' ) ] ||= lexer
44
- end
45
- end
46
-
47
- lexer . mimetypes . each do |type |
48
- @mimetypes_index [ type ] = lexer
49
- end
50
-
51
- lexer
52
- end
53
-
54
7
# Public: Get all Lexers
55
8
#
56
- # Returns an Array of Lexers
9
+ # @return [ Array<Lexer>]
57
10
def self . all
58
- @ lexers
11
+ LexerCache . instance . lexers
59
12
end
60
13
61
14
# Public: Look up Lexer by name or alias.
@@ -65,12 +18,15 @@ def self.all
65
18
# Lexer.find('Ruby')
66
19
# => #<Lexer name="Ruby">
67
20
#
68
- # Returns the Lexer or nil if none was found.
21
+ # @return [ Lexer, nil]
69
22
def self . find ( name )
70
- @ index[ name . to_s . downcase ]
23
+ LexerCache . instance . index [ name . to_s . downcase ]
71
24
end
72
25
73
26
# Public: Alias for find.
27
+ #
28
+ # @param name [String]
29
+ # @return [Lexer, nil]
74
30
def self . []( name )
75
31
find ( name )
76
32
end
@@ -84,9 +40,10 @@ def self.[](name)
84
40
# Lexer.find_by_name('Ruby')
85
41
# # => #<Lexer name="Ruby">
86
42
#
87
- # Returns the Lexer or nil if none was found.
43
+ # @param name [String]
44
+ # @return [Lexer, nil]
88
45
def self . find_by_name ( name )
89
- @ name_index[ name ]
46
+ LexerCache . instance . name_index [ name ]
90
47
end
91
48
92
49
# Public: Look up Lexer by one of its aliases.
@@ -98,9 +55,10 @@ def self.find_by_name(name)
98
55
# Lexer.find_by_alias('rb')
99
56
# # => #<Lexer name="Ruby">
100
57
#
101
- # Returns the Lexer or nil if none was found.
58
+ # @param name [String]
59
+ # @return [Lexer, nil]
102
60
def self . find_by_alias ( name )
103
- @ alias_index[ name ]
61
+ LexerCache . instance . alias_index [ name ]
104
62
end
105
63
106
64
# Public: Look up Lexer by one of it's file extensions.
@@ -112,9 +70,10 @@ def self.find_by_alias(name)
112
70
# Lexer.find_by_extname('.rb')
113
71
# # => #<Lexer name="Ruby">
114
72
#
115
- # Returns the Lexer or nil if none was found.
73
+ # @param extname [String]
74
+ # @return [Lexer, nil]
116
75
def self . find_by_extname ( extname )
117
- @ extname_index[ extname ]
76
+ LexerCache . instance . extname_index [ extname ]
118
77
end
119
78
120
79
# Public: Look up Lexer by one of it's mime types.
@@ -126,9 +85,10 @@ def self.find_by_extname(extname)
126
85
# Lexer.find_by_mimetype('application/x-ruby')
127
86
# # => #<Lexer name="Ruby">
128
87
#
129
- # Returns the Lexer or nil if none was found.
88
+ # @param type [String]
89
+ # @return [Lexer, nil]
130
90
def self . find_by_mimetype ( type )
131
- @ mimetypes_index[ type ]
91
+ LexerCache . instance . mimetypes_index [ type ]
132
92
end
133
93
134
94
# Public: Highlight syntax of text
@@ -146,5 +106,67 @@ def highlight(text, options = {})
146
106
alias eql? equal?
147
107
end
148
108
149
- lexers . values . each { |h | Lexer . create ( h ) }
109
+ class LexerCache
110
+ include Singleton
111
+
112
+ # @return [Array<Lexer>]
113
+ attr_reader ( :lexers )
114
+ # @return [Map<String, Lexer>]
115
+ attr_reader ( :index )
116
+ # @return [Map<String, Lexer>]
117
+ attr_reader ( :name_index )
118
+ # @return [Map<String, Lexer]
119
+ attr_reader ( :alias_index )
120
+ # @return [Map<String, Lexer>]
121
+ attr_reader ( :extname_index )
122
+ # @return [Map<String, Lexer>]
123
+ attr_reader ( :mimetypes_index )
124
+
125
+ attr_reader ( :raw_lexers )
126
+
127
+ def initialize
128
+ @lexers = [ ]
129
+ @index = { }
130
+ @name_index = { }
131
+ @alias_index = { }
132
+ @extname_index = { }
133
+ @mimetypes_index = { }
134
+ @raw_lexers = Pygments . lexers!
135
+
136
+ @raw_lexers . values . each do |hash |
137
+ lexer = Lexer . new ( hash [ :name ] , hash [ :aliases ] , hash [ :filenames ] , hash [ :mimetypes ] )
138
+
139
+ @lexers << lexer
140
+
141
+ @index [ lexer . name . downcase ] = @name_index [ lexer . name ] = lexer
142
+
143
+ lexer . aliases . each do |name |
144
+ @alias_index [ name ] = lexer
145
+ @index [ name . downcase ] ||= lexer
146
+ end
147
+
148
+ lexer . filenames . each do |filename |
149
+ extnames = [ ]
150
+
151
+ extname = File . extname ( filename )
152
+ if ( m = extname . match ( /\[ (.+)\] / ) )
153
+ m [ 1 ] . scan ( /./ ) . each do |s |
154
+ extnames << extname . sub ( m [ 0 ] , s )
155
+ end
156
+ elsif extname != ''
157
+ extnames << extname
158
+ end
159
+
160
+ extnames . each do |the_extname |
161
+ @extname_index [ the_extname ] = lexer
162
+ @index [ the_extname . downcase . sub ( /^\. / , '' ) ] ||= lexer
163
+ end
164
+ end
165
+
166
+ lexer . mimetypes . each do |type |
167
+ @mimetypes_index [ type ] = lexer
168
+ end
169
+ end
170
+ end
171
+ end
150
172
end
0 commit comments