mirror of
				https://github.com/Jermolene/TiddlyWiki5
				synced 2025-10-31 15:42:59 +00:00 
			
		
		
		
	Update HTML deserializer to cope with TiddlyWiki classic and TW5 files
This commit is contained in:
		| @@ -35,8 +35,7 @@ Command.prototype.execute = function() { | |||||||
| 			self.callback(err); | 			self.callback(err); | ||||||
| 		} else { | 		} else { | ||||||
| 			var fields = {title: self.params[0]}, | 			var fields = {title: self.params[0]}, | ||||||
| 				extname = path.extname(self.params[0]), | 				type = path.extname(self.params[0]); | ||||||
| 				type = extname === ".html" ? "application/vnd.tiddlywiki2" : extname; |  | ||||||
| 			var tiddlers = self.commander.wiki.deserializeTiddlers(type,data,fields); | 			var tiddlers = self.commander.wiki.deserializeTiddlers(type,data,fields); | ||||||
| 			if(!tiddlers) { | 			if(!tiddlers) { | ||||||
| 				self.callback("No tiddlers found in file \"" + self.params[0] + "\""); | 				self.callback("No tiddlers found in file \"" + self.params[0] + "\""); | ||||||
|   | |||||||
| @@ -13,22 +13,29 @@ Functions to deserialise tiddlers from a block of text | |||||||
| "use strict"; | "use strict"; | ||||||
|  |  | ||||||
| /* | /* | ||||||
| Utility function to parse an old-style tiddler DIV. It looks like this: | Utility function to parse an old-style tiddler DIV in a *.tid file. It looks like this: | ||||||
|  |  | ||||||
| <div title="Title" creator="JoeBloggs" modifier="JoeBloggs" created="201102111106" modified="201102111310" tags="myTag [[my long tag]]"> | <div title="Title" creator="JoeBloggs" modifier="JoeBloggs" created="201102111106" modified="201102111310" tags="myTag [[my long tag]]"> | ||||||
| <pre>The text of the tiddler (without the expected HTML encoding). | <pre>The text of the tiddler (without the expected HTML encoding). | ||||||
| </pre> | </pre> | ||||||
| </div> | </div> | ||||||
|  |  | ||||||
| Note that the field attributes are HTML encoded, but that the body of the <PRE> tag is not. | Note that the field attributes are HTML encoded, but that the body of the <PRE> tag is not encoded. | ||||||
|  |  | ||||||
|  | When these tiddler DIVs are encountered within a TiddlyWiki HTML file then the body is encoded in the usual way. | ||||||
| */ | */ | ||||||
| var parseTiddlerDiv = function(text,fields) { | var parseTiddlerDiv = function(text /* [,fields] */) { | ||||||
|  | 	// Slot together the default results | ||||||
| 	var result = {}; | 	var result = {}; | ||||||
| 	if(fields) { | 	if(arguments.length > 1) { | ||||||
| 		for(var t in fields) { | 		for(var f=1; f<arguments.length; f++) { | ||||||
| 			result[t] = fields[t];		 | 			var fields = arguments[f]; | ||||||
|  | 			for(var t in fields) { | ||||||
|  | 				result[t] = fields[t];		 | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | 	// Parse the DIV body | ||||||
| 	var divRegExp = /^\s*<div\s+([^>]*)>((?:.|\n)*)<\/div>\s*$/gi, | 	var divRegExp = /^\s*<div\s+([^>]*)>((?:.|\n)*)<\/div>\s*$/gi, | ||||||
| 		subDivRegExp = /^\s*<pre>((?:.|\n)*)<\/pre>\s*$/gi, | 		subDivRegExp = /^\s*<pre>((?:.|\n)*)<\/pre>\s*$/gi, | ||||||
| 		attrRegExp = /\s*([^=\s]+)\s*=\s*"([^"]*)"/gi, | 		attrRegExp = /\s*([^=\s]+)\s*=\s*"([^"]*)"/gi, | ||||||
| @@ -49,8 +56,10 @@ var parseTiddlerDiv = function(text,fields) { | |||||||
| 				result[name] = value; | 				result[name] = value; | ||||||
| 			} | 			} | ||||||
| 		} while(attrMatch); | 		} while(attrMatch); | ||||||
|  | 		return result; | ||||||
|  | 	} else { | ||||||
|  | 		return undefined; | ||||||
| 	} | 	} | ||||||
| 	return result;	 |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| exports["application/x-tiddler-html-div"] = function(text,fields) { | exports["application/x-tiddler-html-div"] = function(text,fields) { | ||||||
| @@ -75,43 +84,56 @@ exports["application/json"] = function(text,fields) { | |||||||
| 	return result; | 	return result; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| exports["application/vnd.tiddlywiki2"] = function(text,fields) { | /* | ||||||
| 	var locateStoreArea = function(tiddlywikidoc) { | Parse an HTML file into tiddlers. There are three possibilities: | ||||||
| 			var startSaveArea = '<div id="' + 'storeArea">', | # A TiddlyWiki classic HTML file containing `application/vnd.tiddlywiki2` tiddlers | ||||||
| 				startSaveAreaRegExp = /<div id=["']?storeArea['"]?>/gi, | # A TiddlyWiki5 HTML file containing `application/vnd.tiddlywiki` tiddlers | ||||||
| 				endSaveArea = '</d' + 'iv>', | # An ordinary HTML file | ||||||
| 				endSaveAreaCaps = '</D' + 'IV>', | */ | ||||||
| 				posOpeningDiv = tiddlywikidoc.search(startSaveAreaRegExp), | exports["text/html"] = function(text,fields) { | ||||||
| 				limitClosingDiv = tiddlywikidoc.indexOf("<"+"!--POST-STOREAREA--"+">"); | 	// Check if we've got a store area | ||||||
| 			if(limitClosingDiv == -1) { | 	var storeAreaMarkerRegExp = /<div id=["']?storeArea['"]?( style=["']?display:none;["']?)?>/gi, | ||||||
| 				limitClosingDiv = tiddlywikidoc.indexOf("<"+"!--POST-BODY-START--"+">"); | 		match = storeAreaMarkerRegExp.exec(text); | ||||||
| 			} | 	if(match) { | ||||||
| 			var start = limitClosingDiv == -1 ? tiddlywikidoc.length : limitClosingDiv, | 		// If so, it's either a classic TiddlyWiki file or a TW5 file | ||||||
| 				posClosingDiv = tiddlywikidoc.lastIndexOf(endSaveArea,start); | 		return deserializeTiddlyWikiFile(text,storeAreaMarkerRegExp.lastIndex,!!match[1],fields); | ||||||
| 			if(posClosingDiv == -1) { | 	} else { | ||||||
| 				posClosingDiv = tiddlywikidoc.lastIndexOf(endSaveAreaCaps,start); | 		// It's not a TiddlyWiki so we'll return the entire HTML file as a tiddler | ||||||
| 			} | 		return deserializeHtmlFile(text,fields); | ||||||
| 			return (posOpeningDiv != -1 && posClosingDiv != -1) ? [posOpeningDiv + startSaveArea.length,posClosingDiv] : null; |  | ||||||
| 		}, |  | ||||||
| 		results = [], |  | ||||||
| 		storeAreaPos = locateStoreArea(text); |  | ||||||
| 	if(storeAreaPos) { |  | ||||||
| 		var endOfDivRegExp = /(<\/div>\s*)/gi, |  | ||||||
| 			startPos = storeAreaPos[0]; |  | ||||||
| 		endOfDivRegExp.lastIndex = startPos; |  | ||||||
| 		var match = endOfDivRegExp.exec(text); |  | ||||||
| 		while(match && startPos < storeAreaPos[1]) { |  | ||||||
| 			var endPos = endOfDivRegExp.lastIndex, |  | ||||||
| 				tiddlerFields = parseTiddlerDiv(text.substring(startPos,endPos),fields); |  | ||||||
| 			if(tiddlerFields.text !== null) { |  | ||||||
| 				tiddlerFields.text = $tw.utils.htmlDecode(tiddlerFields.text); |  | ||||||
| 				results.push(tiddlerFields); |  | ||||||
| 			} |  | ||||||
| 			startPos = endPos; |  | ||||||
| 			match = endOfDivRegExp.exec(text); |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 	return results; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | function deserializeHtmlFile(text,fields) { | ||||||
|  | 	var result = {}; | ||||||
|  | 	$tw.utils.each(fields,function(value,name) { | ||||||
|  | 		result[name] = value; | ||||||
|  | 	}); | ||||||
|  | 	result.text = text; | ||||||
|  | 	result.type = "text/html"; | ||||||
|  | 	return [result]; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function deserializeTiddlyWikiFile(text,storeAreaEnd,isTiddlyWiki5,fields) { | ||||||
|  | 	var results = [], | ||||||
|  | 		endOfDivRegExp = /(<\/div>\s*)/gi, | ||||||
|  | 		startPos = storeAreaEnd, | ||||||
|  | 		defaultType = isTiddlyWiki5 ? "application/vnd.tiddlywiki": "application/vnd.tiddlywiki2"; | ||||||
|  | 	endOfDivRegExp.lastIndex = startPos; | ||||||
|  | 	var match = endOfDivRegExp.exec(text); | ||||||
|  | 	while(match) { | ||||||
|  | 		var endPos = endOfDivRegExp.lastIndex, | ||||||
|  | 			tiddlerFields = parseTiddlerDiv(text.substring(startPos,endPos),fields,{type: defaultType}); | ||||||
|  | 		if(!tiddlerFields) { | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		if(tiddlerFields.text !== null) { | ||||||
|  | 			tiddlerFields.text = $tw.utils.htmlDecode(tiddlerFields.text); | ||||||
|  | 			results.push(tiddlerFields); | ||||||
|  | 		} | ||||||
|  | 		startPos = endPos; | ||||||
|  | 		match = endOfDivRegExp.exec(text); | ||||||
|  | 	} | ||||||
|  | 	return results; | ||||||
|  | } | ||||||
|  |  | ||||||
| })(); | })(); | ||||||
|   | |||||||
| @@ -136,10 +136,6 @@ ImportWidget.prototype.importFiles = function(files) { | |||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		// Override HTML files so that they're recognised as TiddlyWiki files |  | ||||||
| 		if(type === "text/html") { |  | ||||||
| 			type = "application/vnd.tiddlywiki2"; |  | ||||||
| 		} |  | ||||||
| 		// Figure out if we're reading a binary file | 		// Figure out if we're reading a binary file | ||||||
| 		var contentTypeInfo = $tw.config.contentTypeInfo[type], | 		var contentTypeInfo = $tw.config.contentTypeInfo[type], | ||||||
| 			isBinary = contentTypeInfo ? contentTypeInfo.encoding === "base64" : false; | 			isBinary = contentTypeInfo ? contentTypeInfo.encoding === "base64" : false; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Jeremy Ruston
					Jeremy Ruston