diff --git a/core/modules/parsers/wikiparser/rules/quoteblock.js b/core/modules/parsers/wikiparser/rules/quoteblock.js index 3f946cf13..329d881b0 100644 --- a/core/modules/parsers/wikiparser/rules/quoteblock.js +++ b/core/modules/parsers/wikiparser/rules/quoteblock.js @@ -73,17 +73,20 @@ exports.parse = function() { }]; }; -exports.serialize = function(tree, serialize) { - // tree: { type: 'element', tag: 'blockquote', attributes: { class: { type: 'string', value: 'tc-quote' } }, children: [{ type: 'text', text: 'Quote text' }] } - // serialize: function that accepts array of nodes or a node and returns a string - // Split the class attribute value into an array of classes, classes: ['tc-quote'] - var classes = tree.attributes.class.value.split(" "); - // Start the serialized string with the opening delimiter and classes, serialized: '<< 0) { this.parser.amendRules(tokens[0],tokens.slice(1)); } - // No parse tree nodes to return - return []; + // No widget to render, return void node. + return [{ + type: "void", + attributes: { + action: {type: "string", value: tokens[0]}, + rules: {type: "string", value: tokens.slice(1).join(" ")} + }, + children: [] + }]; }; -exports.serialize = function(tree, serialize) { - // tree: { type: 'pragma', name: 'rules', args: ['except', 'ruleone', 'ruletwo', 'rulethree'] } - // serialize: function that accepts array of nodes or a node and returns a string - // Start the serialized string with the pragma name - var serialized = "\\rules"; - // Iterate over the arguments and append them to the serialized string - for(var i = 0; i < tree.args.length; i++) { - serialized += " " + tree.args[i]; +exports.serialize = function (tree, serialize) { + // tree: { type: "void", attributes: { action: { type: "string", value: "except" }, rules: { type: "string", value: "ruleone ruletwo rulethree" } }, children: [{ type: "void", attributes: { action: { type: "string", value: "only" }, rules: { type: "string", value: "ruleone ruletwo rulethree" } }, children: [] }] } + var result = []; + if(tree.attributes.action && tree.attributes.rules) { + // tree.attributes.action.value: "except" + // tree.attributes.rules.value: "ruleone ruletwo rulethree" + result.push("\\rules " + tree.attributes.action.value + " " + tree.attributes.rules.value); + tree.children.forEach(function (child) { + if(child.type === "void" && child.attributes.action && child.attributes.rules) { + // child.attributes.action.value: "only" + // child.attributes.rules.value: "ruleone ruletwo rulethree" + result.push("\\rules " + child.attributes.action.value + " " + child.attributes.rules.value); + } + }); } - // Return the complete serialized string - return serialized; + return result.join("\n"); }; })(); diff --git a/core/modules/parsers/wikiparser/rules/styleblock.js b/core/modules/parsers/wikiparser/rules/styleblock.js index 6ea89b5df..e054b0916 100644 --- a/core/modules/parsers/wikiparser/rules/styleblock.js +++ b/core/modules/parsers/wikiparser/rules/styleblock.js @@ -67,29 +67,62 @@ exports.parse = function() { $tw.utils.addAttributeToParseTreeNode(tree[t],"style",styles.join("")); } } - return tree; + return [{ + type: "void", + children: tree + }] }; exports.serialize = function(tree, serialize) { - // tree: [{ type: 'element', tag: 'p', attributes: { class: { type: 'string', value: 'myClass' }, style: { type: 'string', value: 'background-color:red;' } }, children: [{ type: 'text', text: 'This paragraph will have the CSS class `myClass`.' }] }] - // serialize: function that accepts array of nodes or a node and returns a string - // Initialize the serialized string with the opening delimiter - var serialized = "@@"; - // Check for styles and append them to the serialized string - if(tree[0].attributes.style) { - serialized += tree[0].attributes.style.value; - } - // Check for classes and append them to the serialized string - if(tree[0].attributes.class) { - var classes = tree[0].attributes.class.value.split(" "); - for(var i = 0; i < classes.length; i++) { - serialized += "." + classes[i]; + // serialize: function that serializes an array of nodes or a single node to a string + var result = []; + var classes = []; + var styles = []; + + // Collect all unique classes and styles from child nodes + for(var i = 0; i < tree.children.length; i++) { + var node = tree.children[i]; + if(node.attributes && node.attributes.class) { + var nodeClasses = node.attributes.class.value.split(" "); + for(var j = 0; j < nodeClasses.length; j++) { + if(classes.indexOf(nodeClasses[j]) === -1) { + classes.push(nodeClasses[j]); + } + } + } + if(node.attributes && node.attributes.style) { + var nodeStyles = node.attributes.style.value.split(";"); + for(var k = 0; k < nodeStyles.length; k++) { + var style = nodeStyles[k].trim(); + if(style && styles.indexOf(style) === -1) { + styles.push(style); + } + } } } - // Append the serialized children and the closing delimiter - serialized += "\n" + serialize(tree) + "\n@@"; - // Return the complete serialized string - return serialized; + + // Add the style block header if there are any classes or styles + if(classes.length > 0 || styles.length > 0) { + if(styles.length > 0) { + result.push("@@"); + result.push(styles.join(";")); + result.push(";\n"); + } + if(classes.length > 0) { + result.push("@@."); + result.push(classes.join(".")); + result.push("\n"); + } + } + + // Serialize each child node and add to result + for(var i = 0; i < tree.children.length; i++) { + result.push(serialize(tree.children[i])); + } + + // Add the closing @@ for the style block + result.push("@@"); + return result.join(""); }; })(); diff --git a/editions/test/tiddlers/tests/test-wikitext-serialize.js b/editions/test/tiddlers/tests/test-wikitext-serialize.js index 6b7ea72e0..7978b354f 100644 --- a/editions/test/tiddlers/tests/test-wikitext-serialize.js +++ b/editions/test/tiddlers/tests/test-wikitext-serialize.js @@ -276,7 +276,6 @@ describe("WikiAST serialization unit tests", function () { var serialized = $tw.utils.serializeParseTree(wiki.parseTiddler("ParserModeTest").tree).trimEnd(); expect(serialized).toBe(wiki.getTiddlerText("ParserModeTest").trimEnd()); }); - return; wiki.addTiddler({ title: "PrettyExtLinkTest", @@ -316,12 +315,19 @@ describe("WikiAST serialization unit tests", function () { wiki.addTiddler({ title: "StyleBlockTest", - text: "@@.myClass\n@@background-color:red;\nThis paragraph will have the CSS class `myClass`.\n\n* The `