sassc 1.1.2 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/libsass/ast.cpp +124 -43
- data/ext/libsass/ast.hpp +15 -7
- data/ext/libsass/bind.cpp +57 -10
- data/ext/libsass/context.cpp +9 -7
- data/ext/libsass/contextualize.cpp +7 -0
- data/ext/libsass/contextualize_eval.cpp +1 -1
- data/ext/libsass/debugger.hpp +27 -70
- data/ext/libsass/emitter.cpp +5 -2
- data/ext/libsass/emitter.hpp +7 -1
- data/ext/libsass/eval.cpp +27 -13
- data/ext/libsass/expand.cpp +2 -2
- data/ext/libsass/functions.cpp +34 -9
- data/ext/libsass/functions.hpp +2 -0
- data/ext/libsass/inspect.cpp +111 -39
- data/ext/libsass/lexer.cpp +8 -8
- data/ext/libsass/lexer.hpp +8 -8
- data/ext/libsass/output.cpp +13 -5
- data/ext/libsass/parser.cpp +185 -46
- data/ext/libsass/parser.hpp +4 -0
- data/ext/libsass/prelexer.cpp +58 -7
- data/ext/libsass/prelexer.hpp +20 -2
- data/ext/libsass/sass_values.cpp +1 -1
- data/ext/libsass/sass_values.h +1 -1
- data/ext/libsass/to_string.cpp +3 -3
- data/ext/libsass/to_string.hpp +2 -1
- data/ext/libsass/units.cpp +134 -34
- data/ext/libsass/units.hpp +78 -4
- data/ext/libsass/util.cpp +8 -10
- data/ext/libsass/util.hpp +1 -1
- data/lib/sassc/engine.rb +7 -3
- data/lib/sassc/version.rb +1 -1
- data/test/native_test.rb +1 -1
- data/test/output_style_test.rb +7 -0
- metadata +2 -2
data/ext/libsass/parser.hpp
CHANGED
@@ -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
|
|
data/ext/libsass/prelexer.cpp
CHANGED
@@ -34,7 +34,12 @@ namespace Sass {
|
|
34
34
|
{
|
35
35
|
return sequence<
|
36
36
|
zero_plus < space >,
|
37
|
-
delimited_by<
|
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
|
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
|
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>,
|
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
|
-
|
661
|
+
return sequence <
|
662
|
+
ie_keyword_arg_property,
|
623
663
|
optional_css_whitespace,
|
624
664
|
exactly<'='>,
|
625
665
|
optional_css_whitespace,
|
626
|
-
|
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
|
}
|
data/ext/libsass/prelexer.hpp
CHANGED
@@ -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
|
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);
|
data/ext/libsass/sass_values.cpp
CHANGED
@@ -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
|
-
|
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
|
data/ext/libsass/sass_values.h
CHANGED
@@ -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
|
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
|
data/ext/libsass/to_string.cpp
CHANGED
@@ -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.
|
22
|
+
i.in_declaration = in_declaration;
|
23
23
|
n->perform(&i);
|
24
24
|
return i.get_buffer();
|
25
25
|
}
|
data/ext/libsass/to_string.hpp
CHANGED
@@ -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);
|
data/ext/libsass/units.cpp
CHANGED
@@ -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
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
/*
|
16
|
-
/*
|
17
|
-
/*
|
18
|
-
/*
|
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
|
-
|
22
|
+
const double angle_conversion_factors[4][4] =
|
22
23
|
{
|
23
|
-
|
24
|
-
|
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 == "
|
28
|
-
else if (s == "
|
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
|
-
|
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
|
-
|
92
|
+
const char* unit_to_string(SassUnit unit)
|
37
93
|
{
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
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
|
-
|
49
|
-
double
|
122
|
+
// throws incompatibleUnits exceptions
|
123
|
+
double conversion_factor(const string& s1, const string& s2)
|
50
124
|
{
|
51
|
-
|
52
|
-
|
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
|
}
|
data/ext/libsass/units.hpp
CHANGED
@@ -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
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
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
|