diff --git a/doc-src/SASS_CHANGELOG.md b/doc-src/SASS_CHANGELOG.md index 384fb47f..bc55f7eb 100644 --- a/doc-src/SASS_CHANGELOG.md +++ b/doc-src/SASS_CHANGELOG.md @@ -102,7 +102,7 @@ and all of them will be watched: File and directory watching is accessible from Ruby, using the {Sass::Plugin#watch} function. -### Bulk Updating +#### Bulk Updating Another new flag for the `sass` command-line utility is `--update`. It checks a group of Sass files to see if their CSS needs to be updated, @@ -118,14 +118,31 @@ In fact, `--update` work exactly the same as `--watch`, except that it doesn't continue watching the files after the first check. -### Variable Names +### Syntax -SassScript variable names may now contain hyphens. +#### Variable and Mixin Names + +SassScript variable and mixin names may now contain hyphens. +In fact, they may be any valid CSS3 identifier. For example: !prettiest-color = #542FA9 + =pretty-text + color = !prettiest-color -### Single-Quoted Strings +In order to allow frameworks like [Compass](http://compass-style.org) +to use hyphens in variable names +while maintaining backwards-compatibility, +variables and mixins using hyphens may be referred to +with underscores, and vice versa. +For example: + + !prettiest-color = #542FA9 + .pretty + // Using an underscore instead of a hyphen works + color = !prettiest_color + +#### Single-Quoted Strings SassScript now supports single-quoted strings. They behave identically to double-quoted strings, diff --git a/extra/haml-mode.el b/extra/haml-mode.el index 32cb84ca..d5a42bd1 100644 --- a/extra/haml-mode.el +++ b/extra/haml-mode.el @@ -30,6 +30,7 @@ (require 'textile-mode nil t) (require 'markdown-mode nil t) (require 'javascript-mode "javascript" t) +(require 'js nil t) ;; User definable variables @@ -172,13 +173,15 @@ This requires that `css-mode' is available. (defun haml-highlight-js-filter-block (limit) "If a :javascript filter is found within LIMIT, highlight it. -This requires that Karl Landström's \"javascript.el\" be available." - (if (boundp 'js-font-lock-keywords-3) - (haml-fontify-filter-region "javascript" - limit - js-font-lock-keywords-3 - javascript-mode-syntax-table - nil))) +This requires that Karl Landström's javascript mode be available, either as the +\"js.el\" bundled with Emacs 23, or as \"javascript.el\" found in ELPA and +elsewhere." + (let ((keywords (or (and (featurep 'js) js--font-lock-keywords-3) + (and (featurep 'javascript-mode) js-font-lock-keywords-3))) + (syntax-table (or (and (featurep 'js) js-mode-syntax-table) + (and (featurep 'javascript-mode) javascript-mode-syntax-table)))) + (when keywords + (haml-fontify-filter-region "javascript" limit keywords syntax-table nil)))) (defun haml-highlight-textile-filter-block (limit) "If a :textile filter is found within LIMIT, highlight it. diff --git a/lib/sass/engine.rb b/lib/sass/engine.rb index be524895..acf7a51d 100644 --- a/lib/sass/engine.rb +++ b/lib/sass/engine.rb @@ -494,8 +494,10 @@ WARNING nil end + # @private + MIXIN_DEF_RE = /^=\s*(#{Sass::SCSS::RX::IDENT})(.*)$/ def parse_mixin_definition(line) - name, arg_string = line.text.scan(/^=\s*([^(]+)(.*)$/).first + name, arg_string = line.text.scan(MIXIN_DEF_RE).first raise SyntaxError.new("Invalid mixin \"#{line.text[1..-1]}\".") if name.nil? offset = line.offset + line.text.size - arg_string.size @@ -505,8 +507,10 @@ WARNING Tree::MixinDefNode.new(name, args) end + # @private + MIXIN_INCLUDE_RE = /^\+\s*(#{Sass::SCSS::RX::IDENT})(.*)$/ def parse_mixin_include(line, root) - name, arg_string = line.text.scan(/^\+\s*([^(]+)(.*)$/).first + name, arg_string = line.text.scan(MIXIN_INCLUDE_RE).first raise SyntaxError.new("Invalid mixin include \"#{line.text}\".") if name.nil? offset = line.offset + line.text.size - arg_string.size diff --git a/lib/sass/environment.rb b/lib/sass/environment.rb index 5440c213..4f0c577c 100644 --- a/lib/sass/environment.rb +++ b/lib/sass/environment.rb @@ -43,10 +43,16 @@ module Sass def inherited_hash(name) class_eval < "Import directives may only be used at the root of a document.", %Q{!foo = "bar" "baz" !} => %Q{Syntax error in '"bar" "baz" !' at character 20.}, "=foo\n :color red\n.bar\n +bang" => "Undefined mixin 'bang'.", + "=foo\n :color red\n.bar\n +bang_bop" => "Undefined mixin 'bang_bop'.", + "=foo\n :color red\n.bar\n +bang-bop" => "Undefined mixin 'bang-bop'.", ".bar\n =foo\n :color red\n" => ["Mixins may only be defined at the root of a document.", 2], "=foo\n :color red\n.bar\n +foo\n :color red" => "Illegal nesting: Nothing may be nested beneath mixin directives.", " a\n b: c" => ["Indenting at the beginning of the document is illegal.", 1], @@ -90,6 +92,8 @@ MSG "@if false\n@else if " => "Invalid else directive '@else if': expected 'if '.", "a\n !b = 12\nc\n d = !b" => 'Undefined variable: "!b".', "=foo\n !b = 12\nc\n +foo\n d = !b" => 'Undefined variable: "!b".', + "c\n d = !b-foo" => 'Undefined variable: "!b-foo".', + "c\n d = !b_foo" => 'Undefined variable: "!b_foo".', '@for !a from "foo" to 1' => '"foo" is not an integer.', '@for !a from 1 to "2"' => '"2" is not an integer.', '@for !a from 1 to "foo"' => '"foo" is not an integer.', @@ -738,6 +742,37 @@ three SASS end + def test_hyphen_underscore_insensitive_mixins + assert_equal(<