sassc 1.8.3 → 1.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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