rouge 0.0.10 → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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