fast_haml 0.1.8 → 0.1.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/fast_haml.gemspec +2 -0
- data/lib/fast_haml/compiler.rb +30 -14
- data/lib/fast_haml/element_parser.rb +6 -59
- data/lib/fast_haml/filter_compilers.rb +3 -0
- data/lib/fast_haml/filter_compilers/base.rb +2 -0
- data/lib/fast_haml/filter_compilers/cdata.rb +2 -2
- data/lib/fast_haml/filter_compilers/coffee.rb +14 -0
- data/lib/fast_haml/filter_compilers/css.rb +2 -2
- data/lib/fast_haml/filter_compilers/escaped.rb +2 -2
- data/lib/fast_haml/filter_compilers/javascript.rb +2 -2
- data/lib/fast_haml/filter_compilers/plain.rb +7 -3
- data/lib/fast_haml/filter_compilers/preserve.rb +2 -3
- data/lib/fast_haml/filter_compilers/ruby.rb +1 -1
- data/lib/fast_haml/filter_compilers/sass.rb +14 -0
- data/lib/fast_haml/filter_compilers/scss.rb +14 -0
- data/lib/fast_haml/filter_compilers/tilt_base.rb +36 -0
- data/lib/fast_haml/parser.rb +10 -56
- data/lib/fast_haml/script_parser.rb +84 -0
- data/lib/fast_haml/text_compiler.rb +4 -4
- data/lib/fast_haml/version.rb +1 -1
- data/spec/compiler_newline_spec.rb +41 -0
- data/spec/render/doctype_spec.rb +0 -5
- data/spec/render/filters/coffee_spec.rb +25 -0
- data/spec/render/filters/javascript_spec.rb +1 -1
- data/spec/render/filters/sass_spec.rb +28 -0
- data/spec/render/filters/scss_spec.rb +32 -0
- data/spec/render/unescape_spec.rb +5 -0
- data/spec/spec_helper.rb +0 -2
- metadata +41 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d8aa3367427fc4d33e2ff57ba8f1988f31be1047
|
4
|
+
data.tar.gz: da9216a9d2cc12bfdc92b90a9df75f1912876459
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 53802e8411247cecffb2987fde99ec569dfea66b73a1240ee9a33361f4c2e4ba7a2b13892f1952be33e8b84b75b56de75f93be0c93c40e2029eeeb2df7211a28
|
7
|
+
data.tar.gz: 8ec843e6e5946ae0fefcd3d04c3d7c62649a042a038641c716fc498ae60bdc163645f99503424e4a0191ae4ced649f8c276327671d1f579b478bdc298d319eb1
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
## 0.1.9 (2015-03-18)
|
2
|
+
- Refactor script parser (internal)
|
3
|
+
- Fix newline generation with filters
|
4
|
+
- Support sass, scss and coffee filter
|
5
|
+
|
1
6
|
## 0.1.8 (2015-03-17)
|
2
7
|
- Fix whitespace removal (`<` and `>`) behavior
|
3
8
|
- Internally, new instructions `mknl` and `rmnl` are added.
|
data/fast_haml.gemspec
CHANGED
@@ -26,10 +26,12 @@ Gem::Specification.new do |spec|
|
|
26
26
|
spec.add_development_dependency "appraisal"
|
27
27
|
spec.add_development_dependency "benchmark-ips"
|
28
28
|
spec.add_development_dependency "bundler"
|
29
|
+
spec.add_development_dependency "coffee-script"
|
29
30
|
spec.add_development_dependency "coveralls"
|
30
31
|
spec.add_development_dependency "haml"
|
31
32
|
spec.add_development_dependency "rake"
|
32
33
|
spec.add_development_dependency "rake-compiler"
|
33
34
|
spec.add_development_dependency "rspec", ">= 3"
|
35
|
+
spec.add_development_dependency "sass"
|
34
36
|
spec.add_development_dependency "simplecov"
|
35
37
|
end
|
data/lib/fast_haml/compiler.rb
CHANGED
@@ -168,18 +168,9 @@ module FastHaml
|
|
168
168
|
]
|
169
169
|
|
170
170
|
if ast.oneline_child
|
171
|
-
|
171
|
+
temple << compile(ast.oneline_child)
|
172
172
|
elsif !ast.children.empty?
|
173
|
-
|
174
|
-
unless nuke_inner_whitespace?(ast)
|
175
|
-
children << [:mknl]
|
176
|
-
end
|
177
|
-
children << [:newline]
|
178
|
-
compile_children(ast, children)
|
179
|
-
if nuke_inner_whitespace?(ast)
|
180
|
-
children << [:rmnl]
|
181
|
-
end
|
182
|
-
temple << children
|
173
|
+
temple << compile_element_children(ast)
|
183
174
|
end
|
184
175
|
|
185
176
|
if ast.nuke_outer_whitespace
|
@@ -193,6 +184,19 @@ module FastHaml
|
|
193
184
|
ast.self_closing || options[:autoclose].include?(ast.tag_name)
|
194
185
|
end
|
195
186
|
|
187
|
+
def compile_element_children(ast)
|
188
|
+
children = [:multi]
|
189
|
+
unless nuke_inner_whitespace?(ast)
|
190
|
+
children << [:mknl]
|
191
|
+
end
|
192
|
+
children << [:newline]
|
193
|
+
compile_children(ast, children)
|
194
|
+
if nuke_inner_whitespace?(ast)
|
195
|
+
children << [:rmnl]
|
196
|
+
end
|
197
|
+
children
|
198
|
+
end
|
199
|
+
|
196
200
|
def nuke_inner_whitespace?(ast)
|
197
201
|
ast.nuke_inner_whitespace || options[:preserve].include?(ast.tag_name)
|
198
202
|
end
|
@@ -274,6 +278,16 @@ module FastHaml
|
|
274
278
|
end
|
275
279
|
|
276
280
|
def build_optimized_attributes(parser, static_id, static_class)
|
281
|
+
static_attributes = build_optimized_static_attributes(parser, static_id, static_class)
|
282
|
+
dynamic_attributes = build_optimized_dynamic_attributes(parser, static_attributes)
|
283
|
+
if dynamic_attributes
|
284
|
+
[static_attributes, dynamic_attributes]
|
285
|
+
else
|
286
|
+
[nil, nil]
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
def build_optimized_static_attributes(parser, static_id, static_class)
|
277
291
|
static_attributes = {}
|
278
292
|
parser.static_attributes.each do |k, v|
|
279
293
|
static_attributes[k.to_s] = v
|
@@ -284,20 +298,22 @@ module FastHaml
|
|
284
298
|
unless static_id.empty?
|
285
299
|
static_attributes['id'] = [static_id, static_attributes['id']].compact.join('_')
|
286
300
|
end
|
301
|
+
static_attributes
|
302
|
+
end
|
287
303
|
|
304
|
+
def build_optimized_dynamic_attributes(parser, static_attributes)
|
288
305
|
dynamic_attributes = {}
|
289
306
|
parser.dynamic_attributes.each do |k, v|
|
290
307
|
k = k.to_s
|
291
308
|
if static_attributes.has_key?(k)
|
292
309
|
if StaticHashParser::SPECIAL_ATTRIBUTES.include?(k)
|
293
310
|
# XXX: Quit optimization
|
294
|
-
return
|
311
|
+
return nil
|
295
312
|
end
|
296
313
|
end
|
297
314
|
dynamic_attributes[k] = v
|
298
315
|
end
|
299
|
-
|
300
|
-
[static_attributes, dynamic_attributes]
|
316
|
+
dynamic_attributes
|
301
317
|
end
|
302
318
|
|
303
319
|
def compile_static_attribute(key, value)
|
@@ -2,20 +2,19 @@ require 'strscan'
|
|
2
2
|
require 'fast_haml/ast'
|
3
3
|
require 'fast_haml/parser_utils'
|
4
4
|
require 'fast_haml/ruby_multiline'
|
5
|
+
require 'fast_haml/script_parser'
|
5
6
|
require 'fast_haml/syntax_error'
|
6
7
|
|
7
8
|
module FastHaml
|
8
9
|
class ElementParser
|
9
|
-
def initialize(
|
10
|
-
@text = text
|
11
|
-
@lineno = lineno
|
10
|
+
def initialize(line_parser)
|
12
11
|
@line_parser = line_parser
|
13
12
|
end
|
14
13
|
|
15
14
|
ELEMENT_REGEXP = /\A%([-:\w]+)([-:\w.#]*)(.+)?\z/o
|
16
15
|
|
17
|
-
def parse
|
18
|
-
m =
|
16
|
+
def parse(text)
|
17
|
+
m = text.match(ELEMENT_REGEXP)
|
19
18
|
unless m
|
20
19
|
syntax_error!('Invalid element declaration')
|
21
20
|
end
|
@@ -28,7 +27,7 @@ module FastHaml
|
|
28
27
|
element.attributes, rest = parse_attributes(rest)
|
29
28
|
element.nuke_inner_whitespace, element.nuke_outer_whitespace, rest = parse_nuke_whitespace(rest)
|
30
29
|
element.self_closing, rest = parse_self_closing(rest)
|
31
|
-
element.oneline_child =
|
30
|
+
element.oneline_child = ScriptParser.new(@line_parser).parse(rest)
|
32
31
|
|
33
32
|
element
|
34
33
|
end
|
@@ -229,60 +228,8 @@ module FastHaml
|
|
229
228
|
end
|
230
229
|
end
|
231
230
|
|
232
|
-
def parse_oneline_child(rest)
|
233
|
-
case rest[0]
|
234
|
-
when '=', '~'
|
235
|
-
if rest[1] == '='
|
236
|
-
Ast::Text.new(rest[2 .. -1].strip)
|
237
|
-
else
|
238
|
-
script = rest[1 .. -1].lstrip
|
239
|
-
if script.empty?
|
240
|
-
syntax_error!('No Ruby code to evaluate')
|
241
|
-
end
|
242
|
-
script += RubyMultiline.read(@line_parser, script)
|
243
|
-
Ast::Script.new([], script)
|
244
|
-
end
|
245
|
-
when '&'
|
246
|
-
case
|
247
|
-
when rest.start_with?('&==')
|
248
|
-
Ast::Text.new(rest[3 .. -1].lstrip)
|
249
|
-
when rest[1] == '=' || rest[1] == '~'
|
250
|
-
script = rest[2 .. -1].lstrip
|
251
|
-
if script.empty?
|
252
|
-
syntax_error!('No Ruby code to evaluate')
|
253
|
-
end
|
254
|
-
script += RubyMultiline.read(@line_parser, script)
|
255
|
-
Ast::Script.new([], script, true, rest[1] == '~')
|
256
|
-
else
|
257
|
-
Ast::Text.new(rest[1 .. -1].strip)
|
258
|
-
end
|
259
|
-
when '!'
|
260
|
-
case
|
261
|
-
when rest.start_with?('!==')
|
262
|
-
Ast::Text.new(rest[3 .. -1].lstrip, false)
|
263
|
-
when rest[1] == '=' || rest[1] == '~'
|
264
|
-
script = rest[2 .. -1].lstrip
|
265
|
-
if script.empty?
|
266
|
-
syntax_error!('No Ruby code to evaluate')
|
267
|
-
end
|
268
|
-
script += RubyMultiline.read(@line_parser, script)
|
269
|
-
Ast::Script.new([], script, false, rest[1] == '~')
|
270
|
-
Ast::Script.new([], script, false, true)
|
271
|
-
else
|
272
|
-
Ast::Text.new(rest[1 .. -1].lstrip, false)
|
273
|
-
end
|
274
|
-
else
|
275
|
-
rest = rest.lstrip
|
276
|
-
if rest.empty?
|
277
|
-
nil
|
278
|
-
else
|
279
|
-
Ast::Text.new(rest)
|
280
|
-
end
|
281
|
-
end
|
282
|
-
end
|
283
|
-
|
284
231
|
def syntax_error!(message)
|
285
|
-
raise SyntaxError.new(message, @lineno)
|
232
|
+
raise SyntaxError.new(message, @line_parser.lineno)
|
286
233
|
end
|
287
234
|
end
|
288
235
|
end
|
@@ -29,9 +29,12 @@ module FastHaml
|
|
29
29
|
end
|
30
30
|
|
31
31
|
require 'fast_haml/filter_compilers/cdata'
|
32
|
+
require 'fast_haml/filter_compilers/coffee'
|
32
33
|
require 'fast_haml/filter_compilers/css'
|
33
34
|
require 'fast_haml/filter_compilers/escaped'
|
34
35
|
require 'fast_haml/filter_compilers/javascript'
|
35
36
|
require 'fast_haml/filter_compilers/plain'
|
36
37
|
require 'fast_haml/filter_compilers/preserve'
|
37
38
|
require 'fast_haml/filter_compilers/ruby'
|
39
|
+
require 'fast_haml/filter_compilers/sass'
|
40
|
+
require 'fast_haml/filter_compilers/scss'
|
@@ -7,9 +7,11 @@ module FastHaml
|
|
7
7
|
|
8
8
|
def compile_texts(temple, texts, tab_width: 0)
|
9
9
|
tabs = ' ' * tab_width
|
10
|
+
texts = strip_last_empty_lines(texts)
|
10
11
|
texts.each do |text|
|
11
12
|
temple << [:static, tabs] << text_compiler.compile(text) << [:static, "\n"] << [:newline]
|
12
13
|
end
|
14
|
+
temple.pop # discard last [:newline]
|
13
15
|
nil
|
14
16
|
end
|
15
17
|
|
@@ -4,8 +4,8 @@ module FastHaml
|
|
4
4
|
module FilterCompilers
|
5
5
|
class Cdata < Base
|
6
6
|
def compile(texts)
|
7
|
-
temple = [:multi, [:static, "<![CDATA[\n"]]
|
8
|
-
compile_texts(temple,
|
7
|
+
temple = [:multi, [:static, "<![CDATA[\n"], [:newline]]
|
8
|
+
compile_texts(temple, texts, tab_width: 4)
|
9
9
|
temple << [:static, "]]>"]
|
10
10
|
end
|
11
11
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'fast_haml/filter_compilers/tilt_base'
|
2
|
+
|
3
|
+
module FastHaml
|
4
|
+
module FilterCompilers
|
5
|
+
class Coffee < TiltBase
|
6
|
+
def compile(texts)
|
7
|
+
temple = compile_with_tilt('coffee', texts)
|
8
|
+
[:haml, :tag, 'script', false, [:html, :attrs], [:html, :js, temple]]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
register(:coffee, Coffee)
|
13
|
+
end
|
14
|
+
end
|
@@ -4,8 +4,8 @@ module FastHaml
|
|
4
4
|
module FilterCompilers
|
5
5
|
class Css < Base
|
6
6
|
def compile(texts)
|
7
|
-
temple = [:multi, [:static, "\n"]]
|
8
|
-
compile_texts(temple,
|
7
|
+
temple = [:multi, [:static, "\n"], [:newline]]
|
8
|
+
compile_texts(temple, texts, tab_width: 2)
|
9
9
|
[:haml, :tag, 'style', false, [:html, :attrs], temple]
|
10
10
|
end
|
11
11
|
end
|
@@ -6,8 +6,8 @@ module FastHaml
|
|
6
6
|
include Temple::Utils
|
7
7
|
|
8
8
|
def compile(texts)
|
9
|
-
temple = [:multi]
|
10
|
-
compile_texts(temple,
|
9
|
+
temple = [:multi, [:newline]]
|
10
|
+
compile_texts(temple, texts)
|
11
11
|
escape_code = Temple::Filters::Escapable.new.instance_variable_get(:@escape_code)
|
12
12
|
sym = unique_name
|
13
13
|
[:multi,
|
@@ -4,8 +4,8 @@ module FastHaml
|
|
4
4
|
module FilterCompilers
|
5
5
|
class Javascript < Base
|
6
6
|
def compile(texts)
|
7
|
-
temple = [:multi, [:static, "\n"]]
|
8
|
-
compile_texts(temple,
|
7
|
+
temple = [:multi, [:static, "\n"], [:newline]]
|
8
|
+
compile_texts(temple, texts, tab_width: 2)
|
9
9
|
[:haml, :tag, 'script', false, [:html, :attrs], [:html, :js, temple]]
|
10
10
|
end
|
11
11
|
end
|
@@ -4,10 +4,14 @@ module FastHaml
|
|
4
4
|
module FilterCompilers
|
5
5
|
class Plain < Base
|
6
6
|
def compile(texts)
|
7
|
-
temple = [:multi]
|
7
|
+
temple = [:multi, [:newline]]
|
8
8
|
texts = strip_last_empty_lines(texts)
|
9
|
-
|
10
|
-
|
9
|
+
texts.each do |text|
|
10
|
+
temple << text_compiler.compile(text)
|
11
|
+
unless texts.last.equal?(text)
|
12
|
+
temple << [:static, "\n"] << [:newline]
|
13
|
+
end
|
14
|
+
end
|
11
15
|
temple
|
12
16
|
end
|
13
17
|
end
|
@@ -6,13 +6,12 @@ module FastHaml
|
|
6
6
|
include Temple::Utils
|
7
7
|
|
8
8
|
def compile(texts)
|
9
|
-
temple = [:multi]
|
9
|
+
temple = [:multi, [:newline]]
|
10
10
|
texts.each do |text|
|
11
11
|
temple << text_compiler.compile(text)
|
12
12
|
unless texts.last.equal?(text)
|
13
|
-
temple << [:static, "\n"]
|
13
|
+
temple << [:static, "\n"] << [:newline]
|
14
14
|
end
|
15
|
-
temple << [:newline]
|
16
15
|
end
|
17
16
|
sym = unique_name
|
18
17
|
[:multi,
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'fast_haml/filter_compilers/tilt_base'
|
2
|
+
|
3
|
+
module FastHaml
|
4
|
+
module FilterCompilers
|
5
|
+
class Sass < TiltBase
|
6
|
+
def compile(texts)
|
7
|
+
temple = compile_with_tilt('sass', texts)
|
8
|
+
[:haml, :tag, 'style', false, [:html, :attrs], temple]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
register(:sass, Sass)
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'fast_haml/filter_compilers/tilt_base'
|
2
|
+
|
3
|
+
module FastHaml
|
4
|
+
module FilterCompilers
|
5
|
+
class Scss < TiltBase
|
6
|
+
def compile(texts)
|
7
|
+
temple = compile_with_tilt('scss', texts)
|
8
|
+
[:haml, :tag, 'style', false, [:html, :attrs], temple]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
register(:scss, Scss)
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'temple'
|
2
|
+
require 'tilt'
|
3
|
+
require 'fast_haml/filter_compilers/base'
|
4
|
+
require 'fast_haml/text_compiler'
|
5
|
+
|
6
|
+
module FastHaml
|
7
|
+
module FilterCompilers
|
8
|
+
class TiltBase < Base
|
9
|
+
include Temple::Utils
|
10
|
+
|
11
|
+
def self.render_with_tilt(name, source)
|
12
|
+
::Tilt["t.#{name}"].new { source }.render
|
13
|
+
end
|
14
|
+
|
15
|
+
protected
|
16
|
+
|
17
|
+
def compile_with_tilt(name, texts)
|
18
|
+
source = texts.join("\n")
|
19
|
+
temple = [:multi, [:static, "\n"], [:newline]]
|
20
|
+
if TextCompiler.contains_interpolation?(source)
|
21
|
+
text_temple = [:multi]
|
22
|
+
compile_texts(text_temple, texts)
|
23
|
+
sym = unique_name
|
24
|
+
temple << [:capture, sym, text_temple]
|
25
|
+
temple << [:dynamic, "::FastHaml::FilterCompilers::TiltBase.render_with_tilt(#{name.inspect}, #{sym})"]
|
26
|
+
temple << [:newline]
|
27
|
+
else
|
28
|
+
compiled = self.class.render_with_tilt(name, source)
|
29
|
+
temple << [:static, compiled]
|
30
|
+
temple.concat([[:newline]] * (texts.size - 1))
|
31
|
+
end
|
32
|
+
temple
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/fast_haml/parser.rb
CHANGED
@@ -5,6 +5,7 @@ require 'fast_haml/indent_tracker'
|
|
5
5
|
require 'fast_haml/line_parser'
|
6
6
|
require 'fast_haml/parser_utils'
|
7
7
|
require 'fast_haml/ruby_multiline'
|
8
|
+
require 'fast_haml/script_parser'
|
8
9
|
require 'fast_haml/syntax_error'
|
9
10
|
|
10
11
|
module FastHaml
|
@@ -42,18 +43,14 @@ module FastHaml
|
|
42
43
|
|
43
44
|
private
|
44
45
|
|
45
|
-
|
46
46
|
DOCTYPE_PREFIX = '!'
|
47
47
|
ELEMENT_PREFIX = '%'
|
48
|
-
SCRIPT_PREFIX = '='
|
49
48
|
COMMENT_PREFIX = '/'
|
50
49
|
SILENT_SCRIPT_PREFIX = '-'
|
51
50
|
DIV_ID_PREFIX = '#'
|
52
51
|
DIV_CLASS_PREFIX = '.'
|
53
52
|
FILTER_PREFIX = ':'
|
54
53
|
ESCAPE_PREFIX = '\\'
|
55
|
-
PRESERVE_PREFIX = '~'
|
56
|
-
SANITIZE_PREFIX = '&'
|
57
54
|
|
58
55
|
def parse_line(line)
|
59
56
|
text, indent = @indent_tracker.process(line, @line_parser.lineno)
|
@@ -74,54 +71,25 @@ module FastHaml
|
|
74
71
|
when ELEMENT_PREFIX
|
75
72
|
parse_element(text)
|
76
73
|
when DOCTYPE_PREFIX
|
77
|
-
|
78
|
-
when text.start_with?('!!!')
|
74
|
+
if text.start_with?('!!!')
|
79
75
|
parse_doctype(text)
|
80
|
-
when text.start_with?('!==')
|
81
|
-
parse_plain(text[3 .. -1].lstrip, escape_html: false)
|
82
|
-
when text[1] == SCRIPT_PREFIX
|
83
|
-
parse_script(text)
|
84
|
-
when text[1] == PRESERVE_PREFIX
|
85
|
-
parse_script("!=#{text[2 .. -1].lstrip}", preserve: true)
|
86
|
-
when text[1] == ' '
|
87
|
-
parse_plain(text[1 .. -1].lstrip, escape_html: false)
|
88
76
|
else
|
89
|
-
|
77
|
+
parse_script(text)
|
90
78
|
end
|
91
79
|
when COMMENT_PREFIX
|
92
80
|
parse_comment(text)
|
93
|
-
when SCRIPT_PREFIX
|
94
|
-
if text[1] == SCRIPT_PREFIX
|
95
|
-
parse_plain(text[2 .. -1].strip)
|
96
|
-
else
|
97
|
-
parse_script(text)
|
98
|
-
end
|
99
81
|
when SILENT_SCRIPT_PREFIX
|
100
82
|
parse_silent_script(text)
|
101
|
-
when PRESERVE_PREFIX
|
102
|
-
# preserve has no meaning in non-html_escape mode
|
103
|
-
parse_script(text)
|
104
83
|
when DIV_ID_PREFIX, DIV_CLASS_PREFIX
|
105
84
|
if text.start_with?('#{')
|
106
|
-
|
85
|
+
parse_script(text)
|
107
86
|
else
|
108
87
|
parse_line("#{indent}%div#{text}")
|
109
88
|
end
|
110
89
|
when FILTER_PREFIX
|
111
90
|
parse_filter(text)
|
112
|
-
when SANITIZE_PREFIX
|
113
|
-
case
|
114
|
-
when text.start_with?('&==')
|
115
|
-
parse_plain(text[3 .. -1].lstrip)
|
116
|
-
when text[1] == SCRIPT_PREFIX
|
117
|
-
parse_script(text)
|
118
|
-
when text[1] == PRESERVE_PREFIX
|
119
|
-
parse_script("&=#{text[2 .. -1].lstrip}", preserve: true)
|
120
|
-
else
|
121
|
-
parse_plain(text[1 .. -1].strip)
|
122
|
-
end
|
123
91
|
else
|
124
|
-
|
92
|
+
parse_script(text)
|
125
93
|
end
|
126
94
|
end
|
127
95
|
|
@@ -152,30 +120,16 @@ module FastHaml
|
|
152
120
|
end
|
153
121
|
end
|
154
122
|
|
155
|
-
def parse_plain(text
|
156
|
-
@ast << Ast::Text.new(text
|
123
|
+
def parse_plain(text)
|
124
|
+
@ast << Ast::Text.new(text)
|
157
125
|
end
|
158
126
|
|
159
127
|
def parse_element(text)
|
160
|
-
@ast << ElementParser.new(
|
128
|
+
@ast << ElementParser.new(@line_parser).parse(text)
|
161
129
|
end
|
162
130
|
|
163
|
-
def parse_script(text
|
164
|
-
|
165
|
-
script = m[2]
|
166
|
-
if script.empty?
|
167
|
-
syntax_error!("No Ruby code to evaluate")
|
168
|
-
end
|
169
|
-
script += RubyMultiline.read(@line_parser, script)
|
170
|
-
node = Ast::Script.new([], script)
|
171
|
-
case m[1]
|
172
|
-
when '!'
|
173
|
-
node.escape_html = false
|
174
|
-
when '&'
|
175
|
-
node.escape_html = true
|
176
|
-
end
|
177
|
-
node.preserve = preserve
|
178
|
-
@ast << node
|
131
|
+
def parse_script(text)
|
132
|
+
@ast << ScriptParser.new(@line_parser).parse(text)
|
179
133
|
end
|
180
134
|
|
181
135
|
def parse_silent_script(text)
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'fast_haml/ast'
|
2
|
+
require 'fast_haml/ruby_multiline'
|
3
|
+
require 'fast_haml/syntax_error'
|
4
|
+
|
5
|
+
module FastHaml
|
6
|
+
class ScriptParser
|
7
|
+
def initialize(line_parser)
|
8
|
+
@line_parser = line_parser
|
9
|
+
end
|
10
|
+
|
11
|
+
def parse(text)
|
12
|
+
case text[0]
|
13
|
+
when '=', '~'
|
14
|
+
parse_script(text)
|
15
|
+
when '&'
|
16
|
+
parse_sanitized(text)
|
17
|
+
when '!'
|
18
|
+
parse_unescape(text)
|
19
|
+
else
|
20
|
+
parse_text(text)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def parse_script(text)
|
27
|
+
if text[1] == '='
|
28
|
+
Ast::Text.new(text[2 .. -1].strip)
|
29
|
+
else
|
30
|
+
script = text[1 .. -1].lstrip
|
31
|
+
if script.empty?
|
32
|
+
syntax_error!('No Ruby code to evaluate')
|
33
|
+
end
|
34
|
+
script += RubyMultiline.read(@line_parser, script)
|
35
|
+
Ast::Script.new([], script)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def parse_sanitized(text)
|
40
|
+
case
|
41
|
+
when text.start_with?('&==')
|
42
|
+
Ast::Text.new(text[3 .. -1].lstrip)
|
43
|
+
when text[1] == '=' || text[1] == '~'
|
44
|
+
script = text[2 .. -1].lstrip
|
45
|
+
if script.empty?
|
46
|
+
syntax_error!('No Ruby code to evaluate')
|
47
|
+
end
|
48
|
+
script += RubyMultiline.read(@line_parser, script)
|
49
|
+
Ast::Script.new([], script, true, text[1] == '~')
|
50
|
+
else
|
51
|
+
Ast::Text.new(text[1 .. -1].strip)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def parse_unescape(text)
|
56
|
+
case
|
57
|
+
when text.start_with?('!==')
|
58
|
+
Ast::Text.new(text[3 .. -1].lstrip, false)
|
59
|
+
when text[1] == '=' || text[1] == '~'
|
60
|
+
script = text[2 .. -1].lstrip
|
61
|
+
if script.empty?
|
62
|
+
syntax_error!('No Ruby code to evaluate')
|
63
|
+
end
|
64
|
+
script += RubyMultiline.read(@line_parser, script)
|
65
|
+
Ast::Script.new([], script, false, text[1] == '~')
|
66
|
+
else
|
67
|
+
Ast::Text.new(text[1 .. -1].lstrip, false)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def parse_text(text)
|
72
|
+
text = text.lstrip
|
73
|
+
if text.empty?
|
74
|
+
nil
|
75
|
+
else
|
76
|
+
Ast::Text.new(text)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def syntax_error!(message)
|
81
|
+
raise SyntaxError.new(message, @line_parser.lineno)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -11,21 +11,21 @@ module FastHaml
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def compile(text, escape_html: @escape_html)
|
14
|
-
if contains_interpolation?(text)
|
14
|
+
if self.class.contains_interpolation?(text)
|
15
15
|
compile_interpolation(text, escape_html: escape_html)
|
16
16
|
else
|
17
17
|
[:static, text]
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
private
|
22
|
-
|
23
21
|
INTERPOLATION_BEGIN = /(\\*)(#[\{$@])/o
|
24
22
|
|
25
|
-
def contains_interpolation?(text)
|
23
|
+
def self.contains_interpolation?(text)
|
26
24
|
INTERPOLATION_BEGIN === text
|
27
25
|
end
|
28
26
|
|
27
|
+
private
|
28
|
+
|
29
29
|
def compile_interpolation(text, escape_html: @escape_html)
|
30
30
|
s = StringScanner.new(text)
|
31
31
|
temple = [:multi]
|
data/lib/fast_haml/version.rb
CHANGED
@@ -94,4 +94,45 @@ HAML
|
|
94
94
|
HAML
|
95
95
|
end
|
96
96
|
end
|
97
|
+
|
98
|
+
context 'with tilt filters' do
|
99
|
+
it 'keeps newlines in filter' do
|
100
|
+
expect { render_string(<<'HAML') }.to raise_error(LineVerifier, raised_at(4))
|
101
|
+
:scss
|
102
|
+
nav {
|
103
|
+
ul {
|
104
|
+
margin: #{raise LineVerifier}px;
|
105
|
+
}
|
106
|
+
}
|
107
|
+
HAML
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'keeps newlines after filter' do
|
111
|
+
expect { render_string(<<'HAML') }.to raise_error(LineVerifier, raised_at(8))
|
112
|
+
:scss
|
113
|
+
nav {
|
114
|
+
ul {
|
115
|
+
margin: 0;
|
116
|
+
}
|
117
|
+
}
|
118
|
+
|
119
|
+
%span= raise LineVerifier
|
120
|
+
HAML
|
121
|
+
end
|
122
|
+
|
123
|
+
context 'with interpolation' do
|
124
|
+
it 'keeps newlines after filter' do
|
125
|
+
expect { render_string(<<'HAML') }.to raise_error(LineVerifier, raised_at(8))
|
126
|
+
:scss
|
127
|
+
nav {
|
128
|
+
ul {
|
129
|
+
margin: #{0 + 5}px;
|
130
|
+
}
|
131
|
+
}
|
132
|
+
|
133
|
+
%span= raise LineVerifier
|
134
|
+
HAML
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
97
138
|
end
|
data/spec/render/doctype_spec.rb
CHANGED
@@ -1,11 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe 'Doctype rendering', type: :render do
|
4
|
-
it 'ignores 1 or 2 exclamation marks' do
|
5
|
-
expect(render_string('!')).to eq("!\n")
|
6
|
-
expect(render_string('!!')).to eq("!!\n")
|
7
|
-
end
|
8
|
-
|
9
4
|
context 'with html format' do
|
10
5
|
it 'renders html5 doctype by default' do
|
11
6
|
expect(render_string('!!!')).to eq("<!DOCTYPE html>\n")
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe 'CoffeeScript filter rendering', type: :render do
|
4
|
+
it 'renders CoffeeScript filter' do
|
5
|
+
html = render_string(<<HAML)
|
6
|
+
:coffee
|
7
|
+
square = (x) -> x * x
|
8
|
+
square(3)
|
9
|
+
HAML
|
10
|
+
expect(html).to include('<script>')
|
11
|
+
expect(html).to include('square = function(x)')
|
12
|
+
expect(html).to include('square(3)')
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'parses string interpolation' do
|
16
|
+
html = render_string(<<'HAML')
|
17
|
+
:coffee
|
18
|
+
square = (x) -> x * x
|
19
|
+
square(#{1 + 2})
|
20
|
+
HAML
|
21
|
+
expect(html).to include('<script>')
|
22
|
+
expect(html).to include('square = function(x)')
|
23
|
+
expect(html).to include('square(3)')
|
24
|
+
end
|
25
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
RSpec.describe 'JavaScript filter
|
3
|
+
RSpec.describe 'JavaScript filter rendering', type: :render do
|
4
4
|
it 'renders javascript filter' do
|
5
5
|
expect(render_string(<<HAML)).to eq("<div>\n<script>\n alert('hello');\n</script>\n<span>world</span>\n</div>\n")
|
6
6
|
%div
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe 'SASS filter rendering', type: :render do
|
4
|
+
it 'renders SASS filter' do
|
5
|
+
html = render_string(<<'HAML')
|
6
|
+
:sass
|
7
|
+
nav
|
8
|
+
ul
|
9
|
+
margin: 0
|
10
|
+
content: "hello"
|
11
|
+
HAML
|
12
|
+
expect(html).to include('<style>')
|
13
|
+
expect(html).to include('nav ul {')
|
14
|
+
expect(html).to include('content: "hello"')
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'parses string interpolation' do
|
18
|
+
html = render_string(<<'HAML')
|
19
|
+
:sass
|
20
|
+
nav
|
21
|
+
ul
|
22
|
+
margin: #{0 + 5}px
|
23
|
+
HAML
|
24
|
+
expect(html).to include('<style>')
|
25
|
+
expect(html).to include('nav ul {')
|
26
|
+
expect(html).to include('margin: 5px')
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe 'SCSS filter rendering', type: :render do
|
4
|
+
it 'renders SCSS filter' do
|
5
|
+
html = render_string(<<'HAML')
|
6
|
+
:scss
|
7
|
+
nav {
|
8
|
+
ul {
|
9
|
+
margin: 0;
|
10
|
+
content: "hello";
|
11
|
+
}
|
12
|
+
}
|
13
|
+
HAML
|
14
|
+
expect(html).to include('<style>')
|
15
|
+
expect(html).to include('nav ul {')
|
16
|
+
expect(html).to include('content: "hello"')
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'parses string interpolation' do
|
20
|
+
html = render_string(<<'HAML')
|
21
|
+
:scss
|
22
|
+
nav {
|
23
|
+
ul {
|
24
|
+
margin: #{0 + 5}px;
|
25
|
+
}
|
26
|
+
}
|
27
|
+
HAML
|
28
|
+
expect(html).to include('<style>')
|
29
|
+
expect(html).to include('nav ul {')
|
30
|
+
expect(html).to include('margin: 5px')
|
31
|
+
end
|
32
|
+
end
|
@@ -14,6 +14,11 @@ HAML
|
|
14
14
|
expect(render_string('%span! <p>hello</p>')).to eq("<span><p>hello</p></span>\n")
|
15
15
|
end
|
16
16
|
|
17
|
+
it 'ignores single Unescape mark without spaces' do
|
18
|
+
expect(render_string('!<p>hello</p>')).to eq("<p>hello</p>\n")
|
19
|
+
expect(render_string('%span!<p>hello</p>')).to eq("<span><p>hello</p></span>\n")
|
20
|
+
end
|
21
|
+
|
17
22
|
it 'has effect on string interpolation in plain' do
|
18
23
|
expect(render_string('! <p>#{"<strong>hello</strong>"}</p>')).to eq("<p><strong>hello</strong></p>\n")
|
19
24
|
expect(render_string('%span! <p>#{"<strong>hello</strong>"}</p>')).to eq("<span><p><strong>hello</strong></p></span>\n")
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fast_haml
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kohei Suzuki
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: escape_utils
|
@@ -108,6 +108,20 @@ dependencies:
|
|
108
108
|
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: coffee-script
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
126
|
name: coveralls
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -178,6 +192,20 @@ dependencies:
|
|
178
192
|
- - ">="
|
179
193
|
- !ruby/object:Gem::Version
|
180
194
|
version: '3'
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: sass
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - ">="
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '0'
|
202
|
+
type: :development
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - ">="
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: '0'
|
181
209
|
- !ruby/object:Gem::Dependency
|
182
210
|
name: simplecov
|
183
211
|
requirement: !ruby/object:Gem::Requirement
|
@@ -231,12 +259,16 @@ files:
|
|
231
259
|
- lib/fast_haml/filter_compilers.rb
|
232
260
|
- lib/fast_haml/filter_compilers/base.rb
|
233
261
|
- lib/fast_haml/filter_compilers/cdata.rb
|
262
|
+
- lib/fast_haml/filter_compilers/coffee.rb
|
234
263
|
- lib/fast_haml/filter_compilers/css.rb
|
235
264
|
- lib/fast_haml/filter_compilers/escaped.rb
|
236
265
|
- lib/fast_haml/filter_compilers/javascript.rb
|
237
266
|
- lib/fast_haml/filter_compilers/plain.rb
|
238
267
|
- lib/fast_haml/filter_compilers/preserve.rb
|
239
268
|
- lib/fast_haml/filter_compilers/ruby.rb
|
269
|
+
- lib/fast_haml/filter_compilers/sass.rb
|
270
|
+
- lib/fast_haml/filter_compilers/scss.rb
|
271
|
+
- lib/fast_haml/filter_compilers/tilt_base.rb
|
240
272
|
- lib/fast_haml/filter_parser.rb
|
241
273
|
- lib/fast_haml/html.rb
|
242
274
|
- lib/fast_haml/indent_tracker.rb
|
@@ -247,6 +279,7 @@ files:
|
|
247
279
|
- lib/fast_haml/rails_handler.rb
|
248
280
|
- lib/fast_haml/railtie.rb
|
249
281
|
- lib/fast_haml/ruby_multiline.rb
|
282
|
+
- lib/fast_haml/script_parser.rb
|
250
283
|
- lib/fast_haml/static_hash_parser.rb
|
251
284
|
- lib/fast_haml/syntax_error.rb
|
252
285
|
- lib/fast_haml/text_compiler.rb
|
@@ -311,12 +344,15 @@ files:
|
|
311
344
|
- spec/render/doctype_spec.rb
|
312
345
|
- spec/render/element_spec.rb
|
313
346
|
- spec/render/filters/cdata_spec.rb
|
347
|
+
- spec/render/filters/coffee_spec.rb
|
314
348
|
- spec/render/filters/css_spec.rb
|
315
349
|
- spec/render/filters/escaped_spec.rb
|
316
350
|
- spec/render/filters/javascript_spec.rb
|
317
351
|
- spec/render/filters/plain_spec.rb
|
318
352
|
- spec/render/filters/preserve_spec.rb
|
319
353
|
- spec/render/filters/ruby_spec.rb
|
354
|
+
- spec/render/filters/sass_spec.rb
|
355
|
+
- spec/render/filters/scss_spec.rb
|
320
356
|
- spec/render/filters_spec.rb
|
321
357
|
- spec/render/haml_comment_spec.rb
|
322
358
|
- spec/render/multiline_spec.rb
|
@@ -413,12 +449,15 @@ test_files:
|
|
413
449
|
- spec/render/doctype_spec.rb
|
414
450
|
- spec/render/element_spec.rb
|
415
451
|
- spec/render/filters/cdata_spec.rb
|
452
|
+
- spec/render/filters/coffee_spec.rb
|
416
453
|
- spec/render/filters/css_spec.rb
|
417
454
|
- spec/render/filters/escaped_spec.rb
|
418
455
|
- spec/render/filters/javascript_spec.rb
|
419
456
|
- spec/render/filters/plain_spec.rb
|
420
457
|
- spec/render/filters/preserve_spec.rb
|
421
458
|
- spec/render/filters/ruby_spec.rb
|
459
|
+
- spec/render/filters/sass_spec.rb
|
460
|
+
- spec/render/filters/scss_spec.rb
|
422
461
|
- spec/render/filters_spec.rb
|
423
462
|
- spec/render/haml_comment_spec.rb
|
424
463
|
- spec/render/multiline_spec.rb
|