rouge 0.0.10 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -28,6 +28,7 @@ load load_dir.join('rouge/lexers/xml.rb')
28
28
 
29
29
  load load_dir.join('rouge/lexers/tcl.rb')
30
30
  load load_dir.join('rouge/lexers/python.rb')
31
+ load load_dir.join('rouge/lexers/ruby.rb')
31
32
 
32
33
  load load_dir.join('rouge/lexers/haskell.rb')
33
34
  load load_dir.join('rouge/lexers/scheme.rb')
@@ -214,8 +214,12 @@ module Rouge
214
214
  @defn = defn
215
215
  end
216
216
 
217
- def relative_state(state_name)
218
- @lexer_class.get_state(state_name)
217
+ def relative_state(state_name=nil, &b)
218
+ if state_name
219
+ @lexer_class.get_state(state_name)
220
+ else
221
+ State.new(@lexer_class, b.inspect, &b).load!
222
+ end
219
223
  end
220
224
 
221
225
  def rules
@@ -253,9 +257,9 @@ module Rouge
253
257
  stack.pop
254
258
  end
255
259
 
256
- def push(state_name)
257
- debug { " pushing #{state_name}" }
258
- stack.push(state.relative_state(state_name))
260
+ def push(state_name=nil, &b)
261
+ debug { " pushing #{state_name || 'anonymous state'}" }
262
+ stack.push(state.relative_state(state_name, &b))
259
263
  end
260
264
 
261
265
  def in_state?(state_name)
@@ -282,10 +286,13 @@ module Rouge
282
286
  end
283
287
  end
284
288
 
285
- def token(tok, val=nil)
289
+ def token(tok, val=:__absent__)
290
+ val = scanner[0] if val == :__absent__
291
+ val ||= ''
292
+
286
293
  raise 'no output stream' unless @output_stream
287
294
 
288
- @output_stream << [Token[tok], val || scanner[0]]
295
+ @output_stream << [Token[tok], val]
289
296
  end
290
297
 
291
298
  def group(tok)
@@ -368,6 +375,14 @@ module Rouge
368
375
  @states ||= {}
369
376
  end
370
377
 
378
+ def self.start_procs
379
+ @start_procs ||= []
380
+ end
381
+
382
+ def self.start(&b)
383
+ start_procs << b
384
+ end
385
+
371
386
  def self.state(name, &b)
372
387
  name = name.to_s
373
388
  states[name] = State.new(self, name, &b)
@@ -402,6 +417,10 @@ module Rouge
402
417
  def stream_tokens(stream, &b)
403
418
  scan_state = ScanState.new(self, stream)
404
419
 
420
+ self.class.start_procs.each do |pr|
421
+ scan_state.instance_eval(&pr)
422
+ end
423
+
405
424
  stream_with_state(scan_state, &b)
406
425
  end
407
426
 
@@ -431,7 +450,9 @@ module Rouge
431
450
  case rule
432
451
  when String
433
452
  debug { " entering mixin #{rule}" }
434
- step(get_state(rule), scan_state, &b)
453
+ res = step(get_state(rule), scan_state, &b)
454
+ debug { " exiting mixin #{rule}" }
455
+ res
435
456
  when Rule
436
457
  debug { " trying #{rule.inspect}" }
437
458
  scan_state.scan(rule.re) do |match|
@@ -0,0 +1,342 @@
1
+ module Rouge
2
+ module Lexers
3
+ class Ruby < RegexLexer
4
+ tag 'ruby'
5
+ aliases 'rb'
6
+ filenames '*.rb', '*.ruby', '*.rbw', '*.rake', '*.gemspec',
7
+ 'Rakefile', 'Guardfile', 'Gemfile'
8
+
9
+ mimetypes 'text/x-ruby', 'application/x-ruby'
10
+
11
+ def self.analyze_text(text)
12
+ return 1 if text.shebang? 'ruby'
13
+ end
14
+
15
+ state :strings do
16
+ # symbols
17
+ rule %r(
18
+ : # initial :
19
+ @{0,2} # optional ivar, for :@foo and :@@foo
20
+ [a-z_]\w*[!?] # the symbol
21
+ )x, 'Literal.String.Symbol'
22
+
23
+ # special symbols
24
+ rule %r(:(?:\*\*|[-+]@|[/\%&\|^`~]|\[\]=?|<<|>>|<=?>|<=?|===?)),
25
+ 'Literal.String.Symbol'
26
+
27
+ rule /:'(\\\\|\\'|[^'])*'/, 'Literal.String.Symbol'
28
+ rule /'(\\\\|\\'|[^'])*'/, 'Literal.String.Single'
29
+ rule /:"/, 'Literal.String.Symbol', :simple_sym
30
+ rule /"/, 'Literal.String.Double', :simple_string
31
+ rule /(?<!\.)`/, 'Literal.String.Backtick', :simple_backtick
32
+
33
+ # %-style delimiters
34
+ # %(abc), %[abc], %<abc>, %.abc., %r.abc., etc
35
+ delimiter_map = { '{' => '}', '[' => ']', '(' => ')', '<' => '>' }
36
+ rule /%([rqswQWx])?([^\w\s])/ do |m|
37
+ open = Regexp.escape(m[2])
38
+ close = Regexp.escape(delimiter_map[m[2]] || m[2])
39
+ interp = /[rQWx]/ === m[1]
40
+ toktype = 'Literal.String.Other'
41
+
42
+ debug { " open: #{open.inspect}" }
43
+ debug { " close: #{close.inspect}" }
44
+
45
+ # regexes
46
+ if m[1] == 'r'
47
+ toktype = 'Literal.String.Regex'
48
+ push :regex_flags
49
+ end
50
+
51
+ token toktype
52
+
53
+ push do
54
+ rule /\\[##{open}#{close}\\]/, toktype
55
+ mixin :string_intp_escaped if interp
56
+ # nesting rules only with asymmetric delimiters
57
+ if open != close
58
+ rule /#{open}/, toktype, self
59
+ end
60
+ rule /#{close}/, toktype, :pop!
61
+
62
+ rule /[^##{open}#{close}\\]+/m, toktype
63
+ end
64
+ end
65
+ end
66
+
67
+ state :regex_flags do
68
+ rule /[mixounse]*/, 'Literal.String.Regex', :pop!
69
+ end
70
+
71
+ # double-quoted string and symbol
72
+ [[:string, 'Literal.String.Double', '"'],
73
+ [:sym, 'Literal.String.Symbol', '"'],
74
+ [:backtick, 'Literal.String.Backtick', '`']].each do |name, tok, fin|
75
+ state :"simple_#{name}" do
76
+ mixin :string_intp_escaped
77
+ rule /[^\\#{fin}#]+/m, tok
78
+ rule /[\\#]/, tok
79
+ rule /#{fin}/, tok, :pop!
80
+ end
81
+ end
82
+
83
+ keywords = %w(
84
+ BEGIN END alias begin break case defined\? do else elsif end
85
+ ensure for if in next redo rescue raise retry return super then
86
+ undef unless until when while yield
87
+ )
88
+
89
+ keywords_pseudo = %w(
90
+ initialize new loop include extend raise attr_reader attr_writer
91
+ attr_accessor attr catch throw private module_function public
92
+ protected true false nil __FILE__ __LINE__
93
+ )
94
+
95
+ builtins_g = %w(
96
+ Array Float Integer String __id__ __send__ abort ancestors
97
+ at_exit autoload binding callcc caller catch chomp chop
98
+ class_eval class_variables clone const_defined\? const_get
99
+ const_missing const_set constants display dup eval exec exit
100
+ extend fail fork format freeze getc gets global_variables gsub
101
+ hash id included_modules inspect instance_eval instance_method
102
+ instance_methods instance_variable_get instance_variable_set
103
+ instance_variables lambda load local_variables loop method
104
+ method_missing methods module_eval name object_id open p
105
+ print printf private_class_method private_instance_methods
106
+ private_methods proc protected_instance_methods protected_methods
107
+ public_class_method public_instance_methods public_methods putc
108
+ puts raise rand readline readlines require scan select self send
109
+ set_trace_func singleton_methods sleep split sprintf srand sub
110
+ syscall system taint test throw to_a to_s trace_var trap untaint
111
+ untrace_var warn
112
+ )
113
+
114
+ builtins_q = %w(
115
+ autoload block_given const_defined eql equal frozen
116
+ include instance_of is_a iterator kind_of method_defined
117
+ nil private_method_defined protected_method_defined
118
+ public_method_defined respond_to tainted
119
+ )
120
+
121
+ builtins_b = %w(chomp chop exit gsub sub)
122
+
123
+ start do
124
+ push :expr_start
125
+ @heredoc_queue = []
126
+ end
127
+
128
+ state :root do
129
+ rule /#.*$/, 'Comment.Single'
130
+ rule %r(=begin\b.*?end\b)m, 'Comment.Multiline'
131
+ rule /(?:#{keywords.join('|')})\b/, 'Keyword', :expr_start
132
+ rule /(?:#{keywords_pseudo.join('|')})\b/, 'Keyword.Pseudo', :expr_start
133
+ rule %r(
134
+ (module)
135
+ (\s+)
136
+ ([a-zA-Z_][a-zA-Z0-9_]*(::[a-zA-Z_][a-zA-Z0-9_]*)*)
137
+ ) do
138
+ group 'Keyword'
139
+ group 'Text'
140
+ group 'Name.Namespace'
141
+ end
142
+
143
+ rule /def\b/, 'Keyword', :funcname
144
+ rule /class\b/, 'Keyword', :classname
145
+
146
+ rule /(?:#{builtins_q.join('|')})\?/, 'Name.Builtin', :expr_start
147
+ rule /(?:#{builtins_b.join('|')})!/, 'Name.Builtin', :expr_start
148
+ rule /(?<!\.)(?:#{builtins_g.join('|')})\b/,
149
+ 'Name.Builtin', :method_call
150
+
151
+ rule /__END__/, 'Comment.Preproc', :end_part
152
+
153
+ rule /0_?[0-7]+(?:_[0-7]+)*/, 'Literal.Number.Oct'
154
+ rule /0x[0-9A-Fa-f]+(?:_[0-9A-Fa-f]+)*/, 'Literal.Number.Hex'
155
+ rule /0b[01]+(?:_[01]+)*/, 'Literal.Number.Bin'
156
+ rule /[\d]+(?:_\d+)*/, 'Literal.Number.Integer'
157
+
158
+ # names
159
+ rule /@@[a-z_]\w*/i, 'Name.Variable.Class'
160
+ rule /@[a-z_]\w*/i, 'Name.Variable.Instance'
161
+ rule /\$\w+/, 'Name.Variable.Global'
162
+ rule %r(\$[!@&`'+~=/\\,;.<>_*\$?:"]), 'Name.Variable.Global'
163
+ rule /\$-[0adFiIlpvw]/, 'Name.Variable.Global'
164
+ rule /::/, 'Operator'
165
+
166
+ mixin :strings
167
+
168
+ # char operator. ?x evaulates to "x", unless there's a digit
169
+ # beforehand like x>=0?n[x]:""
170
+ rule %r(
171
+ \?(\\[MC]-)* # modifiers
172
+ (\\([\\abefnrstv\#"']|x[a-fA-F0-9]{1,2}|[0-7]{1,3})|\S)
173
+ (?!\w)
174
+ )x, 'Literal.String.Char'
175
+
176
+ mixin :has_heredocs
177
+
178
+ rule /[A-Z][a-zA-Z0-9_]+/, 'Name.Constant', :method_call
179
+ rule /(\.|::)([a-z_]\w*[!?]?|[*%&^`~+-\/\[<>=])/,
180
+ 'Name.Function', :expr_start
181
+ rule /[a-zA-Z_]\w*[?!]/, 'Name', :expr_start
182
+ rule /[a-zA-Z_]\w*/, 'Name', :method_call
183
+ rule /\[|\]|\*\*|<<?|>>?|>=|<=|<=>|=~|={3}|!~|&&?|\|\||\.{1,3}/,
184
+ 'Operator', :expr_start
185
+ rule /[-+\/*%=<>&!^|~]=?/, 'Operator', :expr_start
186
+ rule %r<[({,?:\\;/]>, 'Punctuation', :expr_start
187
+ rule %r<[)}]>, 'Punctuation'
188
+ rule /\n\s*/m, 'Text', :expr_start
189
+ rule /\s+/, 'Text' # NB: NOT /m
190
+ end
191
+
192
+ state :has_heredocs do
193
+ rule /(?<!\w)(<<-?)(["`']?)([a-zA-Z_]\w*)(\2)/ do |m|
194
+ token 'Operator', m[1]
195
+ token 'Name.Constant', "#{m[2]}#{m[3]}#{m[4]}"
196
+ @heredoc_queue << [m[1] == '<<-', m[3]]
197
+ push :heredoc_queue unless state? :heredoc_queue
198
+ end
199
+
200
+ rule /(<<-?)(["'])(\2)(.*?\n)/ do |m|
201
+ token 'Operator', m[1]
202
+ token 'Name.Constant', "#{m[2]}#{m[3]}#{m[4]}"
203
+ @heredoc_queue << [m[1] == '<<-', '']
204
+ push :heredoc_queue unless state? :heredoc_queue
205
+ end
206
+ end
207
+
208
+ state :heredoc_queue do
209
+ rule /\n/ do
210
+ token 'Text'
211
+ pop!; push :resolve_heredocs
212
+ end
213
+
214
+ mixin :root
215
+ end
216
+
217
+ state :resolve_heredocs do
218
+ rule /(.*)\n/ do |m|
219
+ tolerant, heredoc_name = @heredoc_queue.first
220
+ check = tolerant ? m[1].strip : m[1].rstrip
221
+
222
+ # check if we found the end of the heredoc
223
+ if check == heredoc_name
224
+ token 'Name.Constant'
225
+ @heredoc_queue.shift
226
+ # if there's no more, we're done looking.
227
+ pop! if @heredoc_queue.empty?
228
+ else
229
+ token 'Literal.String.Heredoc'
230
+ end
231
+ end
232
+ end
233
+
234
+ state :funcname do
235
+ rule /\s+/, 'Text'
236
+ rule /\(/, 'Punctuation', :defexpr
237
+ rule %r(
238
+ (?:([a-zA-Z_][\w_]*)(\.))?
239
+ (
240
+ [a-zA-Z_][\w_]*[!?]? |
241
+ \*\*? | [-+]@? | [/%&\|^`~] | \[\]=? |
242
+ << | >> | <=?> | >=? | ===?
243
+ )
244
+ )x do |m|
245
+ debug { "matches: #{[m[0], m[1], m[2], m[3]].inspect}" }
246
+ group 'Name.Class'
247
+ group 'Operator'
248
+ group 'Name.Function'
249
+ pop!
250
+ end
251
+
252
+ rule(//) { pop! }
253
+ end
254
+
255
+ state :classname do
256
+ rule /\s+/, 'Text'
257
+ rule /\(/, 'Punctuation', :defexpr
258
+
259
+ # class << expr
260
+ rule /<</, 'Operator', :pop!
261
+ rule /[A-Z_]\w*/, 'Name.Class'
262
+
263
+ rule(//) { pop! }
264
+ end
265
+
266
+ state :defexpr do
267
+ rule /(\))(\.|::)?/ do
268
+ group 'Punctuation'
269
+ group 'Operator'
270
+ pop!
271
+ end
272
+ rule /\(/, 'Operator', :defexpr
273
+ mixin :root
274
+ end
275
+
276
+ state :in_interp do
277
+ rule /}/, 'Literal.String.Interpol', :pop!
278
+ mixin :root
279
+ end
280
+
281
+ state :string_intp do
282
+ rule /\#{/, 'Literal.String.Interpol', :in_interp
283
+ rule /#(@@?|\$)[a-z_]\w*/i, 'Literal.String.Interpol'
284
+ end
285
+
286
+ state :string_intp_escaped do
287
+ mixin :string_intp
288
+ rule /\\([\\abefnrstv#"']|x[a-fA-F0-9]{1,2}|[0-7]{1,3})/,
289
+ 'Literal.String.Escape'
290
+ end
291
+
292
+ state :method_call do
293
+ rule %r((\s+)(/)(?=\S|\s*/)) do
294
+ group 'Text'
295
+ group 'Literal.String.Regex'
296
+ pop!
297
+ push :slash_regex
298
+ end
299
+
300
+ rule(%r((?=\s*/))) { pop! }
301
+
302
+ rule(//) { pop!; push :expr_start }
303
+ end
304
+
305
+ state :expr_start do
306
+ rule %r((\s*)(/)) do
307
+ group 'Text'
308
+ group 'Literal.String.Regex'
309
+ pop!
310
+ push :slash_regex
311
+ end
312
+
313
+ # special case for using a single space. Ruby demands that
314
+ # these be in a single line, otherwise it would make no sense.
315
+ rule /(\s*)(%[rqswQWx]? \S* )/ do
316
+ group 'Text'
317
+ group 'Literal.String.Other'
318
+ pop!
319
+ end
320
+
321
+ rule(//) { pop! }
322
+ end
323
+
324
+ state :slash_regex do
325
+ mixin :string_intp
326
+ rule %r(\\\\), 'Literal.String.Regex'
327
+ rule %r(\\/), 'Literal.String.Regex'
328
+ rule %r([\\#]), 'Literal.String.Regex'
329
+ rule %r([^\\/#]+)m, 'Literal.String.Regex'
330
+ rule %r(/) do
331
+ token 'Literal.String.Regex'
332
+ pop!; push :regex_flags
333
+ end
334
+ end
335
+
336
+ state :end_part do
337
+ # eat up the rest of the stream as Comment.Preproc
338
+ rule /.+/m, 'Comment.Preproc', :pop!
339
+ end
340
+ end
341
+ end
342
+ end
@@ -46,13 +46,12 @@ module Rouge
46
46
  'Name.Builtin.Pseudo',
47
47
  'Name.Exception',
48
48
  'Name.Tag', :fg => :go_get_it, :bold => true
49
- style 'Literal.Number', :fg => :pink_merengue, :bold => true
49
+ style 'Literal.Number',
50
+ 'Literal.String.Symbol', :fg => :pink_merengue, :bold => true
50
51
  style 'Literal.String', :fg => :dune, :bold => true
51
52
  style 'Literal.String.Escape',
52
53
  'Literal.String.Char',
53
- 'Literal.String.Interpol',
54
- 'Literal.String.Other',
55
- 'Literal.String.Symbol', :fg => :backlit, :bold => true
54
+ 'Literal.String.Interpol', :fg => :backlit, :bold => true
56
55
  style 'Name.Builtin', :fg => :sandy
57
56
  style 'Name.Entity', :fg => '#999999', :bold => true
58
57
  style 'Text.Whitespace', :fg => '#BBBBBB'
@@ -1,5 +1,5 @@
1
1
  module Rouge
2
2
  def self.version
3
- "0.0.10"
3
+ "0.0.11"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rouge
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.11
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-09 00:00:00.000000000 Z
12
+ date: 2012-09-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
@@ -41,6 +41,7 @@ files:
41
41
  - lib/rouge/lexers/scheme.rb
42
42
  - lib/rouge/lexers/xml.rb
43
43
  - lib/rouge/lexers/shell.rb
44
+ - lib/rouge/lexers/ruby.rb
44
45
  - lib/rouge/lexers/javascript.rb
45
46
  - lib/rouge/lexers/diff.rb
46
47
  - lib/rouge/lexers/haskell.rb