@@ -416,43 +416,91 @@ namespace Sass {
416
416
417
417
void Inspect::operator ()(Number* n)
418
418
{
419
+
420
+ string res;
421
+
422
+ // init stuff
419
423
n->normalize ();
424
+ int precision = 5 ;
425
+ double value = n->value ();
426
+ // get option from optional context
427
+ if (ctx) precision = ctx->precision ;
428
+
429
+ // check if the fractional part of the value equals to zero
430
+ // neat trick from http://stackoverflow.com/a/1521682/1550314
431
+ // double int_part; bool is_int = modf(value, &int_part) == 0.0;
432
+
433
+ // this all cannot be done with one run only, since fixed
434
+ // output differs from normal output and regular output
435
+ // can contain scientific notation which we do not want!
436
+
437
+ // first sample
420
438
stringstream ss;
421
- ss.precision (ctx ? ctx->precision : 5 );
422
- ss << fixed << n->value ();
423
- string d (ss.str ());
424
- // store if the value did not equal zero
425
- // if after applying precsision, the value gets
426
- // truncated to zero, sass emits 0.0 instead of 0
427
- bool nonzero = n->value () != 0 ;
428
- size_t decimal = d.find (' .' );
429
- if (decimal != string::npos) {
430
- for (size_t i = d.length ()-1 ; d[i] == ' 0' && i >= decimal; --i) {
431
- d.resize (d.length ()-1 );
432
- }
433
- }
434
- if (d[d.length ()-1 ] == ' .' ) d.resize (d.length ()-1 );
439
+ ss.precision (12 );
440
+ ss << value;
441
+
442
+ // check if we got scientific notation in result
443
+ if (ss.str ().find_first_of (" e" ) != string::npos) {
444
+ ss.clear (); ss.str (string ());
445
+ ss.precision (max (12 , precision));
446
+ ss << fixed << value;
447
+ }
448
+
449
+ string tmp = ss.str ();
450
+ size_t pos_point = tmp.find_first_of (" .," );
451
+ size_t pos_fract = tmp.find_last_not_of (" 0" );
452
+ bool is_int = pos_point == pos_fract ||
453
+ pos_point == string::npos;
454
+
455
+ // reset stream for another run
456
+ ss.clear (); ss.str (string ());
457
+
458
+ // take a shortcut for integers
459
+ if (is_int)
460
+ {
461
+ ss.precision (0 );
462
+ ss << fixed << value;
463
+ res = string (ss.str ());
464
+ }
465
+ // process floats
466
+ else
467
+ {
468
+ // do we have have too much precision?
469
+ if (pos_fract < precision + pos_point)
470
+ { precision = pos_fract - pos_point; }
471
+ // round value again
472
+ ss.precision (precision);
473
+ ss << fixed << value;
474
+ res = string (ss.str ());
475
+ // maybe we truncated up to decimal point
476
+ size_t pos = res.find_last_not_of (" 0" );
477
+ bool at_dec_point = res[pos] == ' .' ||
478
+ res[pos] == ' ,' ;
479
+ // don't leave a blank point
480
+ if (at_dec_point) ++ pos;
481
+ res.resize (pos + 1 );
482
+ }
483
+
484
+ // some final cosmetics
485
+ if (res == " -0.0" ) res.erase (0 , 1 );
486
+ else if (res == " -0" ) res.erase (0 , 1 );
487
+
488
+ // add unit now
489
+ res += n->unit ();
490
+
491
+ // check for a valid unit here
492
+ // includes result for reporting
435
493
if (n->numerator_units ().size () > 1 ||
436
494
n->denominator_units ().size () > 0 ||
437
495
(n->numerator_units ().size () && n->numerator_units ()[0 ].find_first_of (' /' ) != string::npos) ||
438
496
(n->numerator_units ().size () && n->numerator_units ()[0 ].find_first_of (' *' ) != string::npos)
439
497
) {
440
- error (d + n->unit () + " isn't a valid CSS value." , n->pstate ());
441
- }
442
- if (!n->zero () && !in_declaration_list) {
443
- if (d.substr (0 , 3 ) == " -0." ) d.erase (1 , 1 );
444
- if (d.substr (0 , 2 ) == " 0." ) d.erase (0 , 1 );
445
- }
446
- // remove the leading minus
447
- if (d == " -0" ) d.erase (0 , 1 );
448
- // use fractional output if we had
449
- // a value before it got truncated
450
- if (d == " 0" && nonzero) d = " 0.0" ;
451
- // if the precision is 0 sass cast
452
- // casts to a float with precision 1
453
- if (ctx->precision == 0 ) d += " .0" ;
454
- // append number and unit
455
- append_token (d + n->unit (), n);
498
+ error (res + " isn't a valid CSS value." , n->pstate ());
499
+ }
500
+
501
+ // output the final token
502
+ append_token (res, n);
503
+
456
504
}
457
505
458
506
// helper function for serializing colors
0 commit comments