diff --git a/packages/markdown-docx/src/CiceroMarkToOOXML/index.js b/packages/markdown-docx/src/CiceroMarkToOOXML/index.js index 86629091..ed879247 100644 --- a/packages/markdown-docx/src/CiceroMarkToOOXML/index.js +++ b/packages/markdown-docx/src/CiceroMarkToOOXML/index.js @@ -14,7 +14,7 @@ 'use strict'; -const { TEXT_RULE, EMPHASIS_RULE } = require('./rules'); +const { TEXT_RULE, EMPHASIS_RULE, HEADING_RULE } = require('./rules'); const { wrapAroundDefaultDocxTags } = require('./helpers'); const definedNodes = { @@ -34,8 +34,6 @@ const definedNodes = { * Transforms the ciceromark to OOXML */ class CiceroMarkToOOXMLTransfomer { - - /** * Declares the OOXML variable */ @@ -63,6 +61,9 @@ class CiceroMarkToOOXMLTransfomer { */ getNodes(node, counter, parent = null) { if (this.getClass(node) === definedNodes.text) { + if (parent !== null && parent.class === definedNodes.heading) { + return HEADING_RULE(node.text, parent.level); + } if (parent !== null && parent.class === definedNodes.emphasize) { return EMPHASIS_RULE(node.text, true); } else { @@ -78,10 +79,23 @@ class CiceroMarkToOOXMLTransfomer { return ooxml; } + if (this.getClass(node) === definedNodes.heading) { + let ooxml = ''; + node.nodes.forEach(subNode => { + ooxml += this.getNodes(subNode, counter, { class: node.$class, level: node.level }); + }); + this.globalOOXML = ` + ${this.globalOOXML} + + ${ooxml} + + `; + } + if (this.getClass(node) === definedNodes.paragraph) { let ooxml = ''; node.nodes.forEach(subNode => { - ooxml += this.getNodes(subNode, counter,); + ooxml += this.getNodes(subNode, counter); }); this.globalOOXML = `${this.globalOOXML}${ooxml}`; } diff --git a/packages/markdown-docx/src/CiceroMarkToOOXML/index.test.js b/packages/markdown-docx/src/CiceroMarkToOOXML/index.test.js index 233f5cf5..ef7d1ac3 100644 --- a/packages/markdown-docx/src/CiceroMarkToOOXML/index.test.js +++ b/packages/markdown-docx/src/CiceroMarkToOOXML/index.test.js @@ -40,4 +40,20 @@ describe('Perform roundtripping between CiceroMark and OOXML', () => { const convertedObject = ooxmlTransformer.toCiceroMark(ooxml); expect(convertedObject).to.deep.equal(textAndEmphasisCiceroMark); }); + + it('should parse text and heading nodes.', async () => { + let textandHeadingCiceroMark = await fs.readFileSync( + 'test/data/ciceroMark/text-and-heading.json', + 'utf-8' + ); + // converts from string to JSON object + textandHeadingCiceroMark = JSON.parse(textandHeadingCiceroMark); + + const ciceroMarkTransformer = new CiceroMarkToOOXMLTransfomer(); + const ooxml = ciceroMarkTransformer.toOOXML(textandHeadingCiceroMark); + + const ooxmlTransformer = new OoxmlTransformer(); + const convertedObject = ooxmlTransformer.toCiceroMark(ooxml); + expect(convertedObject).to.deep.equal(textandHeadingCiceroMark); + }); }); diff --git a/packages/markdown-docx/src/CiceroMarkToOOXML/rules.js b/packages/markdown-docx/src/CiceroMarkToOOXML/rules.js index d9ff161f..b2d47296 100644 --- a/packages/markdown-docx/src/CiceroMarkToOOXML/rules.js +++ b/packages/markdown-docx/src/CiceroMarkToOOXML/rules.js @@ -47,4 +47,35 @@ const EMPHASIS_RULE = (value) => { `; }; -module.exports = { TEXT_RULE, EMPHASIS_RULE }; +/** + * Transforms the given heading node into OOXML heading. + * + * @param {string} value Text to be rendered as heading + * @param {number} level Level of heading - ranges from 1 to 6 + * @returns {string} OOXMl for heading + * + */ +const HEADING_RULE = (value, level) => { + const definedLevels = { + 1: { style: 'Heading1', size: 25 }, + 2: { style: 'Heading2', size: 20 }, + 3: { style: 'Heading3', size: 16 }, + 4: { style: 'Heading4', size: 16 }, + 5: { style: 'Heading5', size: 16 }, + 6: { style: 'Heading6', size: 16 }, + }; + + return ` + + + + + + + + ${sanitizeHtmlChars(value)} + + `; +}; + +module.exports = { TEXT_RULE, EMPHASIS_RULE, HEADING_RULE }; diff --git a/packages/markdown-docx/test/data/ciceroMark/text-and-heading.json b/packages/markdown-docx/test/data/ciceroMark/text-and-heading.json new file mode 100644 index 00000000..4a2f8ad6 --- /dev/null +++ b/packages/markdown-docx/test/data/ciceroMark/text-and-heading.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":"Try TemplateMark"}]},{"$class":"org.accordproject.commonmark.Paragraph","nodes":[{"$class":"org.accordproject.commonmark.Text","text":"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries,"}]},{"$class":"org.accordproject.commonmark.Heading","level":"3","nodes":[{"$class":"org.accordproject.commonmark.Text","text":"Heading level 3"}]},{"$class":"org.accordproject.commonmark.Paragraph","nodes":[{"$class":"org.accordproject.commonmark.Text","text":"hello there"}]},{"$class":"org.accordproject.commonmark.Heading","level":"1","nodes":[{"$class":"org.accordproject.commonmark.Text","text":"Level 1 heading"}]},{"$class":"org.accordproject.commonmark.Paragraph","nodes":[{"$class":"org.accordproject.commonmark.Text","text":"Some more text here."}]},{"$class":"org.accordproject.commonmark.Heading","level":"4","nodes":[{"$class":"org.accordproject.commonmark.Text","text":"Level 4"}]},{"$class":"org.accordproject.commonmark.Heading","level":"5","nodes":[{"$class":"org.accordproject.commonmark.Text","text":"5th lvl"}]},{"$class":"org.accordproject.commonmark.Paragraph","nodes":[{"$class":"org.accordproject.commonmark.Text","text":"and last but not least, a"}]},{"$class":"org.accordproject.commonmark.Heading","level":"6","nodes":[{"$class":"org.accordproject.commonmark.Text","text":"level 6 heading"}]}]} \ No newline at end of file