sassc4 2.4.0
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.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.gitmodules +3 -0
- data/.travis.yml +16 -0
- data/CHANGELOG.md +97 -0
- data/CODE_OF_CONDUCT.md +10 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +22 -0
- data/README.md +80 -0
- data/Rakefile +51 -0
- data/ext/depend +4 -0
- data/ext/extconf.rb +92 -0
- data/ext/libsass/VERSION +1 -0
- data/ext/libsass/contrib/plugin.cpp +60 -0
- data/ext/libsass/include/sass/base.h +97 -0
- data/ext/libsass/include/sass/context.h +174 -0
- data/ext/libsass/include/sass/functions.h +139 -0
- data/ext/libsass/include/sass/values.h +145 -0
- data/ext/libsass/include/sass/version.h +12 -0
- data/ext/libsass/include/sass.h +15 -0
- data/ext/libsass/include/sass2scss.h +120 -0
- data/ext/libsass/src/MurmurHash2.hpp +91 -0
- data/ext/libsass/src/ast.cpp +953 -0
- data/ext/libsass/src/ast.hpp +1064 -0
- data/ext/libsass/src/ast2c.cpp +80 -0
- data/ext/libsass/src/ast2c.hpp +39 -0
- data/ext/libsass/src/ast_def_macros.hpp +140 -0
- data/ext/libsass/src/ast_fwd_decl.cpp +31 -0
- data/ext/libsass/src/ast_fwd_decl.hpp +274 -0
- data/ext/libsass/src/ast_helpers.hpp +316 -0
- data/ext/libsass/src/ast_sel_cmp.cpp +396 -0
- data/ext/libsass/src/ast_sel_super.cpp +539 -0
- data/ext/libsass/src/ast_sel_unify.cpp +275 -0
- data/ext/libsass/src/ast_sel_weave.cpp +616 -0
- data/ext/libsass/src/ast_selectors.cpp +1070 -0
- data/ext/libsass/src/ast_selectors.hpp +523 -0
- data/ext/libsass/src/ast_supports.cpp +114 -0
- data/ext/libsass/src/ast_supports.hpp +121 -0
- data/ext/libsass/src/ast_values.cpp +1154 -0
- data/ext/libsass/src/ast_values.hpp +498 -0
- data/ext/libsass/src/b64/cencode.h +32 -0
- data/ext/libsass/src/b64/encode.h +79 -0
- data/ext/libsass/src/backtrace.cpp +50 -0
- data/ext/libsass/src/backtrace.hpp +29 -0
- data/ext/libsass/src/base64vlq.cpp +47 -0
- data/ext/libsass/src/base64vlq.hpp +30 -0
- data/ext/libsass/src/bind.cpp +312 -0
- data/ext/libsass/src/bind.hpp +15 -0
- data/ext/libsass/src/c2ast.cpp +64 -0
- data/ext/libsass/src/c2ast.hpp +14 -0
- data/ext/libsass/src/c99func.c +54 -0
- data/ext/libsass/src/cencode.c +106 -0
- data/ext/libsass/src/check_nesting.cpp +393 -0
- data/ext/libsass/src/check_nesting.hpp +70 -0
- data/ext/libsass/src/color_maps.cpp +652 -0
- data/ext/libsass/src/color_maps.hpp +323 -0
- data/ext/libsass/src/color_spaces.cpp +241 -0
- data/ext/libsass/src/color_spaces.hpp +227 -0
- data/ext/libsass/src/constants.cpp +199 -0
- data/ext/libsass/src/constants.hpp +200 -0
- data/ext/libsass/src/context.cpp +870 -0
- data/ext/libsass/src/context.hpp +140 -0
- data/ext/libsass/src/cssize.cpp +521 -0
- data/ext/libsass/src/cssize.hpp +71 -0
- data/ext/libsass/src/dart_helpers.hpp +199 -0
- data/ext/libsass/src/debug.hpp +43 -0
- data/ext/libsass/src/debugger.hpp +964 -0
- data/ext/libsass/src/emitter.cpp +297 -0
- data/ext/libsass/src/emitter.hpp +101 -0
- data/ext/libsass/src/environment.cpp +260 -0
- data/ext/libsass/src/environment.hpp +124 -0
- data/ext/libsass/src/error_handling.cpp +239 -0
- data/ext/libsass/src/error_handling.hpp +248 -0
- data/ext/libsass/src/eval.cpp +1543 -0
- data/ext/libsass/src/eval.hpp +110 -0
- data/ext/libsass/src/eval_selectors.cpp +75 -0
- data/ext/libsass/src/expand.cpp +875 -0
- data/ext/libsass/src/expand.hpp +98 -0
- data/ext/libsass/src/extender.cpp +1226 -0
- data/ext/libsass/src/extender.hpp +399 -0
- data/ext/libsass/src/extension.cpp +43 -0
- data/ext/libsass/src/extension.hpp +89 -0
- data/ext/libsass/src/file.cpp +531 -0
- data/ext/libsass/src/file.hpp +124 -0
- data/ext/libsass/src/fn_colors.cpp +836 -0
- data/ext/libsass/src/fn_colors.hpp +99 -0
- data/ext/libsass/src/fn_lists.cpp +285 -0
- data/ext/libsass/src/fn_lists.hpp +34 -0
- data/ext/libsass/src/fn_maps.cpp +94 -0
- data/ext/libsass/src/fn_maps.hpp +30 -0
- data/ext/libsass/src/fn_miscs.cpp +248 -0
- data/ext/libsass/src/fn_miscs.hpp +40 -0
- data/ext/libsass/src/fn_numbers.cpp +246 -0
- data/ext/libsass/src/fn_numbers.hpp +45 -0
- data/ext/libsass/src/fn_selectors.cpp +205 -0
- data/ext/libsass/src/fn_selectors.hpp +35 -0
- data/ext/libsass/src/fn_strings.cpp +268 -0
- data/ext/libsass/src/fn_strings.hpp +34 -0
- data/ext/libsass/src/fn_utils.cpp +159 -0
- data/ext/libsass/src/fn_utils.hpp +62 -0
- data/ext/libsass/src/inspect.cpp +1126 -0
- data/ext/libsass/src/inspect.hpp +101 -0
- data/ext/libsass/src/json.cpp +1436 -0
- data/ext/libsass/src/json.hpp +117 -0
- data/ext/libsass/src/kwd_arg_macros.hpp +28 -0
- data/ext/libsass/src/lexer.cpp +122 -0
- data/ext/libsass/src/lexer.hpp +304 -0
- data/ext/libsass/src/listize.cpp +70 -0
- data/ext/libsass/src/listize.hpp +37 -0
- data/ext/libsass/src/mapping.hpp +19 -0
- data/ext/libsass/src/memory/allocator.cpp +48 -0
- data/ext/libsass/src/memory/allocator.hpp +138 -0
- data/ext/libsass/src/memory/config.hpp +20 -0
- data/ext/libsass/src/memory/memory_pool.hpp +186 -0
- data/ext/libsass/src/memory/shared_ptr.cpp +33 -0
- data/ext/libsass/src/memory/shared_ptr.hpp +332 -0
- data/ext/libsass/src/memory.hpp +12 -0
- data/ext/libsass/src/operation.hpp +223 -0
- data/ext/libsass/src/operators.cpp +267 -0
- data/ext/libsass/src/operators.hpp +30 -0
- data/ext/libsass/src/ordered_map.hpp +112 -0
- data/ext/libsass/src/output.cpp +320 -0
- data/ext/libsass/src/output.hpp +47 -0
- data/ext/libsass/src/parser.cpp +3059 -0
- data/ext/libsass/src/parser.hpp +395 -0
- data/ext/libsass/src/parser_selectors.cpp +189 -0
- data/ext/libsass/src/permutate.hpp +164 -0
- data/ext/libsass/src/plugins.cpp +188 -0
- data/ext/libsass/src/plugins.hpp +57 -0
- data/ext/libsass/src/position.cpp +163 -0
- data/ext/libsass/src/position.hpp +147 -0
- data/ext/libsass/src/prelexer.cpp +1780 -0
- data/ext/libsass/src/prelexer.hpp +484 -0
- data/ext/libsass/src/remove_placeholders.cpp +86 -0
- data/ext/libsass/src/remove_placeholders.hpp +37 -0
- data/ext/libsass/src/sass.cpp +156 -0
- data/ext/libsass/src/sass.hpp +147 -0
- data/ext/libsass/src/sass2scss.cpp +895 -0
- data/ext/libsass/src/sass_context.cpp +742 -0
- data/ext/libsass/src/sass_context.hpp +129 -0
- data/ext/libsass/src/sass_functions.cpp +210 -0
- data/ext/libsass/src/sass_functions.hpp +50 -0
- data/ext/libsass/src/sass_values.cpp +362 -0
- data/ext/libsass/src/sass_values.hpp +82 -0
- data/ext/libsass/src/settings.hpp +19 -0
- data/ext/libsass/src/source.cpp +69 -0
- data/ext/libsass/src/source.hpp +95 -0
- data/ext/libsass/src/source_data.hpp +32 -0
- data/ext/libsass/src/source_map.cpp +202 -0
- data/ext/libsass/src/source_map.hpp +65 -0
- data/ext/libsass/src/stylesheet.cpp +22 -0
- data/ext/libsass/src/stylesheet.hpp +57 -0
- data/ext/libsass/src/to_value.cpp +114 -0
- data/ext/libsass/src/to_value.hpp +46 -0
- data/ext/libsass/src/units.cpp +507 -0
- data/ext/libsass/src/units.hpp +110 -0
- data/ext/libsass/src/utf8/checked.h +336 -0
- data/ext/libsass/src/utf8/core.h +332 -0
- data/ext/libsass/src/utf8/unchecked.h +235 -0
- data/ext/libsass/src/utf8.h +34 -0
- data/ext/libsass/src/utf8_string.cpp +104 -0
- data/ext/libsass/src/utf8_string.hpp +38 -0
- data/ext/libsass/src/util.cpp +723 -0
- data/ext/libsass/src/util.hpp +105 -0
- data/ext/libsass/src/util_string.cpp +125 -0
- data/ext/libsass/src/util_string.hpp +73 -0
- data/ext/libsass/src/values.cpp +140 -0
- data/ext/libsass/src/values.hpp +12 -0
- data/lib/sassc/dependency.rb +17 -0
- data/lib/sassc/engine.rb +141 -0
- data/lib/sassc/error.rb +37 -0
- data/lib/sassc/functions_handler.rb +73 -0
- data/lib/sassc/import_handler.rb +50 -0
- data/lib/sassc/importer.rb +31 -0
- data/lib/sassc/native/native_context_api.rb +147 -0
- data/lib/sassc/native/native_functions_api.rb +159 -0
- data/lib/sassc/native/sass2scss_api.rb +10 -0
- data/lib/sassc/native/sass_input_style.rb +13 -0
- data/lib/sassc/native/sass_output_style.rb +12 -0
- data/lib/sassc/native/sass_value.rb +97 -0
- data/lib/sassc/native/string_list.rb +10 -0
- data/lib/sassc/native.rb +64 -0
- data/lib/sassc/sass_2_scss.rb +9 -0
- data/lib/sassc/script/functions.rb +8 -0
- data/lib/sassc/script/value/bool.rb +32 -0
- data/lib/sassc/script/value/color.rb +95 -0
- data/lib/sassc/script/value/list.rb +136 -0
- data/lib/sassc/script/value/map.rb +69 -0
- data/lib/sassc/script/value/number.rb +389 -0
- data/lib/sassc/script/value/string.rb +96 -0
- data/lib/sassc/script/value.rb +137 -0
- data/lib/sassc/script/value_conversion/base.rb +13 -0
- data/lib/sassc/script/value_conversion/bool.rb +13 -0
- data/lib/sassc/script/value_conversion/color.rb +18 -0
- data/lib/sassc/script/value_conversion/list.rb +25 -0
- data/lib/sassc/script/value_conversion/map.rb +21 -0
- data/lib/sassc/script/value_conversion/number.rb +13 -0
- data/lib/sassc/script/value_conversion/string.rb +17 -0
- data/lib/sassc/script/value_conversion.rb +69 -0
- data/lib/sassc/script.rb +17 -0
- data/lib/sassc/util/normalized_map.rb +117 -0
- data/lib/sassc/util.rb +231 -0
- data/lib/sassc/version.rb +5 -0
- data/lib/sassc.rb +57 -0
- data/sassc.gemspec +69 -0
- data/test/css_color_level4_test.rb +168 -0
- data/test/custom_importer_test.rb +127 -0
- data/test/engine_test.rb +314 -0
- data/test/error_test.rb +29 -0
- data/test/fixtures/paths.scss +10 -0
- data/test/functions_test.rb +340 -0
- data/test/native_test.rb +213 -0
- data/test/output_style_test.rb +107 -0
- data/test/sass_2_scss_test.rb +14 -0
- data/test/test_helper.rb +45 -0
- metadata +396 -0
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
// sass.hpp must go before all system headers to get the
|
|
2
|
+
// __EXTENSIONS__ fix on Solaris.
|
|
3
|
+
#include "sass.hpp"
|
|
4
|
+
#include "emitter.hpp"
|
|
5
|
+
#include "util_string.hpp"
|
|
6
|
+
#include "util.hpp"
|
|
7
|
+
|
|
8
|
+
namespace Sass {
|
|
9
|
+
|
|
10
|
+
Emitter::Emitter(struct Sass_Output_Options& opt)
|
|
11
|
+
: wbuf(),
|
|
12
|
+
opt(opt),
|
|
13
|
+
indentation(0),
|
|
14
|
+
scheduled_space(0),
|
|
15
|
+
scheduled_linefeed(0),
|
|
16
|
+
scheduled_delimiter(false),
|
|
17
|
+
scheduled_crutch(0),
|
|
18
|
+
scheduled_mapping(0),
|
|
19
|
+
in_custom_property(false),
|
|
20
|
+
in_comment(false),
|
|
21
|
+
in_wrapped(false),
|
|
22
|
+
in_media_block(false),
|
|
23
|
+
in_declaration(false),
|
|
24
|
+
in_space_array(false),
|
|
25
|
+
in_comma_array(false)
|
|
26
|
+
{ }
|
|
27
|
+
|
|
28
|
+
// return buffer as string
|
|
29
|
+
sass::string Emitter::get_buffer(void)
|
|
30
|
+
{
|
|
31
|
+
return wbuf.buffer;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
Sass_Output_Style Emitter::output_style(void) const
|
|
35
|
+
{
|
|
36
|
+
return opt.output_style;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// PROXY METHODS FOR SOURCE MAPS
|
|
40
|
+
|
|
41
|
+
void Emitter::add_source_index(size_t idx)
|
|
42
|
+
{ wbuf.smap.source_index.push_back(idx); }
|
|
43
|
+
|
|
44
|
+
sass::string Emitter::render_srcmap(Context &ctx)
|
|
45
|
+
{ return wbuf.smap.render_srcmap(ctx); }
|
|
46
|
+
|
|
47
|
+
void Emitter::set_filename(const sass::string& str)
|
|
48
|
+
{ wbuf.smap.file = str; }
|
|
49
|
+
|
|
50
|
+
void Emitter::schedule_mapping(const AST_Node* node)
|
|
51
|
+
{ scheduled_mapping = node; }
|
|
52
|
+
void Emitter::add_open_mapping(const AST_Node* node)
|
|
53
|
+
{ wbuf.smap.add_open_mapping(node); }
|
|
54
|
+
void Emitter::add_close_mapping(const AST_Node* node)
|
|
55
|
+
{ wbuf.smap.add_close_mapping(node); }
|
|
56
|
+
SourceSpan Emitter::remap(const SourceSpan& pstate)
|
|
57
|
+
{ return wbuf.smap.remap(pstate); }
|
|
58
|
+
|
|
59
|
+
// MAIN BUFFER MANIPULATION
|
|
60
|
+
|
|
61
|
+
// add outstanding delimiter
|
|
62
|
+
void Emitter::finalize(bool final)
|
|
63
|
+
{
|
|
64
|
+
scheduled_space = 0;
|
|
65
|
+
if (output_style() == SASS_STYLE_COMPRESSED)
|
|
66
|
+
if (final) scheduled_delimiter = false;
|
|
67
|
+
if (scheduled_linefeed)
|
|
68
|
+
scheduled_linefeed = 1;
|
|
69
|
+
flush_schedules();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// flush scheduled space/linefeed
|
|
73
|
+
void Emitter::flush_schedules(void)
|
|
74
|
+
{
|
|
75
|
+
// check the schedule
|
|
76
|
+
if (scheduled_linefeed) {
|
|
77
|
+
sass::string linefeeds = "";
|
|
78
|
+
|
|
79
|
+
for (size_t i = 0; i < scheduled_linefeed; i++)
|
|
80
|
+
linefeeds += opt.linefeed;
|
|
81
|
+
scheduled_space = 0;
|
|
82
|
+
scheduled_linefeed = 0;
|
|
83
|
+
append_string(linefeeds);
|
|
84
|
+
|
|
85
|
+
} else if (scheduled_space) {
|
|
86
|
+
sass::string spaces(scheduled_space, ' ');
|
|
87
|
+
scheduled_space = 0;
|
|
88
|
+
append_string(spaces);
|
|
89
|
+
}
|
|
90
|
+
if (scheduled_delimiter) {
|
|
91
|
+
scheduled_delimiter = false;
|
|
92
|
+
append_string(";");
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// prepend some text or token to the buffer
|
|
97
|
+
void Emitter::prepend_output(const OutputBuffer& output)
|
|
98
|
+
{
|
|
99
|
+
wbuf.smap.prepend(output);
|
|
100
|
+
wbuf.buffer = output.buffer + wbuf.buffer;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// prepend some text or token to the buffer
|
|
104
|
+
void Emitter::prepend_string(const sass::string& text)
|
|
105
|
+
{
|
|
106
|
+
// do not adjust mappings for utf8 bom
|
|
107
|
+
// seems they are not counted in any UA
|
|
108
|
+
if (text.compare("\xEF\xBB\xBF") != 0) {
|
|
109
|
+
wbuf.smap.prepend(Offset(text));
|
|
110
|
+
}
|
|
111
|
+
wbuf.buffer = text + wbuf.buffer;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
char Emitter::last_char()
|
|
115
|
+
{
|
|
116
|
+
return wbuf.buffer.back();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// append a single char to the buffer
|
|
120
|
+
void Emitter::append_char(const char chr)
|
|
121
|
+
{
|
|
122
|
+
// write space/lf
|
|
123
|
+
flush_schedules();
|
|
124
|
+
// add to buffer
|
|
125
|
+
wbuf.buffer += chr;
|
|
126
|
+
// account for data in source-maps
|
|
127
|
+
wbuf.smap.append(Offset(chr));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// append some text or token to the buffer
|
|
131
|
+
void Emitter::append_string(const sass::string& text)
|
|
132
|
+
{
|
|
133
|
+
|
|
134
|
+
// write space/lf
|
|
135
|
+
flush_schedules();
|
|
136
|
+
|
|
137
|
+
if (in_comment) {
|
|
138
|
+
sass::string out = Util::normalize_newlines(text);
|
|
139
|
+
if (output_style() == COMPACT) {
|
|
140
|
+
out = comment_to_compact_string(out);
|
|
141
|
+
}
|
|
142
|
+
wbuf.smap.append(Offset(out));
|
|
143
|
+
wbuf.buffer += std::move(out);
|
|
144
|
+
} else {
|
|
145
|
+
// add to buffer
|
|
146
|
+
wbuf.buffer += text;
|
|
147
|
+
// account for data in source-maps
|
|
148
|
+
wbuf.smap.append(Offset(text));
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// append some white-space only text
|
|
153
|
+
void Emitter::append_wspace(const sass::string& text)
|
|
154
|
+
{
|
|
155
|
+
if (text.empty()) return;
|
|
156
|
+
if (peek_linefeed(text.c_str())) {
|
|
157
|
+
scheduled_space = 0;
|
|
158
|
+
append_mandatory_linefeed();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// append some text or token to the buffer
|
|
163
|
+
// this adds source-mappings for node start and end
|
|
164
|
+
void Emitter::append_token(const sass::string& text, const AST_Node* node)
|
|
165
|
+
{
|
|
166
|
+
flush_schedules();
|
|
167
|
+
add_open_mapping(node);
|
|
168
|
+
// hotfix for browser issues
|
|
169
|
+
// this is pretty ugly indeed
|
|
170
|
+
if (scheduled_crutch) {
|
|
171
|
+
add_open_mapping(scheduled_crutch);
|
|
172
|
+
scheduled_crutch = 0;
|
|
173
|
+
}
|
|
174
|
+
append_string(text);
|
|
175
|
+
add_close_mapping(node);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// HELPER METHODS
|
|
179
|
+
|
|
180
|
+
void Emitter::append_indentation()
|
|
181
|
+
{
|
|
182
|
+
if (output_style() == COMPRESSED) return;
|
|
183
|
+
if (output_style() == COMPACT) return;
|
|
184
|
+
if (in_declaration && in_comma_array) return;
|
|
185
|
+
if (scheduled_linefeed && indentation)
|
|
186
|
+
scheduled_linefeed = 1;
|
|
187
|
+
sass::string indent = "";
|
|
188
|
+
for (size_t i = 0; i < indentation; i++)
|
|
189
|
+
indent += opt.indent;
|
|
190
|
+
append_string(indent);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
void Emitter::append_delimiter()
|
|
194
|
+
{
|
|
195
|
+
scheduled_delimiter = true;
|
|
196
|
+
if (output_style() == COMPACT) {
|
|
197
|
+
if (indentation == 0) {
|
|
198
|
+
append_mandatory_linefeed();
|
|
199
|
+
} else {
|
|
200
|
+
append_mandatory_space();
|
|
201
|
+
}
|
|
202
|
+
} else if (output_style() != COMPRESSED) {
|
|
203
|
+
append_optional_linefeed();
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
void Emitter::append_comma_separator()
|
|
208
|
+
{
|
|
209
|
+
// scheduled_space = 0;
|
|
210
|
+
append_string(",");
|
|
211
|
+
append_optional_space();
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
void Emitter::append_colon_separator()
|
|
215
|
+
{
|
|
216
|
+
scheduled_space = 0;
|
|
217
|
+
append_string(":");
|
|
218
|
+
if (!in_custom_property) append_optional_space();
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
void Emitter::append_mandatory_space()
|
|
222
|
+
{
|
|
223
|
+
scheduled_space = 1;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
void Emitter::append_optional_space()
|
|
227
|
+
{
|
|
228
|
+
if ((output_style() != COMPRESSED) && buffer().size()) {
|
|
229
|
+
unsigned char lst = buffer().at(buffer().length() - 1);
|
|
230
|
+
if (!isspace(lst) || scheduled_delimiter) {
|
|
231
|
+
if (last_char() != '(') {
|
|
232
|
+
append_mandatory_space();
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
void Emitter::append_special_linefeed()
|
|
239
|
+
{
|
|
240
|
+
if (output_style() == COMPACT) {
|
|
241
|
+
append_mandatory_linefeed();
|
|
242
|
+
for (size_t p = 0; p < indentation; p++)
|
|
243
|
+
append_string(opt.indent);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
void Emitter::append_optional_linefeed()
|
|
248
|
+
{
|
|
249
|
+
if (in_declaration && in_comma_array) return;
|
|
250
|
+
if (output_style() == COMPACT) {
|
|
251
|
+
append_mandatory_space();
|
|
252
|
+
} else {
|
|
253
|
+
append_mandatory_linefeed();
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
void Emitter::append_mandatory_linefeed()
|
|
258
|
+
{
|
|
259
|
+
if (output_style() != COMPRESSED) {
|
|
260
|
+
scheduled_linefeed = 1;
|
|
261
|
+
scheduled_space = 0;
|
|
262
|
+
// flush_schedules();
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
void Emitter::append_scope_opener(AST_Node* node)
|
|
267
|
+
{
|
|
268
|
+
scheduled_linefeed = 0;
|
|
269
|
+
append_optional_space();
|
|
270
|
+
flush_schedules();
|
|
271
|
+
if (node) add_open_mapping(node);
|
|
272
|
+
append_string("{");
|
|
273
|
+
append_optional_linefeed();
|
|
274
|
+
// append_optional_space();
|
|
275
|
+
++ indentation;
|
|
276
|
+
}
|
|
277
|
+
void Emitter::append_scope_closer(AST_Node* node)
|
|
278
|
+
{
|
|
279
|
+
-- indentation;
|
|
280
|
+
scheduled_linefeed = 0;
|
|
281
|
+
if (output_style() == COMPRESSED)
|
|
282
|
+
scheduled_delimiter = false;
|
|
283
|
+
if (output_style() == EXPANDED) {
|
|
284
|
+
append_optional_linefeed();
|
|
285
|
+
append_indentation();
|
|
286
|
+
} else {
|
|
287
|
+
append_optional_space();
|
|
288
|
+
}
|
|
289
|
+
append_string("}");
|
|
290
|
+
if (node) add_close_mapping(node);
|
|
291
|
+
append_optional_linefeed();
|
|
292
|
+
if (indentation != 0) return;
|
|
293
|
+
if (output_style() != COMPRESSED)
|
|
294
|
+
scheduled_linefeed = 2;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
#ifndef SASS_EMITTER_H
|
|
2
|
+
#define SASS_EMITTER_H
|
|
3
|
+
|
|
4
|
+
// sass.hpp must go before all system headers to get the
|
|
5
|
+
// __EXTENSIONS__ fix on Solaris.
|
|
6
|
+
#include "sass.hpp"
|
|
7
|
+
|
|
8
|
+
#include "sass/base.h"
|
|
9
|
+
#include "source_map.hpp"
|
|
10
|
+
#include "ast_fwd_decl.hpp"
|
|
11
|
+
|
|
12
|
+
namespace Sass {
|
|
13
|
+
class Context;
|
|
14
|
+
|
|
15
|
+
class Emitter {
|
|
16
|
+
|
|
17
|
+
public:
|
|
18
|
+
Emitter(struct Sass_Output_Options& opt);
|
|
19
|
+
virtual ~Emitter() { }
|
|
20
|
+
|
|
21
|
+
protected:
|
|
22
|
+
OutputBuffer wbuf;
|
|
23
|
+
public:
|
|
24
|
+
const sass::string& buffer(void) { return wbuf.buffer; }
|
|
25
|
+
const SourceMap smap(void) { return wbuf.smap; }
|
|
26
|
+
const OutputBuffer output(void) { return wbuf; }
|
|
27
|
+
// proxy methods for source maps
|
|
28
|
+
void add_source_index(size_t idx);
|
|
29
|
+
void set_filename(const sass::string& str);
|
|
30
|
+
void add_open_mapping(const AST_Node* node);
|
|
31
|
+
void add_close_mapping(const AST_Node* node);
|
|
32
|
+
void schedule_mapping(const AST_Node* node);
|
|
33
|
+
sass::string render_srcmap(Context &ctx);
|
|
34
|
+
SourceSpan remap(const SourceSpan& pstate);
|
|
35
|
+
|
|
36
|
+
public:
|
|
37
|
+
struct Sass_Output_Options& opt;
|
|
38
|
+
size_t indentation;
|
|
39
|
+
size_t scheduled_space;
|
|
40
|
+
size_t scheduled_linefeed;
|
|
41
|
+
bool scheduled_delimiter;
|
|
42
|
+
const AST_Node* scheduled_crutch;
|
|
43
|
+
const AST_Node* scheduled_mapping;
|
|
44
|
+
|
|
45
|
+
public:
|
|
46
|
+
// output strings different in custom css properties
|
|
47
|
+
bool in_custom_property;
|
|
48
|
+
// output strings different in comments
|
|
49
|
+
bool in_comment;
|
|
50
|
+
// selector list does not get linefeeds
|
|
51
|
+
bool in_wrapped;
|
|
52
|
+
// lists always get a space after delimiter
|
|
53
|
+
bool in_media_block;
|
|
54
|
+
// nested list must not have parentheses
|
|
55
|
+
bool in_declaration;
|
|
56
|
+
// nested lists need parentheses
|
|
57
|
+
bool in_space_array;
|
|
58
|
+
bool in_comma_array;
|
|
59
|
+
|
|
60
|
+
public:
|
|
61
|
+
// return buffer as sass::string
|
|
62
|
+
sass::string get_buffer(void);
|
|
63
|
+
// flush scheduled space/linefeed
|
|
64
|
+
Sass_Output_Style output_style(void) const;
|
|
65
|
+
// add outstanding linefeed
|
|
66
|
+
void finalize(bool final = true);
|
|
67
|
+
// flush scheduled space/linefeed
|
|
68
|
+
void flush_schedules(void);
|
|
69
|
+
// prepend some text or token to the buffer
|
|
70
|
+
void prepend_string(const sass::string& text);
|
|
71
|
+
void prepend_output(const OutputBuffer& out);
|
|
72
|
+
// append some text or token to the buffer
|
|
73
|
+
void append_string(const sass::string& text);
|
|
74
|
+
// append a single character to buffer
|
|
75
|
+
void append_char(const char chr);
|
|
76
|
+
// append some white-space only text
|
|
77
|
+
void append_wspace(const sass::string& text);
|
|
78
|
+
// append some text or token to the buffer
|
|
79
|
+
// this adds source-mappings for node start and end
|
|
80
|
+
void append_token(const sass::string& text, const AST_Node* node);
|
|
81
|
+
// query last appended character
|
|
82
|
+
char last_char();
|
|
83
|
+
|
|
84
|
+
public: // syntax sugar
|
|
85
|
+
void append_indentation();
|
|
86
|
+
void append_optional_space(void);
|
|
87
|
+
void append_mandatory_space(void);
|
|
88
|
+
void append_special_linefeed(void);
|
|
89
|
+
void append_optional_linefeed(void);
|
|
90
|
+
void append_mandatory_linefeed(void);
|
|
91
|
+
void append_scope_opener(AST_Node* node = 0);
|
|
92
|
+
void append_scope_closer(AST_Node* node = 0);
|
|
93
|
+
void append_comma_separator(void);
|
|
94
|
+
void append_colon_separator(void);
|
|
95
|
+
void append_delimiter(void);
|
|
96
|
+
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
#endif
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
#include "sass.hpp"
|
|
2
|
+
#include "ast.hpp"
|
|
3
|
+
#include "environment.hpp"
|
|
4
|
+
|
|
5
|
+
namespace Sass {
|
|
6
|
+
|
|
7
|
+
template <typename T>
|
|
8
|
+
Environment<T>::Environment(bool is_shadow)
|
|
9
|
+
: local_frame_(environment_map<sass::string, T>()),
|
|
10
|
+
parent_(0), is_shadow_(false)
|
|
11
|
+
{ }
|
|
12
|
+
template <typename T>
|
|
13
|
+
Environment<T>::Environment(Environment<T>* env, bool is_shadow)
|
|
14
|
+
: local_frame_(environment_map<sass::string, T>()),
|
|
15
|
+
parent_(env), is_shadow_(is_shadow)
|
|
16
|
+
{ }
|
|
17
|
+
template <typename T>
|
|
18
|
+
Environment<T>::Environment(Environment<T>& env, bool is_shadow)
|
|
19
|
+
: local_frame_(environment_map<sass::string, T>()),
|
|
20
|
+
parent_(&env), is_shadow_(is_shadow)
|
|
21
|
+
{ }
|
|
22
|
+
|
|
23
|
+
// link parent to create a stack
|
|
24
|
+
template <typename T>
|
|
25
|
+
void Environment<T>::link(Environment& env) { parent_ = &env; }
|
|
26
|
+
template <typename T>
|
|
27
|
+
void Environment<T>::link(Environment* env) { parent_ = env; }
|
|
28
|
+
|
|
29
|
+
// this is used to find the global frame
|
|
30
|
+
// which is the second last on the stack
|
|
31
|
+
template <typename T>
|
|
32
|
+
bool Environment<T>::is_lexical() const
|
|
33
|
+
{
|
|
34
|
+
return !! parent_ && parent_->parent_;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// only match the real root scope
|
|
38
|
+
// there is still a parent around
|
|
39
|
+
// not sure what it is actually use for
|
|
40
|
+
// I guess we store functions etc. there
|
|
41
|
+
template <typename T>
|
|
42
|
+
bool Environment<T>::is_global() const
|
|
43
|
+
{
|
|
44
|
+
return parent_ && ! parent_->parent_;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
template <typename T>
|
|
48
|
+
environment_map<sass::string, T>& Environment<T>::local_frame() {
|
|
49
|
+
return local_frame_;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
template <typename T>
|
|
53
|
+
bool Environment<T>::has_local(const sass::string& key) const
|
|
54
|
+
{ return local_frame_.find(key) != local_frame_.end(); }
|
|
55
|
+
|
|
56
|
+
template <typename T> EnvResult
|
|
57
|
+
Environment<T>::find_local(const sass::string& key)
|
|
58
|
+
{
|
|
59
|
+
auto end = local_frame_.end();
|
|
60
|
+
auto it = local_frame_.find(key);
|
|
61
|
+
return EnvResult(it, it != end);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
template <typename T>
|
|
65
|
+
T& Environment<T>::get_local(const sass::string& key)
|
|
66
|
+
{ return local_frame_[key]; }
|
|
67
|
+
|
|
68
|
+
template <typename T>
|
|
69
|
+
void Environment<T>::set_local(const sass::string& key, const T& val)
|
|
70
|
+
{
|
|
71
|
+
local_frame_[key] = val;
|
|
72
|
+
}
|
|
73
|
+
template <typename T>
|
|
74
|
+
void Environment<T>::set_local(const sass::string& key, T&& val)
|
|
75
|
+
{
|
|
76
|
+
local_frame_[key] = val;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
template <typename T>
|
|
80
|
+
void Environment<T>::del_local(const sass::string& key)
|
|
81
|
+
{ local_frame_.erase(key); }
|
|
82
|
+
|
|
83
|
+
template <typename T>
|
|
84
|
+
Environment<T>* Environment<T>::global_env()
|
|
85
|
+
{
|
|
86
|
+
Environment* cur = this;
|
|
87
|
+
while (cur->is_lexical()) {
|
|
88
|
+
cur = cur->parent_;
|
|
89
|
+
}
|
|
90
|
+
return cur;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
template <typename T>
|
|
94
|
+
bool Environment<T>::has_global(const sass::string& key)
|
|
95
|
+
{ return global_env()->has(key); }
|
|
96
|
+
|
|
97
|
+
template <typename T>
|
|
98
|
+
T& Environment<T>::get_global(const sass::string& key)
|
|
99
|
+
{ return (*global_env())[key]; }
|
|
100
|
+
|
|
101
|
+
template <typename T>
|
|
102
|
+
void Environment<T>::set_global(const sass::string& key, const T& val)
|
|
103
|
+
{
|
|
104
|
+
global_env()->local_frame_[key] = val;
|
|
105
|
+
}
|
|
106
|
+
template <typename T>
|
|
107
|
+
void Environment<T>::set_global(const sass::string& key, T&& val)
|
|
108
|
+
{
|
|
109
|
+
global_env()->local_frame_[key] = val;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
template <typename T>
|
|
113
|
+
void Environment<T>::del_global(const sass::string& key)
|
|
114
|
+
{ global_env()->local_frame_.erase(key); }
|
|
115
|
+
|
|
116
|
+
template <typename T>
|
|
117
|
+
Environment<T>* Environment<T>::lexical_env(const sass::string& key)
|
|
118
|
+
{
|
|
119
|
+
Environment* cur = this;
|
|
120
|
+
while (cur) {
|
|
121
|
+
if (cur->has_local(key)) {
|
|
122
|
+
return cur;
|
|
123
|
+
}
|
|
124
|
+
cur = cur->parent_;
|
|
125
|
+
}
|
|
126
|
+
return this;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// see if we have a lexical variable
|
|
130
|
+
// move down the stack but stop before we
|
|
131
|
+
// reach the global frame (is not included)
|
|
132
|
+
template <typename T>
|
|
133
|
+
bool Environment<T>::has_lexical(const sass::string& key) const
|
|
134
|
+
{
|
|
135
|
+
auto cur = this;
|
|
136
|
+
while (cur->is_lexical()) {
|
|
137
|
+
if (cur->has_local(key)) return true;
|
|
138
|
+
cur = cur->parent_;
|
|
139
|
+
}
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// see if we have a lexical we could update
|
|
144
|
+
// either update already existing lexical value
|
|
145
|
+
// or if flag is set, we create one if no lexical found
|
|
146
|
+
template <typename T>
|
|
147
|
+
void Environment<T>::set_lexical(const sass::string& key, const T& val)
|
|
148
|
+
{
|
|
149
|
+
Environment<T>* cur = this;
|
|
150
|
+
bool shadow = false;
|
|
151
|
+
while ((cur && cur->is_lexical()) || shadow) {
|
|
152
|
+
EnvResult rv(cur->find_local(key));
|
|
153
|
+
if (rv.found) {
|
|
154
|
+
rv.it->second = val;
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
shadow = cur->is_shadow();
|
|
158
|
+
cur = cur->parent_;
|
|
159
|
+
}
|
|
160
|
+
set_local(key, val);
|
|
161
|
+
}
|
|
162
|
+
// this one moves the value
|
|
163
|
+
template <typename T>
|
|
164
|
+
void Environment<T>::set_lexical(const sass::string& key, T&& val)
|
|
165
|
+
{
|
|
166
|
+
Environment<T>* cur = this;
|
|
167
|
+
bool shadow = false;
|
|
168
|
+
while ((cur && cur->is_lexical()) || shadow) {
|
|
169
|
+
EnvResult rv(cur->find_local(key));
|
|
170
|
+
if (rv.found) {
|
|
171
|
+
rv.it->second = val;
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
shadow = cur->is_shadow();
|
|
175
|
+
cur = cur->parent_;
|
|
176
|
+
}
|
|
177
|
+
set_local(key, val);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// look on the full stack for key
|
|
181
|
+
// include all scopes available
|
|
182
|
+
template <typename T>
|
|
183
|
+
bool Environment<T>::has(const sass::string& key) const
|
|
184
|
+
{
|
|
185
|
+
auto cur = this;
|
|
186
|
+
while (cur) {
|
|
187
|
+
if (cur->has_local(key)) {
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
190
|
+
cur = cur->parent_;
|
|
191
|
+
}
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// look on the full stack for key
|
|
196
|
+
// include all scopes available
|
|
197
|
+
template <typename T> EnvResult
|
|
198
|
+
Environment<T>::find(const sass::string& key)
|
|
199
|
+
{
|
|
200
|
+
auto cur = this;
|
|
201
|
+
while (true) {
|
|
202
|
+
EnvResult rv(cur->find_local(key));
|
|
203
|
+
if (rv.found) return rv;
|
|
204
|
+
cur = cur->parent_;
|
|
205
|
+
if (!cur) return rv;
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
// use array access for getter and setter functions
|
|
210
|
+
template <typename T>
|
|
211
|
+
T& Environment<T>::get(const sass::string& key)
|
|
212
|
+
{
|
|
213
|
+
auto cur = this;
|
|
214
|
+
while (cur) {
|
|
215
|
+
if (cur->has_local(key)) {
|
|
216
|
+
return cur->get_local(key);
|
|
217
|
+
}
|
|
218
|
+
cur = cur->parent_;
|
|
219
|
+
}
|
|
220
|
+
return get_local(key);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// use array access for getter and setter functions
|
|
224
|
+
template <typename T>
|
|
225
|
+
T& Environment<T>::operator[](const sass::string& key)
|
|
226
|
+
{
|
|
227
|
+
auto cur = this;
|
|
228
|
+
while (cur) {
|
|
229
|
+
if (cur->has_local(key)) {
|
|
230
|
+
return cur->get_local(key);
|
|
231
|
+
}
|
|
232
|
+
cur = cur->parent_;
|
|
233
|
+
}
|
|
234
|
+
return get_local(key);
|
|
235
|
+
}
|
|
236
|
+
/*
|
|
237
|
+
#ifdef DEBUG
|
|
238
|
+
template <typename T>
|
|
239
|
+
size_t Environment<T>::print(sass::string prefix)
|
|
240
|
+
{
|
|
241
|
+
size_t indent = 0;
|
|
242
|
+
if (parent_) indent = parent_->print(prefix) + 1;
|
|
243
|
+
std::cerr << prefix << sass::string(indent, ' ') << "== " << this << std::endl;
|
|
244
|
+
for (typename environment_map<sass::string, T>::iterator i = local_frame_.begin(); i != local_frame_.end(); ++i) {
|
|
245
|
+
if (!ends_with(i->first, "[f]") && !ends_with(i->first, "[f]4") && !ends_with(i->first, "[f]2")) {
|
|
246
|
+
std::cerr << prefix << sass::string(indent, ' ') << i->first << " " << i->second;
|
|
247
|
+
if (Value* val = Cast<Value>(i->second))
|
|
248
|
+
{ std::cerr << " : " << val->to_string(); }
|
|
249
|
+
std::cerr << std::endl;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return indent ;
|
|
253
|
+
}
|
|
254
|
+
#endif
|
|
255
|
+
*/
|
|
256
|
+
// compile implementation for AST_Node
|
|
257
|
+
template class Environment<AST_Node_Obj>;
|
|
258
|
+
|
|
259
|
+
}
|
|
260
|
+
|