From 17d5bc40afdd3371cd953f969ee573762f8fa855 Mon Sep 17 00:00:00 2001 From: Nathan Weizenbaum Date: Sat, 31 May 2008 21:17:43 -0700 Subject: [PATCH] Allow flexible indentation for Sass docs. --- lib/sass/engine.rb | 26 ++++++++++++++------------ test/sass/engine_test.rb | 23 +++++++++++++++++------ 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/lib/sass/engine.rb b/lib/sass/engine.rb index d6ecf191..c728034a 100644 --- a/lib/sass/engine.rb +++ b/lib/sass/engine.rb @@ -6,6 +6,7 @@ require 'sass/tree/attr_node' require 'sass/tree/directive_node' require 'sass/constant' require 'sass/error' +require 'haml/shared' module Sass # This is the class where all the parsing and processing of the Sass @@ -146,7 +147,7 @@ module Sass if tabs # if line isn't blank if tabs - old_tabs > 1 - raise SyntaxError.new("#{tabs * 2} spaces were used for indentation. Sass must be indented using two spaces.", @line) + raise SyntaxError.new("The line was indented #{tabs - old_tabs} levels deeper than the previous line.", @line) end @lines << [line.strip, tabs] @@ -162,19 +163,20 @@ module Sass # Counts the tabulation of a line. def count_tabs(line) return nil if line.strip.empty? - return nil unless spaces = line.index(/[^ ]/) + return 0 unless whitespace = line[/^\s+/] - if spaces % 2 == 1 - raise SyntaxError.new(< 'Invalid constant: "!a".', "! a" => 'Invalid constant: "! a".', "!a b" => 'Invalid constant: "!a b".', - "a\n\t:b c" => < "1 space was used for indentation. Sass must be indented using two spaces.", - "a\n :b c" => "4 spaces were used for indentation. Sass must be indented using two spaces.", "a\n :b c\n !d = 3" => "Constants may only be declared at the root of a document.", "!a = 1b + 2c" => "Incompatible units: b and c.", "& a\n :b c" => "Base-level rules cannot contain the parent-selector-referencing character '&'.", @@ -58,6 +52,14 @@ END "=foo\n :color red\n.bar\n +bang" => "Undefined mixin 'bang'.", ".bar\n =foo\n :color red\n" => "Mixins may only be defined at the root of a document.", "=foo\n :color red\n.bar\n +foo\n :color red" => "Illegal nesting: Nothing may be nested beneath mixin directives.", + "a\n b: c\n b: c" => ["Inconsistent indentation: 1 space was used for indentation, but the rest of the document was indented using 2 spaces.", 3], + "a\n b: c\na\n b: c" => ["Inconsistent indentation: 1 space was used for indentation, but the rest of the document was indented using 2 spaces.", 4], + "a\n\t\tb: c\n\tb: c" => ["Inconsistent indentation: 1 tab was used for indentation, but the rest of the document was indented using 2 tabs.", 3], + "a\n b: c\n b: c" => ["Inconsistent indentation: 3 spaces were used for indentation, but the rest of the document was indented using 2 spaces.", 3], + "a\n \t b: c\n \tb: c" => ['Inconsistent indentation: " \t" was used for indentation, but the rest of the document was indented using " \t ".', 3], + "a\n b: c\n a\n d: e" => ["Inconsistent indentation: 3 spaces were used for indentation, but the rest of the document was indented using 2 spaces.", 4], + "a\n b: c\na\n d: e" => ["The line was indented 2 levels deeper than the previous line.", 4], + "a\n b: c\n a\n d: e" => ["The line was indented 3 levels deeper than the previous line.", 4], # Regression tests "a\n b:\n c\n d" => ["Illegal nesting: Only attributes may be nested beneath attributes.", 3] @@ -79,6 +81,15 @@ END renders_correctly "compressed", { :style => :compressed } end + def test_flexible_tabulation + assert_equal("p {\n a: b; }\n p q {\n c: d; }\n", + render("p\n a: b\n q\n c: d\n")) + assert_equal("p {\n a: b; }\n p q {\n c: d; }\n", + render("p\n\ta: b\n\tq\n\t\tc: d\n")) + assert_equal("p {\n a: b; }\n p q {\n c: d; }\n", + render("p\n \t \t a: b\n \t \t q\n \t \t \t \t c: d\n")) + end + def test_exceptions EXCEPTION_MAP.each do |key, value| begin