fast_haml 0.1.8 → 0.1.9
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 +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
|