UNPKG

markpage

Version:

Build and manage markdown-based content with distributed navigation - framework agnostic content management system

163 lines (162 loc) 5.25 kB
import { mkdirSync, writeFileSync, readFileSync } from "fs"; import { dirname, join } from "path"; import { validateContentStructure, buildNavigationTree } from "./parser.js"; class BuilderError extends Error { constructor(message, filePath) { super(message); this.filePath = filePath; this.name = "BuilderError"; } } async function buildPages(contentPath, options = {}) { try { validateContentStructure(contentPath, { autoDiscover: options.autoDiscover }); const navigation = buildNavigationTree(contentPath, { autoDiscover: options.autoDiscover }); let content; if (options.includeContent !== false) { content = bundleMarkdownContent(navigation, contentPath); } if (options.appOutput) { await writeAppOutput(navigation, content, options.appOutput); } if (options.websiteOutput) { await writeWebsiteOutput(navigation, options.websiteOutput); } return { navigation, content: content || void 0 }; } catch (error) { if (error instanceof BuilderError) { throw error; } throw new BuilderError( `Build failed: ${error instanceof Error ? error.message : "Unknown error"}`, contentPath ); } } function bundleMarkdownContent(navigation, basePath) { const content = {}; function processItems(items) { for (const item of items) { if (item.type === "page" && item.path) { const filePath = join(basePath, item.path); try { const markdownContent = readFileSync(filePath, "utf-8"); content[item.path] = markdownContent; } catch (error) { throw new BuilderError( `Failed to read markdown file: ${error instanceof Error ? error.message : "Unknown error"}`, filePath ); } } else if (item.type === "section" && item.path) { const filePath = join(basePath, item.path); try { const markdownContent = readFileSync(filePath, "utf-8"); content[item.path] = markdownContent; } catch (error) { throw new BuilderError( `Failed to read section markdown file: ${error instanceof Error ? error.message : "Unknown error"}`, filePath ); } } if (item.items) { processItems(item.items); } } } processItems(navigation); return content; } async function writeAppOutput(navigation, content, outputPath) { try { mkdirSync(dirname(outputPath), { recursive: true }); const navigationPath = join(outputPath, "navigation.json"); writeFileSync(navigationPath, JSON.stringify(navigation, null, 2)); if (content) { const contentPath = join(outputPath, "content.json"); writeFileSync(contentPath, JSON.stringify(content, null, 2)); } } catch (error) { throw new BuilderError( `Failed to write app output: ${error instanceof Error ? error.message : "Unknown error"}`, outputPath ); } } async function writeWebsiteOutput(navigation, outputPath) { try { mkdirSync(dirname(outputPath), { recursive: true }); const navigationPath = join(outputPath, "navigation.json"); writeFileSync(navigationPath, JSON.stringify(navigation, null, 2)); } catch (error) { throw new BuilderError( `Failed to write website output: ${error instanceof Error ? error.message : "Unknown error"}`, outputPath ); } } function processMarkdown(content, processor) { return processor ? processor.process(content) : content; } function generateStaticPages(navigation, basePath, options = {}) { const pages = []; function processItems(items) { for (const item of items) { if (item.type === "page" && item.path) { const filePath = join(basePath, item.path); try { const markdownContent = readFileSync(filePath, "utf-8"); const processedMd = processMarkdown(markdownContent, options.processor); const fullHtml = generateHTMLPage(processedMd, item.label, options.pageOptions); pages.push({ path: item.path.replace(/\.md$/, ".html"), content: markdownContent, html: fullHtml }); } catch (error) { throw new BuilderError( `Failed to process page ${item.path}: ${error instanceof Error ? error.message : "Unknown error"}`, filePath ); } } else if (item.items) { processItems(item.items); } } } processItems(navigation); return pages; } function generateHTMLPage(content, title, options = {}) { const pageTitle = options.title || title; const baseUrl = options.baseUrl || ""; const css = options.css || ""; const js = options.js || ""; return `<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>${pageTitle}</title> <base href="${baseUrl}"> ${css ? `<style>${css}</style>` : ""} </head> <body> <div class="content"> ${content} </div> ${js ? `<script>${js}<\/script>` : ""} </body> </html>`; } export { BuilderError, buildPages, generateStaticPages, processMarkdown }; //# sourceMappingURL=builder.js.map