sassc4 2.4.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.
Files changed (216) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.gitmodules +3 -0
  4. data/.travis.yml +16 -0
  5. data/CHANGELOG.md +97 -0
  6. data/CODE_OF_CONDUCT.md +10 -0
  7. data/Gemfile +2 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +80 -0
  10. data/Rakefile +51 -0
  11. data/ext/depend +4 -0
  12. data/ext/extconf.rb +92 -0
  13. data/ext/libsass/VERSION +1 -0
  14. data/ext/libsass/contrib/plugin.cpp +60 -0
  15. data/ext/libsass/include/sass/base.h +97 -0
  16. data/ext/libsass/include/sass/context.h +174 -0
  17. data/ext/libsass/include/sass/functions.h +139 -0
  18. data/ext/libsass/include/sass/values.h +145 -0
  19. data/ext/libsass/include/sass/version.h +12 -0
  20. data/ext/libsass/include/sass.h +15 -0
  21. data/ext/libsass/include/sass2scss.h +120 -0
  22. data/ext/libsass/src/MurmurHash2.hpp +91 -0
  23. data/ext/libsass/src/ast.cpp +953 -0
  24. data/ext/libsass/src/ast.hpp +1064 -0
  25. data/ext/libsass/src/ast2c.cpp +80 -0
  26. data/ext/libsass/src/ast2c.hpp +39 -0
  27. data/ext/libsass/src/ast_def_macros.hpp +140 -0
  28. data/ext/libsass/src/ast_fwd_decl.cpp +31 -0
  29. data/ext/libsass/src/ast_fwd_decl.hpp +274 -0
  30. data/ext/libsass/src/ast_helpers.hpp +316 -0
  31. data/ext/libsass/src/ast_sel_cmp.cpp +396 -0
  32. data/ext/libsass/src/ast_sel_super.cpp +539 -0
  33. data/ext/libsass/src/ast_sel_unify.cpp +275 -0
  34. data/ext/libsass/src/ast_sel_weave.cpp +616 -0
  35. data/ext/libsass/src/ast_selectors.cpp +1070 -0
  36. data/ext/libsass/src/ast_selectors.hpp +523 -0
  37. data/ext/libsass/src/ast_supports.cpp +114 -0
  38. data/ext/libsass/src/ast_supports.hpp +121 -0
  39. data/ext/libsass/src/ast_values.cpp +1154 -0
  40. data/ext/libsass/src/ast_values.hpp +498 -0
  41. data/ext/libsass/src/b64/cencode.h +32 -0
  42. data/ext/libsass/src/b64/encode.h +79 -0
  43. data/ext/libsass/src/backtrace.cpp +50 -0
  44. data/ext/libsass/src/backtrace.hpp +29 -0
  45. data/ext/libsass/src/base64vlq.cpp +47 -0
  46. data/ext/libsass/src/base64vlq.hpp +30 -0
  47. data/ext/libsass/src/bind.cpp +312 -0
  48. data/ext/libsass/src/bind.hpp +15 -0
  49. data/ext/libsass/src/c2ast.cpp +64 -0
  50. data/ext/libsass/src/c2ast.hpp +14 -0
  51. data/ext/libsass/src/c99func.c +54 -0
  52. data/ext/libsass/src/cencode.c +106 -0
  53. data/ext/libsass/src/check_nesting.cpp +393 -0
  54. data/ext/libsass/src/check_nesting.hpp +70 -0
  55. data/ext/libsass/src/color_maps.cpp +652 -0
  56. data/ext/libsass/src/color_maps.hpp +323 -0
  57. data/ext/libsass/src/color_spaces.cpp +241 -0
  58. data/ext/libsass/src/color_spaces.hpp +227 -0
  59. data/ext/libsass/src/constants.cpp +199 -0
  60. data/ext/libsass/src/constants.hpp +200 -0
  61. data/ext/libsass/src/context.cpp +870 -0
  62. data/ext/libsass/src/context.hpp +140 -0
  63. data/ext/libsass/src/cssize.cpp +521 -0
  64. data/ext/libsass/src/cssize.hpp +71 -0
  65. data/ext/libsass/src/dart_helpers.hpp +199 -0
  66. data/ext/libsass/src/debug.hpp +43 -0
  67. data/ext/libsass/src/debugger.hpp +964 -0
  68. data/ext/libsass/src/emitter.cpp +297 -0
  69. data/ext/libsass/src/emitter.hpp +101 -0
  70. data/ext/libsass/src/environment.cpp +260 -0
  71. data/ext/libsass/src/environment.hpp +124 -0
  72. data/ext/libsass/src/error_handling.cpp +239 -0
  73. data/ext/libsass/src/error_handling.hpp +248 -0
  74. data/ext/libsass/src/eval.cpp +1543 -0
  75. data/ext/libsass/src/eval.hpp +110 -0
  76. data/ext/libsass/src/eval_selectors.cpp +75 -0
  77. data/ext/libsass/src/expand.cpp +875 -0
  78. data/ext/libsass/src/expand.hpp +98 -0
  79. data/ext/libsass/src/extender.cpp +1226 -0
  80. data/ext/libsass/src/extender.hpp +399 -0
  81. data/ext/libsass/src/extension.cpp +43 -0
  82. data/ext/libsass/src/extension.hpp +89 -0
  83. data/ext/libsass/src/file.cpp +531 -0
  84. data/ext/libsass/src/file.hpp +124 -0
  85. data/ext/libsass/src/fn_colors.cpp +836 -0
  86. data/ext/libsass/src/fn_colors.hpp +99 -0
  87. data/ext/libsass/src/fn_lists.cpp +285 -0
  88. data/ext/libsass/src/fn_lists.hpp +34 -0
  89. data/ext/libsass/src/fn_maps.cpp +94 -0
  90. data/ext/libsass/src/fn_maps.hpp +30 -0
  91. data/ext/libsass/src/fn_miscs.cpp +248 -0
  92. data/ext/libsass/src/fn_miscs.hpp +40 -0
  93. data/ext/libsass/src/fn_numbers.cpp +246 -0
  94. data/ext/libsass/src/fn_numbers.hpp +45 -0
  95. data/ext/libsass/src/fn_selectors.cpp +205 -0
  96. data/ext/libsass/src/fn_selectors.hpp +35 -0
  97. data/ext/libsass/src/fn_strings.cpp +268 -0
  98. data/ext/libsass/src/fn_strings.hpp +34 -0
  99. data/ext/libsass/src/fn_utils.cpp +159 -0
  100. data/ext/libsass/src/fn_utils.hpp +62 -0
  101. data/ext/libsass/src/inspect.cpp +1126 -0
  102. data/ext/libsass/src/inspect.hpp +101 -0
  103. data/ext/libsass/src/json.cpp +1436 -0
  104. data/ext/libsass/src/json.hpp +117 -0
  105. data/ext/libsass/src/kwd_arg_macros.hpp +28 -0
  106. data/ext/libsass/src/lexer.cpp +122 -0
  107. data/ext/libsass/src/lexer.hpp +304 -0
  108. data/ext/libsass/src/listize.cpp +70 -0
  109. data/ext/libsass/src/listize.hpp +37 -0
  110. data/ext/libsass/src/mapping.hpp +19 -0
  111. data/ext/libsass/src/memory/allocator.cpp +48 -0
  112. data/ext/libsass/src/memory/allocator.hpp +138 -0
  113. data/ext/libsass/src/memory/config.hpp +20 -0
  114. data/ext/libsass/src/memory/memory_pool.hpp +186 -0
  115. data/ext/libsass/src/memory/shared_ptr.cpp +33 -0
  116. data/ext/libsass/src/memory/shared_ptr.hpp +332 -0
  117. data/ext/libsass/src/memory.hpp +12 -0
  118. data/ext/libsass/src/operation.hpp +223 -0
  119. data/ext/libsass/src/operators.cpp +267 -0
  120. data/ext/libsass/src/operators.hpp +30 -0
  121. data/ext/libsass/src/ordered_map.hpp +112 -0
  122. data/ext/libsass/src/output.cpp +320 -0
  123. data/ext/libsass/src/output.hpp +47 -0
  124. data/ext/libsass/src/parser.cpp +3059 -0
  125. data/ext/libsass/src/parser.hpp +395 -0
  126. data/ext/libsass/src/parser_selectors.cpp +189 -0
  127. data/ext/libsass/src/permutate.hpp +164 -0
  128. data/ext/libsass/src/plugins.cpp +188 -0
  129. data/ext/libsass/src/plugins.hpp +57 -0
  130. data/ext/libsass/src/position.cpp +163 -0
  131. data/ext/libsass/src/position.hpp +147 -0
  132. data/ext/libsass/src/prelexer.cpp +1780 -0
  133. data/ext/libsass/src/prelexer.hpp +484 -0
  134. data/ext/libsass/src/remove_placeholders.cpp +86 -0
  135. data/ext/libsass/src/remove_placeholders.hpp +37 -0
  136. data/ext/libsass/src/sass.cpp +156 -0
  137. data/ext/libsass/src/sass.hpp +147 -0
  138. data/ext/libsass/src/sass2scss.cpp +895 -0
  139. data/ext/libsass/src/sass_context.cpp +742 -0
  140. data/ext/libsass/src/sass_context.hpp +129 -0
  141. data/ext/libsass/src/sass_functions.cpp +210 -0
  142. data/ext/libsass/src/sass_functions.hpp +50 -0
  143. data/ext/libsass/src/sass_values.cpp +362 -0
  144. data/ext/libsass/src/sass_values.hpp +82 -0
  145. data/ext/libsass/src/settings.hpp +19 -0
  146. data/ext/libsass/src/source.cpp +69 -0
  147. data/ext/libsass/src/source.hpp +95 -0
  148. data/ext/libsass/src/source_data.hpp +32 -0
  149. data/ext/libsass/src/source_map.cpp +202 -0
  150. data/ext/libsass/src/source_map.hpp +65 -0
  151. data/ext/libsass/src/stylesheet.cpp +22 -0
  152. data/ext/libsass/src/stylesheet.hpp +57 -0
  153. data/ext/libsass/src/to_value.cpp +114 -0
  154. data/ext/libsass/src/to_value.hpp +46 -0
  155. data/ext/libsass/src/units.cpp +507 -0
  156. data/ext/libsass/src/units.hpp +110 -0
  157. data/ext/libsass/src/utf8/checked.h +336 -0
  158. data/ext/libsass/src/utf8/core.h +332 -0
  159. data/ext/libsass/src/utf8/unchecked.h +235 -0
  160. data/ext/libsass/src/utf8.h +34 -0
  161. data/ext/libsass/src/utf8_string.cpp +104 -0
  162. data/ext/libsass/src/utf8_string.hpp +38 -0
  163. data/ext/libsass/src/util.cpp +723 -0
  164. data/ext/libsass/src/util.hpp +105 -0
  165. data/ext/libsass/src/util_string.cpp +125 -0
  166. data/ext/libsass/src/util_string.hpp +73 -0
  167. data/ext/libsass/src/values.cpp +140 -0
  168. data/ext/libsass/src/values.hpp +12 -0
  169. data/lib/sassc/dependency.rb +17 -0
  170. data/lib/sassc/engine.rb +141 -0
  171. data/lib/sassc/error.rb +37 -0
  172. data/lib/sassc/functions_handler.rb +73 -0
  173. data/lib/sassc/import_handler.rb +50 -0
  174. data/lib/sassc/importer.rb +31 -0
  175. data/lib/sassc/native/native_context_api.rb +147 -0
  176. data/lib/sassc/native/native_functions_api.rb +159 -0
  177. data/lib/sassc/native/sass2scss_api.rb +10 -0
  178. data/lib/sassc/native/sass_input_style.rb +13 -0
  179. data/lib/sassc/native/sass_output_style.rb +12 -0
  180. data/lib/sassc/native/sass_value.rb +97 -0
  181. data/lib/sassc/native/string_list.rb +10 -0
  182. data/lib/sassc/native.rb +64 -0
  183. data/lib/sassc/sass_2_scss.rb +9 -0
  184. data/lib/sassc/script/functions.rb +8 -0
  185. data/lib/sassc/script/value/bool.rb +32 -0
  186. data/lib/sassc/script/value/color.rb +95 -0
  187. data/lib/sassc/script/value/list.rb +136 -0
  188. data/lib/sassc/script/value/map.rb +69 -0
  189. data/lib/sassc/script/value/number.rb +389 -0
  190. data/lib/sassc/script/value/string.rb +96 -0
  191. data/lib/sassc/script/value.rb +137 -0
  192. data/lib/sassc/script/value_conversion/base.rb +13 -0
  193. data/lib/sassc/script/value_conversion/bool.rb +13 -0
  194. data/lib/sassc/script/value_conversion/color.rb +18 -0
  195. data/lib/sassc/script/value_conversion/list.rb +25 -0
  196. data/lib/sassc/script/value_conversion/map.rb +21 -0
  197. data/lib/sassc/script/value_conversion/number.rb +13 -0
  198. data/lib/sassc/script/value_conversion/string.rb +17 -0
  199. data/lib/sassc/script/value_conversion.rb +69 -0
  200. data/lib/sassc/script.rb +17 -0
  201. data/lib/sassc/util/normalized_map.rb +117 -0
  202. data/lib/sassc/util.rb +231 -0
  203. data/lib/sassc/version.rb +5 -0
  204. data/lib/sassc.rb +57 -0
  205. data/sassc.gemspec +69 -0
  206. data/test/css_color_level4_test.rb +168 -0
  207. data/test/custom_importer_test.rb +127 -0
  208. data/test/engine_test.rb +314 -0
  209. data/test/error_test.rb +29 -0
  210. data/test/fixtures/paths.scss +10 -0
  211. data/test/functions_test.rb +340 -0
  212. data/test/native_test.rb +213 -0
  213. data/test/output_style_test.rb +107 -0
  214. data/test/sass_2_scss_test.rb +14 -0
  215. data/test/test_helper.rb +45 -0
  216. metadata +396 -0
@@ -0,0 +1,1780 @@
1
+ // sass.hpp must go before all system headers to get the
2
+ // __EXTENSIONS__ fix on Solaris.
3
+ #include "sass.hpp"
4
+
5
+ #include <iostream>
6
+ #include <iomanip>
7
+ #include "util.hpp"
8
+ #include "util_string.hpp"
9
+ #include "position.hpp"
10
+ #include "prelexer.hpp"
11
+ #include "constants.hpp"
12
+
13
+
14
+ namespace Sass {
15
+ // using namespace Lexer;
16
+ using namespace Constants;
17
+
18
+ namespace Prelexer {
19
+
20
+
21
+ /*
22
+
23
+ def string_re(open, close)
24
+ /#{open}((?:\\.|\#(?!\{)|[^#{close}\\#])*)(#{close}|#\{)/m
25
+ end
26
+ end
27
+
28
+ # A hash of regular expressions that are used for tokenizing strings.
29
+ #
30
+ # The key is a `[Symbol, Boolean]` pair.
31
+ # The symbol represents which style of quotation to use,
32
+ # while the boolean represents whether or not the string
33
+ # is following an interpolated segment.
34
+ STRING_REGULAR_EXPRESSIONS = {
35
+ :double => {
36
+ /#{open}((?:\\.|\#(?!\{)|[^#{close}\\#])*)(#{close}|#\{)/m
37
+ false => string_re('"', '"'),
38
+ true => string_re('', '"')
39
+ },
40
+ :single => {
41
+ false => string_re("'", "'"),
42
+ true => string_re('', "'")
43
+ },
44
+ :uri => {
45
+ false => /url\(#{W}(#{URLCHAR}*?)(#{W}\)|#\{)/,
46
+ true => /(#{URLCHAR}*?)(#{W}\)|#\{)/
47
+ },
48
+ # Defined in https://developer.mozilla.org/en/CSS/@-moz-document as a
49
+ # non-standard version of http://www.w3.org/TR/css3-conditional/
50
+ :url_prefix => {
51
+ false => /url-prefix\(#{W}(#{URLCHAR}*?)(#{W}\)|#\{)/,
52
+ true => /(#{URLCHAR}*?)(#{W}\)|#\{)/
53
+ },
54
+ :domain => {
55
+ false => /domain\(#{W}(#{URLCHAR}*?)(#{W}\)|#\{)/,
56
+ true => /(#{URLCHAR}*?)(#{W}\)|#\{)/
57
+ }
58
+ }
59
+ */
60
+
61
+ /*
62
+ /#{open}
63
+ (
64
+ \\.
65
+ |
66
+ \# (?!\{)
67
+ |
68
+ [^#{close}\\#]
69
+ )*
70
+ (#{close}|#\{)
71
+ /m
72
+ false => string_re('"', '"'),
73
+ true => string_re('', '"')
74
+ */
75
+ extern const char string_double_negates[] = "\"\\#";
76
+ const char* re_string_double_close(const char* src)
77
+ {
78
+ return sequence <
79
+ // valid chars
80
+ zero_plus <
81
+ alternatives <
82
+ // escaped char
83
+ sequence <
84
+ exactly <'\\'>,
85
+ any_char
86
+ >,
87
+ // non interpolate hash
88
+ sequence <
89
+ exactly <'#'>,
90
+ negate <
91
+ exactly <'{'>
92
+ >
93
+ >,
94
+ // other valid chars
95
+ neg_class_char <
96
+ string_double_negates
97
+ >
98
+ >
99
+ >,
100
+ // quoted string closer
101
+ // or interpolate opening
102
+ alternatives <
103
+ exactly <'"'>,
104
+ lookahead < exactly< hash_lbrace > >
105
+ >
106
+ >(src);
107
+ }
108
+
109
+ const char* re_string_double_open(const char* src)
110
+ {
111
+ return sequence <
112
+ // quoted string opener
113
+ exactly <'"'>,
114
+ // valid chars
115
+ zero_plus <
116
+ alternatives <
117
+ // escaped char
118
+ sequence <
119
+ exactly <'\\'>,
120
+ any_char
121
+ >,
122
+ // non interpolate hash
123
+ sequence <
124
+ exactly <'#'>,
125
+ negate <
126
+ exactly <'{'>
127
+ >
128
+ >,
129
+ // other valid chars
130
+ neg_class_char <
131
+ string_double_negates
132
+ >
133
+ >
134
+ >,
135
+ // quoted string closer
136
+ // or interpolate opening
137
+ alternatives <
138
+ exactly <'"'>,
139
+ lookahead < exactly< hash_lbrace > >
140
+ >
141
+ >(src);
142
+ }
143
+
144
+ extern const char string_single_negates[] = "'\\#";
145
+ const char* re_string_single_close(const char* src)
146
+ {
147
+ return sequence <
148
+ // valid chars
149
+ zero_plus <
150
+ alternatives <
151
+ // escaped char
152
+ sequence <
153
+ exactly <'\\'>,
154
+ any_char
155
+ >,
156
+ // non interpolate hash
157
+ sequence <
158
+ exactly <'#'>,
159
+ negate <
160
+ exactly <'{'>
161
+ >
162
+ >,
163
+ // other valid chars
164
+ neg_class_char <
165
+ string_single_negates
166
+ >
167
+ >
168
+ >,
169
+ // quoted string closer
170
+ // or interpolate opening
171
+ alternatives <
172
+ exactly <'\''>,
173
+ lookahead < exactly< hash_lbrace > >
174
+ >
175
+ >(src);
176
+ }
177
+
178
+ const char* re_string_single_open(const char* src)
179
+ {
180
+ return sequence <
181
+ // quoted string opener
182
+ exactly <'\''>,
183
+ // valid chars
184
+ zero_plus <
185
+ alternatives <
186
+ // escaped char
187
+ sequence <
188
+ exactly <'\\'>,
189
+ any_char
190
+ >,
191
+ // non interpolate hash
192
+ sequence <
193
+ exactly <'#'>,
194
+ negate <
195
+ exactly <'{'>
196
+ >
197
+ >,
198
+ // other valid chars
199
+ neg_class_char <
200
+ string_single_negates
201
+ >
202
+ >
203
+ >,
204
+ // quoted string closer
205
+ // or interpolate opening
206
+ alternatives <
207
+ exactly <'\''>,
208
+ lookahead < exactly< hash_lbrace > >
209
+ >
210
+ >(src);
211
+ }
212
+
213
+ /*
214
+ :uri => {
215
+ false => /url\(#{W}(#{URLCHAR}*?)(#{W}\)|#\{)/,
216
+ true => /(#{URLCHAR}*?)(#{W}\)|#\{)/
217
+ },
218
+ */
219
+ const char* re_string_uri_close(const char* src)
220
+ {
221
+ return sequence <
222
+ non_greedy<
223
+ alternatives<
224
+ class_char< real_uri_chars >,
225
+ uri_character,
226
+ NONASCII,
227
+ ESCAPE
228
+ >,
229
+ alternatives<
230
+ sequence < optional < W >, exactly <')'> >,
231
+ lookahead < exactly< hash_lbrace > >
232
+ >
233
+ >,
234
+ optional <
235
+ sequence < optional < W >, exactly <')'> >
236
+ >
237
+ >(src);
238
+ }
239
+
240
+ const char* re_string_uri_open(const char* src)
241
+ {
242
+ return sequence <
243
+ exactly <'u'>,
244
+ exactly <'r'>,
245
+ exactly <'l'>,
246
+ exactly <'('>,
247
+ W,
248
+ alternatives<
249
+ quoted_string,
250
+ non_greedy<
251
+ alternatives<
252
+ class_char< real_uri_chars >,
253
+ uri_character,
254
+ NONASCII,
255
+ ESCAPE
256
+ >,
257
+ alternatives<
258
+ sequence < W, exactly <')'> >,
259
+ exactly< hash_lbrace >
260
+ >
261
+ >
262
+ >
263
+ >(src);
264
+ }
265
+
266
+ // Match a line comment (/.*?(?=\n|\r\n?|\f|\Z)/.
267
+ const char* line_comment(const char* src)
268
+ {
269
+ return sequence<
270
+ exactly <
271
+ slash_slash
272
+ >,
273
+ non_greedy<
274
+ any_char,
275
+ end_of_line
276
+ >
277
+ >(src);
278
+ }
279
+
280
+ // Match a block comment.
281
+ const char* block_comment(const char* src)
282
+ {
283
+ return sequence<
284
+ delimited_by<
285
+ slash_star,
286
+ star_slash,
287
+ false
288
+ >
289
+ >(src);
290
+ }
291
+ /* not use anymore - remove?
292
+ const char* block_comment_prefix(const char* src) {
293
+ return exactly<slash_star>(src);
294
+ }
295
+ // Match either comment.
296
+ const char* comment(const char* src) {
297
+ return line_comment(src);
298
+ }
299
+ */
300
+
301
+ // Match zero plus white-space or line_comments
302
+ const char* optional_css_whitespace(const char* src) {
303
+ return zero_plus< alternatives<spaces, line_comment> >(src);
304
+ }
305
+ const char* css_whitespace(const char* src) {
306
+ return one_plus< alternatives<spaces, line_comment> >(src);
307
+ }
308
+ // Match optional_css_whitespace plus block_comments
309
+ const char* optional_css_comments(const char* src) {
310
+ return zero_plus< alternatives<spaces, line_comment, block_comment> >(src);
311
+ }
312
+ const char* css_comments(const char* src) {
313
+ return one_plus< alternatives<spaces, line_comment, block_comment> >(src);
314
+ }
315
+
316
+ // Match one backslash escaped char /\\./
317
+ const char* escape_seq(const char* src)
318
+ {
319
+ return sequence<
320
+ exactly<'\\'>,
321
+ alternatives <
322
+ minmax_range<
323
+ 1, 3, xdigit
324
+ >,
325
+ any_char
326
+ >,
327
+ optional <
328
+ exactly <' '>
329
+ >
330
+ >(src);
331
+ }
332
+
333
+ // Match identifier start
334
+ const char* identifier_alpha(const char* src)
335
+ {
336
+ return alternatives<
337
+ unicode_seq,
338
+ alpha,
339
+ nonascii,
340
+ exactly<'-'>,
341
+ exactly<'_'>,
342
+ NONASCII,
343
+ ESCAPE,
344
+ escape_seq
345
+ >(src);
346
+ }
347
+
348
+ // Match identifier after start
349
+ const char* identifier_alnum(const char* src)
350
+ {
351
+ return alternatives<
352
+ unicode_seq,
353
+ alnum,
354
+ nonascii,
355
+ exactly<'-'>,
356
+ exactly<'_'>,
357
+ NONASCII,
358
+ ESCAPE,
359
+ escape_seq
360
+ >(src);
361
+ }
362
+
363
+ // Match CSS identifiers.
364
+ const char* strict_identifier(const char* src)
365
+ {
366
+ return sequence<
367
+ one_plus < strict_identifier_alpha >,
368
+ zero_plus < strict_identifier_alnum >
369
+ // word_boundary not needed
370
+ >(src);
371
+ }
372
+
373
+ // Match CSS identifiers.
374
+ const char* identifier(const char* src)
375
+ {
376
+ return sequence<
377
+ zero_plus< exactly<'-'> >,
378
+ one_plus < identifier_alpha >,
379
+ zero_plus < identifier_alnum >
380
+ // word_boundary not needed
381
+ >(src);
382
+ }
383
+
384
+ const char* strict_identifier_alpha(const char* src)
385
+ {
386
+ return alternatives <
387
+ alpha,
388
+ nonascii,
389
+ escape_seq,
390
+ exactly<'_'>
391
+ >(src);
392
+ }
393
+
394
+ const char* strict_identifier_alnum(const char* src)
395
+ {
396
+ return alternatives <
397
+ alnum,
398
+ nonascii,
399
+ escape_seq,
400
+ exactly<'_'>
401
+ >(src);
402
+ }
403
+
404
+ // Match a single CSS unit
405
+ const char* one_unit(const char* src)
406
+ {
407
+ return sequence <
408
+ optional < exactly <'-'> >,
409
+ strict_identifier_alpha,
410
+ zero_plus < alternatives<
411
+ strict_identifier_alnum,
412
+ sequence <
413
+ one_plus < exactly<'-'> >,
414
+ strict_identifier_alpha
415
+ >
416
+ > >
417
+ >(src);
418
+ }
419
+
420
+ // Match numerator/denominator CSS units
421
+ const char* multiple_units(const char* src)
422
+ {
423
+ return
424
+ sequence <
425
+ one_unit,
426
+ zero_plus <
427
+ sequence <
428
+ exactly <'*'>,
429
+ one_unit
430
+ >
431
+ >
432
+ >(src);
433
+ }
434
+
435
+ // Match complex CSS unit identifiers
436
+ const char* unit_identifier(const char* src)
437
+ {
438
+ return sequence <
439
+ multiple_units,
440
+ optional <
441
+ sequence <
442
+ exactly <'/'>,
443
+ negate < sequence <
444
+ exactly < calc_fn_kwd >,
445
+ exactly < '(' >
446
+ > >,
447
+ multiple_units
448
+ > >
449
+ >(src);
450
+ }
451
+
452
+ const char* identifier_alnums(const char* src)
453
+ {
454
+ return one_plus< identifier_alnum >(src);
455
+ }
456
+
457
+ // Match number prefix ([\+\-]+)
458
+ const char* number_prefix(const char* src) {
459
+ return alternatives <
460
+ exactly < '+' >,
461
+ sequence <
462
+ exactly < '-' >,
463
+ optional_css_whitespace,
464
+ exactly< '-' >
465
+ >
466
+ >(src);
467
+ }
468
+
469
+ // Match interpolant schemas
470
+ const char* identifier_schema(const char* src) {
471
+
472
+ return sequence <
473
+ one_plus <
474
+ sequence <
475
+ zero_plus <
476
+ alternatives <
477
+ sequence <
478
+ optional <
479
+ exactly <'$'>
480
+ >,
481
+ identifier
482
+ >,
483
+ exactly <'-'>
484
+ >
485
+ >,
486
+ interpolant,
487
+ zero_plus <
488
+ alternatives <
489
+ digits,
490
+ sequence <
491
+ optional <
492
+ exactly <'$'>
493
+ >,
494
+ identifier
495
+ >,
496
+ quoted_string,
497
+ exactly<'-'>
498
+ >
499
+ >
500
+ >
501
+ >,
502
+ negate <
503
+ exactly<'%'>
504
+ >
505
+ > (src);
506
+ }
507
+
508
+ // interpolants can be recursive/nested
509
+ const char* interpolant(const char* src) {
510
+ return recursive_scopes< exactly<hash_lbrace>, exactly<rbrace> >(src);
511
+ }
512
+
513
+ // $re_squote = /'(?:$re_itplnt|\\.|[^'])*'/
514
+ const char* single_quoted_string(const char* src) {
515
+ // match a single quoted string, while skipping interpolants
516
+ return sequence <
517
+ exactly <'\''>,
518
+ zero_plus <
519
+ alternatives <
520
+ // skip escapes
521
+ sequence <
522
+ exactly < '\\' >,
523
+ re_linebreak
524
+ >,
525
+ escape_seq,
526
+ unicode_seq,
527
+ // skip interpolants
528
+ interpolant,
529
+ // skip non delimiters
530
+ any_char_but < '\'' >
531
+ >
532
+ >,
533
+ exactly <'\''>
534
+ >(src);
535
+ }
536
+
537
+ // $re_dquote = /"(?:$re_itp|\\.|[^"])*"/
538
+ const char* double_quoted_string(const char* src) {
539
+ // match a single quoted string, while skipping interpolants
540
+ return sequence <
541
+ exactly <'"'>,
542
+ zero_plus <
543
+ alternatives <
544
+ // skip escapes
545
+ sequence <
546
+ exactly < '\\' >,
547
+ re_linebreak
548
+ >,
549
+ escape_seq,
550
+ unicode_seq,
551
+ // skip interpolants
552
+ interpolant,
553
+ // skip non delimiters
554
+ any_char_but < '"' >
555
+ >
556
+ >,
557
+ exactly <'"'>
558
+ >(src);
559
+ }
560
+
561
+ // $re_quoted = /(?:$re_squote|$re_dquote)/
562
+ const char* quoted_string(const char* src) {
563
+ // match a quoted string, while skipping interpolants
564
+ return alternatives<
565
+ single_quoted_string,
566
+ double_quoted_string
567
+ >(src);
568
+ }
569
+
570
+ const char* sass_value(const char* src) {
571
+ return alternatives <
572
+ quoted_string,
573
+ identifier,
574
+ percentage,
575
+ hex,
576
+ dimension,
577
+ number
578
+ >(src);
579
+ }
580
+
581
+ // this is basically `one_plus < sass_value >`
582
+ // takes care to not parse invalid combinations
583
+ const char* value_combinations(const char* src) {
584
+ // `2px-2px` is invalid combo
585
+ bool was_number = false;
586
+ const char* pos;
587
+ while (src) {
588
+ if ((pos = alternatives < quoted_string, identifier, percentage, hex >(src))) {
589
+ was_number = false;
590
+ src = pos;
591
+ } else if (!was_number && !exactly<'+'>(src) && (pos = alternatives < dimension, number >(src))) {
592
+ was_number = true;
593
+ src = pos;
594
+ } else {
595
+ break;
596
+ }
597
+ }
598
+ return src;
599
+ }
600
+
601
+ // must be at least one interpolant
602
+ // can be surrounded by sass values
603
+ // make sure to never parse (dim)(dim)
604
+ // since this wrongly consumes `2px-1px`
605
+ // `2px1px` is valid number (unit `px1px`)
606
+ const char* value_schema(const char* src)
607
+ {
608
+ return sequence <
609
+ one_plus <
610
+ sequence <
611
+ optional < value_combinations >,
612
+ interpolant,
613
+ optional < value_combinations >
614
+ >
615
+ >
616
+ >(src);
617
+ }
618
+
619
+ // Match CSS '@' keywords.
620
+ const char* at_keyword(const char* src) {
621
+ return sequence<exactly<'@'>, identifier>(src);
622
+ }
623
+
624
+ /*
625
+ tok(%r{
626
+ (
627
+ \\.
628
+ |
629
+ (?!url\()
630
+ [^"'/\#!;\{\}] # "
631
+ |
632
+ /(?![\*\/])
633
+ |
634
+ \#(?!\{)
635
+ |
636
+ !(?![a-z]) # TODO: never consume "!" when issue 1126 is fixed.
637
+ )+
638
+ }xi) || tok(COMMENT) || tok(SINGLE_LINE_COMMENT) || interp_string || interp_uri ||
639
+ interpolation(:warn_for_color)
640
+ */
641
+ const char* re_almost_any_value_token(const char* src) {
642
+
643
+ return alternatives <
644
+ one_plus <
645
+ alternatives <
646
+ sequence <
647
+ exactly <'\\'>,
648
+ any_char
649
+ >,
650
+ sequence <
651
+ negate <
652
+ uri_prefix
653
+ >,
654
+ neg_class_char <
655
+ almost_any_value_class
656
+ >
657
+ >,
658
+ sequence <
659
+ exactly <'/'>,
660
+ negate <
661
+ alternatives <
662
+ exactly <'/'>,
663
+ exactly <'*'>
664
+ >
665
+ >
666
+ >,
667
+ sequence <
668
+ exactly <'\\'>,
669
+ exactly <'#'>,
670
+ negate <
671
+ exactly <'{'>
672
+ >
673
+ >,
674
+ sequence <
675
+ exactly <'!'>,
676
+ negate <
677
+ alpha
678
+ >
679
+ >
680
+ >
681
+ >,
682
+ block_comment,
683
+ line_comment,
684
+ interpolant,
685
+ space,
686
+ sequence <
687
+ exactly<'u'>,
688
+ exactly<'r'>,
689
+ exactly<'l'>,
690
+ exactly<'('>,
691
+ zero_plus <
692
+ alternatives <
693
+ class_char< real_uri_chars >,
694
+ uri_character,
695
+ NONASCII,
696
+ ESCAPE
697
+ >
698
+ >,
699
+ // false => /url\(#{W}(#{URLCHAR}*?)(#{W}\)|#\{)/,
700
+ // true => /(#{URLCHAR}*?)(#{W}\)|#\{)/
701
+ exactly<')'>
702
+ >
703
+ >(src);
704
+ }
705
+
706
+ /*
707
+ DIRECTIVES = Set[:mixin, :include, :function, :return, :debug, :warn, :for,
708
+ :each, :while, :if, :else, :extend, :import, :media, :charset, :content,
709
+ :_moz_document, :at_root, :error]
710
+ */
711
+ const char* re_special_directive(const char* src) {
712
+ return alternatives <
713
+ word < mixin_kwd >,
714
+ word < include_kwd >,
715
+ word < function_kwd >,
716
+ word < return_kwd >,
717
+ word < debug_kwd >,
718
+ word < warn_kwd >,
719
+ word < for_kwd >,
720
+ word < each_kwd >,
721
+ word < while_kwd >,
722
+ word < if_kwd >,
723
+ word < else_kwd >,
724
+ word < extend_kwd >,
725
+ word < import_kwd >,
726
+ word < media_kwd >,
727
+ word < charset_kwd >,
728
+ word < content_kwd >,
729
+ // exactly < moz_document_kwd >,
730
+ word < at_root_kwd >,
731
+ word < error_kwd >
732
+ >(src);
733
+ }
734
+
735
+ const char* re_prefixed_directive(const char* src) {
736
+ return sequence <
737
+ optional <
738
+ sequence <
739
+ exactly <'-'>,
740
+ one_plus < alnum >,
741
+ exactly <'-'>
742
+ >
743
+ >,
744
+ exactly < supports_kwd >
745
+ >(src);
746
+ }
747
+
748
+ const char* re_reference_combinator(const char* src) {
749
+ return sequence <
750
+ optional <
751
+ sequence <
752
+ zero_plus <
753
+ exactly <'-'>
754
+ >,
755
+ identifier,
756
+ exactly <'|'>
757
+ >
758
+ >,
759
+ zero_plus <
760
+ exactly <'-'>
761
+ >,
762
+ identifier
763
+ >(src);
764
+ }
765
+
766
+ const char* static_reference_combinator(const char* src) {
767
+ return sequence <
768
+ exactly <'/'>,
769
+ re_reference_combinator,
770
+ exactly <'/'>
771
+ >(src);
772
+ }
773
+
774
+ const char* schema_reference_combinator(const char* src) {
775
+ return sequence <
776
+ exactly <'/'>,
777
+ optional <
778
+ sequence <
779
+ css_ip_identifier,
780
+ exactly <'|'>
781
+ >
782
+ >,
783
+ css_ip_identifier,
784
+ exactly <'/'>
785
+ > (src);
786
+ }
787
+
788
+ const char* kwd_import(const char* src) {
789
+ return word<import_kwd>(src);
790
+ }
791
+
792
+ const char* kwd_at_root(const char* src) {
793
+ return word<at_root_kwd>(src);
794
+ }
795
+
796
+ const char* kwd_with_directive(const char* src) {
797
+ return word<with_kwd>(src);
798
+ }
799
+
800
+ const char* kwd_without_directive(const char* src) {
801
+ return word<without_kwd>(src);
802
+ }
803
+
804
+ const char* kwd_media(const char* src) {
805
+ return word<media_kwd>(src);
806
+ }
807
+
808
+ const char* kwd_supports_directive(const char* src) {
809
+ return word<supports_kwd>(src);
810
+ }
811
+
812
+ const char* kwd_mixin(const char* src) {
813
+ return word<mixin_kwd>(src);
814
+ }
815
+
816
+ const char* kwd_function(const char* src) {
817
+ return word<function_kwd>(src);
818
+ }
819
+
820
+ const char* kwd_return_directive(const char* src) {
821
+ return word<return_kwd>(src);
822
+ }
823
+
824
+ const char* kwd_include_directive(const char* src) {
825
+ return word<include_kwd>(src);
826
+ }
827
+
828
+ const char* kwd_content_directive(const char* src) {
829
+ return word<content_kwd>(src);
830
+ }
831
+
832
+ const char* kwd_charset_directive(const char* src) {
833
+ return word<charset_kwd>(src);
834
+ }
835
+
836
+ const char* kwd_extend(const char* src) {
837
+ return word<extend_kwd>(src);
838
+ }
839
+
840
+
841
+ const char* kwd_if_directive(const char* src) {
842
+ return word<if_kwd>(src);
843
+ }
844
+
845
+ const char* kwd_else_directive(const char* src) {
846
+ return word<else_kwd>(src);
847
+ }
848
+ const char* elseif_directive(const char* src) {
849
+ return sequence< exactly< else_kwd >,
850
+ optional_css_comments,
851
+ word< if_after_else_kwd > >(src);
852
+ }
853
+
854
+ const char* kwd_for_directive(const char* src) {
855
+ return word<for_kwd>(src);
856
+ }
857
+
858
+ const char* kwd_from(const char* src) {
859
+ return word<from_kwd>(src);
860
+ }
861
+
862
+ const char* kwd_to(const char* src) {
863
+ return word<to_kwd>(src);
864
+ }
865
+
866
+ const char* kwd_through(const char* src) {
867
+ return word<through_kwd>(src);
868
+ }
869
+
870
+ const char* kwd_each_directive(const char* src) {
871
+ return word<each_kwd>(src);
872
+ }
873
+
874
+ const char* kwd_in(const char* src) {
875
+ return word<in_kwd>(src);
876
+ }
877
+
878
+ const char* kwd_while_directive(const char* src) {
879
+ return word<while_kwd>(src);
880
+ }
881
+
882
+ const char* name(const char* src) {
883
+ return one_plus< alternatives< alnum,
884
+ exactly<'-'>,
885
+ exactly<'_'>,
886
+ escape_seq > >(src);
887
+ }
888
+
889
+ const char* kwd_warn(const char* src) {
890
+ return word<warn_kwd>(src);
891
+ }
892
+
893
+ const char* kwd_err(const char* src) {
894
+ return word<error_kwd>(src);
895
+ }
896
+
897
+ const char* kwd_dbg(const char* src) {
898
+ return word<debug_kwd>(src);
899
+ }
900
+
901
+ /* not used anymore - remove?
902
+ const char* directive(const char* src) {
903
+ return sequence< exactly<'@'>, identifier >(src);
904
+ } */
905
+
906
+ const char* kwd_null(const char* src) {
907
+ return word<null_kwd>(src);
908
+ }
909
+
910
+ const char* css_identifier(const char* src) {
911
+ return sequence <
912
+ zero_plus <
913
+ exactly <'-'>
914
+ >,
915
+ identifier
916
+ >(src);
917
+ }
918
+
919
+ const char* css_ip_identifier(const char* src) {
920
+ return sequence <
921
+ zero_plus <
922
+ exactly <'-'>
923
+ >,
924
+ alternatives <
925
+ identifier,
926
+ interpolant
927
+ >
928
+ >(src);
929
+ }
930
+
931
+ // Match CSS type selectors
932
+ const char* namespace_prefix(const char* src) {
933
+ return sequence <
934
+ optional <
935
+ alternatives <
936
+ exactly <'*'>,
937
+ css_identifier
938
+ >
939
+ >,
940
+ exactly <'|'>,
941
+ negate <
942
+ exactly <'='>
943
+ >
944
+ >(src);
945
+ }
946
+
947
+ // Match CSS type selectors
948
+ const char* namespace_schema(const char* src) {
949
+ return sequence <
950
+ optional <
951
+ alternatives <
952
+ exactly <'*'>,
953
+ css_ip_identifier
954
+ >
955
+ >,
956
+ exactly<'|'>,
957
+ negate <
958
+ exactly <'='>
959
+ >
960
+ >(src);
961
+ }
962
+
963
+ const char* hyphens_and_identifier(const char* src) {
964
+ return sequence< zero_plus< exactly< '-' > >, identifier_alnums >(src);
965
+ }
966
+ const char* hyphens_and_name(const char* src) {
967
+ return sequence< zero_plus< exactly< '-' > >, name >(src);
968
+ }
969
+ const char* universal(const char* src) {
970
+ return sequence< optional<namespace_schema>, exactly<'*'> >(src);
971
+ }
972
+ // Match CSS id names.
973
+ const char* id_name(const char* src) {
974
+ return sequence<exactly<'#'>, identifier_alnums >(src);
975
+ }
976
+ // Match CSS class names.
977
+ const char* class_name(const char* src) {
978
+ return sequence<exactly<'.'>, identifier >(src);
979
+ }
980
+ // Attribute name in an attribute selector.
981
+ const char* attribute_name(const char* src) {
982
+ return alternatives< sequence< optional<namespace_schema>, identifier>,
983
+ identifier >(src);
984
+ }
985
+ // match placeholder selectors
986
+ const char* placeholder(const char* src) {
987
+ return sequence<exactly<'%'>, identifier_alnums >(src);
988
+ }
989
+ // Match CSS numeric constants.
990
+
991
+ const char* op(const char* src) {
992
+ return class_char<op_chars>(src);
993
+ }
994
+ const char* sign(const char* src) {
995
+ return class_char<sign_chars>(src);
996
+ }
997
+ const char* unsigned_number(const char* src) {
998
+ return alternatives<sequence< zero_plus<digits>,
999
+ exactly<'.'>,
1000
+ one_plus<digits> >,
1001
+ digits>(src);
1002
+ }
1003
+ const char* number(const char* src) {
1004
+ return sequence<
1005
+ optional<sign>,
1006
+ unsigned_number,
1007
+ optional<
1008
+ sequence<
1009
+ exactly<'e'>,
1010
+ optional<sign>,
1011
+ unsigned_number
1012
+ >
1013
+ >
1014
+ >(src);
1015
+ }
1016
+ const char* coefficient(const char* src) {
1017
+ return alternatives< sequence< optional<sign>, digits >,
1018
+ sign >(src);
1019
+ }
1020
+ const char* binomial(const char* src) {
1021
+ return sequence <
1022
+ optional < sign >,
1023
+ optional < digits >,
1024
+ exactly <'n'>,
1025
+ zero_plus < sequence <
1026
+ optional_css_whitespace, sign,
1027
+ optional_css_whitespace, digits
1028
+ > >
1029
+ >(src);
1030
+ }
1031
+ const char* percentage(const char* src) {
1032
+ return sequence< number, exactly<'%'> >(src);
1033
+ }
1034
+ const char* ampersand(const char* src) {
1035
+ return exactly<'&'>(src);
1036
+ }
1037
+
1038
+ /* not used anymore - remove?
1039
+ const char* em(const char* src) {
1040
+ return sequence< number, exactly<em_kwd> >(src);
1041
+ } */
1042
+ const char* dimension(const char* src) {
1043
+ return sequence<number, unit_identifier >(src);
1044
+ }
1045
+ const char* hex(const char* src) {
1046
+ const char* p = sequence< exactly<'#'>, one_plus<xdigit> >(src);
1047
+ ptrdiff_t len = p - src;
1048
+ return (len != 4 && len != 7) ? 0 : p;
1049
+ }
1050
+ const char* hexa(const char* src) {
1051
+ const char* p = sequence< exactly<'#'>, one_plus<xdigit> >(src);
1052
+ ptrdiff_t len = p - src;
1053
+ return (len != 5 && len != 9) ? 0 : p;
1054
+ }
1055
+ const char* hex0(const char* src) {
1056
+ const char* p = sequence< exactly<'0'>, exactly<'x'>, one_plus<xdigit> >(src);
1057
+ ptrdiff_t len = p - src;
1058
+ return (len != 5 && len != 8) ? 0 : p;
1059
+ }
1060
+
1061
+ /* no longer used - remove?
1062
+ const char* rgb_prefix(const char* src) {
1063
+ return word<rgb_fn_kwd>(src);
1064
+ }*/
1065
+ // Match CSS uri specifiers.
1066
+
1067
+ const char* uri_prefix(const char* src) {
1068
+ return sequence <
1069
+ exactly <
1070
+ url_kwd
1071
+ >,
1072
+ zero_plus <
1073
+ sequence <
1074
+ exactly <'-'>,
1075
+ one_plus <
1076
+ alpha
1077
+ >
1078
+ >
1079
+ >,
1080
+ exactly <'('>
1081
+ >(src);
1082
+ }
1083
+
1084
+ // TODO: rename the following two functions
1085
+ /* no longer used - remove?
1086
+ const char* uri(const char* src) {
1087
+ return sequence< exactly<url_kwd>,
1088
+ optional<spaces>,
1089
+ quoted_string,
1090
+ optional<spaces>,
1091
+ exactly<')'> >(src);
1092
+ }*/
1093
+ /* no longer used - remove?
1094
+ const char* url_value(const char* src) {
1095
+ return sequence< optional< sequence< identifier, exactly<':'> > >, // optional protocol
1096
+ one_plus< sequence< zero_plus< exactly<'/'> >, filename > >, // one or more folders and/or trailing filename
1097
+ optional< exactly<'/'> > >(src);
1098
+ }*/
1099
+ /* no longer used - remove?
1100
+ const char* url_schema(const char* src) {
1101
+ return sequence< optional< sequence< identifier, exactly<':'> > >, // optional protocol
1102
+ filename_schema >(src); // optional trailing slash
1103
+ }*/
1104
+ // Match CSS "!important" keyword.
1105
+ const char* kwd_important(const char* src) {
1106
+ return sequence< exactly<'!'>,
1107
+ optional_css_whitespace,
1108
+ word<important_kwd> >(src);
1109
+ }
1110
+ // Match CSS "!optional" keyword.
1111
+ const char* kwd_optional(const char* src) {
1112
+ return sequence< exactly<'!'>,
1113
+ optional_css_whitespace,
1114
+ word<optional_kwd> >(src);
1115
+ }
1116
+ // Match Sass "!default" keyword.
1117
+ const char* default_flag(const char* src) {
1118
+ return sequence< exactly<'!'>,
1119
+ optional_css_whitespace,
1120
+ word<default_kwd> >(src);
1121
+ }
1122
+ // Match Sass "!global" keyword.
1123
+ const char* global_flag(const char* src) {
1124
+ return sequence< exactly<'!'>,
1125
+ optional_css_whitespace,
1126
+ word<global_kwd> >(src);
1127
+ }
1128
+ // Match CSS pseudo-class/element prefixes.
1129
+ const char* pseudo_prefix(const char* src) {
1130
+ return sequence< exactly<':'>, optional< exactly<':'> > >(src);
1131
+ }
1132
+ // Match CSS function call openers.
1133
+ const char* functional_schema(const char* src) {
1134
+ return sequence <
1135
+ one_plus <
1136
+ sequence <
1137
+ zero_plus <
1138
+ alternatives <
1139
+ identifier,
1140
+ exactly <'-'>
1141
+ >
1142
+ >,
1143
+ one_plus <
1144
+ sequence <
1145
+ interpolant,
1146
+ alternatives <
1147
+ digits,
1148
+ identifier,
1149
+ exactly<'+'>,
1150
+ exactly<'-'>
1151
+ >
1152
+ >
1153
+ >
1154
+ >
1155
+ >,
1156
+ negate <
1157
+ exactly <'%'>
1158
+ >,
1159
+ lookahead <
1160
+ exactly <'('>
1161
+ >
1162
+ > (src);
1163
+ }
1164
+
1165
+ const char* re_nothing(const char* src) {
1166
+ return src;
1167
+ }
1168
+
1169
+ const char* re_functional(const char* src) {
1170
+ return sequence< identifier, optional < block_comment >, exactly<'('> >(src);
1171
+ }
1172
+ const char* re_pseudo_selector(const char* src) {
1173
+ return sequence< identifier, optional < block_comment >, exactly<'('> >(src);
1174
+ }
1175
+ // Match the CSS negation pseudo-class.
1176
+ const char* pseudo_not(const char* src) {
1177
+ return word< pseudo_not_fn_kwd >(src);
1178
+ }
1179
+ // Match CSS 'odd' and 'even' keywords for functional pseudo-classes.
1180
+ const char* even(const char* src) {
1181
+ return word<even_kwd>(src);
1182
+ }
1183
+ const char* odd(const char* src) {
1184
+ return word<odd_kwd>(src);
1185
+ }
1186
+ // Match CSS attribute-matching operators.
1187
+ const char* exact_match(const char* src) { return exactly<'='>(src); }
1188
+ const char* class_match(const char* src) { return exactly<tilde_equal>(src); }
1189
+ const char* dash_match(const char* src) { return exactly<pipe_equal>(src); }
1190
+ const char* prefix_match(const char* src) { return exactly<caret_equal>(src); }
1191
+ const char* suffix_match(const char* src) { return exactly<dollar_equal>(src); }
1192
+ const char* substring_match(const char* src) { return exactly<star_equal>(src); }
1193
+ // Match CSS combinators.
1194
+ /* not used anymore - remove?
1195
+ const char* adjacent_to(const char* src) {
1196
+ return sequence< optional_spaces, exactly<'+'> >(src);
1197
+ }
1198
+ const char* precedes(const char* src) {
1199
+ return sequence< optional_spaces, exactly<'~'> >(src);
1200
+ }
1201
+ const char* parent_of(const char* src) {
1202
+ return sequence< optional_spaces, exactly<'>'> >(src);
1203
+ }
1204
+ const char* ancestor_of(const char* src) {
1205
+ return sequence< spaces, negate< exactly<'{'> > >(src);
1206
+ }*/
1207
+
1208
+ // Match SCSS variable names.
1209
+ const char* variable(const char* src) {
1210
+ return sequence<exactly<'$'>, identifier>(src);
1211
+ }
1212
+
1213
+ // parse `calc`, `-a-calc` and `--b-c-calc`
1214
+ // but do not parse `foocalc` or `foo-calc`
1215
+ const char* calc_fn_call(const char* src) {
1216
+ return sequence <
1217
+ optional < sequence <
1218
+ hyphens,
1219
+ one_plus < sequence <
1220
+ strict_identifier,
1221
+ hyphens
1222
+ > >
1223
+ > >,
1224
+ exactly < calc_fn_kwd >,
1225
+ word_boundary
1226
+ >(src);
1227
+ }
1228
+
1229
+ // Match Sass boolean keywords.
1230
+ const char* kwd_true(const char* src) {
1231
+ return word<true_kwd>(src);
1232
+ }
1233
+ const char* kwd_false(const char* src) {
1234
+ return word<false_kwd>(src);
1235
+ }
1236
+ const char* kwd_only(const char* src) {
1237
+ return keyword < only_kwd >(src);
1238
+ }
1239
+ const char* kwd_and(const char* src) {
1240
+ return keyword < and_kwd >(src);
1241
+ }
1242
+ const char* kwd_or(const char* src) {
1243
+ return keyword < or_kwd >(src);
1244
+ }
1245
+ const char* kwd_not(const char* src) {
1246
+ return keyword < not_kwd >(src);
1247
+ }
1248
+ const char* kwd_eq(const char* src) {
1249
+ return exactly<eq>(src);
1250
+ }
1251
+ const char* kwd_neq(const char* src) {
1252
+ return exactly<neq>(src);
1253
+ }
1254
+ const char* kwd_gt(const char* src) {
1255
+ return exactly<gt>(src);
1256
+ }
1257
+ const char* kwd_gte(const char* src) {
1258
+ return exactly<gte>(src);
1259
+ }
1260
+ const char* kwd_lt(const char* src) {
1261
+ return exactly<lt>(src);
1262
+ }
1263
+ const char* kwd_lte(const char* src) {
1264
+ return exactly<lte>(src);
1265
+ }
1266
+ const char* kwd_using(const char* src) {
1267
+ return keyword<using_kwd>(src);
1268
+ }
1269
+
1270
+ // match specific IE syntax
1271
+ const char* ie_progid(const char* src) {
1272
+ return sequence <
1273
+ word<progid_kwd>,
1274
+ exactly<':'>,
1275
+ alternatives< identifier_schema, identifier >,
1276
+ zero_plus< sequence<
1277
+ exactly<'.'>,
1278
+ alternatives< identifier_schema, identifier >
1279
+ > >,
1280
+ zero_plus < sequence<
1281
+ exactly<'('>,
1282
+ optional_css_whitespace,
1283
+ optional < sequence<
1284
+ alternatives< variable, identifier_schema, identifier >,
1285
+ optional_css_whitespace,
1286
+ exactly<'='>,
1287
+ optional_css_whitespace,
1288
+ alternatives< variable, identifier_schema, identifier, quoted_string, number, hex, hexa >,
1289
+ zero_plus< sequence<
1290
+ optional_css_whitespace,
1291
+ exactly<','>,
1292
+ optional_css_whitespace,
1293
+ sequence<
1294
+ alternatives< variable, identifier_schema, identifier >,
1295
+ optional_css_whitespace,
1296
+ exactly<'='>,
1297
+ optional_css_whitespace,
1298
+ alternatives< variable, identifier_schema, identifier, quoted_string, number, hex, hexa >
1299
+ >
1300
+ > >
1301
+ > >,
1302
+ optional_css_whitespace,
1303
+ exactly<')'>
1304
+ > >
1305
+ >(src);
1306
+ }
1307
+ const char* ie_expression(const char* src) {
1308
+ return sequence < word<expression_kwd>, exactly<'('>, skip_over_scopes< exactly<'('>, exactly<')'> > >(src);
1309
+ }
1310
+ const char* ie_property(const char* src) {
1311
+ return alternatives < ie_expression, ie_progid >(src);
1312
+ }
1313
+
1314
+ // const char* ie_args(const char* src) {
1315
+ // return sequence< alternatives< ie_keyword_arg, value_schema, quoted_string, interpolant, number, identifier, delimited_by< '(', ')', true> >,
1316
+ // zero_plus< sequence< optional_css_whitespace, exactly<','>, optional_css_whitespace, alternatives< ie_keyword_arg, value_schema, quoted_string, interpolant, number, identifier, delimited_by<'(', ')', true> > > > >(src);
1317
+ // }
1318
+
1319
+ const char* ie_keyword_arg_property(const char* src) {
1320
+ return alternatives <
1321
+ variable,
1322
+ identifier_schema,
1323
+ identifier
1324
+ >(src);
1325
+ }
1326
+ const char* ie_keyword_arg_value(const char* src) {
1327
+ return alternatives <
1328
+ variable,
1329
+ identifier_schema,
1330
+ identifier,
1331
+ quoted_string,
1332
+ number,
1333
+ hex,
1334
+ hexa,
1335
+ sequence <
1336
+ exactly < '(' >,
1337
+ skip_over_scopes <
1338
+ exactly < '(' >,
1339
+ exactly < ')' >
1340
+ >
1341
+ >
1342
+ >(src);
1343
+ }
1344
+
1345
+ const char* ie_keyword_arg(const char* src) {
1346
+ return sequence <
1347
+ ie_keyword_arg_property,
1348
+ optional_css_whitespace,
1349
+ exactly<'='>,
1350
+ optional_css_whitespace,
1351
+ ie_keyword_arg_value
1352
+ >(src);
1353
+ }
1354
+
1355
+ // Path matching functions.
1356
+ /* not used anymore - remove?
1357
+ const char* folder(const char* src) {
1358
+ return sequence< zero_plus< any_char_except<'/'> >,
1359
+ exactly<'/'> >(src);
1360
+ }
1361
+ const char* folders(const char* src) {
1362
+ return zero_plus< folder >(src);
1363
+ }*/
1364
+ /* not used anymore - remove?
1365
+ const char* chunk(const char* src) {
1366
+ char inside_str = 0;
1367
+ const char* p = src;
1368
+ size_t depth = 0;
1369
+ while (true) {
1370
+ if (!*p) {
1371
+ return 0;
1372
+ }
1373
+ else if (!inside_str && (*p == '"' || *p == '\'')) {
1374
+ inside_str = *p;
1375
+ }
1376
+ else if (*p == inside_str && *(p-1) != '\\') {
1377
+ inside_str = 0;
1378
+ }
1379
+ else if (*p == '(' && !inside_str) {
1380
+ ++depth;
1381
+ }
1382
+ else if (*p == ')' && !inside_str) {
1383
+ if (depth == 0) return p;
1384
+ else --depth;
1385
+ }
1386
+ ++p;
1387
+ }
1388
+ // unreachable
1389
+ return 0;
1390
+ }
1391
+ */
1392
+
1393
+ // follow the CSS spec more closely and see if this helps us scan URLs correctly
1394
+ /* not used anymore - remove?
1395
+ const char* NL(const char* src) {
1396
+ return alternatives< exactly<'\n'>,
1397
+ sequence< exactly<'\r'>, exactly<'\n'> >,
1398
+ exactly<'\r'>,
1399
+ exactly<'\f'> >(src);
1400
+ }*/
1401
+
1402
+ const char* H(const char* src) {
1403
+ return Util::ascii_isxdigit(static_cast<unsigned char>(*src)) ? src+1 : 0;
1404
+ }
1405
+
1406
+ const char* W(const char* src) {
1407
+ return zero_plus< alternatives<
1408
+ space,
1409
+ exactly< '\t' >,
1410
+ exactly< '\r' >,
1411
+ exactly< '\n' >,
1412
+ exactly< '\f' >
1413
+ > >(src);
1414
+ }
1415
+
1416
+ const char* UUNICODE(const char* src) {
1417
+ return sequence< exactly<'\\'>,
1418
+ between<H, 1, 6>,
1419
+ optional< W >
1420
+ >(src);
1421
+ }
1422
+
1423
+ const char* NONASCII(const char* src) {
1424
+ return nonascii(src);
1425
+ }
1426
+
1427
+ const char* ESCAPE(const char* src) {
1428
+ return alternatives<
1429
+ UUNICODE,
1430
+ sequence<
1431
+ exactly<'\\'>,
1432
+ alternatives<
1433
+ NONASCII,
1434
+ escapable_character
1435
+ >
1436
+ >
1437
+ >(src);
1438
+ }
1439
+
1440
+ const char* list_terminator(const char* src) {
1441
+ return alternatives <
1442
+ exactly<';'>,
1443
+ exactly<'}'>,
1444
+ exactly<'{'>,
1445
+ exactly<')'>,
1446
+ exactly<']'>,
1447
+ exactly<':'>,
1448
+ end_of_file,
1449
+ exactly<ellipsis>,
1450
+ default_flag,
1451
+ global_flag
1452
+ >(src);
1453
+ };
1454
+
1455
+ const char* space_list_terminator(const char* src) {
1456
+ return alternatives <
1457
+ exactly<','>,
1458
+ list_terminator
1459
+ >(src);
1460
+ };
1461
+
1462
+
1463
+ // const char* real_uri_prefix(const char* src) {
1464
+ // return alternatives<
1465
+ // exactly< url_kwd >,
1466
+ // exactly< url_prefix_kwd >
1467
+ // >(src);
1468
+ // }
1469
+
1470
+ const char* real_uri(const char* src) {
1471
+ return sequence<
1472
+ exactly< url_kwd >,
1473
+ exactly< '(' >,
1474
+ W,
1475
+ real_uri_value,
1476
+ exactly< ')' >
1477
+ >(src);
1478
+ }
1479
+
1480
+ const char* real_uri_suffix(const char* src) {
1481
+ return sequence< W, exactly< ')' > >(src);
1482
+ }
1483
+
1484
+ const char* real_uri_value(const char* src) {
1485
+ return
1486
+ sequence<
1487
+ non_greedy<
1488
+ alternatives<
1489
+ class_char< real_uri_chars >,
1490
+ uri_character,
1491
+ NONASCII,
1492
+ ESCAPE
1493
+ >,
1494
+ alternatives<
1495
+ real_uri_suffix,
1496
+ exactly< hash_lbrace >
1497
+ >
1498
+ >
1499
+ >
1500
+ (src);
1501
+ }
1502
+
1503
+ const char* static_string(const char* src) {
1504
+ const char* pos = src;
1505
+ const char * s = quoted_string(pos);
1506
+ Token t(pos, s);
1507
+ const unsigned int p = count_interval< interpolant >(t.begin, t.end);
1508
+ return (p == 0) ? t.end : 0;
1509
+ }
1510
+
1511
+ const char* unicode_seq(const char* src) {
1512
+ return sequence <
1513
+ alternatives <
1514
+ exactly< 'U' >,
1515
+ exactly< 'u' >
1516
+ >,
1517
+ exactly< '+' >,
1518
+ padded_token <
1519
+ 6, xdigit,
1520
+ exactly < '?' >
1521
+ >
1522
+ >(src);
1523
+ }
1524
+
1525
+ const char* static_component(const char* src) {
1526
+ return alternatives< identifier,
1527
+ static_string,
1528
+ percentage,
1529
+ hex,
1530
+ hexa,
1531
+ exactly<'|'>,
1532
+ // exactly<'+'>,
1533
+ sequence < number, unit_identifier >,
1534
+ number,
1535
+ sequence< exactly<'!'>, word<important_kwd> >
1536
+ >(src);
1537
+ }
1538
+
1539
+ const char* static_property(const char* src) {
1540
+ return
1541
+ sequence <
1542
+ zero_plus<
1543
+ sequence <
1544
+ optional_css_comments,
1545
+ alternatives <
1546
+ exactly<','>,
1547
+ exactly<'('>,
1548
+ exactly<')'>,
1549
+ kwd_optional,
1550
+ quoted_string,
1551
+ interpolant,
1552
+ identifier,
1553
+ percentage,
1554
+ dimension,
1555
+ variable,
1556
+ alnum,
1557
+ sequence <
1558
+ exactly <'\\'>,
1559
+ any_char
1560
+ >
1561
+ >
1562
+ >
1563
+ >,
1564
+ lookahead <
1565
+ sequence <
1566
+ optional_css_comments,
1567
+ alternatives <
1568
+ exactly <';'>,
1569
+ exactly <'}'>,
1570
+ end_of_file
1571
+ >
1572
+ >
1573
+ >
1574
+ >(src);
1575
+ }
1576
+
1577
+ const char* static_value(const char* src) {
1578
+ return sequence< sequence<
1579
+ static_component,
1580
+ zero_plus< identifier >
1581
+ >,
1582
+ zero_plus < sequence<
1583
+ alternatives<
1584
+ sequence< optional_spaces, alternatives<
1585
+ exactly < '/' >,
1586
+ exactly < ',' >,
1587
+ exactly < ' ' >
1588
+ >, optional_spaces >,
1589
+ spaces
1590
+ >,
1591
+ static_component
1592
+ > >,
1593
+ zero_plus < spaces >,
1594
+ alternatives< exactly<';'>, exactly<'}'> >
1595
+ >(src);
1596
+ }
1597
+
1598
+ extern const char css_variable_url_negates[] = "()[]{}\"'#/";
1599
+ const char* css_variable_value(const char* src) {
1600
+ return sequence<
1601
+ alternatives<
1602
+ sequence<
1603
+ negate< exactly< url_fn_kwd > >,
1604
+ one_plus< neg_class_char< css_variable_url_negates > >
1605
+ >,
1606
+ sequence< exactly<'#'>, negate< exactly<'{'> > >,
1607
+ sequence< exactly<'/'>, negate< exactly<'*'> > >,
1608
+ static_string,
1609
+ real_uri,
1610
+ block_comment
1611
+ >
1612
+ >(src);
1613
+ }
1614
+
1615
+ extern const char css_variable_url_top_level_negates[] = "()[]{}\"'#/;";
1616
+ const char* css_variable_top_level_value(const char* src) {
1617
+ return sequence<
1618
+ alternatives<
1619
+ sequence<
1620
+ negate< exactly< url_fn_kwd > >,
1621
+ one_plus< neg_class_char< css_variable_url_top_level_negates > >
1622
+ >,
1623
+ sequence< exactly<'#'>, negate< exactly<'{'> > >,
1624
+ sequence< exactly<'/'>, negate< exactly<'*'> > >,
1625
+ static_string,
1626
+ real_uri,
1627
+ block_comment
1628
+ >
1629
+ >(src);
1630
+ }
1631
+
1632
+ const char* parenthese_scope(const char* src) {
1633
+ return sequence <
1634
+ exactly < '(' >,
1635
+ skip_over_scopes <
1636
+ exactly < '(' >,
1637
+ exactly < ')' >
1638
+ >
1639
+ >(src);
1640
+ }
1641
+
1642
+ const char* re_selector_list(const char* src) {
1643
+ return alternatives <
1644
+ // partial bem selector
1645
+ sequence <
1646
+ ampersand,
1647
+ one_plus <
1648
+ exactly < '-' >
1649
+ >,
1650
+ word_boundary,
1651
+ optional_spaces
1652
+ >,
1653
+ // main selector matching
1654
+ one_plus <
1655
+ alternatives <
1656
+ // consume whitespace and comments
1657
+ spaces, block_comment, line_comment,
1658
+ // match `/deep/` selector (pass-trough)
1659
+ // there is no functionality for it yet
1660
+ schema_reference_combinator,
1661
+ // match selector ops /[*&%,\[\]]/
1662
+ class_char < selector_lookahead_ops >,
1663
+ // match selector combinators /[>+~]/
1664
+ class_char < selector_combinator_ops >,
1665
+ // match pseudo selectors
1666
+ sequence <
1667
+ exactly <'('>,
1668
+ optional_spaces,
1669
+ optional <re_selector_list>,
1670
+ optional_spaces,
1671
+ exactly <')'>
1672
+ >,
1673
+ // match attribute compare operators
1674
+ alternatives <
1675
+ exact_match, class_match, dash_match,
1676
+ prefix_match, suffix_match, substring_match
1677
+ >,
1678
+ // main selector match
1679
+ sequence <
1680
+ // allow namespace prefix
1681
+ optional < namespace_schema >,
1682
+ // modifiers prefixes
1683
+ alternatives <
1684
+ sequence <
1685
+ exactly <'#'>,
1686
+ // not for interpolation
1687
+ negate < exactly <'{'> >
1688
+ >,
1689
+ // class match
1690
+ exactly <'.'>,
1691
+ // single or double colon
1692
+ sequence <
1693
+ optional < pseudo_prefix >,
1694
+ // fix libsass issue 2376
1695
+ negate < uri_prefix >
1696
+ >
1697
+ >,
1698
+ // accept hypens in token
1699
+ one_plus < sequence <
1700
+ // can start with hyphens
1701
+ zero_plus <
1702
+ sequence <
1703
+ exactly <'-'>,
1704
+ optional_spaces
1705
+ >
1706
+ >,
1707
+ // now the main token
1708
+ alternatives <
1709
+ kwd_optional,
1710
+ exactly <'*'>,
1711
+ quoted_string,
1712
+ interpolant,
1713
+ identifier,
1714
+ variable,
1715
+ percentage,
1716
+ binomial,
1717
+ dimension,
1718
+ alnum
1719
+ >
1720
+ > >,
1721
+ // can also end with hyphens
1722
+ zero_plus < exactly<'-'> >
1723
+ >
1724
+ >
1725
+ >
1726
+ >(src);
1727
+ }
1728
+
1729
+ const char* type_selector(const char* src) {
1730
+ return sequence< optional<namespace_schema>, identifier>(src);
1731
+ }
1732
+ const char* re_type_selector(const char* src) {
1733
+ return alternatives< type_selector, universal, dimension, percentage, number, identifier_alnums >(src);
1734
+ }
1735
+ const char* re_static_expression(const char* src) {
1736
+ return sequence< number, optional_spaces, exactly<'/'>, optional_spaces, number >(src);
1737
+ }
1738
+
1739
+ // lexer special_fn: these functions cannot be overloaded
1740
+ // (/((-[\w-]+-)?(calc|element)|expression|progid:[a-z\.]*)\(/i)
1741
+ const char* re_special_fun(const char* src) {
1742
+
1743
+ // match this first as we test prefix hyphens
1744
+ if (const char* calc = calc_fn_call(src)) {
1745
+ return calc;
1746
+ }
1747
+
1748
+ return sequence <
1749
+ optional <
1750
+ sequence <
1751
+ exactly <'-'>,
1752
+ one_plus <
1753
+ alternatives <
1754
+ alpha,
1755
+ exactly <'+'>,
1756
+ exactly <'-'>
1757
+ >
1758
+ >
1759
+ >
1760
+ >,
1761
+ alternatives <
1762
+ word < expression_kwd >,
1763
+ sequence <
1764
+ sequence <
1765
+ exactly < progid_kwd >,
1766
+ exactly <':'>
1767
+ >,
1768
+ zero_plus <
1769
+ alternatives <
1770
+ char_range <'a', 'z'>,
1771
+ exactly <'.'>
1772
+ >
1773
+ >
1774
+ >
1775
+ >
1776
+ >(src);
1777
+ }
1778
+
1779
+ }
1780
+ }