Commit 7e6b3662 by Aaron Leung

Parsing interpolants inside property names.

parent 1878317b
...@@ -161,6 +161,7 @@ namespace Sass { ...@@ -161,6 +161,7 @@ namespace Sass {
Node parse_function_call(); Node parse_function_call();
Node parse_string(); Node parse_string();
Node parse_value_schema(); Node parse_value_schema();
Node parse_identifier_schema();
Node parse_if_directive(Node surrounding_ruleset, Node::Type inside_of = Node::none); Node parse_if_directive(Node surrounding_ruleset, Node::Type inside_of = Node::none);
Node parse_for_directive(Node surrounding_ruleset, Node::Type inside_of = Node::none); Node parse_for_directive(Node surrounding_ruleset, Node::Type inside_of = Node::none);
Node parse_each_directive(Node surrounding_ruleset, Node::Type inside_of = Node::none); Node parse_each_directive(Node surrounding_ruleset, Node::Type inside_of = Node::none);
......
...@@ -568,12 +568,12 @@ namespace Sass { ...@@ -568,12 +568,12 @@ namespace Sass {
Node Document::parse_rule() { Node Document::parse_rule() {
Node rule(context.new_Node(Node::rule, path, line, 2)); Node rule(context.new_Node(Node::rule, path, line, 2));
if (lex< sequence< optional< exactly<'*'> >, identifier > >()) { if (peek< sequence< optional< exactly<'*'> >, identifier_schema > >()) {
rule << context.new_Node(node::property, path, line, lexed);
}
else if (peek< sequence< optional< exactly<'*'> >, identifier_schema > >()) {
rule << parse_identifier_schema(); rule << parse_identifier_schema();
} }
else if (lex< sequence< optional< exactly<'*'> >, identifier > >()) {
rule << context.new_Node(Node::property, path, line, lexed);
}
else { else {
throw_syntax_error("invalid property name"); throw_syntax_error("invalid property name");
} }
...@@ -925,15 +925,41 @@ namespace Sass { ...@@ -925,15 +925,41 @@ namespace Sass {
} }
Node Document::parse_identifier_schema() Node Document::parse_identifier_schema()
{ {
lex< sequence< optional< exactly<'*'> >, identifier_schema > >();
Token id(lexed);
const char* i = id.begin;
// see if there any interpolants
const char* p = find_first_in_interval< sequence< negate< exactly<'\\'> >, exactly<hash_lbrace> > >(id.begin, id.end);
if (!p) {
return context.new_Node(Node::string_constant, path, line, id);
}
Node schema(context.new_Node(Node::identifier_schema, path, line, 1)); Node schema(context.new_Node(Node::identifier_schema, path, line, 1));
Token stok(lexed); while (i < id.end) {
while (position < stok.end) { p = find_first_in_interval< sequence< negate< exactly<'\\'> >, exactly<hash_lbrace> > >(i, id.end);
if (p) {
if (i < p) {
schema << context.new_Node(Node::identifier, path, line, Token::make(i, p)); // accumulate the preceding segment if it's nonempty
}
const char* j = find_first_in_interval< exactly<rbrace> >(p, id.end); // find the closing brace
if (j) {
// parse the interpolant and accumulate it
Node interp_node(Document::make_from_token(context, Token::make(p+2, j), path, line).parse_list());
interp_node.should_eval() = true;
schema << interp_node;
i = j+1;
}
else {
// throw an error if the interpolant is unterminated
throw_syntax_error("unterminated interpolant inside string constant " + id.to_string());
}
}
else { // no interpolants left; add the last segment if nonempty
if (i < id.end) schema << context.new_Node(Node::identifier, path, line, Token::make(i, id.end));
break;
}
} }
schema.should_eval() = true;
return schema; return schema;
} }
......
...@@ -143,6 +143,7 @@ namespace Sass { ...@@ -143,6 +143,7 @@ namespace Sass {
value_schema, value_schema,
string_schema, string_schema,
identifier_schema,
css_import, css_import,
function_call, function_call,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment