Skip to content

Commit

Permalink
feat(markdown-docx): add codeblock transformer - #397 (#430)
Browse files Browse the repository at this point in the history
Signed-off-by: k-kumar-01 <[email protected]>
  • Loading branch information
K-Kumar-01 authored Aug 3, 2021
1 parent 2b617d1 commit 1c569bf
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 6 deletions.
82 changes: 77 additions & 5 deletions packages/markdown-docx/src/ToCiceroMarkVisitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,50 @@ class ToCiceroMarkVisitor {
return isBorderPresent;
}

/**
* Checks if the node is a codeblock or not
*
* @param {Array} paragraphProperties paragraph styling properties
* @returns {boolean} true if the node is of type codeblock or else, false
*/
checkCodeBlockProperties(paragraphProperties) {
let isDesiredTopBorderPresent = false;
let isDesiredBottomBorderPresent = false;
let isDesiredLeftBorderPresent = false;
let isDesiredRightBorderPresent = false;
let isDesiredShadePresent = false;

for (const property of paragraphProperties) {
if (property.name === 'w:pBdr') {
// do something
for (const borderProperty of property.elements) {
if (borderProperty.attributes['w:color'] === 'CCCCCC') {
if (borderProperty.name === 'w:top') {
isDesiredTopBorderPresent = true;
} else if (borderProperty.name === 'w:bottom') {
isDesiredBottomBorderPresent = true;
} else if (borderProperty.name === 'w:left') {
isDesiredLeftBorderPresent = true;
} else if (borderProperty.name === 'w:right') {
isDesiredRightBorderPresent = true;
}
}
}
} else if (property.name === 'w:shd') {
if (property.attributes['w:fill'] === 'F8F8F8') {
isDesiredShadePresent = true;
}
}
}
return (
isDesiredTopBorderPresent &&
isDesiredBottomBorderPresent &&
isDesiredLeftBorderPresent &&
isDesiredRightBorderPresent &&
isDesiredShadePresent
);
}

/**
* Constructs a ciceroMark Node for inline element from the information.
*
Expand Down Expand Up @@ -213,10 +257,13 @@ class ToCiceroMarkVisitor {
/**
* Traverses for properties and value.
*
* @param {Array} node Node to be traversed
* @param {object} nodeInformation Information for the current node
* @param {Array} node Node to be traversed
* @param {object} nodeInformation Information for the current node
* @param {Boolean} calledByCodeBlock Is function called by codeblock checker
* @returns {string} Value in <w:t> tags
*/
fetchFormattingProperties(node, nodeInformation) {
fetchFormattingProperties(node, nodeInformation, calledByCodeBlock = false) {
let ooxmlTagTextValue = '';
for (const runTimeNodes of node.elements) {
if (runTimeNodes.name === 'w:rPr') {
let colorCodePresent = false;
Expand Down Expand Up @@ -245,13 +292,21 @@ class ToCiceroMarkVisitor {
nodeInformation.nodeType = TRANSFORMED_NODES.code;
}
} else if (runTimeNodes.name === 'w:t') {
nodeInformation.value = runTimeNodes.elements ? runTimeNodes.elements[0].text : ' ';
this.JSONXML = [...this.JSONXML, nodeInformation];
if (calledByCodeBlock) {
ooxmlTagTextValue += runTimeNodes.elements ? runTimeNodes.elements[0].text : '';
} else {
ooxmlTagTextValue = runTimeNodes.elements ? runTimeNodes.elements[0].text : ' ';
nodeInformation.value = ooxmlTagTextValue;
this.JSONXML = [...this.JSONXML, nodeInformation];
}
} else if (runTimeNodes.name === 'w:br') {
ooxmlTagTextValue += '\n';
} else if (runTimeNodes.name === 'w:sym') {
nodeInformation.nodeType = TRANSFORMED_NODES.softbreak;
this.JSONXML = [...this.JSONXML, nodeInformation];
}
}
return ooxmlTagTextValue;
}

/**
Expand All @@ -273,6 +328,23 @@ class ToCiceroMarkVisitor {

const isThematicBreak = this.checkThematicBreakProperties(subNode.elements[0].elements);

const isCodeBlock = this.checkCodeBlockProperties(subNode.elements[0].elements);

if (isCodeBlock) {
let text = '';
for (const codeBlockSubNode of subNode.elements) {
if (codeBlockSubNode.name === 'w:r') {
text = this.fetchFormattingProperties(codeBlockSubNode, undefined, true);
}
}
const codeBlockNode = {
$class: TRANSFORMED_NODES.codeBlock,
text,
};
this.nodes = [...this.nodes, codeBlockNode];
continue;
}

if (isThematicBreak) {
const thematicBreakNode = {
$class: TRANSFORMED_NODES.thematicBreak,
Expand Down
18 changes: 17 additions & 1 deletion packages/markdown-docx/src/ToOOXMLVisitor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ const {
STRONG_RULE,
CODE_PROPERTIES_RULE,
THEMATICBREAK_RULE,
CODEBLOCK_PROPERTIES_RULE,
CODEBLOCK_FONTPROPERTIES_RULE,
} = require('./rules');
const { wrapAroundDefaultDocxTags } = require('./helpers');
const { TRANSFORMED_NODES } = require('../constants');
Expand Down Expand Up @@ -99,6 +101,20 @@ class ToOOXMLVisitor {

let tag = TEXT_WRAPPER_RULE(propertyTag, textValueTag);
this.tags = [...this.tags, tag];
} else if (this.getClass(subNode) === TRANSFORMED_NODES.codeBlock) {
let ooxml = CODEBLOCK_PROPERTIES_RULE();
let textValues = subNode.text.split('\n');
let textValueTag = '';
for (let textValueIndex = 0; textValueIndex < textValues.length; textValueIndex++) {
textValueTag += TEXT_RULE(textValues[textValueIndex]);
if (textValueIndex !== textValues.length - 1) {
textValueTag += '<w:br />';
}
}
let textPropertyTag = TEXT_STYLES_RULE(CODEBLOCK_FONTPROPERTIES_RULE());
ooxml += TEXT_WRAPPER_RULE(textPropertyTag, textValueTag);

this.globalOOXML += PARAGRAPH_RULE(ooxml);
} else if (this.getClass(subNode) === TRANSFORMED_NODES.variable) {
const tag = subNode.name;
const type = subNode.elementType;
Expand All @@ -122,7 +138,7 @@ class ToOOXMLVisitor {
this.tags = [...this.tags, VARIABLE_RULE(title, tag, value, type)];
} else if (this.getClass(subNode) === TRANSFORMED_NODES.softbreak) {
this.tags = [...this.tags, SOFTBREAK_RULE()];
} else if(this.getClass(subNode) === TRANSFORMED_NODES.thematicBreak){
} else if (this.getClass(subNode) === TRANSFORMED_NODES.thematicBreak) {
this.globalOOXML += THEMATICBREAK_RULE();
} else {
if (subNode.nodes) {
Expand Down
20 changes: 20 additions & 0 deletions packages/markdown-docx/src/ToOOXMLVisitor/rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,24 @@ const CODE_PROPERTIES_RULE = () => {
`;
};

const CODEBLOCK_FONTPROPERTIES_RULE = () => {
return '<w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New"/>';
};

const CODEBLOCK_PROPERTIES_RULE = () => {
return `
<w:pPr>
<w:pBdr>
<w:top w:val="single" w:sz="4" w:space="1" w:color="CCCCCC" />
<w:left w:val="single" w:sz="4" w:space="4" w:color="CCCCCC" />
<w:bottom w:val="single" w:sz="4" w:space="1" w:color="CCCCCC" />
<w:right w:val="single" w:sz="4" w:space="4" w:color="CCCCCC" />
</w:pBdr>
<w:shd w:val="clear" w:color="auto" w:fill="F8F8F8"/>
</w:pPr>
`;
};

const LINEBREAK_RULE = () => {
return '<w:p/>';
};
Expand Down Expand Up @@ -197,5 +215,7 @@ module.exports = {
SOFTBREAK_RULE,
STRONG_RULE,
CODE_PROPERTIES_RULE,
CODEBLOCK_PROPERTIES_RULE,
CODEBLOCK_FONTPROPERTIES_RULE,
THEMATICBREAK_RULE,
};
1 change: 1 addition & 0 deletions packages/markdown-docx/src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const { NS_PREFIX_CiceroMarkModel } = require('@accordproject/markdown-cicero').

const TRANSFORMED_NODES = {
code: `${NS_PREFIX_CommonMarkModel}Code`,
codeBlock: `${NS_PREFIX_CommonMarkModel}CodeBlock`,
computedVariable: `${NS_PREFIX_CiceroMarkModel}ComputedVariable`,
document: `${NS_PREFIX_CommonMarkModel}Document`,
emphasize: `${NS_PREFIX_CommonMarkModel}Emph`,
Expand Down
1 change: 1 addition & 0 deletions packages/markdown-docx/test/data/ciceroMark/codeblock.json
Original file line number Diff line number Diff line change
@@ -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":"just testing some"}]},{"$class":"org.accordproject.commonmark.CodeBlock","text":"Let us try some sentences to see whether we are able to convert the above\ninto an ooxml document **using some** of the techniques we have already encountered.\nlets hope for the best\n"}]}

0 comments on commit 1c569bf

Please sign in to comment.