1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2025-08-08 06:43:49 +00:00

Update HTML deserializer to cope with TiddlyWiki classic and TW5 files

This commit is contained in:
Jeremy Ruston 2013-04-03 12:57:17 +01:00
parent c182533efc
commit 6c210df0bd
3 changed files with 66 additions and 49 deletions

View File

@ -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] + "\"");

View File

@ -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;
}
})(); })();

View File

@ -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;