version bump 0.11.16: refresh

- HTML whitespace (fixes #849 h/t @laurentauthier)
- XLML number format write (fixes #904 h/t @james-boswell)
- XLAM/XLA write
- 'array' write type
- XLSX/XLSB/XLS/XLML RTL read/write
- XLS merge cells write
- demo and typing refresh
This commit is contained in:
SheetJS 2017-12-30 00:40:35 -05:00
parent 33f96fc6ae
commit f277ebe140
90 changed files with 1977 additions and 1389 deletions

@ -14,8 +14,8 @@ tmp
*.[pP][rR][nN]
*.[sS][lL][kK]
*.socialcalc
*.[xX][lL][sSwWcC]
*.[xX][lL][sS][xXmMbB]
*.[xX][lL][sSwWcCaAtT]
*.[xX][lL][sSaAtT][xXmMbB]
*.[oO][dD][sS]
*.[fF][oO][dD][sS]
*.[xX][mM][lL]

@ -53,6 +53,7 @@ weex
# Other terms
APIs
ArrayBuffer
Base64
Booleans
JS

@ -4,6 +4,11 @@ This log is intended to keep track of backwards-incompatible changes, including
but not limited to API changes and file location changes. Minor behavioral
changes may not be included if they are not expected to break existing code.
## 0.11.16 (2017-12-30)
* XLS ANSI/CP separation
* 'array' write type and ArrayBuffer processing
## 0.11.6 (2017-10-16)
* Semicolon-delimited files are detected

@ -84,6 +84,7 @@ enhancements, additional features by request, and dedicated support.
+ [Workbook File Properties](#workbook-file-properties)
* [Workbook-Level Attributes](#workbook-level-attributes)
+ [Defined Names](#defined-names)
+ [Workbook Views](#workbook-views)
+ [Miscellaneous Workbook Properties](#miscellaneous-workbook-properties)
* [Document Features](#document-features)
+ [Formulae](#formulae)
@ -621,19 +622,12 @@ example uses [FileSaver](https://github.com/eligrey/FileSaver.js/):
```js
/* bookType can be any supported output type */
var wopts = { bookType:'xlsx', bookSST:false, type:'binary' };
var wopts = { bookType:'xlsx', bookSST:false, type:'array' };
var wbout = XLSX.write(workbook,wopts);
function s2ab(s) {
var buf = new ArrayBuffer(s.length);
var view = new Uint8Array(buf);
for (var i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
return buf;
}
/* the saveAs call downloads a file on the local machine */
saveAs(new Blob([s2ab(wbout)],{type:"application/octet-stream"}), "test.xlsx");
saveAs(new Blob([wbout],{type:"application/octet-stream"}), "test.xlsx");
```
</details>
@ -1081,6 +1075,14 @@ Excel allows two sheet-scoped defined names to share the same name. However, a
sheet-scoped name cannot collide with a workbook-scope name. Workbook writers
may not enforce this constraint.
#### Workbook Views
`wb.Workbook.Views` is an array of workbook view objects which have the keys:
| Key | Description |
|:----------------|:----------------------------------------------------|
| `RTL` | If true, display right-to-left |
#### Miscellaneous Workbook Properties
`wb.Workbook.WBProps` holds other workbook properties:
@ -1693,6 +1695,7 @@ The `type` argument for `write` mirrors the `type` argument for `read`:
| `"binary"` | string: binary string (byte `n` is `data.charCodeAt(n)`) |
| `"string"` | string: JS string (characters interpreted as UTF8) |
| `"buffer"` | nodejs Buffer |
| `"array"` | ArrayBuffer, fallback array of 8-bit unsigned int |
| `"file"` | string: path of file that will be created (nodejs only) |
## Utility Functions

@ -19,12 +19,14 @@ program
.option('-B, --xlsb', 'emit XLSB to <sheetname> or <file>.xlsb')
.option('-M, --xlsm', 'emit XLSM to <sheetname> or <file>.xlsm')
.option('-X, --xlsx', 'emit XLSX to <sheetname> or <file>.xlsx')
.option('-I, --xlam', 'emit XLAM to <sheetname> or <file>.xlam')
.option('-Y, --ods', 'emit ODS to <sheetname> or <file>.ods')
.option('-8, --xls', 'emit XLS to <sheetname> or <file>.xls (BIFF8)')
.option('-5, --biff5','emit XLS to <sheetname> or <file>.xls (BIFF5)')
//.option('-4, --biff4','emit XLS to <sheetname> or <file>.xls (BIFF4)')
//.option('-3, --biff3','emit XLS to <sheetname> or <file>.xls (BIFF3)')
.option('-2, --biff2','emit XLS to <sheetname> or <file>.xls (BIFF2)')
.option('-i, --xla', 'emit XLA to <sheetname> or <file>.xla')
.option('-6, --xlml', 'emit SSML to <sheetname> or <file>.xls (2003 XML)')
.option('-T, --fods', 'emit FODS to <sheetname> or <file>.fods (Flat ODS)')
@ -65,8 +67,10 @@ program.on('--help', function() {
var workbook_formats = [
['xlsx', 'xlsx', 'xlsx'],
['xlsm', 'xlsm', 'xlsm'],
['xlam', 'xlam', 'xlam'],
['xlsb', 'xlsb', 'xlsb'],
['xls', 'xls', 'xls'],
['xla', 'xla', 'xla'],
['biff5', 'biff5', 'xls'],
['ods', 'ods', 'ods'],
['fods', 'fods', 'fods']

@ -1 +1 @@
XLSX.version = '0.11.15';
XLSX.version = '0.11.16';

@ -1,21 +1,51 @@
var current_codepage = 1200;
var current_codepage = 1200, current_ansi = 1252;
/*:: declare var cptable:any; */
/*global cptable:true */
if(typeof module !== "undefined" && typeof require !== 'undefined') {
if(typeof cptable === 'undefined') global.cptable = require('./dist/cpexcel.js');
}
function reset_cp() { set_cp(1200); }
var set_cp = function(cp) { current_codepage = cp; };
function char_codes(data) { var o = []; for(var i = 0, len = data.length; i < len; ++i) o[i] = data.charCodeAt(i); return o; }
var VALID_ANSI = [ 874, 932, 936, 949, 950 ];
for(var i = 0; i <= 8; ++i) VALID_ANSI.push(1250 + i);
/* ECMA-376 Part I 18.4.1 charset to codepage mapping */
var CS2CP = ({
/*::[*/0/*::]*/: 1252, /* ANSI */
/*::[*/1/*::]*/: 65001, /* DEFAULT */
/*::[*/2/*::]*/: 65001, /* SYMBOL */
/*::[*/77/*::]*/: 10000, /* MAC */
/*::[*/128/*::]*/: 932, /* SHIFTJIS */
/*::[*/129/*::]*/: 949, /* HANGUL */
/*::[*/130/*::]*/: 1361, /* JOHAB */
/*::[*/134/*::]*/: 936, /* GB2312 */
/*::[*/136/*::]*/: 950, /* CHINESEBIG5 */
/*::[*/161/*::]*/: 1253, /* GREEK */
/*::[*/162/*::]*/: 1254, /* TURKISH */
/*::[*/163/*::]*/: 1258, /* VIETNAMESE */
/*::[*/177/*::]*/: 1255, /* HEBREW */
/*::[*/178/*::]*/: 1256, /* ARABIC */
/*::[*/186/*::]*/: 1257, /* BALTIC */
/*::[*/204/*::]*/: 1251, /* RUSSIAN */
/*::[*/222/*::]*/: 874, /* THAI */
/*::[*/238/*::]*/: 1250, /* EASTEUROPE */
/*::[*/255/*::]*/: 1252, /* OEM */
/*::[*/69/*::]*/: 6969 /* MISC */
}/*:any*/);
var set_ansi = function(cp/*:number*/) { if(VALID_ANSI.indexOf(cp) == -1) return; current_ansi = CS2CP[0] = cp; };
function reset_ansi() { set_ansi(1252); }
var set_cp = function(cp/*:number*/) { current_codepage = cp; set_ansi(cp); };
function reset_cp() { set_cp(1200); reset_ansi(); }
function char_codes(data/*:string*/)/*:Array<number>*/ { var o/*:Array<number>*/ = []; for(var i = 0, len = data.length; i < len; ++i) o[i] = data.charCodeAt(i); return o; }
function utf16leread(data/*:string*/)/*:string*/ {
var o = [];
var o/*:Array<string>*/ = [];
for(var i = 0; i < (data.length>>1); ++i) o[i] = String.fromCharCode(data.charCodeAt(2*i) + (data.charCodeAt(2*i+1)<<8));
return o.join("");
}
function utf16beread(data/*:string*/)/*:string*/ {
var o = [];
var o/*:Array<string>*/ = [];
for(var i = 0; i < (data.length>>1); ++i) o[i] = String.fromCharCode(data.charCodeAt(2*i+1) + (data.charCodeAt(2*i)<<8));
return o.join("");
}

@ -12,6 +12,18 @@ function s2a(s/*:string*/) {
return s.split("").map(function(x){ return x.charCodeAt(0) & 0xff; });
}
function s2ab(s/*:string*/) {
if(typeof ArrayBuffer === 'undefined') return s2a(s);
var buf = new ArrayBuffer(s.length), view = new Uint8Array(buf);
for (var i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
return buf;
}
function arr2str(data/*:any*/)/*:string*/ {
if(Array.isArray(data)) return data.map(_chr).join("");
var o/*:Array<string>*/ = []; for(var i = 0; i < data.length; ++i) o[i] = _chr(data[i]); return o.join("");
}
var bconcat = function(bufs) { return [].concat.apply([], bufs); };
var chr0 = /\u0000/g, chr1 = /[\u0001-\u0006]/g;

@ -1,5 +1,3 @@
function isval(x/*:?any*/)/*:boolean*/ { return x !== undefined && x !== null; }
function keys(o/*:any*/)/*:Array<any>*/ { return Object.keys(o); }
function evert_key(obj/*:any*/, key/*:string*/)/*:EvertType*/ {
@ -99,12 +97,6 @@ function cc2str(arr/*:Array<number>*/)/*:string*/ {
return o;
}
function str2cc(str) {
var o = [];
for(var i = 0; i != str.length; ++i) o.push(str.charCodeAt(i));
return o;
}
function dup(o/*:any*/)/*:any*/ {
if(typeof JSON != 'undefined' && !Array.isArray(o)) return JSON.parse(JSON.stringify(o));
if(typeof o != 'object' || o == null) return o;

@ -13,7 +13,7 @@ function getdatabin(data) {
if(data.asNodeBuffer && has_buf) return data.asNodeBuffer();
if(data._data && data._data.getContent) {
var o = data._data.getContent();
if(typeof o == "string") return str2cc(o);
if(typeof o == "string") return char_codes(o);
return Array.prototype.slice.call(o);
}
return null;

@ -1,6 +1,6 @@
var XML_HEADER = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n';
var attregexg=/([^"\s?>\/]+)=((?:")([^"]*)(?:")|(?:')([^']*)(?:')|([^'">\s]+))/g;
var tagregex=/<[\/\?]?[a-zA-Z0-9:]+(?:\s+[^"\s?>\/]+=(?:"[^"]*"|'[^']*'|[^'">\s]+))*\s?[\/\?]?>/g;
var attregexg=/([^"\s?>\/]+)\s*=\s*((?:")([^"]*)(?:")|(?:')([^']*)(?:')|([^'">\s]+))/g;
var tagregex=/<[\/\?]?[a-zA-Z0-9:]+(?:\s+[^"\s?>\/]+\s*=\s*(?:"[^"]*"|'[^']*'|[^'">\s]+))*\s?[\/\?]?>/g;
if(!(XML_HEADER.match(tagregex))) tagregex = /<[^>]*>/g;
var nsregex=/<\w*:/, nsregex2 = /<(\/?)\w+:/;
function parsexmltag(tag/*:string*/, skip_root/*:?boolean*/)/*:any*/ {
@ -13,7 +13,8 @@ function parsexmltag(tag/*:string*/, skip_root/*:?boolean*/)/*:any*/ {
if(m) for(i = 0; i != m.length; ++i) {
cc = m[i];
for(c=0; c != cc.length; ++c) if(cc.charCodeAt(c) === 61) break;
q = cc.substr(0,c);
q = cc.substr(0,c).trim();
while(cc.charCodeAt(c+1) == 32) ++c;
quot = ((eq=cc.charCodeAt(c+1)) == 34 || eq == 39) ? 1 : 0;
v = cc.substring(c+1+quot, cc.length-quot);
for(j=0;j!=q.length;++j) if(q.charCodeAt(j) === 58) break;
@ -84,7 +85,7 @@ function parsexmlbool(value/*:any*/, tag/*:?string*/)/*:boolean*/ {
}
}
var utf8read/*:StringConv*/ = function utf8reada(orig) {
var utf8read/*:StringConv*/ = function utf8reada(orig/*:string*/)/*:string*/ {
var out = "", i = 0, c = 0, d = 0, e = 0, f = 0, w = 0;
while (i < orig.length) {
c = orig.charCodeAt(i++);
@ -101,7 +102,7 @@ var utf8read/*:StringConv*/ = function utf8reada(orig) {
return out;
};
var utf8write/*:StringConv*/ = function(orig) {
var utf8write/*:StringConv*/ = function(orig/*:string*/)/*:string*/ {
var out/*:Array<string>*/ = [], i = 0, c = 0, d = 0;
while(i < orig.length) {
c = orig.charCodeAt(i++);
@ -156,18 +157,18 @@ if(has_buf) {
// matches <foo>...</foo> extracts content
var matchtag = (function() {
var mtcache/*:{[k:string]:RegExp}*/ = ({}/*:any*/);
return function matchtag(f,g/*:?string*/)/*:RegExp*/ {
return function matchtag(f/*:string*/,g/*:?string*/)/*:RegExp*/ {
var t = f+"|"+(g||"");
if(mtcache[t]) return mtcache[t];
return (mtcache[t] = new RegExp('<(?:\\w+:)?'+f+'(?: xml:space="preserve")?(?:[^>]*)>([\\s\\S]*?)</(?:\\w+:)?'+f+'>',((g||"")/*:any*/)));
};
})();
var htmldecode = (function() {
var entities = [
var htmldecode/*:{(s:string):string}*/ = (function() {
var entities/*:Array<[RegExp, string]>*/ = [
['nbsp', ' '], ['middot', '·'],
['quot', '"'], ['apos', "'"], ['gt', '>'], ['lt', '<'], ['amp', '&']
].map(function(x) { return [new RegExp('&' + x[0] + ';', "g"), x[1]]; });
].map(function(x/*:[string, string]*/) { return [new RegExp('&' + x[0] + ';', "g"), x[1]]; });
return function htmldecode(str/*:string*/)/*:string*/ {
var o = str.trim().replace(/\s+/g, " ").replace(/<\s*[bB][rR]\s*\/?>/g,"\n").replace(/<[^>]*>/g,"");
for(var i = 0; i < entities.length; ++i) o = o.replace(entities[i][0], entities[i][1]);
@ -181,27 +182,27 @@ var vtregex = (function(){ var vt_cache = {};
return (vt_cache[bt] = new RegExp("<(?:vt:)?" + bt + ">([\\s\\S]*?)</(?:vt:)?" + bt + ">", 'g') );
};})();
var vtvregex = /<\/?(?:vt:)?variant>/g, vtmregex = /<(?:vt:)([^>]*)>([\s\S]*)</;
function parseVector(data, opts) {
function parseVector(data/*:string*/, opts)/*:Array<{v:string,t:string}>*/ {
var h = parsexmltag(data);
var matches = data.match(vtregex(h.baseType))||[];
var res = [];
var matches/*:Array<string>*/ = data.match(vtregex(h.baseType))||[];
var res/*:Array<any>*/ = [];
if(matches.length != h.size) {
if(opts.WTF) throw new Error("unexpected vector length " + matches.length + " != " + h.size);
return res;
}
matches.forEach(function(x) {
matches.forEach(function(x/*:string*/) {
var v = x.replace(vtvregex,"").match(vtmregex);
res.push({v:utf8read(v[2]), t:v[1]});
if(v) res.push({v:utf8read(v[2]), t:v[1]});
});
return res;
}
var wtregex = /(^\s|\s$|\n)/;
function writetag(f,g) {return '<' + f + (g.match(wtregex)?' xml:space="preserve"' : "") + '>' + g + '</' + f + '>';}
function writetag(f/*:string*/,g/*:string*/)/*:string*/ { return '<' + f + (g.match(wtregex)?' xml:space="preserve"' : "") + '>' + g + '</' + f + '>'; }
function wxt_helper(h)/*:string*/ { return keys(h).map(function(k) { return " " + k + '="' + h[k] + '"';}).join(""); }
function writextag(f,g,h) { return '<' + f + (isval(h) /*:: && h */? wxt_helper(h) : "") + (isval(g) /*:: && g */? (g.match(wtregex)?' xml:space="preserve"' : "") + '>' + g + '</' + f : "/") + '>';}
function writextag(f/*:string*/,g/*:?string*/,h) { return '<' + f + ((h != null) ? wxt_helper(h) : "") + ((g != null) ? (g.match(wtregex)?' xml:space="preserve"' : "") + '>' + g + '</' + f : "/") + '>';}
function write_w3cdtf(d/*:Date*/, t/*:?boolean*/)/*:string*/ { try { return d.toISOString().replace(/\.\d*/,""); } catch(e) { if(t) throw e; } return ""; }

@ -35,6 +35,8 @@ var __utf8 = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/) { var ss=
var ___utf8 = __utf8;
var __lpstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : "";};
var ___lpstr = __lpstr;
var __cpstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : "";};
var ___cpstr = __cpstr;
var __lpwstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = 2*__readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : "";};
var ___lpwstr = __lpwstr;
var __lpp4, ___lpp4;
@ -49,6 +51,7 @@ if(has_buf/*:: && typeof Buffer !== 'undefined'*/) {
__utf16le = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/)/*:string*/ { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___utf16le(b,s,e); return b.toString('utf16le',s,e).replace(chr0,'')/*.replace(chr1,'!')*/; };
__hexlify = function(b/*:RawBytes|CFBlob*/,s/*:number*/,l/*:number*/)/*:string*/ { return Buffer.isBuffer(b)/*:: && b instanceof Buffer*/ ? b.toString('hex',s,s+l) : ___hexlify(b,s,l); };
__lpstr = function lpstr_b(b/*:RawBytes|CFBlob*/, i/*:number*/) { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___lpstr(b, i); var len = b.readUInt32LE(i); return len > 0 ? b.toString('utf8',i+4,i+4+len-1) : "";};
__cpstr = function cpstr_b(b/*:RawBytes|CFBlob*/, i/*:number*/) { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___cpstr(b, i); var len = b.readUInt32LE(i); return len > 0 ? b.toString('utf8',i+4,i+4+len-1) : "";};
__lpwstr = function lpwstr_b(b/*:RawBytes|CFBlob*/, i/*:number*/) { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___lpwstr(b, i); var len = 2*b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len-1);};
__lpp4 = function lpp4_b(b/*:RawBytes|CFBlob*/, i/*:number*/) { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___lpp4(b, i); var len = b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len);};
__8lpp4 = function lpp4_8b(b/*:RawBytes|CFBlob*/, i/*:number*/) { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___8lpp4(b, i); var len = b.readUInt32LE(i); return b.toString('utf8',i+4,i+4+len);};
@ -63,7 +66,8 @@ if(has_buf/*:: && typeof Buffer !== 'undefined'*/) {
if(typeof cptable !== 'undefined') {
__utf16le = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/) { return cptable.utils.decode(1200, b.slice(s,e)).replace(chr0, ''); };
__utf8 = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/) { return cptable.utils.decode(65001, b.slice(s,e)); };
__lpstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(current_codepage, b.slice(i+4, i+4+len-1)) : "";};
__lpstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(current_ansi, b.slice(i+4, i+4+len-1)) : "";};
__cpstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(current_codepage, b.slice(i+4, i+4+len-1)) : "";};
__lpwstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = 2*__readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(1200, b.slice(i+4,i+4+len-1)) : "";};
__lpp4 = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(1200, b.slice(i+4,i+4+len)) : "";};
__8lpp4 = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(65001, b.slice(i+4,i+4+len)) : "";};
@ -98,9 +102,10 @@ function ReadShift(size/*:number*/, t/*:?string*/)/*:number|string*/ {
size = 2 * size; break;
/* [MS-OLEDS] 2.1.4 LengthPrefixedAnsiString */
case 'lpstr': o = __lpstr(this, this.l); size = 5 + o.length; break;
case 'lpstr-ansi': o = __lpstr(this, this.l); size = 4 + __readUInt32LE(this, this.l); break;
case 'lpstr-cp': o = __cpstr(this, this.l); size = 4 + __readUInt32LE(this, this.l); break;
/* [MS-OLEDS] 2.1.5 LengthPrefixedUnicodeString */
case 'lpwstr': o = __lpwstr(this, this.l); size = 5 + o.length; if(o[o.length-1] == '\u0000') size += 2; break;
case 'lpwstr': o = __lpwstr(this, this.l); size = 4 + 2 * __readUInt32LE(this, this.l); break;
/* [MS-OFFCRYPTO] 2.1.2 Length-Prefixed Padded Unicode String (UNICODE-LP-P4) */
case 'lpp4': size = 4 + __readUInt32LE(this, this.l); o = __lpp4(this, this.l); if(size & 0x02) size += 2; break;
/* [MS-OFFCRYPTO] 2.1.3 Length-Prefixed UTF-8 String (UTF-8-LP-P4) */
@ -222,9 +227,6 @@ function prep_blob(blob, pos/*:number*/)/*:void*/ {
}
function parsenoop(blob, length/*:: :number, opts?:any */) { blob.l += length; }
function parsenooplog(blob, length/*:number*/) { if(typeof console != 'undefined') console.log(blob.slice(blob.l, blob.l + length)); blob.l += length; }
function writenoop(blob, length/*:number*/) { blob.l += length; }
function new_buf(sz/*:number*/)/*:Block*/ {
var o = new_raw_buf(sz);

@ -20,14 +20,14 @@ function recordhopper(data, cb/*:RecordHopperCB*/, opts/*:?any*/) {
/* control buffer usage for fixed-length buffers */
function buf_array()/*:BufArray*/ {
var bufs = [], blksz = has_buf ? 256 : 2048;
var newblk = function ba_newblk(sz) {
var bufs/*:Array<Block>*/ = [], blksz = has_buf ? 256 : 2048;
var newblk = function ba_newblk(sz/*:number*/)/*:Block*/ {
var o/*:Block*/ = (new_buf(sz)/*:any*/);
prep_blob(o, 0);
return o;
};
var curbuf = newblk(blksz);
var curbuf/*:Block*/ = newblk(blksz);
var endbuf = function ba_endbuf() {
if(!curbuf) return;
@ -36,7 +36,7 @@ function buf_array()/*:BufArray*/ {
curbuf = null;
};
var next = function ba_next(sz) {
var next = function ba_next(sz/*:number*/)/*:Block*/ {
if(curbuf && sz < curbuf.length - curbuf.l) return curbuf;
endbuf();
return (curbuf = newblk(Math.max(sz+1, blksz)));
@ -56,7 +56,7 @@ function write_record(ba/*:BufArray*/, type/*:string*/, payload, length/*:?numbe
var t/*:number*/ = +XLSBRE[type], l;
if(isNaN(t)) return; // TODO: throw something here?
if(!length) length = XLSBRecordEnum[t].p || (payload||[]).length || 0;
l = 1 + (t >= 0x80 ? 1 : 0) + 1 + length;
l = 1 + (t >= 0x80 ? 1 : 0) + 1/* + length*/;
if(length >= 0x80) ++l; if(length >= 0x4000) ++l; if(length >= 0x200000) ++l;
var o = ba.next(l);
if(t <= 0x7F) o.write_shift(1, t);

@ -265,3 +265,19 @@ function write_FontFlags(font, o) {
return o;
}
/* [MS-OLEDS] 2.3.1 and 2.3.2 */
function parse_ClipboardFormatOrString(o, w/*:number*/)/*:string*/ {
// $FlowIgnore
var ClipFmt = {2:"BITMAP",3:"METAFILEPICT",8:"DIB",14:"ENHMETAFILE"};
var m/*:number*/ = o.read_shift(4);
switch(m) {
case 0x00000000: return "";
case 0xffffffff: case 0xfffffffe: return ClipFmt[o.read_shift(4)]||"";
}
if(m > 0x190) throw new Error("Unsupported Clipboard: " + m.toString(16));
o.l -= 4;
return o.read_shift(0, w == 1 ? "lpstr" : "lpwstr");
}
function parse_ClipboardFormatOrAnsiString(o) { return parse_ClipboardFormatOrString(o, 1); }
function parse_ClipboardFormatOrUnicodeString(o) { return parse_ClipboardFormatOrString(o, 2); }

@ -87,7 +87,7 @@ var SummaryPIDSI = {
/*::[*/0x0F/*::]*/: { n: 'WordCount', t: VT_I4 },
/*::[*/0x10/*::]*/: { n: 'CharCount', t: VT_I4 },
/*::[*/0x11/*::]*/: { n: 'Thumbnail', t: VT_CF },
/*::[*/0x12/*::]*/: { n: 'ApplicationName', t: VT_LPSTR },
/*::[*/0x12/*::]*/: { n: 'ApplicationName', t: VT_STRING },
/*::[*/0x13/*::]*/: { n: 'DocumentSecurity', t: VT_I4 },
/*::[*/0xFF/*::]*/: {}
};

@ -180,7 +180,7 @@ var CT_LIST = (function(){
xlsb: "application/vnd.ms-excel.styles"
}
};
keys(o).forEach(function(k) { if(!o[k].xlsm) o[k].xlsm = o[k].xlsx; });
keys(o).forEach(function(k) { ["xlsm", "xlam"].forEach(function(v) { if(!o[k][v]) o[k][v] = o[k].xlsx; }); });
keys(o).forEach(function(k){ keys(o[k]).forEach(function(v) { ct2type[o[k][v]] = k; }); });
return o;
})();

@ -84,7 +84,7 @@ var EXT_PROPS_XML_ROOT = writextag('Properties', null, {
});
function write_ext_props(cp, opts)/*:string*/ {
var o = [], p = {}, W = writextag;
var o/*:Array<string>*/ = [], p = {}, W = writextag;
if(!cp) cp = {};
cp.Application = "SheetJS";
o[o.length] = (XML_HEADER);

@ -39,7 +39,7 @@ function xlml_set_prop(Props, tag/*:string*/, val) {
}
function xlml_write_docprops(Props, opts) {
var o = [];
var o/*:Array<string>*/ = [];
keys(XLMLDocPropsMap).map(function(m) {
for(var i = 0; i < CORE_PROPS.length; ++i) if(CORE_PROPS[i][1] == m) return CORE_PROPS[i];
for(i = 0; i < EXT_PROPS.length; ++i) if(EXT_PROPS[i][1] == m) return EXT_PROPS[i];
@ -60,7 +60,7 @@ function xlml_write_docprops(Props, opts) {
function xlml_write_custprops(Props, Custprops, opts) {
var BLACKLIST = ["Worksheets","SheetNames"];
var T = 'CustomDocumentProperties';
var o = [];
var o/*:Array<string>*/ = [];
if(Props) keys(Props).forEach(function(k) {
/*:: if(!Props) return; */
if(!Props.hasOwnProperty(k)) return;

@ -8,8 +8,9 @@ function parse_FILETIME(blob) {
/* [MS-OSHARED] 2.3.3.1.4 Lpstr */
function parse_lpstr(blob, type, pad/*:?number*/) {
var str = blob.read_shift(0, 'lpstr');
if(pad) blob.l += (4 - ((str.length+1) & 3)) & 3;
var start = blob.l;
var str = blob.read_shift(0, 'lpstr-cp');
if(pad) while((blob.l - start) & 3) ++blob.l;
return str;
}
@ -32,15 +33,15 @@ function parse_VtString(blob, t/*:number*/, pad/*:?boolean*/) { return parse_VtS
function parse_VtUnalignedString(blob, t/*:number*/) { if(!t) throw new Error("VtUnalignedString must have positive length"); return parse_VtStringBase(blob, t, 0); }
/* [MS-OSHARED] 2.3.3.1.9 VtVecUnalignedLpstrValue */
function parse_VtVecUnalignedLpstrValue(blob) {
function parse_VtVecUnalignedLpstrValue(blob)/*:Array<string>*/ {
var length = blob.read_shift(4);
var ret = [];
for(var i = 0; i != length; ++i) ret[i] = blob.read_shift(0, 'lpstr');
var ret/*:Array<string>*/ = [];
for(var i = 0; i != length; ++i) ret[i] = blob.read_shift(0, 'lpstr-cp').replace(chr0,'');
return ret;
}
/* [MS-OSHARED] 2.3.3.1.10 VtVecUnalignedLpstr */
function parse_VtVecUnalignedLpstr(blob) {
function parse_VtVecUnalignedLpstr(blob)/*:Array<string>*/ {
return parse_VtVecUnalignedLpstrValue(blob);
}
@ -155,16 +156,17 @@ function parse_PropertySet(blob, PIDSI) {
var Offset = blob.read_shift(4);
Props[i] = [PropID, Offset + start_addr];
}
Props.sort(function(x,y) { return x[1] - y[1]; });
var PropH = {};
for(i = 0; i != NumProps; ++i) {
if(blob.l !== Props[i][1]) {
var fail = true;
if(i>0 && PIDSI) switch(PIDSI[Props[i-1][0]].t) {
case 0x02 /*VT_I2*/: if(blob.l +2 === Props[i][1]) { blob.l+=2; fail = false; } break;
case 0x02 /*VT_I2*/: if(blob.l+2 === Props[i][1]) { blob.l+=2; fail = false; } break;
case 0x50 /*VT_STRING*/: if(blob.l <= Props[i][1]) { blob.l=Props[i][1]; fail = false; } break;
case 0x100C /*VT_VECTOR|VT_VARIANT*/: if(blob.l <= Props[i][1]) { blob.l=Props[i][1]; fail = false; } break;
}
if(!PIDSI && blob.l <= Props[i][1]) { fail=false; blob.l = Props[i][1]; }
if((!PIDSI||i==0) && blob.l <= Props[i][1]) { fail=false; blob.l = Props[i][1]; }
if(fail) throw new Error("Read Error: Expected address " + Props[i][1] + ' at ' + blob.l + ' :' + i);
}
if(PIDSI) {
@ -326,7 +328,7 @@ function parse_XLUnicodeRichExtendedString(blob) {
var z = {};
if(fRichSt) cRun = blob.read_shift(2);
if(fExtSt) cbExtRst = blob.read_shift(4);
var encoding = (flags & 0x1) ? 'dbcs-cont' : 'sbcs-cont';
var encoding = width == 2 ? 'dbcs-cont' : 'sbcs-cont';
var msg = cch === 0 ? "" : blob.read_shift(cch, encoding);
if(fRichSt) blob.l += 4 * cRun; //TODO: parse this
if(fExtSt) blob.l += cbExtRst; //TODO: parse this
@ -398,15 +400,14 @@ function parse_URLMoniker(blob/*::, length, opts*/) {
/* [MS-OSHARED] 2.3.7.8 FileMoniker TODO: all fields */
function parse_FileMoniker(blob, length) {
var cAnti = blob.read_shift(2);
var ansiLength = blob.read_shift(4);
var ansiPath = blob.read_shift(ansiLength, 'cstr');
var ansiPath = blob.read_shift(0, 'lpstr-ansi');
var endServer = blob.read_shift(2);
var versionNumber = blob.read_shift(2);
var cbUnicodePathSize = blob.read_shift(4);
if(cbUnicodePathSize === 0) return ansiPath.replace(/\\/g,"/");
var cbUnicodePathBytes = blob.read_shift(4);
var usKeyValue = blob.read_shift(2);
var unicodePath = blob.read_shift(cbUnicodePathBytes>>1, 'utf16le').replace(chr0,"");
if(blob.read_shift(2) != 0xDEAD) throw new Error("Bad FileMoniker");
var sz = blob.read_shift(4);
if(sz === 0) return ansiPath.replace(/\\/g,"/");
var bytes = blob.read_shift(4);
if(blob.read_shift(2) != 3) throw new Error("Bad FileMoniker");
var unicodePath = blob.read_shift(bytes>>1, 'utf16le').replace(chr0,"");
return unicodePath;
}

@ -61,6 +61,14 @@ function parse_Ref8U(blob, length) {
var colLast = blob.read_shift(2);
return {s:{c:colFirst, r:rwFirst}, e:{c:colLast,r:rwLast}};
}
function write_Ref8U(r/*:Range*/, o) {
if(!o) o = new_buf(8);
o.write_shift(2, r.s.r);
o.write_shift(2, r.e.r);
o.write_shift(2, r.s.c);
o.write_shift(2, r.e.c);
return o;
}
/* 2.5.211 */
function parse_RefU(blob, length) {
@ -165,6 +173,7 @@ function write_BOF(wb/*:Workbook*/, t/*:number*/, o) {
case 'biff4': h = 0x0004; w = 6; break;
case 'biff3': h = 0x0003; w = 6; break;
case 'biff2': h = 0x0002; w = 4; break;
case 'xla': break;
default: throw new Error("unsupported BIFF version");
}
var out = new_buf(w);
@ -337,6 +346,22 @@ function write_Window1(opts) {
o.write_shift(2, 0x01f4);
return o;
}
/* 2.4.346 TODO */
function parse_Window2(blob, length, opts) {
if(opts && opts.biff >= 2 && opts.biff < 8) return {};
var f = blob.read_shift(2);
return { RTL: f & 0x40 };
}
function write_Window2(view) {
var o = new_buf(18), f = 0x6b6;
if(view && view.RTL) f |= 0x40;
o.write_shift(2, f);
o.write_shift(4, 0);
o.write_shift(4, 64);
o.write_shift(4, 0);
o.write_shift(4, 0);
return o;
}
/* 2.4.122 TODO */
function parse_Font(blob, length, opts) {
@ -624,7 +649,6 @@ function parse_ExternSheet(blob, length, opts) {
var o = [], target = blob.l + length, len = blob.read_shift(opts.biff > 8 ? 4 : 2);
while(len-- !== 0) o.push(parse_XTI(blob, opts.biff > 8 ? 12 : 6, opts));
// [iSupBook, itabFirst, itabLast];
var oo = [];
return o;
}
function parse_BIFF5ExternSheet(blob, length, opts) {
@ -689,12 +713,18 @@ function parse_Note(blob, length, opts) {
}
/* 2.4.168 */
function parse_MergeCells(blob, length) {
var merges = [];
function parse_MergeCells(blob, length)/*:Array<Range>*/ {
var merges/*:Array<Range>*/ = [];
var cmcs = blob.read_shift(2);
while (cmcs--) merges.push(parse_Ref8U(blob,length));
return merges;
}
function write_MergeCells(merges/*:Array<Range>*/) {
var o = new_buf(2 + merges.length * 8);
o.write_shift(2, merges.length);
for(var i = 0; i < merges.length; ++i) write_Ref8U(merges[i], o);
return o;
}
/* 2.4.181 TODO: parse all the things! */
function parse_Obj(blob, length, opts) {
@ -821,8 +851,8 @@ function write_HLinkTooltip(hl) {
}
/* 2.4.63 */
function parse_Country(blob, length) {
var o = [], d;
function parse_Country(blob, length)/*:[string|number, string|number]*/ {
var o = [0,0], d;
d = blob.read_shift(2); o[0] = CountryEnum[d] || d;
d = blob.read_shift(2); o[1] = CountryEnum[d] || d;
return o;

@ -86,10 +86,11 @@ function dbf_to_aoa(buf, opts)/*:AOA*/ {
d.l+=2;
}
if(l7) d.l += 36;
var fields = [], field = {};
/*:: type DBFField = { name:string; len:number; type:string; } */
var fields/*:Array<DBFField>*/ = [], field/*:DBFField*/ = ({}/*:any*/);
var hend = fpos - 10 - (vfp ? 264 : 0), ww = l7 ? 32 : 11;
while(ft == 0x02 ? d.l < d.length && d[d.l] != 0x0d: d.l < hend) {
field = {};
field = ({}/*:any*/);
field.name = cptable.utils.decode(current_cp, d.slice(d.l, d.l+ww)).replace(/[\u0000\r\n].*$/g,"");
d.l += ww;
field.type = String.fromCharCode(d.read_shift(1));
@ -210,7 +211,7 @@ function sheet_to_dbf(ws/*:Worksheet*/, opts/*:WriteOpts*/) {
if(headers.indexOf(headers[i] + "_" + j) == -1) { headers[i] += "_" + j; break; }
}
var range = safe_decode_range(ws['!ref']);
var coltypes = [];
var coltypes/*:Array<string>*/ = [];
for(i = 0; i <= range.e.c - range.s.c; ++i) {
var col/*:Array<any>*/ = [];
for(j=0; j < data.length; ++j) {
@ -307,10 +308,10 @@ var SYLK = (function() {
throw new Error("Unrecognized type " + opts.type);
}
function sylk_to_aoa_str(str/*:string*/, opts)/*:[AOA, Worksheet]*/ {
var records = str.split(/[\n\r]+/), R = -1, C = -1, ri = 0, rj = 0, arr = [];
var formats = [];
var next_cell_format = null;
var sht = {}, rowinfo = [], colinfo = [], cw = [];
var records = str.split(/[\n\r]+/), R = -1, C = -1, ri = 0, rj = 0, arr/*:AOA*/ = [];
var formats/*:Array<string>*/ = [];
var next_cell_format/*:string|null*/ = null;
var sht = {}, rowinfo/*:Array<RowInfo>*/ = [], colinfo/*:Array<ColInfo>*/ = [], cw/*:Array<string>*/ = [];
var Mval = 0, j;
for (; ri !== records.length; ++ri) {
Mval = 0;
@ -484,7 +485,7 @@ var DIF = (function() {
throw new Error("Unrecognized type " + opts.type);
}
function dif_to_aoa_str(str/*:string*/, opts)/*:AOA*/ {
var records = str.split('\n'), R = -1, C = -1, ri = 0, arr = [];
var records = str.split('\n'), R = -1, C = -1, ri = 0, arr/*:AOA*/ = [];
for (; ri !== records.length; ++ri) {
if (records[ri].trim() === 'BOT') { arr[++R] = []; C = 0; continue; }
if (R < 0) continue;
@ -585,7 +586,7 @@ var ETH = (function() {
function encode(s/*:string*/)/*:string*/ { return s.replace(/\\/g, "\\b").replace(/:/g, "\\c").replace(/\n/g,"\\n"); }
function eth_to_aoa(str/*:string*/, opts)/*:AOA*/ {
var records = str.split('\n'), R = -1, C = -1, ri = 0, arr = [];
var records = str.split('\n'), R = -1, C = -1, ri = 0, arr/*:AOA*/ = [];
for (; ri !== records.length; ++ri) {
var record = records[ri].trim().split(":");
if(record[0] !== 'cell') continue;
@ -632,7 +633,7 @@ var ETH = (function() {
function sheet_to_eth_data(ws/*:Worksheet*/)/*:string*/ {
if(!ws || !ws['!ref']) return "";
var o = [], oo = [], cell, coord;
var o/*:Array<string>*/ = [], oo/*:Array<string>*/ = [], cell, coord = "";
var r = decode_range(ws['!ref']);
var dense = Array.isArray(ws);
for(var R = r.s.r; R <= r.e.r; ++R) {
@ -648,12 +649,12 @@ var ETH = (function() {
else { oo[2]='vtf'; oo[3]='n'; oo[4]=cell.v; oo[5]=encode(cell.f); }
break;
case 'b':
oo[2] = 'vt'+(cell.f?'f':'c'); oo[3]='nl'; oo[4]=+!!cell.v;
oo[2] = 'vt'+(cell.f?'f':'c'); oo[3]='nl'; oo[4]=cell.v?"1":"0";
oo[5] = encode(cell.f||(cell.v?'TRUE':'FALSE'));
break;
case 'd':
var t = datenum(parseDate(cell.v));
oo[2] = 'vtc'; oo[3] = 'nd'; oo[4] = t;
oo[2] = 'vtc'; oo[3] = 'nd'; oo[4] = ""+t;
oo[5] = cell.w || SSF.format(cell.z || SSF._table[14], t);
break;
case 'e': continue;
@ -840,7 +841,7 @@ var PRN = (function() {
var r = safe_decode_range(ws['!ref']), cell/*:Cell*/;
var dense = Array.isArray(ws);
for(var R = r.s.r; R <= r.e.r; ++R) {
var oo = [];
var oo/*:Array<string>*/ = [];
for(var C = r.s.c; C <= r.e.c; ++C) {
var coord = encode_cell({r:R,c:C});
cell = dense ? (ws[R]||[])[C] : ws[coord];

@ -1,27 +1,3 @@
/* 18.4.1 charset to codepage mapping */
var CS2CP = ({
/*::[*/0/*::]*/: 1252, /* ANSI */
/*::[*/1/*::]*/: 65001, /* DEFAULT */
/*::[*/2/*::]*/: 65001, /* SYMBOL */
/*::[*/77/*::]*/: 10000, /* MAC */
/*::[*/128/*::]*/: 932, /* SHIFTJIS */
/*::[*/129/*::]*/: 949, /* HANGUL */
/*::[*/130/*::]*/: 1361, /* JOHAB */
/*::[*/134/*::]*/: 936, /* GB2312 */
/*::[*/136/*::]*/: 950, /* CHINESEBIG5 */
/*::[*/161/*::]*/: 1253, /* GREEK */
/*::[*/162/*::]*/: 1254, /* TURKISH */
/*::[*/163/*::]*/: 1258, /* VIETNAMESE */
/*::[*/177/*::]*/: 1255, /* HEBREW */
/*::[*/178/*::]*/: 1256, /* ARABIC */
/*::[*/186/*::]*/: 1257, /* BALTIC */
/*::[*/204/*::]*/: 1251, /* RUSSIAN */
/*::[*/222/*::]*/: 874, /* THAI */
/*::[*/238/*::]*/: 1250, /* EASTEUROPE */
/*::[*/255/*::]*/: 1252, /* OEM */
/*::[*/69/*::]*/: 6969 /* MISC */
}/*:any*/);
/* Parse a list of <r> tags */
var parse_rs = (function parse_rs_factory() {
var tregex = matchtag("t"), rpregex = matchtag("rPr"), rregex = /<(?:\w+:)?r>/g, rend = /<\/(?:\w+:)?r>/, nlregex = /\r\n/g;
@ -122,7 +98,7 @@ var parse_rs = (function parse_rs_factory() {
if(y[0].charCodeAt(1) !== 47) throw 'Unrecognized rich format ' + y[0];
}
}
var style = [];
var style/*:Array<string>*/ = [];
if(font.u) style.push("text-decoration: underline;");
if(font.uval) style.push("text-underline-style:" + font.uval + ";");
@ -145,14 +121,14 @@ var parse_rs = (function parse_rs_factory() {
/* 18.4.4 r CT_RElt */
function parse_r(r) {
var terms = [[],"",[]];
var terms/*:[Array<string>, string, Array<string>]*/ = [[],"",[]];
/* 18.4.12 t ST_Xstring */
var t = r.match(tregex), cp = 65001;
if(!isval(t)/*:: || !t*/) return "";
if(!t) return "";
terms[1] = t[1];
var rpr = r.match(rpregex);
if(isval(rpr)/*:: && rpr*/) cp = parse_rpr(rpr[1], terms[0], terms[2]);
if(rpr) cp = parse_rpr(rpr[1], terms[0], terms[2]);
return terms[0].join("") + terms[1].replace(nlregex,'<br/>') + terms[2].join("");
}
@ -196,7 +172,7 @@ function parse_sst_xml(data/*:string*/, opts)/*:SST*/ {
if(!data) return s;
/* 18.4.9 sst CT_Sst */
var sst = data.match(sstr0);
if(isval(sst)/*:: && sst*/) {
if(sst) {
ss = sst[2].replace(sstr1,"").split(sstr2);
for(var i = 0; i != ss.length; ++i) {
var o = parse_si(ss[i].trim(), opts);

@ -1,6 +1,6 @@
function _JS2ANSI(str/*:string*/)/*:Array<number>*/ {
if(typeof cptable !== 'undefined') return cptable.utils.encode(1252, str);
var o = [], oo = str.split("");
if(typeof cptable !== 'undefined') return cptable.utils.encode(current_ansi, str);
var o/*:Array<number>*/ = [], oo = str.split("");
for(var i = 0; i < oo.length; ++i) o[i] = oo[i].charCodeAt(0);
return o;
}
@ -31,14 +31,9 @@ function parse_DataSpaceMapEntry(blob) {
var end = blob.l + len - 4;
var o = {};
var cnt = blob.read_shift(4);
var comps = [];
while(cnt-- > 0) {
/* [MS-OFFCRYPTO] 2.1.6.2 DataSpaceReferenceComponent Structure */
var rc = {};
rc.t = blob.read_shift(4);
rc.v = blob.read_shift(0, 'lpp4');
comps.push(rc);
}
var comps/*:Array<{t:number, v:string}>*/ = [];
/* [MS-OFFCRYPTO] 2.1.6.2 DataSpaceReferenceComponent Structure */
while(cnt-- > 0) comps.push({ t: blob.read_shift(4), v: blob.read_shift(0, 'lpp4') });
o.name = blob.read_shift(0, 'lpp4');
o.comps = comps;
if(blob.l != end) throw new Error("Bad DataSpaceMapEntry: " + blob.l + " != " + end);
@ -55,8 +50,8 @@ function parse_DataSpaceMap(blob, length) {
}
/* [MS-OFFCRYPTO] 2.1.7 DataSpaceDefinition */
function parse_DataSpaceDefinition(blob, length) {
var o = [];
function parse_DataSpaceDefinition(blob, length)/*:Array<string>*/ {
var o/*:Array<string>*/ = [];
blob.l += 4; // must be 0x8
var cnt = blob.read_shift(4);
while(cnt-- > 0) o.push(blob.read_shift(0, 'lpp4'));

@ -321,7 +321,7 @@ function parse_cellXfs(t, styles, opts) {
}
function write_cellXfs(cellXfs)/*:string*/ {
var o = [];
var o/*:Array<string>*/ = [];
o[o.length] = (writextag('cellXfs',null));
cellXfs.forEach(function(c) { o[o.length] = (writextag('xf', null, c)); });
o[o.length] = ("</cellXfs>");

@ -206,7 +206,7 @@ function parse_sty_bin(data, themes, opts) {
styles.CellXf = [];
styles.Fonts = [];
var state = [];
var state/*:Array<string>*/ = [];
var pass = false;
recordhopper(data, function hopper_sty(val, R_n, RT) {
switch(RT) {

@ -1,8 +1,15 @@
/* [MS-XLS] 2.4.326 TODO: payload is a zip file */
function parse_Theme(blob, length, opts) {
var end = blob.l + length;
var dwThemeVersion = blob.read_shift(4);
if(dwThemeVersion === 124226) return;
blob.l += length-4;
if(!opts.cellStyles || !jszip) { blob.l = end; return; }
var data = blob.slice(blob.l);
blob.l = end;
var zip; try { zip = new jszip(data); } catch(e) { return; }
var themeXML = getzipstr(zip, "theme/theme/theme1.xml", true);
if(!themeXML) return;
return parse_theme_xml(themeXML, opts);
}
/* 2.5.49 */
@ -35,7 +42,7 @@ function parse_XFExtGradient(blob, length) {
}
/* 2.5.108 */
function parse_ExtProp(blob, length) {
function parse_ExtProp(blob, length)/*:Array<any>*/ {
var extType = blob.read_shift(2);
var cb = blob.read_shift(2);
var o = [extType];
@ -57,7 +64,7 @@ function parse_XFExt(blob, length) {
var ixfe = blob.read_shift(2);
blob.l += 2;
var cexts = blob.read_shift(2);
var ext = [];
var ext/*:AOA*/ = [];
while(cexts-- > 0) ext.push(parse_ExtProp(blob, end-blob.l));
return {ixfe:ixfe, ext:ext};
}

@ -18,9 +18,9 @@ function parse_comments(zip, dirComments, sheets, sheetRels, opts) {
}
}
function insertCommentsIntoSheet(sheetName, sheet, comments) {
function insertCommentsIntoSheet(sheetName, sheet, comments/*:Array<RawComment>*/) {
var dense = Array.isArray(sheet);
var cell, r;
var cell/*:Cell*/, r;
comments.forEach(function(comment) {
if(dense) {
r = decode_cell(comment.ref);
@ -42,7 +42,7 @@ function insertCommentsIntoSheet(sheetName, sheet, comments) {
}
if (!cell.c) cell.c = [];
var o = ({a: comment.author, t: comment.t, r: comment.r}/*:any*/);
var o/*:Comment*/ = ({a: comment.author, t: comment.t, r: comment.r});
if(comment.h) o.h = comment.h;
cell.c.push(o);
});

@ -1,9 +1,9 @@
/* 18.7 Comments */
function parse_comments_xml(data/*:string*/, opts)/*:Array<Comment>*/ {
function parse_comments_xml(data/*:string*/, opts)/*:Array<RawComment>*/ {
/* 18.7.6 CT_Comments */
if(data.match(/<(?:\w+:)?comments *\/>/)) return [];
var authors = [];
var commentList = [];
var authors/*:Array<string>*/ = [];
var commentList/*:Array<RawComment>*/ = [];
var authtag = data.match(/<(?:\w+:)?authors>([\s\S]*)<\/(?:\w+:)?authors>/);
if(authtag && authtag[1]) authtag[1].split(/<\/\w*:?author>/).forEach(function(x) {
if(x === "" || x.trim() === "") return;
@ -16,7 +16,7 @@ function parse_comments_xml(data/*:string*/, opts)/*:Array<Comment>*/ {
var cm = x.match(/<(?:\w+:)?comment[^>]*>/);
if(!cm) return;
var y = parsexmltag(cm[0]);
var comment/*:Comment*/ = ({ author: y.authorId && authors[y.authorId] || "sheetjsghost", ref: y.ref, guid: y.guid }/*:any*/);
var comment/*:RawComment*/ = ({ author: y.authorId && authors[y.authorId] || "sheetjsghost", ref: y.ref, guid: y.guid }/*:any*/);
var cell = decode_cell(y.ref);
if(opts.sheetRows && opts.sheetRows <= cell.r) return;
var textMatch = x.match(/<(?:\w+:)?text>([\s\S]*)<\/(?:\w+:)?text>/);
@ -34,7 +34,7 @@ var CMNT_XML_ROOT = writextag('comments', null, { 'xmlns': XMLNS.main[0] });
function write_comments_xml(data, opts) {
var o = [XML_HEADER, CMNT_XML_ROOT];
var iauthor = [];
var iauthor/*:Array<string>*/ = [];
o.push("<authors>");
data.map(function(x) { return x[1]; }).forEach(function(comment) {
comment.map(function(x) { return escapexml(x.a); }).forEach(function(a) {

@ -24,9 +24,9 @@ var parse_BrtCommentAuthor = parse_XLWideString;
function write_BrtCommentAuthor(data) { return write_XLWideString(data.slice(0, 54)); }
/* [MS-XLSB] 2.1.7.8 Comments */
function parse_comments_bin(data, opts) {
var out = [];
var authors = [];
function parse_comments_bin(data, opts)/*:Array<RawComment>*/ {
var out/*:Array<RawComment>*/ = [];
var authors/*:Array<string>*/ = [];
var c = {};
var pass = false;
recordhopper(data, function hopper_cmnt(val, R_n, RT) {
@ -65,33 +65,32 @@ function parse_comments_bin(data, opts) {
function write_comments_bin(data, opts) {
var ba = buf_array();
var iauthor = [];
var iauthor/*:Array<string>*/ = [];
write_record(ba, "BrtBeginComments");
{ /* COMMENTAUTHORS */
write_record(ba, "BrtBeginCommentAuthors");
data.forEach(function(comment) {
comment[1].forEach(function(c) {
if(iauthor.indexOf(c.a) > -1) return;
iauthor.push(c.a.slice(0,54));
write_record(ba, "BrtCommentAuthor", write_BrtCommentAuthor(c.a));
});