-
Notifications
You must be signed in to change notification settings - Fork 0
/
build.ts
86 lines (80 loc) · 2.8 KB
/
build.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import { promises as fs } from 'fs'
import Path from 'path'
import MDIT from 'markdown-it'
import MA from 'markdown-it-anchor'
const source = process.argv[2] || 'src'
const target = process.argv[3] || 'docs'
const MD = MDIT('commonmark', {
html: true,
linkify: true,
typographer: true,
}).use(MA)
const readDirR = async (dir: string, files: string[] = []) => {
const entries = await fs.readdir(dir, { withFileTypes: true })
const jobs: Array<Promise<any>> = []
for (const entry of entries) {
if (entry.isDirectory()) jobs.push(readDirR(Path.join(dir, entry.name), files))
if (entry.isFile()) files.push(Path.join(dir, entry.name))
}
await Promise.all(jobs)
return files
}
const wrapHtml = (main: string, title: string = '') => `<!-- autogenerated -->
<!DOCTYPE html>
<html>
<head>
<title>${title}</title>
<meta name=viewport content="width=device-width, initial-scale=1">
<link rel=stylesheet href=//cdn.jsdelivr.net/npm/[email protected]/build/web/hack.css>
<link rel=stylesheet media=print href=/css/print.css>
<link rel=stylesheet media=screen href=/css/screen.css>
<link rel=stylesheet href=/css/readable.css>
<link rel=stylesheet href=//cdn.jsdelivr.net/highlight.js/9.1.0/styles/github.min.css>
<script type=module src=/js/dark-toggle.js></script>
<script type=module src=/js/sw-register.js></script>
</head>
<body>
<header>
<nav>
<a href=/ >home</a>
<a href=https://github.com/qwelias/qwelias.github.io>source</a>
</nav>
<nav>
<a href=https://github.com/qwelias>github</a>
</nav>
</header>
<main>
${main}
</main>
</body>
</html>
`
const transforms: { [k: string]: (text: string, path: string) => [text: string, path: string] } = {
'.md': (text, path) => {
path = target + path.slice(source.length, -3)
const content = wrapHtml(MD.render(text))
return [content, path + '.html']
},
'*': (text, path) => {
path = target + path.slice(source.length)
return [text, path]
},
}
const applyTransform = (text: string, path: string) => {
for (const [ext, transform] of Object.entries(transforms)) {
if (path.endsWith(ext) || ext === '*') return transform(text, path)
}
return []
}
;(async () => {
await Promise.all(((await readDirR(source)).map(async file => {
const text = String(await fs.readFile(file))
const [newText, newFile] = applyTransform(text, file)
if (!newText) return
await fs.mkdir(Path.dirname(newFile), { recursive: true })
return await fs.writeFile(newFile, newText)
})))
})().catch(reason => {
console.error(reason)
process.exit(1)
})