From 7651099cfb5b25e142ce63c4a2e40f0256dc0404 Mon Sep 17 00:00:00 2001
From: Kushal Kumar <59891164+K-Kumar-01@users.noreply.github.com>
Date: Fri, 11 Jun 2021 17:20:20 +0530
Subject: [PATCH] feat: add text and emphasis transformers - #397 (#401)
---
.../src/CiceroMarkToOOXML/helpers.js | 88 ++++++++++++++
.../src/CiceroMarkToOOXML/index.js | 109 ++++++++++++++++++
.../src/CiceroMarkToOOXML/index.test.js | 43 +++++++
.../src/CiceroMarkToOOXML/rules.js | 50 ++++++++
.../src/CiceroMarkToOOXMLTransformer.js | 49 --------
.../index.js} | 15 +++
.../index.test.js} | 2 +-
packages/markdown-docx/src/index.js | 17 +++
.../data/ciceroMark/text-and-emphasis.json | 1 +
9 files changed, 324 insertions(+), 50 deletions(-)
create mode 100644 packages/markdown-docx/src/CiceroMarkToOOXML/helpers.js
create mode 100644 packages/markdown-docx/src/CiceroMarkToOOXML/index.js
create mode 100644 packages/markdown-docx/src/CiceroMarkToOOXML/index.test.js
create mode 100644 packages/markdown-docx/src/CiceroMarkToOOXML/rules.js
delete mode 100644 packages/markdown-docx/src/CiceroMarkToOOXMLTransformer.js
rename packages/markdown-docx/src/{OoxmlTransformer.js => OOXMLTransformer/index.js} (92%)
rename packages/markdown-docx/src/{OoxmlTransformer.test.js => OOXMLTransformer/index.test.js} (95%)
create mode 100644 packages/markdown-docx/src/index.js
create mode 100644 packages/markdown-docx/test/data/ciceroMark/text-and-emphasis.json
diff --git a/packages/markdown-docx/src/CiceroMarkToOOXML/helpers.js b/packages/markdown-docx/src/CiceroMarkToOOXML/helpers.js
new file mode 100644
index 00000000..a7f1ae06
--- /dev/null
+++ b/packages/markdown-docx/src/CiceroMarkToOOXML/helpers.js
@@ -0,0 +1,88 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+'use strict';
+
+/**
+ * Replaces the angular brackets with the respective codes.
+ *
+ * @param {string} node String to be replaced
+ * @returns {string} String with replaced angular brackets
+ */
+function sanitizeHtmlChars(node) {
+ return node.replace(/>/g, '>').replace(/
+
+
+
+
+
+
+
+
+
+
+
+ ${ooxml}
+
+
+
+
+
+ `;
+
+ return ooxml;
+}
+
+module.exports = { sanitizeHtmlChars, wrapAroundDefaultDocxTags };
diff --git a/packages/markdown-docx/src/CiceroMarkToOOXML/index.js b/packages/markdown-docx/src/CiceroMarkToOOXML/index.js
new file mode 100644
index 00000000..86629091
--- /dev/null
+++ b/packages/markdown-docx/src/CiceroMarkToOOXML/index.js
@@ -0,0 +1,109 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+'use strict';
+
+const { TEXT_RULE, EMPHASIS_RULE } = require('./rules');
+const { wrapAroundDefaultDocxTags } = require('./helpers');
+
+const definedNodes = {
+ computedVariable: 'org.accordproject.ciceromark.ComputedVariable',
+ heading: 'org.accordproject.commonmark.Heading',
+ item: 'org.accordproject.commonmark.Item',
+ list: 'org.accordproject.commonmark.List',
+ listBlock: 'org.accordproject.ciceromark.ListBlock',
+ paragraph: 'org.accordproject.commonmark.Paragraph',
+ softbreak: 'org.accordproject.commonmark.Softbreak',
+ text: 'org.accordproject.commonmark.Text',
+ variable: 'org.accordproject.ciceromark.Variable',
+ emphasize: 'org.accordproject.commonmark.Emph',
+};
+
+/**
+ * Transforms the ciceromark to OOXML
+ */
+class CiceroMarkToOOXMLTransfomer {
+
+
+ /**
+ * Declares the OOXML variable
+ */
+ constructor() {
+ this.globalOOXML = '';
+ }
+
+ /**
+ * Gets the class of a given CiceroMark node.
+ *
+ * @param {object} node CiceroMark node entity
+ * @returns {string} Class of given node
+ */
+ getClass(node) {
+ return node.$class;
+ }
+
+ /**
+ * Gets the OOXML for the given node.
+ *
+ * @param {object} node Description of node type
+ * @param {object} counter Counter for different variables based on node name
+ * @param {object} parent Parent object for a node
+ * @returns {string} OOXML for the given node
+ */
+ getNodes(node, counter, parent = null) {
+ if (this.getClass(node) === definedNodes.text) {
+ if (parent !== null && parent.class === definedNodes.emphasize) {
+ return EMPHASIS_RULE(node.text, true);
+ } else {
+ return TEXT_RULE(node.text);
+ }
+ }
+
+ if (this.getClass(node) === definedNodes.emphasize) {
+ let ooxml = '';
+ node.nodes.forEach(subNode => {
+ ooxml += this.getNodes(subNode, counter, { class: node.$class });
+ });
+ return ooxml;
+ }
+
+ if (this.getClass(node) === definedNodes.paragraph) {
+ let ooxml = '';
+ node.nodes.forEach(subNode => {
+ ooxml += this.getNodes(subNode, counter,);
+ });
+ this.globalOOXML = `${this.globalOOXML}${ooxml}`;
+ }
+ return '';
+ }
+
+ /**
+ * Transforms the given CiceroMark JSON to OOXML
+ *
+ * @param {Object} ciceromark CiceroMark JSON to be converted
+ * @param {Object} counter Counter for different variables based on node name
+ * @param {string} ooxml Initial OOXML string
+ * @returns {string} Converted OOXML string i.e. CicecoMark->OOXML
+ */
+ toOOXML(ciceromark, counter, ooxml = '') {
+ this.globalOOXML = ooxml;
+ ciceromark.nodes.forEach(node => {
+ this.getNodes(node, counter);
+ });
+ this.globalOOXML = wrapAroundDefaultDocxTags(this.globalOOXML);
+ return this.globalOOXML;
+ }
+}
+
+module.exports = CiceroMarkToOOXMLTransfomer;
diff --git a/packages/markdown-docx/src/CiceroMarkToOOXML/index.test.js b/packages/markdown-docx/src/CiceroMarkToOOXML/index.test.js
new file mode 100644
index 00000000..233f5cf5
--- /dev/null
+++ b/packages/markdown-docx/src/CiceroMarkToOOXML/index.test.js
@@ -0,0 +1,43 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// @ts-nocheck
+/* eslint-disable no-undef */
+'use strict';
+
+const fs = require('fs');
+const chai = require('chai');
+
+const expect = chai.expect;
+
+const OoxmlTransformer = require('../OOXMLTransformer');
+const CiceroMarkToOOXMLTransfomer = require('.');
+
+describe('Perform roundtripping between CiceroMark and OOXML', () => {
+ it('should parse textgraphs and emphasis nodes.', async () => {
+ let textAndEmphasisCiceroMark = await fs.readFileSync(
+ 'test/data/ciceroMark/text-and-emphasis.json',
+ 'utf-8'
+ );
+ // converts from string to JSON object
+ textAndEmphasisCiceroMark = JSON.parse(textAndEmphasisCiceroMark);
+
+ const ciceroMarkTransformer = new CiceroMarkToOOXMLTransfomer();
+ const ooxml = ciceroMarkTransformer.toOOXML(textAndEmphasisCiceroMark);
+
+ const ooxmlTransformer = new OoxmlTransformer();
+ const convertedObject = ooxmlTransformer.toCiceroMark(ooxml);
+ expect(convertedObject).to.deep.equal(textAndEmphasisCiceroMark);
+ });
+});
diff --git a/packages/markdown-docx/src/CiceroMarkToOOXML/rules.js b/packages/markdown-docx/src/CiceroMarkToOOXML/rules.js
new file mode 100644
index 00000000..d9ff161f
--- /dev/null
+++ b/packages/markdown-docx/src/CiceroMarkToOOXML/rules.js
@@ -0,0 +1,50 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+'use strict';
+
+const { sanitizeHtmlChars } = require('./helpers');
+
+/**
+ * Inserts text.
+ *
+ * @param {string} value Enclosing value of the OOXML tag
+ * @returns {string} OOXML tag for the text
+ */
+const TEXT_RULE = (value) => {
+ return `
+
+ ${sanitizeHtmlChars(value)}
+
+ `;
+};
+
+/**
+ * Inserts emphasised text.
+ *
+ * @param {string} value Enclosing value of the OOXML tag
+ * @returns {string} OOXML tag for the emphasised text
+ */
+const EMPHASIS_RULE = (value) => {
+ return `
+
+
+
+
+ ${sanitizeHtmlChars(value)}
+
+ `;
+};
+
+module.exports = { TEXT_RULE, EMPHASIS_RULE };
diff --git a/packages/markdown-docx/src/CiceroMarkToOOXMLTransformer.js b/packages/markdown-docx/src/CiceroMarkToOOXMLTransformer.js
deleted file mode 100644
index c6335689..00000000
--- a/packages/markdown-docx/src/CiceroMarkToOOXMLTransformer.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-'use strict';
-
-/**
- * Transforms the ciceromark to OOXML
- */
-class CiceroMarkToOOXMLTransfomer {
-
- definedNodes = {
- computedVariable: 'org.accordproject.ciceromark.ComputedVariable',
- heading: 'org.accordproject.commonmark.Heading',
- item: 'org.accordproject.commonmark.Item',
- list: 'org.accordproject.commonmark.List',
- listBlock: 'org.accordproject.ciceromark.ListBlock',
- paragraph: 'org.accordproject.commonmark.Paragraph',
- softbreak: 'org.accordproject.commonmark.Softbreak',
- text: 'org.accordproject.commonmark.Text',
- variable: 'org.accordproject.ciceromark.Variable',
- emphasize: 'org.accordproject.commonmark.Emph',
- };
-
- /**
- * Transforms the given CiceroMark JSON to OOXML
- *
- * @param {Object} ciceromark CiceroMark JSON to be converted
- * @param {Object} counter Counter for different variables based on node name
- * @param {string} ooxml Initial OOXML string
- * @returns {string} Converted OOXML string i.e. CicecoMark->OOXML
- */
- toOOXML(ciceromark, counter, ooxml) {
- let globalOOXML = ooxml;
- return globalOOXML;
- }
-}
-
-module.exports = CiceroMarkToOOXMLTransfomer;
\ No newline at end of file
diff --git a/packages/markdown-docx/src/OoxmlTransformer.js b/packages/markdown-docx/src/OOXMLTransformer/index.js
similarity index 92%
rename from packages/markdown-docx/src/OoxmlTransformer.js
rename to packages/markdown-docx/src/OOXMLTransformer/index.js
index 2fcde302..b6af73d2 100644
--- a/packages/markdown-docx/src/OoxmlTransformer.js
+++ b/packages/markdown-docx/src/OOXMLTransformer/index.js
@@ -151,6 +151,21 @@ class OoxmlTransformer {
$class: `${NS_PREFIX_CommonMarkModel}Softbreak`,
};
case 'w:r':
+ if (element.elements[0].name === 'w:rPr') {
+ let emphasisedTextFound = element.elements[0].elements.some(
+ subElement => {
+ return subElement.name === 'w:i';
+ }
+ );
+ if (emphasisedTextFound) {
+ return {
+ $class: `${NS_PREFIX_CommonMarkModel}Emph`,
+ nodes: [
+ ...this.deserializeElements(element.elements),
+ ],
+ };
+ }
+ }
return [...this.deserializeElements(element.elements)];
case 'w:color':
return element.attributes['w:color'];
diff --git a/packages/markdown-docx/src/OoxmlTransformer.test.js b/packages/markdown-docx/src/OOXMLTransformer/index.test.js
similarity index 95%
rename from packages/markdown-docx/src/OoxmlTransformer.test.js
rename to packages/markdown-docx/src/OOXMLTransformer/index.test.js
index 5fe7c24c..f0740bb7 100644
--- a/packages/markdown-docx/src/OoxmlTransformer.test.js
+++ b/packages/markdown-docx/src/OOXMLTransformer/index.test.js
@@ -19,7 +19,7 @@ const chai = require('chai');
const expect = chai.expect;
-const OoxmlTransformer = require('./OoxmlTransformer');
+const OoxmlTransformer = require('.');
describe('OOXML -> CiceroMark', () => {
diff --git a/packages/markdown-docx/src/index.js b/packages/markdown-docx/src/index.js
new file mode 100644
index 00000000..ed611a3f
--- /dev/null
+++ b/packages/markdown-docx/src/index.js
@@ -0,0 +1,17 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+'use strict';
+
+module.exports.CiceroMarkToOOXMLTransfomer= require('./CiceroMarkToOOXML');
diff --git a/packages/markdown-docx/test/data/ciceroMark/text-and-emphasis.json b/packages/markdown-docx/test/data/ciceroMark/text-and-emphasis.json
new file mode 100644
index 00000000..b1198879
--- /dev/null
+++ b/packages/markdown-docx/test/data/ciceroMark/text-and-emphasis.json
@@ -0,0 +1 @@
+{"$class":"org.accordproject.commonmark.Document","xmlns":"http://commonmark.org/xml/1.0","nodes":[{"$class":"org.accordproject.commonmark.Paragraph","nodes":[{"$class":"org.accordproject.commonmark.Text","text":"Hello and Welcome to the testing round. Today we try "},{"$class":"org.accordproject.commonmark.Emph","nodes":[{"$class":"org.accordproject.commonmark.Text","text":"testing"}]},{"$class":"org.accordproject.commonmark.Text","text":" of the converters."}]},{"$class":"org.accordproject.commonmark.Paragraph","nodes":[{"$class":"org.accordproject.commonmark.Text","text":"Let\"s start with the basic testing of the converters."}]},{"$class":"org.accordproject.commonmark.Paragraph","nodes":[{"$class":"org.accordproject.commonmark.Text","text":"The Accord Project is a non-profit, collaborative, initiative developing an ecosystem and open source tools specifically for smart legal contracts. Open source means that anyone can freely use and contribute to development."}]},{"$class":"org.accordproject.commonmark.Paragraph","nodes":[{"$class":"org.accordproject.commonmark.Text","text":"We hope to see many more successful tests."}]}]}
\ No newline at end of file