rouge 0.1.2 → 0.2.0

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.
@@ -207,31 +207,26 @@ module Rouge
207
207
  structure-object symbol synonym-stream t two-way-stream vector
208
208
  )
209
209
 
210
- def stream_tokens(*a, &b)
211
- super(*a) do |tok, val|
212
- case tok
213
- when Token['Name.Variable']
214
- if BUILTIN_FUNCTIONS.include? val
215
- yield Token['Name.Builtin'], val
216
- elsif SPECIAL_FORMS.include? val
217
- yield Token['Keyword'], val
218
- elsif MACROS.include? val
219
- yield Token['Name.Builtin'], val
220
- elsif LAMBDA_LIST_KEYWORDS.include? val
221
- yield Token['Keyword'], val
222
- elsif DECLARATIONS.include? val
223
- yield Token['Keyword'], val
224
- elsif BUILTIN_TYPES.include? val
225
- yield Token['Keyword.Type'], val
226
- elsif BUILTIN_CLASSES.include? val
227
- yield Token['Name.Class'], val
228
- else
229
- yield tok, val
230
- end
231
- else
232
- yield tok, val
233
- end
210
+ postprocess 'Name.Variable' do |tok, val|
211
+ tok = if BUILTIN_FUNCTIONS.include? val
212
+ 'Name.Builtin'
213
+ elsif SPECIAL_FORMS.include? val
214
+ 'Keyword'
215
+ elsif MACROS.include? val
216
+ 'Name.Builtin'
217
+ elsif LAMBDA_LIST_KEYWORDS.include? val
218
+ 'Keyword'
219
+ elsif DECLARATIONS.include? val
220
+ 'Keyword'
221
+ elsif BUILTIN_TYPES.include? val
222
+ 'Keyword.Type'
223
+ elsif BUILTIN_CLASSES.include? val
224
+ 'Name.Class'
225
+ else
226
+ 'Name.Variable'
234
227
  end
228
+
229
+ token tok, val
235
230
  end
236
231
 
237
232
  nonmacro = /\\.|[a-zA-Z0-9!$%&*+-\/<=>?@\[\]^_{}~]/
@@ -1,6 +1,6 @@
1
1
  module Rouge
2
2
  module Lexers
3
- class ERB < RegexLexer
3
+ class ERB < TemplateLexer
4
4
  tag 'erb'
5
5
  aliases 'eruby', 'rhtml'
6
6
 
@@ -11,19 +11,13 @@ module Rouge
11
11
  end
12
12
 
13
13
  def initialize(opts={})
14
- @parent = opts.delete(:parent) || 'html'
15
- if @parent.is_a? String
16
- lexer_class = Lexer.find(@parent)
17
- @parent = lexer_class.new(opts)
18
- end
19
-
20
14
  @ruby_lexer = Ruby.new(opts)
21
15
 
22
16
  super(opts)
23
17
  end
24
18
 
25
19
  start do
26
- @parent.reset!
20
+ parent.reset!
27
21
  @ruby_lexer.reset!
28
22
  end
29
23
 
@@ -36,7 +30,7 @@ module Rouge
36
30
  rule open, 'Comment.Preproc', :ruby
37
31
 
38
32
  rule /.+?(?=#{open})|.+/m do
39
- delegate @parent
33
+ delegate parent
40
34
  end
41
35
  end
42
36
 
@@ -0,0 +1,300 @@
1
+ module Rouge
2
+ module Lexers
3
+ class Factor < RegexLexer
4
+ tag 'factor'
5
+ filenames '*.factor'
6
+ mimetypes 'text/x-factor'
7
+
8
+ def self.analyze_text(text)
9
+ return 1 if text.shebang? 'factor'
10
+ end
11
+
12
+ def self.builtins
13
+ @builtins ||= {}.tap do |builtins|
14
+ builtins[:kernel] = Set.new %w(
15
+ or 2bi 2tri while wrapper nip 4dip wrapper? bi*
16
+ callstack>array both? hashcode die dupd callstack
17
+ callstack? 3dup tri@ pick curry build ?execute 3bi prepose
18
+ >boolean if clone eq? tri* ? = swapd 2over 2keep 3keep clear
19
+ 2dup when not tuple? dup 2bi* 2tri* call tri-curry object bi@
20
+ do unless* if* loop bi-curry* drop when* assert= retainstack
21
+ assert? -rot execute 2bi@ 2tri@ boa with either? 3drop bi
22
+ curry? datastack until 3dip over 3curry tri-curry* tri-curry@
23
+ swap and 2nip throw bi-curry (clone) hashcode* compose 2dip if
24
+ 3tri unless compose? tuple keep 2curry equal? assert tri 2drop
25
+ most <wrapper> boolean? identity-hashcode identity-tuple?
26
+ null new dip bi-curry@ rot xor identity-tuple boolean
27
+ )
28
+
29
+ builtins[:assocs] = Set.new %w(
30
+ ?at assoc? assoc-clone-like assoc= delete-at* assoc-partition
31
+ extract-keys new-assoc value? assoc-size map>assoc push-at
32
+ assoc-like key? assoc-intersect assoc-refine update
33
+ assoc-union assoc-combine at* assoc-empty? at+ set-at
34
+ assoc-all? assoc-subset? assoc-hashcode change-at assoc-each
35
+ assoc-diff zip values value-at rename-at inc-at enum? at cache
36
+ assoc>map <enum> assoc assoc-map enum value-at* assoc-map-as
37
+ >alist assoc-filter-as clear-assoc assoc-stack maybe-set-at
38
+ substitute assoc-filter 2cache delete-at assoc-find keys
39
+ assoc-any? unzip
40
+ )
41
+
42
+ builtins[:combinators] = Set.new %w(
43
+ case execute-effect no-cond no-case? 3cleave>quot 2cleave
44
+ cond>quot wrong-values? no-cond? cleave>quot no-case case>quot
45
+ 3cleave wrong-values to-fixed-point alist>quot case-find
46
+ cond cleave call-effect 2cleave>quot recursive-hashcode
47
+ linear-case-quot spread spread>quot
48
+ )
49
+
50
+ builtins[:math] = Set.new %w(
51
+ number= if-zero next-power-of-2 each-integer ?1+
52
+ fp-special? imaginary-part unless-zero float>bits number?
53
+ fp-infinity? bignum? fp-snan? denominator fp-bitwise= *
54
+ + power-of-2? - u>= / >= bitand log2-expects-positive <
55
+ log2 > integer? number bits>double 2/ zero? (find-integer)
56
+ bits>float float? shift ratio? even? ratio fp-sign bitnot
57
+ >fixnum complex? /i /f byte-array>bignum when-zero sgn >bignum
58
+ next-float u< u> mod recip rational find-last-integer >float
59
+ (all-integers?) 2^ times integer fixnum? neg fixnum sq bignum
60
+ (each-integer) bit? fp-qnan? find-integer complex <fp-nan>
61
+ real double>bits bitor rem fp-nan-payload all-integers?
62
+ real-part log2-expects-positive? prev-float align unordered?
63
+ float fp-nan? abs bitxor u<= odd? <= /mod rational? >integer
64
+ real? numerator
65
+ )
66
+
67
+ builtins[:sequences] = Set.new %w(
68
+ member-eq? append assert-sequence= find-last-from
69
+ trim-head-slice clone-like 3sequence assert-sequence? map-as
70
+ last-index-from reversed index-from cut* pad-tail
71
+ remove-eq! concat-as but-last snip trim-tail nths
72
+ nth 2selector sequence slice? <slice> partition
73
+ remove-nth tail-slice empty? tail* if-empty
74
+ find-from virtual-sequence? member? set-length
75
+ drop-prefix unclip unclip-last-slice iota map-sum
76
+ bounds-error? sequence-hashcode-step selector-for
77
+ accumulate-as map start midpoint@ (accumulate) rest-slice
78
+ prepend fourth sift accumulate! new-sequence follow map! like
79
+ first4 1sequence reverse slice unless-empty padding virtual@
80
+ repetition? set-last index 4sequence max-length set-second
81
+ immutable-sequence first2 first3 replicate-as reduce-index
82
+ unclip-slice supremum suffix! insert-nth trim-tail-slice
83
+ tail 3append short count suffix concat flip filter sum
84
+ immutable? reverse! 2sequence map-integers delete-all start*
85
+ indices snip-slice check-slice sequence? head map-find
86
+ filter! append-as reduce sequence= halves collapse-slice
87
+ interleave 2map filter-as binary-reduce slice-error? product
88
+ bounds-check? bounds-check harvest immutable virtual-exemplar
89
+ find produce remove pad-head last replicate set-fourth
90
+ remove-eq shorten reversed? map-find-last 3map-as
91
+ 2unclip-slice shorter? 3map find-last head-slice pop* 2map-as
92
+ tail-slice* but-last-slice 2map-reduce iota? collector-for
93
+ accumulate each selector append! new-resizable cut-slice
94
+ each-index head-slice* 2reverse-each sequence-hashcode
95
+ pop set-nth ?nth <flat-slice> second join when-empty
96
+ collector immutable-sequence? <reversed> all? 3append-as
97
+ virtual-sequence subseq? remove-nth! push-either new-like
98
+ length last-index push-if 2all? lengthen assert-sequence
99
+ copy map-reduce move third first 3each tail? set-first prefix
100
+ bounds-error any? <repetition> trim-slice exchange surround
101
+ 2reduce cut change-nth min-length set-third produce-as
102
+ push-all head? delete-slice rest sum-lengths 2each head*
103
+ infimum remove! glue slice-error subseq trim replace-slice
104
+ push repetition map-index trim-head unclip-last mismatch
105
+ )
106
+
107
+ builtins[:namespaces] = Set.new %w(
108
+ global +@ change set-namestack change-global init-namespaces
109
+ on off set-global namespace set with-scope bind with-variable
110
+ inc dec counter initialize namestack get get-global make-assoc
111
+ )
112
+
113
+ builtins[:arrays] = Set.new %w(
114
+ <array> 2array 3array pair >array 1array 4array pair?
115
+ array resize-array array?
116
+ )
117
+
118
+ builtins[:io] = Set.new %w(
119
+ +character+ bad-seek-type? readln each-morsel
120
+ stream-seek read print with-output-stream contents
121
+ write1 stream-write1 stream-copy stream-element-type
122
+ with-input-stream stream-print stream-read stream-contents
123
+ stream-tell tell-output bl seek-output bad-seek-type nl
124
+ stream-nl write flush stream-lines +byte+ stream-flush
125
+ read1 seek-absolute? stream-read1 lines stream-readln
126
+ stream-read-until each-line seek-end with-output-stream*
127
+ seek-absolute with-streams seek-input seek-relative?
128
+ input-stream stream-write read-partial seek-end?
129
+ seek-relative error-stream read-until with-input-stream*
130
+ with-streams* tell-input each-block output-stream
131
+ stream-read-partial each-stream-block each-stream-line
132
+ )
133
+
134
+ builtins[:strings] = Set.new %w(
135
+ resize-string >string <string> 1string string string?
136
+ )
137
+
138
+ builtins[:vectors] = Set.new %w(
139
+ with-return restarts return-continuation with-datastack
140
+ recover rethrow-restarts <restart> ifcc set-catchstack
141
+ >continuation< cleanup ignore-errors restart?
142
+ compute-restarts attempt-all-error error-thread
143
+ continue <continuation> attempt-all-error? condition?
144
+ <condition> throw-restarts error catchstack continue-with
145
+ thread-error-hook continuation rethrow callcc1
146
+ error-continuation callcc0 attempt-all condition
147
+ continuation? restart return
148
+ )
149
+
150
+ builtins[:continuations] = Set.new %w(
151
+ with-return restarts return-continuation with-datastack
152
+ recover rethrow-restarts <restart> ifcc set-catchstack
153
+ >continuation< cleanup ignore-errors restart?
154
+ compute-restarts attempt-all-error error-thread
155
+ continue <continuation> attempt-all-error? condition?
156
+ <condition> throw-restarts error catchstack continue-with
157
+ thread-error-hook continuation rethrow callcc1
158
+ error-continuation callcc0 attempt-all condition
159
+ continuation? restart return
160
+ )
161
+ end
162
+ end
163
+
164
+ state :root do
165
+ rule /\s+/m, 'Text'
166
+
167
+ rule /(:|::|MACRO:|MEMO:|GENERIC:|HELP:)(\s+)(\S+)/m do
168
+ group 'Keyword'; group 'Text'
169
+ group 'Name.Function'
170
+ end
171
+
172
+ rule /(M:|HOOK:|GENERIC#)(\s+)(\S+)(\s+)(\S+)/m do
173
+ group 'Keyword'; group 'Text'
174
+ group 'Name.Class'; group 'Text'
175
+ group 'Name.Function'
176
+ end
177
+
178
+ rule /\((?=\s)/, 'Name.Function', :stack_effect
179
+ rule /;(?=\s)/, 'Keyword'
180
+
181
+ rule /(USING:)((?:\s|\\\s)+)/m do
182
+ group 'Keyword.Namespace'; group 'Text'
183
+ push :import
184
+ end
185
+
186
+ rule /(IN:|USE:|UNUSE:|QUALIFIED:|QUALIFIED-WITH:)(\s+)(\S+)/m do
187
+ group 'Keyword.Namespace'; group 'Text'; group 'Name.Namespace'
188
+ end
189
+
190
+ rule /(FROM:|EXCLUDE:)(\s+)(\S+)(\s+)(=>)/m do
191
+ group 'Keyword.Namespace'; group 'Text'
192
+ group 'Name.Namespace'; group 'Text'
193
+ group 'Punctuation'
194
+ end
195
+
196
+ rule /(?:ALIAS|DEFER|FORGET|POSTPONE):/, 'Keyword.Namespace'
197
+
198
+ rule /(TUPLE:)(\s+)(\S+)(\s+)(<)(\s+)(\S+)/m do
199
+ group 'Keyword'; group 'Text'
200
+ group 'Name.Class'; group 'Text'
201
+ group 'Punctuation'; group 'Text'
202
+ group 'Name.Class'
203
+ push :slots
204
+ end
205
+
206
+ rule /(TUPLE:)(\s+)(\S+)/m do
207
+ group 'Keyword'; group 'Text'; group 'Name.Class'
208
+ push :slots
209
+ end
210
+
211
+ rule /(UNION:|INTERSECTION:)(\s+)(\S+)/m do
212
+ group 'Keyword'; group 'Text'; group 'Name.Class'
213
+ end
214
+
215
+ rule /(PREDICATE:)(\s+)(\S+)(\s+)(<)(\s+)(\S+)/m do
216
+ group 'Keyword'; group 'Text'
217
+ group 'Name.Class'; group 'Text'
218
+ group 'Punctuation'; group 'Text'
219
+ group 'Name.Class'
220
+ end
221
+
222
+ rule /(C:)(\s+)(\S+)(\s+)(\S+)/m do
223
+ group 'Keyword'; group 'Text'
224
+ group 'Name.Function'; group 'Text'
225
+ group 'Name.Class'
226
+ end
227
+
228
+ rule %r(
229
+ (INSTANCE|SLOT|MIXIN|SINGLETONS?|CONSTANT|SYMBOLS?|ERROR|SYNTAX
230
+ |ALIEN|TYPEDEF|FUNCTION|STRUCT):
231
+ )x, 'Keyword'
232
+
233
+ rule /(?:<PRIVATE|PRIVATE>)/, 'Keyword.Namespace'
234
+
235
+ rule /(MAIN:)(\s+)(\S+)/ do
236
+ group 'Keyword.Namespace'; group 'Text'; group 'Name.Function'
237
+ end
238
+
239
+ # strings
240
+ rule /"""\s+.*?\s+"""/, 'Literal.String'
241
+ rule /"(\\.|[^\\])*?"/, 'Literal.String'
242
+ rule /(CHAR:)(\s+)(\\[\\abfnrstv]*|\S)(?=\s)/, 'Literal.String.Char'
243
+
244
+ # comments
245
+ rule /!\s+.*$/, 'Comment'
246
+ rule /#!\s+.*$/, 'Comment'
247
+
248
+ # booleans
249
+ rule /[tf](?=\s)/, 'Name.Constant'
250
+
251
+ # numbers
252
+ rule /-?\d+\.\d+(?=\s)/, 'Literal.Number.Float'
253
+ rule /-?\d+(?=\s)/, 'Literal.Number.Integer'
254
+
255
+ rule /HEX:\s+[a-fA-F\d]+(?=\s)/m, 'Literal.Number.Hex'
256
+ rule /BIN:\s+[01]+(?=\s)/, 'Literal.Number.Bin'
257
+ rule /OCT:\s+[0-7]+(?=\s)/, 'Literal.Number.Oct'
258
+
259
+ rule %r([-+/*=<>^](?=\s)), 'Operator'
260
+
261
+ rule /(?:deprecated|final|foldable|flushable|inline|recursive)(?=\s)/,
262
+ 'Keyword'
263
+
264
+ # words, to be postprocessed for builtins and things
265
+ rule /\S+/, 'Postprocess.Word'
266
+ end
267
+
268
+ state :stack_effect do
269
+ rule /\s+/, 'Text'
270
+ rule /\(/, 'Name.Function', :stack_effect
271
+ rule /\)/, 'Name.Function', :pop!
272
+
273
+ rule /--/, 'Name.Function'
274
+ rule /\S+/, 'Name.Variable'
275
+ end
276
+
277
+ state :slots do
278
+ rule /\s+/, 'Text'
279
+ rule /;(?=\s)/, 'Keyword', :pop!
280
+ rule /\S+/, 'Name.Variable'
281
+ end
282
+
283
+ state :import do
284
+ rule /;(?=\s)/, 'Keyword', :pop!
285
+ rule /\s+/, 'Text'
286
+ rule /\S+/, 'Name.Namespace'
287
+ end
288
+
289
+ postprocess 'Postprocess.Word' do |tok, val|
290
+ tok = if self.class.builtins.values.any? { |b| b.include? val }
291
+ 'Name.Builtin'
292
+ else
293
+ 'Name'
294
+ end
295
+
296
+ token tok, val
297
+ end
298
+ end
299
+ end
300
+ end
@@ -0,0 +1,238 @@
1
+ module Rouge
2
+ module Lexers
3
+ class Haml < RegexLexer
4
+ tag 'haml'
5
+ aliases 'HAML'
6
+
7
+ filenames '*.haml'
8
+ mimetypes 'text/x-haml'
9
+
10
+ def self.analyze_text(text)
11
+ return 0.1 if text.start_with? '!!!'
12
+ end
13
+
14
+ # option :filters is a hash of filter name to lexer of how
15
+ # various filters should be highlighted. By default, :javascript
16
+ # and :stylesheet are supported.
17
+ def initialize(opts={})
18
+ (opts.delete(:filters) || {}).each do |name, lexer|
19
+ unless lexer.respond_to? :lex
20
+ lexer = Lexer.find(lexer) or raise "unknown lexer: #{lexer}"
21
+ lexer = lexer.new(options)
22
+ end
23
+
24
+ self.filters[name.to_s] = lexer
25
+ end
26
+
27
+ super(opts)
28
+ end
29
+
30
+ def ruby
31
+ @ruby ||= Ruby.new(options)
32
+ end
33
+
34
+ def html
35
+ @html ||= HTML.new(options)
36
+ end
37
+
38
+ def filters
39
+ @filters ||= {
40
+ 'javascript' => Javascript.new(options),
41
+ 'css' => CSS.new(options),
42
+ 'ruby' => ruby,
43
+ 'erb' => ERB.new(options),
44
+ # TODO
45
+ # 'sass' => Sass.new(options),
46
+ # 'textile' => Textile.new(options),
47
+ # 'markdown' => Markdown.new(options),
48
+ # 'maruku' => Maruku.new(options),
49
+ }
50
+ end
51
+
52
+ start { ruby.reset!; html.reset! }
53
+
54
+ # push a state for the next indented block
55
+ def starts_block(block_state)
56
+ @block_state = block_state
57
+ @block_indentation = @last_indentation || ''
58
+ debug { " haml: starts_block #{block_state.inspect}" }
59
+ debug { " haml: block_indentation: #{@block_indentation.inspect}" }
60
+ end
61
+
62
+ def indentation(indent_str)
63
+ debug { " haml: indentation #{indent_str.inspect}" }
64
+ debug { " haml: block_indentation: #{@block_indentation.inspect}" }
65
+ @last_indentation = indent_str
66
+
67
+ # if it's an indent and we know where to go next,
68
+ # push that state. otherwise, push content and
69
+ # clear the block state.
70
+ if (@block_state &&
71
+ indent_str.start_with?(@block_indentation) &&
72
+ indent_str != @block_indentation
73
+ )
74
+ push @block_state
75
+ else
76
+ @block_state = @block_indentation = nil
77
+ push :content
78
+ end
79
+ end
80
+
81
+ identifier = /[\w:-]+/
82
+ ruby_var = /[a-z]\w*/
83
+
84
+ # Haml can include " |\n" anywhere,
85
+ # which is ignored and used to wrap long lines.
86
+ # To accomodate this, use this custom faux dot instead.
87
+ dot = /[ ]\|\n(?=.*[ ]\|)|./
88
+
89
+ # In certain places, a comma at the end of the line
90
+ # allows line wrapping as well.
91
+ comma_dot = /,\s*\n|#{dot}/
92
+
93
+ state :root do
94
+ rule /\s*\n/, 'Text'
95
+ rule(/\s*/) { |m| token 'Text'; indentation(m[0]) }
96
+ end
97
+
98
+ state :content do
99
+ mixin :css
100
+ rule(/%#{identifier}/) { token 'Name.Tag'; pop!; push :tag }
101
+ rule /!!!#{dot}*\n/, 'Name.Namespace', :pop!
102
+ rule %r(
103
+ (/) (\[#{dot}*?\]) (#{dot}*\n)
104
+ )x do
105
+ group 'Comment'; group 'Comment.Special'; group 'Comment'
106
+ pop!
107
+ end
108
+
109
+ rule %r(/#{dot}*\n) do
110
+ token 'Comment'
111
+ pop!
112
+ starts_block :html_comment_block
113
+ end
114
+
115
+ rule /-##{dot}*\n/ do
116
+ token 'Comment'
117
+ pop!
118
+ starts_block :haml_comment_block
119
+ end
120
+
121
+ rule /-/ do
122
+ token 'Punctuation'
123
+ reset_stack
124
+ push :ruby_line
125
+ end
126
+
127
+ # filters
128
+ rule /:(#{dot}*)\n/ do |m|
129
+ token 'Name.Decorator'
130
+ pop!
131
+ starts_block :filter_block
132
+
133
+ filter_name = m[1].strip
134
+
135
+ @filter_lexer = self.filters[filter_name]
136
+ @filter_lexer.reset! unless @filter_lexer.nil?
137
+
138
+ debug { " haml: filter #{filter_name.inspect} #{@filter_lexer.inspect}" }
139
+ end
140
+
141
+ mixin :eval_or_plain
142
+ end
143
+
144
+ state :css do
145
+ rule(/\.#{identifier}/) { token 'Name.Class'; pop!; push :tag }
146
+ rule(/##{identifier}/) { token 'Name.Function'; pop!; push :tag }
147
+ end
148
+
149
+ state :tag do
150
+ mixin :css
151
+ rule(/\{#{comma_dot}*?\}/) { delegate ruby }
152
+ rule(/\[#{dot}*?\]/) { delegate ruby }
153
+ rule /\(/, 'Punctuation', :html_attributes
154
+ rule /\s*\n/, 'Text', :pop!
155
+
156
+ # whitespace chompers
157
+ rule /[<>]{1,2}(?=[ \t=])/, 'Punctuation'
158
+
159
+ mixin :eval_or_plain
160
+ end
161
+
162
+ state :plain do
163
+ rule(/([^#\n]|#[^{\n]|(\\\\)*\\#\{)+/) { delegate html }
164
+ mixin :interpolation
165
+ rule(/\n/) { token 'Text'; reset_stack }
166
+ end
167
+
168
+ state :eval_or_plain do
169
+ rule /[&!]?==/, 'Punctuation', :plain
170
+ rule /[&!]?[=!]/ do
171
+ token 'Punctuation'
172
+ reset_stack
173
+ push :ruby_line
174
+ end
175
+
176
+ rule(//) { push :plain }
177
+ end
178
+
179
+ state :ruby_line do
180
+ rule /\n/, 'Text', :pop!
181
+ rule(/,[ \t]*\n/) { delegate ruby }
182
+ rule /[ ]\|[ \t]*\n/, 'Literal.String.Escape'
183
+ rule(/.*?(?=(,$| \|)?[ \t]*$)/) { delegate ruby }
184
+ end
185
+
186
+ state :html_attributes do
187
+ rule /\s+/, 'Text'
188
+ rule /#{identifier}\s*=/, 'Name.Attribute', :html_attribute_value
189
+ rule identifier, 'Name.Attribute'
190
+ rule /\)/, 'Text', :pop!
191
+ end
192
+
193
+ state :html_attribute_value do
194
+ rule /\s+/, 'Text'
195
+ rule ruby_var, 'Name.Variable', :pop!
196
+ rule /@#{ruby_var}/, 'Name.Variable.Instance', :pop!
197
+ rule /\$#{ruby_var}/, 'Name.Variable.Global', :pop!
198
+ rule /'(\\\\|\\'|[^'\n])*'/, 'Literal.String', :pop!
199
+ rule /"(\\\\|\\"|[^"\n])*"/, 'Literal.String', :pop!
200
+ end
201
+
202
+ state :html_comment_block do
203
+ rule /#{dot}+/, 'Comment'
204
+ mixin :indented_block
205
+ end
206
+
207
+ state :haml_comment_block do
208
+ rule /#{dot}+/, 'Comment.Preproc'
209
+ mixin :indented_block
210
+ end
211
+
212
+ state :filter_block do
213
+ rule /([^#\n]|#[^{\n]|(\\\\)*\\#\{)+/ do
214
+ if @filter_lexer
215
+ delegate @filter_lexer
216
+ else
217
+ token 'Name.Decorator'
218
+ end
219
+ end
220
+
221
+ mixin :interpolation
222
+ mixin :indented_block
223
+ end
224
+
225
+ state :interpolation do
226
+ rule /(#\{)(#{dot}*?)(\})/ do |m|
227
+ token 'Literal.String.Interpol', m[1]
228
+ delegate ruby, m[2]
229
+ token 'Literal.String.Interpol', m[3]
230
+ end
231
+ end
232
+
233
+ state :indented_block do
234
+ rule(/\n/) { token 'Text'; reset_stack }
235
+ end
236
+ end
237
+ end
238
+ end