You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
3.0 KiB
JavaScript
130 lines
3.0 KiB
JavaScript
{
|
|
function filterTerminators(values) {
|
|
return values.map((value) => {
|
|
return value[1];
|
|
});
|
|
}
|
|
|
|
function collapseText(contents) {
|
|
/* To make the closing-tag parsing work, we interrupt a 'text' block
|
|
* every time we encounter a brace. Unfortunately, for non-closing-tag
|
|
* braces, this means things get broken up into consecutive text items.
|
|
* This function stitches consecutive text items back together. */
|
|
|
|
let textBuffer = "";
|
|
let newContents = [];
|
|
|
|
function completeTextItem() {
|
|
if (textBuffer.length > 0) {
|
|
newContents.push({
|
|
type: "text",
|
|
text: textBuffer
|
|
});
|
|
|
|
textBuffer = "";
|
|
}
|
|
}
|
|
|
|
contents.forEach((item) => {
|
|
if (item.type === "text") {
|
|
textBuffer += item.text;
|
|
} else {
|
|
completeTextItem();
|
|
newContents.push(item);
|
|
}
|
|
});
|
|
|
|
completeTextItem();
|
|
|
|
return newContents;
|
|
}
|
|
|
|
function processContents(contents) {
|
|
return collapseText(filterTerminators(contents));
|
|
}
|
|
|
|
function combineDelimitedItems(firstItem, nextItems, nextItemIndex = 1) {
|
|
return [firstItem].concat(nextItems.map((item) => {
|
|
return item[nextItemIndex];
|
|
}));
|
|
}
|
|
}
|
|
|
|
start
|
|
= contents:thing* {
|
|
return collapseText(contents);
|
|
}
|
|
|
|
text
|
|
= firstCharacter:. otherCharacters:[^{]* {
|
|
return {type: "text", text: firstCharacter + otherCharacters.join("")};
|
|
}
|
|
|
|
thing
|
|
= classTag
|
|
/*/ colorTag
|
|
/ boldTag
|
|
/ italicTag
|
|
/ weightTag
|
|
/ fontTag
|
|
/ sizeTag*/
|
|
/ alignmentTag
|
|
/ text
|
|
|
|
tagParameter
|
|
= characters:[^}:]+ { return characters.join(""); }
|
|
|
|
alignmentParameter
|
|
= "left"
|
|
/ "center"
|
|
/ "right"
|
|
/ "justify"
|
|
|
|
weightParameter
|
|
= "bold"
|
|
/ "normal"
|
|
/ [0-9]+
|
|
|
|
classParameter
|
|
= characters:[^}:,]+ { return characters.join(""); }
|
|
|
|
classTag
|
|
= "{class:" firstClassName:classParameter nextClassNames:("," classParameter)* "}" contents:(!"{/class}" thing)* "{/class}" {
|
|
return {type: "class", classNames: combineDelimitedItems(firstClassName, nextClassNames), contents: processContents(contents)};
|
|
}
|
|
|
|
/*colorTag
|
|
= "{color:" color:tagParameter "}" contents:(!"{/color}" thing)* "{/color}" {
|
|
return {type: "color", color: color, contents: processContents(contents)};
|
|
}
|
|
|
|
fontTag
|
|
= "{font:" font:tagParameter "}" contents:(!"{/font}" thing)* "{/font}" {
|
|
return {type: "font", font: font, contents: processContents(contents)};
|
|
}
|
|
|
|
sizeTag
|
|
= "{size:" size:tagParameter "}" contents:(!"{/size}" thing)* "{/size}" {
|
|
return {type: "size", size: size, contents: processContents(contents)};
|
|
}*/
|
|
|
|
alignmentTag
|
|
= "{align:" alignment:alignmentParameter "}" contents:(!"{/align}" thing)* "{/align}" {
|
|
return {type: "alignment", alignment: alignment, contents: processContents(contents)};
|
|
}
|
|
|
|
/*weightTag
|
|
= "{weight:" weight:tagParameter "}" contents:(!"{/weight}" thing)* "{/weight}" {
|
|
return {type: "weight", weight: weight, contents: processContents(contents)};
|
|
}
|
|
|
|
boldTag
|
|
= "{bold}" contents:(!"{/bold}" thing)* "{/bold}" {
|
|
return {type: "bold", contents: processContents(contents)};
|
|
}
|
|
|
|
italicTag
|
|
= "{italic}" contents:(!"{/italic}" thing)* "{/italic}" {
|
|
return {type: "italic", contents: processContents(contents)};
|
|
}*/
|