Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions dev/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,34 @@ import { parse, join } from 'path'
import * as esbuild from 'esbuild'

import { rootDir, DEV, time } from './utils.js'
import { generateContentJSON } from './exo-parser.js'

const getHash = async head => {
const getHash = async (head) => {
if (!head.startsWith('ref:')) return { hash: head.trim(), branch: 'detached' }
const parts = head.split(' ')[1].trim().split('/')
const branch = parts[parts.length - 1]
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)
process.env.HASH = `${branch}@${hash.trim()}`
} catch (err) {
console.warn('Unable to load git commit version, fallback to time based hash', err)
console.warn(
'Unable to load git commit version, fallback to time based hash',
err,
)
const now = Math.floor((Date.now() - 16e11) / 1000)
process.env.HASH = `unk@${now.toString(36)}`
}

export const exoJsDir = () => readdir(join(rootDir, 'js-introduction'))

export const bundleJSONDir = (dirName) =>
mkdir(join(rootDir, dirName), { recursive: true })

const templateDir = join(rootDir, 'template')
const readEntry = async ({ name, ext, base }) => [
name,
Expand Down Expand Up @@ -51,6 +60,7 @@ const config = {

const serve = () => esbuild.serve({ servedir }, config)
const generate = async (file = 'index') => {
await generateContentJSON('js-introduction', 'public')
const content = await readdir(templateDir)
const entries = await Promise.all(content.map(parse).map(readEntry))
const templates = Object.fromEntries(entries)
Expand All @@ -61,7 +71,6 @@ const generate = async (file = 'index') => {
(cache[key] =
templates[key]?.replace(/<!-- ([a-zA-Z0-9]+) -->/gm, replace) ||
`<!-- missing template ${key} -->`)

return readTemplate(file)
}

Expand Down
81 changes: 81 additions & 0 deletions dev/exo-parser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { readdir, writeFile, readFile, mkdir } from 'fs/promises'
import { join, parse as pathParse } from 'path'

import { fromMarkdown } from 'mdast-util-from-markdown'

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' || node.type === 'text'
const isCODE = (node) => node.type === 'code' || node.type === 'inlineCode'
const isLI = (node) => node.type === 'list'

const parseContent = (nodeList) => {
const content = { description: '' }
let mode,
test = 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 === 'instructions') {
if (isP(node) || isLI(node)) {
content.instructions = children(node)
.map(getTrimValue)
.filter(Boolean)
.join(' ')
}
} else if (mode === 'tests') {
if (isH3(node)) {
test = { name: textContent(node) }
content.tests.push(test)
} else if (test && isCODE(node)) {
test.code = textContent(node)
test.lang = node.lang
} else {
console.warn('ignored node', node)
}
} else if (mode) {
// any other mode is stored in raw tree
content[mode].push(node)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

## Instructions pourra etre gerer ici

} else {
// before any mode is set, we are writing the description
content.description += `${textContent(node).trim()}\n`
}
}
return content
}

const readdirParse = async (path) =>
(await readdir(join(path))).map((file) => pathParse(join(path, file)))

export const generateContentJSON = async (input, ouput) => {
const dirList = await readdirParse(join(rootDir, input))
const contentProcessing = dirList.map(async ({ dir, base, name }) => {
const content = await readFile(join(dir, base))
const root = fromMarkdown(content)
const parsed = parseContent(root.children)
const outDir = join(rootDir, ouput, dir.slice(rootDir.length))
await mkdir(outDir, { recursive: true })
await writeFile(join(outDir, `${name}.json`), JSON.stringify(parsed))
return [name, parsed]
})

return Object.fromEntries(await Promise.all(contentProcessing))
}
4 changes: 3 additions & 1 deletion dev/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,6 @@ createServer(async (req, res) => {

// Apply headers from the worker
sendResponse({ body, options, res })
}).listen(PORT, () => console.log(`Dev server ready on ${process.env.DOMAIN}`))
}).listen(PORT, () => {
console.log(`Dev server ready on ${process.env.DOMAIN}`)
})
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}