Skip to content

Commit

Permalink
Refactor inspection/output of numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
mgreter committed Dec 12, 2018
1 parent e94b5f9 commit aabb867
Showing 1 changed file with 19 additions and 60 deletions.
79 changes: 19 additions & 60 deletions src/inspect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -519,82 +519,41 @@ namespace Sass {
void Inspect::operator()(Number_Ptr n)
{

std::string res;

// reduce units
n->reduce();

// check if the fractional part of the value equals to zero
// neat trick from http://stackoverflow.com/a/1521682/1550314
// double int_part; bool is_int = modf(value, &int_part) == 0.0;

// this all cannot be done with one run only, since fixed
// output differs from normal output and regular output
// can contain scientific notation which we do not want!

// first sample
std::stringstream ss;
ss.precision(12);
ss << n->value();

// check if we got scientific notation in result
if (ss.str().find_first_of("e") != std::string::npos) {
ss.clear(); ss.str(std::string());
ss.precision(std::max(12, opt.precision));
ss << std::fixed << n->value();
}

std::string tmp = ss.str();
size_t pos_point = tmp.find_first_of(".,");
size_t pos_fract = tmp.find_last_not_of("0");
bool is_int = pos_point == pos_fract ||
pos_point == std::string::npos;
ss.precision(opt.precision);
ss << std::fixed << n->value();

// reset stream for another run
ss.clear(); ss.str(std::string());
std::string res = ss.str();
int s = res.length();

// take a shortcut for integers
if (is_int)
// delete trailing zeros
for(s = s - 1; s > 0; --s)
{
ss.precision(0);
ss << std::fixed << n->value();
res = std::string(ss.str());
}
// process floats
else
{
// do we have have too much precision?
if (pos_fract < opt.precision + pos_point)
{ ss.precision((int)(pos_fract - pos_point)); }
else { ss.precision(opt.precision); }
// round value again
ss << std::fixed << n->value();
res = std::string(ss.str());
// maybe we truncated up to decimal point
size_t pos = res.find_last_not_of("0");
// handle case where we have a "0"
if (pos == std::string::npos) {
res = "0.0";
} else {
bool at_dec_point = res[pos] == '.' ||
res[pos] == ',';
// don't leave a blank point
if (at_dec_point) ++ pos;
res.resize (pos + 1);
}
if(res[s] == '0') {
res.erase(s, 1);
}
else break;
}

// delete trailing decimal separator
if(res[s] == '.') res.erase(s, 1);

// some final cosmetics
if (res == "0.0") res = "0";
else if (res == "") res = "0";
else if (res == "-0") res = "0";
else if (res == "-0.0") res = "0";
else if (opt.output_style == COMPRESSED)
{
// check if handling negative nr
size_t off = res[0] == '-' ? 1 : 0;
// remove leading zero from floating point in compressed mode
if (n->zero() && res[off] == '0' && res[off+1] == '.') res.erase(off, 1);
if (n->zero()) {
// check if handling negative nr
size_t off = res[0] == '-' ? 1 : 0;
// remove leading zero from floating point in compressed mode
if (res[off] == '0' && res[off+1] == '.') res.erase(off, 1);
}
}

// add unit now
Expand Down

0 comments on commit aabb867

Please sign in to comment.