Repository navigation
Expand file tree
/
Copy pathcontent-preview.js
More file actions
66 lines (59 loc) · 1.8 KB
/
Copy pathcontent-preview.js
File metadata and controls
66 lines (59 loc) · 1.8 KB
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
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { openDb } from '@async/db';
const exampleRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
const db = await openDb({ cwd: exampleRoot });
await db.runtime.hydrate();
const [docs, blog] = await Promise.all([
db.collection('docs').all(),
db.collection('blog').all(),
]);
const output = [
'<main>',
...docs
.sort((left, right) => (left.order ?? 100) - (right.order ?? 100))
.map((record) => renderArticle('doc', record)),
...blog.map((record) => renderArticle('blog', {
...record,
href: `/blog/${record.id}`,
})),
'</main>',
'',
].join('\n');
console.log(output);
export function renderArticle(kind, record) {
const title = escapeHtml(record.title ?? record.id);
const body = renderMdxPreview(record.body ?? '');
const href = record.href ? ` data-href="${escapeHtml(record.href)}"` : '';
return [
`<article data-kind="${kind}" data-id="${escapeHtml(record.id)}"${href}>`,
` <h2>${title}</h2>`,
` <p>${escapeHtml(record.summary ?? '')}</p>`,
` <div>${body}</div>`,
'</article>',
].join('\n');
}
function renderMdxPreview(source) {
return String(source)
.split(/\n{2,}/u)
.map((block) => block.trim())
.filter(Boolean)
.map((block) => {
if (block.startsWith('# ')) {
return `<h1>${escapeHtml(block.slice(2))}</h1>`;
}
if (block.startsWith('## ')) {
return `<h2>${escapeHtml(block.slice(3))}</h2>`;
}
const withoutJsxTags = block.replace(/<\/?[A-Z][^>]*>/gu, '');
return `<p>${escapeHtml(withoutJsxTags)}</p>`;
})
.join('');
}
function escapeHtml(value) {
return String(value)
.replaceAll('&', '&')
.replaceAll('<', '<')
.replaceAll('>', '>')
.replaceAll('"', '"');
}