diff --git a/packages/markdown-docx/src/ToCiceroMarkVisitor.js b/packages/markdown-docx/src/ToCiceroMarkVisitor.js
index 58a0b868..19fd9309 100644
--- a/packages/markdown-docx/src/ToCiceroMarkVisitor.js
+++ b/packages/markdown-docx/src/ToCiceroMarkVisitor.js
@@ -230,6 +230,22 @@ class ToCiceroMarkVisitor {
ciceroMarkNode.whenSome = [];
}
}
+ if (nodeInformation.properties[nodePropertyIndex] === TRANSFORMED_NODES.conditional) {
+ let currentNodes = [...ciceroMarkNode.nodes];
+ ciceroMarkNode = {
+ $class: TRANSFORMED_NODES.conditional,
+ ...nodeInformation.optionalProperties,
+ isTrue: nodeInformation.hasSome,
+ nodes: currentNodes,
+ };
+ if (nodeInformation.whenSomeType) {
+ ciceroMarkNode.whenTrue = currentNodes;
+ ciceroMarkNode.whenFalse = [];
+ } else {
+ ciceroMarkNode.whenFalse = currentNodes;
+ ciceroMarkNode.whenTrue = [];
+ }
+ }
if (nodeInformation.properties[nodePropertyIndex] === TRANSFORMED_NODES.link) {
ciceroMarkNode.title = '';
for (const relationshipElement of this.relationshipXML) {
@@ -312,6 +328,18 @@ class ToCiceroMarkVisitor {
} else {
eval(`${nestedExpression}nodes=${nestedExpression}whenNone`);
}
+ } else if (propertiesCurrent[commonPropertiesLength - 1] === TRANSFORMED_NODES.conditional) {
+ // equivalent to whenTrue
+ if (this.JSONXML[nodeIndex].whenSomeType) {
+ eval(`${nestedExpression}whenTrue=[...${nestedExpression}whenTrue, constructedNode]`);
+ } else {
+ eval(`${nestedExpression}whenFalse=[...${nestedExpression}whenFalse, constructedNode]`);
+ }
+ if (eval(`${nestedExpression}isTrue`)) {
+ eval(`${nestedExpression}nodes=${nestedExpression}whenTrue`);
+ } else {
+ eval(`${nestedExpression}nodes=${nestedExpression}whenFalse`);
+ }
} else {
eval(`${nestedExpression}nodes=[...${nestedExpression}nodes, constructedNode]`);
}
@@ -375,6 +403,15 @@ class ToCiceroMarkVisitor {
if (colorCodePresent && shadeCodePresent) {
nodeInformation.nodeType = TRANSFORMED_NODES.code;
}
+ /**
+ * for optional hasSome and whenSome stand for same as would be in the ciceromark.
+ * for conditional, the following relations with optional can be made
+ * optional | conditional
+ * hasSome | isTrue
+ * whenSome | whenTrue
+ * whenFalse | whenFalse
+ * The properties for conditional are not added therefore.
+ */
if (vanishPropertyPresent) {
if (fontFamilyPresent) {
nodeInformation.whenSomeType = false;
@@ -395,7 +432,7 @@ class ToCiceroMarkVisitor {
} else if (runTimeNodes.name === 'w:t') {
if (calledBy === TRANSFORMED_NODES.codeBlock) {
ooxmlTagTextValue += runTimeNodes.elements ? runTimeNodes.elements[0].text : '';
- } else if (calledBy === TRANSFORMED_NODES.optional) {
+ } else if (calledBy === TRANSFORMED_NODES.optional || calledBy === TRANSFORMED_NODES.conditional) {
ooxmlTagTextValue = runTimeNodes.elements && runTimeNodes.elements[0].text;
nodeInformation.value = ooxmlTagTextValue;
} else {
@@ -407,7 +444,7 @@ class ToCiceroMarkVisitor {
ooxmlTagTextValue += '\n';
} else if (runTimeNodes.name === 'w:sym') {
nodeInformation.nodeType = TRANSFORMED_NODES.softbreak;
- if (calledBy !== TRANSFORMED_NODES.optional) {
+ if (!(calledBy === TRANSFORMED_NODES.optional || calledBy === TRANSFORMED_NODES.conditional)) {
this.JSONXML = [...this.JSONXML, nodeInformation];
}
}
@@ -419,7 +456,7 @@ class ToCiceroMarkVisitor {
nodeInformation.hasSome = true;
}
- if (calledBy === TRANSFORMED_NODES.optional) {
+ if (calledBy === TRANSFORMED_NODES.optional || calledBy === TRANSFORMED_NODES.conditional) {
return nodeInformation;
}
return ooxmlTagTextValue;
@@ -555,6 +592,20 @@ class ToCiceroMarkVisitor {
this.JSONXML = [...this.JSONXML, { ...node }];
}
}
+ } else if (nodeInformation.nodeType === TRANSFORMED_NODES.conditional) {
+ if (variableSubNodes.elements) {
+ const optionalNodes = this.traverseElements(
+ variableSubNodes.elements,
+ TRANSFORMED_NODES.conditional
+ );
+ for (const node of optionalNodes) {
+ node.properties = [TRANSFORMED_NODES.conditional, ...node.properties];
+ node.optionalProperties = {
+ name: nodeInformation.name,
+ };
+ this.JSONXML = [...this.JSONXML, { ...node }];
+ }
+ }
} else {
for (const variableContentNodes of variableSubNodes.elements) {
if (variableContentNodes.name === 'w:r') {
@@ -582,7 +633,7 @@ class ToCiceroMarkVisitor {
inlineNodes = [...inlineNodes, this.fetchFormattingProperties(subNode, parent, nodeInformation)];
}
}
- if (parent === TRANSFORMED_NODES.optional) {
+ if (parent === TRANSFORMED_NODES.optional || parent === TRANSFORMED_NODES.conditional) {
return inlineNodes;
}
return blockNodes;
diff --git a/packages/markdown-docx/src/ToOOXMLVisitor/index.js b/packages/markdown-docx/src/ToOOXMLVisitor/index.js
index 9e430009..05007c94 100644
--- a/packages/markdown-docx/src/ToOOXMLVisitor/index.js
+++ b/packages/markdown-docx/src/ToOOXMLVisitor/index.js
@@ -34,6 +34,7 @@ const {
OPTIONAL_RULE,
VANISH_PROPERTY_RULE,
CONDITIONAL_OR_OPTIONAL_FONT_FAMILY_RULE,
+ CONDITIONAL_RULE,
} = require('./rules');
const { wrapAroundDefaultDocxTags, wrapAroundLockedContentControls } = require('./helpers');
const { TRANSFORMED_NODES, RELATIONSHIP_OFFSET } = require('../constants');
@@ -153,13 +154,13 @@ class ToOOXMLVisitor {
if (this.getClass(subNode) === TRANSFORMED_NODES.text) {
const tag = this.generateTextOrCodeOOXML(subNode.text, properties, false, parentProperties);
inlineOOXML += tag;
- if (parent !== TRANSFORMED_NODES.optional) {
+ if (!(parent === TRANSFORMED_NODES.optional || parent === TRANSFORMED_NODES.conditional)) {
this.tags = [...this.tags, tag];
}
} else if (this.getClass(subNode) === TRANSFORMED_NODES.code) {
const tag = this.generateTextOrCodeOOXML(subNode.text, properties, true, parentProperties);
inlineOOXML += tag;
- if (parent !== TRANSFORMED_NODES.optional) {
+ if (!(parent === TRANSFORMED_NODES.optional || parent === TRANSFORMED_NODES.conditional)) {
this.tags = [...this.tags, tag];
}
} else if (this.getClass(subNode) === TRANSFORMED_NODES.codeBlock) {
@@ -190,12 +191,12 @@ class ToOOXMLVisitor {
type,
parentProperties.traversingNodeHiddenInConditional
);
- if (parent !== TRANSFORMED_NODES.optional) {
+ if (!(parent === TRANSFORMED_NODES.optional || parent === TRANSFORMED_NODES.conditional)) {
this.tags = [...this.tags, VARIABLE_RULE(title, tag, value, type)];
}
} else if (this.getClass(subNode) === TRANSFORMED_NODES.softbreak) {
inlineOOXML += SOFTBREAK_RULE();
- if (parent !== TRANSFORMED_NODES.optional) {
+ if (!(parent === TRANSFORMED_NODES.optional || parent === TRANSFORMED_NODES.conditional)) {
this.tags = [...this.tags, SOFTBREAK_RULE()];
}
} else if (this.getClass(subNode) === TRANSFORMED_NODES.thematicBreak) {
@@ -325,6 +326,31 @@ class ToOOXMLVisitor {
// make the parentProperties false as traversal is done
parentProperties.traversingNodeHiddenInConditional = false;
parentProperties.traversingNodePresentInWhenFalseOrWhenNoneCondtion = false;
+ } else if (this.getClass(subNode) === TRANSFORMED_NODES.conditional) {
+ parentProperties.traversingNodeHiddenInConditional = !subNode.isTrue;
+ // traverse true nodes
+ const whenTrueOOXML = this.traverseNodes(
+ subNode.whenTrue,
+ properties,
+ TRANSFORMED_NODES.conditional,
+ parentProperties
+ );
+ parentProperties.traversingNodePresentInWhenFalseOrWhenNoneCondtion = true;
+ // traverse false nodes
+ const whenFalseOOXML = this.traverseNodes(
+ subNode.whenFalse,
+ properties,
+ TRANSFORMED_NODES.conditional,
+ parentProperties
+ );
+ const ooxml = `${whenTrueOOXML} ${whenFalseOOXML}`;
+ const tag = subNode.name;
+ this.createOrUpdateCounter(tag);
+ const title = `${tag.toUpperCase()[0]}${tag.substring(1)}${this.counter[tag].count}`;
+ const conditionalTag = CONDITIONAL_RULE(title, tag, ooxml);
+ this.tags = [...this.tags, conditionalTag];
+ parentProperties.traversingNodeHiddenInConditional = false;
+ parentProperties.traversingNodePresentInWhenFalseOrWhenNoneCondtion = false;
} else {
if (this.getClass(subNode) === TRANSFORMED_NODES.link) {
this.relationships = [
@@ -336,7 +362,7 @@ class ToOOXMLVisitor {
];
}
let newProperties = [...properties, subNode.$class];
- this.traverseNodes(subNode.nodes, newProperties, parent, parentProperties);
+ inlineOOXML += this.traverseNodes(subNode.nodes, newProperties, parent, parentProperties);
}
}
}
diff --git a/packages/markdown-docx/src/ToOOXMLVisitor/rules.js b/packages/markdown-docx/src/ToOOXMLVisitor/rules.js
index eedffa2e..915e78a1 100644
--- a/packages/markdown-docx/src/ToOOXMLVisitor/rules.js
+++ b/packages/markdown-docx/src/ToOOXMLVisitor/rules.js
@@ -283,14 +283,38 @@ const OPTIONAL_RULE = (title, tag, value, type) => {
const VANISH_PROPERTY_RULE = () => '';
/**
- * Inserts a different font family so that the `whenNone` nodes for optional content can be distinguished from `whenSome` nodes.
- *
+ * Inserts a different font family so that the conditional/optional content(else condition) can be distinguished. They can be of following types:-
+ * 1) `whenNone` nodes for optional(to be distinguished from `whenSome`)
+ * 2) `whenFalse` nodes for conditional(to be distinguished from `whenTrue`)
* @returns {string} OOXML tag for Baskerville Old Face font family
*/
const CONDITIONAL_OR_OPTIONAL_FONT_FAMILY_RULE = () => {
return '';
};
+/**
+ * Inserts optional node in OOXML form.
+ *
+ * @param {string} title Title of the optional node. Eg. receiver-1, shipper-1
+ * @param {string} tag Name of the optional node. Eg. receiver, shipper
+ * @param {string} value Value of the optional node
+ * @returns {string} OOXML string for the variable
+ */
+const CONDITIONAL_RULE = (title, tag, value) => {
+ return `
+
+
+
+
+
+
+
+ ${value}
+
+
+ `;
+};
+
module.exports = {
TEXT_RULE,
EMPHASIS_RULE,
@@ -311,4 +335,5 @@ module.exports = {
OPTIONAL_RULE,
VANISH_PROPERTY_RULE,
CONDITIONAL_OR_OPTIONAL_FONT_FAMILY_RULE,
+ CONDITIONAL_RULE,
};
diff --git a/packages/markdown-docx/src/constants.js b/packages/markdown-docx/src/constants.js
index 4014c688..8b86a2b1 100644
--- a/packages/markdown-docx/src/constants.js
+++ b/packages/markdown-docx/src/constants.js
@@ -21,6 +21,7 @@ const TRANSFORMED_NODES = {
code: `${NS_PREFIX_CommonMarkModel}Code`,
codeBlock: `${NS_PREFIX_CommonMarkModel}CodeBlock`,
computedVariable: `${NS_PREFIX_CiceroMarkModel}ComputedVariable`,
+ conditional: `${NS_PREFIX_CiceroMarkModel}Conditional`,
optional: `${NS_PREFIX_CiceroMarkModel}Optional`,
document: `${NS_PREFIX_CommonMarkModel}Document`,
emphasize: `${NS_PREFIX_CommonMarkModel}Emph`,
diff --git a/packages/markdown-docx/test/data/ciceroMark/conditional-isTrue-false.json b/packages/markdown-docx/test/data/ciceroMark/conditional-isTrue-false.json
new file mode 100644
index 00000000..40709229
--- /dev/null
+++ b/packages/markdown-docx/test/data/ciceroMark/conditional-isTrue-false.json
@@ -0,0 +1 @@
+{"$class":"org.accordproject.commonmark.Document","xmlns":"http://commonmark.org/xml/1.0","nodes":[{"$class":"org.accordproject.commonmark.Heading","level":"2","nodes":[{"$class":"org.accordproject.commonmark.Text","text":"Late Delivery and Penalty."}]},{"$class":"org.accordproject.commonmark.Paragraph","nodes":[{"$class":"org.accordproject.commonmark.Text","text":"In case of delayed delivery"},{"$class":"org.accordproject.ciceromark.Conditional","isTrue":false,"whenTrue":[{"$class":"org.accordproject.commonmark.Text","text":" except for Force Majeure cases,"}],"whenFalse":[{"$class":"org.accordproject.commonmark.Text","text":" even when Force Majeure occurs,"}],"name":"forceMajeure","nodes":[{"$class":"org.accordproject.commonmark.Text","text":" even when Force Majeure occurs,"}]},{"$class":"org.accordproject.commonmark.Softbreak"},{"$class":"org.accordproject.ciceromark.Variable","value":"\"Dan\"","name":"seller","elementType":"org.accordproject.party.Party"},{"$class":"org.accordproject.commonmark.Text","text":" (the Seller) shall pay to "},{"$class":"org.accordproject.ciceromark.Variable","value":"\"Steve\"","name":"buyer","elementType":"org.accordproject.party.Party"},{"$class":"org.accordproject.commonmark.Text","text":" (the Buyer) for every "},{"$class":"org.accordproject.ciceromark.Variable","value":"2","name":"amount","elementType":"Long"},{"$class":"org.accordproject.commonmark.Text","text":" "},{"$class":"org.accordproject.commonmark.Softbreak"},{"$class":"org.accordproject.commonmark.Text","text":"of delay penalty amounting to "},{"$class":"org.accordproject.ciceromark.Variable","value":"10.5","name":"penaltyPercentage","elementType":"Double"},{"$class":"org.accordproject.commonmark.Text","text":"% of the total value of the Equipment"},{"$class":"org.accordproject.commonmark.Softbreak"},{"$class":"org.accordproject.commonmark.Text","text":"whose delivery has been delayed. Any fractional part of a "},{"$class":"org.accordproject.commonmark.Text","text":" is to be"},{"$class":"org.accordproject.commonmark.Softbreak"},{"$class":"org.accordproject.commonmark.Text","text":"considered a full "},{"$class":"org.accordproject.commonmark.Text","text":". The total amount of penalty shall not however,"},{"$class":"org.accordproject.commonmark.Softbreak"},{"$class":"org.accordproject.commonmark.Text","text":"exceed "},{"$class":"org.accordproject.ciceromark.Variable","value":"55.0","name":"capPercentage","elementType":"Double"},{"$class":"org.accordproject.commonmark.Text","text":"% of the total value of the Equipment involved in late delivery."},{"$class":"org.accordproject.commonmark.Softbreak"},{"$class":"org.accordproject.commonmark.Text","text":"If the delay is more than "},{"$class":"org.accordproject.ciceromark.Variable","value":"15","name":"amount","elementType":"Long"},{"$class":"org.accordproject.commonmark.Text","text":" "},{"$class":"org.accordproject.commonmark.Text","text":", the Buyer is entitled to terminate this Contract."}]}]}
\ No newline at end of file
diff --git a/packages/markdown-docx/test/data/ciceroMark/conditional.json b/packages/markdown-docx/test/data/ciceroMark/conditional.json
new file mode 100644
index 00000000..aecea8a5
--- /dev/null
+++ b/packages/markdown-docx/test/data/ciceroMark/conditional.json
@@ -0,0 +1 @@
+{"$class":"org.accordproject.commonmark.Document","xmlns":"http://commonmark.org/xml/1.0","nodes":[{"$class":"org.accordproject.commonmark.Heading","level":"2","nodes":[{"$class":"org.accordproject.commonmark.Text","text":"Late Delivery and Penalty."}]},{"$class":"org.accordproject.commonmark.Paragraph","nodes":[{"$class":"org.accordproject.commonmark.Text","text":"In case of delayed delivery"},{"$class":"org.accordproject.ciceromark.Conditional","isTrue":true,"whenTrue":[{"$class":"org.accordproject.commonmark.Text","text":" except for Force Majeure cases,"},{"$class":"org.accordproject.commonmark.Emph","nodes":[{"$class":"org.accordproject.commonmark.Text","text":"not"}]}],"whenFalse":[{"$class":"org.accordproject.commonmark.Text","text":" even when Force Majeure occurs,"}],"name":"forceMajeure","nodes":[{"$class":"org.accordproject.commonmark.Text","text":" except for Force Majeure cases,"},{"$class":"org.accordproject.commonmark.Emph","nodes":[{"$class":"org.accordproject.commonmark.Text","text":"not"}]}]},{"$class":"org.accordproject.commonmark.Softbreak"},{"$class":"org.accordproject.ciceromark.Variable","value":"\"Dan\"","name":"seller","elementType":"org.accordproject.party.Party"},{"$class":"org.accordproject.commonmark.Text","text":" (the Seller) shall pay to "},{"$class":"org.accordproject.ciceromark.Variable","value":"\"Steve\"","name":"buyer","elementType":"org.accordproject.party.Party"},{"$class":"org.accordproject.commonmark.Text","text":" (the Buyer) for every "},{"$class":"org.accordproject.ciceromark.Variable","value":"2","name":"amount","elementType":"Long"},{"$class":"org.accordproject.commonmark.Text","text":" "},{"$class":"org.accordproject.commonmark.Softbreak"},{"$class":"org.accordproject.commonmark.Text","text":"of delay penalty amounting to "},{"$class":"org.accordproject.ciceromark.Variable","value":"10.5","name":"penaltyPercentage","elementType":"Double"},{"$class":"org.accordproject.commonmark.Text","text":"% of the total value of the Equipment"},{"$class":"org.accordproject.commonmark.Softbreak"},{"$class":"org.accordproject.commonmark.Text","text":"whose delivery has been delayed. Any fractional part of a "},{"$class":"org.accordproject.commonmark.Text","text":" is to be"},{"$class":"org.accordproject.commonmark.Softbreak"},{"$class":"org.accordproject.commonmark.Text","text":"considered a full "},{"$class":"org.accordproject.commonmark.Text","text":". The total amount of penalty shall not however,"},{"$class":"org.accordproject.commonmark.Softbreak"},{"$class":"org.accordproject.commonmark.Text","text":"exceed "},{"$class":"org.accordproject.ciceromark.Variable","value":"55.0","name":"capPercentage","elementType":"Double"},{"$class":"org.accordproject.commonmark.Text","text":"% of the total value of the Equipment involved in late delivery."},{"$class":"org.accordproject.commonmark.Softbreak"},{"$class":"org.accordproject.commonmark.Text","text":"If the delay is more than "},{"$class":"org.accordproject.ciceromark.Variable","value":"15","name":"amount","elementType":"Long"},{"$class":"org.accordproject.commonmark.Text","text":" "},{"$class":"org.accordproject.commonmark.Text","text":", the Buyer is entitled to terminate this Contract."}]}]}
\ No newline at end of file