2015-04-02 20:32:22 +00:00
var attregexg = /([\w:]+)=((?:")([^"]*)(?:")|(?:')([^']*)(?:'))/g ;
2014-06-29 18:29:45 +00:00
var tagregex = /<[^>]*>/g ;
var nsregex = /<\w*:/ , nsregex2 = /<(\/?)\w+:/ ;
2017-02-10 19:23:01 +00:00
function parsexmltag ( tag /*:string*/ , skip _root /*:?boolean*/ ) /*:any*/ {
var z = ( [ ] /*:any*/ ) ;
2014-06-29 18:29:45 +00:00
var eq = 0 , c = 0 ;
for ( ; eq !== tag . length ; ++ eq ) if ( ( c = tag . charCodeAt ( eq ) ) === 32 || c === 10 || c === 13 ) break ;
if ( ! skip _root ) z [ 0 ] = tag . substr ( 0 , eq ) ;
if ( eq === tag . length ) return z ;
var m = tag . match ( attregexg ) , j = 0 , w = "" , v = "" , i = 0 , q = "" , cc = "" ;
2014-06-02 05:19:07 +00:00
if ( m ) for ( i = 0 ; i != m . length ; ++ i ) {
2014-06-29 18:29:45 +00:00
cc = m [ i ] ;
for ( c = 0 ; c != cc . length ; ++ c ) if ( cc . charCodeAt ( c ) === 61 ) break ;
q = cc . substr ( 0 , c ) ; v = cc . substring ( c + 2 , cc . length - 1 ) ;
for ( j = 0 ; j != q . length ; ++ j ) if ( q . charCodeAt ( j ) === 58 ) break ;
if ( j === q . length ) z [ q ] = v ;
else z [ ( j === 5 && q . substr ( 0 , 5 ) === "xmlns" ? "xmlns" : "" ) + q . substr ( j + 1 ) ] = v ;
2014-06-02 05:19:07 +00:00
}
2013-05-02 16:59:27 +00:00
return z ;
}
2017-02-10 19:23:01 +00:00
function strip _ns ( x /*:string*/ ) /*:string*/ { return x . replace ( nsregex2 , "<$1" ) ; }
2013-05-02 16:59:27 +00:00
var encodings = {
'"' : '"' ,
''' : "'" ,
'>' : '>' ,
'<' : '<' ,
'&' : '&'
} ;
2014-01-29 06:00:09 +00:00
var rencoding = evert ( encodings ) ;
2014-01-28 16:38:02 +00:00
var rencstr = "&<>'\"" . split ( "" ) ;
2014-01-29 06:00:09 +00:00
2013-05-02 16:59:27 +00:00
// TODO: CP remap (need to read file version to determine OS)
2017-02-10 19:23:01 +00:00
var unescapexml /*:StringConv*/ = ( function ( ) {
2015-04-02 20:32:22 +00:00
var encregex = /&[a-z]*;/g , coderegex = /_x([\da-fA-F]+)_/g ;
2017-02-10 19:23:01 +00:00
return function unescapexml ( text /*:string*/ ) /*:string*/ {
2015-04-02 20:32:22 +00:00
var s = text + '' ;
return s . replace ( encregex , function ( $$ ) { return encodings [ $$ ] ; } ) . replace ( coderegex , function ( m , c ) { return String . fromCharCode ( parseInt ( c , 16 ) ) ; } ) ;
} ;
} ) ( ) ;
2014-06-29 18:29:45 +00:00
var decregex = /[&<>'"]/g , charegex = /[\u0000-\u0008\u000b-\u001f]/g ;
2017-02-10 19:23:01 +00:00
function escapexml ( text /*:string*/ ) /*:string*/ {
2014-01-28 16:38:02 +00:00
var s = text + '' ;
2017-02-22 06:57:59 +00:00
return s . replace ( decregex , function ( y ) { return rencoding [ y ] ; } ) . replace ( charegex , function ( s ) { return "_x" + ( "000" + s . charCodeAt ( 0 ) . toString ( 16 ) ) . slice ( - 4 ) + "_" ; } ) ;
2014-01-28 16:38:02 +00:00
}
2015-04-02 20:32:22 +00:00
/* TODO: handle codepages */
2017-02-10 19:23:01 +00:00
var xlml _fixstr /*:StringConv*/ = ( function ( ) {
2015-04-02 20:32:22 +00:00
var entregex = /&#(\d+);/g ;
2017-02-10 19:23:01 +00:00
function entrepl ( $$ /*:string*/ , $1 /*:string*/ ) /*:string*/ { return String . fromCharCode ( parseInt ( $1 , 10 ) ) ; }
return function xlml _fixstr ( str /*:string*/ ) /*:string*/ { return str . replace ( entregex , entrepl ) ; } ;
2015-04-02 20:32:22 +00:00
} ) ( ) ;
2017-02-10 19:23:01 +00:00
function parsexmlbool ( value /*:any*/ , tag /*:?string*/ ) /*:boolean*/ {
2013-05-02 16:59:27 +00:00
switch ( value ) {
2014-06-29 18:29:45 +00:00
case '1' : case 'true' : case 'TRUE' : return true ;
/* case '0': case 'false': case 'FALSE':*/
default : return false ;
2013-05-02 16:59:27 +00:00
}
}
2017-02-10 19:23:01 +00:00
var utf8read /*:StringConv*/ = function utf8reada ( orig ) {
2014-06-29 18:29:45 +00:00
var out = "" , i = 0 , c = 0 , d = 0 , e = 0 , f = 0 , w = 0 ;
2013-05-02 16:59:27 +00:00
while ( i < orig . length ) {
c = orig . charCodeAt ( i ++ ) ;
2014-06-29 18:29:45 +00:00
if ( c < 128 ) { out += String . fromCharCode ( c ) ; continue ; }
d = orig . charCodeAt ( i ++ ) ;
if ( c > 191 && c < 224 ) { out += String . fromCharCode ( ( ( c & 31 ) << 6 ) | ( d & 63 ) ) ; continue ; }
e = orig . charCodeAt ( i ++ ) ;
if ( c < 240 ) { out += String . fromCharCode ( ( ( c & 15 ) << 12 ) | ( ( d & 63 ) << 6 ) | ( e & 63 ) ) ; continue ; }
f = orig . charCodeAt ( i ++ ) ;
w = ( ( ( c & 7 ) << 18 ) | ( ( d & 63 ) << 12 ) | ( ( e & 63 ) << 6 ) | ( f & 63 ) ) - 65536 ;
out += String . fromCharCode ( 0xD800 + ( ( w >>> 10 ) & 1023 ) ) ;
out += String . fromCharCode ( 0xDC00 + ( w & 1023 ) ) ;
2013-05-02 16:59:27 +00:00
}
2014-06-29 18:29:45 +00:00
return out ;
2013-05-02 16:59:27 +00:00
} ;
2014-06-29 18:29:45 +00:00
2014-07-28 13:22:32 +00:00
if ( has _buf ) {
2014-06-29 18:29:45 +00:00
var utf8readb = function utf8readb ( data ) {
var out = new Buffer ( 2 * data . length ) , w , i , j = 1 , k = 0 , ww = 0 , c ;
for ( i = 0 ; i < data . length ; i += j ) {
j = 1 ;
if ( ( c = data . charCodeAt ( i ) ) < 128 ) w = c ;
else if ( c < 224 ) { w = ( c & 31 ) * 64 + ( data . charCodeAt ( i + 1 ) & 63 ) ; j = 2 ; }
else if ( c < 240 ) { w = ( c & 15 ) * 4096 + ( data . charCodeAt ( i + 1 ) & 63 ) * 64 + ( data . charCodeAt ( i + 2 ) & 63 ) ; j = 3 ; }
else { j = 4 ;
w = ( c & 7 ) * 262144 + ( data . charCodeAt ( i + 1 ) & 63 ) * 4096 + ( data . charCodeAt ( i + 2 ) & 63 ) * 64 + ( data . charCodeAt ( i + 3 ) & 63 ) ;
w -= 65536 ; ww = 0xD800 + ( ( w >>> 10 ) & 1023 ) ; w = 0xDC00 + ( w & 1023 ) ;
}
if ( ww !== 0 ) { out [ k ++ ] = ww & 255 ; out [ k ++ ] = ww >>> 8 ; ww = 0 ; }
out [ k ++ ] = w % 256 ; out [ k ++ ] = w >>> 8 ;
}
out . length = k ;
return out . toString ( 'ucs2' ) ;
} ;
var corpus = "foo bar baz\u00e2\u0098\u0083\u00f0\u009f\u008d\u00a3" ;
if ( utf8read ( corpus ) == utf8readb ( corpus ) ) utf8read = utf8readb ;
var utf8readc = function utf8readc ( data ) { return Buffer ( data , 'binary' ) . toString ( 'utf8' ) ; } ;
if ( utf8read ( corpus ) == utf8readc ( corpus ) ) utf8read = utf8readc ;
}
2013-05-02 16:59:27 +00:00
// matches <foo>...</foo> extracts content
2014-06-29 18:29:45 +00:00
var matchtag = ( function ( ) {
var mtcache = { } ;
return function matchtag ( f , g ) {
2017-02-10 19:23:01 +00:00
var t = f + "|" + ( g || "" ) ;
2014-06-29 18:29:45 +00:00
if ( mtcache [ t ] !== undefined ) return mtcache [ t ] ;
return ( mtcache [ t ] = new RegExp ( '<(?:\\w+:)?' + f + '(?: xml:space="preserve")?(?:[^>]*)>([^\u2603]*)</(?:\\w+:)?' + f + '>' , ( g || "" ) ) ) ;
} ;
} ) ( ) ;
2013-05-02 16:59:27 +00:00
2014-06-29 18:29:45 +00:00
var vtregex = ( function ( ) { var vt _cache = { } ;
return function vt _regex ( bt ) {
if ( vt _cache [ bt ] !== undefined ) return vt _cache [ bt ] ;
2017-02-19 20:36:32 +00:00
return ( vt _cache [ bt ] = new RegExp ( "<(?:vt:)?" + bt + ">(.*?)</(?:vt:)?" + bt + ">" , 'g' ) ) ;
2014-06-29 18:29:45 +00:00
} ; } ) ( ) ;
2017-02-19 20:36:32 +00:00
var vtvregex = /<\/?(:?vt:)?variant>/g , vtmregex = /<(:?vt:)?([^>]*)>(.*)</ ;
2013-05-02 16:59:27 +00:00
function parseVector ( data ) {
var h = parsexmltag ( data ) ;
2014-06-29 18:29:45 +00:00
var matches = data . match ( vtregex ( h . baseType ) ) || [ ] ;
2017-02-10 19:23:01 +00:00
if ( matches . length != h . size ) throw new Error ( "unexpected vector length " + matches . length + " != " + h . size ) ;
2013-05-02 16:59:27 +00:00
var res = [ ] ;
matches . forEach ( function ( x ) {
2014-06-29 18:29:45 +00:00
var v = x . replace ( vtvregex , "" ) . match ( vtmregex ) ;
2013-05-02 16:59:27 +00:00
res . push ( { v : v [ 2 ] , t : v [ 1 ] } ) ;
} ) ;
return res ;
}
2014-06-29 18:29:45 +00:00
var wtregex = /(^\s|\s$|\n)/ ;
function writetag ( f , g ) { return '<' + f + ( g . match ( wtregex ) ? ' xml:space="preserve"' : "" ) + '>' + g + '</' + f + '>' ; }
2014-05-16 00:33:34 +00:00
2017-02-10 19:23:01 +00:00
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 : "/" ) + '>' ; }
2014-05-16 00:33:34 +00:00
2017-02-10 19:23:01 +00:00
function write _w3cdtf ( d /*:Date*/ , t /*:?boolean*/ ) /*:string*/ { try { return d . toISOString ( ) . replace ( /\.\d*/ , "" ) ; } catch ( e ) { if ( t ) throw e ; } return "" ; }
2014-05-16 00:33:34 +00:00
function write _vt ( s ) {
2014-06-29 18:29:45 +00:00
switch ( typeof s ) {
case 'string' : return writextag ( 'vt:lpwstr' , s ) ;
case 'number' : return writextag ( ( s | 0 ) == s ? 'vt:i4' : 'vt:r8' , String ( s ) ) ;
case 'boolean' : return writextag ( 'vt:bool' , s ? 'true' : 'false' ) ;
}
2014-05-16 00:33:34 +00:00
if ( s instanceof Date ) return writextag ( 'vt:filetime' , write _w3cdtf ( s ) ) ;
throw new Error ( "Unable to serialize " + s ) ;
}
var XML _HEADER = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n' ;
2017-02-10 19:23:01 +00:00
var XMLNS = ( {
2014-05-16 00:33:34 +00:00
'dc' : 'http://purl.org/dc/elements/1.1/' ,
'dcterms' : 'http://purl.org/dc/terms/' ,
'dcmitype' : 'http://purl.org/dc/dcmitype/' ,
'mx' : 'http://schemas.microsoft.com/office/mac/excel/2008/main' ,
'r' : 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' ,
'sjs' : 'http://schemas.openxmlformats.org/package/2006/sheetjs/core-properties' ,
'vt' : 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes' ,
'xsi' : 'http://www.w3.org/2001/XMLSchema-instance' ,
'xsd' : 'http://www.w3.org/2001/XMLSchema'
2017-02-10 19:23:01 +00:00
} /*:any*/ ) ;
2014-05-16 00:33:34 +00:00
XMLNS . main = [
'http://schemas.openxmlformats.org/spreadsheetml/2006/main' ,
'http://purl.oclc.org/ooxml/spreadsheetml/main' ,
'http://schemas.microsoft.com/office/excel/2006/main' ,
'http://schemas.microsoft.com/office/excel/2006/2'
] ;
2015-04-02 20:32:22 +00:00