Skip to content

Commit

Permalink
feat(3.2.0): refactor parser for plugin system (#482)
Browse files Browse the repository at this point in the history
  • Loading branch information
ShaunSHamilton authored Feb 12, 2024
2 parents 4feaf70 + b473a95 commit 47e8481
Show file tree
Hide file tree
Showing 45 changed files with 1,155 additions and 798 deletions.
6 changes: 5 additions & 1 deletion .freeCodeCamp/client/components/block.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,11 @@ export const Block = ({
) : null}
</h2>
<div className='block-info'>
<p>{description}</p>
<p
dangerouslySetInnerHTML={{
__html: description
}}
></p>
<span aria-hidden='true'>
{lessonsCompleted}/{numberOfLessons}
</span>
Expand Down
19 changes: 8 additions & 11 deletions .freeCodeCamp/client/components/console.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { ConsoleError } from '../types';
import { parseMarkdown } from '../utils';

export const Console = ({ cons }: { cons: ConsoleError[] }) => {
return (
Expand All @@ -12,16 +11,14 @@ export const Console = ({ cons }: { cons: ConsoleError[] }) => {
};

const ConsoleElement = ({ testText, testId, error }: ConsoleError) => {
const consoleMarkdown = `<details>\n<summary>${testId + 1}) ${parseMarkdown(
testText
)}</summary>\n\n\`\`\`json\n${JSON.stringify(
error,
null,
2
)}\n\`\`\`\n\n</details>`;
const details = `<summary>${testId + 1} ${testText}</summary>
${error}`;
return (
<div
dangerouslySetInnerHTML={{ __html: parseMarkdown(consoleMarkdown) }}
></div>
<details
dangerouslySetInnerHTML={{
__html: details
}}
></details>
);
};
12 changes: 8 additions & 4 deletions .freeCodeCamp/client/components/heading.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export const Heading = ({
const canGoForward =
lessonNumberExists && numberOfLessons && lessonNumber < numberOfLessons - 1;

const h1 = title + (lessonNumberExists ? ' - Lesson ' + lessonNumber : '');
return (
<nav className='heading'>
{goToPreviousLesson && (
Expand All @@ -40,10 +41,13 @@ export const Heading = ({
{'<'}
</button>
)}
<h1 id='project-heading' className={anim}>
{title}
{lessonNumberExists && ' - Lesson ' + lessonNumber}
</h1>
<h1
id='project-heading'
className={anim}
dangerouslySetInnerHTML={{
__html: h1
}}
></h1>
{goToNextLesson && (
<button
className='next-lesson-btn'
Expand Down
18 changes: 10 additions & 8 deletions .freeCodeCamp/client/components/hints.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { parseMarkdown } from '../utils';

export const Hints = ({ hints }: { hints: string[] }) => {
return (
<ul style={{ listStyle: 'none' }}>
Expand All @@ -11,12 +9,16 @@ export const Hints = ({ hints }: { hints: string[] }) => {
};

const HintElement = ({ hint, i }: { hint: string; i: number }) => {
const consoleMarkdown = `<details>\n<summary>Hint ${
i + 1
}</summary>\n${hint}\n\n</details>`;
const details = `<summary>Hint ${i + 1}</summary>
${hint}`;
return (
<div
dangerouslySetInnerHTML={{ __html: parseMarkdown(consoleMarkdown) }}
></div>
<div>
<details
dangerouslySetInnerHTML={{
__html: details
}}
></details>
</div>
);
};
3 changes: 1 addition & 2 deletions .freeCodeCamp/client/components/test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Loader } from './loader';
import { TestType } from '../types';
import { parseMarkdown } from '../utils';

export const Test = ({ testText, passed, isLoading, testId }: TestType) => {
return (
Expand All @@ -10,7 +9,7 @@ export const Test = ({ testText, passed, isLoading, testId }: TestType) => {
</span>
<div
style={{ display: 'inline' }}
dangerouslySetInnerHTML={{ __html: parseMarkdown(testText) }}
dangerouslySetInnerHTML={{ __html: testText }}
></div>
</li>
);
Expand Down
4 changes: 2 additions & 2 deletions .freeCodeCamp/client/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
import { Loader } from './components/loader';
import { Landing } from './templates/landing';
import { Project } from './templates/project';
import { parseMarkdown, parse } from './utils/index';
import { parse } from './utils/index';
import { Header } from './components/header';
import './styles.css';
import { E44o5 } from './components/error';
Expand Down Expand Up @@ -129,7 +129,7 @@ const App = () => {
}

function updateDescription({ description }: { description: string }) {
setDescription(parseMarkdown(description));
setDescription(description);
}

function updateTests({ tests }: { tests: TestType[] }) {
Expand Down
2 changes: 1 addition & 1 deletion .freeCodeCamp/client/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ marked.use(
})
);

export function parseMarkdown(markdown: string) {
function parseMarkdown(markdown: string) {
return marked.parse(markdown, { gfm: true });
}

Expand Down
94 changes: 93 additions & 1 deletion .freeCodeCamp/plugin/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
import { readFile } from 'fs/promises';
import { freeCodeCampConfig, getState, ROOT } from '../tooling/env.js';
import { CoffeeDown, parseMarkdown } from '../tooling/parser.js';
import { join } from 'path';
import { logover } from '../tooling/logger.js';

/**
* Project config from `config/projects.json`
* @typedef {Object} Project
Expand All @@ -24,6 +30,19 @@
* @property {boolean} isLoading
*/

/**
* @typedef {Object} Lesson
* @property {string} description
* @property {[[string, string]]} tests
* @property {string[]} hints
* @property {[{filePath: string; fileSeed: string} | string]} seed
* @property {boolean?} isForce
* @property {string?} beforeAll
* @property {string?} afterAll
* @property {string?} beforeEach
* @property {string?} afterEach
*/

export const pluginEvents = {
/**
* @param {Project} project
Expand Down Expand Up @@ -55,5 +74,78 @@ export const pluginEvents = {
/**
* @param {Project} project
*/
onLessonFailed: async project => {}
onLessonFailed: async project => {},

/**
* @param {string} projectDashedName
* @returns {Promise<{title: string; description: string; numberOfLessons: number}>}
*/
getProjectMeta: async projectDashedName => {
const { locale } = await getState();
const projectFilePath = join(
ROOT,
freeCodeCampConfig.curriculum.locales[locale],
projectDashedName + '.md'
);
const projectFile = await readFile(projectFilePath, 'utf8');
const coffeeDown = new CoffeeDown(projectFile);
const projectMeta = coffeeDown.getProjectMeta();
// Remove `<p>` tags if present
const title = parseMarkdown(projectMeta.title).replace(/<p>|<\/p>/g, '');
const description = parseMarkdown(projectMeta.description);
const numberOfLessons = projectMeta.numberOfLessons;
return { title, description, numberOfLessons };
},

/**
* @param {string} projectDashedName
* @param {number} lessonNumber
* @returns {Promise<Lesson>} lesson
*/
getLesson: async (projectDashedName, lessonNumber) => {
const { locale } = await getState();
const projectFilePath = join(
ROOT,
freeCodeCampConfig.curriculum.locales[locale],
projectDashedName + '.md'
);
const projectFile = await readFile(projectFilePath, 'utf8');
const coffeeDown = new CoffeeDown(projectFile);
const lesson = coffeeDown.getLesson(lessonNumber);
let seed = lesson.seed;
if (!seed.length) {
// Check for external seed file
const seedFilePath = projectFilePath.replace(/.md$/, '-seed.md');
try {
const seedContent = await readFile(seedFilePath, 'utf-8');
const coffeeDown = new CoffeeDown(seedContent);
seed = coffeeDown.getLesson(lessonNumber).seed;
} catch (e) {
if (e?.code !== 'ENOENT') {
logover.debug(e);
throw new Error(
`Error reading external seed for lesson ${lessonNumber}`
);
}
}
}
const { afterAll, afterEach, beforeAll, beforeEach, isForce } = lesson;
const description = parseMarkdown(lesson.description);
const tests = lesson.tests.map(([testText, test]) => [
parseMarkdown(testText),
test
]);
const hints = lesson.hints.map(parseMarkdown);
return {
description,
tests,
hints,
seed,
beforeAll,
afterAll,
beforeEach,
afterEach,
isForce
};
}
};
74 changes: 0 additions & 74 deletions .freeCodeCamp/tests/fixtures/expected-format.md

This file was deleted.

31 changes: 0 additions & 31 deletions .freeCodeCamp/tests/fixtures/valid-poor-format.md

This file was deleted.

Loading

0 comments on commit 47e8481

Please sign in to comment.