Skip to content

Commit 990ed25

Browse files
committed
split '" string states in Sass scanner (edge case)
1 parent 94e4bb3 commit 990ed25

File tree

1 file changed

+11
-16
lines changed

1 file changed

+11
-16
lines changed

lib/coderay/scanners/sass.rb

+11-16
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,6 @@ class Sass < CSS
77
register_for :sass
88
file_extension 'sass'
99

10-
STRING_CONTENT_PATTERN = {
11-
"'" => /(?:[^\n\'\#]+|\\\n|#{RE::Escape}|#(?!\{))+/,
12-
'"' => /(?:[^\n\"\#]+|\\\n|#{RE::Escape}|#(?!\{))+/,
13-
}
14-
1510
protected
1611

1712
def setup
@@ -20,7 +15,8 @@ def setup
2015

2116
def scan_tokens encoder, options
2217
states = Array(options[:state] || @state).dup
23-
string_delimiter = nil
18+
19+
encoder.begin_group :string if states.last == :sqstring || states.last == :dqstring
2420

2521
until eos?
2622

@@ -91,24 +87,23 @@ def scan_tokens encoder, options
9187
next
9288
end
9389

94-
when :string
95-
if match = scan(STRING_CONTENT_PATTERN[string_delimiter])
90+
when :sqstring, :dqstring
91+
if match = scan(states.last == :sqstring ? /(?:[^\n\'\#]+|\\\n|#{RE::Escape}|#(?!\{))+/o : /(?:[^\n\"\#]+|\\\n|#{RE::Escape}|#(?!\{))+/o)
9692
encoder.text_token match, :content
9793
elsif match = scan(/['"]/)
9894
encoder.text_token match, :delimiter
9995
encoder.end_group :string
100-
string_delimiter = nil
10196
states.pop
10297
elsif match = scan(/#\{/)
10398
encoder.begin_group :inline
10499
encoder.text_token match, :inline_delimiter
105100
states.push :sass_inline
106101
elsif match = scan(/ \\ | $ /x)
107-
encoder.end_group :string
102+
encoder.end_group states.last
108103
encoder.text_token match, :error unless match.empty?
109104
states.pop
110105
else
111-
raise_inspect "else case #{string_delimiter} reached; %p not handled." % peek(1), encoder
106+
raise_inspect "else case #{states.last} reached; %p not handled." % peek(1), encoder
112107
end
113108

114109
when :include
@@ -157,15 +152,15 @@ def scan_tokens encoder, options
157152

158153
elsif match = scan(/['"]/)
159154
encoder.begin_group :string
160-
string_delimiter = match
161155
encoder.text_token match, :delimiter
162156
if states.include? :sass_inline
163-
content = scan_until(/(?=#{string_delimiter}|\}|\z)/)
157+
# no nesting, just scan the string until delimiter
158+
content = scan_until(/(?=#{match}|\}|\z)/)
164159
encoder.text_token content, :content unless content.empty?
165-
encoder.text_token string_delimiter, :delimiter if scan(/#{string_delimiter}/)
160+
encoder.text_token match, :delimiter if scan(/#{match}/)
166161
encoder.end_group :string
167162
else
168-
states.push :string
163+
states.push match == "'" ? :sqstring : :dqstring
169164
end
170165

171166
elsif match = scan(/#{RE::Function}/o)
@@ -221,7 +216,7 @@ def scan_tokens encoder, options
221216
while state = states.pop
222217
if state == :sass_inline
223218
encoder.end_group :inline
224-
elsif state == :string
219+
elsif state == :sqstring || state == :dqstring
225220
encoder.end_group :string
226221
end
227222
end

0 commit comments

Comments
 (0)