diff --git a/.gitignore b/.gitignore
index 1f212e6..3f6aeb3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
node_modules
misc/coverage.html
tmp
+*.xlsx
diff --git a/.jscs.json b/.jscs.json
new file mode 100644
index 0000000..5965004
--- /dev/null
+++ b/.jscs.json
@@ -0,0 +1,6 @@
+{
+ "requireCommaBeforeLineBreak": true,
+ "disallowTrailingWhitespace": true,
+ "disallowTrailingComma": true
+}
+
diff --git a/.travis.yml b/.travis.yml
index 4fb8f04..5a28536 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,5 +1,6 @@
language: node_js
node_js:
+ - "0.11"
- "0.10"
- "0.8"
before_install:
diff --git a/Makefile b/Makefile
index ddfaf8d..68e0c89 100644
--- a/Makefile
+++ b/Makefile
@@ -13,7 +13,11 @@ bits/01_version.js: package.json
.PHONY: clean
clean:
- rm $(TARGET)
+ rm -f $(TARGET)
+
+.PHONY: clean-data
+clean-data:
+ rm -f *.xlsx *.xlsm *.xlsb *.xls *.xml
.PHONY: init
init:
@@ -37,6 +41,13 @@ $(TESTFMT): test_%:
.PHONY: lint
lint: $(TARGET)
jshint --show-non-errors $(TARGET)
+ jscs $(TARGET)
+
+.PHONY: test-osx
+test-osx:
+ node tests/write.js
+ open -a Numbers sheetjs.xlsx
+ open -a "Microsoft Excel" sheetjs.xlsx
.PHONY: cov cov-spin
cov: misc/coverage.html
diff --git a/bits/01_version.js b/bits/01_version.js
index e918874..1188156 100644
--- a/bits/01_version.js
+++ b/bits/01_version.js
@@ -1 +1 @@
-XLSX.version = '0.7.5';
+XLSX.version = '0.7.6';
diff --git a/bits/02_codepage.js b/bits/02_codepage.js
index 221315d..7a0fd66 100644
--- a/bits/02_codepage.js
+++ b/bits/02_codepage.js
@@ -13,7 +13,7 @@ if(typeof cptable !== 'undefined') _getchar = function(x) {
return cptable.utils.decode(current_codepage, [x%256,x>>8])[0];
};
-function char_codes(data) { return data.split("").map(function(x) { return x.charCodeAt(0); }); }
+function char_codes(data) { var o = []; for(var i = 0; i != data.length; ++i) o[i] = data.charCodeAt(i); return o; }
function debom_xml(data) {
if(typeof cptable !== 'undefined') {
if(data.charCodeAt(0) === 0xFF && data.charCodeAt(1) === 0xFE) { return cptable.utils.decode(1200, char_codes(data.substr(2))); }
diff --git a/bits/10_ssf.js b/bits/10_ssf.js
index 59b243f..96ce71c 100644
--- a/bits/10_ssf.js
+++ b/bits/10_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.7.0';
+SSF.version = '0.7.1';
/* Options */
var opts_fmt = {
date1904:0,
@@ -252,7 +252,10 @@ 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(fmt.match(/^[#?]+$/)) {
+ o = String(Math.round(val)).replace(/^0$/,"");
+ return o.length > fmt.length ? o : fmt.substr(0,fmt.length-o.length).replace(/#/g,"").replace(/[?]/g," ") + o;
+ }
if((r = fmt.match(/^#*0*\.(0+)/))) {
o = Math.round(val * Math.pow(10,r[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); });
@@ -278,20 +281,32 @@ var write_num = function(type, fmt, val) {
ff = write_num(type, "##########", val);
return "(" + ff.substr(0,3) + ") " + ff.substr(3, 3) + "-" + ff.substr(6);
}
- if((r = fmt.match(/^([?]+)([ ]?)\/([ ]?)([?]+)/))) {
- rr = Math.min(Math.max(r[1].length, r[4].length),7);
+ var oa = "";
+ if((r = fmt.match(/^([#0?]+)([ ]?)\/([ ]?)([#0?]+)/))) {
+ o="";
+ rr = Math.min(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));
+ o += sign;
+ oa = write_num("n", r[1], ff[1]);
+ if(oa[oa.length-1] == " ") oa = oa.substr(0,oa.length-1) + "0";
+ o += oa;
+ o += r[2];
+ o += "/";
+ o += r[3];
+ oa = rpad(ff[2],rr," ");
+ if(oa.length < r[4].length) oa = r[4].substr(r[4].length-oa.length).replace(/[?]/g," ").replace(/#/g,"") + oa;
+ o += oa;
+ return o;
}
- if((r = fmt.match(/^# ([?]+)([ ]?)\/([ ]?)([?]+)/))) {
+ if((r = fmt.match(/^# ([#0?]+)([ ]?)\/([ ]?)([#0?]+)/))) {
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));
}
- if((r = fmt.match(/^[#0]+$/))) {
+ 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;
+ return fmt.substr(0,fmt.length-o.length).replace(/#/g,"").replace(/\?/g," ") + o;
}
if((r = fmt.match(/^([#0]+)\.([#0]+)$/))) {
o = "" + val.toFixed(Math.min(r[2].length,10)).replace(/([^0])0+$/,"$1");
@@ -507,7 +522,9 @@ function eval_fmt(fmt, v, opts, flen) {
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("");
+ var retval = "";
+ for(i=0; i != out.length; ++i) if(out[i]) retval += out[i].v;
+ return retval;
}
SSF._eval = eval_fmt;
function choose_fmt(fmt, v, o) {
diff --git a/bits/22_xmlutils.js b/bits/22_xmlutils.js
index 4a8d7aa..ee20b1d 100644
--- a/bits/22_xmlutils.js
+++ b/bits/22_xmlutils.js
@@ -2,9 +2,9 @@ var _chr = function(c) { return String.fromCharCode(c); };
var _ord = function(c) { return c.charCodeAt(0); };
var attregexg=/([\w:]+)=((?:")([^"]*)(?:")|(?:')([^']*)(?:'))/g;
var attregex=/([\w:]+)=((?:")(?:[^"]*)(?:")|(?:')(?:[^']*)(?:'))/;
-function parsexmltag(tag) {
+function parsexmltag(tag, skip_root) {
var words = tag.split(/\s+/);
- var z = {'0': words[0]};
+ var z = []; if(!skip_root) z[0] = words[0];
if(words.length === 1) return z;
var m = tag.match(attregexg), y, j, w, i;
if(m) for(i = 0; i != m.length; ++i) {
diff --git a/bits/42_sstxml.js b/bits/42_sstxml.js
index 1a32bb4..0ae9317 100644
--- a/bits/42_sstxml.js
+++ b/bits/42_sstxml.js
@@ -140,7 +140,7 @@ var parse_si = function(x, opts) {
if(!x) return null;
var y;
/* 18.4.12 t ST_Xstring (Plaintext String) */
- if(x[1] === 't') {
+ if(x.charCodeAt(1) === 116) {
z.t = utf8read(unescapexml(x.substr(x.indexOf(">")+1).split(/<\/t>/)[0]));
z.r = x;
if(html) z.h = z.t;
diff --git a/bits/47_styxml.js b/bits/47_styxml.js
index 1f4c0d9..5b0d1f9 100644
--- a/bits/47_styxml.js
+++ b/bits/47_styxml.js
@@ -20,23 +20,23 @@ function parse_fills(t, opts) {
/* 18.8.3 bgColor CT_Color */
case '
=a:return[265,a-11,1];case 14>=a:return[266,a-13,1];case 16>=a:return[267,a-15,1];case 18>=a:return[268,a-17,1];case 22>=a:return[269,a-19,2];case 26>=a:return[270,a-23,2];case 30>=a:return[271,a-27,2];case 34>=a:return[272,a-31,2];case 42>=a:return[273,a-35,3];case 50>=a:return[274,a-43,3];case 58>=a:return[275,a-51,3];case 66>=a:return[276,a-59,3];case 82>=a:return[277,a-67,4];case 98>=a:return[278,a-83,4];case 114>=a:return[279,a-99,4];case 130>=a:return[280,a-115,4];case 162>=a:return[281,a-131,5];case 194>=a:return[282,a-163,5];case 226>=a:return[283,a-195,5];case 257>=a:return[284,a-227,5];case 258===a:return[285,a-258,0];default:throw"invalid length: "+a}}var d=[],c,f;for(c=3;258>=c;c++)f=e(c),d[c]=f[2]<<24|f[1]<<16|f[0];return d}(),Ga=C?new Uint32Array(Fa):Fa;function na(e,d){function c(a,c){var b=a.g,d=[],f=0,e;e=Ga[a.length];d[f++]=e&65535;d[f++]=e>>16&255;d[f++]=e>>24;var g;switch(u){case 1===b:g=[0,b-1,0];break;case 2===b:g=[1,b-2,0];break;case 3===b:g=[2,b-3,0];break;case 4===b:g=[3,b-4,0];break;case 6>=b:g=[4,b-5,1];break;case 8>=b:g=[5,b-7,1];break;case 12>=b:g=[6,b-9,2];break;case 16>=b:g=[7,b-13,2];break;case 24>=b:g=[8,b-17,3];break;case 32>=b:g=[9,b-25,3];break;case 48>=b:g=[10,b-33,4];break;case 64>=b:g=[11,b-49,4];break;case 96>=b:g=[12,b-65,5];break;case 128>=b:g=[13,b-97,5];break;case 192>=b:g=[14,b-129,6];break;case 256>=b:g=[15,b-193,6];break;case 384>=b:g=[16,b-257,7];break;case 512>=b:g=[17,b-385,7];break;case 768>=b:g=[18,b-513,8];break;case 1024>=b:g=[19,b-769,8];break;case 1536>=b:g=[20,b-1025,9];break;case 2048>=b:g=[21,b-1537,9];break;case 3072>=b:g=[22,b-2049,10];break;case 4096>=b:g=[23,b-3073,10];break;case 6144>=b:g=[24,b-4097,11];break;case 8192>=b:g=[25,b-6145,11];break;case 12288>=b:g=[26,b-8193,12];break;case 16384>=b:g=[27,b-12289,12];break;case 24576>=b:g=[28,b-16385,13];break;case 32768>=b:g=[29,b-24577,13];break;default:throw"invalid distance"}e=g;d[f++]=e[0];d[f++]=e[1];d[f++]=e[2];var k,m;k=0;for(m=d.length;k
")+terms[2].join("")}return function(rs){return rs.replace(/
")+terms[2].join("")}return function(rs){return rs.replace(/
")+terms[2].join("")}return function(rs){return rs.replace(/
")+terms[2].join("")}return function(rs){return rs.replace(/
")+terms[2].join("")}return function(rs){return rs.replace(/
")+terms[2].join("")}return function(rs){return rs.replace(/
+