Comparing version 0.5.2 to 0.5.3
{ | ||
"name": "ssf", | ||
"version": "0.5.2", | ||
"version": "0.5.3", | ||
"author": "SheetJS", | ||
@@ -5,0 +5,0 @@ "description": "pure-JS library to format data using ECMA-376 spreadsheet Format Codes", |
58
ssf.js
@@ -8,2 +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.5.3'; | ||
/* Options */ | ||
@@ -44,3 +45,5 @@ var opts_fmt = {}; | ||
48: '##0.0E+0', | ||
49: '@' | ||
49: '@', | ||
56: '"上午/下午 "hh"時"mm"分"ss"秒 "', | ||
65535: 'General' | ||
}; | ||
@@ -197,3 +200,2 @@ var days = [ | ||
case 'e': { return val.y; } break; | ||
case 'A': return (val.h>=12 ? 'P' : 'A') + fmt.substr(1); | ||
default: throw 'bad format type ' + type + ' in ' + fmt; | ||
@@ -215,3 +217,2 @@ } | ||
var idx = fmt.indexOf("E") - fmt.indexOf(".") - 1; | ||
//if(fmt.match(/^#+0\.0E\+0$/)) | ||
if(fmt == '##0.0E+0') { | ||
@@ -234,17 +235,20 @@ var period = fmt.length - 5; | ||
var r, ff, aval = val < 0 ? -val : val, sign = val < 0 ? "-" : ""; | ||
if((r = fmt.match(/# (\?+) \/ (\d+)/))) { | ||
var den = Number(r[2]), rnd = Math.round(aval * den), base = Math.floor(rnd/den); | ||
if((r = fmt.match(/# (\?+)([ ]?)\/([ ]?)(\d+)/))) { | ||
var den = Number(r[4]), rnd = Math.round(aval * den), base = Math.floor(rnd/den); | ||
var myn = (rnd - base*den), myd = den; | ||
return sign + (base?base:"") + " " + (myn === 0 ? fill(" ", r[1].length + 1 + r[2].length) : pad(myn,r[1].length," ") + "/" + pad(myd,r[2].length)); | ||
return sign + (base?base:"") + " " + (myn === 0 ? fill(" ", r[1].length + 1 + r[4].length) : pad(myn,r[1].length," ") + r[2] + "/" + r[3] + pad(myd,r[4].length)); | ||
} | ||
if(fmt.match(/^00*$/)) return (val<0?"-":"")+pad(Math.round(aval),fmt.length); | ||
if(fmt.match(/^####*$/)) return Math.round(val); | ||
if(fmt.match(/^00+$/)) return (val<0?"-":"")+pad(Math.round(aval),fmt.length); | ||
if(fmt.match(/^[#?]+$/)) return String(Math.round(val)).replace(/^0$/,""); | ||
if(r = fmt.match(/^#*0+\.(0+)/)) { | ||
o = Math.round(val * Math.pow(10,r[1].length)); | ||
return String(o/Math.pow(10,r[1].length)).replace(/^([^\.]+)$/,"$1."+r[1]).replace(/\.$/,"."+r[1]).replace(/\.([0-9]*)$/,function($$, $1) { return "." + $1 + fill("0", r[1].length-$1.length); }); | ||
} | ||
if(r = fmt.match(/^# ([?]+)([ ]?)\/([ ]?)([?]+)/)) { | ||
var rr = Math.min(Math.max(r[1].length, r[4].length),7); | ||
ff = frac(aval, Math.pow(10,rr)-1, true); | ||
return sign + (ff[0]||(ff[1] ? "" : "0")) + " " + (ff[1] ? pad(ff[1],rr," ") + r[2] + "/" + r[3] + rpad(ff[2],rr," "): fill(" ", 2*rr+1 + r[2].length + r[3].length)); | ||
} | ||
switch(fmt) { | ||
case "0": return Math.round(val); | ||
case "0.0": o = Math.round(val*10); | ||
return String(o/10).replace(/^([^\.]+)$/,"$1.0").replace(/\.$/,".0"); | ||
case "0.00": o = Math.round(val*100); | ||
return String(o/100).replace(/^([^\.]+)$/,"$1.00").replace(/\.$/,".00").replace(/\.([0-9])$/,".$1"+"0"); | ||
case "0.000": o = Math.round(val*1000); | ||
return String(o/1000).replace(/^([^\.]+)$/,"$1.000").replace(/\.$/,".000").replace(/\.([0-9])$/,".$1"+"00").replace(/\.([0-9][0-9])$/,".$1"+"0"); | ||
case "0": case "#0": return Math.round(val); | ||
case "#.##": o = Math.round(val*100); | ||
@@ -254,7 +258,11 @@ return String(o/100).replace(/^([^\.]+)$/,"$1.").replace(/^0\.$/,"."); | ||
case "#,##0": return sign + commaify(String(Math.round(aval))); | ||
case "#,##0.0": r = Math.round((val-Math.floor(val))*10); return val < 0 ? "-" + write_num(type, fmt, -val) : commaify(String(Math.floor(val))) + "." + r; | ||
case "#,##0.00": r = Math.round((val-Math.floor(val))*100); return val < 0 ? "-" + write_num(type, fmt, -val) : commaify(String(Math.floor(val))) + "." + (r < 10 ? "0"+r:r); | ||
case "# ? / ?": ff = frac(aval, 9, true); return sign + (ff[0]||(ff[1] ? "" : "0")) + " " + (ff[1] === 0 ? " " : ff[1] + "/" + ff[2]); | ||
case "# ?? / ??": ff = frac(aval, 99, true); return sign + (ff[0]||(ff[1] ? "" : "0")) + " " + (ff[1] ? pad(ff[1],2," ") + "/" + rpad(ff[2],2," ") : " "); | ||
case "# ??? / ???": ff = frac(aval, 999, true); return sign + (ff[0]||(ff[1] ? "" : "0")) + " " + (ff[1] ? pad(ff[1],3," ") + "/" + rpad(ff[2],3," ") : " "); | ||
case "#,##0.0": r = Math.round((val-Math.floor(val))*10); return val < 0 ? "-" + write_num(type, fmt, -val) : commaify(String(Math.floor(val))) + "." + pad(r,1,"0"); | ||
case "#,##0.00": r = Math.round((val-Math.floor(val))*100); return val < 0 ? "-" + write_num(type, fmt, -val) : commaify(String(Math.floor(val))) + "." + pad(r,2,"0"); | ||
case "#,##0.000": r = Math.round((val-Math.floor(val))*1000); return val < 0 ? "-" + write_num(type, fmt, -val) : commaify(String(Math.floor(val))) + "." + pad(r,3,0); | ||
case "#,##0.0000": r = Math.round((val-Math.floor(val))*10000); return val < 0 ? "-" + write_num(type, fmt, -val) : commaify(String(Math.floor(val))) + "." + pad(r,4,0); | ||
case "#,##0.00000": r = Math.round((val-Math.floor(val))*Math.pow(10,5)); return val < 0 ? "-" + write_num(type, fmt, -val) : commaify(String(Math.floor(val))) + "." + pad(r,5,0); | ||
case "#,##0.000000": r = Math.round((val-Math.floor(val))*Math.pow(10,6)); return val < 0 ? "-" + write_num(type, fmt, -val) : commaify(String(Math.floor(val))) + "." + pad(r,6,0); | ||
case "#,##0.0000000": r = Math.round((val-Math.floor(val))*Math.pow(10,7)); return val < 0 ? "-" + write_num(type, fmt, -val) : commaify(String(Math.floor(val))) + "." + pad(r,7,0); | ||
case "#,##0.00000000": r = Math.round((val-Math.floor(val))*Math.pow(10,8)); return val < 0 ? "-" + write_num(type, fmt, -val) : commaify(String(Math.floor(val))) + "." + pad(r,8,0); | ||
case "#,##0.000000000": r = Math.round((val-Math.floor(val))*Math.pow(10,9)); return val < 0 ? "-" + write_num(type, fmt, -val) : commaify(String(Math.floor(val))) + "." + pad(r,9,0); | ||
default: | ||
@@ -344,3 +352,3 @@ } | ||
default: | ||
if("$-+/():!^&'~{}<>=".indexOf(c) === -1) | ||
if(",$-+/():!^&'~{}<>=".indexOf(c) === -1) | ||
throw 'unrecognized character ' + fmt[i] + ' in ' + fmt; | ||
@@ -367,6 +375,6 @@ out.push({t:'t', v:c}); ++i; break; | ||
out[i].t = 't'; break; | ||
case 'n': case '(': | ||
case 'n': case '(': case '?': | ||
var jj = i+1; | ||
while(out[jj] && ("?D".indexOf(out[jj].t) > -1 || (out[jj].t == " " && (out[jj+1]||{}).t === "?" ) || out[i].t == '(' && (out[jj].t == ')' || out[jj].t == 'n') || out[jj].t == 't' && (out[jj].v == '/' || out[jj].v == '$' || (out[jj].v == ' ' && (out[jj+1]||{}).t == '?')))) { | ||
if(out[jj].v!==' ') out[i].v += ' ' + out[jj].v; | ||
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 == '(' && (out[jj].t == ')' || out[jj].t == 'n') || out[jj].t == 't' && (out[jj].v == '/' || out[jj].v == '$' || (out[jj].v == ' ' && (out[jj+1]||{}).t == '?')))) { | ||
out[i].v += out[jj].v; | ||
delete out[jj]; ++jj; | ||
@@ -378,3 +386,3 @@ } | ||
case 'G': out[i].t = 't'; out[i].v = general_fmt(v,opts); break; | ||
default: throw "unrecognized type " + out[i].t; | ||
default: console.error(out); throw "unrecognized type " + out[i].t; | ||
} | ||
@@ -381,0 +389,0 @@ } |
79
ssf.md
@@ -217,3 +217,16 @@ # SSF | ||
48: '##0.0E+0', | ||
49: '@' | ||
49: '@', | ||
``` | ||
There are special implicit format codes identified in [ECMA-376] 18.8.30. | ||
Assuming zh-tw is the default: | ||
``` | ||
56: '"上午/下午 "hh"時"mm"分"ss"秒 "', | ||
``` | ||
some writers erroneously emit 65535 for general: | ||
``` | ||
65535: 'General' | ||
}; | ||
@@ -349,3 +362,2 @@ ``` | ||
Percentage values should be physically shifted: | ||
@@ -369,3 +381,2 @@ | ||
``` | ||
//if(fmt.match(/^#+0\.0E\+0$/)) | ||
if(fmt == '##0.0E+0') { | ||
@@ -403,6 +414,6 @@ var period = fmt.length - 5; | ||
var r, ff, aval = val < 0 ? -val : val, sign = val < 0 ? "-" : ""; | ||
if((r = fmt.match(/# (\?+) \/ (\d+)/))) { | ||
var den = Number(r[2]), rnd = Math.round(aval * den), base = Math.floor(rnd/den); | ||
if((r = fmt.match(/# (\?+)([ ]?)\/([ ]?)(\d+)/))) { | ||
var den = Number(r[4]), rnd = Math.round(aval * den), base = Math.floor(rnd/den); | ||
var myn = (rnd - base*den), myd = den; | ||
return sign + (base?base:"") + " " + (myn === 0 ? fill(" ", r[1].length + 1 + r[2].length) : pad(myn,r[1].length," ") + "/" + pad(myd,r[2].length)); | ||
return sign + (base?base:"") + " " + (myn === 0 ? fill(" ", r[1].length + 1 + r[4].length) : pad(myn,r[1].length," ") + r[2] + "/" + r[3] + pad(myd,r[4].length)); | ||
} | ||
@@ -414,6 +425,20 @@ ``` | ||
``` | ||
if(fmt.match(/^00*$/)) return (val<0?"-":"")+pad(Math.round(aval),fmt.length); | ||
if(fmt.match(/^####*$/)) return Math.round(val); | ||
if(fmt.match(/^00+$/)) return (val<0?"-":"")+pad(Math.round(aval),fmt.length); | ||
if(fmt.match(/^[#?]+$/)) return String(Math.round(val)).replace(/^0$/,""); | ||
if(r = fmt.match(/^#*0+\.(0+)/)) { | ||
o = Math.round(val * Math.pow(10,r[1].length)); | ||
return String(o/Math.pow(10,r[1].length)).replace(/^([^\.]+)$/,"$1."+r[1]).replace(/\.$/,"."+r[1]).replace(/\.([0-9]*)$/,function($$, $1) { return "." + $1 + fill("0", r[1].length-$1.length); }); | ||
} | ||
``` | ||
The frac helper function is used for fraction formats (defined below). | ||
``` | ||
if(r = fmt.match(/^# ([?]+)([ ]?)\/([ ]?)([?]+)/)) { | ||
var rr = Math.min(Math.max(r[1].length, r[4].length),7); | ||
ff = frac(aval, Math.pow(10,rr)-1, true); | ||
return sign + (ff[0]||(ff[1] ? "" : "0")) + " " + (ff[1] ? pad(ff[1],rr," ") + r[2] + "/" + r[3] + rpad(ff[2],rr," "): fill(" ", 2*rr+1 + r[2].length + r[3].length)); | ||
} | ||
``` | ||
The default cases are hard-coded. TODO: actually parse them | ||
@@ -423,9 +448,3 @@ | ||
switch(fmt) { | ||
case "0": return Math.round(val); | ||
case "0.0": o = Math.round(val*10); | ||
return String(o/10).replace(/^([^\.]+)$/,"$1.0").replace(/\.$/,".0"); | ||
case "0.00": o = Math.round(val*100); | ||
return String(o/100).replace(/^([^\.]+)$/,"$1.00").replace(/\.$/,".00").replace(/\.([0-9])$/,".$1"+"0"); | ||
case "0.000": o = Math.round(val*1000); | ||
return String(o/1000).replace(/^([^\.]+)$/,"$1.000").replace(/\.$/,".000").replace(/\.([0-9])$/,".$1"+"00").replace(/\.([0-9][0-9])$/,".$1"+"0"); | ||
case "0": case "#0": return Math.round(val); | ||
case "#.##": o = Math.round(val*100); | ||
@@ -435,12 +454,16 @@ return String(o/100).replace(/^([^\.]+)$/,"$1.").replace(/^0\.$/,"."); | ||
case "#,##0": return sign + commaify(String(Math.round(aval))); | ||
case "#,##0.0": r = Math.round((val-Math.floor(val))*10); return val < 0 ? "-" + write_num(type, fmt, -val) : commaify(String(Math.floor(val))) + "." + r; | ||
case "#,##0.00": r = Math.round((val-Math.floor(val))*100); return val < 0 ? "-" + write_num(type, fmt, -val) : commaify(String(Math.floor(val))) + "." + (r < 10 ? "0"+r:r); | ||
case "#,##0.0": r = Math.round((val-Math.floor(val))*10); return val < 0 ? "-" + write_num(type, fmt, -val) : commaify(String(Math.floor(val))) + "." + pad(r,1,"0"); | ||
case "#,##0.00": r = Math.round((val-Math.floor(val))*100); return val < 0 ? "-" + write_num(type, fmt, -val) : commaify(String(Math.floor(val))) + "." + pad(r,2,"0"); | ||
case "#,##0.000": r = Math.round((val-Math.floor(val))*1000); return val < 0 ? "-" + write_num(type, fmt, -val) : commaify(String(Math.floor(val))) + "." + pad(r,3,0); | ||
case "#,##0.0000": r = Math.round((val-Math.floor(val))*10000); return val < 0 ? "-" + write_num(type, fmt, -val) : commaify(String(Math.floor(val))) + "." + pad(r,4,0); | ||
case "#,##0.00000": r = Math.round((val-Math.floor(val))*Math.pow(10,5)); return val < 0 ? "-" + write_num(type, fmt, -val) : commaify(String(Math.floor(val))) + "." + pad(r,5,0); | ||
case "#,##0.000000": r = Math.round((val-Math.floor(val))*Math.pow(10,6)); return val < 0 ? "-" + write_num(type, fmt, -val) : commaify(String(Math.floor(val))) + "." + pad(r,6,0); | ||
case "#,##0.0000000": r = Math.round((val-Math.floor(val))*Math.pow(10,7)); return val < 0 ? "-" + write_num(type, fmt, -val) : commaify(String(Math.floor(val))) + "." + pad(r,7,0); | ||
case "#,##0.00000000": r = Math.round((val-Math.floor(val))*Math.pow(10,8)); return val < 0 ? "-" + write_num(type, fmt, -val) : commaify(String(Math.floor(val))) + "." + pad(r,8,0); | ||
case "#,##0.000000000": r = Math.round((val-Math.floor(val))*Math.pow(10,9)); return val < 0 ? "-" + write_num(type, fmt, -val) : commaify(String(Math.floor(val))) + "." + pad(r,9,0); | ||
``` | ||
The frac helper function is used for fraction formats (defined below). | ||
For now, the default case is an error: | ||
```js>tmp/60_number.js | ||
case "# ? / ?": ff = frac(aval, 9, true); return sign + (ff[0]||(ff[1] ? "" : "0")) + " " + (ff[1] === 0 ? " " : ff[1] + "/" + ff[2]); | ||
case "# ?? / ??": ff = frac(aval, 99, true); return sign + (ff[0]||(ff[1] ? "" : "0")) + " " + (ff[1] ? pad(ff[1],2," ") + "/" + rpad(ff[2],2," ") : " "); | ||
case "# ??? / ???": ff = frac(aval, 999, true); return sign + (ff[0]||(ff[1] ? "" : "0")) + " " + (ff[1] ? pad(ff[1],3," ") + "/" + rpad(ff[2],3," ") : " "); | ||
default: | ||
@@ -625,3 +648,3 @@ } | ||
default: | ||
if("$-+/():!^&'~{}<>=".indexOf(c) === -1) | ||
if(",$-+/():!^&'~{}<>=".indexOf(c) === -1) | ||
throw 'unrecognized character ' + fmt[i] + ' in ' + fmt; | ||
@@ -648,6 +671,6 @@ out.push({t:'t', v:c}); ++i; break; | ||
out[i].t = 't'; break; | ||
case 'n': case '(': | ||
case 'n': case '(': case '?': | ||
var jj = i+1; | ||
while(out[jj] && ("?D".indexOf(out[jj].t) > -1 || (out[jj].t == " " && (out[jj+1]||{}).t === "?" ) || out[i].t == '(' && (out[jj].t == ')' || out[jj].t == 'n') || out[jj].t == 't' && (out[jj].v == '/' || out[jj].v == '$' || (out[jj].v == ' ' && (out[jj+1]||{}).t == '?')))) { | ||
if(out[jj].v!==' ') out[i].v += ' ' + out[jj].v; | ||
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 == '(' && (out[jj].t == ')' || out[jj].t == 'n') || out[jj].t == 't' && (out[jj].v == '/' || out[jj].v == '$' || (out[jj].v == ' ' && (out[jj+1]||{}).t == '?')))) { | ||
out[i].v += out[jj].v; | ||
delete out[jj]; ++jj; | ||
@@ -659,3 +682,3 @@ } | ||
case 'G': out[i].t = 't'; out[i].v = general_fmt(v,opts); break; | ||
default: throw "unrecognized type " + out[i].t; | ||
default: console.error(out); throw "unrecognized type " + out[i].t; | ||
} | ||
@@ -743,3 +766,2 @@ } | ||
case 'e': { return val.y; } break; | ||
case 'A': return (val.h>=12 ? 'P' : 'A') + fmt.substr(1); | ||
default: throw 'bad format type ' + type + ' in ' + fmt; | ||
@@ -881,2 +903,3 @@ } | ||
npm install | ||
echo "SSF.version = '"`grep version package.json | awk '{gsub(/[^0-9\.]/,"",$2); print $2}'`"';" > tmp/01_version.js | ||
cat tmp/*.js > ssf.js | ||
@@ -942,3 +965,3 @@ ``` | ||
"name": "ssf", | ||
"version": "0.5.2", | ||
"version": "0.5.3", | ||
"author": "SheetJS", | ||
@@ -945,0 +968,0 @@ "description": "pure-JS library to format data using ECMA-376 spreadsheet Format Codes", |
@@ -106,3 +106,6 @@ [ | ||
[0.123251512342345, "# ??/?????????", " 480894/3901729"], | ||
[0.123251512342345, "# ?? / ?????????", " 480894 / 3901729"], | ||
[0, "0", "0"] | ||
] |
@@ -22,3 +22,11 @@ [ | ||
["_($* #,##0_);_($* (#,##0);_($* \"-\"_);_(@_)", [1, " $1 "], [-1, " $(1)"], [0," $- "], ["TODO", " TODO "]], | ||
["#,##0.0", [1, "1.0"], [-1, "-1.0"], [0,"0.0"], ["TODO", "TODO"]], | ||
["#,##0.0", [1,"1.0"], [-1,"-1.0"], [0,"0.0"], ["TODO","TODO"]], | ||
["#,##0.00", [1,"1.00"], [-1,"-1.00"], [0,"0.00"], ["TODO","TODO"]], | ||
["#,##0.000", [1,"1.000"], [-1,"-1.000"], [0,"0.000"], ["TODO","TODO"]], | ||
["#,##0.0000", [1,"1.0000"], [-1,"-1.0000"], [0,"0.0000"], ["TODO","TODO"]], | ||
["#,##0.00000", [1000000, "1,000,000.00000"]], | ||
["#,##0.000000", [1000000, "1,000,000.000000"]], | ||
["#,##0.0000000", [1000000, "1,000,000.0000000"]], | ||
["#,##0.00000000", [1000000, "1,000,000.00000000"]], | ||
["#,##0.000000000", [1000000, "1,000,000.000000000"]], | ||
["#,###", [1, "1"], [-1, "-1"], [0,""], ["TODO", "TODO"]], | ||
@@ -30,2 +38,3 @@ ["#.##", [1, "1."], [-1, "-1."], [0,"."], ["sheetjs", "sheetjs"]], | ||
["0.000", [1, "1.000"], [-1, "-1.000"], [0,"0.000"], ["sheetjs", "sheetjs"]], | ||
["0.0000", [1, "1.0000"], [-1, "-1.0000"], [0,"0.0000"], ["sheetjs", "sheetjs"]], | ||
["hh:mm AM/PM", [0.7, "04:48 PM"]], | ||
@@ -32,0 +41,0 @@ ["hhh:mm AM/PM", [0.7]], |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
102403
1902