Skip to content

Commit 0a50d1c

Browse files
committed
Merge remote-tracking branch 'origin/pr/1166'
2 parents 23f06ec + 8bc46e4 commit 0a50d1c

File tree

1 file changed

+78
-30
lines changed

1 file changed

+78
-30
lines changed

inspect.cpp

Lines changed: 78 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -416,43 +416,91 @@ namespace Sass {
416416

417417
void Inspect::operator()(Number* n)
418418
{
419+
420+
string res;
421+
422+
// init stuff
419423
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
420438
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
435493
if (n->numerator_units().size() > 1 ||
436494
n->denominator_units().size() > 0 ||
437495
(n->numerator_units().size() && n->numerator_units()[0].find_first_of('/') != string::npos) ||
438496
(n->numerator_units().size() && n->numerator_units()[0].find_first_of('*') != string::npos)
439497
) {
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+
456504
}
457505

458506
// helper function for serializing colors

0 commit comments

Comments
 (0)