aboutsummaryrefslogtreecommitdiffstats
path: root/app/pages.ts
blob: 3bef4a9638d0b1e18d9d6287d348c92ae6341b11 (plain)
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
87
import { readFileSync } from 'fs';
import glob from 'glob';
import { logger } from './logger.js'
import { marked } from 'marked';
import matter from 'gray-matter';

export function buildPage(page: Page) {
    logger.info(`Building ${page.path}`);
    try {
        const result = matter(page.raw);
        const metadata = result.data;
        const html = marked.parse(result.content, { mangle: false, headerIds: false });

        page.html = html;
        page.metadata = metadata;
        page.buildTime = Date.now();
    } catch (e) {  
        logger.error(`Failed to build page ${page.path}: ${e.message}`);
    }
}

export namespace PageDirectory {
    export const pages: Record<string, Page> = {};
    export let lastBuild: number;
    
    export const rebuild = (pagePath: string): boolean => {
        for (const page in pages) {
            delete pages[page];
        }

        const localPages = glob.sync(`**/*.{md,html}`, { cwd: pagePath })

        // Load page content
        localPages.forEach(page => {
            let route = page.replace(/\.[^.]*$/,'')
            let name = /[^/]*$/.exec(route)[0];
            let path = `${pagePath}/${page}`
            let raw: string;
            try {
                raw = loadRaw(path);
            } catch (e) {
                logger.error(`Failed to read page ${path}: ${e.message}`);
                return;
            }

            pages[route] = {
                route: route,
                name: name,
                path: path,
                raw: raw,
                buildTime: 0,
                metadata: {
                    title: "A Page"
                }
            }
        });
        
        // Build pages
        Object.values(pages).forEach(page => buildPage(page));

        lastBuild = Date.now();
        return true;
    }

    export function get(name: string): Page {
        const page = pages[name];
        if (!page) {
            return undefined;
        }

        return page;
    }

    function loadRaw(path: string): string {
        return readFileSync(`${path}`, 'utf-8'); 
    }
}

export type Page = {
    html?: string;
    raw?: string;
    route: string;
    name: string;
    path: string;
    buildTime: number;
    metadata: any;
};