mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-11-27 03:57:21 +00:00
Added basic support for HTML rendering
This commit is contained in:
parent
620add5579
commit
e7cda202fb
@ -40,15 +40,62 @@ var WikiTextParser = function(text) {
|
|||||||
this.subWikify(this.tree);
|
this.subWikify(this.tree);
|
||||||
};
|
};
|
||||||
|
|
||||||
WikiTextParser.prototype.outputText = function(place,startPos,endPos)
|
// Render the tiddler as HTML from its parse tree
|
||||||
{
|
// type - MIME type of required output
|
||||||
|
// store - store object providing context for inter-tiddler operations
|
||||||
|
// title - render the tree as if it came from a tiddler of this title
|
||||||
|
WikiTextParser.prototype.render = function(type,store,title) {
|
||||||
|
if(type === "text/html") {
|
||||||
|
return this.renderAsHtml(store,title);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
WikiTextParser.prototype.renderAsHtml = function(store,title) {
|
||||||
|
var output = [];
|
||||||
|
var renderElement = function(element, selfClosing) {
|
||||||
|
var tagBits = [element.type];
|
||||||
|
if(element.attributes) {
|
||||||
|
for(var a in element.attributes) {
|
||||||
|
tagBits.push(a + "=\"" + element.attributes[a] + "\"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output.push("<" + tagBits.join(" ") + (selfClosing ? " /" : "") + ">");
|
||||||
|
if(!selfClosing) {
|
||||||
|
if(element.children) {
|
||||||
|
renderSubTree(element.children);
|
||||||
|
}
|
||||||
|
output.push("</" + element.type + ">");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var renderSubTree = function(tree) {
|
||||||
|
for(var t=0; t<tree.length; t++) {
|
||||||
|
switch(tree[t].type) {
|
||||||
|
case "text":
|
||||||
|
output.push(tree[t].value);
|
||||||
|
break;
|
||||||
|
case "br":
|
||||||
|
case "img":
|
||||||
|
renderElement(tree[t],true); // Self closing elements
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
renderElement(tree[t]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
renderSubTree(this.tree);
|
||||||
|
return output.join("");
|
||||||
|
};
|
||||||
|
|
||||||
|
WikiTextParser.prototype.outputText = function(place,startPos,endPos) {
|
||||||
if(startPos < endPos) {
|
if(startPos < endPos) {
|
||||||
place.push({type: "text", value: this.source.substring(startPos,endPos)});
|
place.push({type: "text", value: this.source.substring(startPos,endPos)});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
WikiTextParser.prototype.subWikify = function(output,terminator)
|
WikiTextParser.prototype.subWikify = function(output,terminator) {
|
||||||
{
|
|
||||||
// Handle the terminated and unterminated cases separately, this speeds up wikifikation by about 30%
|
// Handle the terminated and unterminated cases separately, this speeds up wikifikation by about 30%
|
||||||
if(terminator)
|
if(terminator)
|
||||||
this.subWikifyTerm(output,new RegExp("(" + terminator + ")","mg"));
|
this.subWikifyTerm(output,new RegExp("(" + terminator + ")","mg"));
|
||||||
@ -56,8 +103,7 @@ WikiTextParser.prototype.subWikify = function(output,terminator)
|
|||||||
this.subWikifyUnterm(output);
|
this.subWikifyUnterm(output);
|
||||||
};
|
};
|
||||||
|
|
||||||
WikiTextParser.prototype.subWikifyUnterm = function(output)
|
WikiTextParser.prototype.subWikifyUnterm = function(output) {
|
||||||
{
|
|
||||||
// subWikify can be indirectly recursive, so we need to save the old output pointer
|
// subWikify can be indirectly recursive, so we need to save the old output pointer
|
||||||
var oldOutput = this.output;
|
var oldOutput = this.output;
|
||||||
this.output = output;
|
this.output = output;
|
||||||
@ -94,8 +140,7 @@ WikiTextParser.prototype.subWikifyUnterm = function(output)
|
|||||||
this.output = oldOutput;
|
this.output = oldOutput;
|
||||||
};
|
};
|
||||||
|
|
||||||
WikiTextParser.prototype.subWikifyTerm = function(output,terminatorRegExp)
|
WikiTextParser.prototype.subWikifyTerm = function(output,terminatorRegExp) {
|
||||||
{
|
|
||||||
// subWikify can be indirectly recursive, so we need to save the old output pointer
|
// subWikify can be indirectly recursive, so we need to save the old output pointer
|
||||||
var oldOutput = this.output;
|
var oldOutput = this.output;
|
||||||
this.output = output;
|
this.output = output;
|
||||||
|
@ -54,7 +54,7 @@ WikiTextRules.createElementAndWikify = function(w) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
WikiTextRules.setAttr = function(e,attr,value) {
|
WikiTextRules.setAttr = function(e,attr,value) {
|
||||||
if(!"attributes" in e) {
|
if(!e.attributes) {
|
||||||
e.attributes = {};
|
e.attributes = {};
|
||||||
}
|
}
|
||||||
e.attributes[attr] = value;
|
e.attributes[attr] = value;
|
||||||
@ -165,7 +165,8 @@ WikiTextRules.rules = [
|
|||||||
rowContainer.attributes.align = rowCount === 0 ? "top" : "bottom";
|
rowContainer.attributes.align = rowCount === 0 ? "top" : "bottom";
|
||||||
w.subWikifyTerm(rowContainer.children,this.rowTermRegExp);
|
w.subWikifyTerm(rowContainer.children,this.rowTermRegExp);
|
||||||
} else {
|
} else {
|
||||||
var theRow = {type: "tr", className: rowCount%2 ? "oddRow" : "evenRow", children: []};
|
var theRow = {type: "tr", children: []};
|
||||||
|
WikiTextRules.setAttr(theRow,"className",rowCount%2 ? "oddRow" : "evenRow")
|
||||||
rowContainer.children.push(theRow);
|
rowContainer.children.push(theRow);
|
||||||
this.rowHandler(w,theRow,prevColumns);
|
this.rowHandler(w,theRow,prevColumns);
|
||||||
rowCount++;
|
rowCount++;
|
||||||
@ -188,10 +189,10 @@ WikiTextRules.rules = [
|
|||||||
var last = prevColumns[col];
|
var last = prevColumns[col];
|
||||||
if(last) {
|
if(last) {
|
||||||
last.rowSpanCount++;
|
last.rowSpanCount++;
|
||||||
last.element.attributes.rowspan = last.rowSpanCount;
|
WikiTextRules.setAttr(last.element,"rowspan",last.rowSpanCount);
|
||||||
last.element.attributes.valign = "center";
|
WikiTextRules.setAttr(last.element,"valign","center");
|
||||||
if(colSpanCount > 1) {
|
if(colSpanCount > 1) {
|
||||||
last.element.attributes.colspan = colSpanCount;
|
WikiTextRules.setAttr(last.element,"colspan",colSpanCount);
|
||||||
colSpanCount = 1;
|
colSpanCount = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -203,7 +204,7 @@ WikiTextRules.rules = [
|
|||||||
} else if(cellMatch[2]) {
|
} else if(cellMatch[2]) {
|
||||||
// End of row
|
// End of row
|
||||||
if(prevCell && colSpanCount > 1) {
|
if(prevCell && colSpanCount > 1) {
|
||||||
prevCell.attributes.colspan = colSpanCount;
|
WikiTextRules.setAttr(prevCell,"colspan",colSpanCount);
|
||||||
}
|
}
|
||||||
w.nextMatch = this.cellRegExp.lastIndex;
|
w.nextMatch = this.cellRegExp.lastIndex;
|
||||||
break;
|
break;
|
||||||
@ -230,15 +231,15 @@ WikiTextRules.rules = [
|
|||||||
prevCell = cell;
|
prevCell = cell;
|
||||||
prevColumns[col] = {rowSpanCount:1,element:cell};
|
prevColumns[col] = {rowSpanCount:1,element:cell};
|
||||||
if(colSpanCount > 1) {
|
if(colSpanCount > 1) {
|
||||||
cell.attributes.colspan = colSpanCount;
|
WikiTextRules.setAttr(cell,"colspan",colSpanCount);
|
||||||
colSpanCount = 1;
|
colSpanCount = 1;
|
||||||
}
|
}
|
||||||
WikiTextRules.applyCssHelper(cell,styles);
|
WikiTextRules.applyCssHelper(cell,styles);
|
||||||
w.subWikifyTerm(cell,this.cellTermRegExp);
|
w.subWikifyTerm(cell,this.cellTermRegExp);
|
||||||
if(w.matchText.substr(w.matchText.length-2,1) == " ") // spaceRight
|
if(w.matchText.substr(w.matchText.length-2,1) == " ") // spaceRight
|
||||||
cell.attributes.align = spaceLeft ? "center" : "left";
|
WikiTextRules.setAttr(cell,"align",spaceLeft ? "center" : "left");
|
||||||
else if(spaceLeft)
|
else if(spaceLeft)
|
||||||
cell.attributes.align = "right";
|
WikiTextRules.setAttr(cell,"align","right");
|
||||||
w.nextMatch--;
|
w.nextMatch--;
|
||||||
}
|
}
|
||||||
col++;
|
col++;
|
||||||
@ -354,7 +355,7 @@ WikiTextRules.rules = [
|
|||||||
}
|
}
|
||||||
currLevel = newLevel;
|
currLevel = newLevel;
|
||||||
w.subWikifyTerm(stack[stack.length-1],this.termRegExp);
|
w.subWikifyTerm(stack[stack.length-1],this.termRegExp);
|
||||||
stack[stack.length-1].push({type: "br", attributes: {}});
|
stack[stack.length-1].push({type: "br"});
|
||||||
this.lookaheadRegExp.lastIndex = w.nextMatch;
|
this.lookaheadRegExp.lastIndex = w.nextMatch;
|
||||||
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
|
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
|
||||||
matched = lookaheadMatch && lookaheadMatch.index == w.nextMatch;
|
matched = lookaheadMatch && lookaheadMatch.index == w.nextMatch;
|
||||||
@ -371,7 +372,7 @@ WikiTextRules.rules = [
|
|||||||
match: "^----+$\\n?|<hr ?/?>\\n?",
|
match: "^----+$\\n?|<hr ?/?>\\n?",
|
||||||
handler: function(w)
|
handler: function(w)
|
||||||
{
|
{
|
||||||
var e = {type: "hr", attributes: {}};
|
var e = {type: "hr"};
|
||||||
w.output.push(e);
|
w.output.push(e);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -442,13 +443,15 @@ WikiTextRules.rules = [
|
|||||||
// Pretty bracketted link
|
// Pretty bracketted link
|
||||||
var link = lookaheadMatch[3];
|
var link = lookaheadMatch[3];
|
||||||
if(!lookaheadMatch[2] && WikiTextRules.isExternalLink(w,link)) {
|
if(!lookaheadMatch[2] && WikiTextRules.isExternalLink(w,link)) {
|
||||||
e = {type: "a", href: link, children: []};
|
e = {type: "a", children: []};
|
||||||
} else {
|
} else {
|
||||||
e = {type: "tiddlerLink", href: link, children: []};
|
e = {type: "tiddlerLink", children: []};
|
||||||
}
|
}
|
||||||
|
WikiTextRules.setAttr(e,"href",link);
|
||||||
} else {
|
} else {
|
||||||
// Simple bracketted link
|
// Simple bracketted link
|
||||||
e = {type: "tiddlerLink", href: text, children: []};
|
e = {type: "tiddlerLink", children: []};
|
||||||
|
WikiTextRules.setAttr(e,"href",text);
|
||||||
}
|
}
|
||||||
w.output.push(e);
|
w.output.push(e);
|
||||||
e.children.push({type: "text", value: text});
|
e.children.push({type: "text", value: text});
|
||||||
@ -476,7 +479,8 @@ WikiTextRules.rules = [
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(w.autoLinkWikiWords) {
|
if(w.autoLinkWikiWords) {
|
||||||
var link = {type: "tiddlerLink", href: w.matchText, children: []};
|
var link = {type: "tiddlerLink", children: []};
|
||||||
|
WikiTextRules.setAttr(link,"href",w.matchText);
|
||||||
w.output.push(link);
|
w.output.push(link);
|
||||||
w.outputText(link.children,w.matchStart,w.nextMatch);
|
w.outputText(link.children,w.matchStart,w.nextMatch);
|
||||||
} else {
|
} else {
|
||||||
@ -490,7 +494,8 @@ WikiTextRules.rules = [
|
|||||||
match: textPrimitives.urlPattern,
|
match: textPrimitives.urlPattern,
|
||||||
handler: function(w)
|
handler: function(w)
|
||||||
{
|
{
|
||||||
var e = {type: "a", href: w.matchText, children: []};
|
var e = {type: "a", children: []};
|
||||||
|
WikiTextRules.setAttr(e,"href",w.matchText);
|
||||||
w.output.push(e);
|
w.output.push(e);
|
||||||
w.outputText(e.children,w.matchStart,w.nextMatch);
|
w.outputText(e.children,w.matchStart,w.nextMatch);
|
||||||
}
|
}
|
||||||
@ -510,15 +515,16 @@ WikiTextRules.rules = [
|
|||||||
if(lookaheadMatch[5]) {
|
if(lookaheadMatch[5]) {
|
||||||
var link = lookaheadMatch[5],t;
|
var link = lookaheadMatch[5],t;
|
||||||
if(WikiTextRules.isExternalLink(w,link)) {
|
if(WikiTextRules.isExternalLink(w,link)) {
|
||||||
t = {type: "a", href: link, children: []};
|
t = {type: "a", children: []};
|
||||||
w.output.push(t);
|
w.output.push(t);
|
||||||
e = t.children;
|
e = t.children;
|
||||||
} else {
|
} else {
|
||||||
t = {type: "tiddlerLink", href: link, children: []};
|
t = {type: "tiddlerLink", children: []};
|
||||||
w.output.push(t);
|
w.output.push(t);
|
||||||
e = t.children;
|
e = t.children;
|
||||||
}
|
}
|
||||||
t.attributes.className = "imageLink";
|
WikiTextRules.setAttr(t,"href",link);
|
||||||
|
WikiTextRules.setAttr(t,"className","imageLink");
|
||||||
}
|
}
|
||||||
var img = {type: "img"};
|
var img = {type: "img"};
|
||||||
e.push(img);
|
e.push(img);
|
||||||
@ -530,7 +536,7 @@ WikiTextRules.rules = [
|
|||||||
WikiTextRules.setAttr(img,"title",lookaheadMatch[3]);
|
WikiTextRules.setAttr(img,"title",lookaheadMatch[3]);
|
||||||
WikiTextRules.setAttr(img,"alt",lookaheadMatch[3]);
|
WikiTextRules.setAttr(img,"alt",lookaheadMatch[3]);
|
||||||
}
|
}
|
||||||
img.src = lookaheadMatch[4];
|
WikiTextRules.setAttr(img,"src",lookaheadMatch[4]);
|
||||||
w.nextMatch = this.lookaheadRegExp.lastIndex;
|
w.nextMatch = this.lookaheadRegExp.lastIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -623,7 +629,7 @@ WikiTextRules.rules = [
|
|||||||
{
|
{
|
||||||
switch(w.matchText) {
|
switch(w.matchText) {
|
||||||
case "@@":
|
case "@@":
|
||||||
var e = {type: "span", attributes: {}, children: []};
|
var e = {type: "span", children: []};
|
||||||
w.output.push(e);
|
w.output.push(e);
|
||||||
var styles = WikiTextRules.inlineCssHelper(w);
|
var styles = WikiTextRules.inlineCssHelper(w);
|
||||||
if(styles.length === 0)
|
if(styles.length === 0)
|
||||||
|
23
wikitest.js
23
wikitest.js
@ -13,12 +13,17 @@ var wikiTest = function(spec) {
|
|||||||
store = new TiddlyWiki(),
|
store = new TiddlyWiki(),
|
||||||
w;
|
w;
|
||||||
for(t=0; t<spec.tiddlers.length; t++) {
|
for(t=0; t<spec.tiddlers.length; t++) {
|
||||||
store.addTiddler(new Tiddler(spec.tiddlers[t]));
|
var tid = new Tiddler(spec.tiddlers[t]);
|
||||||
|
store.addTiddler(tid);
|
||||||
|
|
||||||
|
console.error("%s in HTML:\n%s",tid.fields.title,tid.getParseTree().render("text/html",store,tid.fields.title));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
for(t=0; t<spec.tests.length; t++) {
|
for(t=0; t<spec.tests.length; t++) {
|
||||||
w = store.getTiddler(spec.tests[t].tiddler).getParseTree().tree;
|
w = store.getTiddler(spec.tests[t].tiddler).getParseTree().tree;
|
||||||
if(JSON.stringify(w) !== JSON.stringify(spec.tests[t].output)) {
|
if(JSON.stringify(w) !== JSON.stringify(spec.tests[t].output)) {
|
||||||
console.error("Failed at tiddler: " + spec.tests[t].tiddler + " with JSON:\n" + util.inspect(w,false,8));
|
console.error("Failed at tiddler: " + spec.tests[t].tiddler + " with JSON:\n" + util.inspect(w,false,8) + "\nTarget was:\n" + util.inspect(spec.tests[t].output,false,8));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -41,8 +46,8 @@ wikiTest({ tiddlers:
|
|||||||
{ type: 'text',
|
{ type: 'text',
|
||||||
value: ' of the first tiddler, with a link to the ' },
|
value: ' of the first tiddler, with a link to the ' },
|
||||||
{ type: 'tiddlerLink',
|
{ type: 'tiddlerLink',
|
||||||
href: 'SecondTiddler',
|
children: [ { type: 'text', value: 'SecondTiddler' } ],
|
||||||
children: [ { type: 'text', value: 'SecondTiddler' } ] },
|
attributes: {href: 'SecondTiddler'} },
|
||||||
{ type: 'text', value: ', too.' } ] },
|
{ type: 'text', value: ', too.' } ] },
|
||||||
{ tiddler: 'SecondTiddler',
|
{ tiddler: 'SecondTiddler',
|
||||||
output:
|
output:
|
||||||
@ -66,14 +71,14 @@ wikiTest({ tiddlers:
|
|||||||
output:
|
output:
|
||||||
[ { type: 'text', value: 'An explicit link ' },
|
[ { type: 'text', value: 'An explicit link ' },
|
||||||
{ type: 'tiddlerLink',
|
{ type: 'tiddlerLink',
|
||||||
href: 'Fourth Tiddler',
|
children: [ { type: 'text', value: 'Fourth Tiddler' } ],
|
||||||
children: [ { type: 'text', value: 'Fourth Tiddler' } ] },
|
attributes: { href: 'Fourth Tiddler' } },
|
||||||
{ type: 'text', value: ' and ' },
|
{ type: 'text', value: ' and ' },
|
||||||
{ type: 'tiddlerLink',
|
{ type: 'tiddlerLink',
|
||||||
href: 'Fourth Tiddler',
|
children: [ { type: 'text', value: 'a pretty link' } ],
|
||||||
children: [ { type: 'text', value: 'a pretty link' } ] } ] },
|
attributes: { href: 'Fourth Tiddler' } } ] },
|
||||||
{ tiddler: 'Fourth Tiddler',
|
{ tiddler: 'Fourth Tiddler',
|
||||||
output:
|
output:
|
||||||
[ { type: 'text', value: 'An image ' },
|
[ { type: 'text', value: 'An image ' },
|
||||||
{ type: 'img', src: 'Something.jpg' } ] } ] }
|
{ type: 'img', attributes: {src: 'Something.jpg' } } ] } ] }
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user