Skip to content

Commit 667cfff

Browse files
switch to eslint
- eslint pass (eliminates jshint and jscs) - moved cell reference functions to reduce forward references - themeXLSX override XLSX/XLSB/XLSM theme
1 parent 7906ff3 commit 667cfff

File tree

11 files changed

+261
-227
lines changed

11 files changed

+261
-227
lines changed

.eslintrc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"env": { "shared-node-browser":true },
3+
"globals": {},
4+
"parserOptions": {
5+
"ecmaVersion": 3,
6+
},
7+
"plugins": [ "html", "json" ],
8+
"rules": {
9+
"no-use-before-define": [ 1, {
10+
"functions":true, "classes":true, "variables":true
11+
}],
12+
"no-bitwise": 0,
13+
"curly": 0,
14+
"comma-style": [ 2, "last" ],
15+
"no-trailing-spaces": 2,
16+
"comma-dangle": [ 2, "never" ]
17+
}
18+
}

.npmignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,11 @@ tmp
2828
*.sheetjs
2929
*.exe
3030
.gitignore
31+
.eslintrc
3132
.jshintrc
3233
CONTRIBUTING.md
3334
Makefile
35+
make.cmd
3436
*.lst
3537
.npmignore
3638
xlsworker.js

Makefile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,12 @@ demo-systemjs: ## Run systemjs demo build
143143
## Code Checking
144144

145145
.PHONY: lint
146-
lint: $(TARGET) $(AUXTARGETS) ## Run jshint and jscs checks
146+
lint: $(TARGET) $(AUXTARGETS) ## Run eslint checks
147+
@eslint --ext .js,.njs,.json,.html,.htm $(TARGET) $(AUXTARGETS) $(CMDS) $(HTMLLINT) package.json bower.json
148+
if [ -e $(CLOSURE) ]; then java -jar $(CLOSURE) $(REQS) $(FLOWTARGET) --jscomp_warning=reportUnknownTypes >/dev/null; fi
149+
150+
.PHONY: old-lint
151+
old-lint: $(TARGET) $(AUXTARGETS) ## Run jshint and jscs checks
147152
@jshint --show-non-errors $(TARGET) $(AUXTARGETS)
148153
@jshint --show-non-errors $(CMDS)
149154
@jshint --show-non-errors package.json bower.json

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,6 +1025,7 @@ The exported `write` and `writeFile` functions accept an options argument:
10251025
| sheet | `""` | Name of Worksheet for single-sheet formats ** |
10261026
| compression | `false` | Use ZIP compression for ZIP-based formats ** |
10271027
| Props | | Override workbook properties when writing ** |
1028+
| themeXLSX | | Override theme XML when writing XLSX/XLSB/XLSM ** |
10281029

10291030
- `bookSST` is slower and more memory intensive, but has better compatibility
10301031
with older versions of iOS Numbers
@@ -1035,6 +1036,8 @@ The exported `write` and `writeFile` functions accept an options argument:
10351036
so non-Excel tools may ignore the data or blow up in the presence of dates.
10361037
- `Props` is an object mirroring the workbook `Props` field. See the table from
10371038
the [Workbook File Properties](#workbook-file-properties) section.
1039+
- if specified, the string from `themeXLSX` will be saved as the primary theme
1040+
for XLSX/XLSB/XLSM files (to `xl/theme/theme1.xml` in the ZIP)
10381041

10391042
### Supported Output Formats
10401043

bits/27_csfutils.js

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,79 @@
1+
function decode_row(rowstr/*:string*/)/*:number*/ { return parseInt(unfix_row(rowstr),10) - 1; }
2+
function encode_row(row/*:number*/)/*:string*/ { return "" + (row + 1); }
3+
function fix_row(cstr/*:string*/)/*:string*/ { return cstr.replace(/([A-Z]|^)(\d+)$/,"$1$$$2"); }
4+
function unfix_row(cstr/*:string*/)/*:string*/ { return cstr.replace(/\$(\d+)$/,"$1"); }
5+
6+
function decode_col(colstr/*:string*/)/*:number*/ { var c = unfix_col(colstr), d = 0, i = 0; for(; i !== c.length; ++i) d = 26*d + c.charCodeAt(i) - 64; return d - 1; }
7+
function encode_col(col/*:number*/)/*:string*/ { var s=""; for(++col; col; col=Math.floor((col-1)/26)) s = String.fromCharCode(((col-1)%26) + 65) + s; return s; }
8+
function fix_col(cstr/*:string*/)/*:string*/ { return cstr.replace(/^([A-Z])/,"$$$1"); }
9+
function unfix_col(cstr/*:string*/)/*:string*/ { return cstr.replace(/^\$([A-Z])/,"$1"); }
10+
11+
function split_cell(cstr/*:string*/)/*:Array<string>*/ { return cstr.replace(/(\$?[A-Z]*)(\$?\d*)/,"$1,$2").split(","); }
12+
function decode_cell(cstr/*:string*/)/*:CellAddress*/ { var splt = split_cell(cstr); return { c:decode_col(splt[0]), r:decode_row(splt[1]) }; }
13+
function encode_cell(cell/*:CellAddress*/)/*:string*/ { return encode_col(cell.c) + encode_row(cell.r); }
14+
function fix_cell(cstr/*:string*/)/*:string*/ { return fix_col(fix_row(cstr)); }
15+
function unfix_cell(cstr/*:string*/)/*:string*/ { return unfix_col(unfix_row(cstr)); }
16+
function decode_range(range/*:string*/)/*:Range*/ { var x =range.split(":").map(decode_cell); return {s:x[0],e:x[x.length-1]}; }
17+
/*# if only one arg, it is assumed to be a Range. If 2 args, both are cell addresses */
18+
function encode_range(cs/*:CellAddrSpec|Range*/,ce/*:?CellAddrSpec*/)/*:string*/ {
19+
if(typeof ce === 'undefined' || typeof ce === 'number') {
20+
/*:: if(!(cs instanceof Range)) throw "unreachable"; */
21+
return encode_range(cs.s, cs.e);
22+
}
23+
/*:: if((cs instanceof Range)) throw "unreachable"; */
24+
if(typeof cs !== 'string') cs = encode_cell((cs/*:any*/));
25+
if(typeof ce !== 'string') ce = encode_cell((ce/*:any*/));
26+
/*:: if(typeof cs !== 'string') throw "unreachable"; */
27+
/*:: if(typeof ce !== 'string') throw "unreachable"; */
28+
return cs == ce ? cs : cs + ":" + ce;
29+
}
30+
31+
function safe_decode_range(range/*:string*/)/*:Range*/ {
32+
var o = {s:{c:0,r:0},e:{c:0,r:0}};
33+
var idx = 0, i = 0, cc = 0;
34+
var len = range.length;
35+
for(idx = 0; i < len; ++i) {
36+
if((cc=range.charCodeAt(i)-64) < 1 || cc > 26) break;
37+
idx = 26*idx + cc;
38+
}
39+
o.s.c = --idx;
40+
41+
for(idx = 0; i < len; ++i) {
42+
if((cc=range.charCodeAt(i)-48) < 0 || cc > 9) break;
43+
idx = 10*idx + cc;
44+
}
45+
o.s.r = --idx;
46+
47+
if(i === len || range.charCodeAt(++i) === 58) { o.e.c=o.s.c; o.e.r=o.s.r; return o; }
48+
49+
for(idx = 0; i != len; ++i) {
50+
if((cc=range.charCodeAt(i)-64) < 1 || cc > 26) break;
51+
idx = 26*idx + cc;
52+
}
53+
o.e.c = --idx;
54+
55+
for(idx = 0; i != len; ++i) {
56+
if((cc=range.charCodeAt(i)-48) < 0 || cc > 9) break;
57+
idx = 10*idx + cc;
58+
}
59+
o.e.r = --idx;
60+
return o;
61+
}
62+
63+
function safe_format_cell(cell/*:Cell*/, v/*:any*/) {
64+
var q = (cell.t == 'd' && v instanceof Date);
65+
if(cell.z != null) try { return (cell.w = SSF.format(cell.z, q ? datenum(v) : v)); } catch(e) { }
66+
try { return (cell.w = SSF.format((cell.XF||{}).ifmt||(q ? 14 : 0), q ? datenum(v) : v)); } catch(e) { return ''+v; }
67+
}
68+
69+
function format_cell(cell/*:Cell*/, v/*:any*/, o/*:any*/) {
70+
if(cell == null || cell.t == null || cell.t == 'z') return "";
71+
if(cell.w !== undefined) return cell.w;
72+
if(cell.t == 'd' && !cell.z && o && o.dateNF) cell.z = o.dateNF;
73+
if(v == undefined) return safe_format_cell(cell, cell.v, o);
74+
return safe_format_cell(cell, v, o);
75+
}
76+
177
function sheet_to_workbook(sheet/*:Worksheet*/, opts)/*:Workbook*/ {
278
var n = opts && opts.sheet ? opts.sheet : "Sheet1";
379
var sheets = {}; sheets[n] = sheet;

bits/49_theme.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ function parse_theme_xml(data/*:string*/, opts) {
111111
}
112112

113113
function write_theme(Themes, opts)/*:string*/ {
114+
if(opts && opts.themeXLSX) return opts.themeXLSX;
114115
var o = [XML_HEADER];
115116
o[o.length] = '<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="Office Theme">';
116117
o[o.length] = '<a:themeElements>';

bits/67_wsxml.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess, themes, styles) {
264264
} else ++tagc;
265265
for(i = 0; i != x.length; ++i) if(x.charCodeAt(i) === 62) break; ++i;
266266
tag = parsexmltag(x.substr(0,i), true);
267-
if(!tag.r) tag.r = utils.encode_cell({r:tagr-1, c:tagc});
267+
if(!tag.r) tag.r = encode_cell({r:tagr-1, c:tagc});
268268
d = x.substr(i);
269269
p = ({t:""}/*:any*/);
270270

bits/90_utils.js

Lines changed: 0 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,3 @@
1-
function decode_row(rowstr/*:string*/)/*:number*/ { return parseInt(unfix_row(rowstr),10) - 1; }
2-
function encode_row(row/*:number*/)/*:string*/ { return "" + (row + 1); }
3-
function fix_row(cstr/*:string*/)/*:string*/ { return cstr.replace(/([A-Z]|^)(\d+)$/,"$1$$$2"); }
4-
function unfix_row(cstr/*:string*/)/*:string*/ { return cstr.replace(/\$(\d+)$/,"$1"); }
5-
6-
function decode_col(colstr/*:string*/)/*:number*/ { var c = unfix_col(colstr), d = 0, i = 0; for(; i !== c.length; ++i) d = 26*d + c.charCodeAt(i) - 64; return d - 1; }
7-
function encode_col(col/*:number*/)/*:string*/ { var s=""; for(++col; col; col=Math.floor((col-1)/26)) s = String.fromCharCode(((col-1)%26) + 65) + s; return s; }
8-
function fix_col(cstr/*:string*/)/*:string*/ { return cstr.replace(/^([A-Z])/,"$$$1"); }
9-
function unfix_col(cstr/*:string*/)/*:string*/ { return cstr.replace(/^\$([A-Z])/,"$1"); }
10-
11-
function split_cell(cstr/*:string*/)/*:Array<string>*/ { return cstr.replace(/(\$?[A-Z]*)(\$?\d*)/,"$1,$2").split(","); }
12-
function decode_cell(cstr/*:string*/)/*:CellAddress*/ { var splt = split_cell(cstr); return { c:decode_col(splt[0]), r:decode_row(splt[1]) }; }
13-
function encode_cell(cell/*:CellAddress*/)/*:string*/ { return encode_col(cell.c) + encode_row(cell.r); }
14-
function fix_cell(cstr/*:string*/)/*:string*/ { return fix_col(fix_row(cstr)); }
15-
function unfix_cell(cstr/*:string*/)/*:string*/ { return unfix_col(unfix_row(cstr)); }
16-
function decode_range(range/*:string*/)/*:Range*/ { var x =range.split(":").map(decode_cell); return {s:x[0],e:x[x.length-1]}; }
17-
/*# if only one arg, it is assumed to be a Range. If 2 args, both are cell addresses */
18-
function encode_range(cs/*:CellAddrSpec|Range*/,ce/*:?CellAddrSpec*/)/*:string*/ {
19-
if(typeof ce === 'undefined' || typeof ce === 'number') {
20-
/*:: if(!(cs instanceof Range)) throw "unreachable"; */
21-
return encode_range(cs.s, cs.e);
22-
}
23-
/*:: if((cs instanceof Range)) throw "unreachable"; */
24-
if(typeof cs !== 'string') cs = encode_cell((cs/*:any*/));
25-
if(typeof ce !== 'string') ce = encode_cell((ce/*:any*/));
26-
/*:: if(typeof cs !== 'string') throw "unreachable"; */
27-
/*:: if(typeof ce !== 'string') throw "unreachable"; */
28-
return cs == ce ? cs : cs + ":" + ce;
29-
}
30-
31-
function safe_decode_range(range/*:string*/)/*:Range*/ {
32-
var o = {s:{c:0,r:0},e:{c:0,r:0}};
33-
var idx = 0, i = 0, cc = 0;
34-
var len = range.length;
35-
for(idx = 0; i < len; ++i) {
36-
if((cc=range.charCodeAt(i)-64) < 1 || cc > 26) break;
37-
idx = 26*idx + cc;
38-
}
39-
o.s.c = --idx;
40-
41-
for(idx = 0; i < len; ++i) {
42-
if((cc=range.charCodeAt(i)-48) < 0 || cc > 9) break;
43-
idx = 10*idx + cc;
44-
}
45-
o.s.r = --idx;
46-
47-
if(i === len || range.charCodeAt(++i) === 58) { o.e.c=o.s.c; o.e.r=o.s.r; return o; }
48-
49-
for(idx = 0; i != len; ++i) {
50-
if((cc=range.charCodeAt(i)-64) < 1 || cc > 26) break;
51-
idx = 26*idx + cc;
52-
}
53-
o.e.c = --idx;
54-
55-
for(idx = 0; i != len; ++i) {
56-
if((cc=range.charCodeAt(i)-48) < 0 || cc > 9) break;
57-
idx = 10*idx + cc;
58-
}
59-
o.e.r = --idx;
60-
return o;
61-
}
62-
63-
function safe_format_cell(cell/*:Cell*/, v/*:any*/) {
64-
var q = (cell.t == 'd' && v instanceof Date);
65-
if(cell.z != null) try { return (cell.w = SSF.format(cell.z, q ? datenum(v) : v)); } catch(e) { }
66-
try { return (cell.w = SSF.format((cell.XF||{}).ifmt||(q ? 14 : 0), q ? datenum(v) : v)); } catch(e) { return ''+v; }
67-
}
68-
69-
function format_cell(cell/*:Cell*/, v/*:any*/, o/*:any*/) {
70-
if(cell == null || cell.t == null || cell.t == 'z') return "";
71-
if(cell.w !== undefined) return cell.w;
72-
if(cell.t == 'd' && !cell.z && o && o.dateNF) cell.z = o.dateNF;
73-
if(v == undefined) return safe_format_cell(cell, cell.v, o);
74-
return safe_format_cell(cell, v, o);
75-
}
76-
771
function sheet_to_json(sheet/*:Worksheet*/, opts/*:?Sheet2JSONOpts*/){
782
if(sheet == null || sheet["!ref"] == null) return [];
793
var val = {t:'n',v:0}, header = 0, offset = 1, hdr/*:Array<any>*/ = [], isempty = true, v=0, vv="";

docbits/81_writeopts.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ The exported `write` and `writeFile` functions accept an options argument:
1111
| sheet | `""` | Name of Worksheet for single-sheet formats ** |
1212
| compression | `false` | Use ZIP compression for ZIP-based formats ** |
1313
| Props | | Override workbook properties when writing ** |
14+
| themeXLSX | | Override theme XML when writing XLSX/XLSB/XLSM ** |
1415

1516
- `bookSST` is slower and more memory intensive, but has better compatibility
1617
with older versions of iOS Numbers
@@ -21,6 +22,8 @@ The exported `write` and `writeFile` functions accept an options argument:
2122
so non-Excel tools may ignore the data or blow up in the presence of dates.
2223
- `Props` is an object mirroring the workbook `Props` field. See the table from
2324
the [Workbook File Properties](#workbook-file-properties) section.
25+
- if specified, the string from `themeXLSX` will be saved as the primary theme
26+
for XLSX/XLSB/XLSM files (to `xl/theme/theme1.xml` in the ZIP)
2427

2528
### Supported Output Formats
2629

0 commit comments

Comments
 (0)