sassc 1.9.0 → 1.10.0
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.
- checksums.yaml +4 -4
- data/README.md +30 -3
- data/ext/libsass/.gitignore +3 -0
- data/ext/libsass/.travis.yml +1 -1
- data/ext/libsass/GNUmakefile.am +7 -7
- data/ext/libsass/Makefile +7 -4
- data/ext/libsass/Makefile.conf +0 -1
- data/ext/libsass/appveyor.yml +6 -2
- data/ext/libsass/docs/api-context.md +4 -4
- data/ext/libsass/docs/api-doc.md +29 -11
- data/ext/libsass/docs/api-importer-example.md +5 -5
- data/ext/libsass/docs/build-on-windows.md +1 -1
- data/ext/libsass/include/sass/base.h +10 -0
- data/ext/libsass/include/sass/version.h +4 -0
- data/ext/libsass/include/sass/version.h.in +4 -0
- data/ext/libsass/include/sass2scss.h +1 -1
- data/ext/libsass/script/ci-build-libsass +15 -3
- data/ext/libsass/src/ast.cpp +161 -6
- data/ext/libsass/src/ast.hpp +71 -44
- data/ext/libsass/src/ast_factory.hpp +1 -1
- data/ext/libsass/src/ast_fwd_decl.hpp +2 -2
- data/ext/libsass/src/constants.cpp +2 -4
- data/ext/libsass/src/constants.hpp +3 -4
- data/ext/libsass/src/context.cpp +16 -17
- data/ext/libsass/src/context.hpp +2 -2
- data/ext/libsass/src/cssize.cpp +19 -8
- data/ext/libsass/src/cssize.hpp +5 -2
- data/ext/libsass/src/debugger.hpp +6 -3
- data/ext/libsass/src/emitter.cpp +1 -1
- data/ext/libsass/src/environment.cpp +1 -1
- data/ext/libsass/src/eval.cpp +42 -14
- data/ext/libsass/src/eval.hpp +1 -1
- data/ext/libsass/src/expand.cpp +24 -8
- data/ext/libsass/src/expand.hpp +2 -1
- data/ext/libsass/src/extend.cpp +55 -15
- data/ext/libsass/src/extend.hpp +5 -1
- data/ext/libsass/src/functions.cpp +10 -5
- data/ext/libsass/src/inspect.cpp +25 -19
- data/ext/libsass/src/inspect.hpp +2 -2
- data/ext/libsass/src/json.cpp +20 -9
- data/ext/libsass/src/json.hpp +5 -5
- data/ext/libsass/src/lexer.cpp +4 -1
- data/ext/libsass/src/lexer.hpp +21 -0
- data/ext/libsass/src/listize.cpp +2 -1
- data/ext/libsass/src/operation.hpp +4 -4
- data/ext/libsass/src/output.cpp +1 -1
- data/ext/libsass/src/output.hpp +1 -1
- data/ext/libsass/src/parser.cpp +189 -90
- data/ext/libsass/src/parser.hpp +42 -2
- data/ext/libsass/src/prelexer.cpp +474 -7
- data/ext/libsass/src/prelexer.hpp +15 -2
- data/ext/libsass/src/remove_placeholders.cpp +5 -5
- data/ext/libsass/src/remove_placeholders.hpp +3 -2
- data/ext/libsass/src/sass.cpp +33 -3
- data/ext/libsass/src/sass2scss.cpp +7 -0
- data/ext/libsass/src/sass_context.cpp +32 -62
- data/ext/libsass/src/sass_functions.cpp +3 -3
- data/ext/libsass/src/sass_values.cpp +5 -5
- data/ext/libsass/src/utf8/unchecked.h +16 -16
- data/ext/libsass/src/util.cpp +51 -30
- data/ext/libsass/src/util.hpp +6 -1
- data/ext/libsass/win/libsass.targets +0 -2
- data/ext/libsass/win/libsass.vcxproj.filters +0 -6
- data/lib/sassc/engine.rb +4 -1
- data/lib/sassc/error.rb +23 -1
- data/lib/sassc/version.rb +1 -1
- data/test/error_test.rb +27 -0
- data/test/native_test.rb +1 -1
- metadata +5 -5
- data/ext/libsass/include/sass/interface.h +0 -105
- data/ext/libsass/src/sass_interface.cpp +0 -215
data/ext/libsass/src/parser.hpp
CHANGED
@@ -133,6 +133,8 @@ namespace Sass {
|
|
133
133
|
const char* lex(bool lazy = true, bool force = false)
|
134
134
|
{
|
135
135
|
|
136
|
+
if (*position == 0) return 0;
|
137
|
+
|
136
138
|
// position considered before lexed token
|
137
139
|
// we can skip whitespace or comments for
|
138
140
|
// lazy developers (but we need control)
|
@@ -298,12 +300,22 @@ namespace Sass {
|
|
298
300
|
Supports_Condition* parse_supports_declaration();
|
299
301
|
Supports_Condition* parse_supports_condition_in_parens();
|
300
302
|
At_Root_Block* parse_at_root_block();
|
301
|
-
|
302
|
-
|
303
|
+
At_Root_Query* parse_at_root_query();
|
304
|
+
String_Schema* parse_almost_any_value();
|
305
|
+
Directive* parse_special_directive();
|
306
|
+
Directive* parse_prefixed_directive();
|
307
|
+
Directive* parse_directive();
|
303
308
|
Warning* parse_warning();
|
304
309
|
Error* parse_error();
|
305
310
|
Debug* parse_debug();
|
306
311
|
|
312
|
+
// be more like ruby sass
|
313
|
+
Expression* lex_almost_any_value_token();
|
314
|
+
Expression* lex_almost_any_value_chars();
|
315
|
+
Expression* lex_interp_string();
|
316
|
+
Expression* lex_interp_uri();
|
317
|
+
Expression* lex_interpolation();
|
318
|
+
|
307
319
|
// these will throw errors
|
308
320
|
Token lex_variable();
|
309
321
|
Token lex_identifier();
|
@@ -319,6 +331,34 @@ namespace Sass {
|
|
319
331
|
|
320
332
|
void throw_syntax_error(std::string message, size_t ln = 0);
|
321
333
|
void throw_read_error(std::string message, size_t ln = 0);
|
334
|
+
|
335
|
+
|
336
|
+
template <Prelexer::prelexer open, Prelexer::prelexer close>
|
337
|
+
Expression* lex_interp()
|
338
|
+
{
|
339
|
+
if (lex < open >(false)) {
|
340
|
+
String_Schema* schema = SASS_MEMORY_NEW(ctx.mem, String_Schema, pstate);
|
341
|
+
// std::cerr << "LEX [[" << std::string(lexed) << "]]\n";
|
342
|
+
*schema << SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, lexed);
|
343
|
+
if (position[0] == '#' && position[1] == '{') {
|
344
|
+
Expression* itpl = lex_interpolation();
|
345
|
+
if (itpl) *schema << itpl;
|
346
|
+
while (lex < close >(false)) {
|
347
|
+
// std::cerr << "LEX [[" << std::string(lexed) << "]]\n";
|
348
|
+
*schema << SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, lexed);
|
349
|
+
if (position[0] == '#' && position[1] == '{') {
|
350
|
+
Expression* itpl = lex_interpolation();
|
351
|
+
if (itpl) *schema << itpl;
|
352
|
+
} else {
|
353
|
+
return schema;
|
354
|
+
}
|
355
|
+
}
|
356
|
+
} else {
|
357
|
+
return SASS_MEMORY_NEW(ctx.mem, String_Constant, pstate, lexed);
|
358
|
+
}
|
359
|
+
}
|
360
|
+
return 0;
|
361
|
+
}
|
322
362
|
};
|
323
363
|
|
324
364
|
size_t check_bom_chars(const char* src, const char *end, const unsigned char* bom, size_t len);
|
@@ -16,6 +16,248 @@ namespace Sass {
|
|
16
16
|
namespace Prelexer {
|
17
17
|
|
18
18
|
|
19
|
+
/*
|
20
|
+
|
21
|
+
def string_re(open, close)
|
22
|
+
/#{open}((?:\\.|\#(?!\{)|[^#{close}\\#])*)(#{close}|#\{)/m
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# A hash of regular expressions that are used for tokenizing strings.
|
27
|
+
#
|
28
|
+
# The key is a `[Symbol, Boolean]` pair.
|
29
|
+
# The symbol represents which style of quotation to use,
|
30
|
+
# while the boolean represents whether or not the string
|
31
|
+
# is following an interpolated segment.
|
32
|
+
STRING_REGULAR_EXPRESSIONS = {
|
33
|
+
:double => {
|
34
|
+
/#{open}((?:\\.|\#(?!\{)|[^#{close}\\#])*)(#{close}|#\{)/m
|
35
|
+
false => string_re('"', '"'),
|
36
|
+
true => string_re('', '"')
|
37
|
+
},
|
38
|
+
:single => {
|
39
|
+
false => string_re("'", "'"),
|
40
|
+
true => string_re('', "'")
|
41
|
+
},
|
42
|
+
:uri => {
|
43
|
+
false => /url\(#{W}(#{URLCHAR}*?)(#{W}\)|#\{)/,
|
44
|
+
true => /(#{URLCHAR}*?)(#{W}\)|#\{)/
|
45
|
+
},
|
46
|
+
# Defined in https://developer.mozilla.org/en/CSS/@-moz-document as a
|
47
|
+
# non-standard version of http://www.w3.org/TR/css3-conditional/
|
48
|
+
:url_prefix => {
|
49
|
+
false => /url-prefix\(#{W}(#{URLCHAR}*?)(#{W}\)|#\{)/,
|
50
|
+
true => /(#{URLCHAR}*?)(#{W}\)|#\{)/
|
51
|
+
},
|
52
|
+
:domain => {
|
53
|
+
false => /domain\(#{W}(#{URLCHAR}*?)(#{W}\)|#\{)/,
|
54
|
+
true => /(#{URLCHAR}*?)(#{W}\)|#\{)/
|
55
|
+
}
|
56
|
+
}
|
57
|
+
*/
|
58
|
+
|
59
|
+
/*
|
60
|
+
/#{open}
|
61
|
+
(
|
62
|
+
\\.
|
63
|
+
|
|
64
|
+
\# (?!\{)
|
65
|
+
|
|
66
|
+
[^#{close}\\#]
|
67
|
+
)*
|
68
|
+
(#{close}|#\{)
|
69
|
+
/m
|
70
|
+
false => string_re('"', '"'),
|
71
|
+
true => string_re('', '"')
|
72
|
+
*/
|
73
|
+
extern const char string_double_negates[] = "\"\\#";
|
74
|
+
const char* re_string_double_close(const char* src)
|
75
|
+
{
|
76
|
+
return sequence <
|
77
|
+
// valid chars
|
78
|
+
zero_plus <
|
79
|
+
alternatives <
|
80
|
+
// escaped char
|
81
|
+
sequence <
|
82
|
+
exactly <'\\'>,
|
83
|
+
any_char
|
84
|
+
>,
|
85
|
+
// non interpolate hash
|
86
|
+
sequence <
|
87
|
+
exactly <'#'>,
|
88
|
+
negate <
|
89
|
+
exactly <'{'>
|
90
|
+
>
|
91
|
+
>,
|
92
|
+
// other valid chars
|
93
|
+
neg_class_char <
|
94
|
+
string_double_negates
|
95
|
+
>
|
96
|
+
>
|
97
|
+
>,
|
98
|
+
// quoted string closer
|
99
|
+
// or interpolate opening
|
100
|
+
alternatives <
|
101
|
+
exactly <'"'>,
|
102
|
+
lookahead < exactly< hash_lbrace > >
|
103
|
+
>
|
104
|
+
>(src);
|
105
|
+
}
|
106
|
+
|
107
|
+
const char* re_string_double_open(const char* src)
|
108
|
+
{
|
109
|
+
return sequence <
|
110
|
+
// quoted string opener
|
111
|
+
exactly <'"'>,
|
112
|
+
// valid chars
|
113
|
+
zero_plus <
|
114
|
+
alternatives <
|
115
|
+
// escaped char
|
116
|
+
sequence <
|
117
|
+
exactly <'\\'>,
|
118
|
+
any_char
|
119
|
+
>,
|
120
|
+
// non interpolate hash
|
121
|
+
sequence <
|
122
|
+
exactly <'#'>,
|
123
|
+
negate <
|
124
|
+
exactly <'{'>
|
125
|
+
>
|
126
|
+
>,
|
127
|
+
// other valid chars
|
128
|
+
neg_class_char <
|
129
|
+
string_double_negates
|
130
|
+
>
|
131
|
+
>
|
132
|
+
>,
|
133
|
+
// quoted string closer
|
134
|
+
// or interpolate opening
|
135
|
+
alternatives <
|
136
|
+
exactly <'"'>,
|
137
|
+
lookahead < exactly< hash_lbrace > >
|
138
|
+
>
|
139
|
+
>(src);
|
140
|
+
}
|
141
|
+
|
142
|
+
extern const char string_single_negates[] = "'\\#";
|
143
|
+
const char* re_string_single_close(const char* src)
|
144
|
+
{
|
145
|
+
return sequence <
|
146
|
+
// valid chars
|
147
|
+
zero_plus <
|
148
|
+
alternatives <
|
149
|
+
// escaped char
|
150
|
+
sequence <
|
151
|
+
exactly <'\\'>,
|
152
|
+
any_char
|
153
|
+
>,
|
154
|
+
// non interpolate hash
|
155
|
+
sequence <
|
156
|
+
exactly <'#'>,
|
157
|
+
negate <
|
158
|
+
exactly <'{'>
|
159
|
+
>
|
160
|
+
>,
|
161
|
+
// other valid chars
|
162
|
+
neg_class_char <
|
163
|
+
string_single_negates
|
164
|
+
>
|
165
|
+
>
|
166
|
+
>,
|
167
|
+
// quoted string closer
|
168
|
+
// or interpolate opening
|
169
|
+
alternatives <
|
170
|
+
exactly <'\''>,
|
171
|
+
lookahead < exactly< hash_lbrace > >
|
172
|
+
>
|
173
|
+
>(src);
|
174
|
+
}
|
175
|
+
|
176
|
+
const char* re_string_single_open(const char* src)
|
177
|
+
{
|
178
|
+
return sequence <
|
179
|
+
// quoted string opener
|
180
|
+
exactly <'\''>,
|
181
|
+
// valid chars
|
182
|
+
zero_plus <
|
183
|
+
alternatives <
|
184
|
+
// escaped char
|
185
|
+
sequence <
|
186
|
+
exactly <'\\'>,
|
187
|
+
any_char
|
188
|
+
>,
|
189
|
+
// non interpolate hash
|
190
|
+
sequence <
|
191
|
+
exactly <'#'>,
|
192
|
+
negate <
|
193
|
+
exactly <'{'>
|
194
|
+
>
|
195
|
+
>,
|
196
|
+
// other valid chars
|
197
|
+
neg_class_char <
|
198
|
+
string_single_negates
|
199
|
+
>
|
200
|
+
>
|
201
|
+
>,
|
202
|
+
// quoted string closer
|
203
|
+
// or interpolate opening
|
204
|
+
alternatives <
|
205
|
+
exactly <'\''>,
|
206
|
+
lookahead < exactly< hash_lbrace > >
|
207
|
+
>
|
208
|
+
>(src);
|
209
|
+
}
|
210
|
+
|
211
|
+
/*
|
212
|
+
:uri => {
|
213
|
+
false => /url\(#{W}(#{URLCHAR}*?)(#{W}\)|#\{)/,
|
214
|
+
true => /(#{URLCHAR}*?)(#{W}\)|#\{)/
|
215
|
+
},
|
216
|
+
*/
|
217
|
+
const char* re_string_uri_close(const char* src)
|
218
|
+
{
|
219
|
+
return sequence <
|
220
|
+
non_greedy<
|
221
|
+
alternatives<
|
222
|
+
class_char< real_uri_chars >,
|
223
|
+
uri_character,
|
224
|
+
NONASCII,
|
225
|
+
ESCAPE
|
226
|
+
>,
|
227
|
+
alternatives<
|
228
|
+
sequence < optional < W >, exactly <')'> >,
|
229
|
+
lookahead < exactly< hash_lbrace > >
|
230
|
+
>
|
231
|
+
>,
|
232
|
+
optional <
|
233
|
+
sequence < optional < W >, exactly <')'> >
|
234
|
+
>
|
235
|
+
>(src);
|
236
|
+
}
|
237
|
+
|
238
|
+
const char* re_string_uri_open(const char* src)
|
239
|
+
{
|
240
|
+
return sequence <
|
241
|
+
exactly <'u'>,
|
242
|
+
exactly <'r'>,
|
243
|
+
exactly <'l'>,
|
244
|
+
exactly <'('>,
|
245
|
+
W,
|
246
|
+
non_greedy<
|
247
|
+
alternatives<
|
248
|
+
class_char< real_uri_chars >,
|
249
|
+
uri_character,
|
250
|
+
NONASCII,
|
251
|
+
ESCAPE
|
252
|
+
>,
|
253
|
+
alternatives<
|
254
|
+
sequence < W, exactly <')'> >,
|
255
|
+
exactly< hash_lbrace >
|
256
|
+
>
|
257
|
+
>
|
258
|
+
>(src);
|
259
|
+
}
|
260
|
+
|
19
261
|
// Match a line comment (/.*?(?=\n|\r\n?|\Z)/.
|
20
262
|
const char* line_comment(const char* src)
|
21
263
|
{
|
@@ -370,6 +612,133 @@ namespace Sass {
|
|
370
612
|
return sequence<exactly<'@'>, identifier>(src);
|
371
613
|
}
|
372
614
|
|
615
|
+
/*
|
616
|
+
tok(%r{
|
617
|
+
(
|
618
|
+
\\.
|
619
|
+
|
|
620
|
+
(?!url\()
|
621
|
+
[^"'/\#!;\{\}] # "
|
622
|
+
|
|
623
|
+
/(?![\*\/])
|
624
|
+
|
|
625
|
+
\#(?!\{)
|
626
|
+
|
|
627
|
+
!(?![a-z]) # TODO: never consume "!" when issue 1126 is fixed.
|
628
|
+
)+
|
629
|
+
}xi) || tok(COMMENT) || tok(SINGLE_LINE_COMMENT) || interp_string || interp_uri ||
|
630
|
+
interpolation(:warn_for_color)
|
631
|
+
*/
|
632
|
+
const char* re_almost_any_value_token(const char* src) {
|
633
|
+
|
634
|
+
return alternatives <
|
635
|
+
one_plus <
|
636
|
+
alternatives <
|
637
|
+
sequence <
|
638
|
+
exactly <'\\'>,
|
639
|
+
any_char
|
640
|
+
>,
|
641
|
+
sequence <
|
642
|
+
negate <
|
643
|
+
sequence <
|
644
|
+
exactly < url_kwd >,
|
645
|
+
exactly <'('>
|
646
|
+
>
|
647
|
+
>,
|
648
|
+
neg_class_char <
|
649
|
+
almost_any_value_class
|
650
|
+
>
|
651
|
+
>,
|
652
|
+
sequence <
|
653
|
+
exactly <'/'>,
|
654
|
+
negate <
|
655
|
+
alternatives <
|
656
|
+
exactly <'/'>,
|
657
|
+
exactly <'*'>
|
658
|
+
>
|
659
|
+
>
|
660
|
+
>,
|
661
|
+
sequence <
|
662
|
+
exactly <'\\'>,
|
663
|
+
exactly <'#'>,
|
664
|
+
negate <
|
665
|
+
exactly <'{'>
|
666
|
+
>
|
667
|
+
>,
|
668
|
+
sequence <
|
669
|
+
exactly <'!'>,
|
670
|
+
negate <
|
671
|
+
alpha
|
672
|
+
>
|
673
|
+
>
|
674
|
+
>
|
675
|
+
>,
|
676
|
+
block_comment,
|
677
|
+
line_comment,
|
678
|
+
interpolant,
|
679
|
+
space,
|
680
|
+
sequence <
|
681
|
+
exactly<'u'>,
|
682
|
+
exactly<'r'>,
|
683
|
+
exactly<'l'>,
|
684
|
+
exactly<'('>,
|
685
|
+
zero_plus <
|
686
|
+
alternatives <
|
687
|
+
class_char< real_uri_chars >,
|
688
|
+
uri_character,
|
689
|
+
NONASCII,
|
690
|
+
ESCAPE
|
691
|
+
>
|
692
|
+
>,
|
693
|
+
// false => /url\(#{W}(#{URLCHAR}*?)(#{W}\)|#\{)/,
|
694
|
+
// true => /(#{URLCHAR}*?)(#{W}\)|#\{)/
|
695
|
+
exactly<')'>
|
696
|
+
>
|
697
|
+
>(src);
|
698
|
+
}
|
699
|
+
|
700
|
+
/*
|
701
|
+
DIRECTIVES = Set[:mixin, :include, :function, :return, :debug, :warn, :for,
|
702
|
+
:each, :while, :if, :else, :extend, :import, :media, :charset, :content,
|
703
|
+
:_moz_document, :at_root, :error]
|
704
|
+
*/
|
705
|
+
const char* re_special_directive(const char* src) {
|
706
|
+
return alternatives <
|
707
|
+
word < mixin_kwd >,
|
708
|
+
word < include_kwd >,
|
709
|
+
word < function_kwd >,
|
710
|
+
word < return_kwd >,
|
711
|
+
word < debug_kwd >,
|
712
|
+
word < warn_kwd >,
|
713
|
+
word < for_kwd >,
|
714
|
+
word < each_kwd >,
|
715
|
+
word < while_kwd >,
|
716
|
+
word < if_kwd >,
|
717
|
+
word < else_kwd >,
|
718
|
+
word < extend_kwd >,
|
719
|
+
word < import_kwd >,
|
720
|
+
word < media_kwd >,
|
721
|
+
word < charset_kwd >,
|
722
|
+
word < content_kwd >,
|
723
|
+
// exactly < moz_document_kwd >,
|
724
|
+
word < at_root_kwd >,
|
725
|
+
word < error_kwd >
|
726
|
+
>(src);
|
727
|
+
}
|
728
|
+
|
729
|
+
const char* re_prefixed_directive(const char* src) {
|
730
|
+
return sequence <
|
731
|
+
optional <
|
732
|
+
sequence <
|
733
|
+
exactly <'-'>,
|
734
|
+
one_plus < alnum >,
|
735
|
+
exactly <'-'>
|
736
|
+
>
|
737
|
+
>,
|
738
|
+
exactly < supports_kwd >
|
739
|
+
>(src);
|
740
|
+
}
|
741
|
+
|
373
742
|
const char* re_reference_combinator(const char* src) {
|
374
743
|
return sequence <
|
375
744
|
optional <
|
@@ -508,7 +877,7 @@ namespace Sass {
|
|
508
877
|
return one_plus< alternatives< alnum,
|
509
878
|
exactly<'-'>,
|
510
879
|
exactly<'_'>,
|
511
|
-
|
880
|
+
escape_seq > >(src);
|
512
881
|
}
|
513
882
|
|
514
883
|
const char* kwd_warn(const char* src) {
|
@@ -586,7 +955,7 @@ namespace Sass {
|
|
586
955
|
}
|
587
956
|
|
588
957
|
const char* hyphens_and_identifier(const char* src) {
|
589
|
-
return sequence< zero_plus< exactly< '-' > >,
|
958
|
+
return sequence< zero_plus< exactly< '-' > >, identifier_alnums >(src);
|
590
959
|
}
|
591
960
|
const char* hyphens_and_name(const char* src) {
|
592
961
|
return sequence< zero_plus< exactly< '-' > >, name >(src);
|
@@ -596,11 +965,11 @@ namespace Sass {
|
|
596
965
|
}
|
597
966
|
// Match CSS id names.
|
598
967
|
const char* id_name(const char* src) {
|
599
|
-
return sequence<exactly<'#'>,
|
968
|
+
return sequence<exactly<'#'>, identifier_alnums >(src);
|
600
969
|
}
|
601
970
|
// Match CSS class names.
|
602
971
|
const char* class_name(const char* src) {
|
603
|
-
return sequence<exactly<'.'>, identifier>(src);
|
972
|
+
return sequence<exactly<'.'>, identifier >(src);
|
604
973
|
}
|
605
974
|
// Attribute name in an attribute selector.
|
606
975
|
const char* attribute_name(const char* src) {
|
@@ -609,7 +978,7 @@ namespace Sass {
|
|
609
978
|
}
|
610
979
|
// match placeholder selectors
|
611
980
|
const char* placeholder(const char* src) {
|
612
|
-
return sequence<exactly<'%'>,
|
981
|
+
return sequence<exactly<'%'>, identifier_alnums >(src);
|
613
982
|
}
|
614
983
|
// Match CSS numeric constants.
|
615
984
|
|
@@ -825,6 +1194,22 @@ namespace Sass {
|
|
825
1194
|
return sequence<exactly<'$'>, identifier>(src);
|
826
1195
|
}
|
827
1196
|
|
1197
|
+
// parse `calc`, `-a-calc` and `--b-c-calc`
|
1198
|
+
// but do not parse `foocalc` or `foo-calc`
|
1199
|
+
const char* calc_fn_call(const char* src) {
|
1200
|
+
return sequence <
|
1201
|
+
optional < sequence <
|
1202
|
+
hyphens,
|
1203
|
+
one_plus < sequence <
|
1204
|
+
strict_identifier,
|
1205
|
+
hyphens
|
1206
|
+
> >
|
1207
|
+
> >,
|
1208
|
+
exactly < calc_fn_kwd >,
|
1209
|
+
word_boundary
|
1210
|
+
>(src);
|
1211
|
+
}
|
1212
|
+
|
828
1213
|
// Match Sass boolean keywords.
|
829
1214
|
const char* kwd_true(const char* src) {
|
830
1215
|
return word<true_kwd>(src);
|
@@ -1167,6 +1552,83 @@ namespace Sass {
|
|
1167
1552
|
>(src);
|
1168
1553
|
}
|
1169
1554
|
|
1555
|
+
const char* re_selector_list(const char* src) {
|
1556
|
+
return alternatives <
|
1557
|
+
// partial bem selector
|
1558
|
+
sequence <
|
1559
|
+
ampersand,
|
1560
|
+
one_plus <
|
1561
|
+
exactly < '-' >
|
1562
|
+
>,
|
1563
|
+
word_boundary,
|
1564
|
+
optional_spaces
|
1565
|
+
>,
|
1566
|
+
// main selector matching
|
1567
|
+
one_plus <
|
1568
|
+
alternatives <
|
1569
|
+
// consume whitespace and comments
|
1570
|
+
spaces, block_comment, line_comment,
|
1571
|
+
// match `/deep/` selector (pass-trough)
|
1572
|
+
// there is no functionality for it yet
|
1573
|
+
schema_reference_combinator,
|
1574
|
+
// match selector ops /[*&%,\[\]]/
|
1575
|
+
class_char < selector_lookahead_ops >,
|
1576
|
+
// match selector combinators /[>+~]/
|
1577
|
+
class_char < selector_combinator_ops >,
|
1578
|
+
// match attribute compare operators
|
1579
|
+
sequence <
|
1580
|
+
exactly <'('>,
|
1581
|
+
optional_spaces,
|
1582
|
+
optional <re_selector_list>,
|
1583
|
+
optional_spaces,
|
1584
|
+
exactly <')'>
|
1585
|
+
>,
|
1586
|
+
alternatives <
|
1587
|
+
exact_match, class_match, dash_match,
|
1588
|
+
prefix_match, suffix_match, substring_match
|
1589
|
+
>,
|
1590
|
+
// main selector match
|
1591
|
+
sequence <
|
1592
|
+
// allow namespace prefix
|
1593
|
+
optional < namespace_schema >,
|
1594
|
+
// modifiers prefixes
|
1595
|
+
alternatives <
|
1596
|
+
sequence <
|
1597
|
+
exactly <'#'>,
|
1598
|
+
// not for interpolation
|
1599
|
+
negate < exactly <'{'> >
|
1600
|
+
>,
|
1601
|
+
// class match
|
1602
|
+
exactly <'.'>,
|
1603
|
+
// single or double colon
|
1604
|
+
optional < pseudo_prefix >
|
1605
|
+
>,
|
1606
|
+
// accept hypens in token
|
1607
|
+
one_plus < sequence <
|
1608
|
+
// can start with hyphens
|
1609
|
+
zero_plus < exactly<'-'> >,
|
1610
|
+
// now the main token
|
1611
|
+
alternatives <
|
1612
|
+
kwd_optional,
|
1613
|
+
exactly <'*'>,
|
1614
|
+
quoted_string,
|
1615
|
+
interpolant,
|
1616
|
+
identifier,
|
1617
|
+
variable,
|
1618
|
+
percentage,
|
1619
|
+
binomial,
|
1620
|
+
dimension,
|
1621
|
+
alnum
|
1622
|
+
>
|
1623
|
+
> >,
|
1624
|
+
// can also end with hyphens
|
1625
|
+
zero_plus < exactly<'-'> >
|
1626
|
+
>
|
1627
|
+
>
|
1628
|
+
>
|
1629
|
+
>(src);
|
1630
|
+
}
|
1631
|
+
|
1170
1632
|
const char* type_selector(const char* src) {
|
1171
1633
|
return sequence< optional<namespace_schema>, identifier>(src);
|
1172
1634
|
}
|
@@ -1183,6 +1645,12 @@ namespace Sass {
|
|
1183
1645
|
// lexer special_fn: these functions cannot be overloaded
|
1184
1646
|
// (/((-[\w-]+-)?(calc|element)|expression|progid:[a-z\.]*)\(/i)
|
1185
1647
|
const char* re_special_fun(const char* src) {
|
1648
|
+
|
1649
|
+
// match this first as we test prefix hyphens
|
1650
|
+
if (const char* calc = calc_fn_call(src)) {
|
1651
|
+
return calc;
|
1652
|
+
}
|
1653
|
+
|
1186
1654
|
return sequence <
|
1187
1655
|
optional <
|
1188
1656
|
sequence <
|
@@ -1197,8 +1665,7 @@ namespace Sass {
|
|
1197
1665
|
>
|
1198
1666
|
>,
|
1199
1667
|
alternatives <
|
1200
|
-
|
1201
|
-
exactly < expression_kwd >,
|
1668
|
+
word < expression_kwd >,
|
1202
1669
|
sequence <
|
1203
1670
|
sequence <
|
1204
1671
|
exactly < progid_kwd >,
|