11#include " eval.hpp"
22#include " ast.hpp"
33#include " bind.hpp"
4+ #include " util.hpp"
45#include " to_string.hpp"
56#include " inspect.hpp"
67#include " to_c.hpp"
@@ -561,27 +562,35 @@ namespace Sass {
561562 Expression* result = 0 ;
562563 bool zero = !( t->value ().substr (0 , 1 ) == " ." ||
563564 t->value ().substr (0 , 2 ) == " -." );
565+
566+ const string& text = t->value ();
567+ size_t num_pos = text.find_first_not_of (" \n\r\t " );
568+ if (num_pos == string::npos) num_pos = text.length ();
569+ size_t unit_pos = text.find_first_not_of (" -+0123456789." , num_pos);
570+ if (unit_pos == string::npos) unit_pos = text.length ();
571+ const string& num = text.substr (num_pos, unit_pos - num_pos);
572+
564573 switch (t->type ())
565574 {
566575 case Textual::NUMBER:
567576 result = new (ctx.mem ) Number (t->path (),
568577 t->position (),
569- atof (t-> value () .c_str ()),
578+ atof (num .c_str ()),
570579 " " ,
571580 zero);
572581 break ;
573582 case Textual::PERCENTAGE:
574583 result = new (ctx.mem ) Number (t->path (),
575584 t->position (),
576- atof (t-> value () .c_str ()),
585+ atof (num .c_str ()),
577586 " %" ,
578587 zero);
579588 break ;
580589 case Textual::DIMENSION:
581590 result = new (ctx.mem ) Number (t->path (),
582591 t->position (),
583- atof (t-> value () .c_str ()),
584- Token (number (t-> value () .c_str ())),
592+ atof (num .c_str ()),
593+ Token (number (text .c_str ())),
585594 zero);
586595 break ;
587596 case Textual::HEX: {
@@ -595,7 +604,7 @@ namespace Sass {
595604 static_cast <double >(strtol (r.c_str (), NULL , 16 )),
596605 static_cast <double >(strtol (g.c_str (), NULL , 16 )),
597606 static_cast <double >(strtol (b.c_str (), NULL , 16 )),
598- 1 ,
607+ 1 , true ,
599608 t->value ());
600609 }
601610 else {
@@ -604,7 +613,7 @@ namespace Sass {
604613 static_cast <double >(strtol (string (2 ,hext[0 ]).c_str (), NULL , 16 )),
605614 static_cast <double >(strtol (string (2 ,hext[1 ]).c_str (), NULL , 16 )),
606615 static_cast <double >(strtol (string (2 ,hext[2 ]).c_str (), NULL , 16 )),
607- 1 ,
616+ 1 , false ,
608617 t->value ());
609618 }
610619 } break ;
@@ -938,11 +947,13 @@ namespace Sass {
938947 case Binary_Expression::DIV: {
939948 string sep (op == Binary_Expression::SUB ? " -" : " /" );
940949 To_String to_string;
950+ string color (r->sixtuplet () ? r->perform (&to_string) :
951+ Util::normalize_sixtuplet (r->perform (&to_string)));
941952 return new (ctx.mem ) String_Constant (l->path (),
942953 l->position (),
943954 l->perform (&to_string)
944955 + sep
945- + r-> perform (&to_string) );
956+ + color );
946957 } break ;
947958 case Binary_Expression::MOD: {
948959 error (" cannot divide a number by a color" , r->path (), r->position ());
@@ -992,27 +1003,30 @@ namespace Sass {
9921003 Expression::Concrete_Type ltype = lhs->concrete_type ();
9931004 Expression::Concrete_Type rtype = rhs->concrete_type ();
9941005
995- // TODO: currently SASS converts colors to standard form when adding to strings;
996- // when https://github.com/nex3/sass/issues/363 is added this can be removed to
997- // preserve the original value
998- if (ltype == Expression::COLOR) ((Sass::Color*)lhs)->disp (" " );
999- if (rtype == Expression::COLOR) ((Sass::Color*)rhs)->disp (" " );
1000-
10011006 string lstr (lhs->perform (&to_string));
10021007 string rstr (rhs->perform (&to_string));
1008+
1009+ bool l_str_quoted = ((Sass::String*)lhs) && ((Sass::String*)lhs)->needs_unquoting ();
1010+ bool r_str_quoted = ((Sass::String*)rhs) && ((Sass::String*)rhs)->needs_unquoting ();
1011+ bool l_str_color = ltype == Expression::STRING && ctx.names_to_colors .count (lstr) && !l_str_quoted;
1012+ bool r_str_color = rtype == Expression::STRING && ctx.names_to_colors .count (rstr) && !r_str_quoted;
1013+
10031014 bool unquoted = false ;
10041015 if (ltype == Expression::STRING && lstr[0 ] != ' "' && lstr[0 ] != ' \' ' ) unquoted = true ;
1005- if (ltype == Expression::STRING && !lhs->is_delayed () && ctx.names_to_colors .count (lstr) &&
1006- rtype == Expression::STRING && !rhs->is_delayed () && ctx.names_to_colors .count (rstr)) {
1016+ if (l_str_color && r_str_color) {
10071017 return op_colors (ctx, op, ctx.names_to_colors [lstr], ctx.names_to_colors [rstr]);
10081018 }
1009- else if (ltype == Expression::STRING && !lhs->is_delayed () && ctx.names_to_colors .count (lstr) &&
1010- rtype == Expression::NUMBER) {
1019+ else if (l_str_color && rtype == Expression::COLOR) {
1020+ return op_colors (ctx, op, ctx.names_to_colors [lstr], rhs);
1021+ }
1022+ else if (l_str_color && rtype == Expression::NUMBER) {
10111023 return op_color_number (ctx, op, ctx.names_to_colors [lstr], rhs);
10121024 }
1013- else if (ltype == Expression::NUMBER &&
1014- rtype == Expression::STRING && !rhs->is_delayed () && ctx.names_to_colors .count (rstr)) {
1015- return op_number_color (ctx, op, rhs, ctx.names_to_colors [rstr]);
1025+ else if (ltype == Expression::COLOR && r_str_color) {
1026+ return op_number_color (ctx, op, lhs, ctx.names_to_colors [rstr]);
1027+ }
1028+ else if (ltype == Expression::NUMBER && r_str_color) {
1029+ return op_number_color (ctx, op, lhs, ctx.names_to_colors [rstr]);
10161030 }
10171031 if (op == Binary_Expression::MUL) error (" invalid operands for multiplication" , lhs->path (), lhs->position ());
10181032 if (op == Binary_Expression::MOD) error (" invalid operands for modulo" , lhs->path (), lhs->position ());
0 commit comments