From 00176c6c5e83651f095f7fe22da28b4b21d8f8d1 Mon Sep 17 00:00:00 2001 From: Thomas Allmer Date: Tue, 26 May 2020 16:15:54 +0200 Subject: [PATCH] fix(remark-extend): task order is the same as in provided extend md --- packages/remark-extend/src/remarkExtend.js | 203 +++++++++--------- .../test-node/remark-extend.test.js | 89 ++++---- 2 files changed, 155 insertions(+), 137 deletions(-) diff --git a/packages/remark-extend/src/remarkExtend.js b/packages/remark-extend/src/remarkExtend.js index 7b1f133d0..29b6a31fb 100644 --- a/packages/remark-extend/src/remarkExtend.js +++ b/packages/remark-extend/src/remarkExtend.js @@ -13,35 +13,64 @@ function addTask(file, newAction) { file.data.remarkExtend.push(newAction); } -function findReplacementTasks(tree, file) { - visit(tree, 'code', node => { - if (node.lang === 'js' && node.meta && node.meta.startsWith('::replaceFrom')) { - const startSelector = node.meta.substring( - node.meta.indexOf("('") + 2, - node.meta.indexOf("')"), - ); - addTask(file, { - action: 'replaceFrom', - startSelector, - jsCode: node.value, - }); - } - if (node.lang === 'js' && node.meta && node.meta.startsWith('::replaceBetween')) { - const startSelector = node.meta.substring( - node.meta.indexOf("('") + 2, - node.meta.indexOf("',"), - ); - const endSelector = node.meta - .substring(node.meta.indexOf("',") + 4, node.meta.indexOf("')")) - .trim(); - addTask(file, { - action: 'replaceBetween', - startSelector, - endSelector, - jsCode: node.value, - }); - } - }); +function evaluateAsReplacementTask(node, file) { + if ( + node.type === 'code' && + node.lang === 'js' && + node.meta && + node.meta.startsWith('::replaceFrom') + ) { + const startSelector = node.meta.substring(node.meta.indexOf("('") + 2, node.meta.indexOf("')")); + addTask(file, { + action: 'replaceFrom', + startSelector, + jsCode: node.value, + }); + } + if ( + node.type === 'code' && + node.lang === 'js' && + node.meta && + node.meta.startsWith('::replaceBetween') + ) { + const startSelector = node.meta.substring(node.meta.indexOf("('") + 2, node.meta.indexOf("',")); + const endSelector = node.meta + .substring(node.meta.indexOf("',") + 4, node.meta.indexOf("')")) + .trim(); + addTask(file, { + action: 'replaceBetween', + startSelector, + endSelector, + jsCode: node.value, + }); + } +} + +function evaluateAsRemoveTask(node, file) { + if (node.type === 'code' && node.value && node.value.startsWith('::removeFrom')) { + const startSelector = node.value.substring( + node.value.indexOf("('") + 2, + node.value.indexOf("')"), + ); + addTask(file, { + action: 'removeFrom', + startSelector, + }); + } + if (node.type === 'code' && node.value && node.value.startsWith('::removeBetween')) { + const startSelector = node.value.substring( + node.value.indexOf("('") + 2, + node.value.indexOf("',"), + ); + const endSelector = node.value + .substring(node.value.indexOf("',") + 4, node.value.indexOf("')")) + .trim(); + addTask(file, { + action: 'removeBetween', + startSelector, + endSelector, + }); + } } function shouldFinishGathering(node) { @@ -54,83 +83,63 @@ function shouldFinishGathering(node) { return false; } -function findMdAdditionTasks(tree, file) { - let addNodes = []; - let gathering = false; - let startSelector; - let action = ''; - visit(tree, (node, index, parent) => { - if (gathering === true && shouldFinishGathering(node)) { - gathering = false; - addTask(file, { - action, - startSelector, - addNodes, - }); - addNodes = []; - } - - if (gathering === true) { - if (parent.type === 'root') { - addNodes.push(node); - } - } - - if (node.type === 'code' && node.value && node.value.startsWith('::addMdAfter')) { - startSelector = node.value.substring(node.value.indexOf("('") + 2, node.value.indexOf("')")); - gathering = true; - action = 'addMdAfter'; - } - if (node.type === 'code' && node.value && node.value.startsWith('::addMdBefore')) { - startSelector = node.value.substring(node.value.indexOf("('") + 2, node.value.indexOf("')")); - gathering = true; - action = 'addMdBefore'; - } - }); - - if (gathering === true) { +let mdAdditionAddNodes = []; +let mdAdditionGathering = false; +let mdAdditionStartSelector; +let mdAdditionAction = ''; +function evaluateAsMdAdditionTask(node, file, parent) { + if (mdAdditionGathering === true && shouldFinishGathering(node)) { + mdAdditionGathering = false; addTask(file, { - action, - startSelector, - addNodes, + action: mdAdditionAction, + startSelector: mdAdditionStartSelector, + addNodes: mdAdditionAddNodes, }); + mdAdditionAddNodes = []; } -} -function findRemoveTasks(tree, file) { - visit(tree, 'code', node => { - if (node.value && node.value.startsWith('::removeFrom')) { - const startSelector = node.value.substring( - node.value.indexOf("('") + 2, - node.value.indexOf("')"), - ); - addTask(file, { - action: 'removeFrom', - startSelector, - }); + if (mdAdditionGathering === true) { + if (parent.type === 'root') { + mdAdditionAddNodes.push(node); } - if (node.value && node.value.startsWith('::removeBetween')) { - const startSelector = node.value.substring( - node.value.indexOf("('") + 2, - node.value.indexOf("',"), - ); - const endSelector = node.value - .substring(node.value.indexOf("',") + 4, node.value.indexOf("')")) - .trim(); - addTask(file, { - action: 'removeBetween', - startSelector, - endSelector, - }); - } - }); + } + + if (node.type === 'code' && node.value && node.value.startsWith('::addMdAfter')) { + mdAdditionStartSelector = node.value.substring( + node.value.indexOf("('") + 2, + node.value.indexOf("')"), + ); + mdAdditionGathering = true; + mdAdditionAction = 'addMdAfter'; + } + if (node.type === 'code' && node.value && node.value.startsWith('::addMdBefore')) { + mdAdditionStartSelector = node.value.substring( + node.value.indexOf("('") + 2, + node.value.indexOf("')"), + ); + mdAdditionGathering = true; + mdAdditionAction = 'addMdBefore'; + } } function findExtendTasks() { return (tree, file) => { - findReplacementTasks(tree, file); - findMdAdditionTasks(tree, file); - findRemoveTasks(tree, file); + visit(tree, (node, index, parent) => { + evaluateAsReplacementTask(node, file); + evaluateAsMdAdditionTask(node, file, parent); + evaluateAsRemoveTask(node, file); + }); + + // for evaluateAsMdAdditionTask + if (mdAdditionGathering === true) { + mdAdditionGathering = false; + addTask(file, { + action: mdAdditionAction, + startSelector: mdAdditionStartSelector, + addNodes: mdAdditionAddNodes, + }); + mdAdditionAddNodes = []; + } }; } diff --git a/packages/remark-extend/test-node/remark-extend.test.js b/packages/remark-extend/test-node/remark-extend.test.js index bb2d664c3..b3398da98 100644 --- a/packages/remark-extend/test-node/remark-extend.test.js +++ b/packages/remark-extend/test-node/remark-extend.test.js @@ -88,46 +88,6 @@ describe('remarkExtend', () => { expect(result.contents).to.equal(output); }); - it('does replacements in order of extendMd', async () => { - const input = [ - '### Red', // <-- start - '', - 'red is the fire', - ].join('\n'); - const extendMd = [ - "```js ::replaceFrom(':root')", - 'module.exports.replaceSection = (node) => {', - ' if (node.value) {', - " node.value = node.value.replace(/red/g, 'green').replace(/Red/g, 'Green');", - ' }', - ' return node;', - '};', - '```', - "```js ::replaceFrom(':root')", - 'module.exports.replaceSection = (node) => {', - ' if (node.value) {', - " node.value = node.value.replace(/green/g, 'yellow').replace(/Green/g, 'Yellow');", - ' }', - ' return node;', - '};', - '```', - ].join('\n'); - const output = [ - '

Yellow

', // <-- start - '

yellow is the fire

', - '', - ].join('\n'); - - const parser = unified() - // - .use(markdown) - .use(remarkExtend, { extendMd }) - .use(mdStringify); - const result = await parser.process(input); - - expect(result.contents).to.equal(output); - }); - it('can replace from a starting point downward', async () => { const input = [ '### Red', @@ -622,4 +582,53 @@ describe('remarkExtend', () => { expect(result.contents).to.equal(output); }); + + it('does replacements in order of extendMd', async () => { + const input = [ + '### Red', // <-- start + '', + 'red is the fire', + '### More', + ].join('\n'); + const extendMd = [ + '```', + "::removeBetween('heading:has([value=Red]) + *', 'heading:has([value=Red]) ~ heading')", + '```', + "```js ::replaceFrom(':root')", + 'module.exports.replaceSection = (node) => {', + ' if (node.value) {', + " node.value = node.value.replace(/red/g, 'green').replace(/Red/g, 'Green');", + ' }', + ' return node;', + '};', + '```', + "```js ::replaceFrom(':root')", + 'module.exports.replaceSection = (node) => {', + ' if (node.value) {', + " node.value = node.value.replace(/green/g, 'yellow').replace(/Green/g, 'Yellow');", + ' }', + ' return node;', + '};', + '```', + '```', + "::addMdAfter('heading:has([value=Yellow])')", + '```', + 'This is added', + ].join('\n'); + const output = [ + '

Yellow

', // <-- start + '

This is added

', + '

More

', + '', + ].join('\n'); + + const parser = unified() + // + .use(markdown) + .use(remarkExtend, { extendMd }) + .use(mdStringify); + const result = await parser.process(input); + + expect(result.contents).to.equal(output); + }); });