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,24 +13,27 @@ 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("')"),
);
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.lang === 'js' && node.meta && node.meta.startsWith('::replaceBetween')) {
const startSelector = node.meta.substring(
node.meta.indexOf("('") + 2,
node.meta.indexOf("',"),
);
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();
@ -41,65 +44,10 @@ function findReplacementTasks(tree, file) {
jsCode: node.value,
});
}
});
}
function shouldFinishGathering(node) {
if (node.type === 'code' && node.lang === 'js' && node.meta && node.meta.startsWith('::')) {
return true;
}
if (node.value && node.value.startsWith('::')) {
return true;
}
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) {
addTask(file, {
action,
startSelector,
addNodes,
});
}
}
function findRemoveTasks(tree, file) {
visit(tree, 'code', node => {
if (node.value && node.value.startsWith('::removeFrom')) {
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("')"),
@ -109,7 +57,7 @@ function findRemoveTasks(tree, file) {
startSelector,
});
}
if (node.value && node.value.startsWith('::removeBetween')) {
if (node.type === 'code' && node.value && node.value.startsWith('::removeBetween')) {
const startSelector = node.value.substring(
node.value.indexOf("('") + 2,
node.value.indexOf("',"),
@ -123,14 +71,75 @@ function findRemoveTasks(tree, file) {
endSelector,
});
}
}
function shouldFinishGathering(node) {
if (node.type === 'code' && node.lang === 'js' && node.meta && node.meta.startsWith('::')) {
return true;
}
if (node.value && node.value.startsWith('::')) {
return true;
}
return false;
}
let mdAdditionAddNodes = [];
let mdAdditionGathering = false;
let mdAdditionStartSelector;
let mdAdditionAction = '';
function evaluateAsMdAdditionTask(node, file, parent) {
if (mdAdditionGathering === true && shouldFinishGathering(node)) {
mdAdditionGathering = false;
addTask(file, {
action: mdAdditionAction,
startSelector: mdAdditionStartSelector,
addNodes: mdAdditionAddNodes,
});
mdAdditionAddNodes = [];
}
if (mdAdditionGathering === true) {
if (parent.type === 'root') {
mdAdditionAddNodes.push(node);
}
}
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 = [];
}
};
}

View file

@ -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 = [
'<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 () => {
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 = [
'<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);
});
});