feat: reorganize builder

This commit is contained in:
obvTiger 2025-03-27 13:28:12 +01:00
parent ff7bb041ef
commit 362b7aa15e
18 changed files with 1094 additions and 310 deletions

View file

@ -1,11 +1,12 @@
const fs = require("fs");
const path = require("path");
const TokenParser = require("./TokenParser");
const ASTBuilder = require("./ASTBuilder");
const CSSGenerator = require("./CSSGenerator");
const HTMLGenerator = require("./HTMLGenerator");
const MetadataManager = require("./MetadataManager");
const BlueprintCompiler = require("./BlueprintCompiler");
const BlueprintFileHandler = require("./BlueprintFileHandler");
/**
* BlueprintBuilder coordinates the entire build process from reading Blueprint files
* to writing compiled HTML and CSS files.
*/
class BlueprintBuilder {
/**
* Create a new Blueprint builder instance.
@ -20,14 +21,10 @@ class BlueprintBuilder {
...options,
};
this.tokenParser = new TokenParser(this.options);
this.astBuilder = new ASTBuilder(this.options);
this.cssGenerator = new CSSGenerator(this.options);
this.htmlGenerator = new HTMLGenerator(this.options, this.cssGenerator);
this.metadataManager = new MetadataManager(this.options);
this.compiler = new BlueprintCompiler(this.options);
this.fileHandler = new BlueprintFileHandler(this.options);
}
/**
* Builds a Blueprint file.
* @param {string} inputPath - Path to the Blueprint file to build
@ -40,42 +37,23 @@ class BlueprintBuilder {
}
try {
if (!inputPath.endsWith(".bp")) {
throw new Error("Input file must have .bp extension");
}
const input = fs.readFileSync(inputPath, "utf8");
const tokens = this.tokenParser.tokenize(input);
const ast = this.astBuilder.buildAST(tokens);
const pageNode = ast.children.find((node) => node.tag === "page");
if (pageNode) {
this.metadataManager.processPageMetadata(pageNode);
}
const html = this.htmlGenerator.generateHTML(ast);
const css = this.cssGenerator.generateCSS();
const input = this.fileHandler.readBlueprintFile(inputPath);
const baseName = path.basename(inputPath, ".bp");
const headContent = this.metadataManager.generateHeadContent(baseName);
const finalHtml = this.generateFinalHtml(headContent, html);
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
const result = this.compiler.compile(input, baseName);
if (result.success) {
this.fileHandler.writeCompiledFiles(outputDir, baseName, result.html, result.css);
if (this.options.debug) {
console.log("[DEBUG] Build completed successfully");
}
}
fs.writeFileSync(path.join(outputDir, `${baseName}.html`), finalHtml);
fs.writeFileSync(path.join(outputDir, `${baseName}.css`), css);
if (this.options.debug) {
console.log("[DEBUG] Build completed successfully");
}
return {
success: true,
errors: [],
success: result.success,
errors: result.errors,
};
} catch (error) {
if (this.options.debug) {
@ -94,51 +72,6 @@ class BlueprintBuilder {
};
}
}
/**
* Generates the final HTML document as a string.
*
* @param {string} headContent - The HTML content to be placed within the <head> tag.
* @param {string} bodyContent - The HTML content to be placed within the <body> tag.
* @returns {string} - A complete HTML document containing the provided head and body content.
*/
generateFinalHtml(headContent, bodyContent) {
return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
${headContent}
<style>
:root {
--navbar-height: 4rem;
}
body {
margin: 0;
padding: 0;
padding-top: var(--navbar-height);
background-color: #0d1117;
color: #e6edf3;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
line-height: 1.5;
min-height: 100vh;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
::selection {
background-color: rgba(59, 130, 246, 0.2);
}
</style>
</head>
<body>
${bodyContent}
</body>
</html>`;
}
}
module.exports = BlueprintBuilder;