CSS-Sass

 view release on metacpan or  search on metacpan

libsass/output.cpp  view on Meta::CPAN

#include "ast.hpp"
#include "output.hpp"
#include "to_string.hpp"

namespace Sass {
  using namespace std;

  Output::Output(Context* ctx)
  : Inspect(Emitter(ctx)),
    charset(""),
    top_imports(0),
    top_comments(0)
  {}

  Output::~Output() { }

  void Output::fallback_impl(AST_Node* n)
  {
    return n->perform(this);
  }

  void Output::operator()(Import* imp)
  {
    top_imports.push_back(imp);
  }

  OutputBuffer Output::get_buffer(void)
  {

    Emitter emitter(ctx);
    Inspect inspect(emitter);

    size_t size_com = top_comments.size();
    for (size_t i = 0; i < size_com; i++) {
      top_comments[i]->perform(&inspect);
      inspect.append_mandatory_linefeed();
    }

    size_t size_imp = top_imports.size();
    for (size_t i = 0; i < size_imp; i++) {
      top_imports[i]->perform(&inspect);
      inspect.append_mandatory_linefeed();
    }

    // flush scheduled outputs
    inspect.finalize();
    // prepend buffer on top
    prepend_output(inspect.output());
    // make sure we end with a linefeed
    if (!ends_with(wbuf.buffer, ctx->linefeed)) {
      // if the output is not completely empty
      if (!wbuf.buffer.empty()) append_string(ctx->linefeed);
    }

    // search for unicode char
    for(const char& chr : wbuf.buffer) {
      // skip all ascii chars
      if (chr >= 0) continue;
      // declare the charset
      if (output_style() != COMPRESSED)
        charset = "@charset \"UTF-8\";"
                  + ctx->linefeed;
      else charset = "\xEF\xBB\xBF";
      // abort search
      break;
    }

    // add charset as first line, before comments and imports
    if (!charset.empty()) prepend_string(charset);

    return wbuf;

  }

  void Output::operator()(Comment* c)
  {
    To_String to_string(ctx);
    string txt = c->text()->perform(&to_string);
    // if (indentation && txt == "/**/") return;
    bool important = c->is_important();
    if (output_style() != COMPRESSED || important) {
      if (buffer().size() + top_imports.size() == 0) {
        top_comments.push_back(c);
      } else {
        in_comment = true;
        append_indentation();
        c->text()->perform(this);
        in_comment = false;
        if (indentation == 0) {
          append_mandatory_linefeed();
        } else {
          append_optional_linefeed();
        }
      }
    }
  }

  void Output::operator()(Ruleset* r)
  {
    Selector* s     = r->selector();
    Block*    b     = r->block();
    bool      decls = false;

    // Filter out rulesets that aren't printable (process its children though)
    if (!Util::isPrintable(r, output_style())) {
      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        if (dynamic_cast<Has_Block*>(stm)) {
          stm->perform(this);
        }
      }
      return;
    }

    if (b->has_non_hoistable()) {



( run in 2.530 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )