forked from sheetjs/sheetjs
		
	
		
			
	
	
		
			140 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			140 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | /* 18.4 Shared String Table */ | ||
|  | var parse_sst = (function(){ | ||
|  | 	var tregex = matchtag("t"), rpregex = matchtag("rPr"); | ||
|  | 	/* Parse a list of <r> tags */ | ||
|  | 	var parse_rs = (function() { | ||
|  | 		/* 18.4.7 rPr CT_RPrElt */ | ||
|  | 		var parse_rpr = function(rpr, intro, outro) { | ||
|  | 			var font = {}; | ||
|  | 			rpr.match(/<[^>]*>/g).forEach(function(x) { | ||
|  | 				var y = parsexmltag(x); | ||
|  | 				switch(y[0]) { | ||
|  | 					/* 18.8.12 condense CT_BooleanProperty */ | ||
|  | 					/* ** not required . */ | ||
|  | 					case '<condense': break; | ||
|  | 					/* 18.8.17 extend CT_BooleanProperty */ | ||
|  | 					/* ** not required . */ | ||
|  | 					case '<extend': break; | ||
|  | 					/* 18.8.36 shadow CT_BooleanProperty */ | ||
|  | 					/* ** not required . */ | ||
|  | 					case '<shadow': break; | ||
|  | 
 | ||
|  | 					/* 18.4.1 charset CT_IntProperty TODO */ | ||
|  | 					case '<charset': break; | ||
|  | 
 | ||
|  | 					/* 18.4.2 outline CT_BooleanProperty TODO */ | ||
|  | 					case '<outline': break; | ||
|  | 
 | ||
|  | 					/* 18.4.5 rFont CT_FontName */ | ||
|  | 					case '<rFont': font.name = y.val; break; | ||
|  | 
 | ||
|  | 					/* 18.4.11 sz CT_FontSize */ | ||
|  | 					case '<sz': font.sz = y.val; break; | ||
|  | 
 | ||
|  | 					/* 18.4.10 strike CT_BooleanProperty */ | ||
|  | 					case '<strike': | ||
|  | 						if(!y.val) break; | ||
|  | 						/* falls through */ | ||
|  | 					case '<strike/>': font.strike = 1; break; | ||
|  | 					case '</strike>': break; | ||
|  | 
 | ||
|  | 					/* 18.4.13 u CT_UnderlineProperty */ | ||
|  | 					case '<u': | ||
|  | 						if(!y.val) break; | ||
|  | 						/* falls through */ | ||
|  | 					case '<u/>': font.u = 1; break; | ||
|  | 					case '</u>': break; | ||
|  | 
 | ||
|  | 					/* 18.8.2 b */ | ||
|  | 					case '<b': | ||
|  | 						if(!y.val) break; | ||
|  | 						/* falls through */ | ||
|  | 					case '<b/>': font.b = 1; break; | ||
|  | 					case '</b>': break; | ||
|  | 
 | ||
|  | 					/* 18.8.26 i */ | ||
|  | 					case '<i': | ||
|  | 						if(!y.val) break; | ||
|  | 						/* falls through */ | ||
|  | 					case '<i/>': font.i = 1; break; | ||
|  | 					case '</i>': break; | ||
|  | 
 | ||
|  | 					/* 18.3.1.15 color CT_Color TODO: tint, theme, auto, indexed */ | ||
|  | 					case '<color': | ||
|  | 						if(y.rgb) font.color = y.rgb.substr(2,6); | ||
|  | 						break; | ||
|  | 
 | ||
|  | 					/* 18.8.18 family ST_FontFamily */ | ||
|  | 					case '<family': font.family = y.val; break; | ||
|  | 
 | ||
|  | 					/* 18.4.14 vertAlign CT_VerticalAlignFontProperty TODO */ | ||
|  | 					case '<vertAlign': break; | ||
|  | 
 | ||
|  | 					/* 18.8.35 scheme CT_FontScheme TODO */ | ||
|  | 					case '<scheme': break; | ||
|  | 
 | ||
|  | 					default: | ||
|  | 						if(y[0][2] !== '/') throw 'Unrecognized rich format ' + y[0]; | ||
|  | 				} | ||
|  | 			}); | ||
|  | 			/* TODO: These should be generated styles, not inline */ | ||
|  | 			var style = []; | ||
|  | 			if(font.b) style.push("font-weight: bold;"); | ||
|  | 			if(font.i) style.push("font-style: italic;"); | ||
|  | 			intro.push('<span style="' + style.join("") + '">'); | ||
|  | 			outro.push("</span>"); | ||
|  | 		}; | ||
|  | 
 | ||
|  | 		/* 18.4.4 r CT_RElt */ | ||
|  | 		function parse_r(r) { | ||
|  | 			var terms = [[],"",[]]; | ||
|  | 			/* 18.4.12 t ST_Xstring */ | ||
|  | 			var t = r.match(tregex); | ||
|  | 			if(!isval(t)) return ""; | ||
|  | 			terms[1] = t[1]; | ||
|  | 
 | ||
|  | 			var rpr = r.match(rpregex); | ||
|  | 			if(isval(rpr)) parse_rpr(rpr[1], terms[0], terms[2]); | ||
|  | 			return terms[0].join("") + terms[1].replace(/\r\n/g,'<br/>') + terms[2].join(""); | ||
|  | 		} | ||
|  | 		return function(rs) { | ||
|  | 			return rs.replace(/<r>/g,"").split(/<\/r>/).map(parse_r).join(""); | ||
|  | 		}; | ||
|  | 	})(); | ||
|  | 
 | ||
|  | 	/* 18.4.8 si CT_Rst */ | ||
|  | 	var parse_si = function(x) { | ||
|  | 		var z = {}; | ||
|  | 		if(!x) return z; | ||
|  | 		var y; | ||
|  | 		/* 18.4.12 t ST_Xstring (Plaintext String) */ | ||
|  | 		if(x[1] === 't') { | ||
|  | 			z.t = utf8read(unescapexml(x.replace(/<[^>]*>/g,""))); | ||
|  | 			z.raw = x; | ||
|  | 			z.r = z.t; | ||
|  | 		} | ||
|  | 		/* 18.4.4 r CT_RElt (Rich Text Run) */ | ||
|  | 		else if((y = x.match(/<r>/))) { | ||
|  | 			z.raw = x; | ||
|  | 			/* TODO: properly parse (note: no other valid child can have body text) */ | ||
|  | 			z.t = utf8read(unescapexml(x.replace(/<[^>]*>/gm,""))); | ||
|  | 			z.r = parse_rs(x); | ||
|  | 		} | ||
|  | 		/* 18.4.3 phoneticPr CT_PhoneticPr (TODO: needed for Asian support) */ | ||
|  | 		/* 18.4.6 rPh CT_PhoneticRun (TODO: needed for Asian support) */ | ||
|  | 		return z; | ||
|  | 	}; | ||
|  | 
 | ||
|  | 
 | ||
|  | 	return function(data) { | ||
|  | 		var s = []; | ||
|  | 		/* 18.4.9 sst CT_Sst */ | ||
|  | 		var sst = data.match(new RegExp("<sst([^>]*)>([\\s\\S]*)<\/sst>","m")); | ||
|  | 		if(sst) { | ||
|  | 			s = sst[2].replace(/<si>/g,"").split(/<\/si>/).map(parse_si); | ||
|  | 			sst = parsexmltag(sst[1]); s.Count = sst.count; s.Unique = sst.uniqueCount; | ||
|  | 		} | ||
|  | 		return s; | ||
|  | 	}; | ||
|  | })(); |