sassc 0.0.9 → 0.0.10

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 (111) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -1
  3. data/ext/libsass/.gitignore +13 -6
  4. data/ext/libsass/Makefile +42 -26
  5. data/ext/libsass/Makefile.am +43 -30
  6. data/ext/libsass/Readme.md +4 -2
  7. data/ext/libsass/appveyor.yml +10 -14
  8. data/ext/libsass/ast.cpp +54 -44
  9. data/ext/libsass/ast.hpp +404 -236
  10. data/ext/libsass/ast_def_macros.hpp +5 -0
  11. data/ext/libsass/ast_factory.hpp +6 -3
  12. data/ext/libsass/ast_fwd_decl.hpp +12 -0
  13. data/ext/libsass/b64/encode.h +2 -2
  14. data/ext/libsass/backtrace.hpp +13 -17
  15. data/ext/libsass/base64vlq.hpp +4 -1
  16. data/ext/libsass/bind.cpp +12 -15
  17. data/ext/libsass/bind.hpp +6 -6
  18. data/ext/libsass/color_names.hpp +4 -1
  19. data/ext/libsass/configure.ac +7 -21
  20. data/ext/libsass/constants.cpp +6 -4
  21. data/ext/libsass/constants.hpp +10 -4
  22. data/ext/libsass/context.cpp +89 -58
  23. data/ext/libsass/context.hpp +28 -35
  24. data/ext/libsass/contextualize.cpp +20 -10
  25. data/ext/libsass/contextualize.hpp +8 -23
  26. data/ext/libsass/contrib/libsass.spec +66 -0
  27. data/ext/libsass/cssize.cpp +547 -0
  28. data/ext/libsass/cssize.hpp +82 -0
  29. data/ext/libsass/debug.hpp +3 -3
  30. data/ext/libsass/debugger.hpp +358 -0
  31. data/ext/libsass/emitter.cpp +255 -0
  32. data/ext/libsass/emitter.hpp +83 -0
  33. data/ext/libsass/environment.hpp +7 -3
  34. data/ext/libsass/error_handling.cpp +11 -14
  35. data/ext/libsass/error_handling.hpp +9 -7
  36. data/ext/libsass/eval.cpp +253 -161
  37. data/ext/libsass/eval.hpp +13 -13
  38. data/ext/libsass/expand.cpp +135 -64
  39. data/ext/libsass/expand.hpp +11 -13
  40. data/ext/libsass/extend.cpp +66 -20
  41. data/ext/libsass/extend.hpp +6 -11
  42. data/ext/libsass/file.cpp +31 -26
  43. data/ext/libsass/file.hpp +6 -1
  44. data/ext/libsass/functions.cpp +270 -287
  45. data/ext/libsass/functions.hpp +8 -11
  46. data/ext/libsass/inspect.cpp +385 -255
  47. data/ext/libsass/inspect.hpp +15 -26
  48. data/ext/libsass/kwd_arg_macros.hpp +5 -0
  49. data/ext/libsass/mapping.hpp +4 -3
  50. data/ext/libsass/memory_manager.hpp +5 -2
  51. data/ext/libsass/node.cpp +50 -50
  52. data/ext/libsass/node.hpp +26 -27
  53. data/ext/libsass/operation.hpp +15 -4
  54. data/ext/libsass/output.cpp +401 -0
  55. data/ext/libsass/output.hpp +56 -0
  56. data/ext/libsass/parser.cpp +573 -399
  57. data/ext/libsass/parser.hpp +122 -88
  58. data/ext/libsass/paths.hpp +7 -2
  59. data/ext/libsass/plugins.cpp +155 -0
  60. data/ext/libsass/plugins.hpp +56 -0
  61. data/ext/libsass/position.cpp +128 -0
  62. data/ext/libsass/position.hpp +108 -11
  63. data/ext/libsass/prelexer.cpp +184 -110
  64. data/ext/libsass/prelexer.hpp +131 -24
  65. data/ext/libsass/remove_placeholders.cpp +1 -1
  66. data/ext/libsass/remove_placeholders.hpp +6 -6
  67. data/ext/libsass/sass.cpp +3 -3
  68. data/ext/libsass/sass.h +12 -4
  69. data/ext/libsass/sass2scss.cpp +3 -2
  70. data/ext/libsass/sass2scss.h +5 -0
  71. data/ext/libsass/sass_context.cpp +136 -37
  72. data/ext/libsass/sass_context.h +19 -10
  73. data/ext/libsass/sass_functions.cpp +29 -2
  74. data/ext/libsass/sass_functions.h +8 -2
  75. data/ext/libsass/sass_interface.cpp +32 -23
  76. data/ext/libsass/sass_interface.h +9 -4
  77. data/ext/libsass/sass_util.cpp +19 -23
  78. data/ext/libsass/sass_util.hpp +28 -27
  79. data/ext/libsass/sass_values.cpp +6 -4
  80. data/ext/libsass/sass_values.h +3 -3
  81. data/ext/libsass/script/ci-build-libsass +13 -1
  82. data/ext/libsass/script/ci-report-coverage +2 -1
  83. data/ext/libsass/source_map.cpp +79 -28
  84. data/ext/libsass/source_map.hpp +35 -16
  85. data/ext/libsass/subset_map.hpp +6 -4
  86. data/ext/libsass/to_c.hpp +4 -4
  87. data/ext/libsass/to_string.cpp +13 -8
  88. data/ext/libsass/to_string.hpp +6 -4
  89. data/ext/libsass/units.cpp +2 -1
  90. data/ext/libsass/units.hpp +6 -1
  91. data/ext/libsass/utf8_string.cpp +0 -5
  92. data/ext/libsass/utf8_string.hpp +3 -2
  93. data/ext/libsass/util.cpp +461 -49
  94. data/ext/libsass/util.hpp +34 -13
  95. data/ext/libsass/version.sh +10 -0
  96. data/ext/libsass/win/libsass.filters +20 -11
  97. data/ext/libsass/win/libsass.vcxproj +11 -8
  98. data/lib/sassc/importer.rb +1 -8
  99. data/lib/sassc/native.rb +7 -0
  100. data/lib/sassc/native/native_context_api.rb +5 -5
  101. data/lib/sassc/version.rb +1 -1
  102. data/test/native_test.rb +1 -1
  103. metadata +14 -10
  104. data/ext/libsass/copy_c_str.cpp +0 -13
  105. data/ext/libsass/copy_c_str.hpp +0 -5
  106. data/ext/libsass/output_compressed.cpp +0 -401
  107. data/ext/libsass/output_compressed.hpp +0 -95
  108. data/ext/libsass/output_nested.cpp +0 -364
  109. data/ext/libsass/output_nested.hpp +0 -108
  110. data/ext/libsass/test-driver +0 -127
  111. data/ext/libsass/token.hpp +0 -32
@@ -0,0 +1,56 @@
1
+ #ifndef SASS_PLUGINS_H
2
+ #define SASS_PLUGINS_H
3
+
4
+ #include <string>
5
+ #include <vector>
6
+ #include "utf8_string.hpp"
7
+ #include "sass_functions.h"
8
+
9
+ #ifdef _WIN32
10
+
11
+ #define LOAD_LIB(var, path) HMODULE var = LoadLibraryW(UTF_8::convert_to_utf16(path).c_str())
12
+ #define LOAD_LIB_WCHR(var, path_wide_str) HMODULE var = LoadLibraryW(path_wide_str.c_str())
13
+ #define LOAD_LIB_FN(type, var, name) type var = (type) GetProcAddress(plugin, name)
14
+ #define CLOSE_LIB(var) FreeLibrary(var)
15
+
16
+ #ifndef dlerror
17
+ #define dlerror() 0
18
+ #endif
19
+
20
+ #else
21
+
22
+ #define LOAD_LIB(var, path) void* var = dlopen(path.c_str(), RTLD_LAZY)
23
+ #define LOAD_LIB_FN(type, var, name) type var = (type) dlsym(plugin, name)
24
+ #define CLOSE_LIB(var) dlclose(var)
25
+
26
+ #endif
27
+
28
+ namespace Sass {
29
+
30
+ using namespace std;
31
+
32
+ class Plugins {
33
+
34
+ public: // c-tor
35
+ Plugins(void);
36
+ ~Plugins(void);
37
+
38
+ public: // methods
39
+ // load one specific plugin
40
+ bool load_plugin(const string& path);
41
+ // load all plugins from a directory
42
+ size_t load_plugins(const string& path);
43
+
44
+ public: // public accessors
45
+ // const vector<Sass_C_Import_Callback> get_importers(void) { return importers; };
46
+ const vector<Sass_C_Function_Callback> get_functions(void) { return functions; };
47
+
48
+ private: // private vars
49
+ // vector<Sass_C_Import_Callback> importers;
50
+ vector<Sass_C_Function_Callback> functions;
51
+
52
+ };
53
+
54
+ }
55
+
56
+ #endif
@@ -0,0 +1,128 @@
1
+ #include "position.hpp"
2
+
3
+ namespace Sass {
4
+
5
+ using namespace std;
6
+
7
+ Offset::Offset(const char* string)
8
+ : line(0), column(0)
9
+ {
10
+ *this = inc(string, string + strlen(string));
11
+ }
12
+
13
+ Offset::Offset(const string& text)
14
+ : line(0), column(0)
15
+ {
16
+ *this = inc(text.c_str(), text.c_str() + text.size());
17
+ }
18
+
19
+ Offset::Offset(const size_t line, const size_t column)
20
+ : line(line), column(column) { }
21
+
22
+ // increase offset by given string (mostly called by lexer)
23
+ // increase line counter and count columns on the last line
24
+ Offset Offset::inc(const char* begin, const char* end) const
25
+ {
26
+ Offset offset(line, column);
27
+ while (begin < end && *begin) {
28
+ if (*begin == '\n') {
29
+ ++ offset.line;
30
+ offset.column = 0;
31
+ } else {
32
+ ++ offset.column;
33
+ }
34
+ ++begin;
35
+ }
36
+ return offset;
37
+ }
38
+
39
+ bool Offset::operator== (const Offset &pos) const
40
+ {
41
+ return line == pos.line && column == pos.column;
42
+ }
43
+
44
+ bool Offset::operator!= (const Offset &pos) const
45
+ {
46
+ return line != pos.line || column != pos.column;
47
+ }
48
+
49
+ void Offset::operator+= (const Offset &off)
50
+ {
51
+ *this = Offset(line + off.line, off.line > 0 ? off.column : off.column + column);
52
+ }
53
+
54
+ Offset Offset::operator+ (const Offset &off) const
55
+ {
56
+ return Offset(line + off.line, off.line > 0 ? off.column : off.column + column);
57
+ }
58
+
59
+ Position::Position(const size_t file)
60
+ : Offset(0, 0), file(file) { }
61
+
62
+ Position::Position(const size_t file, const Offset& offset)
63
+ : Offset(offset), file(file) { }
64
+
65
+ Position::Position(const size_t line, const size_t column)
66
+ : Offset(line, column), file(-1) { }
67
+
68
+ Position::Position(const size_t file, const size_t line, const size_t column)
69
+ : Offset(line, column), file(file) { }
70
+
71
+
72
+ ParserState::ParserState(string path)
73
+ : Position(-1, 0, 0), path(path), offset(0, 0), token() { }
74
+
75
+ ParserState::ParserState(string path, const size_t file)
76
+ : Position(file, 0, 0), path(path), offset(0, 0), token() { }
77
+
78
+ ParserState::ParserState(string path, Position position, Offset offset)
79
+ : Position(position), path(path), offset(offset), token() { }
80
+
81
+ ParserState::ParserState(string path, Token token, Position position, Offset offset)
82
+ : Position(position), path(path), offset(offset), token(token) { }
83
+
84
+ Position Position::inc(const char* begin, const char* end) const
85
+ {
86
+ Offset offset(line, column);
87
+ offset = offset.inc(begin, end);
88
+ return Position(file, offset);
89
+ }
90
+
91
+ bool Position::operator== (const Position &pos) const
92
+ {
93
+ return file == pos.file && line == pos.line && column == pos.column;
94
+ }
95
+
96
+ bool Position::operator!= (const Position &pos) const
97
+ {
98
+ return file == pos.file || line != pos.line || column != pos.column;
99
+ }
100
+
101
+ void Position::operator+= (const Offset &off)
102
+ {
103
+ *this = Position(file, line + off.line, off.line > 0 ? off.column : off.column + column);
104
+ }
105
+
106
+ const Position Position::operator+ (const Offset &off) const
107
+ {
108
+ return Position(file, line + off.line, off.line > 0 ? off.column : off.column + column);
109
+ }
110
+
111
+ /* not used anymore - remove?
112
+ std::ostream& operator<<(std::ostream& strm, const Offset& off)
113
+ {
114
+ if (off.line == string::npos) strm << "-1:"; else strm << off.line << ":";
115
+ if (off.column == string::npos) strm << "-1"; else strm << off.column;
116
+ return strm;
117
+ } */
118
+
119
+ /* not used anymore - remove?
120
+ std::ostream& operator<<(std::ostream& strm, const Position& pos)
121
+ {
122
+ if (pos.file != string::npos) strm << pos.file << ":";
123
+ if (pos.line == string::npos) strm << "-1:"; else strm << pos.line << ":";
124
+ if (pos.column == string::npos) strm << "-1"; else strm << pos.column;
125
+ return strm;
126
+ } */
127
+
128
+ }
@@ -1,22 +1,119 @@
1
- #define SASS_POSITION
1
+ #ifndef SASS_POSITION_H
2
+ #define SASS_POSITION_H
2
3
 
4
+ #include <string>
5
+ #include <cstring>
3
6
  #include <cstdlib>
7
+ #include <sstream>
8
+ #include <iostream>
4
9
 
5
10
  namespace Sass {
6
11
 
7
- struct Position {
8
- size_t file;
9
- size_t line;
10
- size_t column;
12
+ using namespace std;
11
13
 
12
- Position()
13
- : file(0), line(0), column(0) { }
14
+ class Offset {
14
15
 
15
- Position(const size_t file, const size_t line, const size_t column)
16
- : file(file), line(line), column(column) { }
16
+ public: // c-tor
17
+ Offset(const char* string);
18
+ Offset(const string& text);
19
+ Offset(const size_t line, const size_t column);
20
+
21
+ // return new position, incremented by the given string
22
+ Offset inc(const char* begin, const char* end) const;
23
+
24
+ public: // overload operators for position
25
+ void operator+= (const Offset &pos);
26
+ bool operator== (const Offset &pos) const;
27
+ bool operator!= (const Offset &pos) const;
28
+ Offset operator+ (const Offset &off) const;
29
+
30
+ public: // overload output stream operator
31
+ // friend ostream& operator<<(ostream& strm, const Offset& off);
32
+
33
+ public:
34
+ Offset off() { return *this; };
35
+
36
+ public:
37
+ size_t line;
38
+ size_t column;
39
+
40
+ };
41
+
42
+ class Position : public Offset {
43
+
44
+ public: // c-tor
45
+ Position(const size_t file); // line(0), column(0)
46
+ Position(const size_t file, const Offset& offset);
47
+ Position(const size_t line, const size_t column); // file(-1)
48
+ Position(const size_t file, const size_t line, const size_t column);
49
+
50
+ public: // overload operators for position
51
+ void operator+= (const Offset &off);
52
+ bool operator== (const Position &pos) const;
53
+ bool operator!= (const Position &pos) const;
54
+ const Position operator+ (const Offset &off) const;
55
+ // return new position, incremented by the given string
56
+ Position inc(const char* begin, const char* end) const;
57
+
58
+ public: // overload output stream operator
59
+ // friend ostream& operator<<(ostream& strm, const Position& pos);
60
+
61
+ public:
62
+ size_t file;
63
+
64
+ };
65
+
66
+ // Token type for representing lexed chunks of text
67
+ class Token {
68
+ public:
69
+ const char* prefix;
70
+ const char* begin;
71
+ const char* end;
72
+ const char* suffix;
73
+ Position start;
74
+ Position stop;
75
+
76
+ Token()
77
+ : prefix(0), begin(0), end(0), suffix(0), start(0), stop(0) { }
78
+ Token(const char* b, const char* e, const Position pos)
79
+ : prefix(b), begin(b), end(e), suffix(e), start(pos), stop(pos.inc(b, e)) { }
80
+ Token(const char* s, const Position pos)
81
+ : prefix(s), begin(s), end(s + strlen(s)), suffix(end), start(pos), stop(pos.inc(s, s + strlen(s))) { }
82
+ Token(const char* p, const char* b, const char* e, const char* s, const Position pos)
83
+ : prefix(p), begin(b), end(e), suffix(s), start(pos), stop(pos.inc(b, e)) { }
84
+
85
+ size_t length() const { return end - begin; }
86
+ string ws_before() const { return string(prefix, begin); }
87
+ string to_string() const { return string(begin, end); }
88
+ string ws_after() const { return string(end, suffix); }
89
+
90
+ // string unquote() const;
91
+
92
+ operator bool() { return begin && end && begin >= end; }
93
+ operator string() { return to_string(); }
94
+
95
+ bool operator==(Token t) { return to_string() == t.to_string(); }
96
+ };
97
+
98
+ class ParserState : public Position {
99
+
100
+ public: // c-tor
101
+ ParserState(string path);
102
+ ParserState(string path, const size_t file);
103
+ ParserState(string path, Position position, Offset offset = Offset(0, 0));
104
+ ParserState(string path, Token token, Position position, Offset offset = Offset(0, 0));
105
+
106
+ public: // down casts
107
+ Offset off() { return *this; };
108
+ Position pos() { return *this; };
109
+
110
+ public:
111
+ string path;
112
+ Offset offset;
113
+ Token token;
17
114
 
18
- Position(const size_t line, const size_t column)
19
- : file(0), line(line), column(column) { }
20
115
  };
21
116
 
22
117
  }
118
+
119
+ #endif
@@ -2,9 +2,10 @@
2
2
  #include <cstddef>
3
3
  #include <iostream>
4
4
  #include <iomanip>
5
- #include "constants.hpp"
6
- #include "prelexer.hpp"
7
5
  #include "util.hpp"
6
+ #include "position.hpp"
7
+ #include "prelexer.hpp"
8
+ #include "constants.hpp"
8
9
 
9
10
 
10
11
  namespace Sass {
@@ -13,16 +14,20 @@ namespace Sass {
13
14
  namespace Prelexer {
14
15
  using std::ptrdiff_t;
15
16
  // Matches zero characters (always succeeds without consuming input).
17
+ /* not used anymore - remove?
16
18
  const char* epsilon(char *src) {
17
19
  return src;
18
- }
20
+ }*/
19
21
  // Matches the empty string.
22
+ /* not used anymore - remove?
20
23
  const char* empty(char *src) {
21
24
  return *src ? 0 : src;
22
- }
25
+ }*/
23
26
 
24
27
  // Match any single character.
25
28
  const char* any_char(const char* src) { return *src ? src+1 : src; }
29
+ // Match word boundary (look ahead)
30
+ const char* word_boundary(const char* src) { return !*src || isspace(*src) || ispunct(*src) || !Sass::Util::isAscii(*src) ? src : 0 ; }
26
31
 
27
32
  // Match a single character satisfying the ctype predicates.
28
33
  const char* space(const char* src) { return std::isspace(*src) ? src+1 : 0; }
@@ -54,9 +59,18 @@ namespace Sass {
54
59
  }
55
60
  // Match either comment.
56
61
  const char* comment(const char* src) {
57
- return alternatives<block_comment, line_comment>(src);
62
+ return line_comment(src);
63
+ }
64
+
65
+ const char* wspaces(const char* src) {
66
+ return
67
+ alternatives<
68
+ exactly<' '>,
69
+ exactly<'\t'>
70
+ >(src);
58
71
  }
59
72
 
73
+ /* not used anymore - remove?
60
74
  const char* newline(const char* src) {
61
75
  return
62
76
  alternatives<
@@ -65,79 +79,31 @@ namespace Sass {
65
79
  exactly<'\r'>,
66
80
  exactly<'\f'>
67
81
  >(src);
68
- }
82
+ }*/
69
83
 
84
+ /* not used anymore - remove?
70
85
  const char* whitespace(const char* src) {
71
- return
72
- alternatives<
73
- newline,
74
- exactly<' '>,
75
- exactly<'\t'>
76
- >(src);
77
- }
86
+ return spaces(src);
87
+ }*/
78
88
 
89
+ /* not used anymore - remove?
79
90
  const char* escape(const char* src) {
80
91
  return
81
92
  sequence<
82
93
  exactly<'\\'>,
83
94
  any_char
84
95
  >(src);
85
- }
86
-
87
- // Match double- and single-quoted strings.
88
- const char* double_quoted_string(const char* src) {
89
- src = exactly<'"'>(src);
90
- if (!src) return 0;
91
- const char* p;
92
- while (1) {
93
- if (!*src) return 0;
94
- if((p = escape(src))) {
95
- src = p;
96
- continue;
97
- }
98
- else if((p = exactly<'"'>(src))) {
99
- return p;
100
- }
101
- else {
102
- ++src;
103
- }
104
- }
105
- return 0;
106
- }
107
- const char* single_quoted_string(const char* src) {
108
- src = exactly<'\''>(src);
109
- if (!src) return 0;
110
- const char* p;
111
- while (1) {
112
- if (!*src) return 0;
113
- if((p = escape(src))) {
114
- src = p;
115
- continue;
116
- }
117
- else if((p = exactly<'\''>(src))) {
118
- return p;
119
- }
120
- else {
121
- ++src;
122
- }
123
- }
124
- return 0;
125
- }
126
- const char* string_constant(const char* src) {
127
- return alternatives<double_quoted_string, single_quoted_string>(src);
128
- }
129
- // Match interpolants.
96
+ }*/
130
97
 
131
98
 
132
- const char* interpolant(const char* src) {
133
- return delimited_by<hash_lbrace, rbrace, false>(src);
134
- }
135
-
136
99
  // Whitespace handling.
137
100
  const char* optional_spaces(const char* src) { return optional<spaces>(src); }
138
- const char* optional_comment(const char* src) { return optional<comment>(src); }
101
+ // const char* optional_comment(const char* src) { return optional<comment>(src); }
102
+ const char* optional_spaces_and_comments(const char* src) {
103
+ return zero_plus< alternatives<spaces, line_comment> >(src);
104
+ }
139
105
  const char* spaces_and_comments(const char* src) {
140
- return zero_plus< alternatives<spaces, comment> >(src);
106
+ return one_plus< alternatives<spaces, line_comment> >(src);
141
107
  }
142
108
  const char* no_spaces(const char* src) {
143
109
  return negate< spaces >(src);
@@ -165,6 +131,7 @@ namespace Sass {
165
131
  }
166
132
 
167
133
  // Match CSS selectors.
134
+ /* not used anymore - remove?
168
135
  const char* sel_ident(const char* src) {
169
136
  return sequence< optional< alternatives< exactly<'-'>, exactly<'|'> > >,
170
137
  alternatives< alpha, exactly<'_'>, backslash_something, exactly<'|'> >,
@@ -173,13 +140,25 @@ namespace Sass {
173
140
  exactly<'_'>,
174
141
  exactly<'|'>,
175
142
  backslash_something > > >(src);
176
- }
143
+ }*/
177
144
 
178
145
  // Match CSS css variables.
179
146
  const char* custom_property_name(const char* src) {
180
147
  return sequence< exactly<'-'>, exactly<'-'>, identifier >(src);
181
148
  }
182
149
 
150
+ // Match number prefix ([\+\-]+)
151
+ const char* number_prefix(const char* src) {
152
+ return alternatives <
153
+ exactly < '+' >,
154
+ sequence <
155
+ exactly < '-' >,
156
+ optional_spaces_and_comments,
157
+ exactly< '-' >
158
+ >
159
+ >(src);
160
+ }
161
+
183
162
  // Match interpolant schemas
184
163
  const char* identifier_schema(const char* src) {
185
164
  // follows this pattern: (x*ix*)+ ... well, not quite
@@ -188,17 +167,71 @@ namespace Sass {
188
167
  zero_plus< alternatives< identifier, number, exactly<'-'> > > > >,
189
168
  negate< exactly<'%'> > >(src);
190
169
  }
170
+
171
+ // interpolants can be recursive/nested
172
+ const char* interpolant(const char* src) {
173
+ return recursive_scopes< exactly<hash_lbrace>, exactly<rbrace> >(src);
174
+ }
175
+
176
+ // $re_squote = /'(?:$re_itplnt|\\.|[^'])*'/
177
+ const char* single_quoted_string(const char* src) {
178
+ // match a single quoted string, while skipping interpolants
179
+ return sequence <
180
+ exactly <'\''>,
181
+ zero_plus <
182
+ alternatives <
183
+ // skip all escaped chars first
184
+ backslash_something,
185
+ // skip interpolants
186
+ interpolant,
187
+ // skip non delimiters
188
+ any_char_except < '\'' >
189
+ >
190
+ >,
191
+ exactly <'\''>
192
+ >(src);
193
+ }
194
+
195
+ // $re_dquote = /"(?:$re_itp|\\.|[^"])*"/
196
+ const char* double_quoted_string(const char* src) {
197
+ // match a single quoted string, while skipping interpolants
198
+ return sequence <
199
+ exactly <'"'>,
200
+ zero_plus <
201
+ alternatives <
202
+ // skip all escaped chars first
203
+ backslash_something,
204
+ // skip interpolants
205
+ interpolant,
206
+ // skip non delimiters
207
+ any_char_except < '"' >
208
+ >
209
+ >,
210
+ exactly <'"'>
211
+ >(src);
212
+ }
213
+
214
+ // $re_quoted = /(?:$re_squote|$re_dquote)/
215
+ const char* quoted_string(const char* src) {
216
+ // match a quoted string, while skipping interpolants
217
+ return alternatives<
218
+ single_quoted_string,
219
+ double_quoted_string
220
+ >(src);
221
+ }
222
+
191
223
  const char* value_schema(const char* src) {
192
224
  // follows this pattern: ([xyz]*i[xyz]*)+
193
- return one_plus< sequence< zero_plus< alternatives< identifier, percentage, dimension, hex, number, string_constant > >,
225
+ return one_plus< sequence< zero_plus< alternatives< identifier, percentage, dimension, hex, number, quoted_string > >,
194
226
  interpolant,
195
- zero_plus< alternatives< identifier, percentage, dimension, hex, number, string_constant, exactly<'%'> > > > >(src);
227
+ zero_plus< alternatives< identifier, percentage, dimension, hex, number, quoted_string, exactly<'%'> > > > >(src);
196
228
  }
229
+ /* not used anymore - remove?
197
230
  const char* filename_schema(const char* src) {
198
231
  return one_plus< sequence< zero_plus< alternatives< identifier, number, exactly<'.'>, exactly<'/'> > >,
199
232
  interpolant,
200
233
  zero_plus< alternatives< identifier, number, exactly<'.'>, exactly<'/'> > > > >(src);
201
- }
234
+ }*/
202
235
 
203
236
  const char* filename(const char* src) {
204
237
  return one_plus< alternatives< identifier, number, exactly<'.'> > >(src);
@@ -213,6 +246,18 @@ namespace Sass {
213
246
  return exactly<import_kwd>(src);
214
247
  }
215
248
 
249
+ const char* at_root(const char* src) {
250
+ return exactly<at_root_kwd>(src);
251
+ }
252
+
253
+ const char* with_directive(const char* src) {
254
+ return exactly<with_kwd>(src);
255
+ }
256
+
257
+ const char* without_directive(const char* src) {
258
+ return exactly<without_kwd>(src);
259
+ }
260
+
216
261
  const char* media(const char* src) {
217
262
  return exactly<media_kwd>(src);
218
263
  }
@@ -221,17 +266,20 @@ namespace Sass {
221
266
  return exactly<supports_kwd>(src);
222
267
  }
223
268
 
269
+ /* not used anymore - remove?
224
270
  const char* keyframes(const char* src) {
225
271
  return sequence< exactly<'@'>, optional< vendor_prefix >, exactly< keyframes_kwd > >(src);
226
- }
272
+ } */
227
273
 
274
+ /* not used anymore - remove?
228
275
  const char* vendor_prefix(const char* src) {
229
276
  return alternatives< exactly< vendor_opera_kwd >, exactly< vendor_webkit_kwd >, exactly< vendor_mozilla_kwd >, exactly< vendor_ms_kwd >, exactly< vendor_khtml_kwd > >(src);
230
- }
277
+ } */
231
278
 
279
+ /* not used anymore - remove?
232
280
  const char* keyf(const char* src) {
233
281
  return one_plus< alternatives< to, from, percentage > >(src);
234
- }
282
+ } */
235
283
 
236
284
  const char* mixin(const char* src) {
237
285
  return exactly<mixin_kwd>(src);
@@ -254,7 +302,7 @@ namespace Sass {
254
302
  }
255
303
 
256
304
  const char* extend(const char* src) {
257
- return exactly<extend_kwd>(src);
305
+ return sequence < exactly<extend_kwd>, word_boundary >(src);
258
306
  }
259
307
 
260
308
 
@@ -267,7 +315,7 @@ namespace Sass {
267
315
  }
268
316
  const char* elseif_directive(const char* src) {
269
317
  return sequence< else_directive,
270
- spaces_and_comments,
318
+ optional_spaces_and_comments,
271
319
  exactly< if_after_else_kwd > >(src);
272
320
  }
273
321
 
@@ -318,9 +366,10 @@ namespace Sass {
318
366
  return exactly<debug_kwd>(src);
319
367
  }
320
368
 
369
+ /* not used anymore - remove?
321
370
  const char* directive(const char* src) {
322
371
  return sequence< exactly<'@'>, identifier >(src);
323
- }
372
+ } */
324
373
 
325
374
  const char* null(const char* src) {
326
375
  return exactly<null_kwd>(src);
@@ -389,11 +438,12 @@ namespace Sass {
389
438
  return sequence< number, exactly<'%'> >(src);
390
439
  }
391
440
 
441
+ /* not used anymore - remove?
392
442
  const char* em(const char* src) {
393
443
  return sequence< number, exactly<em_kwd> >(src);
394
- }
444
+ } */
395
445
  const char* dimension(const char* src) {
396
- return sequence<number, identifier>(src);
446
+ return sequence<number, one_plus< alpha > >(src);
397
447
  }
398
448
  const char* hex(const char* src) {
399
449
  const char* p = sequence< exactly<'#'>, one_plus<xdigit> >(src);
@@ -405,54 +455,63 @@ namespace Sass {
405
455
  ptrdiff_t len = p - src;
406
456
  return (len != 4 && len != 7 && len != 9) ? 0 : p;
407
457
  }
458
+ const char* hex0(const char* src) {
459
+ const char* p = sequence< exactly<'0'>, exactly<'x'>, one_plus<xdigit> >(src);
460
+ ptrdiff_t len = p - src;
461
+ return (len != 5 && len != 8) ? 0 : p;
462
+ }
408
463
 
464
+ /* no longer used - remove?
409
465
  const char* rgb_prefix(const char* src) {
410
466
  return exactly<rgb_kwd>(src);
411
- }
467
+ }*/
412
468
  // Match CSS uri specifiers.
413
469
 
414
470
  const char* uri_prefix(const char* src) {
415
471
  return exactly<url_kwd>(src);
416
472
  }
417
473
  // TODO: rename the following two functions
474
+ /* no longer used - remove?
418
475
  const char* uri(const char* src) {
419
476
  return sequence< exactly<url_kwd>,
420
477
  optional<spaces>,
421
- string_constant,
478
+ quoted_string,
422
479
  optional<spaces>,
423
480
  exactly<')'> >(src);
424
- }
481
+ }*/
482
+ /* no longer used - remove?
425
483
  const char* url_value(const char* src) {
426
484
  return sequence< optional< sequence< identifier, exactly<':'> > >, // optional protocol
427
485
  one_plus< sequence< zero_plus< exactly<'/'> >, filename > >, // one or more folders and/or trailing filename
428
486
  optional< exactly<'/'> > >(src);
429
- }
487
+ }*/
488
+ /* no longer used - remove?
430
489
  const char* url_schema(const char* src) {
431
490
  return sequence< optional< sequence< identifier, exactly<':'> > >, // optional protocol
432
491
  filename_schema >(src); // optional trailing slash
433
- }
492
+ }*/
434
493
  // Match CSS "!important" keyword.
435
494
  const char* important(const char* src) {
436
495
  return sequence< exactly<'!'>,
437
- spaces_and_comments,
496
+ optional_spaces_and_comments,
438
497
  exactly<important_kwd> >(src);
439
498
  }
440
499
  // Match CSS "!optional" keyword.
441
500
  const char* optional(const char* src) {
442
501
  return sequence< exactly<'!'>,
443
- spaces_and_comments,
502
+ optional_spaces_and_comments,
444
503
  exactly<optional_kwd> >(src);
445
504
  }
446
505
  // Match Sass "!default" keyword.
447
506
  const char* default_flag(const char* src) {
448
507
  return sequence< exactly<'!'>,
449
- spaces_and_comments,
508
+ optional_spaces_and_comments,
450
509
  exactly<default_kwd> >(src);
451
510
  }
452
511
  // Match Sass "!global" keyword.
453
512
  const char* global_flag(const char* src) {
454
513
  return sequence< exactly<'!'>,
455
- spaces_and_comments,
514
+ optional_spaces_and_comments,
456
515
  exactly<global_kwd> >(src);
457
516
  }
458
517
  // Match CSS pseudo-class/element prefixes.
@@ -485,6 +544,7 @@ namespace Sass {
485
544
  const char* suffix_match(const char* src) { return exactly<dollar_equal>(src); }
486
545
  const char* substring_match(const char* src) { return exactly<star_equal>(src); }
487
546
  // Match CSS combinators.
547
+ /* not used anymore - remove?
488
548
  const char* adjacent_to(const char* src) {
489
549
  return sequence< optional_spaces, exactly<'+'> >(src);
490
550
  }
@@ -496,7 +556,7 @@ namespace Sass {
496
556
  }
497
557
  const char* ancestor_of(const char* src) {
498
558
  return sequence< spaces, negate< exactly<'{'> > >(src);
499
- }
559
+ }*/
500
560
 
501
561
  // Match SCSS variable names.
502
562
  const char* variable(const char* src) {
@@ -550,29 +610,28 @@ namespace Sass {
550
610
  > >,
551
611
  zero_plus < sequence<
552
612
  exactly<'('>,
553
- spaces_and_comments,
613
+ optional_spaces_and_comments,
554
614
  optional < sequence<
555
615
  alternatives< variable, identifier_schema, identifier >,
556
- spaces_and_comments,
616
+ optional_spaces_and_comments,
557
617
  exactly<'='>,
558
- spaces_and_comments,
559
- alternatives< variable, identifier_schema, identifier, string_constant, number, hexa >,
618
+ optional_spaces_and_comments,
619
+ alternatives< variable, identifier_schema, identifier, quoted_string, number, hexa >,
560
620
  zero_plus< sequence<
561
- spaces_and_comments,
621
+ optional_spaces_and_comments,
562
622
  exactly<','>,
563
- spaces_and_comments,
623
+ optional_spaces_and_comments,
564
624
  sequence<
565
625
  alternatives< variable, identifier_schema, identifier >,
566
- spaces_and_comments,
626
+ optional_spaces_and_comments,
567
627
  exactly<'='>,
568
- spaces_and_comments,
569
- alternatives< variable, identifier_schema, identifier, string_constant, number, hexa >
628
+ optional_spaces_and_comments,
629
+ alternatives< variable, identifier_schema, identifier, quoted_string, number, hexa >
570
630
  >
571
631
  > >
572
632
  > >,
573
- spaces_and_comments,
574
- exactly<')'>,
575
- spaces_and_comments
633
+ optional_spaces_and_comments,
634
+ exactly<')'>
576
635
  > >
577
636
  >(src);
578
637
  }
@@ -584,22 +643,29 @@ namespace Sass {
584
643
  }
585
644
 
586
645
  // const char* ie_args(const char* src) {
587
- // return sequence< alternatives< ie_keyword_arg, value_schema, string_constant, interpolant, number, identifier, delimited_by< '(', ')', true> >,
588
- // zero_plus< sequence< spaces_and_comments, exactly<','>, spaces_and_comments, alternatives< ie_keyword_arg, value_schema, string_constant, interpolant, number, identifier, delimited_by<'(', ')', true> > > > >(src);
646
+ // return sequence< alternatives< ie_keyword_arg, value_schema, quoted_string, interpolant, number, identifier, delimited_by< '(', ')', true> >,
647
+ // zero_plus< sequence< optional_spaces_and_comments, exactly<','>, optional_spaces_and_comments, alternatives< ie_keyword_arg, value_schema, quoted_string, interpolant, number, identifier, delimited_by<'(', ')', true> > > > >(src);
589
648
  // }
590
649
 
591
650
  const char* ie_keyword_arg(const char* src) {
592
- return sequence< alternatives< variable, identifier_schema, identifier >, spaces_and_comments, exactly<'='>, spaces_and_comments, alternatives< variable, identifier_schema, identifier, string_constant, number, hexa > >(src);
651
+ return sequence<
652
+ alternatives< variable, identifier_schema, identifier >,
653
+ optional_spaces_and_comments,
654
+ exactly<'='>,
655
+ optional_spaces_and_comments,
656
+ alternatives< variable, identifier_schema, identifier, quoted_string, number, hexa >
657
+ >(src);
593
658
  }
594
659
 
595
660
  // Path matching functions.
661
+ /* not used anymore - remove?
596
662
  const char* folder(const char* src) {
597
663
  return sequence< zero_plus< any_char_except<'/'> >,
598
664
  exactly<'/'> >(src);
599
665
  }
600
666
  const char* folders(const char* src) {
601
667
  return zero_plus< folder >(src);
602
- }
668
+ }*/
603
669
 
604
670
  const char* chunk(const char* src) {
605
671
  char inside_str = 0;
@@ -629,26 +695,30 @@ namespace Sass {
629
695
  }
630
696
 
631
697
  // follow the CSS spec more closely and see if this helps us scan URLs correctly
698
+ /* not used anymore - remove?
632
699
  const char* NL(const char* src) {
633
700
  return alternatives< exactly<'\n'>,
634
701
  sequence< exactly<'\r'>, exactly<'\n'> >,
635
702
  exactly<'\r'>,
636
703
  exactly<'\f'> >(src);
637
- }
704
+ }*/
638
705
 
706
+ /* not used anymore - remove?
639
707
  const char* H(const char* src) {
640
708
  return std::isxdigit(*src) ? src+1 : 0;
641
- }
709
+ }*/
642
710
 
711
+ /* not used anymore - remove?
643
712
  const char* unicode(const char* src) {
644
713
  return sequence< exactly<'\\'>,
645
714
  between<H, 1, 6>,
646
715
  optional< class_char<url_space_chars> > >(src);
647
- }
716
+ }*/
648
717
 
718
+ /* not used anymore - remove?
649
719
  const char* ESCAPE(const char* src) {
650
720
  return alternatives< unicode, class_char<escape_chars> >(src);
651
- }
721
+ }*/
652
722
 
653
723
  const char* url(const char* src) {
654
724
  return chunk(src);
@@ -656,8 +726,8 @@ namespace Sass {
656
726
 
657
727
  const char* static_string(const char* src) {
658
728
  const char* pos = src;
659
- const char * s = string_constant(pos);
660
- Token t(pos, s);
729
+ const char * s = quoted_string(pos);
730
+ Token t(pos, s, Position(0, 0));
661
731
  const unsigned int p = count_interval< interpolant >(t.begin, t.end);
662
732
  return (p == 0) ? t.end : 0;
663
733
  }
@@ -665,6 +735,7 @@ namespace Sass {
665
735
  const char* static_component(const char* src) {
666
736
  return alternatives< identifier,
667
737
  static_string,
738
+ percentage,
668
739
  hex,
669
740
  number,
670
741
  sequence< exactly<'!'>, exactly<important_kwd> >
@@ -675,8 +746,11 @@ namespace Sass {
675
746
  return sequence< static_component,
676
747
  zero_plus < sequence<
677
748
  alternatives<
678
- sequence< optional_spaces, exactly<'/'>, optional_spaces >,
679
- sequence< optional_spaces, exactly<','>, optional_spaces >,
749
+ sequence< optional_spaces, alternatives<
750
+ exactly < '/' >,
751
+ exactly < ',' >,
752
+ exactly < ' ' >
753
+ >, optional_spaces >,
680
754
  spaces
681
755
  >,
682
756
  static_component