sassc 1.1.2 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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