diff --git a/tools/challenge-helper-scripts/create-next-step.js b/tools/challenge-helper-scripts/create-next-step.js
index 7512630616..c59bec66bc 100644
--- a/tools/challenge-helper-scripts/create-next-step.js
+++ b/tools/challenge-helper-scripts/create-next-step.js
@@ -4,7 +4,7 @@ const path = require('path');
const {
reorderSteps,
createStepFile,
- getChallengeSeed,
+ getChallengeSeeds,
getProjectPath
} = require('./utils');
@@ -28,14 +28,14 @@ const getLastStepFileContent = () => {
return {
nextStepNum: lastStepFileNum + 1,
- challengeSeed: getChallengeSeed(projectPath + fileName)
+ challengeSeeds: getChallengeSeeds(projectPath + fileName)
};
};
const projectPath = getProjectPath();
-const { nextStepNum, challengeSeed } = getLastStepFileContent();
+const { nextStepNum, challengeSeeds } = getLastStepFileContent();
-createStepFile({ stepNum: nextStepNum, projectPath, challengeSeed });
+createStepFile({ stepNum: nextStepNum, projectPath, challengeSeeds });
console.log(`Sucessfully added step #${nextStepNum}`);
reorderSteps();
diff --git a/tools/challenge-helper-scripts/create-step-between.js b/tools/challenge-helper-scripts/create-step-between.js
index 9fde86e4a5..a2ba8fed36 100644
--- a/tools/challenge-helper-scripts/create-step-between.js
+++ b/tools/challenge-helper-scripts/create-step-between.js
@@ -1,7 +1,7 @@
const {
reorderSteps,
createStepFile,
- getChallengeSeed,
+ getChallengeSeeds,
padWithLeadingZeros,
getExistingStepNums,
getProjectPath,
@@ -35,13 +35,13 @@ if (!allStepsExist(existingSteps, [start, end])) {
throw 'Step not created. At least one of the steps specified does not exist.';
}
-const challengeSeed = getChallengeSeed(
+const challengeSeeds = getChallengeSeeds(
`${projectPath}part-${padWithLeadingZeros(start)}.md`
);
createStepFile({
stepNum: start,
projectPath,
- challengeSeed,
+ challengeSeeds,
stepBetween: true
});
console.log(`Sucessfully added step between step #${start} and step #${end}`);
diff --git a/tools/challenge-helper-scripts/utils.js b/tools/challenge-helper-scripts/utils.js
index 038ec46866..950e31541d 100644
--- a/tools/challenge-helper-scripts/utils.js
+++ b/tools/challenge-helper-scripts/utils.js
@@ -2,67 +2,106 @@ const fs = require('fs');
const path = require('path');
const matter = require('gray-matter');
const ObjectID = require('bson-objectid');
+const { parseMDSync } = require('../challenge-parser/parser');
const padWithLeadingZeros = originalNum => {
/* always want file step numbers 3 digits */
return ('' + originalNum).padStart(3, '0');
};
-const removeErms = seedCode => {
+const insertErms = (seedCode, erms) => {
const lines = seedCode.split('\n');
- return lines
- .filter(line => !line.includes('--fcc-editable-region--'))
- .join('\n');
+ if (Number.isInteger(erms[0])) {
+ lines.splice(erms[0], 0, '--fcc-editable-region--');
+ }
+ if (Number.isInteger(erms[1])) {
+ lines.splice(erms[1], 0, '--fcc-editable-region--');
+ }
+ return lines.join('\n');
};
const createStepFile = ({
projectPath,
stepNum,
- challengeSeed = '',
+ challengeSeeds = {},
stepBetween = false
}) => {
- if (challengeSeed) {
- challengeSeed = removeErms(challengeSeed);
- }
+ const seedTexts = Object.values(challengeSeeds).map(
+ ({ contents, ext, editableRegionBoundaries }) => {
+ const fullContents = insertErms(contents, editableRegionBoundaries);
+ return `\`\`\`${ext}
+${fullContents}
+\`\`\``;
+ }
+ );
+
+ const seedHeads = Object.values(challengeSeeds)
+ .filter(({ head }) => head)
+ .map(
+ ({ ext, head }) => `\`\`\`${ext}
+${head}
+\`\`\``
+ )
+ .join('\n');
+
+ const seedTails = Object.values(challengeSeeds)
+ .filter(({ tail }) => tail)
+ .map(
+ ({ ext, tail }) => `\`\`\`${ext}
+${tail}
+\`\`\``
+ )
+ .join('\n');
const descStepNum = stepBetween ? stepNum + 1 : stepNum;
const stepDescription = `${
stepBetween ? 'new' : ''
} step ${descStepNum} instructions`;
- const challengeSeedSection = `
+ const challengeSeedSection = `
+# --seed--
-${challengeSeed.trim()}
+## --seed-contents--
-`;
+${seedTexts.join('\n')}`;
- const template = `---
+ const seedHeadSection = seedHeads
+ ? `
+
+## --before-user-code--
+
+${seedHeads}`
+ : '';
+
+ const seedTailSection = seedTails
+ ? `
+
+## --after-user-code--
+
+${seedTails}`
+ : '';
+
+ const template =
+ `---
id: ${ObjectID.generate()}
title: Part ${stepNum}
challengeType: 0
---
-## Description
-
+# --description--
${stepDescription}
-
+# --hints--
-## Tests
-
+Test 1
-\`\`\`yml
-tests:
- - text: Test 1
- testString: ''
+\`\`\`js
\`\`\`
-
-
-
-## Challenge Seed
-${challengeSeedSection}
-`;
+` +
+ challengeSeedSection +
+ seedHeadSection +
+ seedTailSection;
let finalStepNum = padWithLeadingZeros(stepNum);
finalStepNum += stepBetween ? 'a' : '';
@@ -158,19 +197,8 @@ const reorderSteps = () => {
console.log('Reordered steps');
};
-const getChallengeSeed = challengeFilePath => {
- const fileContent = fs.readFileSync(challengeFilePath, 'utf8');
- const matchedSection = fileContent
- .toString()
- .match(/(?[\s\S]+)<\/section>/);
- let finalChallengeSeed = '';
- if (matchedSection) {
- let {
- groups: { challengeSeed }
- } = matchedSection;
- finalChallengeSeed = challengeSeed ? challengeSeed : '';
- }
- return finalChallengeSeed;
+const getChallengeSeeds = challengeFilePath => {
+ return parseMDSync(challengeFilePath).files;
};
const getExistingStepNums = projectPath => {
@@ -208,7 +236,7 @@ const getArgValues = argv => {
module.exports = {
createStepFile,
- getChallengeSeed,
+ getChallengeSeeds,
padWithLeadingZeros,
reorderSteps,
getExistingStepNums,
diff --git a/tools/challenge-parser/parser/index.js b/tools/challenge-parser/parser/index.js
index a1479ec66a..60ad65fbcb 100644
--- a/tools/challenge-parser/parser/index.js
+++ b/tools/challenge-parser/parser/index.js
@@ -53,7 +53,6 @@ exports.parseMD = function parseMD(filename) {
const tree = processor.parse(file);
processor.run(tree, file, function (err, node, file) {
if (!err) {
- delete file.contents;
resolve(file.data);
} else {
err.message += ' in file ' + filename;
@@ -62,3 +61,15 @@ exports.parseMD = function parseMD(filename) {
});
});
};
+
+exports.parseMDSync = function parseMDSync(filename) {
+ const file = readSync(filename);
+ const tree = processor.parse(file);
+ try {
+ processor.runSync(tree, file);
+ } catch (err) {
+ err.message += ' in file ' + filename;
+ throw err;
+ }
+ return file.data;
+};