haml-edge 2.3.15 → 2.3.16
Sign up to get free protection for your applications and to get access to all the features.
- data/EDGE_GEM_VERSION +1 -1
- data/VERSION +1 -1
- data/extra/haml-mode.el +2 -3
- data/lib/sass/engine.rb +9 -31
- data/lib/sass/script/functions.rb +2 -1
- data/lib/sass/script/lexer.rb +1 -0
- data/lib/sass/script/parser.rb +51 -1
- data/lib/sass/tree/mixin_def_node.rb +2 -2
- data/lib/sass/tree/mixin_node.rb +3 -3
- data/test/sass/engine_test.rb +21 -6
- data/test/sass/functions_test.rb +1 -0
- metadata +6 -6
data/EDGE_GEM_VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.3.
|
1
|
+
2.3.16
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.3.
|
1
|
+
2.3.16
|
data/extra/haml-mode.el
CHANGED
@@ -603,9 +603,8 @@ If N is negative, will remove the spaces instead. Assumes all
|
|
603
603
|
lines in the region have indentation >= that of the first line."
|
604
604
|
(let ((ci (current-indentation)))
|
605
605
|
(save-excursion
|
606
|
-
(
|
607
|
-
|
608
|
-
nil (point) (mark)))))
|
606
|
+
(while (re-search-forward (concat "^" (make-string ci ?\s)) (mark) t)
|
607
|
+
(replace-match (make-string (max 0 (+ ci n)) ?\s))))))
|
609
608
|
|
610
609
|
(defun haml-electric-backspace (arg)
|
611
610
|
"Delete characters or back-dent the current line.
|
data/lib/sass/engine.rb
CHANGED
@@ -425,46 +425,24 @@ END
|
|
425
425
|
nil
|
426
426
|
end
|
427
427
|
|
428
|
-
# parses out the arguments between the commas and cleans up the mixin arguments
|
429
|
-
# returns nil if it fails to parse, otherwise an array.
|
430
|
-
def parse_mixin_arguments(arg_string)
|
431
|
-
arg_string = arg_string.strip
|
432
|
-
return [] if arg_string.empty?
|
433
|
-
return nil unless (arg_string[0] == ?( && arg_string[-1] == ?))
|
434
|
-
arg_string = arg_string[1...-1]
|
435
|
-
arg_string.split(",", -1).map {|a| a.strip}
|
436
|
-
end
|
437
|
-
|
438
428
|
def parse_mixin_definition(line)
|
439
429
|
name, arg_string = line.text.scan(/^=\s*([^(]+)(.*)$/).first
|
440
|
-
|
441
|
-
|
430
|
+
raise SyntaxError.new("Invalid mixin \"#{line.text[1..-1]}\".", @line) if name.nil?
|
431
|
+
|
432
|
+
offset = line.offset + line.text.size - arg_string.size
|
433
|
+
args = Script::Parser.new(arg_string.strip, @line, offset).parse_mixin_definition_arglist
|
442
434
|
default_arg_found = false
|
443
|
-
required_arg_count = 0
|
444
|
-
args.map! do |arg|
|
445
|
-
raise SyntaxError.new("Mixin arguments can't be empty.", @line) if arg.empty? || arg == "!"
|
446
|
-
unless arg[0] == Script::VARIABLE_CHAR
|
447
|
-
raise SyntaxError.new("Mixin argument \"#{arg}\" must begin with an exclamation point (!).", @line)
|
448
|
-
end
|
449
|
-
arg, default = arg.split(/\s*=\s*/, 2)
|
450
|
-
required_arg_count += 1 unless default
|
451
|
-
default_arg_found ||= default
|
452
|
-
raise SyntaxError.new("Invalid variable \"#{arg}\".", @line) unless arg =~ Script::VALIDATE
|
453
|
-
raise SyntaxError.new("Required arguments must not follow optional arguments \"#{arg}\".", @line) if default_arg_found && !default
|
454
|
-
default = parse_script(default, :offset => line.offset + line.text.index(default)) if default
|
455
|
-
[arg[1..-1], default]
|
456
|
-
end
|
457
435
|
Tree::MixinDefNode.new(name, args)
|
458
436
|
end
|
459
437
|
|
460
438
|
def parse_mixin_include(line, root)
|
461
439
|
name, arg_string = line.text.scan(/^\+\s*([^(]+)(.*)$/).first
|
462
|
-
|
463
|
-
raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath mixin directives.", @line + 1) unless line.children.empty?
|
464
|
-
raise SyntaxError.new("Invalid mixin include \"#{line.text}\".", @line) if name.nil? || args.nil?
|
465
|
-
args.each {|a| raise SyntaxError.new("Mixin arguments can't be empty.", @line) if a.empty?}
|
440
|
+
raise SyntaxError.new("Invalid mixin include \"#{line.text}\".", @line) if name.nil?
|
466
441
|
|
467
|
-
|
442
|
+
offset = line.offset + line.text.size - arg_string.size
|
443
|
+
args = Script::Parser.new(arg_string.strip, @line, offset).parse_mixin_include_arglist
|
444
|
+
raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath mixin directives.", @line + 1) unless line.children.empty?
|
445
|
+
Tree::MixinNode.new(name, args)
|
468
446
|
end
|
469
447
|
|
470
448
|
def parse_script(script, options = {})
|
@@ -71,7 +71,8 @@ module Sass::Script
|
|
71
71
|
# A number between 0 and 255 inclusive
|
72
72
|
def rgb(red, green, blue)
|
73
73
|
[red.value, green.value, blue.value].each do |v|
|
74
|
-
|
74
|
+
next unless v < 0 || v > 255
|
75
|
+
raise ArgumentError.new("Color value #{v} must be between 0 and 255 inclusive")
|
75
76
|
end
|
76
77
|
Color.new([red.value, green.value, blue.value])
|
77
78
|
end
|
data/lib/sass/script/lexer.rb
CHANGED
data/lib/sass/script/parser.rb
CHANGED
@@ -36,10 +36,42 @@ module Sass
|
|
36
36
|
# @raise [Sass::SyntaxError] if the expression isn't valid SassScript
|
37
37
|
def parse
|
38
38
|
expr = assert_expr :expr
|
39
|
-
|
39
|
+
assert_done
|
40
40
|
expr
|
41
41
|
end
|
42
42
|
|
43
|
+
# Parses the argument list for a mixin include.
|
44
|
+
#
|
45
|
+
# @return [Array<Script::Node>] The root nodes of the arguments.
|
46
|
+
# @raise [Sass::SyntaxError] if the argument list isn't valid SassScript
|
47
|
+
def parse_mixin_include_arglist
|
48
|
+
args = []
|
49
|
+
|
50
|
+
if try_tok(:lparen)
|
51
|
+
args = arglist || args
|
52
|
+
assert_tok(:rparen)
|
53
|
+
end
|
54
|
+
assert_done
|
55
|
+
|
56
|
+
args
|
57
|
+
end
|
58
|
+
|
59
|
+
# Parses the argument list for a mixin definition.
|
60
|
+
#
|
61
|
+
# @return [Array<Script::Node>] The root nodes of the arguments.
|
62
|
+
# @raise [Sass::SyntaxError] if the argument list isn't valid SassScript
|
63
|
+
def parse_mixin_definition_arglist
|
64
|
+
args = []
|
65
|
+
|
66
|
+
if try_tok(:lparen)
|
67
|
+
args = defn_arglist(false) || args
|
68
|
+
assert_tok(:rparen)
|
69
|
+
end
|
70
|
+
assert_done
|
71
|
+
|
72
|
+
args
|
73
|
+
end
|
74
|
+
|
43
75
|
# Parses a SassScript expression.
|
44
76
|
#
|
45
77
|
# @overload parse(str, line, offset, filename = nil)
|
@@ -120,6 +152,19 @@ END
|
|
120
152
|
end
|
121
153
|
end
|
122
154
|
|
155
|
+
def defn_arglist(must_have_default)
|
156
|
+
return unless c = try_tok(:const)
|
157
|
+
var = Script::Variable.new(c.value)
|
158
|
+
if try_tok(:single_eq)
|
159
|
+
val = assert_expr(:concat)
|
160
|
+
elsif must_have_default
|
161
|
+
raise SyntaxError.new("Required argument #{var.inspect} must come before any optional arguments.", @line)
|
162
|
+
end
|
163
|
+
|
164
|
+
return [[var, val]] unless try_tok(:comma)
|
165
|
+
[[var, val], *defn_arglist(val)]
|
166
|
+
end
|
167
|
+
|
123
168
|
def arglist
|
124
169
|
return unless e = concat
|
125
170
|
return [e] unless try_tok(:comma)
|
@@ -167,6 +212,11 @@ END
|
|
167
212
|
peeked = @lexer.peek
|
168
213
|
peeked && names.include?(peeked.type) && @lexer.next
|
169
214
|
end
|
215
|
+
|
216
|
+
def assert_done
|
217
|
+
return if @lexer.done?
|
218
|
+
raise Sass::SyntaxError.new("Unexpected #{@lexer.peek.type} token.")
|
219
|
+
end
|
170
220
|
end
|
171
221
|
end
|
172
222
|
end
|
@@ -5,8 +5,8 @@ module Sass
|
|
5
5
|
# @see Sass::Tree
|
6
6
|
class MixinDefNode < Node
|
7
7
|
# @param name [String] The mixin name
|
8
|
-
# @param args [Array<(
|
9
|
-
# Each element is a tuple containing the
|
8
|
+
# @param args [Array<(Script::Node, Script::Node)>] The arguments for the mixin.
|
9
|
+
# Each element is a tuple containing the variable for argument
|
10
10
|
# and the parse tree for the default value of the argument
|
11
11
|
def initialize(name, args)
|
12
12
|
@name = name
|
data/lib/sass/tree/mixin_node.rb
CHANGED
@@ -32,14 +32,14 @@ Mixin #{@name} takes #{mixin.args.size} argument#{'s' if mixin.args.size != 1}
|
|
32
32
|
END
|
33
33
|
|
34
34
|
environment = mixin.args.zip(@args).
|
35
|
-
inject(Sass::Environment.new(mixin.environment)) do |env, ((
|
36
|
-
env.set_local_var(name,
|
35
|
+
inject(Sass::Environment.new(mixin.environment)) do |env, ((var, default), value)|
|
36
|
+
env.set_local_var(var.name,
|
37
37
|
if value
|
38
38
|
value.perform(environment)
|
39
39
|
elsif default
|
40
40
|
default.perform(env)
|
41
41
|
end)
|
42
|
-
raise Sass::SyntaxError.new("Mixin #{@name} is missing parameter
|
42
|
+
raise Sass::SyntaxError.new("Mixin #{@name} is missing parameter #{var.inspect}.") unless env.var(var.name)
|
43
43
|
env
|
44
44
|
end
|
45
45
|
mixin.tree.map {|c| c.perform(environment)}.flatten
|
data/test/sass/engine_test.rb
CHANGED
@@ -65,14 +65,14 @@ class SassEngineTest < Test::Unit::TestCase
|
|
65
65
|
"a\n b: c\na\n d: e" => ["The line was indented 2 levels deeper than the previous line.", 4],
|
66
66
|
"a\n b: c\n a\n d: e" => ["The line was indented 3 levels deeper than the previous line.", 4],
|
67
67
|
"a\n \tb: c" => ["Indentation can't use both tabs and spaces.", 2],
|
68
|
-
"=a(" => '
|
69
|
-
"=a(b)" => '
|
70
|
-
"=a(,)" => "
|
71
|
-
"=a(!)" => "
|
72
|
-
"=a(!foo bar)" => "
|
68
|
+
"=a(" => 'Expected rparen token, was end of text.',
|
69
|
+
"=a(b)" => 'Expected rparen token, was ident token.',
|
70
|
+
"=a(,)" => "Expected rparen token, was comma token.",
|
71
|
+
"=a(!)" => "Syntax error in '(!)' at character 4.",
|
72
|
+
"=a(!foo bar)" => "Expected rparen token, was ident token.",
|
73
73
|
"=foo\n bar: baz\n+foo" => ["Properties aren't allowed at the root of a document.", 2],
|
74
74
|
"a-\#{!b\n c: d" => ["Expected end_interpolation token, was end of text.", 1],
|
75
|
-
"=a(!b = 1, !c)" => "Required
|
75
|
+
"=a(!b = 1, !c)" => "Required argument !c must come before any optional arguments.",
|
76
76
|
"=a(!b = 1)\n :a= !b\ndiv\n +a(1,2)" => "Mixin a takes 1 argument but 2 were passed.",
|
77
77
|
"=a(!b)\n :a= !b\ndiv\n +a" => "Mixin a is missing parameter !b.",
|
78
78
|
"@else\n a\n b: c" => ["@else must come after @if.", 1],
|
@@ -706,6 +706,21 @@ SASS
|
|
706
706
|
|
707
707
|
# Regression tests
|
708
708
|
|
709
|
+
def test_parens_in_mixins
|
710
|
+
assert_equal(<<CSS, render(<<SASS))
|
711
|
+
.foo {
|
712
|
+
color: #01ff7f;
|
713
|
+
background-color: #000102; }
|
714
|
+
CSS
|
715
|
+
=foo(!c1, !c2 = rgb(0, 1, 2))
|
716
|
+
color = !c1
|
717
|
+
background-color = !c2
|
718
|
+
|
719
|
+
.foo
|
720
|
+
+foo(rgb(1,255,127))
|
721
|
+
SASS
|
722
|
+
end
|
723
|
+
|
709
724
|
def test_comment_beneath_prop
|
710
725
|
assert_equal(<<RESULT, render(<<SOURCE))
|
711
726
|
.box {
|
data/test/sass/functions_test.rb
CHANGED
@@ -91,6 +91,7 @@ class SassFunctionTest < Test::Unit::TestCase
|
|
91
91
|
def test_rgb
|
92
92
|
assert_equal("#123456", evaluate("rgb(18, 52, 86)"))
|
93
93
|
assert_equal("#beaded", evaluate("rgb(190, 173, 237)"))
|
94
|
+
assert_equal("#00ff7f", evaluate("rgb(0, 255, 127)"))
|
94
95
|
|
95
96
|
assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgb'",
|
96
97
|
"rgb(256, 1, 1)")
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: haml-edge
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.3.
|
4
|
+
version: 2.3.16
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathan Weizenbaum
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2009-07-
|
13
|
+
date: 2009-07-19 00:00:00 -04:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -44,9 +44,9 @@ extensions: []
|
|
44
44
|
|
45
45
|
extra_rdoc_files:
|
46
46
|
- README.md
|
47
|
-
- VERSION
|
48
|
-
- MIT-LICENSE
|
49
47
|
- REVISION
|
48
|
+
- MIT-LICENSE
|
49
|
+
- VERSION
|
50
50
|
- VERSION_NAME
|
51
51
|
- EDGE_GEM_VERSION
|
52
52
|
files:
|
@@ -249,9 +249,9 @@ files:
|
|
249
249
|
- init.rb
|
250
250
|
- .yardopts
|
251
251
|
- README.md
|
252
|
-
- VERSION
|
253
|
-
- MIT-LICENSE
|
254
252
|
- REVISION
|
253
|
+
- MIT-LICENSE
|
254
|
+
- VERSION
|
255
255
|
- VERSION_NAME
|
256
256
|
- EDGE_GEM_VERSION
|
257
257
|
has_rdoc: true
|