mirror of
https://github.com/Jermolene/TiddlyWiki5.git
synced 2026-05-30 23:51:56 -07:00
* Initial commit
The idea is to extend the macro call syntax to accept dynamic parameter values (ie thing:{{more}} etc). Eventually, this will work in all the contexts in which the double angle bracket syntax is valid.
This initial commit gets the tests passing, but doesn't yet activate the new functionality.
* Test for standalone macro calls with dynamic parameters
* Parse attribute macros with the new parser
This fixes the tests
* Test for attribute macros
* Add some examples
* Tweak examples
* Fix test
* Temporarily disable a broken serializer test
* Fix/dynamic macro calls test (#9459)
* Revert "Temporarily disable a broken serializer test"
This reverts commit b3144300ee.
* restore synamic parameter parse result
* lint
* lint
* remove duplicate
* Update core/modules/parsers/parseutils.js
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update editions/test/tiddlers/tests/data/serialize/DynamicWidgetAttribute.tid
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update editions/test/tiddlers/tests/data/serialize/DynamicWidgetAttribute.tid
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* fix: mixed qouted and unquoted
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Fix unneeded diff
* Minor docs update
* Genuflecting to the linter
* Remove debug logging
* Add change note
* Allow single closing square brackets within double square brackets quoted strings
* Only allow new style parameter values if the separator is an equals sign
* On reflection, new style values should not be allowed for anonymous parameters
Backwards compatibility
* Docs updates
* Docs updates
---------
Co-authored-by: lin onetwo <linonetwo012@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
132 lines
4.2 KiB
JavaScript
132 lines
4.2 KiB
JavaScript
/*\
|
|
title: $:/plugins/tiddlywiki/wikitext-serialize/utils/parsetree.js
|
|
type: application/javascript
|
|
module-type: utils
|
|
|
|
Parse tree utility functions.
|
|
|
|
\*/
|
|
|
|
"use strict";
|
|
|
|
function initSerializers(Parser) {
|
|
if(Parser && !Parser.prototype.serializers) {
|
|
Parser.prototype.serializers = {};
|
|
$tw.modules.forEachModuleOfType("wikiruleserializer",function(title,module) {
|
|
var rule = module.name;
|
|
var serialize = module.serialize;
|
|
Parser.prototype.serializers[rule] = serialize;
|
|
});
|
|
}
|
|
};
|
|
|
|
/*
|
|
Utility to get the (similarly but not 1:1 equal) original wikitext of a parse tree node or array of nodes.
|
|
Based on `node.rule` metadata added in `wikiparser.js`.
|
|
*/
|
|
exports.serializeWikitextParseTree = function serializeWikitextParseTree(tree,options) {
|
|
options = options || {};
|
|
var output = [];
|
|
if($tw.utils.isArray(tree)) {
|
|
$tw.utils.each(tree,function(node) {
|
|
output.push(serializeWikitextParseTree(node,options));
|
|
});
|
|
} else if(tree) {
|
|
if(tree.type === "text" && !tree.rule) {
|
|
output.push(tree.text);
|
|
} else {
|
|
var Parser = $tw.utils.getParser("text/vnd.tiddlywiki");
|
|
// initialize the serializers only once on first use
|
|
initSerializers(Parser);
|
|
var serializeOneRule = Parser.prototype.serializers[tree.rule];
|
|
if(serializeOneRule) {
|
|
output.push(serializeOneRule(tree,serializeWikitextParseTree));
|
|
} else if(tree.rule === "parseblock") {
|
|
output.push(serializeWikitextParseTree(tree.children,options),"\n\n");
|
|
} else {
|
|
// when no rule is found, just serialize the children, for example the void nodes
|
|
output.push(serializeWikitextParseTree(tree.children,options));
|
|
}
|
|
}
|
|
}
|
|
return output.join("");
|
|
};
|
|
|
|
/*
|
|
Serialize a parsed attribute node
|
|
*/
|
|
exports.serializeAttribute = function(node,options) {
|
|
options = options || {};
|
|
if(!node || typeof node !== "object" || !node.name || !node.type) {
|
|
return null;
|
|
}
|
|
// If name is number, means it is a positional attribute and name is omitted
|
|
var positional = parseInt(node.name) >= 0,
|
|
// Use the original assignment operator if available, otherwise default to '='
|
|
assign = positional ? "" : (node.assignmentOperator || "="),
|
|
attributeString = positional ? "" : node.name;
|
|
if(node.type === "string") {
|
|
if(node.value === "true") {
|
|
return attributeString;
|
|
}
|
|
// For macro parameters (using ':' separator), preserve unquoted values
|
|
// For widget attributes (using '=' separator), always use quotes
|
|
if(assign === ":" && !node.quoted) {
|
|
attributeString += assign + node.value;
|
|
} else if(assign === "") {
|
|
// Positional parameter
|
|
if(!node.quoted) {
|
|
attributeString += node.value;
|
|
} else {
|
|
attributeString += '"' + node.value + '"';
|
|
}
|
|
} else {
|
|
attributeString += assign + '"' + node.value + '"';
|
|
}
|
|
} else if(node.type === "filtered") {
|
|
attributeString += assign + "{{{" + node.filter + "}}}";
|
|
} else if(node.type === "indirect") {
|
|
attributeString += assign + "{{" + node.textReference + "}}";
|
|
} else if(node.type === "substituted") {
|
|
attributeString += assign + "`" + node.rawValue + "`";
|
|
} else if(node.type === "macro") {
|
|
if(node.value && typeof node.value === "object") {
|
|
if(node.value.type === "transclude") {
|
|
// Handle the transclude-based macro call structure
|
|
var macroName = node.value.attributes && node.value.attributes["$variable"] ?
|
|
node.value.attributes["$variable"].value : "";
|
|
if(!macroName) {
|
|
return null;
|
|
}
|
|
var params = [];
|
|
if(node.value.orderedAttributes) {
|
|
node.value.orderedAttributes.forEach(function(attr) {
|
|
if(attr.name !== "$variable") {
|
|
var paramStr = exports.serializeAttribute(attr);
|
|
if(paramStr) {
|
|
params.push(paramStr);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
attributeString += assign + "<<" + macroName + (params.length > 0 ? " " + params.join(" ") : "") + ">>";
|
|
} else if(node.value.type === "macrocall") {
|
|
// Handle the classical macrocall structure for backwards compatibility
|
|
var params = node.value.params.map(function(param) {
|
|
return param.value;
|
|
}).join(" ");
|
|
attributeString += assign + "<<" + node.value.name + " " + params + ">>";
|
|
} else {
|
|
// Unsupported macro structure
|
|
return null;
|
|
}
|
|
} else {
|
|
// Unsupported macro structure
|
|
return null;
|
|
}
|
|
} else {
|
|
// Unsupported type
|
|
return null;
|
|
}
|
|
return attributeString;
|
|
};
|