sassc 1.8.3 → 1.8.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -1
  3. data/ext/libsass/.editorconfig +1 -1
  4. data/ext/libsass/.gitignore +1 -0
  5. data/ext/libsass/LICENSE +1 -1
  6. data/ext/libsass/Makefile +20 -14
  7. data/ext/libsass/Makefile.conf +0 -1
  8. data/ext/libsass/Readme.md +3 -1
  9. data/ext/libsass/appveyor.yml +19 -11
  10. data/ext/libsass/docs/api-importer-example.md +2 -1235
  11. data/ext/libsass/docs/build-with-autotools.md +10 -0
  12. data/ext/libsass/docs/build-with-makefiles.md +18 -0
  13. data/ext/libsass/include/sass/base.h +4 -1
  14. data/ext/libsass/include/sass/values.h +2 -1
  15. data/ext/libsass/src/ast.cpp +279 -346
  16. data/ext/libsass/src/ast.hpp +234 -60
  17. data/ext/libsass/src/base64vlq.cpp +1 -0
  18. data/ext/libsass/src/bind.cpp +35 -45
  19. data/ext/libsass/src/bind.hpp +1 -0
  20. data/ext/libsass/src/color_maps.cpp +1 -0
  21. data/ext/libsass/src/constants.cpp +4 -1
  22. data/ext/libsass/src/constants.hpp +2 -1
  23. data/ext/libsass/src/context.cpp +41 -31
  24. data/ext/libsass/src/context.hpp +10 -10
  25. data/ext/libsass/src/cssize.cpp +7 -4
  26. data/ext/libsass/src/cssize.hpp +1 -3
  27. data/ext/libsass/src/debugger.hpp +73 -14
  28. data/ext/libsass/src/emitter.cpp +37 -25
  29. data/ext/libsass/src/emitter.hpp +10 -9
  30. data/ext/libsass/src/environment.cpp +16 -5
  31. data/ext/libsass/src/environment.hpp +5 -3
  32. data/ext/libsass/src/error_handling.cpp +91 -14
  33. data/ext/libsass/src/error_handling.hpp +105 -4
  34. data/ext/libsass/src/eval.cpp +519 -330
  35. data/ext/libsass/src/eval.hpp +12 -13
  36. data/ext/libsass/src/expand.cpp +92 -56
  37. data/ext/libsass/src/expand.hpp +5 -3
  38. data/ext/libsass/src/extend.cpp +60 -51
  39. data/ext/libsass/src/extend.hpp +1 -3
  40. data/ext/libsass/src/file.cpp +37 -27
  41. data/ext/libsass/src/functions.cpp +78 -62
  42. data/ext/libsass/src/functions.hpp +1 -0
  43. data/ext/libsass/src/inspect.cpp +293 -64
  44. data/ext/libsass/src/inspect.hpp +2 -0
  45. data/ext/libsass/src/lexer.cpp +1 -0
  46. data/ext/libsass/src/listize.cpp +14 -15
  47. data/ext/libsass/src/listize.hpp +3 -5
  48. data/ext/libsass/src/memory_manager.cpp +1 -0
  49. data/ext/libsass/src/node.cpp +2 -3
  50. data/ext/libsass/src/operation.hpp +70 -71
  51. data/ext/libsass/src/output.cpp +28 -32
  52. data/ext/libsass/src/output.hpp +1 -2
  53. data/ext/libsass/src/parser.cpp +402 -183
  54. data/ext/libsass/src/parser.hpp +19 -9
  55. data/ext/libsass/src/plugins.cpp +1 -0
  56. data/ext/libsass/src/position.cpp +1 -0
  57. data/ext/libsass/src/prelexer.cpp +134 -56
  58. data/ext/libsass/src/prelexer.hpp +51 -3
  59. data/ext/libsass/src/remove_placeholders.cpp +35 -9
  60. data/ext/libsass/src/remove_placeholders.hpp +4 -3
  61. data/ext/libsass/src/sass.cpp +1 -0
  62. data/ext/libsass/src/sass.hpp +129 -0
  63. data/ext/libsass/src/sass_context.cpp +31 -14
  64. data/ext/libsass/src/sass_context.hpp +2 -31
  65. data/ext/libsass/src/sass_functions.cpp +1 -0
  66. data/ext/libsass/src/sass_interface.cpp +5 -6
  67. data/ext/libsass/src/sass_util.cpp +1 -2
  68. data/ext/libsass/src/sass_util.hpp +5 -5
  69. data/ext/libsass/src/sass_values.cpp +13 -10
  70. data/ext/libsass/src/source_map.cpp +4 -3
  71. data/ext/libsass/src/source_map.hpp +2 -2
  72. data/ext/libsass/src/subset_map.hpp +0 -1
  73. data/ext/libsass/src/to_c.cpp +1 -0
  74. data/ext/libsass/src/to_c.hpp +1 -3
  75. data/ext/libsass/src/to_value.cpp +3 -5
  76. data/ext/libsass/src/to_value.hpp +1 -1
  77. data/ext/libsass/src/units.cpp +96 -59
  78. data/ext/libsass/src/units.hpp +10 -8
  79. data/ext/libsass/src/utf8_string.cpp +5 -0
  80. data/ext/libsass/src/util.cpp +23 -156
  81. data/ext/libsass/src/util.hpp +10 -14
  82. data/ext/libsass/src/values.cpp +1 -0
  83. data/ext/libsass/test/test_node.cpp +2 -6
  84. data/ext/libsass/test/test_selector_difference.cpp +1 -3
  85. data/ext/libsass/test/test_specificity.cpp +0 -2
  86. data/ext/libsass/test/test_superselector.cpp +0 -2
  87. data/ext/libsass/test/test_unification.cpp +1 -3
  88. data/ext/libsass/win/libsass.targets +18 -5
  89. data/ext/libsass/win/libsass.vcxproj +9 -7
  90. data/ext/libsass/win/libsass.vcxproj.filters +148 -106
  91. data/lib/sassc/version.rb +1 -1
  92. data/test/engine_test.rb +12 -0
  93. data/test/native_test.rb +1 -1
  94. metadata +3 -4
  95. data/ext/libsass/src/to_string.cpp +0 -48
  96. data/ext/libsass/src/to_string.hpp +0 -38
@@ -1,9 +1,9 @@
1
+ #include "sass.hpp"
1
2
  #include <iostream>
2
3
  #include <typeinfo>
3
4
  #include <vector>
4
5
 
5
6
  #include "cssize.hpp"
6
- #include "to_string.hpp"
7
7
  #include "context.hpp"
8
8
  #include "backtrace.hpp"
9
9
 
@@ -100,6 +100,10 @@ namespace Sass {
100
100
  // rr->tabs(r->block()->tabs());
101
101
  p_stack.pop_back();
102
102
 
103
+ if (!rr->block()) {
104
+ error("Illegal nesting: Only properties may be nested beneath properties.", r->block()->pstate());
105
+ }
106
+
103
107
  Block* props = SASS_MEMORY_NEW(ctx.mem, Block, rr->block()->pstate());
104
108
  Block* rules = SASS_MEMORY_NEW(ctx.mem, Block, rr->block()->pstate());
105
109
  for (size_t i = 0, L = rr->block()->length(); i < L; i++)
@@ -513,15 +517,14 @@ namespace Sass {
513
517
 
514
518
  Media_Query* Cssize::merge_media_query(Media_Query* mq1, Media_Query* mq2)
515
519
  {
516
- To_String to_string(&ctx);
517
520
 
518
521
  std::string type;
519
522
  std::string mod;
520
523
 
521
524
  std::string m1 = std::string(mq1->is_restricted() ? "only" : mq1->is_negated() ? "not" : "");
522
- std::string t1 = mq1->media_type() ? mq1->media_type()->perform(&to_string) : "";
525
+ std::string t1 = mq1->media_type() ? mq1->media_type()->to_string(ctx.c_options) : "";
523
526
  std::string m2 = std::string(mq2->is_restricted() ? "only" : mq1->is_negated() ? "not" : "");
524
- std::string t2 = mq2->media_type() ? mq2->media_type()->perform(&to_string) : "";
527
+ std::string t2 = mq2->media_type() ? mq2->media_type()->to_string(ctx.c_options) : "";
525
528
 
526
529
 
527
530
  if (t1.empty()) t1 = t2;
@@ -22,9 +22,7 @@ namespace Sass {
22
22
 
23
23
  public:
24
24
  Cssize(Context&, Backtrace*);
25
- virtual ~Cssize() { }
26
-
27
- using Operation<Statement*>::operator();
25
+ ~Cssize() { }
28
26
 
29
27
  Statement* operator()(Block*);
30
28
  Statement* operator()(Ruleset*);
@@ -77,8 +77,10 @@ inline void debug_ast(AST_Node* node, std::string ind, Env* env)
77
77
  Selector_List* selector = dynamic_cast<Selector_List*>(node);
78
78
  std::cerr << ind << "Selector_List " << selector;
79
79
  std::cerr << " (" << pstate_source_position(node) << ")";
80
+ std::cerr << " <" << selector->hash() << ">";
80
81
  std::cerr << " [@media:" << selector->media_block() << "]";
81
82
  std::cerr << (selector->is_optional() ? " [is_optional]": " -");
83
+ std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -");
82
84
  std::cerr << (selector->has_line_break() ? " [line-break]": " -");
83
85
  std::cerr << (selector->has_line_feed() ? " [line-feed]": " -");
84
86
  std::cerr << std::endl;
@@ -94,6 +96,7 @@ inline void debug_ast(AST_Node* node, std::string ind, Env* env)
94
96
  std::cerr << ind << "Parent_Selector " << selector;
95
97
  // if (selector->not_selector()) cerr << " [in_declaration]";
96
98
  std::cerr << " (" << pstate_source_position(node) << ")";
99
+ std::cerr << " <" << selector->hash() << ">";
97
100
  std::cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << std::endl;
98
101
  // debug_ast(selector->selector(), ind + "->", env);
99
102
 
@@ -101,9 +104,11 @@ inline void debug_ast(AST_Node* node, std::string ind, Env* env)
101
104
  Complex_Selector* selector = dynamic_cast<Complex_Selector*>(node);
102
105
  std::cerr << ind << "Complex_Selector " << selector
103
106
  << " (" << pstate_source_position(node) << ")"
107
+ << " <" << selector->hash() << ">"
104
108
  << " [weight:" << longToHex(selector->specificity()) << "]"
105
109
  << " [@media:" << selector->media_block() << "]"
106
110
  << (selector->is_optional() ? " [is_optional]": " -")
111
+ << (selector->has_parent_ref() ? " [has parent]": " -")
107
112
  << (selector->has_line_feed() ? " [line-feed]": " -")
108
113
  << (selector->has_line_break() ? " [line-break]": " -")
109
114
  << " -- ";
@@ -129,9 +134,12 @@ inline void debug_ast(AST_Node* node, std::string ind, Env* env)
129
134
  Compound_Selector* selector = dynamic_cast<Compound_Selector*>(node);
130
135
  std::cerr << ind << "Compound_Selector " << selector;
131
136
  std::cerr << " (" << pstate_source_position(node) << ")";
137
+ std::cerr << " <" << selector->hash() << ">";
132
138
  std::cerr << " [weight:" << longToHex(selector->specificity()) << "]";
133
139
  std::cerr << " [@media:" << selector->media_block() << "]";
140
+ std::cerr << (selector->extended() ? " [extended]": " -");
134
141
  std::cerr << (selector->is_optional() ? " [is_optional]": " -");
142
+ std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -");
135
143
  std::cerr << (selector->has_line_break() ? " [line-break]": " -");
136
144
  std::cerr << (selector->has_line_feed() ? " [line-feed]": " -");
137
145
  std::cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << std::endl;
@@ -146,35 +154,66 @@ inline void debug_ast(AST_Node* node, std::string ind, Env* env)
146
154
  Wrapped_Selector* selector = dynamic_cast<Wrapped_Selector*>(node);
147
155
  std::cerr << ind << "Wrapped_Selector " << selector;
148
156
  std::cerr << " (" << pstate_source_position(node) << ")";
149
- std::cerr << " <<" << selector->ns_name() << ">>" << (selector->has_line_break() ? " [line-break]": " -") << (selector->has_line_feed() ? " [line-feed]": " -") << std::endl;
157
+ std::cerr << " <" << selector->hash() << ">";
158
+ std::cerr << " <<" << selector->ns_name() << ">>";
159
+ std::cerr << (selector->is_optional() ? " [is_optional]": " -");
160
+ std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -");
161
+ std::cerr << (selector->has_line_break() ? " [line-break]": " -");
162
+ std::cerr << (selector->has_line_feed() ? " [line-feed]": " -");
163
+ std::cerr << std::endl;
150
164
  debug_ast(selector->selector(), ind + " () ", env);
151
165
  } else if (dynamic_cast<Pseudo_Selector*>(node)) {
152
166
  Pseudo_Selector* selector = dynamic_cast<Pseudo_Selector*>(node);
153
167
  std::cerr << ind << "Pseudo_Selector " << selector;
154
168
  std::cerr << " (" << pstate_source_position(node) << ")";
155
- std::cerr << " <<" << selector->ns_name() << ">>" << (selector->has_line_break() ? " [line-break]": " -") << (selector->has_line_feed() ? " [line-feed]": " -") << std::endl;
169
+ std::cerr << " <" << selector->hash() << ">";
170
+ std::cerr << " <<" << selector->ns_name() << ">>";
171
+ std::cerr << (selector->is_optional() ? " [is_optional]": " -");
172
+ std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -");
173
+ std::cerr << (selector->has_line_break() ? " [line-break]": " -");
174
+ std::cerr << (selector->has_line_feed() ? " [line-feed]": " -");
175
+ std::cerr << std::endl;
156
176
  debug_ast(selector->expression(), ind + " <= ", env);
157
177
  } else if (dynamic_cast<Attribute_Selector*>(node)) {
158
178
  Attribute_Selector* selector = dynamic_cast<Attribute_Selector*>(node);
159
179
  std::cerr << ind << "Attribute_Selector " << selector;
160
180
  std::cerr << " (" << pstate_source_position(node) << ")";
161
- std::cerr << " <<" << selector->ns_name() << ">>" << (selector->has_line_break() ? " [line-break]": " -") << (selector->has_line_feed() ? " [line-feed]": " -") << std::endl;
181
+ std::cerr << " <" << selector->hash() << ">";
182
+ std::cerr << " <<" << selector->ns_name() << ">>";
183
+ std::cerr << (selector->is_optional() ? " [is_optional]": " -");
184
+ std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -");
185
+ std::cerr << (selector->has_line_break() ? " [line-break]": " -");
186
+ std::cerr << (selector->has_line_feed() ? " [line-feed]": " -");
187
+ std::cerr << std::endl;
162
188
  debug_ast(selector->value(), ind + "[" + selector->matcher() + "] ", env);
163
189
  } else if (dynamic_cast<Selector_Qualifier*>(node)) {
164
190
  Selector_Qualifier* selector = dynamic_cast<Selector_Qualifier*>(node);
165
191
  std::cerr << ind << "Selector_Qualifier " << selector;
166
192
  std::cerr << " (" << pstate_source_position(node) << ")";
167
- std::cerr << " <<" << selector->ns_name() << ">>" << (selector->has_line_break() ? " [line-break]": " -") << (selector->has_line_feed() ? " [line-feed]": " -") << std::endl;
193
+ std::cerr << " <" << selector->hash() << ">";
194
+ std::cerr << " <<" << selector->ns_name() << ">>";
195
+ std::cerr << (selector->is_optional() ? " [is_optional]": " -");
196
+ std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -");
197
+ std::cerr << (selector->has_line_break() ? " [line-break]": " -");
198
+ std::cerr << (selector->has_line_feed() ? " [line-feed]": " -");
199
+ std::cerr << std::endl;
168
200
  } else if (dynamic_cast<Type_Selector*>(node)) {
169
201
  Type_Selector* selector = dynamic_cast<Type_Selector*>(node);
170
202
  std::cerr << ind << "Type_Selector " << selector;
171
203
  std::cerr << " (" << pstate_source_position(node) << ")";
172
- std::cerr << " <<" << selector->ns_name() << ">>" << (selector->has_line_break() ? " [line-break]": " -") <<
173
- " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << std::endl;
204
+ std::cerr << " <" << selector->hash() << ">";
205
+ std::cerr << " <<" << selector->ns_name() << ">>";
206
+ std::cerr << (selector->is_optional() ? " [is_optional]": " -");
207
+ std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -");
208
+ std::cerr << (selector->has_line_break() ? " [line-break]": " -");
209
+ std::cerr << (selector->has_line_feed() ? " [line-feed]": " -");
210
+ std::cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">";
211
+ std::cerr << std::endl;
174
212
  } else if (dynamic_cast<Selector_Placeholder*>(node)) {
175
213
 
176
214
  Selector_Placeholder* selector = dynamic_cast<Selector_Placeholder*>(node);
177
215
  std::cerr << ind << "Selector_Placeholder [" << selector->ns_name() << "] " << selector
216
+ << " <" << selector->hash() << ">"
178
217
  << " [@media:" << selector->media_block() << "]"
179
218
  << (selector->is_optional() ? " [is_optional]": " -")
180
219
  << (selector->has_line_break() ? " [line-break]": " -")
@@ -282,6 +321,7 @@ inline void debug_ast(AST_Node* node, std::string ind, Env* env)
282
321
  std::cerr << ind << "Debug " << block;
283
322
  std::cerr << " (" << pstate_source_position(node) << ")";
284
323
  std::cerr << " " << block->tabs() << std::endl;
324
+ debug_ast(block->value(), ind + " ");
285
325
  } else if (dynamic_cast<Comment*>(node)) {
286
326
  Comment* block = dynamic_cast<Comment*>(node);
287
327
  std::cerr << ind << "Comment " << block;
@@ -323,9 +363,9 @@ inline void debug_ast(AST_Node* node, std::string ind, Env* env)
323
363
  std::cerr << ind << "Import " << block;
324
364
  std::cerr << " (" << pstate_source_position(node) << ")";
325
365
  std::cerr << " " << block->tabs() << std::endl;
326
- debug_ast(block->media_queries(), ind + " @ ");
327
366
  // std::vector<std::string> files_;
328
- for (auto imp : block->urls()) debug_ast(imp, "@ ", env);
367
+ for (auto imp : block->urls()) debug_ast(imp, ind + "@: ", env);
368
+ debug_ast(block->media_queries(), ind + "@@ ");
329
369
  } else if (dynamic_cast<Assignment*>(node)) {
330
370
  Assignment* block = dynamic_cast<Assignment*>(node);
331
371
  std::cerr << ind << "Assignment " << block;
@@ -414,11 +454,13 @@ inline void debug_ast(AST_Node* node, std::string ind, Env* env)
414
454
  else if (expression->type() == Textual::DIMENSION) std::cerr << " [DIMENSION]";
415
455
  else if (expression->type() == Textual::HEX) std::cerr << " [HEX]";
416
456
  std::cerr << expression << " [" << expression->value() << "]";
457
+ std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
417
458
  if (expression->is_delayed()) std::cerr << " [delayed]";
418
459
  std::cerr << std::endl;
419
460
  } else if (dynamic_cast<Variable*>(node)) {
420
461
  Variable* expression = dynamic_cast<Variable*>(node);
421
462
  std::cerr << ind << "Variable " << expression;
463
+ std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
422
464
  std::cerr << " (" << pstate_source_position(node) << ")";
423
465
  std::cerr << " [" << expression->name() << "]" << std::endl;
424
466
  std::string name(expression->name());
@@ -426,6 +468,7 @@ inline void debug_ast(AST_Node* node, std::string ind, Env* env)
426
468
  } else if (dynamic_cast<Function_Call_Schema*>(node)) {
427
469
  Function_Call_Schema* expression = dynamic_cast<Function_Call_Schema*>(node);
428
470
  std::cerr << ind << "Function_Call_Schema " << expression;
471
+ std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
429
472
  std::cerr << " (" << pstate_source_position(node) << ")";
430
473
  std::cerr << "" << std::endl;
431
474
  debug_ast(expression->name(), ind + "name: ", env);
@@ -433,8 +476,12 @@ inline void debug_ast(AST_Node* node, std::string ind, Env* env)
433
476
  } else if (dynamic_cast<Function_Call*>(node)) {
434
477
  Function_Call* expression = dynamic_cast<Function_Call*>(node);
435
478
  std::cerr << ind << "Function_Call " << expression;
479
+ std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
436
480
  std::cerr << " (" << pstate_source_position(node) << ")";
437
- std::cerr << " [" << expression->name() << "]" << std::endl;
481
+ std::cerr << " [" << expression->name() << "]";
482
+ if (expression->is_delayed()) std::cerr << " [delayed]";
483
+ if (expression->is_interpolant()) std::cerr << " [interpolant]";
484
+ std::cerr << std::endl;
438
485
  debug_ast(expression->arguments(), ind + " args: ", env);
439
486
  } else if (dynamic_cast<Arguments*>(node)) {
440
487
  Arguments* expression = dynamic_cast<Arguments*>(node);
@@ -473,13 +520,19 @@ inline void debug_ast(AST_Node* node, std::string ind, Env* env)
473
520
  } else if (dynamic_cast<Unary_Expression*>(node)) {
474
521
  Unary_Expression* expression = dynamic_cast<Unary_Expression*>(node);
475
522
  std::cerr << ind << "Unary_Expression " << expression;
523
+ std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
476
524
  std::cerr << " (" << pstate_source_position(node) << ")";
477
525
  std::cerr << " [" << expression->type() << "]" << std::endl;
478
526
  debug_ast(expression->operand(), ind + " operand: ", env);
479
527
  } else if (dynamic_cast<Binary_Expression*>(node)) {
480
528
  Binary_Expression* expression = dynamic_cast<Binary_Expression*>(node);
481
529
  std::cerr << ind << "Binary_Expression " << expression;
530
+ if (expression->is_interpolant()) std::cerr << " [is interpolant] ";
531
+ if (expression->is_left_interpolant()) std::cerr << " [left interpolant] ";
532
+ if (expression->is_right_interpolant()) std::cerr << " [right interpolant] ";
482
533
  std::cerr << " [delayed: " << expression->is_delayed() << "] ";
534
+ std::cerr << " [ws_before: " << expression->op().ws_before << "] ";
535
+ std::cerr << " [ws_after: " << expression->op().ws_after << "] ";
483
536
  std::cerr << " (" << pstate_source_position(node) << ")";
484
537
  std::cerr << " [" << expression->type_name() << "]" << std::endl;
485
538
  debug_ast(expression->left(), ind + " left: ", env);
@@ -487,6 +540,7 @@ inline void debug_ast(AST_Node* node, std::string ind, Env* env)
487
540
  } else if (dynamic_cast<Map*>(node)) {
488
541
  Map* expression = dynamic_cast<Map*>(node);
489
542
  std::cerr << ind << "Map " << expression;
543
+ std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
490
544
  std::cerr << " (" << pstate_source_position(node) << ")";
491
545
  std::cerr << " [Hashed]" << std::endl;
492
546
  for (auto i : expression->elements()) {
@@ -498,7 +552,7 @@ inline void debug_ast(AST_Node* node, std::string ind, Env* env)
498
552
  std::cerr << ind << "List " << expression;
499
553
  std::cerr << " (" << pstate_source_position(node) << ")";
500
554
  std::cerr << " (" << expression->length() << ") " <<
501
- (expression->separator() == SASS_COMMA ? "Comma " : "Space ") <<
555
+ (expression->separator() == SASS_COMMA ? "Comma " : expression->separator() == SASS_HASH ? "Map" : "Space ") <<
502
556
  " [delayed: " << expression->is_delayed() << "] " <<
503
557
  " [interpolant: " << expression->is_interpolant() << "] " <<
504
558
  " [arglist: " << expression->is_arglist() << "] " <<
@@ -514,16 +568,19 @@ inline void debug_ast(AST_Node* node, std::string ind, Env* env)
514
568
  Boolean* expression = dynamic_cast<Boolean*>(node);
515
569
  std::cerr << ind << "Boolean " << expression;
516
570
  std::cerr << " (" << pstate_source_position(node) << ")";
571
+ std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
517
572
  std::cerr << " [" << expression->value() << "]" << std::endl;
518
573
  } else if (dynamic_cast<Color*>(node)) {
519
574
  Color* expression = dynamic_cast<Color*>(node);
520
575
  std::cerr << ind << "Color " << expression;
521
576
  std::cerr << " (" << pstate_source_position(node) << ")";
577
+ std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
522
578
  std::cerr << " [" << expression->r() << ":" << expression->g() << ":" << expression->b() << "@" << expression->a() << "]" << std::endl;
523
579
  } else if (dynamic_cast<Number*>(node)) {
524
580
  Number* expression = dynamic_cast<Number*>(node);
525
581
  std::cerr << ind << "Number " << expression;
526
582
  std::cerr << " (" << pstate_source_position(node) << ")";
583
+ std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
527
584
  std::cerr << " [" << expression->value() << expression->unit() << "]" <<
528
585
  " [hash: " << expression->hash() << "] " <<
529
586
  std::endl;
@@ -554,8 +611,10 @@ inline void debug_ast(AST_Node* node, std::string ind, Env* env)
554
611
  std::cerr << ind << "String_Schema " << expression;
555
612
  std::cerr << " " << expression->concrete_type();
556
613
  if (expression->is_delayed()) std::cerr << " [delayed]";
557
- if (expression->has_interpolants()) std::cerr << " [has_interpolants]";
558
- if (expression->is_interpolant()) std::cerr << " [interpolant]";
614
+ if (expression->is_interpolant()) std::cerr << " [is interpolant]";
615
+ if (expression->has_interpolant()) std::cerr << " [has interpolant]";
616
+ if (expression->is_left_interpolant()) std::cerr << " [left interpolant] ";
617
+ if (expression->is_right_interpolant()) std::cerr << " [right interpolant] ";
559
618
  std::cerr << " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << std::endl;
560
619
  for(auto i : expression->elements()) { debug_ast(i, ind + " ", env); }
561
620
  } else if (dynamic_cast<String*>(node)) {
@@ -660,10 +719,10 @@ inline void debug_node(const Node* node, std::string ind = "")
660
719
  debug_node(const_cast<Node*>(node), ind);
661
720
  }
662
721
 
663
- inline void debug_extenstion_map(Sass::ExtensionSubsetMap* map, std::string ind = "")
722
+ inline void debug_subset_map(Sass::ExtensionSubsetMap& map, std::string ind = "")
664
723
  {
665
724
  if (ind == "") std::cerr << "#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
666
- for(auto const &it : map->values()) {
725
+ for(auto const &it : map.values()) {
667
726
  debug_ast(it.first, ind + "first: ");
668
727
  debug_ast(it.second, ind + "second: ");
669
728
  }
@@ -1,3 +1,4 @@
1
+ #include "sass.hpp"
1
2
  #include "util.hpp"
2
3
  #include "context.hpp"
3
4
  #include "output.hpp"
@@ -6,20 +7,20 @@
6
7
 
7
8
  namespace Sass {
8
9
 
9
- Emitter::Emitter(Context* ctx)
10
+ Emitter::Emitter(struct Sass_Output_Options& opt)
10
11
  : wbuf(),
11
- ctx(ctx),
12
+ opt(opt),
12
13
  indentation(0),
13
14
  scheduled_space(0),
14
15
  scheduled_linefeed(0),
15
16
  scheduled_delimiter(false),
17
+ scheduled_mapping(0),
16
18
  in_comment(false),
17
19
  in_wrapped(false),
18
20
  in_media_block(false),
19
21
  in_declaration(false),
20
22
  in_space_array(false),
21
- in_comma_array(false),
22
- in_debug(false)
23
+ in_comma_array(false)
23
24
  { }
24
25
 
25
26
  // return buffer as string
@@ -28,9 +29,9 @@ namespace Sass {
28
29
  return wbuf.buffer;
29
30
  }
30
31
 
31
- Sass_Output_Style Emitter::output_style(void)
32
+ Sass_Output_Style Emitter::output_style(void) const
32
33
  {
33
- return ctx ? ctx->output_style() : SASS_STYLE_COMPRESSED;
34
+ return opt.output_style;
34
35
  }
35
36
 
36
37
  // PROXY METHODS FOR SOURCE MAPS
@@ -44,9 +45,11 @@ namespace Sass {
44
45
  void Emitter::set_filename(const std::string& str)
45
46
  { wbuf.smap.file = str; }
46
47
 
47
- void Emitter::add_open_mapping(AST_Node* node)
48
+ void Emitter::schedule_mapping(const AST_Node* node)
49
+ { scheduled_mapping = node; }
50
+ void Emitter::add_open_mapping(const AST_Node* node)
48
51
  { wbuf.smap.add_open_mapping(node); }
49
- void Emitter::add_close_mapping(AST_Node* node)
52
+ void Emitter::add_close_mapping(const AST_Node* node)
50
53
  { wbuf.smap.add_close_mapping(node); }
51
54
  ParserState Emitter::remap(const ParserState& pstate)
52
55
  { return wbuf.smap.remap(pstate); }
@@ -54,9 +57,11 @@ namespace Sass {
54
57
  // MAIN BUFFER MANIPULATION
55
58
 
56
59
  // add outstanding delimiter
57
- void Emitter::finalize(void)
60
+ void Emitter::finalize(bool final)
58
61
  {
59
62
  scheduled_space = 0;
63
+ if (output_style() == SASS_STYLE_COMPRESSED)
64
+ if (final) scheduled_delimiter = false;
60
65
  if (scheduled_linefeed)
61
66
  scheduled_linefeed = 1;
62
67
  flush_schedules();
@@ -70,7 +75,7 @@ namespace Sass {
70
75
  std::string linefeeds = "";
71
76
 
72
77
  for (size_t i = 0; i < scheduled_linefeed; i++)
73
- linefeeds += ctx ? ctx->linefeed : "\n";
78
+ linefeeds += opt.linefeed;
74
79
  scheduled_space = 0;
75
80
  scheduled_linefeed = 0;
76
81
  append_string(linefeeds);
@@ -103,10 +108,11 @@ namespace Sass {
103
108
  // append some text or token to the buffer
104
109
  void Emitter::append_string(const std::string& text)
105
110
  {
111
+
106
112
  // write space/lf
107
113
  flush_schedules();
108
114
 
109
- if (in_comment && output_style() == SASS_STYLE_COMPACT) {
115
+ if (in_comment && output_style() == COMPACT) {
110
116
  // unescape comment nodes
111
117
  std::string out = comment_to_string(text);
112
118
  // add to buffer
@@ -133,10 +139,16 @@ namespace Sass {
133
139
 
134
140
  // append some text or token to the buffer
135
141
  // this adds source-mappings for node start and end
136
- void Emitter::append_token(const std::string& text, AST_Node* node)
142
+ void Emitter::append_token(const std::string& text, const AST_Node* node)
137
143
  {
138
144
  flush_schedules();
139
145
  add_open_mapping(node);
146
+ // hotfix for browser issues
147
+ // this is pretty ugly indeed
148
+ if (scheduled_mapping) {
149
+ add_open_mapping(scheduled_mapping);
150
+ scheduled_mapping = 0;
151
+ }
140
152
  append_string(text);
141
153
  add_close_mapping(node);
142
154
  }
@@ -145,27 +157,27 @@ namespace Sass {
145
157
 
146
158
  void Emitter::append_indentation()
147
159
  {
148
- if (output_style() == SASS_STYLE_COMPRESSED) return;
149
- if (output_style() == SASS_STYLE_COMPACT) return;
160
+ if (output_style() == COMPRESSED) return;
161
+ if (output_style() == COMPACT) return;
150
162
  if (in_declaration && in_comma_array) return;
151
163
  if (scheduled_linefeed && indentation)
152
164
  scheduled_linefeed = 1;
153
165
  std::string indent = "";
154
166
  for (size_t i = 0; i < indentation; i++)
155
- indent += ctx ? ctx->indent : " ";
167
+ indent += opt.indent;
156
168
  append_string(indent);
157
169
  }
158
170
 
159
171
  void Emitter::append_delimiter()
160
172
  {
161
173
  scheduled_delimiter = true;
162
- if (output_style() == SASS_STYLE_COMPACT) {
174
+ if (output_style() == COMPACT) {
163
175
  if (indentation == 0) {
164
176
  append_mandatory_linefeed();
165
177
  } else {
166
178
  append_mandatory_space();
167
179
  }
168
- } else if (output_style() != SASS_STYLE_COMPRESSED) {
180
+ } else if (output_style() != COMPRESSED) {
169
181
  append_optional_linefeed();
170
182
  }
171
183
  }
@@ -191,7 +203,7 @@ namespace Sass {
191
203
 
192
204
  void Emitter::append_optional_space()
193
205
  {
194
- if ((output_style() != SASS_STYLE_COMPRESSED || in_debug) && buffer().size()) {
206
+ if ((output_style() != COMPRESSED) && buffer().size()) {
195
207
  char lst = buffer().at(buffer().length() - 1);
196
208
  if (!isspace(lst) || scheduled_delimiter) {
197
209
  append_mandatory_space();
@@ -201,17 +213,17 @@ namespace Sass {
201
213
 
202
214
  void Emitter::append_special_linefeed()
203
215
  {
204
- if (output_style() == SASS_STYLE_COMPACT) {
216
+ if (output_style() == COMPACT) {
205
217
  append_mandatory_linefeed();
206
218
  for (size_t p = 0; p < indentation; p++)
207
- append_string(ctx ? ctx->indent : " ");
219
+ append_string(opt.indent);
208
220
  }
209
221
  }
210
222
 
211
223
  void Emitter::append_optional_linefeed()
212
224
  {
213
225
  if (in_declaration && in_comma_array) return;
214
- if (output_style() == SASS_STYLE_COMPACT) {
226
+ if (output_style() == COMPACT) {
215
227
  append_mandatory_space();
216
228
  } else {
217
229
  append_mandatory_linefeed();
@@ -220,7 +232,7 @@ namespace Sass {
220
232
 
221
233
  void Emitter::append_mandatory_linefeed()
222
234
  {
223
- if (output_style() != SASS_STYLE_COMPRESSED) {
235
+ if (output_style() != COMPRESSED) {
224
236
  scheduled_linefeed = 1;
225
237
  scheduled_space = 0;
226
238
  // flush_schedules();
@@ -242,9 +254,9 @@ namespace Sass {
242
254
  {
243
255
  -- indentation;
244
256
  scheduled_linefeed = 0;
245
- if (output_style() == SASS_STYLE_COMPRESSED)
257
+ if (output_style() == COMPRESSED)
246
258
  scheduled_delimiter = false;
247
- if (output_style() == SASS_STYLE_EXPANDED) {
259
+ if (output_style() == EXPANDED) {
248
260
  append_optional_linefeed();
249
261
  append_indentation();
250
262
  } else {
@@ -254,7 +266,7 @@ namespace Sass {
254
266
  if (node) add_close_mapping(node);
255
267
  append_optional_linefeed();
256
268
  if (indentation != 0) return;
257
- if (output_style() != SASS_STYLE_COMPRESSED)
269
+ if (output_style() != COMPRESSED)
258
270
  scheduled_linefeed = 2;
259
271
  }
260
272