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 CHANGED
@@ -1 +1 @@
1
- 2.3.15
1
+ 2.3.16
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.3.15
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
- (replace-regexp (concat "^" (make-string ci ? ))
607
- (make-string (max 0 (+ ci n)) ? )
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
- args = parse_mixin_arguments(arg_string)
441
- raise SyntaxError.new("Invalid mixin \"#{line.text[1..-1]}\".", @line) if name.nil? || args.nil?
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
- args = parse_mixin_arguments(arg_string)
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
- Tree::MixinNode.new(name, args.map {|s| parse_script(s, :offset => line.offset + line.text.index(s))})
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
- raise ArgumentError.new("Color value #{v} must be between 0 and 255 inclusive") if v <= 0 || v >= 255
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
@@ -28,6 +28,7 @@ module Sass
28
28
  '*' => :times,
29
29
  '/' => :div,
30
30
  '%' => :mod,
31
+ '=' => :single_eq,
31
32
  '(' => :lparen,
32
33
  ')' => :rparen,
33
34
  ',' => :comma,
@@ -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
- raise Sass::SyntaxError.new("Unexpected #{@lexer.peek.type} token.") unless @lexer.done?
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<(String, Script::Node)>] The arguments for the mixin.
9
- # Each element is a tuple containing the name of the argument
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
@@ -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, ((name, default), value)|
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 !#{name}.") unless env.var(name)
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
@@ -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(" => 'Invalid mixin "a(".',
69
- "=a(b)" => 'Mixin argument "b" must begin with an exclamation point (!).',
70
- "=a(,)" => "Mixin arguments can't be empty.",
71
- "=a(!)" => "Mixin arguments can't be empty.",
72
- "=a(!foo bar)" => "Invalid variable \"!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 arguments must not follow optional arguments \"!c\".",
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 {
@@ -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.15
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-16 00:00:00 -04:00
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