mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-09-17 17:59:45 +00:00
88 lines
2.9 KiB
JavaScript
88 lines
2.9 KiB
JavaScript
|
/*\
|
||
|
title: $:/core/modules/parsers/newwikitextparser/blockrules/list.js
|
||
|
type: application/javascript
|
||
|
module-type: wikitextblockrule
|
||
|
|
||
|
Wiki text block rule for lists.
|
||
|
|
||
|
|
||
|
|
||
|
\*/
|
||
|
(function(){
|
||
|
|
||
|
/*jslint node: true, browser: true */
|
||
|
/*global $tw: false */
|
||
|
"use strict";
|
||
|
|
||
|
exports.name = "list";
|
||
|
|
||
|
exports.regExpString = "[\\*#;:]+";
|
||
|
|
||
|
var listTypes = {
|
||
|
"*": {listTag: "ul", itemTag: "li"},
|
||
|
"#": {listTag: "ol", itemTag: "li"},
|
||
|
";": {listTag: "dl", itemTag: "dt"},
|
||
|
":": {listTag: "dl", itemTag: "dd"}
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
|
||
|
*/
|
||
|
exports.parse = function(match) {
|
||
|
var listStack = [], // Array containing list elements for the previous row in the list
|
||
|
t, listInfo, listElement, itemElement, previousRootListTag;
|
||
|
// Cycle through the rows in the list
|
||
|
do {
|
||
|
// Walk through the list markers for the current row
|
||
|
for(t=0; t<match[0].length; t++) {
|
||
|
listInfo = listTypes[match[0].charAt(t)];
|
||
|
// Remove any stacked up element if we can't re-use it because the list type doesn't match
|
||
|
if(listStack.length > t && listStack[t].type !== listInfo.listTag) {
|
||
|
listStack.splice(t,listStack.length - t);
|
||
|
}
|
||
|
// Construct the list element or reuse the previous one at this level
|
||
|
if(listStack.length <= t) {
|
||
|
listElement = $tw.Tree.Element(listInfo.listTag,{},[$tw.Tree.Element(listInfo.itemTag,{},[])]);
|
||
|
// Link this list element into the last child item of the parent list item
|
||
|
if(t) {
|
||
|
var prevListItem = listStack[t-1].children[listStack[t-1].children.length-1];
|
||
|
prevListItem.children.push(listElement);
|
||
|
}
|
||
|
// Save this element in the stack
|
||
|
listStack[t] = listElement;
|
||
|
} else if(t === (match[0].length - 1)) {
|
||
|
listStack[t].children.push($tw.Tree.Element(listInfo.itemTag,{},[]));
|
||
|
}
|
||
|
}
|
||
|
if(listStack.length > match[0].length) {
|
||
|
listStack.splice(match[0].length,listStack.length - match[0].length);
|
||
|
}
|
||
|
// Skip the list markers
|
||
|
this.pos = match.index + match[0].length;
|
||
|
// Process the body of the list item into the last list item
|
||
|
var lastListInfo = listTypes[match[0].charAt(match[0].length-1)],
|
||
|
lastListChildren = listStack[listStack.length-1].children,
|
||
|
lastListItem = lastListChildren[lastListChildren.length-1],
|
||
|
classedRun = this.parseClassedRun(/(\r?\n)/mg);
|
||
|
for(t=0; t<classedRun.tree.length; t++) {
|
||
|
lastListItem.children.push(classedRun.tree[t]);
|
||
|
}
|
||
|
if(classedRun["class"]) {
|
||
|
lastListItem.addClass(classedRun["class"]);
|
||
|
}
|
||
|
// Remember the root list tag of this list item
|
||
|
previousRootListTag = listStack[0].type;
|
||
|
// Consume any whitespace following the list item
|
||
|
this.skipWhitespace();
|
||
|
// Lookahead to see if the next line is part of the same list
|
||
|
var nextListItemRegExp = /(^[\*#;:]+)/mg;
|
||
|
nextListItemRegExp.lastIndex = this.pos;
|
||
|
match = nextListItemRegExp.exec(this.source);
|
||
|
listInfo = match ? listTypes[match[0].charAt(0)] : null;
|
||
|
} while(match && match.index === this.pos && listInfo && previousRootListTag === listInfo.listTag);
|
||
|
// Return the root element of the list
|
||
|
return [listStack[0]];
|
||
|
};
|
||
|
|
||
|
})();
|