fix(remark-extend): task order is the same as in provided extend md

This commit is contained in:
Thomas Allmer 2020-05-26 16:15:54 +02:00 committed by Thomas Allmer
parent 20146d54bf
commit 00176c6c5e
2 changed files with 155 additions and 137 deletions

View file

@ -13,35 +13,64 @@ function addTask(file, newAction) {
file.data.remarkExtend.push(newAction); file.data.remarkExtend.push(newAction);
} }
function findReplacementTasks(tree, file) { function evaluateAsReplacementTask(node, file) {
visit(tree, 'code', node => { if (
if (node.lang === 'js' && node.meta && node.meta.startsWith('::replaceFrom')) { node.type === 'code' &&
const startSelector = node.meta.substring( node.lang === 'js' &&
node.meta.indexOf("('") + 2, node.meta &&
node.meta.indexOf("')"), node.meta.startsWith('::replaceFrom')
); ) {
addTask(file, { const startSelector = node.meta.substring(node.meta.indexOf("('") + 2, node.meta.indexOf("')"));
action: 'replaceFrom', addTask(file, {
startSelector, action: 'replaceFrom',
jsCode: node.value, startSelector,
}); jsCode: node.value,
} });
if (node.lang === 'js' && node.meta && node.meta.startsWith('::replaceBetween')) { }
const startSelector = node.meta.substring( if (
node.meta.indexOf("('") + 2, node.type === 'code' &&
node.meta.indexOf("',"), node.lang === 'js' &&
); node.meta &&
const endSelector = node.meta node.meta.startsWith('::replaceBetween')
.substring(node.meta.indexOf("',") + 4, node.meta.indexOf("')")) ) {
.trim(); const startSelector = node.meta.substring(node.meta.indexOf("('") + 2, node.meta.indexOf("',"));
addTask(file, { const endSelector = node.meta
action: 'replaceBetween', .substring(node.meta.indexOf("',") + 4, node.meta.indexOf("')"))
startSelector, .trim();
endSelector, addTask(file, {
jsCode: node.value, 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) { function shouldFinishGathering(node) {
@ -54,83 +83,63 @@ function shouldFinishGathering(node) {
return false; return false;
} }
function findMdAdditionTasks(tree, file) { let mdAdditionAddNodes = [];
let addNodes = []; let mdAdditionGathering = false;
let gathering = false; let mdAdditionStartSelector;
let startSelector; let mdAdditionAction = '';
let action = ''; function evaluateAsMdAdditionTask(node, file, parent) {
visit(tree, (node, index, parent) => { if (mdAdditionGathering === true && shouldFinishGathering(node)) {
if (gathering === true && shouldFinishGathering(node)) { mdAdditionGathering = false;
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) {
addTask(file, { addTask(file, {
action, action: mdAdditionAction,
startSelector, startSelector: mdAdditionStartSelector,
addNodes, addNodes: mdAdditionAddNodes,
}); });
mdAdditionAddNodes = [];
} }
}
function findRemoveTasks(tree, file) { if (mdAdditionGathering === true) {
visit(tree, 'code', node => { if (parent.type === 'root') {
if (node.value && node.value.startsWith('::removeFrom')) { mdAdditionAddNodes.push(node);
const startSelector = node.value.substring(
node.value.indexOf("('") + 2,
node.value.indexOf("')"),
);
addTask(file, {
action: 'removeFrom',
startSelector,
});
} }
if (node.value && node.value.startsWith('::removeBetween')) { }
const startSelector = node.value.substring(
node.value.indexOf("('") + 2, if (node.type === 'code' && node.value && node.value.startsWith('::addMdAfter')) {
node.value.indexOf("',"), mdAdditionStartSelector = node.value.substring(
); node.value.indexOf("('") + 2,
const endSelector = node.value node.value.indexOf("')"),
.substring(node.value.indexOf("',") + 4, node.value.indexOf("')")) );
.trim(); mdAdditionGathering = true;
addTask(file, { mdAdditionAction = 'addMdAfter';
action: 'removeBetween', }
startSelector, if (node.type === 'code' && node.value && node.value.startsWith('::addMdBefore')) {
endSelector, mdAdditionStartSelector = node.value.substring(
}); node.value.indexOf("('") + 2,
} node.value.indexOf("')"),
}); );
mdAdditionGathering = true;
mdAdditionAction = 'addMdBefore';
}
} }
function findExtendTasks() { function findExtendTasks() {
return (tree, file) => { return (tree, file) => {
findReplacementTasks(tree, file); visit(tree, (node, index, parent) => {
findMdAdditionTasks(tree, file); evaluateAsReplacementTask(node, file);
findRemoveTasks(tree, file); evaluateAsMdAdditionTask(node, file, parent);
evaluateAsRemoveTask(node, file);
});
// for evaluateAsMdAdditionTask
if (mdAdditionGathering === true) {
mdAdditionGathering = false;
addTask(file, {
action: mdAdditionAction,
startSelector: mdAdditionStartSelector,
addNodes: mdAdditionAddNodes,
});
mdAdditionAddNodes = [];
}
}; };
} }

View file

@ -88,46 +88,6 @@ describe('remarkExtend', () => {
expect(result.contents).to.equal(output); 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 = [
'<h3>Yellow</h3>', // <-- start
'<p>yellow is the fire</p>',
'',
].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 () => { it('can replace from a starting point downward', async () => {
const input = [ const input = [
'### Red', '### Red',
@ -622,4 +582,53 @@ describe('remarkExtend', () => {
expect(result.contents).to.equal(output); 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 = [
'<h3>Yellow</h3>', // <-- start
'<p>This is added</p>',
'<h3>More</h3>',
'',
].join('\n');
const parser = unified()
//
.use(markdown)
.use(remarkExtend, { extendMd })
.use(mdStringify);
const result = await parser.process(input);
expect(result.contents).to.equal(output);
});
}); });