From b2940bac2162c2ab0b4444444d464e62f31958df Mon Sep 17 00:00:00 2001 From: SheetJS Date: Tue, 25 Mar 2014 00:42:14 -0700 Subject: [PATCH] version bump 0.5.10: support trailing commas --- package.json | 2 +- ssf.js | 11 +++++++---- ssf.md | 17 +++++++++++++---- test/comma.js | 21 +++++++++++++++++++++ test/comma.tsv | 15 +++++++++++++++ 5 files changed, 57 insertions(+), 9 deletions(-) create mode 100644 test/comma.js create mode 100644 test/comma.tsv diff --git a/package.json b/package.json index d548e61..15208a4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ssf", - "version": "0.5.9", + "version": "0.5.10", "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 626f7a9..e24dc17 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.9'; +SSF.version = '0.5.10'; /* Options */ var opts_fmt = {}; function fixopts(o){for(var y in opts_fmt) if(o[y]===undefined) o[y]=opts_fmt[y];} @@ -205,6 +205,8 @@ var write_num = function(type, fmt, val) { var mul = 0, o; fmt = fmt.replace(/%/g,function(x) { mul++; return ""; }); if(mul !== 0) return write_num(type, fmt, val * Math.pow(10,2*mul)) + fill("%",mul); + fmt = fmt.replace(/(\.0+)(,+)$/g,function($$,$1,$2) { mul=$2.length; return $1; }); + if(mul !== 0) return write_num(type, fmt, val / Math.pow(10,3*mul)); if(fmt.indexOf("E") > -1) { var idx = fmt.indexOf("E") - fmt.indexOf(".") - 1; if(fmt.match(/^#+0.0E\+0$/)) { @@ -238,11 +240,12 @@ var write_num = function(type, fmt, val) { if(fmt.match(/^#+0+$/)) fmt = fmt.replace(/#/g,""); 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+)/))) { + 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); }); + rr = 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); }); + return fmt.match(/0\./) ? rr : rr.replace(/^0\./,"."); } - fmt = fmt.replace(/^#+0/, "0"); + fmt = fmt.replace(/^#+([0.])/, "$1"); if((r = fmt.match(/^(0*)\.(#*)$/))) { o = Math.round(aval*Math.pow(10,r[2].length)); return sign + String(o / Math.pow(10,r[2].length)).replace(/\.(\d*[1-9])0*$/,".$1").replace(/^([-]?\d*)$/,"$1.").replace(/^0\./,r[1].length?"0.":"."); diff --git a/ssf.md b/ssf.md index d7bf29b..6802e24 100644 --- a/ssf.md +++ b/ssf.md @@ -366,6 +366,14 @@ Percentage values should be physically shifted: if(mul !== 0) return write_num(type, fmt, val * Math.pow(10,2*mul)) + fill("%",mul); ``` +Formats with multiple commas after the decimal point should be shifted by the +appropiate multiple of 1000 (more magic): + +```js>tmp/60_number.js + fmt = fmt.replace(/(\.0+)(,+)$/g,function($$,$1,$2) { mul=$2.length; return $1; }); + if(mul !== 0) return write_num(type, fmt, val / Math.pow(10,3*mul)); +``` + For exponents, get the exponent and mantissa and format them separately: ``` @@ -427,16 +435,17 @@ A few special general cases can be handled in a very dumb manner: if(fmt.match(/^#+0+$/)) fmt = fmt.replace(/#/g,""); 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+)/))) { + 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); }); + rr = 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); }); + return fmt.match(/0\./) ? rr : rr.replace(/^0\./,"."); } ``` The next few simplifications ignore leading optional sigils (`#`): ``` - fmt = fmt.replace(/^#+0/, "0"); + fmt = fmt.replace(/^#+([0.])/, "$1"); if((r = fmt.match(/^(0*)\.(#*)$/))) { o = Math.round(aval*Math.pow(10,r[2].length)); return sign + String(o / Math.pow(10,r[2].length)).replace(/\.(\d*[1-9])0*$/,".$1").replace(/^([-]?\d*)$/,"$1.").replace(/^0\./,r[1].length?"0.":"."); @@ -1002,7 +1011,7 @@ coveralls: ```json>package.json { "name": "ssf", - "version": "0.5.9", + "version": "0.5.10", "author": "SheetJS", "description": "pure-JS library to format data using ECMA-376 spreadsheet Format Codes", "keywords": [ "format", "sprintf", "spreadsheet" ], diff --git a/test/comma.js b/test/comma.js new file mode 100644 index 0000000..ce0270f --- /dev/null +++ b/test/comma.js @@ -0,0 +1,21 @@ +/* vim: set ts=2: */ +/*jshint loopfunc:true */ +var SSF = require('../'); +var fs = require('fs'), assert = require('assert'); +var data = fs.readFileSync('./test/comma.tsv','utf8').split("\n"); + +function doit(w, headers) { + it(headers[w], function() { + for(var j=1;j