sassc 1.1.2 → 1.2.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.
@@ -57,6 +57,8 @@ namespace Sass {
57
57
  static Parser from_c_str(const char* src, Context& ctx, ParserState pstate = ParserState("[CSTRING]"));
58
58
  static Parser from_c_str(const char* beg, const char* end, Context& ctx, ParserState pstate = ParserState("[CSTRING]"));
59
59
  static Parser from_token(Token t, Context& ctx, ParserState pstate = ParserState("[TOKEN]"));
60
+ // special static parsers to convert strings into certain selectors
61
+ static Selector_List* parse_selector(const char* src, Context& ctx, ParserState pstate = ParserState("[SELECTOR]"));
60
62
 
61
63
  #ifdef __clang__
62
64
 
@@ -243,6 +245,7 @@ namespace Sass {
243
245
  String* parse_ie_property();
244
246
  String* parse_ie_keyword_arg();
245
247
  String_Schema* parse_value_schema(const char* stop);
248
+ Expression* parse_operators(Expression* factor);
246
249
  String* parse_identifier_schema();
247
250
  // String_Schema* parse_url_schema();
248
251
  If* parse_if_directive(bool else_if = false);
@@ -270,6 +273,7 @@ namespace Sass {
270
273
 
271
274
  void parse_block_comments(Block* block);
272
275
 
276
+ Selector_Lookahead lookahead_for_value(const char* start = 0);
273
277
  Selector_Lookahead lookahead_for_selector(const char* start = 0);
274
278
  Selector_Lookahead lookahead_for_extension_target(const char* start = 0);
275
279
 
@@ -34,7 +34,12 @@ namespace Sass {
34
34
  {
35
35
  return sequence<
36
36
  zero_plus < space >,
37
- delimited_by<slash_star, star_slash, false> >(src);
37
+ delimited_by<
38
+ slash_star,
39
+ star_slash,
40
+ false
41
+ >
42
+ >(src);
38
43
  }
39
44
  /* not use anymore - remove?
40
45
  const char* block_comment_prefix(const char* src) {
@@ -143,7 +148,12 @@ namespace Sass {
143
148
  exactly <'\''>,
144
149
  zero_plus <
145
150
  alternatives <
146
- // skip all escaped chars first
151
+ // skip escapes
152
+ sequence <
153
+ exactly < '\\' >,
154
+ exactly < '\r' >,
155
+ exactly < '\n' >
156
+ >,
147
157
  escape_seq,
148
158
  // skip interpolants
149
159
  interpolant,
@@ -162,7 +172,12 @@ namespace Sass {
162
172
  exactly <'"'>,
163
173
  zero_plus <
164
174
  alternatives <
165
- // skip all escaped chars first
175
+ // skip escapes
176
+ sequence <
177
+ exactly < '\\' >,
178
+ exactly < '\r' >,
179
+ exactly < '\n' >
180
+ >,
166
181
  escape_seq,
167
182
  // skip interpolants
168
183
  interpolant,
@@ -606,7 +621,7 @@ namespace Sass {
606
621
  >(src);
607
622
  }
608
623
  const char* ie_expression(const char* src) {
609
- return sequence < word<expression_kwd>, delimited_by< '(', ')', true> >(src);
624
+ return sequence < word<expression_kwd>, exactly<'('>, skip_over_scopes< exactly<'('>, exactly<')'> > >(src);
610
625
  }
611
626
  const char* ie_property(const char* src) {
612
627
  return alternatives < ie_expression, ie_progid >(src);
@@ -617,13 +632,38 @@ namespace Sass {
617
632
  // 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);
618
633
  // }
619
634
 
635
+ const char* ie_keyword_arg_property(const char* src) {
636
+ return alternatives <
637
+ variable,
638
+ identifier_schema,
639
+ identifier
640
+ >(src);
641
+ }
642
+ const char* ie_keyword_arg_value(const char* src) {
643
+ return alternatives <
644
+ variable,
645
+ identifier_schema,
646
+ identifier,
647
+ quoted_string,
648
+ number,
649
+ hexa,
650
+ sequence <
651
+ exactly < '(' >,
652
+ skip_over_scopes <
653
+ exactly < '(' >,
654
+ exactly < ')' >
655
+ >
656
+ >
657
+ >(src);
658
+ }
659
+
620
660
  const char* ie_keyword_arg(const char* src) {
621
- return sequence<
622
- alternatives< variable, identifier_schema, identifier >,
661
+ return sequence <
662
+ ie_keyword_arg_property,
623
663
  optional_css_whitespace,
624
664
  exactly<'='>,
625
665
  optional_css_whitespace,
626
- alternatives< variable, identifier_schema, identifier, quoted_string, number, hexa >
666
+ ie_keyword_arg_value
627
667
  >(src);
628
668
  }
629
669
 
@@ -729,5 +769,16 @@ namespace Sass {
729
769
  alternatives< exactly<';'>, exactly<'}'> >
730
770
  >(src);
731
771
  }
772
+
773
+ const char* parenthese_scope(const char* src) {
774
+ return sequence <
775
+ exactly < '(' >,
776
+ skip_over_scopes <
777
+ exactly < '(' >,
778
+ exactly < ')' >
779
+ >
780
+ >(src);
781
+ }
782
+
732
783
  }
733
784
  }
@@ -58,7 +58,7 @@ namespace Sass {
58
58
  // recursive skip stuff delimited by start/stop
59
59
  // first start/opener must be consumed already!
60
60
  template<prelexer start, prelexer stop>
61
- const char* skip_over_scopes(const char* src, const char* end = 0) {
61
+ const char* skip_over_scopes(const char* src, const char* end) {
62
62
 
63
63
  size_t level = 0;
64
64
  bool in_squote = false;
@@ -85,8 +85,9 @@ namespace Sass {
85
85
  }
86
86
 
87
87
  // find another opener inside?
88
- else if (start(src)) {
88
+ else if (const char* pos = start(src)) {
89
89
  ++ level; // increase counter
90
+ src = pos - 1; // advance position
90
91
  }
91
92
 
92
93
  // look for the closer (maybe final, maybe not)
@@ -96,6 +97,8 @@ namespace Sass {
96
97
  // return position at end of stop
97
98
  // delimiter may be multiple chars
98
99
  else return final;
100
+ // advance position
101
+ src = final - 1;
99
102
  }
100
103
 
101
104
  // next
@@ -105,6 +108,19 @@ namespace Sass {
105
108
  return 0;
106
109
  }
107
110
 
111
+ // skip to a skip delimited by parentheses
112
+ // uses smart `skip_over_scopes` internally
113
+ const char* parenthese_scope(const char* src);
114
+
115
+ // skip to delimiter (mx) inside given range
116
+ // this will savely skip over all quoted strings
117
+ // recursive skip stuff delimited by start/stop
118
+ // first start/opener must be consumed already!
119
+ template<prelexer start, prelexer stop>
120
+ const char* skip_over_scopes(const char* src) {
121
+ return skip_over_scopes<start, stop>(src, 0);
122
+ }
123
+
108
124
  // Match a sequence of characters delimited by the supplied chars.
109
125
  template <prelexer start, prelexer stop>
110
126
  const char* recursive_scopes(const char* src) {
@@ -296,6 +312,8 @@ namespace Sass {
296
312
  const char* ie_expression(const char* src);
297
313
  const char* ie_property(const char* src);
298
314
  const char* ie_keyword_arg(const char* src);
315
+ const char* ie_keyword_arg_value(const char* src);
316
+ const char* ie_keyword_arg_property(const char* src);
299
317
 
300
318
  // match urls
301
319
  const char* url(const char* src);
@@ -111,7 +111,7 @@ extern "C" {
111
111
  // Getters and setters for Sass_String
112
112
  const char* ADDCALL sass_string_get_value(const union Sass_Value* v) { return v->string.value; }
113
113
  void ADDCALL sass_string_set_value(union Sass_Value* v, char* value) { v->string.value = value; }
114
- const bool ADDCALL sass_string_is_quoted(const union Sass_Value* v) { return v->string.quoted; }
114
+ bool ADDCALL sass_string_is_quoted(const union Sass_Value* v) { return v->string.quoted; }
115
115
  void ADDCALL sass_string_set_quoted(union Sass_Value* v, bool quoted) { v->string.quoted = quoted; }
116
116
 
117
117
  // Getters and setters for Sass_Boolean
@@ -57,7 +57,7 @@ ADDAPI void ADDCALL sass_number_set_unit (union Sass_Value* v, char* unit);
57
57
  // Getters and setters for Sass_String
58
58
  ADDAPI const char* ADDCALL sass_string_get_value (const union Sass_Value* v);
59
59
  ADDAPI void ADDCALL sass_string_set_value (union Sass_Value* v, char* value);
60
- ADDAPI const bool ADDCALL sass_string_is_quoted(const union Sass_Value* v);
60
+ ADDAPI bool ADDCALL sass_string_is_quoted(const union Sass_Value* v);
61
61
  ADDAPI void ADDCALL sass_string_set_quoted(union Sass_Value* v, bool quoted);
62
62
 
63
63
  // Getters and setters for Sass_Boolean
@@ -11,15 +11,15 @@
11
11
  namespace Sass {
12
12
  using namespace std;
13
13
 
14
- To_String::To_String(Context* ctx)
15
- : ctx(ctx) { }
14
+ To_String::To_String(Context* ctx, bool in_declaration)
15
+ : ctx(ctx), in_declaration(in_declaration) { }
16
16
  To_String::~To_String() { }
17
17
 
18
18
  inline string To_String::fallback_impl(AST_Node* n)
19
19
  {
20
20
  Emitter emitter(ctx);
21
21
  Inspect i(emitter);
22
- i.in_declaration_list = true;
22
+ i.in_declaration = in_declaration;
23
23
  n->perform(&i);
24
24
  return i.get_buffer();
25
25
  }
@@ -18,9 +18,10 @@ namespace Sass {
18
18
  string fallback_impl(AST_Node* n);
19
19
 
20
20
  Context* ctx;
21
+ bool in_declaration;
21
22
 
22
23
  public:
23
- To_String(Context* ctx = 0);
24
+ To_String(Context* ctx = 0, bool in_declaration = true);
24
25
  virtual ~To_String();
25
26
 
26
27
  string operator()(Null* n);
@@ -1,55 +1,155 @@
1
+ #include <stdexcept>
1
2
  #include "units.hpp"
2
3
 
3
- #define PI 3.14159265358979323846
4
-
5
4
  namespace Sass {
6
5
 
7
- double conversion_factors[10][10] = {
8
- /* in cm pc mm pt px deg grad rad turn */
9
- /* in */ { 1, 2.54, 6, 25.4, 72, 96, 1, 1, 1, 1 },
10
- /* cm */ { 1.0/2.54, 1, 6.0/2.54, 10, 72.0/2.54, 96.0/2.54, 1, 1, 1, 1 },
11
- /* pc */ { 1.0/6.0, 2.54/6.0, 1, 25.4/6.0, 72.0/6.0, 96.0/6.0, 1, 1, 1, 1 },
12
- /* mm */ { 1.0/25.4, 1.0/10.0, 6.0/25.4, 1, 72.0/25.4, 96.0/25.4, 1, 1, 1, 1 },
13
- /* pt */ { 1.0/72.0, 2.54/72.0, 6.0/72.0, 25.4/72.0, 1, 96.0/72.0, 1, 1, 1, 1 },
14
- /* px */ { 1.0/96.0, 2.54/96.0, 6.0/96.0, 25.4/96.0, 72.0/96.0, 1, 1, 1, 1, 1 },
15
- /* deg */ { 1 , 1 , 1 , 1 , 1 , 1, 1, 40.0/36.0, PI/180.0, 1.0/360.0 },
16
- /* grad */ { 1 , 1 , 1 , 1 , 1 , 1, 36.0/40.0, 1, PI/200.0, 1.0/400.0 },
17
- /* rad */ { 1 , 1 , 1 , 1 , 1 , 1, 180.0/PI, 200.0/PI, 1, PI/2.0 },
18
- /* turn */ { 1 , 1 , 1 , 1 , 1 , 1, 360.0/1.0, 400.0/1.0, 2.0*PI, 1 }
6
+ /* the conversion matrix can be readed the following way */
7
+ /* if you go down, the factor is for the numerator (multiply) */
8
+ /* if you go right, the factor is for the denominator (divide) */
9
+ /* and yes, we actually use both, not sure why, but why not!? */
10
+
11
+ const double size_conversion_factors[6][6] =
12
+ {
13
+ /* in cm pc mm pt px */
14
+ /* in */ { 1, 2.54, 6, 25.4, 72, 96, },
15
+ /* cm */ { 1.0/2.54, 1, 6.0/2.54, 10, 72.0/2.54, 96.0/2.54 },
16
+ /* pc */ { 1.0/6.0, 2.54/6.0, 1, 25.4/6.0, 72.0/6.0, 96.0/6.0 },
17
+ /* mm */ { 1.0/25.4, 1.0/10.0, 6.0/25.4, 1, 72.0/25.4, 96.0/25.4 },
18
+ /* pt */ { 1.0/72.0, 2.54/72.0, 6.0/72.0, 25.4/72.0, 1, 96.0/72.0 },
19
+ /* px */ { 1.0/96.0, 2.54/96.0, 6.0/96.0, 25.4/96.0, 72.0/96.0, 1, }
19
20
  };
20
21
 
21
- Unit string_to_unit(const string& s)
22
+ const double angle_conversion_factors[4][4] =
22
23
  {
23
- if (s == "in") return IN;
24
- else if (s == "cm") return CM;
24
+ /* deg grad rad turn */
25
+ /* deg */ { 1, 40.0/36.0, PI/180.0, 1.0/360.0 },
26
+ /* grad */ { 36.0/40.0, 1, PI/200.0, 1.0/400.0 },
27
+ /* rad */ { 180.0/PI, 200.0/PI, 1, 0.5/PI },
28
+ /* turn */ { 360.0, 400.0, 2.0*PI, 1 }
29
+ };
30
+
31
+ const double time_conversion_factors[2][2] =
32
+ {
33
+ /* s ms */
34
+ /* s */ { 1, 1000.0 },
35
+ /* ms */ { 1/1000.0, 1 }
36
+ };
37
+ const double frequency_conversion_factors[2][2] =
38
+ {
39
+ /* Hz kHz */
40
+ /* Hz */ { 1, 1/1000.0 },
41
+ /* kHz */ { 1000.0, 1 }
42
+ };
43
+ const double resolution_conversion_factors[3][3] =
44
+ {
45
+ /* dpi dpcm dppx */
46
+ /* dpi */ { 1, 2.54, 96 },
47
+ /* dpcm */ { 1/2.54, 1, 96/2.54 },
48
+ /* dppx */ { 1/96.0, 2.54/96, 1 }
49
+ };
50
+
51
+ SassUnitType get_unit_type(SassUnit unit)
52
+ {
53
+ switch (unit & 0xFF00)
54
+ {
55
+ case SIZE: return SIZE; break;
56
+ case ANGLE: return ANGLE; break;
57
+ case TIME: return TIME; break;
58
+ case FREQUENCY: return FREQUENCY; break;
59
+ case RESOLUTION: return RESOLUTION; break;
60
+ default: return INCOMMENSURABLE; break;
61
+ }
62
+ };
63
+
64
+ SassUnit string_to_unit(const string& s)
65
+ {
66
+ // size units
67
+ if (s == "px") return PX;
68
+ else if (s == "pt") return PT;
25
69
  else if (s == "pc") return PC;
26
70
  else if (s == "mm") return MM;
27
- else if (s == "pt") return PT;
28
- else if (s == "px") return PX;
71
+ else if (s == "cm") return CM;
72
+ else if (s == "in") return IN;
73
+ // angle units
29
74
  else if (s == "deg") return DEG;
30
75
  else if (s == "grad") return GRAD;
31
76
  else if (s == "rad") return RAD;
32
77
  else if (s == "turn") return TURN;
33
- else return INCOMMENSURABLE;
78
+ // time units
79
+ else if (s == "s") return SEC;
80
+ else if (s == "ms") return MSEC;
81
+ // frequency units
82
+ else if (s == "Hz") return HERTZ;
83
+ else if (s == "kHz") return KHERTZ;
84
+ // resolutions units
85
+ else if (s == "dpi") return DPI;
86
+ else if (s == "dpcm") return DPCM;
87
+ else if (s == "dppx") return DPPX;
88
+ // for unknown units
89
+ else return UNKNOWN;
34
90
  }
35
91
 
36
- double conversion_factor(const string& s1, const string& s2)
92
+ const char* unit_to_string(SassUnit unit)
37
93
  {
38
- Unit u1 = string_to_unit(s1);
39
- Unit u2 = string_to_unit(s2);
40
- double factor;
41
- if (u1 == INCOMMENSURABLE || u2 == INCOMMENSURABLE)
42
- factor = 0;
43
- else
44
- factor = conversion_factors[u1][u2];
45
- return factor;
94
+ switch (unit) {
95
+ // size units
96
+ case PX: return "px"; break;
97
+ case PT: return "pt"; break;
98
+ case PC: return "pc"; break;
99
+ case MM: return "mm"; break;
100
+ case CM: return "cm"; break;
101
+ case IN: return "in"; break;
102
+ // angle units
103
+ case DEG: return "deg"; break;
104
+ case GRAD: return "grad"; break;
105
+ case RAD: return "rad"; break;
106
+ case TURN: return "turn"; break;
107
+ // time units
108
+ case SEC: return "s"; break;
109
+ case MSEC: return "ms"; break;
110
+ // frequency units
111
+ case HERTZ: return "Hz"; break;
112
+ case KHERTZ: return "kHz"; break;
113
+ // resolutions units
114
+ case DPI: return "dpi"; break;
115
+ case DPCM: return "dpcm"; break;
116
+ case DPPX: return "dppx"; break;
117
+ // for unknown units
118
+ default: return ""; break;;
119
+ }
46
120
  }
47
121
 
48
- /* not used anymore - remove?
49
- double convert(double n, const string& from, const string& to)
122
+ // throws incompatibleUnits exceptions
123
+ double conversion_factor(const string& s1, const string& s2)
50
124
  {
51
- double factor = conversion_factor(from, to);
52
- return factor ? factor * n : n;
53
- } */
125
+ // assert for same units
126
+ if (s1 == s2) return 1;
127
+ // get unit enum from string
128
+ SassUnit u1 = string_to_unit(s1);
129
+ SassUnit u2 = string_to_unit(s2);
130
+ // query unit group types
131
+ SassUnitType t1 = get_unit_type(u1);
132
+ SassUnitType t2 = get_unit_type(u2);
133
+ // get absolute offset
134
+ // used for array acces
135
+ size_t i1 = u1 - t1;
136
+ size_t i2 = u2 - t2;
137
+ // error if units are not of the same group
138
+ if (t1 != t2) throw incompatibleUnits(u1, u2);
139
+ // only process known units
140
+ if (u1 != UNKNOWN && u2 != UNKNOWN) {
141
+ switch (t1) {
142
+ case SIZE: return size_conversion_factors[i1][i2]; break;
143
+ case ANGLE: return angle_conversion_factors[i1][i2]; break;
144
+ case TIME: return time_conversion_factors[i1][i2]; break;
145
+ case FREQUENCY: return frequency_conversion_factors[i1][i2]; break;
146
+ case RESOLUTION: return resolution_conversion_factors[i1][i2]; break;
147
+ // ToDo: should we throw error here?
148
+ case INCOMMENSURABLE: return 0; break;
149
+ }
150
+ }
151
+ // fallback
152
+ return 1;
153
+ }
54
154
 
55
155
  }
@@ -1,15 +1,89 @@
1
1
  #ifndef SASS_UNITS_H
2
2
  #define SASS_UNITS_H
3
3
 
4
+ #include <cmath>
4
5
  #include <string>
6
+ #include <sstream>
5
7
 
6
8
  namespace Sass {
7
9
  using namespace std;
8
- enum Unit { IN, CM, PC, MM, PT, PX, DEG, GRAD, RAD, TURN, INCOMMENSURABLE };
9
- extern double conversion_factors[10][10];
10
- Unit string_to_unit(const string&);
10
+
11
+ const double PI = acos(-1);
12
+
13
+ enum SassUnitType {
14
+ SIZE = 0x000,
15
+ ANGLE = 0x100,
16
+ TIME = 0x200,
17
+ FREQUENCY = 0x300,
18
+ RESOLUTION = 0x400,
19
+ INCOMMENSURABLE = 0x500
20
+ };
21
+
22
+ enum SassUnit {
23
+
24
+ // size units
25
+ IN = SIZE,
26
+ CM,
27
+ PC,
28
+ MM,
29
+ PT,
30
+ PX,
31
+
32
+ // angle units
33
+ DEG = ANGLE,
34
+ GRAD,
35
+ RAD,
36
+ TURN,
37
+
38
+ // time units
39
+ SEC = TIME,
40
+ MSEC,
41
+
42
+ // frequency units
43
+ HERTZ = FREQUENCY,
44
+ KHERTZ,
45
+
46
+ // resolutions units
47
+ DPI = RESOLUTION,
48
+ DPCM,
49
+ DPPX,
50
+
51
+ // for unknown units
52
+ UNKNOWN = INCOMMENSURABLE
53
+
54
+ };
55
+
56
+ extern const double size_conversion_factors[6][6];
57
+ extern const double angle_conversion_factors[4][4];
58
+ extern const double time_conversion_factors[2][2];
59
+ extern const double frequency_conversion_factors[2][2];
60
+ extern const double resolution_conversion_factors[3][3];
61
+
62
+ SassUnit string_to_unit(const string&);
63
+ const char* unit_to_string(SassUnit unit);
64
+ SassUnitType get_unit_type(SassUnit unit);
65
+ // throws incompatibleUnits exceptions
11
66
  double conversion_factor(const string&, const string&);
12
- // double convert(double, const string&, const string&);
67
+
68
+ class incompatibleUnits: public exception
69
+ {
70
+ public:
71
+ const char* msg;
72
+ incompatibleUnits(SassUnit a, SassUnit b)
73
+ : exception()
74
+ {
75
+ stringstream ss;
76
+ ss << "Incompatible units: ";
77
+ ss << "'" << unit_to_string(a) << "' and ";
78
+ ss << "'" << unit_to_string(b) << "'";
79
+ msg = ss.str().c_str();
80
+ };
81
+ virtual const char* what() const throw()
82
+ {
83
+ return msg;
84
+ }
85
+ };
86
+
13
87
  }
14
88
 
15
89
  #endif