refactor: create and use all-section parser (#56282)

This commit is contained in:
Oliver Eyton-Williams
2024-09-25 19:04:16 +02:00
committed by GitHub
parent 5e799317bc
commit e95b040762
13 changed files with 131 additions and 63 deletions
@@ -1,4 +1,4 @@
const getSection = require('./utils/get-section');
const { getSection } = require('./utils/get-section');
const mdastToHtml = require('./utils/mdast-to-html');
const { splitOnThematicBreak } = require('./utils/split-on-thematic-break');
@@ -1,7 +1,7 @@
const { root } = require('mdast-builder');
const find = require('unist-util-find');
const visit = require('unist-util-visit');
const getSection = require('./utils/get-section');
const { getSection } = require('./utils/get-section');
const getAllBefore = require('./utils/before-heading');
const mdastToHtml = require('./utils/mdast-to-html');
@@ -1,5 +1,5 @@
const { root } = require('mdast-builder');
const getSection = require('./utils/get-section');
const { getSection, getAllSections } = require('./utils/get-section');
const mdastToHtml = require('./utils/mdast-to-html');
const { splitOnThematicBreak } = require('./utils/split-on-thematic-break');
@@ -10,27 +10,16 @@ function plugin() {
const quizzesNodes = getSection(tree, `--quizzes--`);
if (quizzesNodes.length > 0) {
const quizzes = [];
const quizTrees = [];
const compiledQuizzes = [];
const quizSections = getAllSections(root(quizzesNodes), `--quiz--`);
quizzesNodes.forEach(quizNode => {
const isStartOfQuiz = quizNode.children?.[0]?.value === '--quiz--';
if (isStartOfQuiz) {
quizTrees.push([quizNode]);
} else {
quizTrees[quizTrees.length - 1].push(quizNode);
}
});
if (quizTrees.length === 0) {
if (quizSections.length === 0) {
throw Error(
'The --quizzes-- section should contain at least one quiz.'
);
}
quizTrees.forEach(allQuizNodes => {
const quizTree = root(allQuizNodes);
const quizNodes = getSection(quizTree, `--quiz--`);
quizSections.forEach(quizNodes => {
const quizQuestions = [];
const questionTrees = [];
@@ -62,11 +51,11 @@ function plugin() {
);
});
quizzes.push({ questions: quizQuestions });
compiledQuizzes.push({ questions: quizQuestions });
});
if (quizzes.length > 0) {
file.data.quizzes = quizzes;
if (compiledQuizzes.length > 0) {
file.data.quizzes = compiledQuizzes;
}
}
}
@@ -1,4 +1,4 @@
const getSection = require('./utils/get-section');
const { getSection } = require('./utils/get-section');
function plugin() {
return transformer;
@@ -1,7 +1,7 @@
const { isEmpty } = require('lodash');
const { root } = require('mdast-builder');
const visitChildren = require('unist-util-visit-children');
const getSection = require('./utils/get-section');
const { getSection } = require('./utils/get-section');
const { getFileVisitor } = require('./utils/get-file-visitor');
const editableRegionMarker = '--fcc-editable-region--';
@@ -3,7 +3,7 @@ const { root } = require('mdast-builder');
const visitChildren = require('unist-util-visit-children');
const { editableRegionMarker } = require('./add-seed');
const getSection = require('./utils/get-section');
const { getSection } = require('./utils/get-section');
const { getFileVisitor } = require('./utils/get-file-visitor');
const { splitOnThematicBreak } = require('./utils/split-on-thematic-break');
@@ -1,5 +1,5 @@
const chunk = require('lodash/chunk');
const getSection = require('./utils/get-section');
const { getSection } = require('./utils/get-section');
const mdastToHtml = require('./utils/mdast-to-html');
function plugin() {
@@ -1,5 +1,5 @@
const { isEmpty } = require('lodash');
const getSection = require('./utils/get-section');
const { getSection } = require('./utils/get-section');
const mdastToHTML = require('./utils/mdast-to-html');
function addText(sectionIds) {
@@ -1,6 +1,6 @@
const { root } = require('mdast-builder');
const find = require('unist-util-find');
const getSection = require('./utils/get-section');
const { getSection } = require('./utils/get-section');
const getAllBefore = require('./utils/before-heading');
const mdastToHtml = require('./utils/mdast-to-html');
@@ -0,0 +1,27 @@
const visit = require('unist-util-visit');
const _ = require('lodash');
/**
* Finds all nodes in a tree that match a given condition. This is a trivial
* extension of `unist-util-find` that returns all matching nodes.
*
* @param {Object} tree - The unist tree to search through.
* @param {Function|Object} condition - The condition to match nodes
* against. This can be a function that accepts a single node argument or an object to match.
* @returns {Array} An array of nodes that match the condition.
*/
function findAll(tree, condition) {
const predicate = _.iteratee(condition);
const results = [];
visit(tree, node => {
if (predicate(node)) {
results.push(node);
}
return visit.CONTINUE;
});
return results;
}
module.exports.findAll = findAll;
@@ -0,0 +1,39 @@
const { findAll } = require('./find-all');
const testTree = {
type: 'root',
children: [
{
type: 'heading',
depth: 1,
children: [{ type: 'text', value: 'test', testId: 1 }]
},
{
type: 'paragraph',
children: [{ type: 'text', value: 'different', testId: 2 }]
},
{
type: 'heading',
depth: 2,
children: [{ type: 'text', value: 'test', testId: 3 }]
},
{
type: 'heading',
depth: 1,
children: [{ type: 'text', value: 'test', testId: 4 }]
}
]
};
describe('findAll', () => {
it('should return an array', () => {
expect(findAll(testTree, _node => false)).toEqual([]);
});
it('should return an array of nodes that match the test', () => {
expect(findAll(testTree, { type: 'text', value: 'test' })).toEqual([
{ type: 'text', value: 'test', testId: 1 },
{ type: 'text', value: 'test', testId: 3 },
{ type: 'text', value: 'test', testId: 4 }
]);
});
});
@@ -2,45 +2,58 @@ const find = require('unist-util-find');
const findAfter = require('unist-util-find-after');
const findAllAfter = require('unist-util-find-all-after');
const between = require('unist-util-find-all-between');
const { findAll } = require('./find-all');
function getSection(tree, marker) {
const start = find(tree, {
type: 'heading',
children: [
{
type: 'text',
value: marker
}
]
});
function _getSection(tree) {
return start => {
if (!start) return [];
if (!start) return [];
const isEnd = node => {
return (
node.type === 'heading' && node.depth <= start.depth && isMarker(node)
);
};
const isMarker = node => {
if (node.children && node.children[0]) {
const child = node.children[0];
const isEnd = node => {
return (
child.type === 'text' &&
child.value.startsWith('--') &&
child.value.endsWith('--')
node.type === 'heading' && node.depth <= start.depth && isMarker(node)
);
} else {
return false;
}
};
const isMarker = node => {
if (node.children && node.children[0]) {
const child = node.children[0];
return (
child.type === 'text' &&
child.value.startsWith('--') &&
child.value.endsWith('--')
);
} else {
return false;
}
};
const end = findAfter(tree, start, isEnd);
const targetNodes = end
? between(tree, start, end)
: findAllAfter(tree, start);
return targetNodes;
};
const end = findAfter(tree, start, isEnd);
const targetNodes = end
? between(tree, start, end)
: findAllAfter(tree, start);
return targetNodes;
}
module.exports = getSection;
const startNode = marker => ({
type: 'heading',
children: [
{
type: 'text',
value: marker
}
]
});
function getSection(tree, marker) {
const start = find(tree, startNode(marker));
return _getSection(tree)(start);
}
function getAllSections(tree, marker) {
const starts = findAll(tree, startNode(marker));
return starts.map(_getSection(tree));
}
module.exports = { getSection, getAllSections };
@@ -3,7 +3,7 @@ const { root } = require('mdast-builder');
const find = require('unist-util-find');
const parseFixture = require('../../__fixtures__/parse-fixture');
const getSection = require('./get-section');
const { getSection } = require('./get-section');
describe('getSection', () => {
let simpleAst, extraHeadingAst;