From 4404d216c2eafbd10aef7b99f7e0b48bd2888c72 Mon Sep 17 00:00:00 2001 From: SheetJS Date: Tue, 25 Mar 2014 01:48:52 -0700 Subject: [PATCH] version bump 0.5.11: improper fractions - ??/?? and friends - stub for 'g' date format --- package.json | 2 +- ssf.js | 11 +++++++---- ssf.md | 13 ++++++++----- test/fraction.json | 11 +++++++++++ 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 15208a4..e1e3fab 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ssf", - "version": "0.5.10", + "version": "0.5.11", "author": "SheetJS", "description": "pure-JS library to format data using ECMA-376 spreadsheet Format Codes", "keywords": [ "format", "sprintf", "spreadsheet" ], diff --git a/ssf.js b/ssf.js index e24dc17..7bc50cf 100644 --- a/ssf.js +++ b/ssf.js @@ -5,7 +5,7 @@ var _strrev = function(x) { return String(x).split("").reverse().join("");}; function fill(c,l) { return new Array(l+1).join(c); } function pad(v,d,c){var t=String(v);return t.length>=d?t:(fill(c||0,d-t.length)+t);} 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.10'; +SSF.version = '0.5.11'; /* Options */ var opts_fmt = {}; function fixopts(o){for(var y in opts_fmt) if(o[y]===undefined) o[y]=opts_fmt[y];} @@ -255,6 +255,11 @@ var write_num = function(type, fmt, val) { rr = Math.round((val-Math.floor(val))*Math.pow(10,r[1].length)); return val < 0 ? "-" + write_num(type, fmt, -val) : commaify(String(Math.floor(val))) + "." + pad(rr,r[1].length,0); } + if((r = fmt.match(/^([?]+)([ ]?)\/([ ]?)([?]+)/))) { + rr = Math.min(Math.max(r[1].length, r[4].length),7); + ff = frac(aval, Math.pow(10,rr)-1, false); + 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)); + } if((r = fmt.match(/^# ([?]+)([ ]?)\/([ ]?)([?]+)/))) { rr = Math.min(Math.max(r[1].length, r[4].length),7); ff = frac(aval, Math.pow(10,rr)-1, true); @@ -262,8 +267,6 @@ var write_num = function(type, fmt, val) { } switch(fmt) { case "0": case "#0": return Math.round(val); - case "#.##": o = Math.round(val*100); - return String(o/100).replace(/^([^\.]+)$/,"$1.").replace(/^0\.$/,"."); case "#,###": var x = commaify(String(Math.round(aval))); return x !== "0" ? sign + x : ""; default: } @@ -308,7 +311,7 @@ function eval_fmt(fmt, v, opts, flen) { case 'M': case 'D': case 'Y': case 'H': case 'S': case 'E': c = c.toLowerCase(); /* falls through */ - case 'm': case 'd': case 'y': case 'h': case 's': case 'e': + case 'm': case 'd': case 'y': case 'h': case 's': case 'e': case 'g': if(v < 0) return ""; if(!dt) dt = parse_date_code(v, opts); if(!dt) return ""; diff --git a/ssf.md b/ssf.md index 6802e24..ca973f4 100644 --- a/ssf.md +++ b/ssf.md @@ -460,6 +460,11 @@ The next few simplifications ignore leading optional sigils (`#`): The frac helper function is used for fraction formats (defined below). ``` + if((r = fmt.match(/^([?]+)([ ]?)\/([ ]?)([?]+)/))) { + rr = Math.min(Math.max(r[1].length, r[4].length),7); + ff = frac(aval, Math.pow(10,rr)-1, false); + 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)); + } if((r = fmt.match(/^# ([?]+)([ ]?)\/([ ]?)([?]+)/))) { rr = Math.min(Math.max(r[1].length, r[4].length),7); ff = frac(aval, Math.pow(10,rr)-1, true); @@ -472,8 +477,6 @@ The default cases are hard-coded. TODO: actually parse them ```js>tmp/60_number.js switch(fmt) { case "0": case "#0": return Math.round(val); - case "#.##": o = Math.round(val*100); - return String(o/100).replace(/^([^\.]+)$/,"$1.").replace(/^0\.$/,"."); case "#,###": var x = commaify(String(Math.round(aval))); return x !== "0" ? sign + x : ""; ``` @@ -539,14 +542,14 @@ mode but I'm not convinced that's the right approach) ``` The date codes `m,d,y,h,s` are standard. There are some special formats like -`e` (era year) that have different behaviors in Japanese/Chinese locales. +`e / g` (era year) that have different behaviors in Japanese/Chinese locales. ``` /* Dates */ case 'M': case 'D': case 'Y': case 'H': case 'S': case 'E': c = c.toLowerCase(); /* falls through */ - case 'm': case 'd': case 'y': case 'h': case 's': case 'e': + case 'm': case 'd': case 'y': case 'h': case 's': case 'e': case 'g': ``` Negative dates are immediately thrown out: @@ -1011,7 +1014,7 @@ coveralls: ```json>package.json { "name": "ssf", - "version": "0.5.10", + "version": "0.5.11", "author": "SheetJS", "description": "pure-JS library to format data using ECMA-376 spreadsheet Format Codes", "keywords": [ "format", "sprintf", "spreadsheet" ], diff --git a/test/fraction.json b/test/fraction.json index 2fbb164..1aaa8b9 100644 --- a/test/fraction.json +++ b/test/fraction.json @@ -99,6 +99,17 @@ [12345.6789, "# ??/100", "12345 68/100"], [-12345.67891, "# ??/100", "-12345 68/100"], + [1, "??/??", " 1/1 "], + [-1.2, "??/??", "- 6/5 "], + [12.3, "??/??", "123/10"], + [-12.34, "??/??", "-617/50"], + [123.45, "??/??", "2469/20"], + [-123.456, "??/??", "-7037/57"], + [1234.567, "??/??", "119753/97"], + [-1234.5678, "??/??", "-100000/81"], + [12345.6789, "??/??", "1000000/81"], + [-12345.67891, "??/??", "-1000000/81"], + [0.3, "# ?/?", " 2/7"], [1.3, "# ?/?", "1 1/3"], [2.3, "# ?/?", "2 2/7"],