mirror of
https://github.com/TiddlyWiki/TiddlyWiki5.git
synced 2026-05-04 11:27:39 +00:00
First step of turning the rabbit hole inside out
This commit is contained in:
242
archive/js/TiddlerInput.js
Executable file
242
archive/js/TiddlerInput.js
Executable file
@@ -0,0 +1,242 @@
|
||||
/*\
|
||||
title: js/TiddlerInput.js
|
||||
|
||||
Functions concerned with parsing representations of tiddlers
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true */
|
||||
"use strict";
|
||||
|
||||
var utils = require("./Utils.js"),
|
||||
Tiddler = require("./Tiddler.js").Tiddler,
|
||||
util = require("util");
|
||||
|
||||
var tiddlerInput = exports;
|
||||
|
||||
/*
|
||||
Utility function to parse a block of metadata and merge the results into a hashmap of tiddler fields.
|
||||
|
||||
The block consists of newline delimited lines consisting of the field name, a colon, and then the value. For example:
|
||||
|
||||
title: Safari
|
||||
modifier: blaine
|
||||
created: 20110211110700
|
||||
modified: 20110211131020
|
||||
tags: browsers issues
|
||||
creator: psd
|
||||
*/
|
||||
var parseMetaDataBlock = function(metaData,fields) {
|
||||
var result = {};
|
||||
if(fields) {
|
||||
for(var t in fields) {
|
||||
result[t] = fields[t];
|
||||
}
|
||||
}
|
||||
metaData.split("\n").forEach(function(line) {
|
||||
var p = line.indexOf(":");
|
||||
if(p !== -1) {
|
||||
var field = line.substr(0, p).trim();
|
||||
var value = line.substr(p+1).trim();
|
||||
result[field] = value;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
/*
|
||||
Utility function to parse an old-style tiddler DIV. It looks like this:
|
||||
|
||||
<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>
|
||||
</div>
|
||||
|
||||
Note that the field attributes are HTML encoded, but that the body of the <PRE> tag is not.
|
||||
*/
|
||||
var parseTiddlerDiv = function(text,fields) {
|
||||
var result = {};
|
||||
if(fields) {
|
||||
for(var t in fields) {
|
||||
result[t] = fields[t];
|
||||
}
|
||||
}
|
||||
var divRegExp = /^\s*<div\s+([^>]*)>((?:.|\n)*)<\/div>\s*$/gi,
|
||||
subDivRegExp = /^\s*<pre>((?:.|\n)*)<\/pre>\s*$/gi,
|
||||
attrRegExp = /\s*([^=\s]+)\s*=\s*"([^"]*)"/gi,
|
||||
match = divRegExp.exec(text);
|
||||
if(match) {
|
||||
var subMatch = subDivRegExp.exec(match[2]); // Body of the <DIV> tag
|
||||
if(subMatch) {
|
||||
result.text = subMatch[1];
|
||||
} else {
|
||||
result.text = match[2];
|
||||
}
|
||||
var attrMatch;
|
||||
do {
|
||||
attrMatch = attrRegExp.exec(match[1]);
|
||||
if(attrMatch) {
|
||||
var name = attrMatch[1];
|
||||
var value = attrMatch[2];
|
||||
result[name] = value;
|
||||
}
|
||||
} while(attrMatch);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
var inputTiddlerPlain = function(text,fields) {
|
||||
fields.text = text;
|
||||
return [fields];
|
||||
};
|
||||
|
||||
var inputTiddlerJavaScript = function(text,fields) {
|
||||
var headerCommentRegExp = /^\/\*\\\n((?:^[^\n]*\n)+?)(^\\\*\/$\n?)/mg,
|
||||
match = headerCommentRegExp.exec(text);
|
||||
fields.text = text;
|
||||
if(match) {
|
||||
fields = parseMetaDataBlock(match[1],fields);
|
||||
}
|
||||
return [fields];
|
||||
};
|
||||
|
||||
var inputTiddlerDiv = function(text,fields) {
|
||||
return [parseTiddlerDiv(text,fields)];
|
||||
};
|
||||
|
||||
var inputTiddler = function(text,fields) {
|
||||
var split = text.indexOf("\n\n");
|
||||
if(split !== -1) {
|
||||
fields.text = text.substr(split + 2);
|
||||
}
|
||||
if(split === -1) {
|
||||
split = text.length;
|
||||
}
|
||||
fields = parseMetaDataBlock(text.substr(0,split),fields);
|
||||
return [fields];
|
||||
};
|
||||
|
||||
var inputTiddlerJSON = function(text,fields) {
|
||||
var tiddlers = JSON.parse(text),
|
||||
result = [],
|
||||
getKnownFields = function(tid) {
|
||||
var fields = {};
|
||||
"title text created creator modified modifier type tags".split(" ").forEach(function(value) {
|
||||
fields[value] = tid[value];
|
||||
});
|
||||
return fields;
|
||||
};
|
||||
for(var t=0; t<tiddlers.length; t++) {
|
||||
result.push(getKnownFields(tiddlers[t]));
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
var inputTiddlyWiki = function(text,fields) {
|
||||
var locateStoreArea = function(tiddlywikidoc) {
|
||||
var startSaveArea = '<div id="' + 'storeArea">',
|
||||
startSaveAreaRegExp = /<div id=["']?storeArea['"]?>/gi,
|
||||
endSaveArea = '</d' + 'iv>',
|
||||
endSaveAreaCaps = '</D' + 'IV>',
|
||||
posOpeningDiv = tiddlywikidoc.search(startSaveAreaRegExp),
|
||||
limitClosingDiv = tiddlywikidoc.indexOf("<"+"!--POST-STOREAREA--"+">");
|
||||
if(limitClosingDiv == -1) {
|
||||
limitClosingDiv = tiddlywikidoc.indexOf("<"+"!--POST-BODY-START--"+">");
|
||||
}
|
||||
var start = limitClosingDiv == -1 ? tiddlywikidoc.length : limitClosingDiv,
|
||||
posClosingDiv = tiddlywikidoc.lastIndexOf(endSaveArea,start);
|
||||
if(posClosingDiv == -1) {
|
||||
posClosingDiv = tiddlywikidoc.lastIndexOf(endSaveAreaCaps,start);
|
||||
}
|
||||
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 = utils.htmlDecode(tiddlerFields.text);
|
||||
results.push(tiddlerFields);
|
||||
}
|
||||
startPos = endPos;
|
||||
match = endOfDivRegExp.exec(text);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
// Given a reference to a DOM node, return the tiddlers stored in the immediate child nodes
|
||||
var inputTiddlerDOM = function(node) {
|
||||
var extractTextTiddler = function(node) {
|
||||
var e = node.firstChild;
|
||||
while(e && e.nodeName.toLowerCase() !== "pre") {
|
||||
e = e.nextSibling;
|
||||
}
|
||||
var title = node.getAttribute ? node.getAttribute("title") : null;
|
||||
if(e && title) {
|
||||
var i,
|
||||
attrs = node.attributes,
|
||||
tiddler = {
|
||||
text: utils.htmlDecode(e.innerHTML)
|
||||
};
|
||||
for(i=attrs.length-1; i >= 0; i--) {
|
||||
if(attrs[i].specified) {
|
||||
var value = attrs[i].value,
|
||||
name = attrs[i].name;
|
||||
if(!Tiddler.isStandardField(name)) {
|
||||
value = utils.unescapeLineBreaks(value);
|
||||
}
|
||||
tiddler[name] = value;
|
||||
}
|
||||
}
|
||||
return tiddler;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
extractModuleTiddler = function(node) {
|
||||
if(node.hasAttribute && node.hasAttribute("data-tiddler-title")) {
|
||||
var text = node.innerHTML,
|
||||
s = text.indexOf("{"),
|
||||
e = text.lastIndexOf("}");
|
||||
if(s !== -1 && e !== -1) {
|
||||
text = text.substring(s+1,e-1);
|
||||
}
|
||||
return {
|
||||
title: node.getAttribute("data-tiddler-title"),
|
||||
text: text,
|
||||
type: "application/javascript"
|
||||
};
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
t,tiddlers = [];
|
||||
for(t = 0; t < node.childNodes.length; t++) {
|
||||
var tiddler = extractTextTiddler(node.childNodes[t]);
|
||||
tiddler = tiddler || extractModuleTiddler(node.childNodes[t]);
|
||||
if(tiddler) {
|
||||
tiddlers.push(tiddler);
|
||||
}
|
||||
}
|
||||
return tiddlers;
|
||||
};
|
||||
|
||||
tiddlerInput.register = function(store) {
|
||||
store.registerTiddlerDeserializer(".txt","text/plain",inputTiddlerPlain);
|
||||
store.registerTiddlerDeserializer(".js","application/javascript",inputTiddlerJavaScript);
|
||||
store.registerTiddlerDeserializer(".tiddler","application/x-tiddler-html-div",inputTiddlerDiv);
|
||||
store.registerTiddlerDeserializer(".tid","application/x-tiddler",inputTiddler);
|
||||
store.registerTiddlerDeserializer(".json","application/json",inputTiddlerJSON);
|
||||
store.registerTiddlerDeserializer(".tiddlywiki","application/x-tiddlywiki",inputTiddlyWiki);
|
||||
store.registerTiddlerDeserializer("(DOM)","(DOM)",inputTiddlerDOM);
|
||||
};
|
||||
|
||||
})();
|
||||
Reference in New Issue
Block a user