haml-edge 2.3.15 → 2.3.16

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.
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