From 6da0ed835f589668272db7dc85ac21f99fc41713 Mon Sep 17 00:00:00 2001 From: Matt Sain Date: Wed, 26 Jun 2019 19:32:57 +1000 Subject: [PATCH] Fix code block wrapping whole document (#36) (#49) * Fix code block wrapping whole document (#25) * Fix lint issues --- src/draftjsToMd.js | 141 ++++++++++++++++++++------------------- test/draftjsToMd.test.js | 9 ++- 2 files changed, 79 insertions(+), 71 deletions(-) diff --git a/src/draftjsToMd.js b/src/draftjsToMd.js index 6d8fc4b..865ee2e 100644 --- a/src/draftjsToMd.js +++ b/src/draftjsToMd.js @@ -107,81 +107,82 @@ function getInlineStyleRangesByLength(inlineStyleRanges) { function draftjsToMd(raw, extraMarkdownDict) { const markdownDict = { ...defaultMarkdownDict, ...extraMarkdownDict }; - let returnString = ''; const appliedBlockStyles = []; - // totalOffset is a difference of index position between raw string and enhanced ones - let totalOffset = 0; - - raw.blocks.forEach((block, blockIndex) => { - if (blockIndex !== 0) { - returnString += '\n'; - totalOffset = 0; - } - - // add block style - returnString += getBlockStyle(block.type, appliedBlockStyles); - appliedBlockStyles.push(block.type); - - const appliedStyles = []; - returnString += block.text.split('').reduce((text, currentChar, index) => { - let newText = text; - - const sortedInlineStyleRanges = getInlineStyleRangesByLength(block.inlineStyleRanges); - - // find all styled at this character - const stylesStartAtChar = sortedInlineStyleRanges - .filter(range => range.offset === index) - .filter(range => markdownDict[range.style]); // disregard styles not defined in the md dict - - // add the symbol to the md string and push the style in the applied styles stack - stylesStartAtChar.forEach(currentStyle => { - const symbolLength = markdownDict[currentStyle.style].length; - newText += markdownDict[currentStyle.style]; - totalOffset += symbolLength; - appliedStyles.push({ - symbol: markdownDict[currentStyle.style], - range: { - start: currentStyle.offset + totalOffset, - end: currentStyle.offset + currentStyle.length + totalOffset - }, - end: currentStyle.offset + (currentStyle.length - 1) + return raw.blocks + .map(block => { + // totalOffset is a difference of index position between raw string and enhanced ones + let totalOffset = 0; + let returnString = ''; + + // add block style + returnString += getBlockStyle(block.type, appliedBlockStyles); + appliedBlockStyles.push(block.type); + + const appliedStyles = []; + returnString += block.text.split('').reduce((text, currentChar, index) => { + let newText = text; + + const sortedInlineStyleRanges = getInlineStyleRangesByLength(block.inlineStyleRanges); + + // find all styled at this character + const stylesStartAtChar = sortedInlineStyleRanges + .filter(range => range.offset === index) + .filter(range => markdownDict[range.style]); // disregard styles not defined in the md dict + + // add the symbol to the md string and push the style in the applied styles stack + stylesStartAtChar.forEach(currentStyle => { + const symbolLength = markdownDict[currentStyle.style].length; + newText += markdownDict[currentStyle.style]; + totalOffset += symbolLength; + appliedStyles.push({ + symbol: markdownDict[currentStyle.style], + range: { + start: currentStyle.offset + totalOffset, + end: currentStyle.offset + currentStyle.length + totalOffset + }, + end: currentStyle.offset + (currentStyle.length - 1) + }); }); - }); - - // check for entityRanges starting and add if existing - const entitiesStartAtChar = block.entityRanges.filter(range => range.offset === index); - entitiesStartAtChar.forEach(entity => { - newText += getEntityStart(raw.entityMap[entity.key]); - }); - - // add the current character to the md string - newText += currentChar; - - // check for entityRanges ending and add if existing - const entitiesEndAtChar = block.entityRanges.filter( - range => range.offset + range.length - 1 === index - ); - entitiesEndAtChar.forEach(entity => { - newText += getEntityEnd(raw.entityMap[entity.key]); - }); - - // apply the 'ending' tags for any styles that end in the current position in order (stack) - while (appliedStyles.length !== 0 && appliedStyles[appliedStyles.length - 1].end === index) { - const endingStyle = appliedStyles.pop(); - newText += endingStyle.symbol; - - newText = fixWhitespacesInsideStyle(newText, endingStyle); - totalOffset += endingStyle.symbol.length; - } - return newText; - }, ''); + // check for entityRanges starting and add if existing + const entitiesStartAtChar = block.entityRanges.filter(range => range.offset === index); + entitiesStartAtChar.forEach(entity => { + newText += getEntityStart(raw.entityMap[entity.key]); + }); + + // add the current character to the md string + newText += currentChar; + + // check for entityRanges ending and add if existing + const entitiesEndAtChar = block.entityRanges.filter( + range => range.offset + range.length - 1 === index + ); + entitiesEndAtChar.forEach(entity => { + newText += getEntityEnd(raw.entityMap[entity.key]); + }); + + // apply the 'ending' tags for any styles that end in the current position in order (stack) + while ( + appliedStyles.length !== 0 && + appliedStyles[appliedStyles.length - 1].end === index + ) { + const endingStyle = appliedStyles.pop(); + newText += endingStyle.symbol; + + newText = fixWhitespacesInsideStyle(newText, endingStyle); + totalOffset += endingStyle.symbol.length; + } + + return newText; + }, ''); + + returnString = applyWrappingBlockStyle(block.type, returnString); + returnString = applyAtomicStyle(block, raw.entityMap, returnString); - returnString = applyWrappingBlockStyle(block.type, returnString); - returnString = applyAtomicStyle(block, raw.entityMap, returnString); - }); - return returnString; + return returnString; + }) + .join('\n'); } module.exports.draftjsToMd = draftjsToMd; diff --git a/test/draftjsToMd.test.js b/test/draftjsToMd.test.js index fe5589b..3de05f3 100644 --- a/test/draftjsToMd.test.js +++ b/test/draftjsToMd.test.js @@ -429,6 +429,13 @@ describe('draftjsToMd', () => { it('converts code blocks to markdown correctly', () => { const raw = { blocks: [ + { + text: 'Country Code:', + type: 'unstyled', + depth: 0, + inlineStyleRanges: [], + entityRanges: [] + }, { text: 'const country = Estonia;', type: 'code-block', @@ -438,7 +445,7 @@ describe('draftjsToMd', () => { } ] }; - const expectedMarkdown = '```\nconst country = Estonia;\n```'; + const expectedMarkdown = 'Country Code:\n```\nconst country = Estonia;\n```'; draftjsToMd(raw).should.equal(expectedMarkdown); });