Text-Sass-XS

 view release on metacpan or  search on metacpan

libsass/old/node_emitters.cpp  view on Meta::CPAN

        }
        if (!(inside_of == identifier_schema || inside_of == property) && is_quoted()) {
          result = "\"" + result + "\"";
        }
        return result;
      } break;

      case warning: {
        return "";
      } break;
      
      default: {
        // return content.token.to_string();
        if (!has_children()) return token().to_string();
        else return "";
      } break;
    }
  }

  void Node::emit_nested_css(stringstream& buf, size_t depth, bool at_toplevel, bool in_media_query, int source_comments)
  {
    switch (type())
    {
      case root: {
        if (has_expansions()) flatten();
        for (size_t i = 0, S = size(); i < S; ++i) {
          at(i).emit_nested_css(buf, depth, true, false, source_comments);
        }
      } break;

      case ruleset: {
        Node sel_group(at(2));
        Node block(at(1));

        if (block.has_expansions()) block.flatten();
        if (block.has_statements() || block.has_comments()) {
          if (source_comments) {
            buf << string(2*depth, ' ');
            switch (source_comments)
            {
              case SASS_SOURCE_COMMENTS_DEFAULT: {
                buf << "/* line " << sel_group.line() << ", " << sel_group.path() << " */" << endl;
              } break;
              case SASS_SOURCE_COMMENTS_MAP: {
                buf << "@media -sass-debug-info{filename{font-family:file:" << sel_group.debug_info_path() << "}line{font-family:\\00003" << sel_group.line() << "}}" << endl;
              } break;
              default: break;
            }
          }
          buf << string(2*depth, ' ');
          buf << sel_group.to_string();
          buf << " {";
          for (size_t i = 0, S = block.size(); i < S; ++i) {
            Type stm_type = block[i].type();
            if (stm_type == block_directive) buf << endl;
            switch (stm_type)
            {
              case comment:
              case rule:
              case css_import:
              case propset:
              case block_directive:
              case blockless_directive:
              case keyframes:
              case warning: {
                block[i].emit_nested_css(buf, depth+1, false, false, source_comments);
              } break;
              default: break;
            }
          }
          buf << " }";
          if (!in_media_query || (in_media_query && block.has_blocks())) buf << endl;
          ++depth; // if we printed content at this level, we need to indent any nested rulesets
        }
        if (block.has_blocks()) {
          for (size_t i = 0, S = block.size(); i < S; ++i) {
            if (block[i].type() == ruleset || block[i].type() == media_query) {
              block[i].emit_nested_css(buf, depth, false, in_media_query, source_comments);
            }
          }
        }
        if (block.has_statements() || block.has_comments()) --depth; // see previous comment
        if ((depth == 0) && at_toplevel && !in_media_query) buf << endl;
      } break;

      case keyframe: {
        buf << string(2*depth, ' ') << at(0).to_string() << " {";
        Node block(at(1));
        if (block.has_expansions()) block.flatten();
        for (size_t i = 0, S = block.size(); i < S; ++i) {
          block[i].emit_nested_css(buf, depth+1, false, in_media_query, source_comments);
        }
        buf << " }";
      } break;

      case keyframes: {
        buf << string(2*depth, ' ') << at(0).to_string() << " " << at(1).to_string() << " {" << endl;
        at(2).emit_nested_css(buf, depth+1, false, in_media_query, source_comments);
        buf << " }" << endl << endl;
      } break;

      case block: {
        if (has_expansions()) flatten();
        for (size_t i = 0, S = size(); i < S; ++i) {
          Type stm_type = at(i).type();
          switch (stm_type)
          {
            case rule:
            case css_import:
            case propset:
            case block_directive:
            case keyframe:
            case blockless_directive:
            case warning: {
              at(i).emit_nested_css(buf, depth, false, false, source_comments);
              if (i != S - 1) buf << endl << endl;
            } break;

            default: break;
          }
        }
      } break;

      case media_query: {
        buf << string(2*depth, ' ');
        buf << "@media " << at(0).to_string() << " {";
        // at(1).emit_nested_css(buf, depth+1, false, true);

        Node block(at(1));
        if (block.has_expansions()) block.flatten();
        bool has_comments   = block.has_comments();
        bool has_statements = block.has_statements();
        bool has_blocks     = block.has_blocks();
        if (has_comments && !has_statements && !has_blocks) {
          // just print out the comments without a block
          for (size_t i = 0, S = block.size(); i < S; ++i) {
            if (block[i].type() == comment)
              block[i].emit_nested_css(buf, depth+1, false, false, source_comments);
          }
        }
        if (has_statements) {
          ++depth;
          buf << endl;
          buf << string(2*depth, ' ');
          buf << at(2).to_string();
          buf << " {";
          for (size_t i = 0, S = block.size(); i < S; ++i) {
            Type stm_type = block[i].type();
            if (stm_type == block_directive) buf << endl;
            switch (stm_type)
            {
              case comment:
              case rule:
              case css_import:
              case propset:
              case block_directive:
              case blockless_directive:
              case warning: {
                // if (stm_type != comment) buf << endl;
                block[i].emit_nested_css(buf, depth+1, false, false, source_comments);
              } break;

              default: break;
            }
          }
          buf << " }";
        }
        if (block.has_blocks()) {
          for (size_t i = 0, S = block.size(); i < S; ++i) {
            Type stm_type = block[i].type();
            if (stm_type == comment && !has_statements) {
              if (i > 0 && block[i-1].type() == ruleset) buf << endl;
              block[i].emit_nested_css(buf, depth+1, false, true, source_comments);
            }
            if (stm_type == ruleset || stm_type == media_query) {
              buf << endl;
              if (i > 0 &&
                  block[i-1].type() == ruleset &&
                  !block[i-1][1].has_blocks())
              { buf << endl; }
              block[i].emit_nested_css(buf, depth+1, false, true, source_comments);
            }
          }
        }
        buf << " }" << endl;
        --depth;
      } break;

      case blockless_directive: {
        buf << endl << string(2*depth, ' ');
        buf << to_string();
        buf << ";";
      } break;

      case block_directive: {
        Node header(at(0));
        Node block(at(1));
        if (block.has_expansions()) block.flatten();
        buf << string(2*depth, ' ');
        buf << header.to_string();
        buf << " {";
        for (size_t i = 0, S = block.size(); i < S; ++i) {
          switch (block[i].type())
          {
            case ruleset:
            case media_query:
            case block_directive:
              buf << endl;
              break;
            default:
              break;
          }
          block[i].emit_nested_css(buf, depth+1, false, in_media_query, source_comments);
        }
        buf << " }" << endl;
        if ((depth == 0) && at_toplevel && !in_media_query) buf << endl;
      } break;

      case propset: {
        emit_propset(buf, depth, "");
      } break;
        
      case rule: {
        buf << endl << string(2*depth, ' ');
        buf << to_string();
        // at(0).emit_nested_css(buf, depth); // property
        // at(1).emit_nested_css(buf, depth); // values
        buf << ";";
      } break;
        
      case css_import: {
        buf << string(2*depth, ' ');
        buf << to_string();
        buf << ";" << endl;
      } break;

      case property: {
        buf << token().to_string() << ": ";
      } break;

      case values: {
        for (size_t i = 0, S = size(); i < S; ++i) {
          buf << " " << at(i).token().to_string();
        }
      } break;

      case comment: {
        if (depth != 0) buf << endl;
        buf << string(2*depth, ' ') << token().to_string();
        if (depth == 0) buf << endl;
      } break;

      default: {
        buf << to_string();
      } break;
    }
  }

  void Node::emit_compressed_css(stringstream& buf)
  {
    switch (type())
    {
      case root: {
        if (has_expansions()) flatten();
        for (size_t i = 0, S = size(); i < S; ++i) {
          at(i).emit_compressed_css(buf);
        }
      } break;

      case ruleset: {
        Node sel_group(at(2));
        Node block(at(1));

        if (block.has_expansions()) block.flatten();
        if (block.has_statements()) {
          buf << sel_group.to_string(none, "") << "{";
          for (size_t i = 0, S = block.size(); i < S; ++i) {
            Type stm_type = block[i].type();
            switch (stm_type)
            {
              case rule:
              case css_import:
              case propset:
              case block_directive:
              case blockless_directive:
              case warning: {
                block[i].emit_compressed_css(buf);
              } break;
              default: break;
            }
          }
          buf << "}";
        }
        if (block.has_blocks()) {
          for (size_t i = 0, S = block.size(); i < S; ++i) {
            if (block[i].type() == ruleset || block[i].type() == media_query) {
              block[i].emit_compressed_css(buf);
            }
          }
        }
      } break;

      case block: {
        if (has_expansions()) flatten();
        buf << "{";
        for (size_t i = 0, S = size(); i < S; ++i) {
          Type stm_type = at(i).type();
          switch (stm_type)
          {
            case rule:
            case css_import:
            case propset:
            case block_directive:
            case keyframe:
            case blockless_directive:
            case warning: {
              at(i).emit_compressed_css(buf);
            } break;

            default: break;
          }
        }
        buf << "}";
      } break;

      case keyframe: {
        buf << at(0).to_string() << " {" << endl;
        Node block(at(1));
        if (block.has_expansions()) block.flatten();
        for (size_t i = 0, S = block.size(); i < S; ++i) {
          block[i].emit_compressed_css(buf);
        }
        buf << "}" << endl;
      } break;

      case keyframes: {
        buf << at(0).to_string() << " "  << at(1).to_string(none, "");
        Node block(at(2));
        if (block.has_expansions()) block.flatten();
        block.emit_compressed_css(buf);
      } break;

      case media_query: {
        buf << "@media " << at(0).to_string(none, "") << "{";

        Node block(at(1));
        if (block.has_expansions()) block.flatten();
        bool has_statements = block.has_statements();
        if (has_statements) {
          buf << at(2).to_string(none, "");
          buf << "{";
          for (size_t i = 0, S = block.size(); i < S; ++i) {
            Type stm_type = block[i].type();
            switch (stm_type)
            {
              case rule:
              case css_import:
              case propset:
              case block_directive:
              case blockless_directive:
              case warning: {
                block[i].emit_compressed_css(buf);
              } break;

              default: break;
            }
          }
          buf << "}";
        }
        if (block.has_blocks()) {
          for (size_t i = 0, S = block.size(); i < S; ++i) {
            Type stm_type = block[i].type();
            if (stm_type == ruleset || stm_type == media_query) {
              block[i].emit_compressed_css(buf);
            }
          }
        }
        buf << "}";
      } break;

      case blockless_directive: {
        buf << to_string(none, "");
        buf << ";";
      } break;

      case block_directive: {
        Node header(at(0));
        Node block(at(1));
        if (block.has_expansions()) block.flatten();
        buf << header.to_string(none, "");
        buf << "{";
        for (size_t i = 0, S = block.size(); i < S; ++i) {
          block[i].emit_compressed_css(buf);
        }
        buf << "}";
      } break;

      case propset: {
        emit_propset(buf, 0, "", true);
      } break;
        
      case rule: {
        buf << to_string(none, "");
        buf << ";";
      } break;
        
      case css_import: {
        buf << to_string(none, "");
        buf << ";";
      } break;

      case property: {
        buf << token().to_string() << ":";
      } break;

      case values: {
        for (size_t i = 0, S = size(); i < S; ++i) {
          buf << " " << at(i).token().to_string();
        }
      } break;

      case comment: {
        // do nothing
      } break;

      default: {
        buf << to_string(none, "");
      } break;
    }
  }
  
  void Node::emit_propset(stringstream& buf, size_t depth, const string& prefix, const bool compressed)
  {
    string new_prefix(prefix);
    // bool has_prefix = false;
    if (new_prefix.empty()) {
      if (!compressed) {
        new_prefix += "\n";
        new_prefix += string(2*depth, ' ');
      }
      new_prefix += at(0).to_string();
    }
    else {
      new_prefix += "-";
      new_prefix += at(0).to_string();
      // has_prefix = true;
    }
    Node rules(at(1));
    rules.flatten();
    for (size_t i = 0, S = rules.size(); i < S; ++i) {
      if (rules[i].type() == propset) {
        rules[i].emit_propset(buf, depth+1, new_prefix, compressed);
      }
      else if (rules[i].type() == rule) {
        buf << new_prefix;
        if (rules[i][0].to_string() != "") buf << '-';
        if (!compressed) {
          rules[i][0].emit_nested_css(buf, depth);
          if (rules[i][0].type() == identifier_schema) buf << ": ";
          rules[i][1].emit_nested_css(buf, depth);
        }
        else {
          rules[i][0].emit_compressed_css(buf);
          if (rules[i][0].type() == identifier_schema) buf << ": ";
          rules[i][1].emit_compressed_css(buf);
        }
        buf << ';';
      }
    }
  }

  void Node::echo(stringstream& buf, size_t depth) { }
  void Node::emit_expanded_css(stringstream& buf, const string& prefix) { }

}



( run in 0.873 second using v1.01-cache-2.11-cpan-71847e10f99 )