|
Packit Service |
7770af |
#include "sass.hpp"
|
|
Packit Service |
7770af |
#include "util.hpp"
|
|
Packit Service |
7770af |
#include "context.hpp"
|
|
Packit Service |
7770af |
#include "output.hpp"
|
|
Packit Service |
7770af |
#include "emitter.hpp"
|
|
Packit Service |
7770af |
#include "utf8_string.hpp"
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
namespace Sass {
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
Emitter::Emitter(struct Sass_Output_Options& opt)
|
|
Packit Service |
7770af |
: wbuf(),
|
|
Packit Service |
7770af |
opt(opt),
|
|
Packit Service |
7770af |
indentation(0),
|
|
Packit Service |
7770af |
scheduled_space(0),
|
|
Packit Service |
7770af |
scheduled_linefeed(0),
|
|
Packit Service |
7770af |
scheduled_delimiter(false),
|
|
Packit Service |
7770af |
scheduled_mapping(0),
|
|
Packit Service |
7770af |
in_comment(false),
|
|
Packit Service |
7770af |
in_wrapped(false),
|
|
Packit Service |
7770af |
in_media_block(false),
|
|
Packit Service |
7770af |
in_declaration(false),
|
|
Packit Service |
7770af |
in_space_array(false),
|
|
Packit Service |
7770af |
in_comma_array(false)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// return buffer as string
|
|
Packit Service |
7770af |
std::string Emitter::get_buffer(void)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return wbuf.buffer;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
Sass_Output_Style Emitter::output_style(void) const
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return opt.output_style;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// PROXY METHODS FOR SOURCE MAPS
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
void Emitter::add_source_index(size_t idx)
|
|
Packit Service |
7770af |
{ wbuf.smap.source_index.push_back(idx); }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
std::string Emitter::render_srcmap(Context &ctx)
|
|
Packit Service |
7770af |
{ return wbuf.smap.render_srcmap(ctx); }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
void Emitter::set_filename(const std::string& str)
|
|
Packit Service |
7770af |
{ wbuf.smap.file = str; }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
void Emitter::schedule_mapping(const AST_Node_Ptr node)
|
|
Packit Service |
7770af |
{ scheduled_mapping = node; }
|
|
Packit Service |
7770af |
void Emitter::add_open_mapping(const AST_Node_Ptr node)
|
|
Packit Service |
7770af |
{ wbuf.smap.add_open_mapping(node); }
|
|
Packit Service |
7770af |
void Emitter::add_close_mapping(const AST_Node_Ptr node)
|
|
Packit Service |
7770af |
{ wbuf.smap.add_close_mapping(node); }
|
|
Packit Service |
7770af |
ParserState Emitter::remap(const ParserState& pstate)
|
|
Packit Service |
7770af |
{ return wbuf.smap.remap(pstate); }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// MAIN BUFFER MANIPULATION
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// add outstanding delimiter
|
|
Packit Service |
7770af |
void Emitter::finalize(bool final)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
scheduled_space = 0;
|
|
Packit Service |
7770af |
if (output_style() == SASS_STYLE_COMPRESSED)
|
|
Packit Service |
7770af |
if (final) scheduled_delimiter = false;
|
|
Packit Service |
7770af |
if (scheduled_linefeed)
|
|
Packit Service |
7770af |
scheduled_linefeed = 1;
|
|
Packit Service |
7770af |
flush_schedules();
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// flush scheduled space/linefeed
|
|
Packit Service |
7770af |
void Emitter::flush_schedules(void)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
// check the schedule
|
|
Packit Service |
7770af |
if (scheduled_linefeed) {
|
|
Packit Service |
7770af |
std::string linefeeds = "";
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
for (size_t i = 0; i < scheduled_linefeed; i++)
|
|
Packit Service |
7770af |
linefeeds += opt.linefeed;
|
|
Packit Service |
7770af |
scheduled_space = 0;
|
|
Packit Service |
7770af |
scheduled_linefeed = 0;
|
|
Packit Service |
7770af |
append_string(linefeeds);
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
} else if (scheduled_space) {
|
|
Packit Service |
7770af |
std::string spaces(scheduled_space, ' ');
|
|
Packit Service |
7770af |
scheduled_space = 0;
|
|
Packit Service |
7770af |
append_string(spaces);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
if (scheduled_delimiter) {
|
|
Packit Service |
7770af |
scheduled_delimiter = false;
|
|
Packit Service |
7770af |
append_string(";");
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// prepend some text or token to the buffer
|
|
Packit Service |
7770af |
void Emitter::prepend_output(const OutputBuffer& output)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
wbuf.smap.prepend(output);
|
|
Packit Service |
7770af |
wbuf.buffer = output.buffer + wbuf.buffer;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// prepend some text or token to the buffer
|
|
Packit Service |
7770af |
void Emitter::prepend_string(const std::string& text)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
wbuf.smap.prepend(Offset(text));
|
|
Packit Service |
7770af |
wbuf.buffer = text + wbuf.buffer;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// append some text or token to the buffer
|
|
Packit Service |
7770af |
void Emitter::append_string(const std::string& text)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// write space/lf
|
|
Packit Service |
7770af |
flush_schedules();
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
if (in_comment && output_style() == COMPACT) {
|
|
Packit Service |
7770af |
// unescape comment nodes
|
|
Packit Service |
7770af |
std::string out = comment_to_string(text);
|
|
Packit Service |
7770af |
// add to buffer
|
|
Packit Service |
7770af |
wbuf.buffer += out;
|
|
Packit Service |
7770af |
// account for data in source-maps
|
|
Packit Service |
7770af |
wbuf.smap.append(Offset(out));
|
|
Packit Service |
7770af |
} else {
|
|
Packit Service |
7770af |
// add to buffer
|
|
Packit Service |
7770af |
wbuf.buffer += text;
|
|
Packit Service |
7770af |
// account for data in source-maps
|
|
Packit Service |
7770af |
wbuf.smap.append(Offset(text));
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// append some white-space only text
|
|
Packit Service |
7770af |
void Emitter::append_wspace(const std::string& text)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (text.empty()) return;
|
|
Packit Service |
7770af |
if (peek_linefeed(text.c_str())) {
|
|
Packit Service |
7770af |
scheduled_space = 0;
|
|
Packit Service |
7770af |
append_mandatory_linefeed();
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// append some text or token to the buffer
|
|
Packit Service |
7770af |
// this adds source-mappings for node start and end
|
|
Packit Service |
7770af |
void Emitter::append_token(const std::string& text, const AST_Node_Ptr node)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
flush_schedules();
|
|
Packit Service |
7770af |
add_open_mapping(node);
|
|
Packit Service |
7770af |
// hotfix for browser issues
|
|
Packit Service |
7770af |
// this is pretty ugly indeed
|
|
Packit Service |
7770af |
if (scheduled_mapping) {
|
|
Packit Service |
7770af |
add_open_mapping(scheduled_mapping);
|
|
Packit Service |
7770af |
scheduled_mapping = 0;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
append_string(text);
|
|
Packit Service |
7770af |
add_close_mapping(node);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// HELPER METHODS
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
void Emitter::append_indentation()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (output_style() == COMPRESSED) return;
|
|
Packit Service |
7770af |
if (output_style() == COMPACT) return;
|
|
Packit Service |
7770af |
if (in_declaration && in_comma_array) return;
|
|
Packit Service |
7770af |
if (scheduled_linefeed && indentation)
|
|
Packit Service |
7770af |
scheduled_linefeed = 1;
|
|
Packit Service |
7770af |
std::string indent = "";
|
|
Packit Service |
7770af |
for (size_t i = 0; i < indentation; i++)
|
|
Packit Service |
7770af |
indent += opt.indent;
|
|
Packit Service |
7770af |
append_string(indent);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
void Emitter::append_delimiter()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
scheduled_delimiter = true;
|
|
Packit Service |
7770af |
if (output_style() == COMPACT) {
|
|
Packit Service |
7770af |
if (indentation == 0) {
|
|
Packit Service |
7770af |
append_mandatory_linefeed();
|
|
Packit Service |
7770af |
} else {
|
|
Packit Service |
7770af |
append_mandatory_space();
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
} else if (output_style() != COMPRESSED) {
|
|
Packit Service |
7770af |
append_optional_linefeed();
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
void Emitter::append_comma_separator()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
// scheduled_space = 0;
|
|
Packit Service |
7770af |
append_string(",");
|
|
Packit Service |
7770af |
append_optional_space();
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
void Emitter::append_colon_separator()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
scheduled_space = 0;
|
|
Packit Service |
7770af |
append_string(":");
|
|
Packit Service |
7770af |
append_optional_space();
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
void Emitter::append_mandatory_space()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
scheduled_space = 1;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
void Emitter::append_optional_space()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if ((output_style() != COMPRESSED) && buffer().size()) {
|
|
Packit Service |
7770af |
unsigned char lst = buffer().at(buffer().length() - 1);
|
|
Packit Service |
7770af |
if (!isspace(lst) || scheduled_delimiter) {
|
|
Packit Service |
7770af |
append_mandatory_space();
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
void Emitter::append_special_linefeed()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (output_style() == COMPACT) {
|
|
Packit Service |
7770af |
append_mandatory_linefeed();
|
|
Packit Service |
7770af |
for (size_t p = 0; p < indentation; p++)
|
|
Packit Service |
7770af |
append_string(opt.indent);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
void Emitter::append_optional_linefeed()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (in_declaration && in_comma_array) return;
|
|
Packit Service |
7770af |
if (output_style() == COMPACT) {
|
|
Packit Service |
7770af |
append_mandatory_space();
|
|
Packit Service |
7770af |
} else {
|
|
Packit Service |
7770af |
append_mandatory_linefeed();
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
void Emitter::append_mandatory_linefeed()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (output_style() != COMPRESSED) {
|
|
Packit Service |
7770af |
scheduled_linefeed = 1;
|
|
Packit Service |
7770af |
scheduled_space = 0;
|
|
Packit Service |
7770af |
// flush_schedules();
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
void Emitter::append_scope_opener(AST_Node_Ptr node)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
scheduled_linefeed = 0;
|
|
Packit Service |
7770af |
append_optional_space();
|
|
Packit Service |
7770af |
flush_schedules();
|
|
Packit Service |
7770af |
if (node) add_open_mapping(node);
|
|
Packit Service |
7770af |
append_string("{");
|
|
Packit Service |
7770af |
append_optional_linefeed();
|
|
Packit Service |
7770af |
// append_optional_space();
|
|
Packit Service |
7770af |
++ indentation;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
void Emitter::append_scope_closer(AST_Node_Ptr node)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
-- indentation;
|
|
Packit Service |
7770af |
scheduled_linefeed = 0;
|
|
Packit Service |
7770af |
if (output_style() == COMPRESSED)
|
|
Packit Service |
7770af |
scheduled_delimiter = false;
|
|
Packit Service |
7770af |
if (output_style() == EXPANDED) {
|
|
Packit Service |
7770af |
append_optional_linefeed();
|
|
Packit Service |
7770af |
append_indentation();
|
|
Packit Service |
7770af |
} else {
|
|
Packit Service |
7770af |
append_optional_space();
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
append_string("}");
|
|
Packit Service |
7770af |
if (node) add_close_mapping(node);
|
|
Packit Service |
7770af |
append_optional_linefeed();
|
|
Packit Service |
7770af |
if (indentation != 0) return;
|
|
Packit Service |
7770af |
if (output_style() != COMPRESSED)
|
|
Packit Service |
7770af |
scheduled_linefeed = 2;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
}
|