Skip to content

Commit

Permalink
added a blog
Browse files Browse the repository at this point in the history
  • Loading branch information
ThinLiquid committed Aug 19, 2024
1 parent b610066 commit 894d7d2
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 55 deletions.
6 changes: 5 additions & 1 deletion root.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
width: 100%;
position: absolute;
left: calc(50% + 105px);
top: 234px;
top: 100px;
z-index: 11;
"
>
Expand All @@ -56,6 +56,10 @@
<img src="/icons/Folder.svg" width="64" height="64" alt="" />
<folder-name>Home</folder-name>
</a>
<a href="/blog">
<img src="/icons/TextEdit.svg" width="64" height="64" alt="" />
<folder-name>Blog</folder-name>
</a>
<a href="/buttons-galore">
<img src="/icons/Folder.svg" width="64" height="64" alt="" />
<folder-name>Buttons Galore</folder-name>
Expand Down
128 changes: 74 additions & 54 deletions scripts/build.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import fs from "fs";
import fs from "fs/promises";
import path from "path";
import chokidar from "chokidar";
import zlib from "zlib";
Expand All @@ -17,17 +17,19 @@ import chalk from "chalk";
const OUTPUT_FOLDER = "./site";
const TEMPLATE_FILE = "./root.html";

const log = console.log;
const { log } = console;
const errorLog = (msg: string) => log(chalk.red(msg));
const successLog = (msg: string) => log(chalk.green(msg));
const infoLog = (msg: string) => log(chalk.blue(msg));

const getGitInfo = () => {
try {
const commitHash = execSync(`git rev-parse HEAD`).toString().trim();
const commitBranch = execSync(`git rev-parse --abbrev-ref HEAD`).toString().trim();
const commitMessage = execSync(`git log -1 --pretty=%B`).toString().trim();
return { commitHash, commitMessage, commitBranch };
const exec = (cmd: string) => execSync(cmd).toString().trim();
return {
commitHash: exec(`git rev-parse HEAD`),
commitBranch: exec(`git rev-parse --abbrev-ref HEAD`),
commitMessage: exec(`git log -1 --pretty=%B`)
};
} catch (error) {
errorLog("Error getting Git info:");
console.error(error);
Expand All @@ -42,29 +44,35 @@ const compileSCSSFiles = async (files: string | string[]): Promise<string> => {
};

const createExternalStyles = (files: string | string[]): string => {
if (Array.isArray(files)) {
return files.map(file => `<link rel="stylesheet" href="${file}">`).join('');
}
return `<link rel="stylesheet" href="${files}">`;
return Array.isArray(files)
? files.map(file => `<link rel="stylesheet" href="${file}">`).join('')
: `<link rel="stylesheet" href="${files}">`;
};

const parseEmojis = (markdown: string) => {
const emojify = (match: string) => `<span className="emoji">${emoji.emojify(match)}</span>`;
return markdown.replace(
/<(pre|template|code)[^>]*?>[\s\S]+?<\/(pre|template|code)>/g,
(m) => m.replace(/:/g, '__colon__')
)
.replace(/:(\w+?):/gi, emojify)
.replace(/__colon__/g, ':');
return markdown.replace(/<(pre|template|code)[^>]*?>[\s\S]+?<\/(pre|template|code)>/g, m => m.replace(/:/g, '__colon__'))
.replace(/:(\w+?):/gi, emojify)
.replace(/__colon__/g, ':');
};

const format = async (filename: string, data: string) => {
const parser = new XMLParser();
const [frontMatter, ...contentParts] = data.split('---');
const json = parser.parse(frontMatter);
const mdContent = parseEmojis(contentParts.join('---'));
let mdContent = parseEmojis(contentParts.join('---'));
const { commitHash, commitMessage } = getGitInfo();

const pageType = json.meta.type ?? 'page';

if (pageType === 'blog post') {
mdContent = dedent`
# ${json.meta.title}
<small>${json.meta.date} | ${json.meta.description}</small>
<hr/>
${mdContent}`;
}

const [html, md] = await Promise.all([
rootTemplate,
marked.parse(mdContent)
Expand All @@ -83,7 +91,18 @@ const format = async (filename: string, data: string) => {
.replace("{{ commit-message }}", commitMessage)
.replace("/* styles */", styles)
.replace("{{ external-styles }}", externalStyles)
.replace("{{ content }}", md);
.replace("{{ content }}", md)
.replace("{{ blog-posts }}", await (await fs.readdir('./src/pages/blog')
.then(async (files) => await Promise.all(files.map(async (file) => {
const [frontMatter] = (await fs.readFile(`./src/pages/blog/${file}`, 'utf-8')).split('---');
const json = parser.parse(frontMatter);
return `
<button onclick="window.location.href = '/blog/${parseFilename(file)}'" style="width:100%;padding:10px;text-align:left;">
<h2>${json.meta.title}</h2>
<p style="margin:0;padding-bottom:5px;">${json.meta.description}</p>
<small>${json.meta.date}</small>
</button>`;
})))).join(''));

const beautified = await prettier.format(page, { parser: "html", htmlWhitespaceSensitivity: "ignore", printWidth: Infinity });

Expand All @@ -101,74 +120,75 @@ ${dedent`
return comment + beautified;
};

const parseFilename = (filename: string) => filename.replace(/\[.*\] /g, '').replaceAll(" ", "-").replace(".md", ".html");

const build = async () => {
try {
fs.rmSync(OUTPUT_FOLDER, { recursive: true, force: true });
fs.mkdirSync(OUTPUT_FOLDER);
await fs.rm(OUTPUT_FOLDER, { recursive: true, force: true });
await fs.mkdir(OUTPUT_FOLDER, { recursive: true });

const files = fs.readdirSync("./src/pages/");
const readFilesRecursively = async (dir: string): Promise<string[]> => {
const list = await fs.readdir(dir, { withFileTypes: true });
const results = await Promise.all(list.map(async (file) => {
const filePath = path.join(dir, file.name);
return file.isDirectory() ? readFilesRecursively(filePath) : filePath;
}));
return results.flat();
};

for (const file of files) {
const files = await readFilesRecursively("./src/pages/");

await Promise.all(files.map(async (file) => {
if (file.endsWith(".md")) {
try {
const data = await fs.promises.readFile(`./src/pages/${file}`, "utf-8");
const parsedFilename = parseFilename(file);
const data = await fs.readFile(file, "utf-8");
const formattedData = await format(file, data);
const brotliCompressedData = zlib.brotliCompressSync(formattedData);

const outputFilePath = path.join(OUTPUT_FOLDER, file.replace(".md", ".html"));
await fs.promises.writeFile(`${outputFilePath}.br`, brotliCompressedData);
await fs.promises.writeFile(outputFilePath, formattedData);
const outputFilePath = path.join(OUTPUT_FOLDER, path.relative("./src/pages", parsedFilename));
await fs.mkdir(path.dirname(outputFilePath), { recursive: true });
await fs.writeFile(`${outputFilePath}.br`, brotliCompressedData);
await fs.writeFile(outputFilePath, formattedData);
successLog(`Built ${file}`);
} catch (e) {
errorLog(`Error processing ${file}:`);
console.error(e);
}
}
}
}));

fs.cpSync('./src/public', OUTPUT_FOLDER, { recursive: true });
await fs.cp('./src/public', OUTPUT_FOLDER, { recursive: true });
successLog("Site built successfully!");
} catch (e) {
errorLog("Error during build:");
console.error(e);
}
};

let rootTemplate = fs.readFileSync(TEMPLATE_FILE, "utf-8");
fs.mkdirSync(OUTPUT_FOLDER, { recursive: true });
let rootTemplate = await fs.readFile(TEMPLATE_FILE, "utf-8");
await fs.mkdir(OUTPUT_FOLDER, { recursive: true });

infoLog("Building site...");
console.log();

const debouncedBuild = debounce(async () => {
infoLog('Building...');
rootTemplate = fs.readFileSync(TEMPLATE_FILE, "utf-8");
rootTemplate = await fs.readFile(TEMPLATE_FILE, "utf-8");
await build();
}, 500);

await build();

if (process.argv[2] === 'watch') {
chokidar.watch(TEMPLATE_FILE).on("change", async () => {
debouncedBuild();
});
chokidar.watch("./src").on("all", async () => {
debouncedBuild();
});
} else if (process.argv[2] === 'serve') {
chokidar.watch(TEMPLATE_FILE).on("change", async () => {
debouncedBuild();
});
chokidar.watch("./src").on("all", async () => {
debouncedBuild();
});

const http = require('http');
const handler = require('serve-handler');

http.createServer((req: any, res: any) => {
return handler(req, res, { public: OUTPUT_FOLDER });
}).listen(8080);

successLog('Server running at http://localhost:8080/');
if (process.argv[2] === 'watch' || process.argv[2] === 'serve') {
chokidar.watch(TEMPLATE_FILE).on("change", debouncedBuild);
chokidar.watch("./src").on("all", debouncedBuild);

if (process.argv[2] === 'serve') {
const http = require('http');
const handler = require('serve-handler');

http.createServer((req: any, res: any) => handler(req, res, { public: OUTPUT_FOLDER })).listen(8080);
successLog('Server running at http://localhost:8080/');
}
}
11 changes: 11 additions & 0 deletions src/pages/blog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<meta>
<title>blog</title>
<description>my ultra super-duper-uber cool blog!!</description>

<use-style>/style.scss</use-style>
</meta>
---
# blog
my ultra super-duper-uber cool blog!!

{{ blog-posts }}
11 changes: 11 additions & 0 deletions src/pages/blog/[19-08-2024] hello blog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<meta>
<title>hello blog!</title>
<description>this is the first entry of my blog</description>
<date>19/08/2024</date>

<type>blog post</type>

<use-style>/style.scss</use-style>
</meta>
---
this is the first entry of my blog, i used to have a blog before but i deleted it because i was too lazy to update it. i hope i can keep this one up for a while! i'll mainly *still* post about my projects and programming languages, or maybe some cool technologies i find. either way i hope you enjoy reading my blog!
7 changes: 7 additions & 0 deletions src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -460,4 +460,11 @@ a:not(folders > a) {

.bounce {
transform: scale(1.1);
}

hr {
border: 0;
height: 1px;
background: var(--surface1);
margin: 10px 0;
}

0 comments on commit 894d7d2

Please sign in to comment.