Skip to content

Commit 3a7ce14

Browse files
committed
Issue jeromegn#48: improve handling of special chars
1 parent f33c23b commit 3a7ce14

File tree

5 files changed

+34
-12
lines changed

5 files changed

+34
-12
lines changed

Diff for: spec/fixtures/attribute-wrappers.slang

+3-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@ div(hello="world" foo="bar")
33
div[hello="world" foo="bar"]
44
div(hello=Process.pid)
55
div{hello="world" foo="bar"}
6-
div{hello="#{"world"}" foo="bar"}
6+
div{hello="world\u0021" foo="bar"}
7+
div{hello="#{"world"}" foo="bar"}
8+
div{hello="#{"world\u0021"}" foo="bar"}

Diff for: spec/fixtures/script.slang

+6-1
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,9 @@ javascript:
1414
something
1515
</div>
1616
`
17-
})
17+
})
18+
19+
javascript:
20+
let twoLines = "bar\nbaz";
21+
let hello = "#{"Hello, " + "world!"}";
22+
let obj = #{{:a => 17, "b" => "foo"}.to_json};

Diff for: spec/fixtures/with_html.slang

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
table
2-
<tr><td>#{Process.pid}</td></tr>
2+
<tr><td>#{Process.pid}</td></tr>
3+
<tr><td>"hello\u0021"</td></tr>

Diff for: spec/slang_spec.cr

+9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require "./spec_helper"
2+
require "json"
23

34
def evaluates_to_true
45
1 == 1
@@ -157,6 +158,7 @@ describe Slang do
157158
res.should eq <<-HTML
158159
<table>
159160
<tr><td>#{Process.pid}</td></tr>
161+
<tr><td>"hello\\u0021"</td></tr>
160162
</table>
161163
HTML
162164
end
@@ -264,6 +266,11 @@ describe Slang do
264266
`
265267
})
266268
</script>
269+
<script>
270+
let twoLines = "bar\\nbaz";
271+
let hello = "Hello, world!";
272+
let obj = {"a":17,"b":"foo"};
273+
</script>
267274
HTML
268275
end
269276
it "renders stylesheets" do
@@ -320,7 +327,9 @@ describe Slang do
320327
<div hello="world" foo="bar"></div>
321328
<div hello="#{Process.pid}"></div>
322329
<div hello="world" foo="bar"></div>
330+
<div hello="world\\u0021" foo="bar"></div>
323331
<div hello="world" foo="bar"></div>
332+
<div hello="world!" foo="bar"></div>
324333
HTML
325334
end
326335
end

Diff for: src/slang/lexer.cr

+14-9
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ module Slang
206206
@token.type = :CONTROL
207207
next_char
208208
next_char if current_char == ' '
209-
@token.value = consume_line
209+
@token.value = consume_line(escape_double_quotes=false)
210210
end
211211

212212
private def consume_output
@@ -228,7 +228,7 @@ module Slang
228228
end
229229

230230
skip_whitespace
231-
@token.value = consume_line.strip
231+
@token.value = consume_line(escape_double_quotes=false).strip
232232
@token.value = " #{@token.value}" if prepend_whitespace
233233
@token.value = "#{@token.value} " if append_whitespace
234234
end
@@ -257,14 +257,14 @@ module Slang
257257
cc = STRING_OPEN_CLOSE_CHARS_MAP[current_char]
258258
str << current_char
259259
next_char
260-
str << consume_string open_char: oc, close_char: cc
260+
str << consume_string open_char: oc, close_char: cc, crystal: true
261261
next
262262
end
263263
if current_char == '"' || current_char == '\''
264264
ch = current_char
265265
str << current_char
266266
next_char
267-
str << consume_string open_char: ch, close_char: ch
267+
str << consume_string open_char: ch, close_char: ch, crystal: true
268268
next
269269
end
270270
if current_char == '}'
@@ -283,7 +283,7 @@ module Slang
283283
end
284284
end
285285

286-
private def consume_string(open_char = '"', close_char = '"', escape_double_quotes = false)
286+
private def consume_string(open_char = '"', close_char = '"', escape_double_quotes = false, crystal = false)
287287
level = 0
288288
escaped = false
289289
maybe_string_interpolation = false
@@ -326,10 +326,11 @@ module Slang
326326
maybe_string_interpolation = true
327327
end
328328

329-
if current_char == '\\' && !escaped
330-
escaped = true
331-
else
329+
if escaped
332330
escaped = false
331+
str << '\\' unless crystal
332+
elsif current_char == '\\'
333+
escaped = true
333334
end
334335

335336
if current_char == '\n' || current_char == '\0'
@@ -348,12 +349,16 @@ module Slang
348349
@token.value = "\"#{consume_line}\""
349350
end
350351

351-
private def consume_line
352+
private def consume_line(escape_double_quotes=true)
352353
String.build do |str|
353354
loop do
354355
if current_char == '\n' || current_char == '\0'
355356
break
356357
else
358+
if escape_double_quotes && (current_char == '"' || current_char == '\\')
359+
str << '\\'
360+
end
361+
357362
str << current_char
358363
next_char
359364
end

0 commit comments

Comments
 (0)