2011-12-03 16:13:35 +00:00
|
|
|
/*global require: false, exports: false, process: false */
|
|
|
|
"use strict";
|
|
|
|
|
2011-12-05 16:50:25 +00:00
|
|
|
var util = require("util");
|
2011-12-03 16:13:35 +00:00
|
|
|
|
2011-12-05 10:34:43 +00:00
|
|
|
var textPrimitives = {
|
2011-12-03 18:19:13 +00:00
|
|
|
upperLetter: "[A-Z\u00c0-\u00de\u0150\u0170]",
|
|
|
|
lowerLetter: "[a-z0-9_\\-\u00df-\u00ff\u0151\u0171]",
|
|
|
|
anyLetter: "[A-Za-z0-9_\\-\u00c0-\u00de\u00df-\u00ff\u0150\u0170\u0151\u0171]",
|
|
|
|
anyLetterStrict: "[A-Za-z0-9\u00c0-\u00de\u00df-\u00ff\u0150\u0170\u0151\u0171]",
|
|
|
|
sliceSeparator: "::",
|
|
|
|
sectionSeparator: "##",
|
|
|
|
urlPattern: "(?:file|http|https|mailto|ftp|irc|news|data):[^\\s'\"]+(?:/|\\b)",
|
|
|
|
unWikiLink: "~",
|
|
|
|
brackettedLink: "\\[\\[([^\\]]+)\\]\\]",
|
|
|
|
titledBrackettedLink: "\\[\\[([^\\[\\]\\|]+)\\|([^\\[\\]\\|]+)\\]\\]"
|
|
|
|
};
|
|
|
|
|
|
|
|
textPrimitives.wikiLink = "(?:(?:" + textPrimitives.upperLetter + "+" +
|
|
|
|
textPrimitives.lowerLetter + "+" +
|
|
|
|
textPrimitives.upperLetter +
|
|
|
|
textPrimitives.anyLetter + "*)|(?:" +
|
|
|
|
textPrimitives.upperLetter + "{2,}" +
|
|
|
|
textPrimitives.lowerLetter + "+))";
|
|
|
|
|
|
|
|
textPrimitives.cssLookahead = "(?:(" + textPrimitives.anyLetter +
|
|
|
|
"+)\\(([^\\)\\|\\n]+)(?:\\):))|(?:(" + textPrimitives.anyLetter + "+):([^;\\|\\n]+);)";
|
|
|
|
|
|
|
|
textPrimitives.cssLookaheadRegExp = new RegExp(textPrimitives.cssLookahead,"mg");
|
|
|
|
|
|
|
|
textPrimitives.tiddlerForcedLinkRegExp = new RegExp("(?:" + textPrimitives.titledBrackettedLink + ")|(?:" +
|
|
|
|
textPrimitives.brackettedLink + ")|(?:" +
|
|
|
|
textPrimitives.urlPattern + ")","mg");
|
|
|
|
|
|
|
|
textPrimitives.tiddlerAnyLinkRegExp = new RegExp("("+ textPrimitives.wikiLink + ")|(?:" +
|
|
|
|
textPrimitives.titledBrackettedLink + ")|(?:" +
|
|
|
|
textPrimitives.brackettedLink + ")|(?:" +
|
|
|
|
textPrimitives.urlPattern + ")","mg");
|
2011-12-03 16:13:35 +00:00
|
|
|
|
2011-12-05 16:50:25 +00:00
|
|
|
function WikiTextRules()
|
2011-12-03 16:13:35 +00:00
|
|
|
{
|
|
|
|
var pattern = [];
|
2011-12-05 16:50:25 +00:00
|
|
|
this.rules = WikiTextRules.rules;
|
|
|
|
for(var n=0; n<this.rules.length; n++) {
|
|
|
|
pattern.push("(" + this.rules[n].match + ")");
|
2011-12-03 16:13:35 +00:00
|
|
|
}
|
2011-12-05 16:50:25 +00:00
|
|
|
this.rulesRegExp = new RegExp(pattern.join("|"),"mg");
|
2011-12-03 16:13:35 +00:00
|
|
|
}
|
|
|
|
|
2011-12-05 16:50:25 +00:00
|
|
|
WikiTextRules.createElementAndWikify = function(w) {
|
2011-12-05 10:34:43 +00:00
|
|
|
var e = {type: this.element, children: []};
|
|
|
|
w.output.push(e);
|
|
|
|
w.subWikifyTerm(e.children,this.termRegExp);
|
2011-12-03 16:18:17 +00:00
|
|
|
};
|
2011-12-03 16:13:35 +00:00
|
|
|
|
2011-12-05 16:50:25 +00:00
|
|
|
WikiTextRules.setAttr = function(e,attr,value) {
|
2011-12-05 18:21:52 +00:00
|
|
|
if(!e.attributes) {
|
2011-12-05 13:15:06 +00:00
|
|
|
e.attributes = {};
|
|
|
|
}
|
|
|
|
e.attributes[attr] = value;
|
2011-12-05 16:50:25 +00:00
|
|
|
};
|
2011-12-05 13:15:06 +00:00
|
|
|
|
2011-12-05 16:50:25 +00:00
|
|
|
WikiTextRules.inlineCssHelper = function(w) {
|
2011-12-03 16:18:17 +00:00
|
|
|
var styles = [];
|
2011-12-03 18:19:13 +00:00
|
|
|
textPrimitives.cssLookaheadRegExp.lastIndex = w.nextMatch;
|
|
|
|
var lookaheadMatch = textPrimitives.cssLookaheadRegExp.exec(w.source);
|
2011-12-03 16:18:17 +00:00
|
|
|
while(lookaheadMatch && lookaheadMatch.index == w.nextMatch) {
|
|
|
|
var s,v;
|
|
|
|
if(lookaheadMatch[1]) {
|
2011-12-06 10:40:49 +00:00
|
|
|
s = lookaheadMatch[1];
|
2011-12-03 16:18:17 +00:00
|
|
|
v = lookaheadMatch[2];
|
|
|
|
} else {
|
2011-12-06 10:40:49 +00:00
|
|
|
s = lookaheadMatch[3];
|
2011-12-03 16:18:17 +00:00
|
|
|
v = lookaheadMatch[4];
|
2011-12-03 16:13:35 +00:00
|
|
|
}
|
2011-12-03 16:18:17 +00:00
|
|
|
if(s=="bgcolor")
|
|
|
|
s = "backgroundColor";
|
|
|
|
if(s=="float")
|
|
|
|
s = "cssFloat";
|
|
|
|
styles.push({style: s, value: v});
|
|
|
|
w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
|
2011-12-03 18:19:13 +00:00
|
|
|
textPrimitives.cssLookaheadRegExp.lastIndex = w.nextMatch;
|
|
|
|
lookaheadMatch = textPrimitives.cssLookaheadRegExp.exec(w.source);
|
2011-12-03 16:18:17 +00:00
|
|
|
}
|
|
|
|
return styles;
|
|
|
|
};
|
2011-12-03 16:13:35 +00:00
|
|
|
|
2011-12-05 16:50:25 +00:00
|
|
|
WikiTextRules.applyCssHelper = function(e,styles) {
|
2011-12-06 18:04:40 +00:00
|
|
|
if(styles.length > 0) {
|
|
|
|
if(!e.attributes) {
|
|
|
|
e.attributes = {};
|
|
|
|
}
|
|
|
|
if(!e.attributes.style) {
|
|
|
|
e.attributes.style = {};
|
|
|
|
}
|
|
|
|
for(var t=0; t< styles.length; t++) {
|
|
|
|
e.attributes.style[styles[t].style] = styles[t].value;
|
|
|
|
}
|
2011-12-03 16:18:17 +00:00
|
|
|
}
|
|
|
|
};
|
2011-12-03 16:13:35 +00:00
|
|
|
|
2011-12-05 16:50:25 +00:00
|
|
|
WikiTextRules.enclosedTextHelper = function(w) {
|
2011-12-03 16:18:17 +00:00
|
|
|
this.lookaheadRegExp.lastIndex = w.matchStart;
|
|
|
|
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
|
|
|
|
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
|
|
|
|
var text = lookaheadMatch[1];
|
2011-12-05 10:34:43 +00:00
|
|
|
w.output.push({type: this.element, children: [
|
|
|
|
{type: "text", value: text}
|
|
|
|
]});
|
2011-12-03 16:18:17 +00:00
|
|
|
w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
|
|
|
|
}
|
|
|
|
};
|
2011-12-03 16:13:35 +00:00
|
|
|
|
2011-12-05 16:50:25 +00:00
|
|
|
WikiTextRules.isExternalLink = function(w,link) {
|
2011-12-03 18:19:13 +00:00
|
|
|
var urlRegExp = new RegExp(textPrimitives.urlPattern,"mg");
|
2011-12-03 16:18:17 +00:00
|
|
|
if(urlRegExp.exec(link)) {
|
2011-12-03 16:36:11 +00:00
|
|
|
// Definitely an external link
|
2011-12-03 16:18:17 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if(link.indexOf(".")!=-1 || link.indexOf("\\")!=-1 || link.indexOf("/")!=-1 || link.indexOf("#")!=-1) {
|
2011-12-03 16:36:11 +00:00
|
|
|
// Link contains . / \ or # so is probably an external link
|
2011-12-03 16:18:17 +00:00
|
|
|
return true;
|
|
|
|
}
|
2011-12-03 16:36:11 +00:00
|
|
|
// Otherwise assume it is not an external link
|
2011-12-03 16:18:17 +00:00
|
|
|
return false;
|
2011-12-03 16:13:35 +00:00
|
|
|
};
|
|
|
|
|
2011-12-05 16:50:25 +00:00
|
|
|
WikiTextRules.rules = [
|
2011-12-03 16:13:35 +00:00
|
|
|
{
|
|
|
|
name: "table",
|
|
|
|
match: "^\\|(?:[^\\n]*)\\|(?:[fhck]?)$",
|
|
|
|
lookaheadRegExp: /^\|([^\n]*)\|([fhck]?)$/mg,
|
|
|
|
rowTermRegExp: /(\|(?:[fhck]?)$\n?)/mg,
|
|
|
|
cellRegExp: /(?:\|([^\n\|]*)\|)|(\|[fhck]?$\n?)/mg,
|
|
|
|
cellTermRegExp: /((?:\x20*)\|)/mg,
|
|
|
|
rowTypes: {"c":"caption", "h":"thead", "":"tbody", "f":"tfoot"},
|
|
|
|
handler: function(w)
|
|
|
|
{
|
2011-12-05 10:34:43 +00:00
|
|
|
var table = {type: "table", attributes: {className: "twtable"}, children: []};
|
|
|
|
w.output.push(table);
|
2011-12-03 16:13:35 +00:00
|
|
|
var prevColumns = [];
|
|
|
|
var currRowType = null;
|
|
|
|
var rowContainer;
|
|
|
|
var rowCount = 0;
|
|
|
|
w.nextMatch = w.matchStart;
|
|
|
|
this.lookaheadRegExp.lastIndex = w.nextMatch;
|
|
|
|
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
|
|
|
|
while(lookaheadMatch && lookaheadMatch.index == w.nextMatch) {
|
|
|
|
var nextRowType = lookaheadMatch[2];
|
|
|
|
if(nextRowType == "k") {
|
2011-12-05 10:34:43 +00:00
|
|
|
table.attributes.className = lookaheadMatch[1];
|
2011-12-03 16:13:35 +00:00
|
|
|
w.nextMatch += lookaheadMatch[0].length+1;
|
|
|
|
} else {
|
|
|
|
if(nextRowType != currRowType) {
|
2011-12-05 10:34:43 +00:00
|
|
|
rowContainer = {type: this.rowTypes[nextRowType], children: [], attributes: {}};
|
|
|
|
table.children.push(rowContainer);
|
2011-12-03 16:13:35 +00:00
|
|
|
currRowType = nextRowType;
|
|
|
|
}
|
|
|
|
if(currRowType == "c") {
|
|
|
|
// Caption
|
|
|
|
w.nextMatch++;
|
2011-12-05 10:34:43 +00:00
|
|
|
// Move the caption to the first row if it isn't already
|
|
|
|
if(table.children.length !== 1) {
|
|
|
|
table.children.pop(); // Take rowContainer out of the children array
|
|
|
|
table.splice(0,0,rowContainer); // Insert it at the bottom
|
|
|
|
}
|
|
|
|
rowContainer.attributes.align = rowCount === 0 ? "top" : "bottom";
|
|
|
|
w.subWikifyTerm(rowContainer.children,this.rowTermRegExp);
|
2011-12-03 16:13:35 +00:00
|
|
|
} else {
|
2011-12-05 18:21:52 +00:00
|
|
|
var theRow = {type: "tr", children: []};
|
|
|
|
WikiTextRules.setAttr(theRow,"className",rowCount%2 ? "oddRow" : "evenRow")
|
2011-12-05 10:34:43 +00:00
|
|
|
rowContainer.children.push(theRow);
|
2011-12-06 18:04:40 +00:00
|
|
|
this.rowHandler(w,theRow.children,prevColumns);
|
2011-12-03 16:13:35 +00:00
|
|
|
rowCount++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.lookaheadRegExp.lastIndex = w.nextMatch;
|
|
|
|
lookaheadMatch = this.lookaheadRegExp.exec(w.source);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
rowHandler: function(w,e,prevColumns)
|
|
|
|
{
|
|
|
|
var col = 0;
|
|
|
|
var colSpanCount = 1;
|
|
|
|
var prevCell = null;
|
|
|
|
this.cellRegExp.lastIndex = w.nextMatch;
|
|
|
|
var cellMatch = this.cellRegExp.exec(w.source);
|
|
|
|
while(cellMatch && cellMatch.index == w.nextMatch) {
|
|
|
|
if(cellMatch[1] == "~") {
|
|
|
|
// Rowspan
|
|
|
|
var last = prevColumns[col];
|
|
|
|
if(last) {
|
|
|
|
last.rowSpanCount++;
|
2011-12-05 18:21:52 +00:00
|
|
|
WikiTextRules.setAttr(last.element,"rowspan",last.rowSpanCount);
|
|
|
|
WikiTextRules.setAttr(last.element,"valign","center");
|
2011-12-03 16:13:35 +00:00
|
|
|
if(colSpanCount > 1) {
|
2011-12-05 18:21:52 +00:00
|
|
|
WikiTextRules.setAttr(last.element,"colspan",colSpanCount);
|
2011-12-03 16:13:35 +00:00
|
|
|
colSpanCount = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
w.nextMatch = this.cellRegExp.lastIndex-1;
|
|
|
|
} else if(cellMatch[1] == ">") {
|
|
|
|
// Colspan
|
|
|
|
colSpanCount++;
|
|
|
|
w.nextMatch = this.cellRegExp.lastIndex-1;
|
|
|
|
} else if(cellMatch[2]) {
|
|
|
|
// End of row
|
|
|
|
if(prevCell && colSpanCount > 1) {
|
2011-12-05 18:21:52 +00:00
|
|
|
WikiTextRules.setAttr(prevCell,"colspan",colSpanCount);
|
2011-12-03 16:13:35 +00:00
|
|
|
}
|
|
|
|
w.nextMatch = this.cellRegExp.lastIndex;
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
// Cell
|
|
|
|
w.nextMatch++;
|
2011-12-05 16:50:25 +00:00
|
|
|
var styles = WikiTextRules.inlineCssHelper(w);
|
2011-12-03 16:13:35 +00:00
|
|
|
var spaceLeft = false;
|
|
|
|
var chr = w.source.substr(w.nextMatch,1);
|
|
|
|
while(chr == " ") {
|
|
|
|
spaceLeft = true;
|
|
|
|
w.nextMatch++;
|
|
|
|
chr = w.source.substr(w.nextMatch,1);
|
|
|
|
}
|
|
|
|
var cell;
|
|
|
|
if(chr == "!") {
|
2011-12-06 18:04:40 +00:00
|
|
|
cell = {type: "th", children: []};
|
2011-12-05 10:34:43 +00:00
|
|
|
e.push(cell);
|
2011-12-03 16:13:35 +00:00
|
|
|
w.nextMatch++;
|
|
|
|
} else {
|
2011-12-06 18:04:40 +00:00
|
|
|
cell = {type: "td", children: []};
|
2011-12-05 10:34:43 +00:00
|
|
|
e.push(cell);
|
2011-12-03 16:13:35 +00:00
|
|
|
}
|
|
|
|
prevCell = cell;
|
|
|
|
prevColumns[col] = {rowSpanCount:1,element:cell};
|
|
|
|
if(colSpanCount > 1) {
|
2011-12-05 18:21:52 +00:00
|
|
|
WikiTextRules.setAttr(cell,"colspan",colSpanCount);
|
2011-12-03 16:13:35 +00:00
|
|
|
colSpanCount = 1;
|
|
|
|
}
|
2011-12-05 16:50:25 +00:00
|
|
|
WikiTextRules.applyCssHelper(cell,styles);
|
2011-12-06 18:04:40 +00:00
|
|
|
w.subWikifyTerm(cell.children,this.cellTermRegExp);
|
2011-12-03 16:13:35 +00:00
|
|
|
if(w.matchText.substr(w.matchText.length-2,1) == " ") // spaceRight
|
2011-12-05 18:21:52 +00:00
|
|
|
WikiTextRules.setAttr(cell,"align",spaceLeft ? "center" : "left");
|
2011-12-03 16:13:35 +00:00
|
|
|
else if(spaceLeft)
|
2011-12-05 18:21:52 +00:00
|
|
|
WikiTextRules.setAttr(cell,"align","right");
|
2011-12-03 16:13:35 +00:00
|
|
|
w.nextMatch--;
|
|
|
|
}
|
|
|
|
col++;
|
|
|
|
this.cellRegExp.lastIndex = w.nextMatch;
|
|
|
|
cellMatch = this.cellRegExp.exec(w.source);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "heading",
|
|
|
|
match: "^!{1,6}",
|
|
|
|
termRegExp: /(\n)/mg,
|
|
|
|
handler: function(w)
|
|
|
|
{
|
2011-12-05 13:15:06 +00:00
|
|
|
var e = {type: "h" + w.matchLength, children: []};
|
2011-12-05 10:34:43 +00:00
|
|
|
w.output.push(e);
|
|
|
|
w.subWikifyTerm(e.children,this.termRegExp);
|
2011-12-03 16:13:35 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "list",
|
|
|
|
match: "^(?:[\\*#;:]+)",
|
|
|
|
lookaheadRegExp: /^(?:(?:(\*)|(#)|(;)|(:))+)/mg,
|
|
|
|
termRegExp: /(\n)/mg,
|
|
|
|
handler: function(w)
|
|
|
|
{
|
|
|
|
var stack = [w.output];
|
|
|
|
var currLevel = 0, currType = null;
|
|
|
|
var listLevel, listType, itemType, baseType;
|
|
|
|
w.nextMatch = w.matchStart;
|
|
|
|
this.lookaheadRegExp.lastIndex = w.nextMatch;
|
|
|
|
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
|
|
|
|
while(lookaheadMatch && lookaheadMatch.index == w.nextMatch) {
|
|
|
|
if(lookaheadMatch[1]) {
|
|
|
|
listType = "ul";
|
|
|
|
itemType = "li";
|
|
|
|
} else if(lookaheadMatch[2]) {
|
|
|
|
listType = "ol";
|
|
|
|
itemType = "li";
|
|
|
|
} else if(lookaheadMatch[3]) {
|
|
|
|
listType = "dl";
|
|
|
|
itemType = "dt";
|
|
|
|
} else if(lookaheadMatch[4]) {
|
|
|
|
listType = "dl";
|
|
|
|
itemType = "dd";
|
|
|
|
}
|
|
|
|
if(!baseType)
|
|
|
|
baseType = listType;
|
|
|
|
listLevel = lookaheadMatch[0].length;
|
|
|
|
w.nextMatch += lookaheadMatch[0].length;
|
2011-12-05 10:34:43 +00:00
|
|
|
var t,e;
|
2011-12-03 16:13:35 +00:00
|
|
|
if(listLevel > currLevel) {
|
|
|
|
for(t=currLevel; t<listLevel; t++) {
|
2011-12-05 10:34:43 +00:00
|
|
|
var target = (currLevel === 0) ? stack[stack.length-1] : stack[stack.length-1].lastChild;
|
2011-12-05 13:15:06 +00:00
|
|
|
e = {type: listType, children: []};
|
2011-12-05 10:34:43 +00:00
|
|
|
target.push(e);
|
|
|
|
stack.push(e.children);
|
2011-12-03 16:13:35 +00:00
|
|
|
}
|
|
|
|
} else if(listType!=baseType && listLevel==1) {
|
|
|
|
w.nextMatch -= lookaheadMatch[0].length;
|
|
|
|
return;
|
|
|
|
} else if(listLevel < currLevel) {
|
|
|
|
for(t=currLevel; t>listLevel; t--)
|
|
|
|
stack.pop();
|
|
|
|
} else if(listLevel == currLevel && listType != currType) {
|
|
|
|
stack.pop();
|
2011-12-05 13:15:06 +00:00
|
|
|
e = {type: listType, children: []};
|
2011-12-05 10:34:43 +00:00
|
|
|
stack[stack.length-1].push(e);
|
|
|
|
stack.push(e.children);
|
2011-12-03 16:13:35 +00:00
|
|
|
}
|
|
|
|
currLevel = listLevel;
|
|
|
|
currType = listType;
|
2011-12-05 13:15:06 +00:00
|
|
|
e = {type: itemType, children: []};
|
2011-12-05 10:34:43 +00:00
|
|
|
stack[stack.length-1].push(e);
|
|
|
|
w.subWikifyTerm(e.children,this.termRegExp);
|
2011-12-03 16:13:35 +00:00
|
|
|
this.lookaheadRegExp.lastIndex = w.nextMatch;
|
|
|
|
lookaheadMatch = this.lookaheadRegExp.exec(w.source);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "quoteByBlock",
|
|
|
|
match: "^<<<\\n",
|
|
|
|
termRegExp: /(^<<<(\n|$))/mg,
|
|
|
|
element: "blockquote",
|
2011-12-05 16:50:25 +00:00
|
|
|
handler: WikiTextRules.createElementAndWikify
|
2011-12-03 16:13:35 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "quoteByLine",
|
|
|
|
match: "^>+",
|
|
|
|
lookaheadRegExp: /^>+/mg,
|
|
|
|
termRegExp: /(\n)/mg,
|
|
|
|
element: "blockquote",
|
|
|
|
handler: function(w)
|
|
|
|
{
|
|
|
|
var stack = [w.output];
|
|
|
|
var currLevel = 0;
|
|
|
|
var newLevel = w.matchLength;
|
2011-12-05 10:34:43 +00:00
|
|
|
var t,matched,e;
|
2011-12-03 16:13:35 +00:00
|
|
|
do {
|
|
|
|
if(newLevel > currLevel) {
|
2011-12-05 10:34:43 +00:00
|
|
|
for(t=currLevel; t<newLevel; t++) {
|
|
|
|
e = {type: this.element, attributes: {}, children: []};
|
|
|
|
stack[stack.length-1].push(e);
|
|
|
|
}
|
2011-12-03 16:13:35 +00:00
|
|
|
} else if(newLevel < currLevel) {
|
|
|
|
for(t=currLevel; t>newLevel; t--)
|
|
|
|
stack.pop();
|
|
|
|
}
|
|
|
|
currLevel = newLevel;
|
|
|
|
w.subWikifyTerm(stack[stack.length-1],this.termRegExp);
|
2011-12-05 18:21:52 +00:00
|
|
|
stack[stack.length-1].push({type: "br"});
|
2011-12-03 16:13:35 +00:00
|
|
|
this.lookaheadRegExp.lastIndex = w.nextMatch;
|
|
|
|
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
|
|
|
|
matched = lookaheadMatch && lookaheadMatch.index == w.nextMatch;
|
|
|
|
if(matched) {
|
|
|
|
newLevel = lookaheadMatch[0].length;
|
|
|
|
w.nextMatch += lookaheadMatch[0].length;
|
|
|
|
}
|
|
|
|
} while(matched);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "rule",
|
|
|
|
match: "^----+$\\n?|<hr ?/?>\\n?",
|
|
|
|
handler: function(w)
|
|
|
|
{
|
2011-12-05 18:21:52 +00:00
|
|
|
var e = {type: "hr"};
|
2011-12-05 10:34:43 +00:00
|
|
|
w.output.push(e);
|
2011-12-03 16:13:35 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "monospacedByLine",
|
|
|
|
match: "^(?:/\\*\\{\\{\\{\\*/|\\{\\{\\{|//\\{\\{\\{|<!--\\{\\{\\{-->)\\n",
|
|
|
|
element: "pre",
|
|
|
|
handler: function(w)
|
|
|
|
{
|
|
|
|
switch(w.matchText) {
|
|
|
|
case "/*{{{*/\n": // CSS
|
|
|
|
this.lookaheadRegExp = /\/\*\{\{\{\*\/\n*((?:^[^\n]*\n)+?)(\n*^\f*\/\*\}\}\}\*\/$\n?)/mg;
|
|
|
|
break;
|
|
|
|
case "{{{\n": // monospaced block
|
|
|
|
this.lookaheadRegExp = /^\{\{\{\n((?:^[^\n]*\n)+?)(^\f*\}\}\}$\n?)/mg;
|
|
|
|
break;
|
|
|
|
case "//{{{\n": // plugin
|
|
|
|
this.lookaheadRegExp = /^\/\/\{\{\{\n\n*((?:^[^\n]*\n)+?)(\n*^\f*\/\/\}\}\}$\n?)/mg;
|
|
|
|
break;
|
|
|
|
case "<!--{{{-->\n": //template
|
|
|
|
this.lookaheadRegExp = /<!--\{\{\{-->\n*((?:^[^\n]*\n)+?)(\n*^\f*<!--\}\}\}-->$\n?)/mg;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2011-12-05 16:50:25 +00:00
|
|
|
WikiTextRules.enclosedTextHelper.call(this,w);
|
2011-12-03 16:13:35 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "wikifyComment",
|
|
|
|
match: "^(?:/\\*\\*\\*|<!---)\\n",
|
|
|
|
handler: function(w)
|
|
|
|
{
|
|
|
|
var termRegExp = (w.matchText == "/***\n") ? (/(^\*\*\*\/\n)/mg) : (/(^--->\n)/mg);
|
|
|
|
w.subWikifyTerm(w.output,termRegExp);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "macro",
|
|
|
|
match: "<<",
|
|
|
|
lookaheadRegExp: /<<([^>\s]+)(?:\s*)((?:[^>]|(?:>(?!>)))*)>>/mg,
|
|
|
|
handler: function(w)
|
|
|
|
{
|
|
|
|
this.lookaheadRegExp.lastIndex = w.matchStart;
|
|
|
|
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
|
|
|
|
if(lookaheadMatch && lookaheadMatch.index == w.matchStart && lookaheadMatch[1]) {
|
|
|
|
w.nextMatch = this.lookaheadRegExp.lastIndex;
|
2011-12-05 10:34:43 +00:00
|
|
|
w.output.push({type: "macro", name: lookaheadMatch[1], params: lookaheadMatch[2]});
|
2011-12-03 16:13:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "prettyLink",
|
|
|
|
match: "\\[\\[",
|
|
|
|
lookaheadRegExp: /\[\[(.*?)(?:\|(~)?(.*?))?\]\]/mg,
|
|
|
|
handler: function(w)
|
|
|
|
{
|
|
|
|
this.lookaheadRegExp.lastIndex = w.matchStart;
|
|
|
|
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
|
|
|
|
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
|
2011-12-06 09:21:45 +00:00
|
|
|
var e = {type: "a", children: []};
|
2011-12-03 16:13:35 +00:00
|
|
|
var text = lookaheadMatch[1];
|
|
|
|
if(lookaheadMatch[3]) {
|
|
|
|
// Pretty bracketted link
|
|
|
|
var link = lookaheadMatch[3];
|
2011-12-06 09:21:45 +00:00
|
|
|
WikiTextRules.setAttr(e,"href",link);
|
2011-12-05 16:50:25 +00:00
|
|
|
if(!lookaheadMatch[2] && WikiTextRules.isExternalLink(w,link)) {
|
2011-12-06 09:21:45 +00:00
|
|
|
WikiTextRules.setAttr(e,"className","externalLink");
|
2011-12-05 10:34:43 +00:00
|
|
|
} else {
|
2011-12-06 09:21:45 +00:00
|
|
|
WikiTextRules.setAttr(e,"className","tiddlyLink");
|
2011-12-05 10:34:43 +00:00
|
|
|
}
|
2011-12-03 16:13:35 +00:00
|
|
|
} else {
|
|
|
|
// Simple bracketted link
|
2011-12-05 18:21:52 +00:00
|
|
|
WikiTextRules.setAttr(e,"href",text);
|
2011-12-06 09:21:45 +00:00
|
|
|
WikiTextRules.setAttr(e,"className","tiddlyLink");
|
2011-12-03 16:13:35 +00:00
|
|
|
}
|
2011-12-05 10:34:43 +00:00
|
|
|
w.output.push(e);
|
|
|
|
e.children.push({type: "text", value: text});
|
2011-12-03 16:13:35 +00:00
|
|
|
w.nextMatch = this.lookaheadRegExp.lastIndex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "wikiLink",
|
2011-12-03 18:19:13 +00:00
|
|
|
match: textPrimitives.unWikiLink+"?"+textPrimitives.wikiLink,
|
2011-12-03 16:13:35 +00:00
|
|
|
handler: function(w)
|
|
|
|
{
|
2011-12-03 18:19:13 +00:00
|
|
|
if(w.matchText.substr(0,1) == textPrimitives.unWikiLink) {
|
2011-12-03 16:13:35 +00:00
|
|
|
w.outputText(w.output,w.matchStart+1,w.nextMatch);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if(w.matchStart > 0) {
|
2011-12-03 18:19:13 +00:00
|
|
|
var preRegExp = new RegExp(textPrimitives.anyLetterStrict,"mg");
|
2011-12-03 16:13:35 +00:00
|
|
|
preRegExp.lastIndex = w.matchStart-1;
|
|
|
|
var preMatch = preRegExp.exec(w.source);
|
|
|
|
if(preMatch.index == w.matchStart-1) {
|
|
|
|
w.outputText(w.output,w.matchStart,w.nextMatch);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2011-12-05 16:50:25 +00:00
|
|
|
if(w.autoLinkWikiWords) {
|
2011-12-06 09:21:45 +00:00
|
|
|
var link = {type: "a", children: []};
|
2011-12-05 18:21:52 +00:00
|
|
|
WikiTextRules.setAttr(link,"href",w.matchText);
|
2011-12-06 09:21:45 +00:00
|
|
|
WikiTextRules.setAttr(link,"className","tiddlyLink");
|
2011-12-05 10:34:43 +00:00
|
|
|
w.output.push(link);
|
|
|
|
w.outputText(link.children,w.matchStart,w.nextMatch);
|
2011-12-03 16:13:35 +00:00
|
|
|
} else {
|
|
|
|
w.outputText(w.output,w.matchStart,w.nextMatch);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "urlLink",
|
2011-12-03 18:19:13 +00:00
|
|
|
match: textPrimitives.urlPattern,
|
2011-12-03 16:13:35 +00:00
|
|
|
handler: function(w)
|
|
|
|
{
|
2011-12-05 18:21:52 +00:00
|
|
|
var e = {type: "a", children: []};
|
|
|
|
WikiTextRules.setAttr(e,"href",w.matchText);
|
2011-12-05 10:34:43 +00:00
|
|
|
w.output.push(e);
|
|
|
|
w.outputText(e.children,w.matchStart,w.nextMatch);
|
2011-12-03 16:13:35 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "image",
|
|
|
|
match: "\\[[<>]?[Ii][Mm][Gg]\\[",
|
2011-12-03 16:36:11 +00:00
|
|
|
// [<] sequence below is to avoid lessThan-questionMark sequence so TiddlyWikis can be included in PHP files
|
2011-12-03 16:13:35 +00:00
|
|
|
lookaheadRegExp: /\[([<]?)(>?)[Ii][Mm][Gg]\[(?:([^\|\]]+)\|)?([^\[\]\|]+)\](?:\[([^\]]*)\])?\]/mg,
|
|
|
|
handler: function(w)
|
|
|
|
{
|
|
|
|
this.lookaheadRegExp.lastIndex = w.matchStart;
|
|
|
|
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
|
|
|
|
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
|
|
|
|
var e = w.output;
|
|
|
|
if(lookaheadMatch[5]) {
|
2011-12-05 10:34:43 +00:00
|
|
|
var link = lookaheadMatch[5],t;
|
2011-12-05 16:50:25 +00:00
|
|
|
if(WikiTextRules.isExternalLink(w,link)) {
|
2011-12-05 18:21:52 +00:00
|
|
|
t = {type: "a", children: []};
|
2011-12-05 10:34:43 +00:00
|
|
|
w.output.push(t);
|
|
|
|
e = t.children;
|
|
|
|
} else {
|
2011-12-05 18:21:52 +00:00
|
|
|
t = {type: "tiddlerLink", children: []};
|
2011-12-05 10:34:43 +00:00
|
|
|
w.output.push(t);
|
|
|
|
e = t.children;
|
|
|
|
}
|
2011-12-05 18:21:52 +00:00
|
|
|
WikiTextRules.setAttr(t,"href",link);
|
|
|
|
WikiTextRules.setAttr(t,"className","imageLink");
|
2011-12-03 16:13:35 +00:00
|
|
|
}
|
2011-12-05 13:15:06 +00:00
|
|
|
var img = {type: "img"};
|
2011-12-05 10:34:43 +00:00
|
|
|
e.push(img);
|
2011-12-03 16:13:35 +00:00
|
|
|
if(lookaheadMatch[1])
|
2011-12-05 16:50:25 +00:00
|
|
|
WikiTextRules.setAttr(img,"align","left");
|
2011-12-03 16:13:35 +00:00
|
|
|
else if(lookaheadMatch[2])
|
2011-12-05 16:50:25 +00:00
|
|
|
WikiTextRules.setAttr(img,"align","right");
|
2011-12-03 16:13:35 +00:00
|
|
|
if(lookaheadMatch[3]) {
|
2011-12-05 16:50:25 +00:00
|
|
|
WikiTextRules.setAttr(img,"title",lookaheadMatch[3]);
|
|
|
|
WikiTextRules.setAttr(img,"alt",lookaheadMatch[3]);
|
2011-12-03 16:13:35 +00:00
|
|
|
}
|
2011-12-05 18:21:52 +00:00
|
|
|
WikiTextRules.setAttr(img,"src",lookaheadMatch[4]);
|
2011-12-03 16:13:35 +00:00
|
|
|
w.nextMatch = this.lookaheadRegExp.lastIndex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "html",
|
|
|
|
match: "<[Hh][Tt][Mm][Ll]>",
|
|
|
|
lookaheadRegExp: /<[Hh][Tt][Mm][Ll]>((?:.|\n)*?)<\/[Hh][Tt][Mm][Ll]>/mg,
|
|
|
|
handler: function(w)
|
|
|
|
{
|
|
|
|
this.lookaheadRegExp.lastIndex = w.matchStart;
|
|
|
|
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
|
|
|
|
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
|
2011-12-05 10:34:43 +00:00
|
|
|
w.output.push({type: "html", value: lookaheadMatch[1]});
|
2011-12-03 16:13:35 +00:00
|
|
|
w.nextMatch = this.lookaheadRegExp.lastIndex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "commentByBlock",
|
|
|
|
match: "/%",
|
|
|
|
lookaheadRegExp: /\/%((?:.|\n)*?)%\//mg,
|
|
|
|
handler: function(w)
|
|
|
|
{
|
|
|
|
this.lookaheadRegExp.lastIndex = w.matchStart;
|
|
|
|
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
|
|
|
|
if(lookaheadMatch && lookaheadMatch.index == w.matchStart)
|
|
|
|
w.nextMatch = this.lookaheadRegExp.lastIndex;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "characterFormat",
|
|
|
|
match: "''|//|__|\\^\\^|~~|--(?!\\s|$)|\\{\\{\\{",
|
|
|
|
handler: function(w)
|
|
|
|
{
|
2011-12-05 10:34:43 +00:00
|
|
|
var e;
|
2011-12-03 16:13:35 +00:00
|
|
|
switch(w.matchText) {
|
|
|
|
case "''":
|
2011-12-05 10:34:43 +00:00
|
|
|
e = {type: "strong", children: []};
|
|
|
|
w.output.push(e);
|
|
|
|
w.subWikifyTerm(e.children,/('')/mg);
|
2011-12-03 16:13:35 +00:00
|
|
|
break;
|
|
|
|
case "//":
|
2011-12-05 10:34:43 +00:00
|
|
|
e = {type: "em", children: []};
|
|
|
|
w.output.push(e);
|
|
|
|
w.subWikifyTerm(e.children,/(\/\/)/mg);
|
2011-12-03 16:13:35 +00:00
|
|
|
break;
|
|
|
|
case "__":
|
2011-12-05 10:34:43 +00:00
|
|
|
e = {type: "u", children: []};
|
|
|
|
w.output.push(e);
|
|
|
|
w.subWikifyTerm(e.children,/(__)/mg);
|
2011-12-03 16:13:35 +00:00
|
|
|
break;
|
|
|
|
case "^^":
|
2011-12-05 10:34:43 +00:00
|
|
|
e = {type: "sup", children: []};
|
|
|
|
w.output.push(e);
|
|
|
|
w.subWikifyTerm(e.children,/(\^\^)/mg);
|
2011-12-03 16:13:35 +00:00
|
|
|
break;
|
|
|
|
case "~~":
|
2011-12-05 10:34:43 +00:00
|
|
|
e = {type: "sub", children: []};
|
|
|
|
w.output.push(e);
|
|
|
|
w.subWikifyTerm(e.children,/(~~)/mg);
|
2011-12-03 16:13:35 +00:00
|
|
|
break;
|
|
|
|
case "--":
|
2011-12-05 10:34:43 +00:00
|
|
|
e = {type: "strike", children: []};
|
|
|
|
w.output.push(e);
|
|
|
|
w.subWikifyTerm(e.children,/(--)/mg);
|
2011-12-03 16:13:35 +00:00
|
|
|
break;
|
|
|
|
case "{{{":
|
|
|
|
var lookaheadRegExp = /\{\{\{((?:.|\n)*?)\}\}\}/mg;
|
|
|
|
lookaheadRegExp.lastIndex = w.matchStart;
|
|
|
|
var lookaheadMatch = lookaheadRegExp.exec(w.source);
|
|
|
|
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
|
2011-12-05 10:34:43 +00:00
|
|
|
w.output.push({type: "code", children: [
|
|
|
|
{type: "text", value: lookaheadMatch[1]}
|
|
|
|
]});
|
2011-12-03 16:13:35 +00:00
|
|
|
w.nextMatch = lookaheadRegExp.lastIndex;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "customFormat",
|
|
|
|
match: "@@|\\{\\{",
|
|
|
|
handler: function(w)
|
|
|
|
{
|
|
|
|
switch(w.matchText) {
|
|
|
|
case "@@":
|
2011-12-05 18:21:52 +00:00
|
|
|
var e = {type: "span", children: []};
|
2011-12-05 10:34:43 +00:00
|
|
|
w.output.push(e);
|
2011-12-05 16:50:25 +00:00
|
|
|
var styles = WikiTextRules.inlineCssHelper(w);
|
2011-12-05 10:34:43 +00:00
|
|
|
if(styles.length === 0)
|
2011-12-03 16:13:35 +00:00
|
|
|
e.className = "marked";
|
|
|
|
else
|
2011-12-05 16:50:25 +00:00
|
|
|
WikiTextRules.applyCssHelper(e,styles);
|
2011-12-05 10:34:43 +00:00
|
|
|
w.subWikifyTerm(e.children,/(@@)/mg);
|
2011-12-03 16:13:35 +00:00
|
|
|
break;
|
|
|
|
case "{{":
|
|
|
|
var lookaheadRegExp = /\{\{[\s]*([\w]+[\s\w]*)[\s]*\{(\n?)/mg;
|
|
|
|
lookaheadRegExp.lastIndex = w.matchStart;
|
|
|
|
var lookaheadMatch = lookaheadRegExp.exec(w.source);
|
|
|
|
if(lookaheadMatch) {
|
|
|
|
w.nextMatch = lookaheadRegExp.lastIndex;
|
2011-12-05 10:34:43 +00:00
|
|
|
e = {type: lookaheadMatch[2] == "\n" ? "div" : "span", children: [
|
|
|
|
{type: "text", value: lookaheadMatch[1]}
|
|
|
|
]};
|
|
|
|
w.output.push(e);
|
|
|
|
w.subWikifyTerm(e.children,/(\}\}\})/mg);
|
2011-12-03 16:13:35 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "mdash",
|
|
|
|
match: "--",
|
|
|
|
handler: function(w)
|
|
|
|
{
|
2011-12-05 10:34:43 +00:00
|
|
|
w.output.push({type: "text", value: "—"});
|
2011-12-03 16:13:35 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "lineBreak",
|
|
|
|
match: "\\n|<br ?/?>",
|
|
|
|
handler: function(w)
|
|
|
|
{
|
2011-12-05 10:34:43 +00:00
|
|
|
w.output.push({type: "br"});
|
2011-12-03 16:13:35 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "rawText",
|
|
|
|
match: "\"{3}|<nowiki>",
|
|
|
|
lookaheadRegExp: /(?:\"{3}|<nowiki>)((?:.|\n)*?)(?:\"{3}|<\/nowiki>)/mg,
|
|
|
|
handler: function(w)
|
|
|
|
{
|
|
|
|
this.lookaheadRegExp.lastIndex = w.matchStart;
|
|
|
|
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
|
|
|
|
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
|
2011-12-05 10:34:43 +00:00
|
|
|
w.output.push({type: "text", value: lookaheadMatch[1]});
|
2011-12-03 16:13:35 +00:00
|
|
|
w.nextMatch = this.lookaheadRegExp.lastIndex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "htmlEntitiesEncoding",
|
|
|
|
match: "(?:(?:&#?[a-zA-Z0-9]{2,8};|.)(?:&#?(?:x0*(?:3[0-6][0-9a-fA-F]|1D[c-fC-F][0-9a-fA-F]|20[d-fD-F][0-9a-fA-F]|FE2[0-9a-fA-F])|0*(?:76[89]|7[7-9][0-9]|8[0-7][0-9]|761[6-9]|76[2-7][0-9]|84[0-3][0-9]|844[0-7]|6505[6-9]|6506[0-9]|6507[0-1]));)+|&#?[a-zA-Z0-9]{2,8};)",
|
|
|
|
handler: function(w)
|
|
|
|
{
|
2011-12-05 10:34:43 +00:00
|
|
|
w.output.push({type: "text", value: w.matchText});
|
2011-12-03 16:13:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
];
|
|
|
|
|
2011-12-05 16:50:25 +00:00
|
|
|
exports.wikiTextRules = new WikiTextRules();
|