version bump 0.12.1: BIFF5 features

- BIFF5 write number formats and other features
- XLSX/XLSB/BIFF8 Suppress "Number stored as Text" errors
- codename awareness (fixes #992 h/t @samusstrike)
- updated CFB to 1.0.3
- demo refresh
This commit is contained in:
SheetJS 2018-02-14 15:06:35 -05:00
parent f002afae4b
commit 19620da30b
62 changed files with 2609 additions and 1836 deletions

@ -62,6 +62,7 @@ APIs
ArrayBuffer
Base64
Booleans
FileReader
JS
NoSQL
README

@ -430,6 +430,8 @@ function handleFile(e) {
input_dom_element.addEventListener('change', handleFile, false);
```
The [`oldie` demo](demos/oldie/) shows an IE-compatible fallback scenario.
</details>
More specialized cases, including mobile app file processing, are covered in the
@ -849,11 +851,13 @@ for(var R = range.s.r; R <= range.e.r; ++R) {
### Cell Object
Cell objects are plain JS objects with keys and values following the convention:
| Key | Description |
| --- | ---------------------------------------------------------------------- |
| `v` | raw value (see Data Types section for more info) |
| `w` | formatted text (if applicable) |
| `t` | cell type: `b` Boolean, `n` Number, `e` error, `s` String, `d` Date |
| `t` | type: `b` Boolean, `e` Error, `n` Number, `d` Date, `s` Text, `z` Stub |
| `f` | cell formula encoded as an A1-style string (if applicable) |
| `F` | range of enclosing array if formula is array formula (if applicable) |
| `r` | rich text encoding (if applicable) |
@ -873,11 +877,18 @@ array range. Other cells in the range will omit the `f` field.
#### Data Types
The raw value is stored in the `v` field, interpreted based on the `t` field.
The raw value is stored in the `v` value property, interpreted based on the `t`
type property. This separation allows for representation of numbers as well as
numeric text. There are 6 valid cell types:
Type `b` is the Boolean type. `v` is interpreted according to JS truth tables.
Type `e` is the Error type. `v` holds the number and `w` holds the common name:
| Type | Description |
| :--: | :-------------------------------------------------------------------- |
| `b` | Boolean: value interpreted as JS `boolean` |
| `e` | Error: value is a numeric code and `w` property stores common name ** |
| `n` | Number: value is a JS `number` ** |
| `d` | Date: value is a JS `Date` object or string to be parsed as Date ** |
| `s` | Text: value interpreted as JS `string` and written as text ** |
| `z` | Stub: blank stub cell that is ignored by data processing utilities ** |
<details>
<summary><b>Error values and interpretation</b> (click to show)</summary>
@ -906,14 +917,17 @@ Since JSON does not have a natural Date type, parsers are generally expected to
store ISO 8601 Date strings like you would get from `date.toISOString()`. On
the other hand, writers and exporters should be able to handle date strings and
JS Date objects. Note that Excel disregards timezone modifiers and treats all
dates in the local timezone. js-xlsx does not correct for this error.
dates in the local timezone. The library does not correct for this error.
Type `s` is the String type. `v` should be explicitly stored as a string to
avoid possible confusion.
Type `s` is the String type. Values are explicitly stored as text. Excel will
interpret these cells as "number stored as text". Generated Excel files
automatically suppress that class of error, but other formats may elicit errors.
Type `z` represents blank stub cells. They are generated in cases where cells
have no assigned value but hold comments or other metadata. They are ignored by
the core library data processing utility functions. By default these cells are
not generated; the parser `sheetStubs` option must be set to `true`.
Type `z` represents blank stub cells. These do not have any data or type, and
are not processed by any of the core library functions. By default these cells
will not be generated; the parser `sheetStubs` option must be set to `true`.
#### Dates

@ -1 +1 @@
XLSX.version = '0.12.0';
XLSX.version = '0.12.1';

@ -18,6 +18,46 @@ var XLMLFormatMap/*{[string]:string}*/ = ({
"On/Off": '"Yes";"Yes";"No";@'
}/*:any*/);
var SSFImplicit/*{[number]:string}*/ = ({
"5": '"$"#,##0_);\\("$"#,##0\\)',
"6": '"$"#,##0_);[Red]\\("$"#,##0\\)',
"7": '"$"#,##0.00_);\\("$"#,##0.00\\)',
"8": '"$"#,##0.00_);[Red]\\("$"#,##0.00\\)',
"23": 'General', "24": 'General', "25": 'General', "26": 'General',
"27": 'm/d/yy', "28": 'm/d/yy', "29": 'm/d/yy', "30": 'm/d/yy', "31": 'm/d/yy',
"32": 'h:mm:ss', "33": 'h:mm:ss', "34": 'h:mm:ss', "35": 'h:mm:ss',
"36": 'm/d/yy',
"41": '_(* #,##0_);_(* \(#,##0\);_(* "-"_);_(@_)',
"42": '_("$"* #,##0_);_("$"* \(#,##0\);_("$"* "-"_);_(@_)',
"43": '_(* #,##0.00_);_(* \(#,##0.00\);_(* "-"??_);_(@_)',
"44": '_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)',
"50": 'm/d/yy', "51": 'm/d/yy', "52": 'm/d/yy', "53": 'm/d/yy', "54": 'm/d/yy',
"55": 'm/d/yy', "56": 'm/d/yy', "57": 'm/d/yy', "58": 'm/d/yy',
"59": '0',
"60": '0.00',
"61": '#,##0',
"62": '#,##0.00',
"63": '"$"#,##0_);\\("$"#,##0\\)',
"64": '"$"#,##0_);[Red]\\("$"#,##0\\)',
"65": '"$"#,##0.00_);\\("$"#,##0.00\\)',
"66": '"$"#,##0.00_);[Red]\\("$"#,##0.00\\)',
"67": '0%',
"68": '0.00%',
"69": '# ?/?',
"70": '# ??/??',
"71": 'm/d/yy',
"72": 'm/d/yy',
"73": 'd-mmm-yy',
"74": 'd-mmm',
"75": 'mmm-yy',
"76": 'h:mm',
"77": 'h:mm:ss',
"78": 'm/d/yy h:mm',
"79": 'mm:ss',
"80": '[h]:mm:ss',
"81": 'mmss.0'
}/*:any*/);
/* dateNF parse TODO: move to SSF */
var dateNFregex = /[dD]+|[mM]+|[yYeE]+|[Hh]+|[Ss]+/g;
function dateNF_regex(dateNF/*:string|number*/)/*:RegExp*/ {

@ -38,7 +38,7 @@ type CFBFiles = {[n:string]:CFBEntry};
/* [MS-CFB] v20130118 */
var CFB = (function _CFB(){
var exports/*:CFBModule*/ = /*::(*/{}/*:: :any)*/;
exports.version = '1.0.2';
exports.version = '1.0.3';
/* [MS-CFB] 2.6.4 */
function namecmp(l/*:string*/, r/*:string*/)/*:number*/ {
var L = l.split("/"), R = r.split("/");
@ -353,14 +353,14 @@ function read_directory(dir_start/*:number*/, sector_list/*:SectorList*/, sector
if(sector_list[o.start] === undefined) sector_list[o.start] = get_sector_list(sectors, o.start, sector_list.fat_addrs, sector_list.ssz);
sector_list[o.start].name = o.name;
o.content = (sector_list[o.start].data.slice(0,o.size)/*:any*/);
prep_blob(o.content, 0);
} else {
o.storage = 'minifat';
if(minifat_store !== ENDOFCHAIN && o.start !== ENDOFCHAIN && sector_list[minifat_store]) {
if(o.size < 0) o.size = 0;
else if(minifat_store !== ENDOFCHAIN && o.start !== ENDOFCHAIN && sector_list[minifat_store]) {
o.content = get_mfat_entry(o, sector_list[minifat_store].data, (sector_list[mini]||{}).data);
prep_blob(o.content, 0);
}
}
if(o.content) prep_blob(o.content, 0);
files[name] = o;
FileIndex.push(o);
}

@ -2,7 +2,7 @@ function keys(o/*:any*/)/*:Array<any>*/ { return Object.keys(o); }
function evert_key(obj/*:any*/, key/*:string*/)/*:EvertType*/ {
var o = ([]/*:any*/), K = keys(obj);
for(var i = 0; i !== K.length; ++i) o[obj[K[i]][key]] = K[i];
for(var i = 0; i !== K.length; ++i) if(o[obj[K[i]][key]] == null) o[obj[K[i]][key]] = K[i];
return o;
}

@ -188,7 +188,7 @@ function WriteShift(t/*:number*/, val/*:string|number*/, f/*:?string*/)/*:any*/
} return this;
} else if(f === 'utf16le') {
/*:: if(typeof val !== "string") throw new Error("unreachable"); */
var end/*:number*/ = this.l + t;
var end/*:number*/ = Math.min(this.l + t, this.length);
for(i = 0; i < Math.min(val.length, t); ++i) {
var cc = val.charCodeAt(i);
this[this.l++] = (cc & 0xff);

@ -27,7 +27,7 @@ function write_StrRun(run, o) {
return o;
}
/* [MS-XLSB] 2.1.7.121 */
/* [MS-XLSB] 2.5.121 */
function parse_RichStr(data, length/*:number*/)/*:XLString*/ {
var start = data.l;
var flags = data.read_shift(1);
@ -54,7 +54,7 @@ function write_RichStr(str/*:XLString*/, o/*:?Block*/)/*:Block*/ {
write_XLWideString(str.t, o);
return _null ? o.slice(0, o.l) : o;
}
/* [MS-XLSB] 2.4.325 BrtCommentText (RichStr w/1 run) */
/* [MS-XLSB] 2.4.328 BrtCommentText (RichStr w/1 run) */
var parse_BrtCommentText = parse_RichStr;
function write_BrtCommentText(str/*:XLString*/, o/*:?Block*/)/*:Block*/ {
/* TODO: formatted string */
@ -108,8 +108,7 @@ var parse_RelID = parse_XLNullableWideString;
var write_RelID = write_XLNullableWideString;
/* [MS-XLSB] 2.5.122 */
/* [MS-XLS] 2.5.217 */
/* [MS-XLS] 2.5.217 ; [MS-XLSB] 2.5.122 */
function parse_RkNumber(data)/*:number*/ {
var b = data.slice(data.l, data.l+4);
var fX100 = (b[0] & 1), fInt = (b[0] & 2);
@ -137,7 +136,6 @@ function parse_RfX(data /*::, length*/)/*:Range*/ {
cell.e.c = data.read_shift(4);
return cell;
}
function write_RfX(r/*:Range*/, o) {
if(!o) o = new_buf(16);
o.write_shift(4, r.s.r);
@ -151,13 +149,12 @@ function write_RfX(r/*:Range*/, o) {
var parse_UncheckedRfX = parse_RfX;
var write_UncheckedRfX = write_RfX;
/* [MS-XLSB] 2.5.171 */
/* [MS-XLS] 2.5.342 */
/* [MS-XLS] 2.5.342 ; [MS-XLSB] 2.5.171 */
/* TODO: error checking, NaN and Infinity values are not valid Xnum */
function parse_Xnum(data/*::, length*/) { return data.read_shift(8, 'f'); }
function write_Xnum(data, o) { return (o || new_buf(8)).write_shift(8, data, 'f'); }
/* [MS-XLSB] 2.5.198.2 */
/* [MS-XLSB] 2.5.97.2 */
var BErr = {
/*::[*/0x00/*::]*/: "#NULL!",
/*::[*/0x07/*::]*/: "#DIV/0!",
@ -171,7 +168,7 @@ var BErr = {
};
var RBErr = evert_num(BErr);
/* [MS-XLSB] 2.4.321 BrtColor */
/* [MS-XLSB] 2.4.324 BrtColor */
function parse_BrtColor(data/*::, length*/) {
var out = {};
var d = data.read_shift(1);

@ -184,7 +184,7 @@ var XLSFillPattern = [
function rgbify(arr) { return arr.map(function(x) { return [(x>>16)&255,(x>>8)&255,x&255]; }); }
/* [MS-XLS] 2.5.161 */
/* [MS-XLSB] 2.5.75 */
/* [MS-XLSB] 2.5.75 Icv */
var XLSIcv = rgbify([
/* Color Constants */
0x000000,

@ -1,8 +1,7 @@
/* Parts enumerated in OPC spec, MS-XLSB and MS-XLSX */
/* 12.3 Part Summary <SpreadsheetML> */
/* 14.2 Part Summary <DrawingML> */
/* [MS-XLSX] 2.1 Part Enumerations */
/* [MS-XLSB] 2.1.7 Part Enumeration */
/* [MS-XLSX] 2.1 Part Enumerations ; [MS-XLSB] 2.1.7 Part Enumeration */
var ct2type/*{[string]:string}*/ = ({
/* Workbook */
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml": "workbooks",

@ -213,7 +213,7 @@ function parse_PropertySet(blob, PIDSI) {
}
/* [MS-OLEPS] 2.21 PropertySetStream */
function parse_PropertySetStream(file, PIDSI) {
function parse_PropertySetStream(file, PIDSI, clsid) {
var blob = file.content;
if(!blob) return ({}/*:any*/);
prep_blob(blob, 0);
@ -223,7 +223,8 @@ function parse_PropertySetStream(file, PIDSI) {
/*var vers = */blob.read_shift(2); // TODO: check version
var SystemIdentifier = blob.read_shift(4);
blob.chk(CFB.utils.consts.HEADER_CLSID, 'CLSID: ');
var CLSID = blob.read_shift(16);
if(CLSID !== CFB.utils.consts.HEADER_CLSID && CLSID !== clsid) throw new Error("Bad PropertySet CLSID " + CLSID);
NumSets = blob.read_shift(4);
if(NumSets !== 1 && NumSets !== 2) throw new Error("Unrecognized #Sets: " + NumSets);
FMTID0 = blob.read_shift(16); Offset0 = blob.read_shift(4);
@ -274,7 +275,7 @@ function parse_Bes(blob/*::, length*/) {
function write_Bes(v, t/*:string*/, o) {
if(!o) o = new_buf(2);
o.write_shift(1, +v);
o.write_shift(1, t == 'e' ? 1 : 0);
o.write_shift(1, ((t == 'e') ? 1 : 0));
return o;
}

@ -1,6 +1,4 @@
/* --- MS-XLS --- */
/* 2.5.19 */
/* [MS-XLS] 2.5.19 */
function parse_XLSCell(blob/*::, length*/)/*:Cell*/ {
var rw = blob.read_shift(2); // 0-indexed
var col = blob.read_shift(2);
@ -15,7 +13,7 @@ function write_XLSCell(R/*:number*/, C/*:number*/, ixfe/*:?number*/, o) {
return o;
}
/* 2.5.134 */
/* [MS-XLS] 2.5.134 */
function parse_frtHeader(blob) {
var rt = blob.read_shift(2);
var flags = blob.read_shift(2); // TODO: parse these flags
@ -27,21 +25,21 @@ function parse_frtHeader(blob) {
function parse_OptXLUnicodeString(blob, length, opts) { return length === 0 ? "" : parse_XLUnicodeString2(blob, length, opts); }
/* 2.5.344 */
/* [MS-XLS] 2.5.344 */
function parse_XTI(blob, length, opts) {
var w = opts.biff > 8 ? 4 : 2;
var iSupBook = blob.read_shift(w), itabFirst = blob.read_shift(w,'i'), itabLast = blob.read_shift(w,'i');
return [iSupBook, itabFirst, itabLast];
}
/* 2.5.218 */
/* [MS-XLS] 2.5.218 */
function parse_RkRec(blob) {
var ixfe = blob.read_shift(2);
var RK = parse_RkNumber(blob);
return [ixfe, RK];
}
/* 2.5.1 */
/* [MS-XLS] 2.5.1 */
function parse_AddinUdf(blob, length, opts) {
blob.l += 4; length -= 4;
var l = blob.l + length;
@ -53,7 +51,7 @@ function parse_AddinUdf(blob, length, opts) {
return udfName;
}
/* 2.5.209 TODO: Check sizes */
/* [MS-XLS] 2.5.209 TODO: Check sizes */
function parse_Ref8U(blob/*::, length*/) {
var rwFirst = blob.read_shift(2);
var rwLast = blob.read_shift(2);
@ -70,7 +68,7 @@ function write_Ref8U(r/*:Range*/, o) {
return o;
}
/* 2.5.211 */
/* [MS-XLS] 2.5.211 */
function parse_RefU(blob/*::, length*/) {
var rwFirst = blob.read_shift(2);
var rwLast = blob.read_shift(2);
@ -79,10 +77,10 @@ function parse_RefU(blob/*::, length*/) {
return {s:{c:colFirst, r:rwFirst}, e:{c:colLast,r:rwLast}};
}
/* 2.5.207 */
/* [MS-XLS] 2.5.207 */
var parse_Ref = parse_RefU;
/* 2.5.143 */
/* [MS-XLS] 2.5.143 */
function parse_FtCmo(blob/*::, length*/) {
blob.l += 4;
var ot = blob.read_shift(2);
@ -92,7 +90,7 @@ function parse_FtCmo(blob/*::, length*/) {
return [id, ot, flags];
}
/* 2.5.149 */
/* [MS-XLS] 2.5.149 */
function parse_FtNts(blob) {
var out = {};
blob.l += 4;
@ -102,7 +100,7 @@ function parse_FtNts(blob) {
return out;
}
/* 2.5.142 */
/* [MS-XLS] 2.5.142 */
function parse_FtCf(blob) {
var out = {};
blob.l += 4;
@ -110,7 +108,7 @@ function parse_FtCf(blob) {
return out;
}
/* 2.5.140 - 2.5.154 and friends */
/* [MS-XLS] 2.5.140 - 2.5.154 and friends */
function parse_FtSkip(blob) { blob.l += 2; blob.l += blob.read_shift(2); }
var FtTab = {
/*::[*/0x00/*::]*/: parse_FtSkip, /* FtEnd */
@ -149,7 +147,7 @@ function parse_FtArray(blob, length/*::, ot*/) {
/* --- 2.4 Records --- */
/* 2.4.21 */
/* [MS-XLS] 2.4.21 */
function parse_BOF(blob, length) {
var o = {BIFFVer:0, dt:0};
o.BIFFVer = blob.read_shift(2); length -= 2;
@ -191,7 +189,7 @@ function write_BOF(wb/*:Workbook*/, t/*:number*/, o) {
}
/* 2.4.146 */
/* [MS-XLS] 2.4.146 */
function parse_InterfaceHdr(blob, length) {
if(length === 0) return 0x04b0;
if((blob.read_shift(2))!==0x04b0){/* empty */}
@ -199,7 +197,7 @@ function parse_InterfaceHdr(blob, length) {
}
/* 2.4.349 */
/* [MS-XLS] 2.4.349 */
function parse_WriteAccess(blob, length, opts) {
if(opts.enc) { blob.l += length; return ""; }
var l = blob.l;
@ -212,20 +210,20 @@ function write_WriteAccess(s/*:string*/, opts) {
var b8 = !opts || opts.biff == 8;
var o = new_buf(b8 ? 112 : 54);
o.write_shift(opts.biff == 8 ? 2 : 1, 7);
o.write_shift(1, 0);
if(b8) o.write_shift(1, 0);
o.write_shift(4, 0x33336853);
o.write_shift(4, 0x00534A74);
while(o.l < o.length) o.write_shift(1, 0);
o.write_shift(4, (0x00534A74 | (b8 ? 0 : 0x20000000)));
while(o.l < o.length) o.write_shift(1, (b8 ? 0 : 32));
return o;
}
/* 2.4.351 */
/* [MS-XLS] 2.4.351 */
function parse_WsBool(blob, length, opts) {
var flags = opts && opts.biff == 8 || length == 2 ? blob.read_shift(2) : (blob.l += length, 0);
return { fDialog: flags & 0x10 };
}
/* 2.4.28 */
/* [MS-XLS] 2.4.28 */
function parse_BoundSheet8(blob, length, opts) {
var pos = blob.read_shift(4);
var hidden = blob.read_shift(1) & 0x03;
@ -253,7 +251,7 @@ function write_BoundSheet8(data, opts) {
out.l = o.l; return out;
}
/* 2.4.265 TODO */
/* [MS-XLS] 2.4.265 TODO */
function parse_SST(blob, length)/*:SST*/ {
var end = blob.l + length;
var cnt = blob.read_shift(4);
@ -266,7 +264,7 @@ function parse_SST(blob, length)/*:SST*/ {
return strs;
}
/* 2.4.107 */
/* [MS-XLS] 2.4.107 */
function parse_ExtSST(blob, length) {
var extsst = {};
extsst.dsst = blob.read_shift(2);
@ -275,7 +273,7 @@ function parse_ExtSST(blob, length) {
}
/* 2.4.221 TODO: check BIFF2-4 */
/* [MS-XLS] 2.4.221 TODO: check BIFF2-4 */
function parse_Row(blob) {
var z = ({}/*:any*/);
z.r = blob.read_shift(2);
@ -293,7 +291,7 @@ function parse_Row(blob) {
}
/* 2.4.125 */
/* [MS-XLS] 2.4.125 */
function parse_ForceFullCalculation(blob) {
var header = parse_frtHeader(blob);
if(header.type != 0x08A3) throw new Error("Invalid Future Record " + header.type);
@ -305,13 +303,13 @@ function parse_ForceFullCalculation(blob) {
/* 2.4.215 rt */
/* [MS-XLS] 2.4.215 rt */
function parse_RecalcId(blob) {
blob.read_shift(2);
return blob.read_shift(4);
}
/* 2.4.87 */
/* [MS-XLS] 2.4.87 */
function parse_DefaultRowHeight(blob, length, opts) {
var f = 0;
if(!(opts && opts.biff == 2)) {
@ -325,7 +323,7 @@ function parse_DefaultRowHeight(blob, length, opts) {
return [fl, miyRw];
}
/* 2.4.345 TODO */
/* [MS-XLS] 2.4.345 TODO */
function parse_Window1(blob) {
var xWn = blob.read_shift(2), yWn = blob.read_shift(2), dxWn = blob.read_shift(2), dyWn = blob.read_shift(2);
var flags = blob.read_shift(2), iTabCur = blob.read_shift(2), iTabFirst = blob.read_shift(2);
@ -346,7 +344,7 @@ function write_Window1(/*::opts*/) {
o.write_shift(2, 0x01f4);
return o;
}
/* 2.4.346 TODO */
/* [MS-XLS] 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);
@ -363,13 +361,13 @@ function write_Window2(view) {
return o;
}
/* 2.4.122 TODO */
/* [MS-XLS] 2.4.122 TODO */
function parse_Font(blob, length, opts) {
var o/*:any*/ = {
dyHeight: blob.read_shift(2),
fl: blob.read_shift(2)
};
switch(opts && opts.biff || 8) {
switch((opts && opts.biff) || 8) {
case 2: break;
case 3: case 4: blob.l += 2; break;
default: blob.l += 10; break;
@ -377,15 +375,29 @@ function parse_Font(blob, length, opts) {
o.name = parse_ShortXLUnicodeString(blob, 0, opts);
return o;
}
function write_Font(data, opts) {
var name = data.name || "Arial";
var b5 = (opts && (opts.biff == 5)), w = (b5 ? (15 + name.length) : (16 + 2 * name.length));
var o = new_buf(w);
o.write_shift(2, (data.sz || 12) * 20);
o.write_shift(4, 0);
o.write_shift(2, 400);
o.write_shift(4, 0);
o.write_shift(2, 0);
o.write_shift(1, name.length);
if(!b5) o.write_shift(1, 1);
o.write_shift((b5 ? 1 : 2) * name.length, name, (b5 ? "sbcs" : "utf16le"));
return o;
}
/* 2.4.149 */
/* [MS-XLS] 2.4.149 */
function parse_LabelSst(blob) {
var cell = parse_XLSCell(blob);
cell.isst = blob.read_shift(4);
return cell;
}
/* 2.4.148 */
/* [MS-XLS] 2.4.148 */
function parse_Label(blob, length, opts) {
var target = blob.l + length;
var cell = parse_XLSCell(blob, 6);
@ -405,23 +417,26 @@ function write_Label(R/*:number*/, C/*:number*/, v/*:string*/, os/*:number*/, op
}
/* 2.4.126 Number Formats */
/* [MS-XLS] 2.4.126 Number Formats */
function parse_Format(blob, length, opts) {
var numFmtId = blob.read_shift(2);
var fmtstr = parse_XLUnicodeString2(blob, 0, opts);
return [numFmtId, fmtstr];
}
function write_Format(i/*:number*/, f/*:string*/, o) {
if(!o) o = new_buf(6 + 4 * f.length);
function write_Format(i/*:number*/, f/*:string*/, opts, o) {
var b5 = (opts && (opts.biff == 5));
if(!o) o = new_buf(b5 ? (3 + f.length) : (5 + 2 * f.length));
o.write_shift(2, i);
write_XLUnicodeString(f, null, o);
o.write_shift((b5 ? 1 : 2), f.length);
if(!b5) o.write_shift(1, 1);
o.write_shift((b5 ? 1 : 2) * f.length, f, (b5 ? 'sbcs' : 'utf16le'));
var out = (o.length > o.l) ? o.slice(0, o.l) : o;
if(o.l == null) o.l = o.length;
if(out.l == null) out.l = out.length;
return out;
}
var parse_BIFF2Format = parse_XLUnicodeString2;
/* 2.4.90 */
/* [MS-XLS] 2.4.90 */
function parse_Dimensions(blob, length, opts) {
var end = blob.l + length;
var w = opts.biff == 8 || !opts.biff ? 4 : 2;
@ -441,14 +456,14 @@ function write_Dimensions(range, opts) {
return o;
}
/* 2.4.220 */
/* [MS-XLS] 2.4.220 */
function parse_RK(blob) {
var rw = blob.read_shift(2), col = blob.read_shift(2);
var rkrec = parse_RkRec(blob);
return {r:rw, c:col, ixfe:rkrec[0], rknum:rkrec[1]};
}
/* 2.4.175 */
/* [MS-XLS] 2.4.175 */
function parse_MulRk(blob, length) {
var target = blob.l + length - 2;
var rw = blob.read_shift(2), col = blob.read_shift(2);
@ -459,7 +474,7 @@ function parse_MulRk(blob, length) {
if(rkrecs.length != lastcol - col + 1) throw new Error("MulRK length mismatch");
return {r:rw, c:col, C:lastcol, rkrec:rkrecs};
}
/* 2.4.174 */
/* [MS-XLS] 2.4.174 */
function parse_MulBlank(blob, length) {
var target = blob.l + length - 2;
var rw = blob.read_shift(2), col = blob.read_shift(2);
@ -471,7 +486,7 @@ function parse_MulBlank(blob, length) {
return {r:rw, c:col, C:lastcol, ixfe:ixfes};
}
/* 2.5.20 2.5.249 TODO: interpret values here */
/* [MS-XLS] 2.5.20 2.5.249 TODO: interpret values here */
function parse_CellStyleXF(blob, length, style, opts) {
var o = {};
var a = blob.read_shift(4), b = blob.read_shift(4);
@ -515,7 +530,7 @@ function parse_CellStyleXF(blob, length, style, opts) {
//function parse_CellXF(blob, length, opts) {return parse_CellStyleXF(blob,length,0, opts);}
//function parse_StyleXF(blob, length, opts) {return parse_CellStyleXF(blob,length,1, opts);}
/* 2.4.353 TODO: actually do this right */
/* [MS-XLS] 2.4.353 TODO: actually do this right */
function parse_XF(blob, length, opts) {
var o = {};
o.ifnt = blob.read_shift(2); o.numFmtId = blob.read_shift(2); o.flags = blob.read_shift(2);
@ -524,19 +539,25 @@ function parse_XF(blob, length, opts) {
o.data = parse_CellStyleXF(blob, length, o.fStyle, opts);
return o;
}
function write_XF(data, ixfeP, o) {
if(!o) o = new_buf(20);
o.write_shift(2, 0);
o.write_shift(2, data.numFmtId||0);
function write_XF(data, ixfeP, opts, o) {
var b5 = (opts && (opts.biff == 5));
if(!o) o = new_buf(b5 ? 16 : 20);
o.write_shift(2, 0);
if(data.style) {
o.write_shift(2, (data.numFmtId||0));
o.write_shift(2, 0xFFF4);
} else {
o.write_shift(2, (data.numFmtId||0));
o.write_shift(2, (ixfeP<<4));
}
o.write_shift(4, 0);
o.write_shift(4, 0);
o.write_shift(4, 0);
if(!b5) o.write_shift(4, 0);
o.write_shift(2, 0);
return o;
}
/* 2.4.134 */
/* [MS-XLS] 2.4.134 */
function parse_Guts(blob) {
blob.l += 4;
var out = [blob.read_shift(2), blob.read_shift(2)];
@ -553,7 +574,7 @@ function write_Guts(guts/*:Array<number>*/) {
return o;
}
/* 2.4.24 */
/* [MS-XLS] 2.4.24 */
function parse_BoolErr(blob, length, opts) {
var cell = parse_XLSCell(blob, 6);
if(opts.biff == 2) ++blob.l;
@ -569,7 +590,7 @@ function write_BoolErr(R/*:number*/, C/*:number*/, v, os/*:number*/, opts, t/*:s
return o;
}
/* 2.4.180 Number */
/* [MS-XLS] 2.4.180 Number */
function parse_Number(blob) {
var cell = parse_XLSCell(blob, 6);
var xnum = parse_Xnum(blob, 8);
@ -585,7 +606,7 @@ function write_Number(R/*:number*/, C/*:number*/, v, os/*:: :number, opts*/) {
var parse_XLHeaderFooter = parse_OptXLUnicodeString; // TODO: parse 2.4.136
/* 2.4.271 */
/* [MS-XLS] 2.4.271 */
function parse_SupBook(blob, length, opts) {
var end = blob.l + length;
var ctab = blob.read_shift(2);
@ -600,7 +621,7 @@ function parse_SupBook(blob, length, opts) {
return [cch, ctab, virtPath, rgst];
}
/* 2.4.105 TODO */
/* [MS-XLS] 2.4.105 TODO */
function parse_ExternName(blob, length, opts) {
var flags = blob.read_shift(2);
var body;
@ -620,7 +641,7 @@ function parse_ExternName(blob, length, opts) {
return o;
}
/* 2.4.150 TODO */
/* [MS-XLS] 2.4.150 TODO */
var XLSLblBuiltIn = [
"_xlnm.Consolidate_Area",
"_xlnm.Auto_Open",
@ -662,7 +683,7 @@ function parse_Lbl(blob, length, opts) {
};
}
/* 2.4.106 TODO: verify filename encoding */
/* [MS-XLS] 2.4.106 TODO: verify filename encoding */
function parse_ExternSheet(blob, length, opts) {
if(opts.biff < 8) return parse_BIFF5ExternSheet(blob, length, opts);
var o = [], target = blob.l + length, len = blob.read_shift(opts.biff > 8 ? 4 : 2);
@ -677,7 +698,7 @@ function parse_BIFF5ExternSheet(blob, length, opts) {
return o.charCodeAt(0) == 0x03 ? o.slice(1) : o;
}
/* 2.4.176 TODO: check older biff */
/* [MS-XLS] 2.4.176 TODO: check older biff */
function parse_NameCmt(blob, length, opts) {
if(opts.biff < 8) { blob.l += length; return; }
var cchName = blob.read_shift(2);
@ -687,7 +708,7 @@ function parse_NameCmt(blob, length, opts) {
return [name, comment];
}
/* 2.4.260 */
/* [MS-XLS] 2.4.260 */
function parse_ShrFmla(blob, length, opts) {
var ref = parse_RefU(blob, 6);
blob.l++;
@ -696,7 +717,7 @@ function parse_ShrFmla(blob, length, opts) {
return [parse_SharedParsedFormula(blob, length, opts), cUse, ref];
}
/* 2.4.4 TODO */
/* [MS-XLS] 2.4.4 TODO */
function parse_Array(blob, length, opts) {
var ref = parse_Ref(blob, 6);
/* TODO: fAlwaysCalc */
@ -708,7 +729,7 @@ function parse_Array(blob, length, opts) {
return [ref, parse_ArrayParsedFormula(blob, length, opts, ref)];
}
/* 2.4.173 */
/* [MS-XLS] 2.4.173 */
function parse_MTRSettings(blob) {
var fMTREnabled = blob.read_shift(4) !== 0x00;
var fUserSetThreadCount = blob.read_shift(4) !== 0x00;
@ -716,7 +737,7 @@ function parse_MTRSettings(blob) {
return [fMTREnabled, fUserSetThreadCount, cUserThreadCount];
}
/* 2.5.186 TODO: BIFF5 */
/* [MS-XLS] 2.5.186 TODO: BIFF5 */
function parse_NoteSh(blob, length, opts) {
if(opts.biff < 8) return;
var row = blob.read_shift(2), col = blob.read_shift(2);
@ -726,13 +747,13 @@ function parse_NoteSh(blob, length, opts) {
return [{r:row,c:col}, stAuthor, idObj, flags];
}
/* 2.4.179 */
/* [MS-XLS] 2.4.179 */
function parse_Note(blob, length, opts) {
/* TODO: Support revisions */
return parse_NoteSh(blob, length, opts);
}
/* 2.4.168 */
/* [MS-XLS] 2.4.168 */
function parse_MergeCells(blob, length)/*:Array<Range>*/ {
var merges/*:Array<Range>*/ = [];
var cmcs = blob.read_shift(2);
@ -746,7 +767,7 @@ function write_MergeCells(merges/*:Array<Range>*/) {
return o;
}
/* 2.4.181 TODO: parse all the things! */
/* [MS-XLS] 2.4.181 TODO: parse all the things! */
function parse_Obj(blob, length, opts) {
if(opts && opts.biff < 8) return parse_BIFF5Obj(blob, length, opts);
var cmo = parse_FtCmo(blob, 22); // id, ot, flags
@ -791,7 +812,7 @@ function parse_BIFF5Obj(blob, length, opts) {
return { cmo: [id, ot, grbit], ft:fts };
}
/* 2.4.329 TODO: parse properly */
/* [MS-XLS] 2.4.329 TODO: parse properly */
function parse_TxO(blob, length, opts) {
var s = blob.l;
var texts = "";
@ -820,7 +841,7 @@ try {
}
blob.l = s + length;
/* 2.5.272 TxORuns */
/* [MS-XLS] 2.5.272 TxORuns */
// var rgTxoRuns = [];
// for(var j = 0; j != cbRuns/8-1; ++j) blob.l += 8;
// var cchText2 = blob.read_shift(2);
@ -831,7 +852,7 @@ try {
} catch(e) { blob.l = s + length; return { t: texts }; }
}
/* 2.4.140 */
/* [MS-XLS] 2.4.140 */
function parse_HLink(blob, length) {
var ref = parse_Ref8U(blob, 8);
blob.l += 16; /* CLSID */
@ -849,7 +870,7 @@ function write_HLink(hl) {
}
/* 2.4.141 */
/* [MS-XLS] 2.4.141 */
function parse_HLinkTooltip(blob, length) {
blob.read_shift(2);
var ref = parse_Ref8U(blob, 8);
@ -869,7 +890,7 @@ function write_HLinkTooltip(hl) {
return O;
}
/* 2.4.63 */
/* [MS-XLS] 2.4.63 */
function parse_Country(blob)/*:[string|number, string|number]*/ {
var o = [0,0], d;
d = blob.read_shift(2); o[0] = CountryEnum[d] || d;
@ -883,7 +904,7 @@ function write_Country(o) {
return o;
}
/* 2.4.50 ClrtClient */
/* [MS-XLS] 2.4.50 ClrtClient */
function parse_ClrtClient(blob) {
var ccv = blob.read_shift(2);
var o = [];
@ -891,7 +912,7 @@ function parse_ClrtClient(blob) {
return o;
}
/* 2.4.188 */
/* [MS-XLS] 2.4.188 */
function parse_Palette(blob) {
var ccv = blob.read_shift(2);
var o = [];
@ -899,7 +920,7 @@ function parse_Palette(blob) {
return o;
}
/* 2.4.354 */
/* [MS-XLS] 2.4.354 */
function parse_XFCRC(blob) {
blob.l += 2;
var o = {cxfs:0, crc:0};
@ -908,7 +929,7 @@ function parse_XFCRC(blob) {
return o;
}
/* 2.4.53 TODO: parse flags */
/* [MS-XLS] 2.4.53 TODO: parse flags */
/* [MS-XLSB] 2.4.323 TODO: parse flags */
function parse_ColInfo(blob, length, opts) {
if(!opts.cellStyles) return parsenoop(blob, length);
@ -922,9 +943,10 @@ function parse_ColInfo(blob, length, opts) {
return {s:colFirst, e:colLast, w:coldx, ixfe:ixfe, flags:flags};
}
/* 2.4.257 */
function parse_Setup(blob/*, length*/) {
/* [MS-XLS] 2.4.257 */
function parse_Setup(blob, length) {
var o = {};
if(length < 32) return o;
blob.l += 16;
o.header = parse_Xnum(blob, 8);
o.footer = parse_Xnum(blob, 8);
@ -932,7 +954,7 @@ function parse_Setup(blob/*, length*/) {
return o;
}
/* 2.4.261 */
/* [MS-XLS] 2.4.261 */
function parse_ShtProps(blob, length, opts) {
var def = {area:false};
if(opts.biff != 5) { blob.l += length; return def; }
@ -941,16 +963,16 @@ function parse_ShtProps(blob, length, opts) {
return def;
}
/* 2.4.241 */
/* [MS-XLS] 2.4.241 */
function write_RRTabId(n/*:number*/) {
var out = new_buf(2 * n);
for(var i = 0; i < n; ++i) out.write_shift(2, i+1);
return out;
}
var parse_Blank = parse_XLSCell; /* 2.4.20 Just the cell */
var parse_Scl = parseuint16a; /* 2.4.247 num, den */
var parse_String = parse_XLUnicodeString; /* 2.4.268 */
var parse_Blank = parse_XLSCell; /* [MS-XLS] 2.4.20 Just the cell */
var parse_Scl = parseuint16a; /* [MS-XLS] 2.4.247 num, den */
var parse_String = parse_XLUnicodeString; /* [MS-XLS] 2.4.268 */
/* --- Specific to versions before BIFF8 --- */
function parse_ImData(blob) {

@ -1,4 +1,4 @@
/* [MS-XLSB] 2.4.219 BrtBeginSst */
/* [MS-XLSB] 2.4.221 BrtBeginSst */
function parse_BrtBeginSst(data) {
return [data.read_shift(4), data.read_shift(4)];
}

@ -1,4 +1,4 @@
/* [MS-XLSB] 2.4.651 BrtFmt */
/* [MS-XLSB] 2.4.657 BrtFmt */
function parse_BrtFmt(data, length/*:number*/) {
var numFmtId = data.read_shift(2);
var stFmtCode = parse_XLWideString(data,length-2);
@ -13,7 +13,7 @@ function write_BrtFmt(i/*:number*/, f/*:string*/, o) {
return out;
}
/* [MS-XLSB] 2.4.653 BrtFont TODO */
/* [MS-XLSB] 2.4.659 BrtFont TODO */
function parse_BrtFont(data, length/*:number*/, opts) {
var out = ({}/*:any*/);
@ -80,7 +80,7 @@ function write_BrtFont(font, o) {
return o.length > o.l ? o.slice(0, o.l) : o;
}
/* [MS-XLSB] 2.4.644 BrtFill */
/* [MS-XLSB] 2.4.650 BrtFill */
var XLSBFillPTNames = [
"none",
"solid",
@ -134,7 +134,7 @@ function write_BrtFill(fill, o) {
return o.length > o.l ? o.slice(0, o.l) : o;
}
/* [MS-XLSB] 2.4.816 BrtXF */
/* [MS-XLSB] 2.4.824 BrtXF */
function parse_BrtXF(data, length/*:number*/) {
var tgt = data.l + length;
var ixfeParent = data.read_shift(2);
@ -167,7 +167,7 @@ function write_Blxf(data, o) {
o.write_shift(4, 0); /* color */
return o;
}
/* [MS-XLSB] 2.4.299 BrtBorder TODO */
/* [MS-XLSB] 2.4.302 BrtBorder TODO */
var parse_BrtBorder = parsenoop;
function write_BrtBorder(border, o) {
if(!o) o = new_buf(51);
@ -180,7 +180,7 @@ function write_BrtBorder(border, o) {
return o.length > o.l ? o.slice(0, o.l) : o;
}
/* [MS-XLSB] 2.4.755 BrtStyle TODO */
/* [MS-XLSB] 2.4.763 BrtStyle TODO */
function write_BrtStyle(style, o) {
if(!o) o = new_buf(12+4*10);
o.write_shift(4, style.xfId);
@ -191,7 +191,7 @@ function write_BrtStyle(style, o) {
return o.length > o.l ? o.slice(0, o.l) : o;
}
/* [MS-XLSB] 2.4.269 BrtBeginTableStyles */
/* [MS-XLSB] 2.4.272 BrtBeginTableStyles */
function write_BrtBeginTableStyles(cnt, defTableStyle, defPivotStyle) {
var o = new_buf(4+256*2*4);
o.write_shift(4, cnt);

@ -41,17 +41,17 @@ function parse_XFExtGradient(blob, length) {
return parsenoop(blob, length);
}
/* 2.5.108 */
/* [MS-XLS] 2.5.108 */
function parse_ExtProp(blob/*::, length*/)/*:Array<any>*/ {
var extType = blob.read_shift(2);
var cb = blob.read_shift(2);
var cb = blob.read_shift(2) - 4;
var o = [extType];
switch(extType) {
case 0x04: case 0x05: case 0x07: case 0x08:
case 0x09: case 0x0A: case 0x0B: case 0x0D:
o[1] = parse_FullColorExt(blob, cb); break;
case 0x06: o[1] = parse_XFExtGradient(blob, cb); break;
case 0x0E: case 0x0F: o[1] = blob.read_shift(cb === 5 ? 1 : 2); break;
case 0x0E: case 0x0F: o[1] = blob.read_shift(cb === 1 ? 1 : 2); break;
default: throw new Error("Unrecognized ExtProp type: " + extType + " " + cb);
}
return o;

@ -19,7 +19,7 @@ function write_BrtBeginComment(data, o) {
return o;
}
/* [MS-XLSB] 2.4.324 BrtCommentAuthor */
/* [MS-XLSB] 2.4.327 BrtCommentAuthor */
var parse_BrtCommentAuthor = parse_XLWideString;
function write_BrtCommentAuthor(data) { return write_XLWideString(data.slice(0, 54)); }

@ -1,17 +1,12 @@
/* --- formula references point to MS-XLS --- */
/* Small helpers */
function parseread1(blob) { blob.l+=1; return; }
/* Rgce Helpers */
/* 2.5.51 */
/* [MS-XLS] 2.5.51 */
function parse_ColRelU(blob, length) {
var c = blob.read_shift(length == 1 ? 1 : 2);
return [c & 0x3FFF, (c >> 14) & 1, (c >> 15) & 1];
}
/* [MS-XLS] 2.5.198.105 */
/* [MS-XLSB] 2.5.97.89 */
/* [MS-XLS] 2.5.198.105 ; [MS-XLSB] 2.5.97.89 */
function parse_RgceArea(blob, length, opts) {
var w = 2;
if(opts) {
@ -31,7 +26,7 @@ function parse_RgceArea_BIFF2(blob/*::, length, opts*/) {
return { s:{r:r[0], c:c, cRel:r[1], rRel:r[2]}, e:{r:R[0], c:C, cRel:R[1], rRel:R[2]} };
}
/* 2.5.198.105 TODO */
/* [MS-XLS] 2.5.198.105 ; [MS-XLSB] 2.5.97.90 */
function parse_RgceAreaRel(blob, length/*::, opts*/) {
var r=blob.read_shift(length == 12 ? 4 : 2), R=blob.read_shift(length == 12 ? 4 : 2);
var c=parse_ColRelU(blob, 2);
@ -39,7 +34,7 @@ function parse_RgceAreaRel(blob, length/*::, opts*/) {
return { s:{r:r, c:c[0], cRel:c[1], rRel:c[2]}, e:{r:R, c:C[0], cRel:C[1], rRel:C[2]} };
}
/* 2.5.198.109 */
/* [MS-XLS] 2.5.198.109 ; [MS-XLSB] 2.5.97.91 */
function parse_RgceLoc(blob, length, opts) {
if(opts && opts.biff >= 2 && opts.biff <= 5) return parse_RgceLoc_BIFF2(blob, length, opts);
var r = blob.read_shift(opts && opts.biff == 12 ? 4 : 2);
@ -52,15 +47,14 @@ function parse_RgceLoc_BIFF2(blob/*::, length, opts*/) {
return {r:r[0], c:c, cRel:r[1], rRel:r[2]};
}
/* 2.5.198.107 , 2.5.47 */
/* [MS-XLS] 2.5.198.107, 2.5.47 */
function parse_RgceElfLoc(blob/*::, length, opts*/) {
var r = blob.read_shift(2);
var c = blob.read_shift(2);
return {r:r, c:c & 0xFF, fQuoted:!!(c & 0x4000), cRel:c>>15, rRel:c>>15 };
}
/* [MS-XLS] 2.5.198.111 TODO */
/* [MS-XLSB] 2.5.97.92 TODO */
/* [MS-XLS] 2.5.198.111 ; [MS-XLSB] 2.5.97.92 TODO */
function parse_RgceLocRel(blob, length, opts) {
var biff = opts && opts.biff ? opts.biff : 8;
if(biff >= 2 && biff <= 5) return parse_RgceLocRel_BIFF2(blob, length, opts);
@ -82,17 +76,14 @@ function parse_RgceLocRel_BIFF2(blob/*::, length:number, opts*/) {
return {r:rl,c:c,cRel:cRel,rRel:rRel};
}
/* Ptg Tokens */
/* 2.5.198.27 */
/* [MS-XLS] 2.5.198.27 ; [MS-XLSB] 2.5.97.18 */
function parse_PtgArea(blob, length, opts) {
var type = (blob[blob.l++] & 0x60) >> 5;
var area = parse_RgceArea(blob, opts.biff >= 2 && opts.biff <= 5 ? 6 : 8, opts);
return [type, area];
}
/* [MS-XLS] 2.5.198.28 */
/* [MS-XLSB] 2.5.97.19 */
/* [MS-XLS] 2.5.198.28 ; [MS-XLSB] 2.5.97.19 */
function parse_PtgArea3d(blob, length, opts) {
var type = (blob[blob.l++] & 0x60) >> 5;
var ixti = blob.read_shift(2, 'i');
@ -105,13 +96,13 @@ function parse_PtgArea3d(blob, length, opts) {
return [type, ixti, area];
}
/* 2.5.198.29 */
/* [MS-XLS] 2.5.198.29 ; [MS-XLSB] 2.5.97.20 */
function parse_PtgAreaErr(blob, length, opts) {
var type = (blob[blob.l++] & 0x60) >> 5;
blob.l += opts && opts.biff > 8 ? 12 : 8;
return [type];
}
/* 2.5.198.30 */
/* [MS-XLS] 2.5.198.30 ; [MS-XLSB] 2.5.97.21 */
function parse_PtgAreaErr3d(blob, length, opts) {
var type = (blob[blob.l++] & 0x60) >> 5;
var ixti = blob.read_shift(2);
@ -124,22 +115,21 @@ function parse_PtgAreaErr3d(blob, length, opts) {
return [type, ixti];
}
/* 2.5.198.31 */
/* [MS-XLS] 2.5.198.31 ; [MS-XLSB] 2.5.97.22 */
function parse_PtgAreaN(blob, length, opts) {
var type = (blob[blob.l++] & 0x60) >> 5;
var area = parse_RgceAreaRel(blob, opts && opts.biff > 8 ? 12 : 8, opts);
return [type, area];
}
/* [MS-XLS] 2.5.198.32 */
/* [MS-XLSB] 2.5.97.23 */
/* [MS-XLS] 2.5.198.32 ; [MS-XLSB] 2.5.97.23 */
function parse_PtgArray(blob, length, opts) {
var type = (blob[blob.l++] & 0x60) >> 5;
blob.l += opts.biff == 2 ? 6 : opts.biff == 12 ? 14 : 7;
return [type];
}
/* 2.5.198.33 */
/* [MS-XLS] 2.5.198.33 ; [MS-XLSB] 2.5.97.24 */
function parse_PtgAttrBaxcel(blob) {
var bitSemi = blob[blob.l+1] & 0x01; /* 1 = volatile */
var bitBaxcel = 1;
@ -147,7 +137,7 @@ function parse_PtgAttrBaxcel(blob) {
return [bitSemi, bitBaxcel];
}
/* 2.5.198.34 */
/* [MS-XLS] 2.5.198.34 ; [MS-XLSB] 2.5.97.25 */
function parse_PtgAttrChoose(blob, length, opts)/*:Array<number>*/ {
blob.l +=2;
var offset = blob.read_shift(opts && opts.biff == 2 ? 1 : 2);
@ -157,14 +147,14 @@ function parse_PtgAttrChoose(blob, length, opts)/*:Array<number>*/ {
return o;
}
/* 2.5.198.35 */
/* [MS-XLS] 2.5.198.35 ; [MS-XLSB] 2.5.97.26 */
function parse_PtgAttrGoto(blob, length, opts) {
var bitGoto = (blob[blob.l+1] & 0xFF) ? 1 : 0;
blob.l += 2;
return [bitGoto, blob.read_shift(opts && opts.biff == 2 ? 1 : 2)];
}
/* 2.5.198.36 */
/* [MS-XLS] 2.5.198.36 ; [MS-XLSB] 2.5.97.27 */
function parse_PtgAttrIf(blob, length, opts) {
var bitIf = (blob[blob.l+1] & 0xFF) ? 1 : 0;
blob.l += 2;
@ -178,32 +168,32 @@ function parse_PtgAttrIfError(blob) {
return [bitIf, blob.read_shift(2)];
}
/* 2.5.198.37 */
/* [MS-XLS] 2.5.198.37 ; [MS-XLSB] 2.5.97.29 */
function parse_PtgAttrSemi(blob, length, opts) {
var bitSemi = (blob[blob.l+1] & 0xFF) ? 1 : 0;
blob.l += opts && opts.biff == 2 ? 3 : 4;
return [bitSemi];
}
/* 2.5.198.40 (used by PtgAttrSpace and PtgAttrSpaceSemi) */
/* [MS-XLS] 2.5.198.40 ; [MS-XLSB] 2.5.97.32 */
function parse_PtgAttrSpaceType(blob/*::, length*/) {