sass 3.2.0.alpha.53 → 3.2.0.alpha.54
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/REVISION +1 -1
- data/VERSION +1 -1
- data/lib/sass/css.rb +0 -1
- data/lib/sass/engine.rb +2 -3
- data/lib/sass/script.rb +0 -1
- data/lib/sass/script/lexer.rb +1 -3
- data/lib/sass/scss/parser.rb +2 -3
- data/lib/sass/shared.rb +2 -4
- data/lib/sass/util.rb +2 -1
- data/lib/sass/util/multibyte_string_scanner.rb +134 -0
- data/test/sass/engine_test.rb +25 -0
- data/test/sass/util/multibyte_string_scanner_test.rb +145 -0
- metadata +7 -4
data/REVISION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
594a6d23b2e7b60d1b522c1c2575c9db8681e9f7
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.2.0.alpha.
|
|
1
|
+
3.2.0.alpha.54
|
data/lib/sass/css.rb
CHANGED
data/lib/sass/engine.rb
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
require 'strscan'
|
|
2
1
|
require 'set'
|
|
3
2
|
require 'digest/sha1'
|
|
4
3
|
require 'sass/cache_stores'
|
|
@@ -570,7 +569,7 @@ WARNING
|
|
|
570
569
|
end
|
|
571
570
|
|
|
572
571
|
def parse_property_or_rule(line)
|
|
573
|
-
scanner =
|
|
572
|
+
scanner = Sass::Util::MultibyteStringScanner.new(line.text)
|
|
574
573
|
hack_char = scanner.scan(/[:\*\.]|\#(?!\{)/)
|
|
575
574
|
parser = Sass::SCSS::SassParser.new(scanner, @options[:filename], @line)
|
|
576
575
|
|
|
@@ -758,7 +757,7 @@ WARNING
|
|
|
758
757
|
raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath import directives.",
|
|
759
758
|
:line => @line + 1) unless line.children.empty?
|
|
760
759
|
|
|
761
|
-
scanner =
|
|
760
|
+
scanner = Sass::Util::MultibyteStringScanner.new(value)
|
|
762
761
|
values = []
|
|
763
762
|
|
|
764
763
|
loop do
|
data/lib/sass/script.rb
CHANGED
data/lib/sass/script/lexer.rb
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
require 'sass/scss/rx'
|
|
2
2
|
|
|
3
|
-
require 'strscan'
|
|
4
|
-
|
|
5
3
|
module Sass
|
|
6
4
|
module Script
|
|
7
5
|
# The lexical analyzer for SassScript.
|
|
@@ -126,7 +124,7 @@ module Sass
|
|
|
126
124
|
# @param options [{Symbol => Object}] An options hash;
|
|
127
125
|
# see {file:SASS_REFERENCE.md#sass_options the Sass options documentation}
|
|
128
126
|
def initialize(str, line, offset, options)
|
|
129
|
-
@scanner = str.is_a?(StringScanner) ? str :
|
|
127
|
+
@scanner = str.is_a?(StringScanner) ? str : Sass::Util::MultibyteStringScanner.new(str)
|
|
130
128
|
@line = line
|
|
131
129
|
@offset = offset
|
|
132
130
|
@options = options
|
data/lib/sass/scss/parser.rb
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
require 'strscan'
|
|
2
1
|
require 'set'
|
|
3
2
|
|
|
4
3
|
module Sass
|
|
@@ -50,7 +49,7 @@ module Sass
|
|
|
50
49
|
if @template.is_a?(StringScanner)
|
|
51
50
|
@template
|
|
52
51
|
else
|
|
53
|
-
|
|
52
|
+
Sass::Util::MultibyteStringScanner.new(@template.gsub("\r", ""))
|
|
54
53
|
end
|
|
55
54
|
end
|
|
56
55
|
|
|
@@ -915,7 +914,7 @@ MESSAGE
|
|
|
915
914
|
if @throw_err
|
|
916
915
|
throw :_sass_parser_error, err
|
|
917
916
|
else
|
|
918
|
-
@scanner =
|
|
917
|
+
@scanner = Sass::Util::MultibyteStringScanner.new(@scanner.string)
|
|
919
918
|
@scanner.pos = err[:pos]
|
|
920
919
|
@line = err[:line]
|
|
921
920
|
@expected = err[:expected]
|
data/lib/sass/shared.rb
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require 'strscan'
|
|
2
|
-
|
|
3
1
|
module Sass
|
|
4
2
|
# This module contains functionality that's shared between Haml and Sass.
|
|
5
3
|
module Shared
|
|
@@ -16,7 +14,7 @@ module Sass
|
|
|
16
14
|
# @yieldparam scan [StringScanner] The scanner scanning through the string
|
|
17
15
|
# @return [String] The text remaining in the scanner after all `#{`s have been processed
|
|
18
16
|
def handle_interpolation(str)
|
|
19
|
-
scan =
|
|
17
|
+
scan = Sass::Util::MultibyteStringScanner.new(str)
|
|
20
18
|
yield scan while scan.scan(/(.*?)(\\*)\#\{/m)
|
|
21
19
|
scan.rest
|
|
22
20
|
end
|
|
@@ -40,7 +38,7 @@ module Sass
|
|
|
40
38
|
# `["Foo (Bar (Baz bang) bop)", " (Bang (bop bip))"]` in the example above.
|
|
41
39
|
def balance(scanner, start, finish, count = 0)
|
|
42
40
|
str = ''
|
|
43
|
-
scanner =
|
|
41
|
+
scanner = Sass::Util::MultibyteStringScanner.new(scanner) unless scanner.is_a? StringScanner
|
|
44
42
|
regexp = Regexp.new("(.*?)[\\#{start.chr}\\#{finish.chr}]", Regexp::MULTILINE)
|
|
45
43
|
while scanner.scan(regexp)
|
|
46
44
|
str << scanner.matched
|
data/lib/sass/util.rb
CHANGED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
require 'strscan'
|
|
2
|
+
|
|
3
|
+
if Sass::Util.ruby1_8?
|
|
4
|
+
Sass::Util::MultibyteStringScanner = StringScanner
|
|
5
|
+
else
|
|
6
|
+
# A wrapper of the native StringScanner class that works correctly with
|
|
7
|
+
# multibyte character encodings. The native class deals only in bytes, not
|
|
8
|
+
# characters, for methods like [#pos] and [#matched_size]. This class deals
|
|
9
|
+
# only in characters, instead.
|
|
10
|
+
class Sass::Util::MultibyteStringScanner < StringScanner
|
|
11
|
+
def self.new(str)
|
|
12
|
+
return StringScanner.new(str) if str.ascii_only?
|
|
13
|
+
super
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def initialize(str)
|
|
17
|
+
super
|
|
18
|
+
@mb_pos = 0
|
|
19
|
+
@mb_matched_size = nil
|
|
20
|
+
@mb_last_pos = nil
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
alias_method :byte_pos, :pos
|
|
24
|
+
alias_method :byte_matched_size, :matched_size
|
|
25
|
+
|
|
26
|
+
def check(pattern); _match super; end
|
|
27
|
+
def check_until(pattern); _matched super; end
|
|
28
|
+
def getch; _forward _match super; end
|
|
29
|
+
def match?(pattern); _size check(pattern); end
|
|
30
|
+
def matched_size; @mb_matched_size; end
|
|
31
|
+
def peek(len); string[@mb_pos, len]; end
|
|
32
|
+
alias_method :peep, :peek
|
|
33
|
+
def pos; @mb_pos; end
|
|
34
|
+
alias_method :pointer, :pos
|
|
35
|
+
def rest_size; rest.size; end
|
|
36
|
+
def scan(pattern); _forward _match super; end
|
|
37
|
+
def scan_until(pattern); _forward _matched super; end
|
|
38
|
+
def skip(pattern); _size scan(pattern); end
|
|
39
|
+
def skip_until(pattern); _matched _size scan_until(pattern); end
|
|
40
|
+
|
|
41
|
+
def get_byte
|
|
42
|
+
raise "MultibyteStringScanner doesn't support #get_byte."
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def getbyte
|
|
46
|
+
raise "MultibyteStringScanner doesn't support #getbyte."
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def pos=(n)
|
|
50
|
+
@mb_last_pos = nil
|
|
51
|
+
|
|
52
|
+
# We set position kind of a lot during parsing, so we want it to be as
|
|
53
|
+
# efficient as possible. This is complicated by the fact that UTF-8 is a
|
|
54
|
+
# variable-length encoding, so it's difficult to find the byte length that
|
|
55
|
+
# corresponds to a given character length.
|
|
56
|
+
#
|
|
57
|
+
# Our heuristic here is to try to count the fewest possible characters. So
|
|
58
|
+
# if the new position is close to the current one, just count the
|
|
59
|
+
# characters between the two; if the new position is closer to the
|
|
60
|
+
# beginning of the string, just count the characters from there.
|
|
61
|
+
if @mb_pos - n < @mb_pos / 2
|
|
62
|
+
# New position is close to old position
|
|
63
|
+
byte_delta = @mb_pos > n ? -string[n...@mb_pos].bytesize : string[@mb_pos...n].bytesize
|
|
64
|
+
super(byte_pos + byte_delta)
|
|
65
|
+
else
|
|
66
|
+
# New position is close to BOS
|
|
67
|
+
super(string[0...n].bytesize)
|
|
68
|
+
end
|
|
69
|
+
@mb_pos = n
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def reset
|
|
73
|
+
@mb_pos = 0
|
|
74
|
+
@mb_matched_size = nil
|
|
75
|
+
@mb_last_pos = nil
|
|
76
|
+
super
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def scan_full(pattern, advance_pointer_p, return_string_p)
|
|
80
|
+
res = _match super(pattern, advance_pointer_p, true)
|
|
81
|
+
_forward res if advance_pointer_p
|
|
82
|
+
return res if return_string_p
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def search_full(pattern, advance_pointer_p, return_string_p)
|
|
86
|
+
res = super(pattern, advance_pointer_p, true)
|
|
87
|
+
_forward res if advance_pointer_p
|
|
88
|
+
_matched((res if return_string_p))
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def string=(str)
|
|
92
|
+
@mb_pos = 0
|
|
93
|
+
@mb_matched_size = nil
|
|
94
|
+
@mb_last_pos = nil
|
|
95
|
+
super
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def terminate
|
|
99
|
+
@mb_pos = string.size
|
|
100
|
+
@mb_matched_size = nil
|
|
101
|
+
@mb_last_pos = nil
|
|
102
|
+
super
|
|
103
|
+
end
|
|
104
|
+
alias_method :clear, :terminate
|
|
105
|
+
|
|
106
|
+
def unscan
|
|
107
|
+
super
|
|
108
|
+
@mb_pos = @mb_last_pos
|
|
109
|
+
@mb_last_pos = @mb_matched_size = nil
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
private
|
|
113
|
+
|
|
114
|
+
def _size(str)
|
|
115
|
+
str && str.size
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def _match(str)
|
|
119
|
+
@mb_matched_size = str && str.size
|
|
120
|
+
str
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def _matched(res)
|
|
124
|
+
_match matched
|
|
125
|
+
res
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def _forward(str)
|
|
129
|
+
@mb_last_pos = @mb_pos
|
|
130
|
+
@mb_pos += str.size if str
|
|
131
|
+
str
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
data/test/sass/engine_test.rb
CHANGED
|
@@ -2545,6 +2545,31 @@ CSS
|
|
|
2545
2545
|
a: b
|
|
2546
2546
|
SASS
|
|
2547
2547
|
end
|
|
2548
|
+
|
|
2549
|
+
# Encoding Regression Test
|
|
2550
|
+
|
|
2551
|
+
def test_multibyte_prop_name
|
|
2552
|
+
assert_equal(<<CSS, render(<<SASS))
|
|
2553
|
+
@charset "UTF-8";
|
|
2554
|
+
#bar {
|
|
2555
|
+
cölor: blue; }
|
|
2556
|
+
CSS
|
|
2557
|
+
#bar
|
|
2558
|
+
cölor: blue
|
|
2559
|
+
SASS
|
|
2560
|
+
end
|
|
2561
|
+
|
|
2562
|
+
def test_multibyte_and_interpolation
|
|
2563
|
+
assert_equal(<<CSS, render(<<SCSS, :syntax => :scss))
|
|
2564
|
+
#bar {
|
|
2565
|
+
background: a 0%; }
|
|
2566
|
+
CSS
|
|
2567
|
+
#bar {
|
|
2568
|
+
//
|
|
2569
|
+
background: \#{a} 0%;
|
|
2570
|
+
}
|
|
2571
|
+
SCSS
|
|
2572
|
+
end
|
|
2548
2573
|
end
|
|
2549
2574
|
|
|
2550
2575
|
def test_original_filename_set
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
require File.dirname(__FILE__) + '/../../test_helper'
|
|
4
|
+
|
|
5
|
+
class MultibyteStringScannerTest < Test::Unit::TestCase
|
|
6
|
+
def setup
|
|
7
|
+
@scanner = Sass::Util::MultibyteStringScanner.new("cölorfül")
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def test_initial
|
|
11
|
+
assert_scanner_state 0, 0, nil, nil
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def test_check
|
|
15
|
+
assert_equal 'cö', @scanner.check(/../)
|
|
16
|
+
assert_scanner_state 0, 0, 2, 3
|
|
17
|
+
assert_equal 0, @scanner.pos
|
|
18
|
+
assert_equal 0, @scanner.pos
|
|
19
|
+
assert_equal 2, @scanner.matched_size
|
|
20
|
+
assert_equal 3, @scanner.byte_matched_size
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def test_check_until
|
|
24
|
+
assert_equal 'cölorfü', @scanner.check_until(/f./)
|
|
25
|
+
assert_scanner_state 0, 0, 2, 3
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def test_getch
|
|
29
|
+
assert_equal 'c', @scanner.getch
|
|
30
|
+
assert_equal 'ö', @scanner.getch
|
|
31
|
+
assert_scanner_state 2, 3, 1, 2
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def test_match?
|
|
35
|
+
assert_equal 2, @scanner.match?(/../)
|
|
36
|
+
assert_scanner_state 0, 0, 2, 3
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def test_peek
|
|
40
|
+
assert_equal 'cö', @scanner.peek(2)
|
|
41
|
+
assert_scanner_state 0, 0, nil, nil
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def test_rest_size
|
|
45
|
+
assert_equal 'cö', @scanner.scan(/../)
|
|
46
|
+
assert_equal 6, @scanner.rest_size
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def test_scan
|
|
50
|
+
assert_equal 'cö', @scanner.scan(/../)
|
|
51
|
+
assert_scanner_state 2, 3, 2, 3
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def test_scan_until
|
|
55
|
+
assert_equal 'cölorfü', @scanner.scan_until(/f./)
|
|
56
|
+
assert_scanner_state 7, 9, 2, 3
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def test_skip
|
|
60
|
+
assert_equal 2, @scanner.skip(/../)
|
|
61
|
+
assert_scanner_state 2, 3, 2, 3
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def test_skip_until
|
|
65
|
+
assert_equal 7, @scanner.skip_until(/f./)
|
|
66
|
+
assert_scanner_state 7, 9, 2, 3
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def test_set_pos
|
|
70
|
+
@scanner.pos = 7
|
|
71
|
+
assert_scanner_state 7, 9, nil, nil
|
|
72
|
+
@scanner.pos = 6
|
|
73
|
+
assert_scanner_state 6, 7, nil, nil
|
|
74
|
+
@scanner.pos = 1
|
|
75
|
+
assert_scanner_state 1, 1, nil, nil
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def test_reset
|
|
79
|
+
@scanner.scan(/../)
|
|
80
|
+
@scanner.reset
|
|
81
|
+
assert_scanner_state 0, 0, nil, nil
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def test_scan_full
|
|
85
|
+
assert_equal 'cö', @scanner.scan_full(/../, true, true)
|
|
86
|
+
assert_scanner_state 2, 3, 2, 3
|
|
87
|
+
|
|
88
|
+
@scanner.reset
|
|
89
|
+
assert_equal 'cö', @scanner.scan_full(/../, false, true)
|
|
90
|
+
assert_scanner_state 0, 0, 2, 3
|
|
91
|
+
|
|
92
|
+
@scanner.reset
|
|
93
|
+
assert_nil @scanner.scan_full(/../, true, false)
|
|
94
|
+
assert_scanner_state 2, 3, 2, 3
|
|
95
|
+
|
|
96
|
+
@scanner.reset
|
|
97
|
+
assert_nil @scanner.scan_full(/../, false, false)
|
|
98
|
+
assert_scanner_state 0, 0, 2, 3
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def test_search_full
|
|
102
|
+
assert_equal 'cölorfü', @scanner.search_full(/f./, true, true)
|
|
103
|
+
assert_scanner_state 7, 9, 2, 3
|
|
104
|
+
|
|
105
|
+
@scanner.reset
|
|
106
|
+
assert_equal 'cölorfü', @scanner.search_full(/f./, false, true)
|
|
107
|
+
assert_scanner_state 0, 0, 2, 3
|
|
108
|
+
|
|
109
|
+
@scanner.reset
|
|
110
|
+
assert_nil @scanner.search_full(/f./, true, false)
|
|
111
|
+
assert_scanner_state 7, 9, 2, 3
|
|
112
|
+
|
|
113
|
+
@scanner.reset
|
|
114
|
+
assert_nil @scanner.search_full(/f./, false, false)
|
|
115
|
+
assert_scanner_state 0, 0, 2, 3
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def test_set_string
|
|
119
|
+
@scanner.scan(/../)
|
|
120
|
+
@scanner.string = 'föóbâr'
|
|
121
|
+
assert_scanner_state 0, 0, nil, nil
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def test_terminate
|
|
125
|
+
@scanner.scan(/../)
|
|
126
|
+
@scanner.terminate
|
|
127
|
+
assert_scanner_state 8, 10, nil, nil
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def test_unscan
|
|
131
|
+
@scanner.scan(/../)
|
|
132
|
+
@scanner.scan_until(/f./)
|
|
133
|
+
@scanner.unscan
|
|
134
|
+
assert_scanner_state 2, 3, nil, nil
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
private
|
|
138
|
+
|
|
139
|
+
def assert_scanner_state(pos, byte_pos, matched_size, byte_matched_size)
|
|
140
|
+
assert_equal pos, @scanner.pos, 'pos'
|
|
141
|
+
assert_equal byte_pos, @scanner.byte_pos, 'byte_pos'
|
|
142
|
+
assert_equal matched_size, @scanner.matched_size, 'matched_size'
|
|
143
|
+
assert_equal byte_matched_size, @scanner.byte_matched_size, 'byte_matched_size'
|
|
144
|
+
end
|
|
145
|
+
end
|
metadata
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sass
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
hash:
|
|
4
|
+
hash: 592302961
|
|
5
5
|
prerelease: 6
|
|
6
6
|
segments:
|
|
7
7
|
- 3
|
|
8
8
|
- 2
|
|
9
9
|
- 0
|
|
10
10
|
- alpha
|
|
11
|
-
-
|
|
12
|
-
version: 3.2.0.alpha.
|
|
11
|
+
- 54
|
|
12
|
+
version: 3.2.0.alpha.54
|
|
13
13
|
platform: ruby
|
|
14
14
|
authors:
|
|
15
15
|
- Nathan Weizenbaum
|
|
@@ -19,7 +19,7 @@ autorequire:
|
|
|
19
19
|
bindir: bin
|
|
20
20
|
cert_chain: []
|
|
21
21
|
|
|
22
|
-
date: 2012-01-
|
|
22
|
+
date: 2012-01-05 00:00:00 -05:00
|
|
23
23
|
default_executable:
|
|
24
24
|
dependencies:
|
|
25
25
|
- !ruby/object:Gem::Dependency
|
|
@@ -164,6 +164,7 @@ files:
|
|
|
164
164
|
- lib/sass/tree/while_node.rb
|
|
165
165
|
- lib/sass/util.rb
|
|
166
166
|
- lib/sass/util/subset_map.rb
|
|
167
|
+
- lib/sass/util/multibyte_string_scanner.rb
|
|
167
168
|
- lib/sass/version.rb
|
|
168
169
|
- vendor/fssm/Gemfile
|
|
169
170
|
- vendor/fssm/LICENSE
|
|
@@ -306,6 +307,7 @@ files:
|
|
|
306
307
|
- test/sass/templates/warn_imported.sass
|
|
307
308
|
- test/sass/test_helper.rb
|
|
308
309
|
- test/sass/util/subset_map_test.rb
|
|
310
|
+
- test/sass/util/multibyte_string_scanner_test.rb
|
|
309
311
|
- test/sass/util_test.rb
|
|
310
312
|
- test/test_helper.rb
|
|
311
313
|
- extra/update_watch.rb
|
|
@@ -374,4 +376,5 @@ test_files:
|
|
|
374
376
|
- test/sass/scss/rx_test.rb
|
|
375
377
|
- test/sass/scss/scss_test.rb
|
|
376
378
|
- test/sass/util/subset_map_test.rb
|
|
379
|
+
- test/sass/util/multibyte_string_scanner_test.rb
|
|
377
380
|
- test/sass/util_test.rb
|