From 62d0226d62a8299b94c65f456dd67c269f6b14d3 Mon Sep 17 00:00:00 2001 From: emmadal Date: Fri, 29 Oct 2021 16:31:12 +0000 Subject: [PATCH] starting generate JSON file for module --- dev/build.js | 24 ++++++++++-- dev/module-parser.js | 75 ++++++++++++++++++++++++++++++++++++++ js-module/Readme.module.md | 69 +++++++++++++++++++++++++++++++++++ package.json | 1 + 4 files changed, 166 insertions(+), 3 deletions(-) create mode 100644 dev/module-parser.js create mode 100644 js-module/Readme.module.md diff --git a/dev/build.js b/dev/build.js index 25befb35..df92d506 100644 --- a/dev/build.js +++ b/dev/build.js @@ -1,9 +1,9 @@ import { readFile, readdir, writeFile, mkdir } from 'fs/promises' import { parse, join } from 'path' - import * as esbuild from 'esbuild' - +import { fromMarkdown } from 'mdast-util-from-markdown' import { rootDir, DEV, time } from './utils.js' +import { generateModJSON, parseContent } from './module-parser.js' const getHash = async head => { if (!head.startsWith('ref:')) return { hash: head.trim(), branch: 'detached' } @@ -12,7 +12,7 @@ const getHash = async head => { const hash = await readFile(join(rootDir, '.git', ...parts), 'utf8') return { hash: hash.trim(), branch } } - + try { const head = await readFile(join(rootDir, '.git/HEAD'), 'utf8') const { hash, branch } = await getHash(head) @@ -23,6 +23,23 @@ try { process.env.HASH = `unk@${now.toString(36)}` } +export const modJsDir = () => readdir(join(rootDir, 'js-module')) + +export const bundleJSONDir = (dirName) => + mkdir(join(rootDir, dirName), { recursive: true }) + +export const readJSMod = async () => { + const dirList = await modJsDir() + const entries = await Promise.all( + dirList.map(async (name) => { + const file = await readFile(join(rootDir, 'js-module', name)) + const root = fromMarkdown(file) + return [name, parseContent(root.children)] + }), + ) + return entries +} + const templateDir = join(rootDir, 'template') const readEntry = async ({ name, ext, base }) => [ name, @@ -51,6 +68,7 @@ const config = { const serve = () => esbuild.serve({ servedir }, config) const generate = async (file = 'index') => { + await generateModJSON() const content = await readdir(templateDir) const entries = await Promise.all(content.map(parse).map(readEntry)) const templates = Object.fromEntries(entries) diff --git a/dev/module-parser.js b/dev/module-parser.js new file mode 100644 index 00000000..ff48af3d --- /dev/null +++ b/dev/module-parser.js @@ -0,0 +1,75 @@ +import { readdir, writeFile, rename } from 'fs/promises' +import { join } from 'path' +import { readJSMod, modJsDir, bundleJSONDir } from './build.js' +import { rootDir } from './utils.js' + +// returns a flatten array of all the children +const children = (n) => + n.children ? [n, ...n.children.flatMap(children)] : [n] + +const getTrimValue = (n) => n.value?.trim() +const textContent = (n) => + children(n).map(getTrimValue).filter(Boolean).join(' ') || '' + +const isH1 = (node) => node.type === 'heading' && node.depth === 1 +const isH2 = (node) => node.type === 'heading' && node.depth === 2 +const isH3 = (node) => node.type === 'heading' && node.depth === 3 +const isP = (node) => node.type === 'paragraph' +const isCODE = (node) => node.type === 'code' +const isLI = (node) => node.type === 'list' + +export const parseContent = (nodeList) => { + const content = { description: '' } + let mode, exercise = isP + for (const node of nodeList) { + if (!content.title && isH1(node)) { + content.title = textContent(node) + } else if (isH2(node)) { + mode = textContent(node).toLowerCase() + content[mode] = [] + } else if (mode === 'notions') { + if (isLI(node)) { + content.notions = children(node).map(getTrimValue).filter(Boolean) + } + } else if (mode === 'description') { + if (isP(node)) { + content.description = children(node) + .map(getTrimValue) + .filter(Boolean) + .join(' ') + } + } else if (mode === 'exercise') { + if (isH3(node)) { + exercise = { name: textContent(node) } + content.exercise.push(exercise) + } else if ( exercise && isCODE(node)) { + console.log(node) + exercise.code = textContent(node) + exercise.lang = node.lang + } else { + console.warn('ignored node', node) + } + } else if (mode) { + // any other mode is stored in raw tree + content[mode].push(node) + } else { + // before any mode is set, we are writing the description + content.description += `${textContent(node).trim()}\n` + } + } + return content +} + +export const generateModJSON = async () => { + const dirList = await modJsDir() + const entries = await readJSMod() + const modulebundle = await bundleJSONDir('modulebundle') + dirList.map(async (file) => { + const data = Object.fromEntries(entries)[file] + await writeFile(`${file.split('.md')[0]}.json`, JSON.stringify(data)) + }) + + await (await readdir(rootDir)) + .filter((filename) => filename.includes('module.json')) + .map((e) => rename(join(rootDir, e), join(modulebundle, e))) +} diff --git a/js-module/Readme.module.md b/js-module/Readme.module.md new file mode 100644 index 00000000..85558065 --- /dev/null +++ b/js-module/Readme.module.md @@ -0,0 +1,69 @@ +# JS Basics + +## Description + +This module talk about the Basics of Javascript Programming + +## Exercise + +### Hello There + +```js +{ name: "Hello There", type: "exercise", key: "01-hello-there.exercise.md"} +``` + +### Anything to declare + +```js +{ name: "Anything to declare", type: "exercise", key: "02-anything-to-declare.exercise.md"} +``` + +### Undefined future + +```js +{ name: "Undefined future", type: "exercise", key: "03-undefined-future.exercise.md"} +``` + +### The great escape + +```js +{ name: "The great escape", type: "exercise", key: "04-the-great-escape.exercise.md"} +``` + +### String of number + +```js +{ name: "String of number", type: "exercise", key: "05-string-of-number.exercise.md"} +``` + +### Redecleration of love + +```js +{ name: "Redecleration of love", type: "exercise", key: "06-redecleration-of-love.exercise.md"} +``` + +### Smooth operator + +```js +{ name: "Smooth operator", type: "exercise", key: "07-smooth-operator.exercise.md"} +``` + +### Placeholders + +```js +{ name: "Placeholders", type: "exercise", key: "08-placeholders.exercise.md"} +``` + +### Duplicate + +```js +{ name: "Duplicate", type: "exercise", key: "09-duplicate.exercise.md"} +``` + +## Quizz + +## Notions + +- variables +- data types +- console diff --git a/package.json b/package.json index 703b4077..15b3c6c8 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "dependencies": { "esbuild": "^0.11.2", "fast-toml": "^0.5.4", + "mdast-util-from-markdown": "^1.0.4", "preact": "^10.5.13" } }