coderay 1.0.9 → 1.1.0.rc1
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.
- checksums.yaml +7 -0
- data/Rakefile +2 -0
- data/bin/coderay +4 -4
- data/lib/coderay.rb +2 -3
- data/lib/coderay/encoders/debug.rb +5 -17
- data/lib/coderay/encoders/debug_lint.rb +62 -0
- data/lib/coderay/encoders/html.rb +84 -84
- data/lib/coderay/encoders/html/css.rb +7 -7
- data/lib/coderay/encoders/html/numbering.rb +24 -19
- data/lib/coderay/encoders/html/output.rb +1 -1
- data/lib/coderay/encoders/lint.rb +57 -0
- data/lib/coderay/encoders/statistic.rb +0 -1
- data/lib/coderay/encoders/terminal.rb +121 -105
- data/lib/coderay/helpers/file_type.rb +54 -47
- data/lib/coderay/helpers/plugin.rb +4 -13
- data/lib/coderay/scanner.rb +58 -26
- data/lib/coderay/scanners/c.rb +1 -1
- data/lib/coderay/scanners/cpp.rb +1 -1
- data/lib/coderay/scanners/css.rb +22 -25
- data/lib/coderay/scanners/diff.rb +53 -31
- data/lib/coderay/scanners/groovy.rb +17 -4
- data/lib/coderay/scanners/html.rb +38 -16
- data/lib/coderay/scanners/java.rb +1 -1
- data/lib/coderay/scanners/java_script.rb +30 -6
- data/lib/coderay/scanners/json.rb +15 -12
- data/lib/coderay/scanners/lua.rb +280 -0
- data/lib/coderay/scanners/php.rb +22 -4
- data/lib/coderay/scanners/python.rb +3 -3
- data/lib/coderay/scanners/raydebug.rb +8 -8
- data/lib/coderay/scanners/ruby.rb +2 -2
- data/lib/coderay/scanners/sass.rb +232 -0
- data/lib/coderay/scanners/sql.rb +7 -4
- data/lib/coderay/scanners/taskpaper.rb +36 -0
- data/lib/coderay/scanners/yaml.rb +2 -2
- data/lib/coderay/styles/alpha.rb +31 -21
- data/lib/coderay/token_kinds.rb +68 -71
- data/lib/coderay/tokens.rb +23 -77
- data/lib/coderay/version.rb +1 -1
- data/test/functional/examples.rb +3 -3
- data/test/functional/for_redcloth.rb +4 -10
- metadata +13 -14
- data/lib/coderay/helpers/gzip.rb +0 -41
@@ -131,7 +131,7 @@ module CodeRay
|
|
131
131
|
|
132
132
|
# A Hash of plugion_id => Plugin pairs.
|
133
133
|
def plugin_hash
|
134
|
-
@plugin_hash ||= make_plugin_hash
|
134
|
+
@plugin_hash ||= (@plugin_hash = make_plugin_hash).tap { load_plugin_map }
|
135
135
|
end
|
136
136
|
|
137
137
|
# Returns an array of all .rb files in the plugin path.
|
@@ -158,7 +158,6 @@ module CodeRay
|
|
158
158
|
# This is done automatically when plugin_path is called.
|
159
159
|
def load_plugin_map
|
160
160
|
mapfile = path_to '_map'
|
161
|
-
@plugin_map_loaded = true
|
162
161
|
if File.exist? mapfile
|
163
162
|
require mapfile
|
164
163
|
true
|
@@ -171,23 +170,16 @@ module CodeRay
|
|
171
170
|
|
172
171
|
# Return a plugin hash that automatically loads plugins.
|
173
172
|
def make_plugin_hash
|
174
|
-
@plugin_map_loaded ||= false
|
175
173
|
Hash.new do |h, plugin_id|
|
176
174
|
id = validate_id(plugin_id)
|
177
175
|
path = path_to id
|
178
176
|
begin
|
179
177
|
require path
|
180
178
|
rescue LoadError => boom
|
181
|
-
if
|
182
|
-
|
183
|
-
warn '%p could not load plugin %p; falling back to %p' % [self, id, h[:default]]
|
184
|
-
h[:default]
|
185
|
-
else
|
186
|
-
raise PluginNotFound, '%p could not load plugin %p: %s' % [self, id, boom]
|
187
|
-
end
|
179
|
+
if h.has_key?(:default)
|
180
|
+
h[:default]
|
188
181
|
else
|
189
|
-
|
190
|
-
h[plugin_id]
|
182
|
+
raise PluginNotFound, '%p could not load plugin %p: %s' % [self, id, boom]
|
191
183
|
end
|
192
184
|
else
|
193
185
|
# Plugin should have registered by now
|
@@ -271,7 +263,6 @@ module CodeRay
|
|
271
263
|
end
|
272
264
|
|
273
265
|
def aliases
|
274
|
-
plugin_host.load_plugin_map
|
275
266
|
plugin_host.plugin_hash.inject [] do |aliases, (key, _)|
|
276
267
|
aliases << key if plugin_host[key] == self
|
277
268
|
aliases
|
data/lib/coderay/scanner.rb
CHANGED
@@ -182,16 +182,9 @@ module CodeRay
|
|
182
182
|
# Scan the code and returns all tokens in a Tokens object.
|
183
183
|
def tokenize source = nil, options = {}
|
184
184
|
options = @options.merge(options)
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
when Array
|
189
|
-
self.string = self.class.normalize(source.join)
|
190
|
-
when nil
|
191
|
-
reset
|
192
|
-
else
|
193
|
-
self.string = self.class.normalize(source)
|
194
|
-
end
|
185
|
+
|
186
|
+
set_tokens_from_options options
|
187
|
+
set_string_from_source source
|
195
188
|
|
196
189
|
begin
|
197
190
|
scan_tokens @tokens, options
|
@@ -261,6 +254,22 @@ module CodeRay
|
|
261
254
|
def setup # :doc:
|
262
255
|
end
|
263
256
|
|
257
|
+
def set_string_from_source source
|
258
|
+
case source
|
259
|
+
when Array
|
260
|
+
self.string = self.class.normalize(source.join)
|
261
|
+
when nil
|
262
|
+
reset
|
263
|
+
else
|
264
|
+
self.string = self.class.normalize(source)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
def set_tokens_from_options options
|
269
|
+
@tokens = options[:tokens] || @tokens || Tokens.new
|
270
|
+
@tokens.scanner = self if @tokens.respond_to? :scanner=
|
271
|
+
end
|
272
|
+
|
264
273
|
# This is the central method, and commonly the only one a
|
265
274
|
# subclass implements.
|
266
275
|
#
|
@@ -277,19 +286,15 @@ module CodeRay
|
|
277
286
|
@binary_string = nil if defined? @binary_string
|
278
287
|
end
|
279
288
|
|
280
|
-
|
281
|
-
def raise_inspect msg, tokens, state = self.state || 'No state given!', ambit = 30, backtrace = caller
|
282
|
-
raise ScanError, <<-EOE % [
|
289
|
+
SCAN_ERROR_MESSAGE = <<-MESSAGE
|
283
290
|
|
284
291
|
|
285
|
-
***ERROR in %s: %s (after %
|
292
|
+
***ERROR in %s: %s (after %s tokens)
|
286
293
|
|
287
294
|
tokens:
|
288
295
|
%s
|
289
296
|
|
290
|
-
|
291
|
-
matched: %p state: %p
|
292
|
-
bol? = %p, eos? = %p
|
297
|
+
%s
|
293
298
|
|
294
299
|
surrounding code:
|
295
300
|
%p ~~ %p
|
@@ -297,16 +302,43 @@ surrounding code:
|
|
297
302
|
|
298
303
|
***ERROR***
|
299
304
|
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
305
|
+
MESSAGE
|
306
|
+
|
307
|
+
def raise_inspect_arguments message, tokens, state, ambit
|
308
|
+
return File.basename(caller[0]),
|
309
|
+
message,
|
310
|
+
tokens_size(tokens),
|
311
|
+
tokens_last(tokens, 10).map(&:inspect).join("\n"),
|
312
|
+
scanner_state_info(state),
|
307
313
|
binary_string[pos - ambit, ambit],
|
308
|
-
binary_string[pos, ambit]
|
309
|
-
|
314
|
+
binary_string[pos, ambit]
|
315
|
+
end
|
316
|
+
|
317
|
+
SCANNER_STATE_INFO = <<-INFO
|
318
|
+
current line: %d column: %d pos: %d
|
319
|
+
matched: %p state: %p
|
320
|
+
bol?: %p, eos?: %p
|
321
|
+
INFO
|
322
|
+
|
323
|
+
def scanner_state_info state
|
324
|
+
SCANNER_STATE_INFO % [
|
325
|
+
line, column, pos,
|
326
|
+
matched, state || 'No state given!',
|
327
|
+
bol?, eos?,
|
328
|
+
]
|
329
|
+
end
|
330
|
+
|
331
|
+
# Scanner error with additional status information
|
332
|
+
def raise_inspect message, tokens, state = self.state, ambit = 30, backtrace = caller
|
333
|
+
raise ScanError, SCAN_ERROR_MESSAGE % raise_inspect_arguments(message, tokens, state, ambit), backtrace
|
334
|
+
end
|
335
|
+
|
336
|
+
def tokens_size tokens
|
337
|
+
tokens.size if tokens.respond_to?(:size)
|
338
|
+
end
|
339
|
+
|
340
|
+
def tokens_last tokens, n
|
341
|
+
tokens.respond_to?(:last) ? tokens.last(n) : []
|
310
342
|
end
|
311
343
|
|
312
344
|
# Shorthand for scan_until(/\z/).
|
data/lib/coderay/scanners/c.rb
CHANGED
@@ -148,7 +148,7 @@ module Scanners
|
|
148
148
|
encoder.text_token match, :char
|
149
149
|
elsif match = scan(/ \\ | $ /x)
|
150
150
|
encoder.end_group :string
|
151
|
-
encoder.text_token match, :error
|
151
|
+
encoder.text_token match, :error unless match.empty?
|
152
152
|
state = :initial
|
153
153
|
label_expected = false
|
154
154
|
else
|
data/lib/coderay/scanners/cpp.rb
CHANGED
@@ -160,7 +160,7 @@ module Scanners
|
|
160
160
|
encoder.text_token match, :char
|
161
161
|
elsif match = scan(/ \\ | $ /x)
|
162
162
|
encoder.end_group :string
|
163
|
-
encoder.text_token match, :error
|
163
|
+
encoder.text_token match, :error unless match.empty?
|
164
164
|
state = :initial
|
165
165
|
label_expected = false
|
166
166
|
else
|
data/lib/coderay/scanners/css.rb
CHANGED
@@ -7,27 +7,25 @@ module Scanners
|
|
7
7
|
|
8
8
|
KINDS_NOT_LOC = [
|
9
9
|
:comment,
|
10
|
-
:class, :pseudo_class, :
|
11
|
-
:
|
10
|
+
:class, :pseudo_class, :tag,
|
11
|
+
:id, :directive,
|
12
12
|
:key, :value, :operator, :color, :float, :string,
|
13
|
-
:error, :important,
|
13
|
+
:error, :important, :type,
|
14
14
|
] # :nodoc:
|
15
15
|
|
16
16
|
module RE # :nodoc:
|
17
17
|
Hex = /[0-9a-fA-F]/
|
18
|
-
Unicode = /\\#{Hex}{1,6}
|
19
|
-
Escape = /#{Unicode}|\\[^\
|
20
|
-
NMChar = /[-_a-zA-Z0-9]
|
21
|
-
NMStart = /[_a-zA-Z]
|
22
|
-
|
23
|
-
|
24
|
-
String2 = /'(?:[^\n\r\f\\']|\\#{NL}|#{Escape})*'?/ # TODO: buggy regexp
|
18
|
+
Unicode = /\\#{Hex}{1,6}\b/ # differs from standard because it allows uppercase hex too
|
19
|
+
Escape = /#{Unicode}|\\[^\n0-9a-fA-F]/
|
20
|
+
NMChar = /[-_a-zA-Z0-9]/
|
21
|
+
NMStart = /[_a-zA-Z]/
|
22
|
+
String1 = /"(?:[^\n\\"]+|\\\n|#{Escape})*"?/ # TODO: buggy regexp
|
23
|
+
String2 = /'(?:[^\n\\']+|\\\n|#{Escape})*'?/ # TODO: buggy regexp
|
25
24
|
String = /#{String1}|#{String2}/
|
26
25
|
|
27
26
|
HexColor = /#(?:#{Hex}{6}|#{Hex}{3})/
|
28
|
-
Color = /#{HexColor}/
|
29
27
|
|
30
|
-
Num = /-?(?:[0-9]
|
28
|
+
Num = /-?(?:[0-9]*\.[0-9]+|[0-9]+)n?/
|
31
29
|
Name = /#{NMChar}+/
|
32
30
|
Ident = /-?#{NMStart}#{NMChar}*/
|
33
31
|
AtKeyword = /@#{Ident}/
|
@@ -35,16 +33,15 @@ module Scanners
|
|
35
33
|
|
36
34
|
reldimensions = %w[em ex px]
|
37
35
|
absdimensions = %w[in cm mm pt pc]
|
38
|
-
Unit = Regexp.union(*(reldimensions + absdimensions + %w[s]))
|
36
|
+
Unit = Regexp.union(*(reldimensions + absdimensions + %w[s dpi dppx deg]))
|
39
37
|
|
40
38
|
Dimension = /#{Num}#{Unit}/
|
41
39
|
|
42
|
-
|
43
|
-
Function = /(?:url|alpha|attr|counters?)\((?:[^)\n\r\f]|\\\))*\)?/
|
40
|
+
Function = /(?:url|alpha|attr|counters?)\((?:[^)\n]|\\\))*\)?/
|
44
41
|
|
45
|
-
Id =
|
42
|
+
Id = /(?!#{HexColor}\b(?!-))##{Name}/
|
46
43
|
Class = /\.#{Name}/
|
47
|
-
PseudoClass =
|
44
|
+
PseudoClass = /::?#{Ident}/
|
48
45
|
AttributeSelector = /\[[^\]]*\]?/
|
49
46
|
end
|
50
47
|
|
@@ -52,11 +49,11 @@ module Scanners
|
|
52
49
|
|
53
50
|
def setup
|
54
51
|
@state = :initial
|
55
|
-
@value_expected =
|
52
|
+
@value_expected = false
|
56
53
|
end
|
57
54
|
|
58
55
|
def scan_tokens encoder, options
|
59
|
-
states = Array(options[:state] || @state)
|
56
|
+
states = Array(options[:state] || @state).dup
|
60
57
|
value_expected = @value_expected
|
61
58
|
|
62
59
|
until eos?
|
@@ -67,13 +64,13 @@ module Scanners
|
|
67
64
|
elsif case states.last
|
68
65
|
when :initial, :media
|
69
66
|
if match = scan(/(?>#{RE::Ident})(?!\()|\*/ox)
|
70
|
-
encoder.text_token match, :
|
67
|
+
encoder.text_token match, :tag
|
71
68
|
next
|
72
69
|
elsif match = scan(RE::Class)
|
73
70
|
encoder.text_token match, :class
|
74
71
|
next
|
75
72
|
elsif match = scan(RE::Id)
|
76
|
-
encoder.text_token match, :
|
73
|
+
encoder.text_token match, :id
|
77
74
|
next
|
78
75
|
elsif match = scan(RE::PseudoClass)
|
79
76
|
encoder.text_token match, :pseudo_class
|
@@ -148,17 +145,17 @@ module Scanners
|
|
148
145
|
start = match[/^\w+\(/]
|
149
146
|
encoder.text_token start, :delimiter
|
150
147
|
if match[-1] == ?)
|
151
|
-
encoder.text_token match[start.size..-2], :content
|
148
|
+
encoder.text_token match[start.size..-2], :content if match.size > start.size + 1
|
152
149
|
encoder.text_token ')', :delimiter
|
153
150
|
else
|
154
|
-
encoder.text_token match[start.size..-1], :content
|
151
|
+
encoder.text_token match[start.size..-1], :content if match.size > start.size
|
155
152
|
end
|
156
153
|
encoder.end_group :function
|
157
154
|
|
158
155
|
elsif match = scan(/(?: #{RE::Dimension} | #{RE::Percentage} | #{RE::Num} )/ox)
|
159
156
|
encoder.text_token match, :float
|
160
157
|
|
161
|
-
elsif match = scan(/#{RE::
|
158
|
+
elsif match = scan(/#{RE::HexColor}/o)
|
162
159
|
encoder.text_token match, :color
|
163
160
|
|
164
161
|
elsif match = scan(/! *important/)
|
@@ -170,7 +167,7 @@ module Scanners
|
|
170
167
|
elsif match = scan(RE::AtKeyword)
|
171
168
|
encoder.text_token match, :directive
|
172
169
|
|
173
|
-
elsif match = scan(/ [
|
170
|
+
elsif match = scan(/ [+>~:;,.=()\/] /x)
|
174
171
|
if match == ':'
|
175
172
|
value_expected = true
|
176
173
|
elsif match == ';'
|
@@ -20,7 +20,7 @@ module Scanners
|
|
20
20
|
|
21
21
|
line_kind = nil
|
22
22
|
state = :initial
|
23
|
-
|
23
|
+
deleted_lines_count = 0
|
24
24
|
scanners = Hash.new do |h, lang|
|
25
25
|
h[lang] = Scanners[lang].new '', :keep_tokens => true, :keep_state => true
|
26
26
|
end
|
@@ -30,7 +30,7 @@ module Scanners
|
|
30
30
|
until eos?
|
31
31
|
|
32
32
|
if match = scan(/\n/)
|
33
|
-
|
33
|
+
deleted_lines_count = 0 unless line_kind == :delete
|
34
34
|
if line_kind
|
35
35
|
encoder.end_line line_kind
|
36
36
|
line_kind = nil
|
@@ -45,7 +45,7 @@ module Scanners
|
|
45
45
|
if match = scan(/--- |\+\+\+ |=+|_+/)
|
46
46
|
encoder.begin_line line_kind = :head
|
47
47
|
encoder.text_token match, :head
|
48
|
-
if match = scan(
|
48
|
+
if match = scan(/[^\x00\n]+?(?=$|[\t\n]| \(revision)/)
|
49
49
|
encoder.text_token match, :filename
|
50
50
|
if options[:highlight_code] && match != '/dev/null'
|
51
51
|
file_type = CodeRay::FileType.fetch(match, :text)
|
@@ -69,7 +69,7 @@ module Scanners
|
|
69
69
|
state = :added
|
70
70
|
elsif match = scan(/\\ .*/)
|
71
71
|
encoder.text_token match, :comment
|
72
|
-
elsif match = scan(/@@(?>[^@\n]
|
72
|
+
elsif match = scan(/@@(?>[^@\n]+)@@/)
|
73
73
|
content_scanner.state = :initial unless match?(/\n\+/)
|
74
74
|
content_scanner_entry_state = nil
|
75
75
|
if check(/\n|$/)
|
@@ -99,37 +99,59 @@ module Scanners
|
|
99
99
|
end
|
100
100
|
next
|
101
101
|
elsif match = scan(/-/)
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
102
|
+
deleted_lines_count += 1
|
103
|
+
if options[:inline_diff] && deleted_lines_count == 1 && (changed_lines_count = 1 + check(/.*(?:\n\-.*)*/).count("\n")) && match?(/(?>.*(?:\n\-.*){#{changed_lines_count - 1}}(?:\n\+.*){#{changed_lines_count}})$(?!\n\+)/)
|
104
|
+
deleted_lines = Array.new(changed_lines_count) { |i| skip(/\n\-/) if i > 0; scan(/.*/) }
|
105
|
+
inserted_lines = Array.new(changed_lines_count) { |i| skip(/\n\+/) ; scan(/.*/) }
|
106
|
+
|
107
|
+
deleted_lines_tokenized = []
|
108
|
+
inserted_lines_tokenized = []
|
109
|
+
for deleted_line, inserted_line in deleted_lines.zip(inserted_lines)
|
110
|
+
pre, deleted_part, inserted_part, post = diff deleted_line, inserted_line
|
111
|
+
content_scanner_entry_state = content_scanner.state
|
112
|
+
deleted_lines_tokenized << content_scanner.tokenize([pre, deleted_part, post], :tokens => Tokens.new)
|
113
|
+
content_scanner.state = content_scanner_entry_state || :initial
|
114
|
+
inserted_lines_tokenized << content_scanner.tokenize([pre, inserted_part, post], :tokens => Tokens.new)
|
115
115
|
end
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
encoder.tokens
|
127
|
-
encoder.
|
116
|
+
|
117
|
+
for pre, deleted_part, post in deleted_lines_tokenized
|
118
|
+
encoder.begin_line :delete
|
119
|
+
encoder.text_token '-', :delete
|
120
|
+
encoder.tokens pre
|
121
|
+
unless deleted_part.empty?
|
122
|
+
encoder.begin_group :eyecatcher
|
123
|
+
encoder.tokens deleted_part
|
124
|
+
encoder.end_group :eyecatcher
|
125
|
+
end
|
126
|
+
encoder.tokens post
|
127
|
+
encoder.end_line :delete
|
128
|
+
encoder.text_token "\n", :space
|
129
|
+
end
|
130
|
+
|
131
|
+
for pre, inserted_part, post in inserted_lines_tokenized
|
132
|
+
encoder.begin_line :insert
|
133
|
+
encoder.text_token '+', :insert
|
134
|
+
encoder.tokens pre
|
135
|
+
unless inserted_part.empty?
|
136
|
+
encoder.begin_group :eyecatcher
|
137
|
+
encoder.tokens inserted_part
|
138
|
+
encoder.end_group :eyecatcher
|
139
|
+
end
|
140
|
+
encoder.tokens post
|
141
|
+
changed_lines_count -= 1
|
142
|
+
if changed_lines_count > 0
|
143
|
+
encoder.end_line :insert
|
144
|
+
encoder.text_token "\n", :space
|
145
|
+
end
|
128
146
|
end
|
129
|
-
|
147
|
+
|
148
|
+
line_kind = :insert
|
149
|
+
|
130
150
|
elsif match = scan(/.*/)
|
151
|
+
encoder.begin_line line_kind = :delete
|
152
|
+
encoder.text_token '-', :delete
|
131
153
|
if options[:highlight_code]
|
132
|
-
if
|
154
|
+
if deleted_lines_count == 1
|
133
155
|
content_scanner_entry_state = content_scanner.state
|
134
156
|
end
|
135
157
|
content_scanner.tokenize match, :tokens => encoder unless match.empty?
|
@@ -36,9 +36,12 @@ module Scanners
|
|
36
36
|
|
37
37
|
protected
|
38
38
|
|
39
|
+
def setup
|
40
|
+
@state = :initial
|
41
|
+
end
|
42
|
+
|
39
43
|
def scan_tokens encoder, options
|
40
|
-
|
41
|
-
state = :initial
|
44
|
+
state = options[:state] || @state
|
42
45
|
inline_block_stack = []
|
43
46
|
inline_block_paren_depth = nil
|
44
47
|
string_delimiter = nil
|
@@ -223,7 +226,7 @@ module Scanners
|
|
223
226
|
encoder.text_token match, :content # TODO: Shouldn't this be :error?
|
224
227
|
|
225
228
|
elsif match = scan(/ \\ | \n /x)
|
226
|
-
encoder.end_group state
|
229
|
+
encoder.end_group state == :regexp ? :regexp : :string
|
227
230
|
encoder.text_token match, :error
|
228
231
|
after_def = value_expected = false
|
229
232
|
state = :initial
|
@@ -243,7 +246,17 @@ module Scanners
|
|
243
246
|
end
|
244
247
|
|
245
248
|
if [:multiline_string, :string, :regexp].include? state
|
246
|
-
encoder.end_group state
|
249
|
+
encoder.end_group state == :regexp ? :regexp : :string
|
250
|
+
end
|
251
|
+
|
252
|
+
if options[:keep_state]
|
253
|
+
@state = state
|
254
|
+
end
|
255
|
+
|
256
|
+
until inline_block_stack.empty?
|
257
|
+
state, = *inline_block_stack.pop
|
258
|
+
encoder.end_group :inline
|
259
|
+
encoder.end_group state == :regexp ? :regexp : :string
|
247
260
|
end
|
248
261
|
|
249
262
|
encoder
|