sassc 1.7.1 → 1.8.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -1
  3. data/ext/libsass/.gitignore +10 -6
  4. data/ext/libsass/.travis.yml +4 -1
  5. data/ext/libsass/GNUmakefile.am +88 -0
  6. data/ext/libsass/Makefile +157 -76
  7. data/ext/libsass/Makefile.conf +47 -0
  8. data/ext/libsass/Readme.md +13 -14
  9. data/ext/libsass/appveyor.yml +25 -41
  10. data/ext/libsass/configure.ac +20 -7
  11. data/ext/libsass/contrib/plugin.cpp +1 -1
  12. data/ext/libsass/include/sass.h +15 -0
  13. data/ext/libsass/{sass.h → include/sass/base.h} +17 -9
  14. data/ext/libsass/{sass_context.h → include/sass/context.h} +3 -1
  15. data/ext/libsass/{sass_functions.h → include/sass/functions.h} +4 -4
  16. data/ext/libsass/{sass_interface.h → include/sass/interface.h} +5 -2
  17. data/ext/libsass/{sass_values.h → include/sass/values.h} +15 -1
  18. data/ext/libsass/{sass_version.h → include/sass/version.h} +0 -0
  19. data/ext/libsass/{sass_version.h.in → include/sass/version.h.in} +0 -0
  20. data/ext/libsass/{sass2scss.h → include/sass2scss.h} +6 -7
  21. data/ext/libsass/m4/m4-ax_cxx_compile_stdcxx_11.m4 +167 -0
  22. data/ext/libsass/script/ci-build-libsass +67 -23
  23. data/ext/libsass/src/GNUmakefile.am +54 -0
  24. data/ext/libsass/src/ast.cpp +2029 -0
  25. data/ext/libsass/{ast.hpp → src/ast.hpp} +832 -660
  26. data/ext/libsass/src/ast_def_macros.hpp +47 -0
  27. data/ext/libsass/src/ast_factory.hpp +93 -0
  28. data/ext/libsass/{ast_fwd_decl.hpp → src/ast_fwd_decl.hpp} +9 -4
  29. data/ext/libsass/{b64 → src/b64}/cencode.h +1 -1
  30. data/ext/libsass/{b64 → src/b64}/encode.h +0 -0
  31. data/ext/libsass/{backtrace.hpp → src/backtrace.hpp} +9 -10
  32. data/ext/libsass/{base64vlq.cpp → src/base64vlq.cpp} +2 -2
  33. data/ext/libsass/{base64vlq.hpp → src/base64vlq.hpp} +1 -2
  34. data/ext/libsass/{bind.cpp → src/bind.cpp} +96 -59
  35. data/ext/libsass/{bind.hpp → src/bind.hpp} +1 -1
  36. data/ext/libsass/src/c99func.c +54 -0
  37. data/ext/libsass/{cencode.c → src/cencode.c} +5 -5
  38. data/ext/libsass/src/color_maps.cpp +643 -0
  39. data/ext/libsass/src/color_maps.hpp +333 -0
  40. data/ext/libsass/{constants.cpp → src/constants.cpp} +10 -1
  41. data/ext/libsass/{constants.hpp → src/constants.hpp} +7 -0
  42. data/ext/libsass/{context.cpp → src/context.cpp} +152 -122
  43. data/ext/libsass/src/context.hpp +150 -0
  44. data/ext/libsass/{cssize.cpp → src/cssize.cpp} +123 -109
  45. data/ext/libsass/{cssize.hpp → src/cssize.hpp} +9 -13
  46. data/ext/libsass/{debug.hpp → src/debug.hpp} +9 -9
  47. data/ext/libsass/src/debugger.hpp +683 -0
  48. data/ext/libsass/{emitter.cpp → src/emitter.cpp} +13 -13
  49. data/ext/libsass/{emitter.hpp → src/emitter.hpp} +10 -11
  50. data/ext/libsass/src/environment.cpp +184 -0
  51. data/ext/libsass/src/environment.hpp +92 -0
  52. data/ext/libsass/src/error_handling.cpp +46 -0
  53. data/ext/libsass/src/error_handling.hpp +34 -0
  54. data/ext/libsass/src/eval.cpp +1462 -0
  55. data/ext/libsass/src/eval.hpp +107 -0
  56. data/ext/libsass/src/expand.cpp +653 -0
  57. data/ext/libsass/{expand.hpp → src/expand.hpp} +17 -16
  58. data/ext/libsass/{extend.cpp → src/extend.cpp} +198 -139
  59. data/ext/libsass/{extend.hpp → src/extend.hpp} +7 -8
  60. data/ext/libsass/{file.cpp → src/file.cpp} +103 -57
  61. data/ext/libsass/{file.hpp → src/file.hpp} +23 -14
  62. data/ext/libsass/{functions.cpp → src/functions.cpp} +642 -333
  63. data/ext/libsass/{functions.hpp → src/functions.hpp} +17 -4
  64. data/ext/libsass/{inspect.cpp → src/inspect.cpp} +147 -260
  65. data/ext/libsass/{inspect.hpp → src/inspect.hpp} +7 -7
  66. data/ext/libsass/{json.cpp → src/json.cpp} +33 -43
  67. data/ext/libsass/{json.hpp → src/json.hpp} +1 -1
  68. data/ext/libsass/{kwd_arg_macros.hpp → src/kwd_arg_macros.hpp} +0 -0
  69. data/ext/libsass/{lexer.cpp → src/lexer.cpp} +28 -0
  70. data/ext/libsass/{lexer.hpp → src/lexer.hpp} +25 -10
  71. data/ext/libsass/{listize.cpp → src/listize.cpp} +17 -13
  72. data/ext/libsass/{listize.hpp → src/listize.hpp} +0 -2
  73. data/ext/libsass/{mapping.hpp → src/mapping.hpp} +0 -0
  74. data/ext/libsass/src/memory_manager.cpp +76 -0
  75. data/ext/libsass/src/memory_manager.hpp +48 -0
  76. data/ext/libsass/{node.cpp → src/node.cpp} +89 -18
  77. data/ext/libsass/{node.hpp → src/node.hpp} +5 -6
  78. data/ext/libsass/{operation.hpp → src/operation.hpp} +18 -12
  79. data/ext/libsass/{output.cpp → src/output.cpp} +47 -55
  80. data/ext/libsass/{output.hpp → src/output.hpp} +5 -4
  81. data/ext/libsass/src/parser.cpp +2529 -0
  82. data/ext/libsass/{parser.hpp → src/parser.hpp} +84 -60
  83. data/ext/libsass/{paths.hpp → src/paths.hpp} +10 -13
  84. data/ext/libsass/{plugins.cpp → src/plugins.cpp} +14 -17
  85. data/ext/libsass/{plugins.hpp → src/plugins.hpp} +10 -11
  86. data/ext/libsass/{position.cpp → src/position.cpp} +5 -6
  87. data/ext/libsass/{position.hpp → src/position.hpp} +19 -22
  88. data/ext/libsass/{prelexer.cpp → src/prelexer.cpp} +401 -53
  89. data/ext/libsass/{prelexer.hpp → src/prelexer.hpp} +50 -10
  90. data/ext/libsass/{remove_placeholders.cpp → src/remove_placeholders.cpp} +12 -16
  91. data/ext/libsass/{remove_placeholders.hpp → src/remove_placeholders.hpp} +1 -7
  92. data/ext/libsass/{sass.cpp → src/sass.cpp} +3 -5
  93. data/ext/libsass/{sass2scss.cpp → src/sass2scss.cpp} +51 -46
  94. data/ext/libsass/{sass_context.cpp → src/sass_context.cpp} +114 -112
  95. data/ext/libsass/{sass_functions.cpp → src/sass_functions.cpp} +11 -18
  96. data/ext/libsass/{sass_interface.cpp → src/sass_interface.cpp} +44 -81
  97. data/ext/libsass/{sass_util.cpp → src/sass_util.cpp} +26 -8
  98. data/ext/libsass/{sass_util.hpp → src/sass_util.hpp} +14 -18
  99. data/ext/libsass/{sass_values.cpp → src/sass_values.cpp} +91 -20
  100. data/ext/libsass/{source_map.cpp → src/source_map.cpp} +13 -13
  101. data/ext/libsass/{source_map.hpp → src/source_map.hpp} +9 -9
  102. data/ext/libsass/{subset_map.hpp → src/subset_map.hpp} +29 -31
  103. data/ext/libsass/{support → src/support}/libsass.pc.in +0 -0
  104. data/ext/libsass/src/to_c.cpp +73 -0
  105. data/ext/libsass/src/to_c.hpp +41 -0
  106. data/ext/libsass/src/to_string.cpp +47 -0
  107. data/ext/libsass/{to_string.hpp → src/to_string.hpp} +9 -7
  108. data/ext/libsass/src/to_value.cpp +109 -0
  109. data/ext/libsass/src/to_value.hpp +50 -0
  110. data/ext/libsass/{units.cpp → src/units.cpp} +56 -51
  111. data/ext/libsass/{units.hpp → src/units.hpp} +8 -9
  112. data/ext/libsass/{utf8.h → src/utf8.h} +0 -0
  113. data/ext/libsass/{utf8 → src/utf8}/checked.h +0 -0
  114. data/ext/libsass/{utf8 → src/utf8}/core.h +12 -12
  115. data/ext/libsass/{utf8 → src/utf8}/unchecked.h +0 -0
  116. data/ext/libsass/{utf8_string.cpp → src/utf8_string.cpp} +0 -0
  117. data/ext/libsass/{utf8_string.hpp → src/utf8_string.hpp} +6 -6
  118. data/ext/libsass/{util.cpp → src/util.cpp} +144 -86
  119. data/ext/libsass/src/util.hpp +59 -0
  120. data/ext/libsass/src/values.cpp +137 -0
  121. data/ext/libsass/src/values.hpp +12 -0
  122. data/ext/libsass/test/test_node.cpp +33 -33
  123. data/ext/libsass/test/test_paths.cpp +5 -6
  124. data/ext/libsass/test/test_selector_difference.cpp +4 -5
  125. data/ext/libsass/test/test_specificity.cpp +4 -5
  126. data/ext/libsass/test/test_subset_map.cpp +91 -91
  127. data/ext/libsass/test/test_superselector.cpp +11 -11
  128. data/ext/libsass/test/test_unification.cpp +4 -4
  129. data/ext/libsass/win/libsass.targets +101 -0
  130. data/ext/libsass/win/libsass.vcxproj +45 -127
  131. data/ext/libsass/win/libsass.vcxproj.filters +303 -0
  132. data/lib/sassc/import_handler.rb +1 -1
  133. data/lib/sassc/native/native_functions_api.rb +3 -3
  134. data/lib/sassc/version.rb +1 -1
  135. data/test/custom_importer_test.rb +1 -4
  136. data/test/functions_test.rb +3 -2
  137. data/test/native_test.rb +4 -3
  138. metadata +117 -110
  139. data/ext/libsass/Makefile.am +0 -146
  140. data/ext/libsass/ast.cpp +0 -945
  141. data/ext/libsass/ast_def_macros.hpp +0 -21
  142. data/ext/libsass/ast_factory.hpp +0 -92
  143. data/ext/libsass/color_names.hpp +0 -327
  144. data/ext/libsass/context.hpp +0 -157
  145. data/ext/libsass/contextualize.cpp +0 -148
  146. data/ext/libsass/contextualize.hpp +0 -46
  147. data/ext/libsass/contextualize_eval.cpp +0 -93
  148. data/ext/libsass/contextualize_eval.hpp +0 -44
  149. data/ext/libsass/debugger.hpp +0 -558
  150. data/ext/libsass/environment.hpp +0 -163
  151. data/ext/libsass/error_handling.cpp +0 -35
  152. data/ext/libsass/error_handling.hpp +0 -32
  153. data/ext/libsass/eval.cpp +0 -1392
  154. data/ext/libsass/eval.hpp +0 -88
  155. data/ext/libsass/expand.cpp +0 -575
  156. data/ext/libsass/memory_manager.hpp +0 -57
  157. data/ext/libsass/parser.cpp +0 -2403
  158. data/ext/libsass/posix/getopt.c +0 -562
  159. data/ext/libsass/posix/getopt.h +0 -95
  160. data/ext/libsass/to_c.cpp +0 -61
  161. data/ext/libsass/to_c.hpp +0 -44
  162. data/ext/libsass/to_string.cpp +0 -34
  163. data/ext/libsass/util.hpp +0 -54
  164. data/ext/libsass/win/libsass.filters +0 -312
@@ -1,11 +1,9 @@
1
1
  #ifndef SASS_FUNCTIONS_H
2
2
  #define SASS_FUNCTIONS_H
3
3
 
4
- #include <string>
5
-
6
4
  #include "position.hpp"
7
5
  #include "environment.hpp"
8
- #include "sass_functions.h"
6
+ #include "sass/functions.h"
9
7
 
10
8
  #define BUILT_IN(name) Expression*\
11
9
  name(Env& env, Env& d_env, Context& ctx, Signature sig, ParserState pstate, Backtrace* backtrace)
@@ -23,6 +21,8 @@ namespace Sass {
23
21
  Definition* make_native_function(Signature, Native_Function, Context& ctx);
24
22
  Definition* make_c_function(Sass_Function_Entry c_func, Context& ctx);
25
23
 
24
+ std::string function_name(Signature);
25
+
26
26
  namespace Functions {
27
27
 
28
28
  extern Signature rgb_sig;
@@ -101,7 +101,14 @@ namespace Sass {
101
101
  extern Signature keywords_sig;
102
102
  extern Signature set_nth_sig;
103
103
  extern Signature unique_id_sig;
104
+ extern Signature selector_nest_sig;
105
+ extern Signature selector_append_sig;
106
+ extern Signature selector_extend_sig;
107
+ extern Signature selector_replace_sig;
108
+ extern Signature selector_unify_sig;
104
109
  extern Signature is_superselector_sig;
110
+ extern Signature simple_selectors_sig;
111
+ extern Signature selector_parse_sig;
105
112
 
106
113
  BUILT_IN(rgb);
107
114
  BUILT_IN(rgba_4);
@@ -176,8 +183,14 @@ namespace Sass {
176
183
  BUILT_IN(keywords);
177
184
  BUILT_IN(set_nth);
178
185
  BUILT_IN(unique_id);
186
+ BUILT_IN(selector_nest);
187
+ BUILT_IN(selector_append);
188
+ BUILT_IN(selector_extend);
189
+ BUILT_IN(selector_replace);
190
+ BUILT_IN(selector_unify);
179
191
  BUILT_IN(is_superselector);
180
-
192
+ BUILT_IN(simple_selectors);
193
+ BUILT_IN(selector_parse);
181
194
  }
182
195
  }
183
196
 
@@ -8,10 +8,11 @@
8
8
  #include "ast.hpp"
9
9
  #include "inspect.hpp"
10
10
  #include "context.hpp"
11
+ #include "listize.hpp"
12
+ #include "color_maps.hpp"
11
13
  #include "utf8/checked.h"
12
14
 
13
15
  namespace Sass {
14
- using namespace std;
15
16
 
16
17
  Inspect::Inspect(Emitter emi)
17
18
  : Emitter(emi)
@@ -76,12 +77,12 @@ namespace Sass {
76
77
  media_block->block()->perform(this);
77
78
  }
78
79
 
79
- void Inspect::operator()(Feature_Block* feature_block)
80
+ void Inspect::operator()(Supports_Block* feature_block)
80
81
  {
81
82
  append_indentation();
82
83
  append_token("@supports", feature_block);
83
84
  append_mandatory_space();
84
- feature_block->feature_queries()->perform(this);
85
+ feature_block->condition()->perform(this);
85
86
  feature_block->block()->perform(this);
86
87
  }
87
88
 
@@ -105,6 +106,10 @@ namespace Sass {
105
106
  at_rule->selector()->perform(this);
106
107
  in_wrapped = was_wrapped;
107
108
  }
109
+ if (at_rule->value()) {
110
+ append_mandatory_space();
111
+ at_rule->value()->perform(this);
112
+ }
108
113
  if (at_rule->block()) {
109
114
  at_rule->block()->perform(this);
110
115
  }
@@ -123,7 +128,14 @@ namespace Sass {
123
128
  append_indentation();
124
129
  dec->property()->perform(this);
125
130
  append_colon_separator();
126
- dec->value()->perform(this);
131
+
132
+ if (dec->value()->concrete_type() == Expression::SELECTOR) {
133
+ Listize listize(*ctx);
134
+ dec->value()->perform(&listize)->perform(this);
135
+ } else {
136
+ dec->value()->perform(this);
137
+ }
138
+
127
139
  if (dec->is_important()) {
128
140
  append_optional_space();
129
141
  append_string("!important");
@@ -157,6 +169,10 @@ namespace Sass {
157
169
  }
158
170
 
159
171
  import->urls().front()->perform(this);
172
+ if (import->media_queries()) {
173
+ append_mandatory_space();
174
+ import->media_queries()->perform(this);
175
+ }
160
176
  append_delimiter();
161
177
  for (size_t i = 1, S = import->urls().size(); i < S; ++i) {
162
178
  append_mandatory_linefeed();
@@ -168,6 +184,10 @@ namespace Sass {
168
184
  }
169
185
 
170
186
  import->urls()[i]->perform(this);
187
+ if (import->media_queries()) {
188
+ append_mandatory_space();
189
+ import->media_queries()->perform(this);
190
+ }
171
191
  append_delimiter();
172
192
  }
173
193
  }
@@ -222,7 +242,7 @@ namespace Sass {
222
242
  append_token("@if", cond);
223
243
  append_mandatory_space();
224
244
  cond->predicate()->perform(this);
225
- cond->consequent()->perform(this);
245
+ cond->block()->perform(this);
226
246
  if (cond->alternative()) {
227
247
  append_optional_linefeed();
228
248
  append_indentation();
@@ -331,8 +351,6 @@ namespace Sass {
331
351
  bool items_output = false;
332
352
  append_string("(");
333
353
  for (auto key : map->keys()) {
334
- if (key->is_invisible()) continue;
335
- if (map->at(key)->is_invisible()) continue;
336
354
  if (items_output) append_comma_separator();
337
355
  key->perform(this);
338
356
  append_colon_separator();
@@ -344,7 +362,7 @@ namespace Sass {
344
362
 
345
363
  void Inspect::operator()(List* list)
346
364
  {
347
- string sep(list->separator() == List::SPACE ? " " : ",");
365
+ std::string sep(list->separator() == SASS_SPACE ? " " : ",");
348
366
  if (output_style() != COMPRESSED && sep == ",") sep += " ";
349
367
  else if (in_media_block && sep != " ") sep += " "; // verified
350
368
  if (list->empty()) return;
@@ -353,14 +371,14 @@ namespace Sass {
353
371
  bool was_space_array = in_space_array;
354
372
  bool was_comma_array = in_comma_array;
355
373
  if (!in_declaration && (
356
- (list->separator() == List::SPACE && in_space_array) ||
357
- (list->separator() == List::COMMA && in_comma_array)
374
+ (list->separator() == SASS_SPACE && in_space_array) ||
375
+ (list->separator() == SASS_COMMA && in_comma_array)
358
376
  )) {
359
377
  append_string("(");
360
378
  }
361
379
 
362
- if (list->separator() == List::SPACE) in_space_array = true;
363
- else if (list->separator() == List::COMMA) in_comma_array = true;
380
+ if (list->separator() == SASS_SPACE) in_space_array = true;
381
+ else if (list->separator() == SASS_COMMA) in_comma_array = true;
364
382
 
365
383
  for (size_t i = 0, L = list->size(); i < L; ++i) {
366
384
  Expression* list_item = (*list)[i];
@@ -379,8 +397,8 @@ namespace Sass {
379
397
  in_comma_array = was_comma_array;
380
398
  in_space_array = was_space_array;
381
399
  if (!in_declaration && (
382
- (list->separator() == List::SPACE && in_space_array) ||
383
- (list->separator() == List::COMMA && in_comma_array)
400
+ (list->separator() == SASS_SPACE && in_space_array) ||
401
+ (list->separator() == SASS_COMMA && in_comma_array)
384
402
  )) {
385
403
  append_string(")");
386
404
  }
@@ -391,19 +409,19 @@ namespace Sass {
391
409
  {
392
410
  expr->left()->perform(this);
393
411
  switch (expr->type()) {
394
- case Binary_Expression::AND: append_string(" and "); break;
395
- case Binary_Expression::OR: append_string(" or "); break;
396
- case Binary_Expression::EQ: append_string(" == "); break;
397
- case Binary_Expression::NEQ: append_string(" != "); break;
398
- case Binary_Expression::GT: append_string(" > "); break;
399
- case Binary_Expression::GTE: append_string(" >= "); break;
400
- case Binary_Expression::LT: append_string(" < "); break;
401
- case Binary_Expression::LTE: append_string(" <= "); break;
402
- case Binary_Expression::ADD: append_string(" + "); break;
403
- case Binary_Expression::SUB: append_string(" - "); break;
404
- case Binary_Expression::MUL: append_string(" * "); break;
405
- case Binary_Expression::DIV: append_string("/"); break;
406
- case Binary_Expression::MOD: append_string(" % "); break;
412
+ case Sass_OP::AND: append_string(" and "); break;
413
+ case Sass_OP::OR: append_string(" or "); break;
414
+ case Sass_OP::EQ: append_string(" == "); break;
415
+ case Sass_OP::NEQ: append_string(" != "); break;
416
+ case Sass_OP::GT: append_string(" > "); break;
417
+ case Sass_OP::GTE: append_string(" >= "); break;
418
+ case Sass_OP::LT: append_string(" < "); break;
419
+ case Sass_OP::LTE: append_string(" <= "); break;
420
+ case Sass_OP::ADD: append_string(" + "); break;
421
+ case Sass_OP::SUB: append_string(" - "); break;
422
+ case Sass_OP::MUL: append_string(" * "); break;
423
+ case Sass_OP::DIV: append_string(in_media_block ? " / " : "/"); break;
424
+ case Sass_OP::MOD: append_string(" % "); break;
407
425
  default: break; // shouldn't get here
408
426
  }
409
427
  expr->right()->perform(this);
@@ -440,191 +458,35 @@ namespace Sass {
440
458
 
441
459
  void Inspect::operator()(Number* n)
442
460
  {
443
-
444
- string res;
445
-
446
- // init stuff
447
- n->normalize();
448
- int precision = 5;
449
- double value = n->value();
450
- // get option from optional context
451
- if (ctx) precision = ctx->precision;
452
-
453
- // check if the fractional part of the value equals to zero
454
- // neat trick from http://stackoverflow.com/a/1521682/1550314
455
- // double int_part; bool is_int = modf(value, &int_part) == 0.0;
456
-
457
- // this all cannot be done with one run only, since fixed
458
- // output differs from normal output and regular output
459
- // can contain scientific notation which we do not want!
460
-
461
- // first sample
462
- stringstream ss;
463
- ss.precision(12);
464
- ss << value;
465
-
466
- // check if we got scientific notation in result
467
- if (ss.str().find_first_of("e") != string::npos) {
468
- ss.clear(); ss.str(string());
469
- ss.precision(max(12, precision));
470
- ss << fixed << value;
471
- }
472
-
473
- string tmp = ss.str();
474
- size_t pos_point = tmp.find_first_of(".,");
475
- size_t pos_fract = tmp.find_last_not_of("0");
476
- bool is_int = pos_point == pos_fract ||
477
- pos_point == string::npos;
478
-
479
- // reset stream for another run
480
- ss.clear(); ss.str(string());
481
-
482
- // take a shortcut for integers
483
- if (is_int)
484
- {
485
- ss.precision(0);
486
- ss << fixed << value;
487
- res = string(ss.str());
488
- }
489
- // process floats
490
- else
491
- {
492
- // do we have have too much precision?
493
- if (pos_fract < precision + pos_point)
494
- { precision = pos_fract - pos_point; }
495
- // round value again
496
- ss.precision(precision);
497
- ss << fixed << value;
498
- res = string(ss.str());
499
- // maybe we truncated up to decimal point
500
- size_t pos = res.find_last_not_of("0");
501
- bool at_dec_point = res[pos] == '.' ||
502
- res[pos] == ',';
503
- // don't leave a blank point
504
- if (at_dec_point) ++ pos;
505
- res.resize (pos + 1);
506
- }
507
-
508
- // some final cosmetics
509
- if (res == "-0.0") res.erase(0, 1);
510
- else if (res == "-0") res.erase(0, 1);
511
-
512
- // add unit now
513
- res += n->unit();
514
-
515
- // check for a valid unit here
516
- // includes result for reporting
517
- if (n->numerator_units().size() > 1 ||
518
- n->denominator_units().size() > 0 ||
519
- (n->numerator_units().size() && n->numerator_units()[0].find_first_of('/') != string::npos) ||
520
- (n->numerator_units().size() && n->numerator_units()[0].find_first_of('*') != string::npos)
521
- ) {
522
- error(res + " isn't a valid CSS value.", n->pstate());
523
- }
524
-
461
+ // use values to_string facility
462
+ bool compressed = ctx->output_style == COMPRESSED;
463
+ std::string res = n->to_string(compressed, (int)ctx->precision);
525
464
  // output the final token
526
465
  append_token(res, n);
527
-
528
- }
529
-
530
- // helper function for serializing colors
531
- template <size_t range>
532
- static double cap_channel(double c) {
533
- if (c > range) return range;
534
- else if (c < 0) return 0;
535
- else return c;
536
466
  }
537
467
 
538
468
  void Inspect::operator()(Color* c)
539
469
  {
540
- stringstream ss;
541
-
542
- // check if we prefer short hex colors
543
- bool want_short = output_style() == COMPRESSED;
544
-
545
- // original color name
546
- // maybe an unknown token
547
- string name = c->disp();
548
-
549
- // resolved color
550
- string res_name = name;
551
-
552
- double r = round(cap_channel<0xff>(c->r()));
553
- double g = round(cap_channel<0xff>(c->g()));
554
- double b = round(cap_channel<0xff>(c->b()));
555
- double a = cap_channel<1> (c->a());
556
-
557
- // get color from given name (if one was given at all)
558
- if (name != "" && ctx && ctx->names_to_colors.count(name)) {
559
- Color* n = ctx->names_to_colors[name];
560
- r = round(cap_channel<0xff>(n->r()));
561
- g = round(cap_channel<0xff>(n->g()));
562
- b = round(cap_channel<0xff>(n->b()));
563
- a = cap_channel<1> (n->a());
564
- }
565
- // otherwise get the possible resolved color name
566
- else {
567
- int numval = static_cast<int>(r) * 0x10000 + static_cast<int>(g) * 0x100 + static_cast<int>(b);
568
- if (ctx && ctx->colors_to_names.count(numval))
569
- res_name = ctx->colors_to_names[numval];
570
- }
571
-
572
- stringstream hexlet;
573
- hexlet << '#' << setw(1) << setfill('0');
574
- // create a short color hexlet if there is any need for it
575
- if (want_short && is_color_doublet(r, g, b) && a == 1) {
576
- hexlet << hex << setw(1) << (static_cast<unsigned long>(r) >> 4);
577
- hexlet << hex << setw(1) << (static_cast<unsigned long>(g) >> 4);
578
- hexlet << hex << setw(1) << (static_cast<unsigned long>(b) >> 4);
579
- } else {
580
- hexlet << hex << setw(2) << static_cast<unsigned long>(r);
581
- hexlet << hex << setw(2) << static_cast<unsigned long>(g);
582
- hexlet << hex << setw(2) << static_cast<unsigned long>(b);
583
- }
584
-
585
- if (want_short && !c->is_delayed()) name = "";
586
-
587
- // retain the originally specified color definition if unchanged
588
- if (name != "") {
589
- ss << name;
590
- }
591
- else if (r == 0 && g == 0 && b == 0 && a == 0) {
592
- ss << "transparent";
593
- }
594
- else if (a >= 1) {
595
- if (res_name != "") {
596
- if (want_short && hexlet.str().size() < res_name.size()) {
597
- ss << hexlet.str();
598
- } else {
599
- ss << res_name;
600
- }
601
- }
602
- else {
603
- ss << hexlet.str();
604
- }
605
- }
606
- else {
607
- ss << "rgba(";
608
- ss << static_cast<unsigned long>(r) << ",";
609
- if (output_style() != COMPRESSED) ss << " ";
610
- ss << static_cast<unsigned long>(g) << ",";
611
- if (output_style() != COMPRESSED) ss << " ";
612
- ss << static_cast<unsigned long>(b) << ",";
613
- if (output_style() != COMPRESSED) ss << " ";
614
- ss << a << ')';
615
- }
616
- append_token(ss.str(), c);
470
+ // use values to_string facility
471
+ bool compressed = ctx->output_style == COMPRESSED;
472
+ std::string res = c->to_string(compressed, (int)ctx->precision);
473
+ // output the final token
474
+ append_token(res, c);
617
475
  }
618
476
 
619
477
  void Inspect::operator()(Boolean* b)
620
478
  {
621
- append_token(b->value() ? "true" : "false", b);
479
+ // use values to_string facility
480
+ bool compressed = ctx->output_style == COMPRESSED;
481
+ std::string res = b->to_string(compressed, (int)ctx->precision);
482
+ // output the final token
483
+ append_token(res, b);
622
484
  }
623
485
 
624
486
  void Inspect::operator()(String_Schema* ss)
625
487
  {
626
- // Evaluation should turn these into String_Constants, so this method is
627
- // only for inspection purposes.
488
+ // Evaluation should turn these into String_Constants,
489
+ // so this method is only for inspection purposes.
628
490
  for (size_t i = 0, L = ss->length(); i < L; ++i) {
629
491
  if ((*ss)[i]->is_interpolant()) append_string("#{");
630
492
  (*ss)[i]->perform(this);
@@ -634,57 +496,68 @@ namespace Sass {
634
496
 
635
497
  void Inspect::operator()(String_Constant* s)
636
498
  {
637
- if (String_Quoted* quoted = dynamic_cast<String_Quoted*>(s)) {
638
- return Inspect::operator()(quoted);
639
- }
640
- append_token(s->value(), s);
499
+ // get options from optional? context
500
+ int precision = ctx ? (int)ctx->precision : 5;
501
+ bool compressed = ctx ? ctx->output_style == COMPRESSED : false;
502
+ // use values to_string facility
503
+ std::string res(s->to_string(compressed, precision));
504
+ // output the final token
505
+ append_token(res, s);
641
506
  }
642
507
 
643
508
  void Inspect::operator()(String_Quoted* s)
644
509
  {
645
- if (s->quote_mark()) {
646
- append_token(quote(s->value(), s->quote_mark(), true), s);
647
- } else {
648
- append_token(s->value(), s);
649
- }
510
+ // get options from optional? context
511
+ int precision = ctx ? (int)ctx->precision : 5;
512
+ bool compressed = ctx ? ctx->output_style == COMPRESSED : false;
513
+ // use values to_string facility
514
+ std::string res(s->to_string(compressed, precision));
515
+ // output the final token
516
+ append_token(res, s);
650
517
  }
651
-
652
- void Inspect::operator()(Feature_Query* fq)
518
+ void Inspect::operator()(Supports_Operator* so)
653
519
  {
654
- size_t i = 0;
655
- (*fq)[i++]->perform(this);
656
- for (size_t L = fq->length(); i < L; ++i) {
657
- (*fq)[i]->perform(this);
658
- }
659
- }
660
520
 
661
- void Inspect::operator()(Feature_Query_Condition* fqc)
662
- {
663
- if (fqc->operand() == Feature_Query_Condition::AND) {
664
- append_mandatory_space();
665
- append_token("and", fqc);
666
- append_mandatory_space();
667
- } else if (fqc->operand() == Feature_Query_Condition::OR) {
521
+ if (so->needs_parens(so->left())) append_string("(");
522
+ so->left()->perform(this);
523
+ if (so->needs_parens(so->left())) append_string(")");
524
+
525
+ if (so->operand() == Supports_Operator::AND) {
668
526
  append_mandatory_space();
669
- append_token("or", fqc);
527
+ append_token("and", so);
670
528
  append_mandatory_space();
671
- } else if (fqc->operand() == Feature_Query_Condition::NOT) {
529
+ } else if (so->operand() == Supports_Operator::OR) {
672
530
  append_mandatory_space();
673
- append_token("not", fqc);
531
+ append_token("or", so);
674
532
  append_mandatory_space();
675
533
  }
676
534
 
677
- if (!fqc->is_root()) append_string("(");
535
+ if (so->needs_parens(so->right())) append_string("(");
536
+ so->right()->perform(this);
537
+ if (so->needs_parens(so->right())) append_string(")");
538
+ }
678
539
 
679
- if (!fqc->length()) {
680
- fqc->feature()->perform(this);
681
- append_string(": "); // verified
682
- fqc->value()->perform(this);
683
- }
684
- for (size_t i = 0, L = fqc->length(); i < L; ++i)
685
- (*fqc)[i]->perform(this);
540
+ void Inspect::operator()(Supports_Negation* sn)
541
+ {
542
+ append_token("not", sn);
543
+ append_mandatory_space();
544
+ if (sn->needs_parens(sn->condition())) append_string("(");
545
+ sn->condition()->perform(this);
546
+ if (sn->needs_parens(sn->condition())) append_string(")");
547
+ }
686
548
 
687
- if (!fqc->is_root()) append_string(")");
549
+ void Inspect::operator()(Supports_Declaration* sd)
550
+ {
551
+ append_string("(");
552
+ sd->feature()->perform(this);
553
+ append_string(": ");
554
+ sd->value()->perform(this);
555
+ append_string(")");
556
+ }
557
+
558
+ void Inspect::operator()(Supports_Interpolation* sd)
559
+ {
560
+ sd->value()->perform(this);
688
561
  }
689
562
 
690
563
  void Inspect::operator()(Media_Query* mq)
@@ -738,18 +611,11 @@ namespace Sass {
738
611
 
739
612
  void Inspect::operator()(Null* n)
740
613
  {
741
- append_token("null", n);
742
- }
743
-
744
- void Inspect::operator()(Parent_Selector* p)
745
- {
746
- if (p->selector()) {
747
- p->selector()->perform(this);
748
- append_delimiter();
749
- }
750
- else {
751
- append_string("&");
752
- }
614
+ // use values to_string facility
615
+ bool compressed = ctx->output_style == COMPRESSED;
616
+ std::string res = n->to_string(compressed, (int)ctx->precision);
617
+ // output the final token
618
+ append_token(res, n);
753
619
  }
754
620
 
755
621
  // parameters and arguments
@@ -816,10 +682,9 @@ namespace Sass {
816
682
  s->contents()->perform(this);
817
683
  }
818
684
 
819
- void Inspect::operator()(Selector_Reference* ref)
685
+ void Inspect::operator()(Parent_Selector* p)
820
686
  {
821
- if (ref->selector()) ref->selector()->perform(this);
822
- else append_string("&");
687
+ append_string("&");
823
688
  }
824
689
 
825
690
  void Inspect::operator()(Selector_Placeholder* s)
@@ -832,12 +697,12 @@ namespace Sass {
832
697
 
833
698
  void Inspect::operator()(Type_Selector* s)
834
699
  {
835
- append_token(s->name(), s);
700
+ append_token(s->ns_name(), s);
836
701
  }
837
702
 
838
703
  void Inspect::operator()(Selector_Qualifier* s)
839
704
  {
840
- append_token(s->name(), s);
705
+ append_token(s->ns_name(), s);
841
706
  if (s->has_line_break()) append_optional_linefeed();
842
707
  if (s->has_line_break()) append_indentation();
843
708
  }
@@ -846,7 +711,7 @@ namespace Sass {
846
711
  {
847
712
  append_string("[");
848
713
  add_open_mapping(s);
849
- append_token(s->name(), s);
714
+ append_token(s->ns_name(), s);
850
715
  if (!s->matcher().empty()) {
851
716
  append_string(s->matcher());
852
717
  if (s->value()) {
@@ -859,8 +724,9 @@ namespace Sass {
859
724
 
860
725
  void Inspect::operator()(Pseudo_Selector* s)
861
726
  {
862
- append_token(s->name(), s);
727
+ append_token(s->ns_name(), s);
863
728
  if (s->expression()) {
729
+ append_string("(");
864
730
  s->expression()->perform(this);
865
731
  append_string(")");
866
732
  }
@@ -871,6 +737,7 @@ namespace Sass {
871
737
  bool was = in_wrapped;
872
738
  in_wrapped = true;
873
739
  append_token(s->name(), s);
740
+ append_string("(");
874
741
  s->selector()->perform(this);
875
742
  append_string(")");
876
743
  in_wrapped = was;
@@ -882,7 +749,9 @@ namespace Sass {
882
749
  (*s)[i]->perform(this);
883
750
  }
884
751
  if (s->has_line_break()) {
885
- append_optional_linefeed();
752
+ if (output_style() != COMPACT) {
753
+ append_optional_linefeed();
754
+ }
886
755
  }
887
756
  }
888
757
 
@@ -891,8 +760,16 @@ namespace Sass {
891
760
  Compound_Selector* head = c->head();
892
761
  Complex_Selector* tail = c->tail();
893
762
  Complex_Selector::Combinator comb = c->combinator();
894
- if (head && !head->is_empty_reference()) head->perform(this);
895
- bool is_empty = head && head->is_empty_reference();
763
+
764
+ if (c->has_line_feed()) {
765
+ if (!(c->has_parent_ref())) {
766
+ append_optional_linefeed();
767
+ append_indentation();
768
+ }
769
+ }
770
+
771
+ if (head && head->length() != 0) head->perform(this);
772
+ bool is_empty = !head || head->length() == 0 || head->is_empty_reference();
896
773
  bool is_tail = head && !head->is_empty_reference() && tail;
897
774
  if (output_style() == COMPRESSED && comb != Complex_Selector::ANCESTOR_OF) scheduled_space = 0;
898
775
 
@@ -910,6 +787,13 @@ namespace Sass {
910
787
  append_string("+");
911
788
  append_optional_space();
912
789
  break;
790
+ case Complex_Selector::REFERENCE:
791
+ append_mandatory_space();
792
+ append_string("/");
793
+ c->reference()->perform(this);
794
+ append_string("/");
795
+ append_mandatory_space();
796
+ break;
913
797
  case Complex_Selector::PRECEDES:
914
798
  if (is_empty) append_optional_space();
915
799
  else append_mandatory_space();
@@ -922,6 +806,11 @@ namespace Sass {
922
806
  if (c->has_line_break()) append_optional_linefeed();
923
807
  }
924
808
  if (tail) tail->perform(this);
809
+ if (!tail && c->has_line_break()) {
810
+ if (output_style() == COMPACT) {
811
+ append_mandatory_space();
812
+ }
813
+ }
925
814
  }
926
815
 
927
816
  void Inspect::operator()(Selector_List* g)
@@ -929,13 +818,11 @@ namespace Sass {
929
818
  if (g->empty()) return;
930
819
  for (size_t i = 0, L = g->length(); i < L; ++i) {
931
820
  if (!in_wrapped && i == 0) append_indentation();
821
+ if ((*g)[i] == 0) continue;
932
822
  (*g)[i]->perform(this);
933
823
  if (i < L - 1) {
824
+ scheduled_space = 0;
934
825
  append_comma_separator();
935
- if ((*g)[i]->has_line_feed()) {
936
- append_optional_linefeed();
937
- append_indentation();
938
- }
939
826
  }
940
827
  }
941
828
  }