Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

ssf

Package Overview
Dependencies
Maintainers
1
Versions
38
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ssf - npm Package Compare versions

Comparing version 0.6.5 to 0.7.0

2

package.json
{
"name": "ssf",
"version": "0.6.5",
"version": "0.7.0",
"author": "SheetJS",

@@ -5,0 +5,0 @@ "description": "pure-JS library to format data using ECMA-376 spreadsheet Format Codes",

@@ -8,3 +8,3 @@ /* ssf.js (C) 2013-2014 SheetJS -- http://sheetjs.com */

function rpad(v,d,c){var t=String(v);return t.length>=d?t:(t+fill(c||0,d-t.length));}
SSF.version = '0.6.5';
SSF.version = '0.7.0';
/* Options */

@@ -153,4 +153,4 @@ var opts_fmt = {

/*jshint -W086 */
var write_date = function(type, fmt, val) {
var o, ss, y = val.y;
var write_date = function(type, fmt, val, ss0) {
var o, ss, tt, y = val.y, sss0;
switch(type) {

@@ -192,7 +192,11 @@ case 'b': y = val.y + 543;

case 's': switch(fmt) { /* seconds */
case 's': ss=Math.round(val.S+val.u); return ss >= 60 ? 0 : ss;
case 'ss': ss=Math.round(val.S+val.u); if(ss>=60) ss=0; return pad(ss,2);
case 'ss.0': ss=Math.round(10*(val.S+val.u)); if(ss>=600) ss = 0; o = pad(ss,3); return o.substr(0,2)+"." + o.substr(2);
case 'ss.00': ss=Math.round(100*(val.S+val.u)); if(ss>=6000) ss = 0; o = pad(ss,4); return o.substr(0,2)+"." + o.substr(2);
case 'ss.000': ss=Math.round(1000*(val.S+val.u)); if(ss>=60000) ss = 0; o = pad(ss,5); return o.substr(0,2)+"." + o.substr(2);
case 's': case 'ss': case '.0': case '.00': case '.000':
sss0 = ss0 || 0;
tt = Math.pow(10,sss0);
ss = Math.round((tt)*(val.S + val.u));
if(fmt === 's') return ss >= 60*tt ? 0 : ss/tt;
else if(fmt === 'ss') { if(ss>=60*tt) ss=0; return pad(ss,(2+sss0)).substr(0,2); }
if(ss >= 60*tt) ss = 0;
o = pad(ss,2 + sss0);
return "." + o.substr(2,fmt.length-1);
default: throw 'bad second format: ' + fmt;

@@ -206,3 +210,2 @@ }

} return fmt.length === 3 ? o : pad(o, 2);
/* TODO: handle the ECMA spec format ee -> yy */
case 'e': { return val.y; } break;

@@ -292,2 +295,13 @@ }

}
if((r = fmt.match(/^[#0]+$/))) {
o = "" + Math.round(val);
if(fmt.length <= o.length) return o;
return fmt.substr(0,fmt.length - o.length).replace(/#/g,"") + o;
}
if((r = fmt.match(/^([#0]+)\.([#0]+)$/))) {
o = "" + val.toFixed(Math.min(r[2].length,10)).replace(/([^0])0+$/,"$1");
rr = o.indexOf(".");
var lres = fmt.indexOf(".") - rr, rres = fmt.length - o.length - lres;
return fmt.substr(0,lres).replace(/#/g,"") + o + fmt.substr(fmt.length-rres).replace(/#/g,"");
}
if((r = fmt.match(/^00,000\.([#0]*0)$/))) {

@@ -298,3 +312,2 @@ rr = val == Math.floor(val) ? 0 : Math.round((val-Math.floor(val))*Math.pow(10,r[1].length));

switch(fmt) {
case "0": case "#0": return ""+Math.round(val);
case "#,###": var x = commaify(String(Math.round(aval))); return x !== "0" ? sign + x : "";

@@ -322,3 +335,3 @@ default:

function eval_fmt(fmt, v, opts, flen) {
var out = [], o = "", i = 0, c = "", lst='t', q, dt;
var out = [], o = "", i = 0, c = "", lst='t', q, dt, j;
fixopts(opts = (opts || {}));

@@ -355,3 +368,2 @@ var hr='H';

o = fmt[i]; while((fmt[++i]||"").toLowerCase() === c) o+=c;
if(c === 's' && fmt[i] === '.' && fmt[i+1] === '0') { o+='.'; while(fmt[++i] === '0') o+= '0'; }
if(c === 'm' && lst.toLowerCase() === 'h') c = 'M'; /* m = minute */

@@ -380,3 +392,9 @@ if(c === 'h') c = hr;

/* Numbers */
case '0': case '#': case '.':
case '.':
if(dt) {
o = c; while((c=fmt[++i]) === "0") o += c;
out.push({t:'s', v:o}); break;
}
/* falls through */
case '0': case '#':
o = c; while("0#?.,E+-%".indexOf(c=fmt[++i]) > -1 || c=='\\' && fmt[i+1] == "-" && "0#".indexOf(fmt[i+2])>-1) o += c;

@@ -399,7 +417,9 @@ out.push({t:'n', v:o}); break;

}
var bt = 0;
var bt = 0, ss0 = 0, ssm;
for(i=out.length-1, lst='t'; i >= 0; --i) {
switch(out[i].t) {
case 'h': case 'H': out[i].t = hr; lst='h'; if(bt < 1) bt = 1; break;
case 's': if(bt < 3) bt = 3;
case 's':
if((ssm=out[i].v.match(/\.0+$/))) ss0=Math.max(ss0,ssm[0].length-1);
if(bt < 3) bt = 3;
/* falls through */

@@ -429,2 +449,3 @@ case 'd': case 'y': case 'M': case 'e': lst=out[i].t; break;

/* replace fields */
var nstr = "", jj;
for(i=0; i < out.length; ++i) {

@@ -435,6 +456,6 @@ switch(out[i].t) {

case 'd': case 'm': case 'y': case 'h': case 'H': case 'M': case 's': case 'e': case 'b': case 'Z':
out[i].v = write_date(out[i].t, out[i].v, dt);
out[i].v = write_date(out[i].t, out[i].v, dt, ss0);
out[i].t = 't'; break;
case 'n': case '(': case '?':
var jj = i+1;
jj = i+1;
while(out[jj] && ("?D".indexOf(out[jj].t) > -1 || (" t".indexOf(out[jj].t) > -1 && "?t".indexOf((out[jj+1]||{}).t)>-1 && (out[jj+1].t == '?' || out[jj+1].v == '/')) || out[i].t == '(' && (")n ".indexOf(out[jj].t) > -1) || out[jj].t == 't' && (out[jj].v == '/' || '$€'.indexOf(out[jj].v) > -1 || (out[jj].v == ' ' && (out[jj+1]||{}).t == '?')))) {

@@ -444,4 +465,3 @@ out[i].v += out[jj].v;

}
out[i].v = write_num(out[i].t, out[i].v, (flen >1 && v < 0 && i>0 && out[i-1].v == "-" ? -v:v));
out[i].t = 't';
nstr += out[i].v;
i = jj-1; break;

@@ -451,2 +471,54 @@ case 'G': out[i].t = 't'; out[i].v = general_fmt(v,opts); break;

}
if(nstr) {
var ostr = write_num(nstr[0]=='(' ? '(' : 'n', nstr, (v<0&&nstr[0] == "-" ? -v : v));
jj=ostr.length-1;
var decpt = out.length;
for(i=0; i < out.length; ++i) if(out[i] && out[i].v.indexOf(".") > -1) { decpt = i; break; }
var lasti=out.length, vv;
if(decpt === out.length && !ostr.match(/E/)) {
for(i=out.length-1; i>= 0;--i) {
if(!out[i] || 'n?('.indexOf(out[i].t) === -1) continue;
vv = out[i].v.split("");
for(j=vv.length-1; j>=0; --j) {
if(jj>=0) vv[j] = ostr[jj--];
else vv[j] = "";
}
out[i].v = vv.join("");
out[i].t = 't';
lasti = i;
}
if(jj>=0 && lasti<out.length) out[lasti].v = ostr.substr(0,jj+1) + out[lasti].v;
}
else if(decpt !== out.length && !ostr.match(/E/)) {
jj = ostr.indexOf(".")-1;
for(i=decpt; i>= 0; --i) {
if(!out[i] || 'n?('.indexOf(out[i].t) === -1) continue;
vv = out[i].v.split("");
for(j=out[i].v.indexOf(".")>-1&&i==decpt?out[i].v.indexOf(".")-1:vv.length-1; j>=0; --j) {
if(jj>=0 && "0#".indexOf(vv[j])>-1) vv[j] = ostr[jj--];
else vv[j] = "";
}
out[i].v = vv.join("");
out[i].t = 't';
lasti = i;
}
if(jj>=0 && lasti<out.length) out[lasti].v = ostr.substr(0,jj+1) + out[lasti].v;
jj = ostr.indexOf(".")+1;
for(i=decpt; i<out.length; ++i) {
if(!out[i] || 'n?('.indexOf(out[i].t) === -1 && i != decpt ) continue;
vv = out[i].v.split("");
for(j=out[i].v.indexOf(".")>-1&&i==decpt?out[i].v.indexOf(".")+1:0; j<vv.length; ++j) {
if(jj<ostr.length) vv[j] = ostr[jj++];
else vv[j] = "";
}
out[i].v = vv.join("");
out[i].t = 't';
lasti = i;
}
}
}
for(i=0; i<out.length; ++i) if(out[i] && 'n(?'.indexOf(out[i].t)>-1) {
out[i].v = write_num(out[i].t, out[i].v, (flen >1 && v < 0 && i>0 && out[i-1].v == "-" ? -v:v));
out[i].t = 't';
}
return out.map(function(x){return x.v;}).join("");

@@ -453,0 +525,0 @@ }

@@ -514,2 +514,18 @@ # SSF

The general class `/^[#0]+$/` treats the unconsumed '0' as literal, '#' as noop:
```
if((r = fmt.match(/^[#0]+$/))) {
o = "" + Math.round(val);
if(fmt.length <= o.length) return o;
return fmt.substr(0,fmt.length - o.length).replace(/#/g,"") + o;
}
if((r = fmt.match(/^([#0]+)\.([#0]+)$/))) {
o = "" + val.toFixed(Math.min(r[2].length,10)).replace(/([^0])0+$/,"$1");
rr = o.indexOf(".");
var lres = fmt.indexOf(".") - rr, rres = fmt.length - o.length - lres;
return fmt.substr(0,lres).replace(/#/g,"") + o + fmt.substr(fmt.length-rres).replace(/#/g,"");
}
```
The default cases are hard-coded. TODO: actually parse them

@@ -528,3 +544,2 @@

switch(fmt) {
case "0": case "#0": return ""+Math.round(val);
case "#,###": var x = commaify(String(Math.round(aval))); return x !== "0" ? sign + x : "";

@@ -546,3 +561,3 @@ ```

function eval_fmt(fmt, v, opts, flen) {
var out = [], o = "", i = 0, c = "", lst='t', q, dt;
var out = [], o = "", i = 0, c = "", lst='t', q, dt, j;
fixopts(opts = (opts || {}));

@@ -631,8 +646,2 @@ var hr='H';

For the special case of s.00, the suffix should be swallowed with the s:
```
if(c === 's' && fmt[i] === '.' && fmt[i+1] === '0') { o+='.'; while(fmt[++i] === '0') o+= '0'; }
```
Only the forward corrections are made here. The reverse corrections are made later:

@@ -683,7 +692,15 @@

Number blocks (following the general pattern `[0#?][0#?.,E+-%]*`) are grouped
together. Literal hyphens are swallowed as well:
together. Literal hyphens are swallowed as well. Since `.000` is a valid
term (for tenths/hundredths/thousandths of a second), it must be handled
separately:
```
/* Numbers */
case '0': case '#': case '.':
case '.':
if(dt) {
o = c; while((c=fmt[++i]) === "0") o += c;
out.push({t:'s', v:o}); break;
}
/* falls through */
case '0': case '#':
o = c; while("0#?.,E+-%".indexOf(c=fmt[++i]) > -1 || c=='\\' && fmt[i+1] == "-" && "0#".indexOf(fmt[i+2])>-1) o += c;

@@ -740,10 +757,13 @@ out.push({t:'n', v:o}); break;

appears after the minute itself, scan backwards. At the same time, we can
identify the smallest time unit (0 = no time, 1 = hour, 2 = minute, 3 = second):
identify the smallest time unit (0 = no time, 1 = hour, 2 = minute, 3 = second)
and the required number of digits for the sub-seconds:
```
var bt = 0;
var bt = 0, ss0 = 0, ssm;
for(i=out.length-1, lst='t'; i >= 0; --i) {
switch(out[i].t) {
case 'h': case 'H': out[i].t = hr; lst='h'; if(bt < 1) bt = 1; break;
case 's': if(bt < 3) bt = 3;
case 's':
if((ssm=out[i].v.match(/\.0+$/))) ss0=Math.max(ss0,ssm[0].length-1);
if(bt < 3) bt = 3;
/* falls through */

@@ -779,6 +799,8 @@ case 'd': case 'y': case 'M': case 'e': lst=out[i].t; break;

Finally, actually write the numbers:
Since number groups in a string should be treated as part of the same whole,
group them together to construct the real number string:
```
/* replace fields */
var nstr = "", jj;
for(i=0; i < out.length; ++i) {

@@ -789,6 +811,6 @@ switch(out[i].t) {

case 'd': case 'm': case 'y': case 'h': case 'H': case 'M': case 's': case 'e': case 'b': case 'Z':
out[i].v = write_date(out[i].t, out[i].v, dt);
out[i].v = write_date(out[i].t, out[i].v, dt, ss0);
out[i].t = 't'; break;
case 'n': case '(': case '?':
var jj = i+1;
jj = i+1;
while(out[jj] && ("?D".indexOf(out[jj].t) > -1 || (" t".indexOf(out[jj].t) > -1 && "?t".indexOf((out[jj+1]||{}).t)>-1 && (out[jj+1].t == '?' || out[jj+1].v == '/')) || out[i].t == '(' && (")n ".indexOf(out[jj].t) > -1) || out[jj].t == 't' && (out[jj].v == '/' || '$€'.indexOf(out[jj].v) > -1 || (out[jj].v == ' ' && (out[jj+1]||{}).t == '?')))) {

@@ -798,4 +820,76 @@ out[i].v += out[jj].v;

}
nstr += out[i].v;
i = jj-1; break;
case 'G': out[i].t = 't'; out[i].v = general_fmt(v,opts); break;
}
}
```
Next, process the complete number string:
```
if(nstr) {
var ostr = write_num(nstr[0]=='(' ? '(' : 'n', nstr, (v<0&&nstr[0] == "-" ? -v : v));
jj=ostr.length-1;
```
Find the first decimal point:
```
var decpt = out.length;
for(i=0; i < out.length; ++i) if(out[i] && out[i].v.indexOf(".") > -1) { decpt = i; break; }
var lasti=out.length, vv;
```
If there is no decimal point or exponential, the algorithm is straightforward:
```
if(decpt === out.length && !ostr.match(/E/)) {
for(i=out.length-1; i>= 0;--i) {
if(!out[i] || 'n?('.indexOf(out[i].t) === -1) continue;
vv = out[i].v.split("");
for(j=vv.length-1; j>=0; --j) {
if(jj>=0) vv[j] = ostr[jj--];
else vv[j] = "";
}
out[i].v = vv.join("");
out[i].t = 't';
lasti = i;
}
if(jj>=0 && lasti<out.length) out[lasti].v = ostr.substr(0,jj+1) + out[lasti].v;
}
```
Otherwise we have to do something a bit trickier:
```
else if(decpt !== out.length && !ostr.match(/E/)) {
jj = ostr.indexOf(".")-1;
for(i=decpt; i>= 0; --i) {
if(!out[i] || 'n?('.indexOf(out[i].t) === -1) continue;
vv = out[i].v.split("");
for(j=out[i].v.indexOf(".")>-1&&i==decpt?out[i].v.indexOf(".")-1:vv.length-1; j>=0; --j) {
if(jj>=0 && "0#".indexOf(vv[j])>-1) vv[j] = ostr[jj--];
else vv[j] = "";
}
out[i].v = vv.join("");
out[i].t = 't';
lasti = i;
}
if(jj>=0 && lasti<out.length) out[lasti].v = ostr.substr(0,jj+1) + out[lasti].v;
jj = ostr.indexOf(".")+1;
for(i=decpt; i<out.length; ++i) {
if(!out[i] || 'n?('.indexOf(out[i].t) === -1 && i != decpt ) continue;
vv = out[i].v.split("");
for(j=out[i].v.indexOf(".")>-1&&i==decpt?out[i].v.indexOf(".")+1:0; j<vv.length; ++j) {
if(jj<ostr.length) vv[j] = ostr[jj++];
else vv[j] = "";
}
out[i].v = vv.join("");
out[i].t = 't';
lasti = i;
}
}
}
```
The magic in the next line is to ensure that the negative number is passed as

@@ -805,14 +899,11 @@ positive when there is an explicit hyphen before it (e.g. `#,##0.0;-#,##0.0`):

```
out[i].v = write_num(out[i].t, out[i].v, (flen >1 && v < 0 && i>0 && out[i-1].v == "-" ? -v:v));
out[i].t = 't';
i = jj-1; break;
case 'G': out[i].t = 't'; out[i].v = general_fmt(v,opts); break;
for(i=0; i<out.length; ++i) if(out[i] && 'n(?'.indexOf(out[i].t)>-1) {
out[i].v = write_num(out[i].t, out[i].v, (flen >1 && v < 0 && i>0 && out[i-1].v == "-" ? -v:v));
out[i].t = 't';
}
```
The default case should not be reachable. In testing, add the line
`default: console.error(out); throw "unrecognized type " + out[i].t;`
Now we just need to combine the elements
```
}
}
return out.map(function(x){return x.v;}).join("");

@@ -832,4 +923,4 @@ }

/*jshint -W086 */
var write_date = function(type, fmt, val) {
var o, ss, y = val.y;
var write_date = function(type, fmt, val, ss0) {
var o, ss, tt, y = val.y, sss0;
switch(type) {

@@ -891,7 +982,17 @@ ```

case 's': switch(fmt) { /* seconds */
case 's': ss=Math.round(val.S+val.u); return ss >= 60 ? 0 : ss;
case 'ss': ss=Math.round(val.S+val.u); if(ss>=60) ss=0; return pad(ss,2);
case 'ss.0': ss=Math.round(10*(val.S+val.u)); if(ss>=600) ss = 0; o = pad(ss,3); return o.substr(0,2)+"." + o.substr(2);
case 'ss.00': ss=Math.round(100*(val.S+val.u)); if(ss>=6000) ss = 0; o = pad(ss,4); return o.substr(0,2)+"." + o.substr(2);
case 'ss.000': ss=Math.round(1000*(val.S+val.u)); if(ss>=60000) ss = 0; o = pad(ss,5); return o.substr(0,2)+"." + o.substr(2);
```
Unfortunately, the actual subsecond string is based on the presence of other
terms. That is passed via the `ss0` parameter:
```
case 's': case 'ss': case '.0': case '.00': case '.000':
sss0 = ss0 || 0;
tt = Math.pow(10,sss0);
ss = Math.round((tt)*(val.S + val.u));
if(fmt === 's') return ss >= 60*tt ? 0 : ss/tt;
else if(fmt === 'ss') { if(ss>=60*tt) ss=0; return pad(ss,(2+sss0)).substr(0,2); }
if(ss >= 60*tt) ss = 0;
o = pad(ss,2 + sss0);
return "." + o.substr(2,fmt.length-1);
default: throw 'bad second format: ' + fmt;

@@ -916,3 +1017,2 @@ }

```
/* TODO: handle the ECMA spec format ee -> yy */
case 'e': { return val.y; } break;

@@ -1161,3 +1261,3 @@ ```

"name": "ssf",
"version": "0.6.5",
"version": "0.7.0",
"author": "SheetJS",

@@ -1164,0 +1264,0 @@ "description": "pure-JS library to format data using ECMA-376 spreadsheet Format Codes",

@@ -44,2 +44,7 @@ [

["hh:mm:sss", [0.7]],
["hh:mm:ss.000", [0.7,"16:48:00.000"], [0.70707,"16:58:10.848"]],
["hh.000", [0.70707, "16.848"]],
["hh .00", [0.70707, "16 .85"]],
["hh .0", [0.70707, "16 .8"]],
["hh .00 .000", [0.70707, "16 .84 .848"]],
["[hhh]", [0.7]],

@@ -75,2 +80,40 @@ ["[", [0.7]],

],
["000#0#0#0##00##00##0#########",
[12345, "0000000000012345"]
],
["0#######0.##0##0######00######0",
[12.3456789, "012.3456789000"]
],
["###\\###\\##0.00",
[0.00101, "##0.00"],
[0.0101, "##0.01"],
[0.101, "##0.10"],
[1.01, "##1.01"],
[10.1, "##10.10"],
[101, "#1#01.00"],
[1010, "#10#10.00"],
[10100, "1#01#00.00"],
[101000, "10#10#00.00"],
[1010000, "101#00#00.00"],
[10100000, "1010#00#00.00"],
[101000000, "10100#00#00.00"],
[123456789.01, "12345#67#89.01"]
],
["###\\\\###\\\\##\\0.00",
[0.00101, "\\\\0.00"],
[0.0101, "\\\\0.01"],
[0.101, "\\\\0.10"],
[1.01, "\\\\10.01"],
[10.1, "\\\\100.10"],
[101, "\\1\\010.00"],
[1010, "\\10\\100.00"],
[10100, "\\101\\000.00"],
[101000, "1\\010\\000.00"],
[1010000, "10\\100\\000.00"],
[10100000, "101\\000\\000.00"],
[101000000, "1010\\000\\000.00"],
[123456789.01, "1234\\567\\890.01"]
],
["###\\\\###\\\\##\\0", [12345.6789, "\\123\\460"]],
["00000-0000", [941051630, "94105-1630"]],

@@ -77,0 +120,0 @@ ["000-00-0000", [123456789, "123-45-6789"]],

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc