From 013c7cef7f505dafbb342b9c91987ef0338231fe Mon Sep 17 00:00:00 2001 From: sophie Date: Tue, 23 Jul 2024 01:04:20 +0300 Subject: [PATCH] website 2 --- .forgejo/workflows/update.yaml | 2 +- .gitignore | 3 - LICENSE | 10 -- README.md | 11 +- bun.lockb | Bin 22999 -> 14666 bytes package.json | 29 +++-- src/build.ts | 99 --------------- src/index.ts | 111 ++++++++++++++++ src/plugins/dev.ts | 93 ++++++++++++++ src/plugins/markdown-compiler.ts | 22 ++++ src/plugins/markdown-metadata.ts | 29 +++++ src/plugins/ts-compiler.ts | 41 ++++++ src/plugins/variables.ts | 36 ++++++ src/readme.md | 97 ++++++++++++++ src/web/blog.html | 106 ---------------- src/web/index.html | 119 ------------------ website/blog.html | 24 ++++ website/blog.ts | 34 +++++ .../blogs/opensource-watch-comparison.md | 0 .../blogs/raspberry-pi-struggles.md | 0 {src/web => website}/blogs/why-i-syncthing.md | 0 website/index.html | 54 ++++++++ {src/web/ts => website}/index.ts | 2 +- {src/web => website}/key.txt | 0 {src/web => website}/sticker.webp | Bin website/style.css | 36 ++++++ website/templates/head.html | 26 ++++ 27 files changed, 626 insertions(+), 358 deletions(-) delete mode 100644 LICENSE delete mode 100644 src/build.ts create mode 100644 src/index.ts create mode 100644 src/plugins/dev.ts create mode 100644 src/plugins/markdown-compiler.ts create mode 100644 src/plugins/markdown-metadata.ts create mode 100644 src/plugins/ts-compiler.ts create mode 100644 src/plugins/variables.ts create mode 100644 src/readme.md delete mode 100644 src/web/blog.html delete mode 100644 src/web/index.html create mode 100644 website/blog.html create mode 100644 website/blog.ts rename {src/web => website}/blogs/opensource-watch-comparison.md (100%) rename {src/web => website}/blogs/raspberry-pi-struggles.md (100%) rename {src/web => website}/blogs/why-i-syncthing.md (100%) create mode 100644 website/index.html rename {src/web/ts => website}/index.ts (99%) rename {src/web => website}/key.txt (100%) rename {src/web => website}/sticker.webp (100%) create mode 100644 website/style.css create mode 100644 website/templates/head.html diff --git a/.forgejo/workflows/update.yaml b/.forgejo/workflows/update.yaml index 0ecd9ed..b1723ed 100644 --- a/.forgejo/workflows/update.yaml +++ b/.forgejo/workflows/update.yaml @@ -11,7 +11,7 @@ jobs: apt-get -qq install rsync shell: bash - run: bun install - - run: bun src/build.ts --build + - run: bun run prod - name: Install SSH Key uses: http://github.com/shimataro/ssh-key-action@v2 with: diff --git a/.gitignore b/.gitignore index 19c165c..9b1ee42 100644 --- a/.gitignore +++ b/.gitignore @@ -173,6 +173,3 @@ dist # Finder (MacOS) folder config .DS_Store - -dist -src/web/dist.js \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index cde4ac6..0000000 --- a/LICENSE +++ /dev/null @@ -1,10 +0,0 @@ -This is free and unencumbered software released into the public domain. - -Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. - -In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and -successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -For more information, please refer to diff --git a/README.md b/README.md index fb2e46a..14718fc 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,7 @@ -# sophie's website -this website is very simple it is located in src/web. -there is a very sophisticated build script in src/build.ts ! -it even supports HMR! \ No newline at end of file +# sophie's website 2 + +contains a extremely complicated buildscript + +run prod with `bun run prod` +edit ssg plugins in src/plugins +read src/buildsystem.md for more info \ No newline at end of file diff --git a/bun.lockb b/bun.lockb index 57777553c792e18ef268eeb614da71938284e4a1..4bfaca006fcf18f0b5aeb0971df419353be61229 100755 GIT binary patch literal 14666 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 literal 22999 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 diff --git a/package.json b/package.json index edd2991..13ad976 100644 --- a/package.json +++ b/package.json @@ -1,24 +1,23 @@ { - "name": "sophie", - "module": "index.ts", + "name": "website2", + "module": "src/index.ts", "type": "module", + "scripts": { + "prod": "bun src/index.ts --prod", + "dev": "bun src/index.ts --dev" + }, "devDependencies": { - "@types/bun": "latest", - "@types/node": "^20.11.30", - "@types/p5": "^1.7.6", - "@types/serve-handler": "^6.1.4", - "esbuild": "0.20.2", - "micro": "^10.0.1", - "serve-handler": "^6.1.5" + "@types/bun": "latest" }, "peerDependencies": { "typescript": "^5.0.0" }, - "scripts": { - "dev": "bun src/build.ts --dev", - "build": "bun src/build.ts --build" - }, "dependencies": { - "ws": "^8.16.0" + "@types/mime-types": "^2.1.4", + "@types/p5": "^1.7.6", + "esbuild": "^0.23.0", + "marked": "^13.0.2", + "mime-types": "^2.1.35", + "p5": "^1.9.4" } -} +} \ No newline at end of file diff --git a/src/build.ts b/src/build.ts deleted file mode 100644 index 271857c..0000000 --- a/src/build.ts +++ /dev/null @@ -1,99 +0,0 @@ -import * as esbuild from "esbuild"; -import { watch, cpSync, rmdirSync, readFileSync, ReadStream } from "node:fs"; -import { serve } from "micro"; -import { Server } from "node:http"; -import handler from "serve-handler"; -import { Readable } from "node:stream"; -import { WebSocketServer } from "ws"; - -const script = `let t;function rr() {console.log("connecting to dev server") -let a = new WebSocket("ws://localhost:8081"); -a.addEventListener("message", g => { - if(g.data == "refresh"){ - location.reload() - } -}); -a.addEventListener("open", () => { - console.log("connected") -}) -a.addEventListener("close", () => { - console.log("socket closed, restarting in 1s") - clearInterval(t) - t = setTimeout(()=>{ - rr() - },1000) -})};window.addEventListener("load", () => rr())`; - -const argv = process.argv.slice(2); - -async function buildTs() { - console.log("[dev] Building file.."); - await esbuild.build({ - entryPoints: ["./src/web/ts/index.ts"], - outfile: "./src/web/dist.js", - }); -} -await buildTs(); - -if (argv[0] == "--build") { - try { - rmdirSync("./dist"); - } catch {} - cpSync("./src/web/", "./dist/", { recursive: true }); - rmdirSync("./dist/ts", { recursive: true }); - - console.log("[dev] View the dist folder"); -} - -if (argv[0] == "--dev") { - const wss = new WebSocketServer({ port: 8081 }); - let allConnections = new Map(); - wss.on("connection", function connection(ws) { - const id = Math.random(); - allConnections.set(id, ws as any); - - ws.on("error", console.error); - ws.on("close", () => { - allConnections.delete(id); - }); - }); - const server = new Server( - serve(async (req, res) => { - await handler( - req, - res, - { - directoryListing: false, - public: "src/web/", - cleanUrls: false - }, - { - createReadStream(path, options) { - let sx = readFileSync(path).toString("utf8"); - - if (!path.toString().endsWith(".html")) { - return Readable.from([sx]) as ReadStream; - } - - sx = sx.replace("", ``); - return Readable.from([sx]) as ReadStream; - }, - } - ); - }) - ); - server.listen(8080); - console.log("[http] Listening HTTP on 8080."); - watch( - "./src/web", - { - recursive: true, - }, - async (e, f) => { - if (f == "dist.js") return; - console.log("[dev] Noticed update in " + f + ", of type " + e + "."); - allConnections.forEach((z) => z.send("refresh")); - await buildTs(); - } - ); -} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..76899a1 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,111 @@ +/* +⡿⣿⠿⢿⠿⣿⢿⡿⡿⡿⢿⠿⣿⠻⢟⡟⣋⣛⡻⡛⠋⠉⠀⠀⠀⠀⢈⡁⠉⢍⠛⡷⣀⠀⠀⠀⠀⠀⠀⠲⢂⠟⡁⢢⢛⡤⢁⣀⡠⣄ +⡳⡜⡺⢌⡳⢍⠎⡵⢣⢝⡩⢒⠡⠉⢈⣨⢗⡶⠛⠁⠀⠀⠀⠀⠉⢉⣲⣌⠑⢮⠑⠺⡅⠉⠁⠀⠒⠚⠷⣿⣌⡣⢜⠠⢎⠰⡉⠆⠱⠌ +⠱⠘⡑⠩⡉⢌⠲⡱⢩⣾⣫⣥⣶⣶⡿⣳⢏⣴⠎⠉⣹⢢⣀⣀⣶⡏⠀⠘⡷⣄⢳⡀⠘⢐⣶⣶⣶⣶⣦⠄⢾⡎⠢⡑⢨⢀⢠⡀⢎⠀ +⠣⡙⠬⠅⠁⠈⠁⠐⣿⣿⣿⣿⣿⣿⣿⣟⣾⣿⣀⣀⣈⣧⣿⣾⣿⣄⣀⡀⢽⣼⡄⢷⡤⣋⣿⣿⣿⣿⣿⣿⣮⣇⠀⠡⢃⡍⢢⣍⠳⣌ +⠂⡍⠂⠀⠀⠀⠀⠀⣹⣿⣿⣿⣿⣿⣿⣿⡟⠛⣿⣿⣏⣿⢻⡇⢀⣿⣿⣿⡿⣿⣿⡈⣷⡱⡞⣿⣿⣿⣿⣿⣿⣿⠀⠀⠢⠐⣃⢤⢫⡔ +⠐⠈⠁⠐⠒⠀⠁⠀⠘⣿⣿⣿⣿⣿⡿⣞⣿⡄⢿⣿⣿⡿⣼⣇⠀⣿⣿⣿⢧⣿⡿⣗⡸⢷⡍⢿⣿⣿⣿⣿⣿⡇⠒⠬⢓⡹⢰⢣⡓⢮ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢿⣿⣿⣿⣿⢿⣯⣿⣦⣙⣋⣵⣿⣿⣦⣌⣛⣽⣿⢯⣟⣧⡟⡼⣘⢧⣿⢻⣿⣿⠟⠐⡉⡒⠬⣁⠎⢦⠙⣃ +⢜⣩⢠⢠⠄⡄⢠⠄⢂⠄⡀⠙⣷⣿⡿⠿⠛⠋⠉⠉⠁⠀⠀⠀⠉⠈⠉⠉⠙⠛⠻⠾⣽⣷⡍⡖⣻⣿⡿⢣⢆⡣⢵⡉⢆⡥⣚⠦⣛⢤ +⢎⡔⣣⢎⡝⡸⢥⡺⢌⠴⡱⣬⠟⠁⢀⣠⠴⠶⠶⢛⠛⠋⠛⠛⠻⠶⢦⣄⠀⠀⠀⠀⠀⠈⠛⢧⡝⣿⠁⠜⠂⢧⠐⠈⠐⡄⠃⠘⠀⢂ +⢞⡼⡱⢞⡜⡳⢤⡙⣆⢦⣱⠏⠀⣰⣿⡃⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣻⣷⡀⠀⠀⠀⠀⠀⠈⢻⡅⡟⣈⠅⡆⢂⠈⡐⠀⠄⡀⠀⠀ +⠊⠼⠹⡄⡙⡜⢧⣽⢞⣮⡏⠀⢰⣿⣿⡿⢦⡌⣁⠒⠐⠂⠐⠀⠀⠐⢉⣩⣽⡇⠀⠀⠀⠀⠀⠀⠈⣷⣰⡌⠭⣰⢀⡱⠌⢢⠱⢠⠌⡘ +⡀⠤⠡⡼⢩⠛⠘⠜⡊⢹⡃⠀⠈⣿⣿⣿⣁⣎⣑⣪⣑⣣⣜⣰⢶⡾⡟⣤⣿⡿⠀⠀⠀⠀⠀⠀⠀⢸⣟⠾⡕⡁⣊⠱⢫⢄⠢⣅⢺⡰ +⠜⣰⢉⠲⣁⠚⡄⠈⡠⢐⡂⠀⠀⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠁⠀⠀⠀⠀⠀⠀⠀⠀⣿⡆⠙⢿⣧⢺⣥⠊⡑⠼⢲⠱ +⠑⡀⢎⡐⡡⢧⠙⣜⢣⢽⡇⠀⠀⠀⠙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⢀⡿⡏⠀⠀⠙⣷⡺⣝⢮⡳⢧⣋ +⠒⠀⠓⡀⠆⢜⠲⢨⡞⡞⣿⣷⣤⣀⠀⠀⢈⣻⣿⣿⣿⣿⣿⣿⡛⠉⠁⠀⠀⠀⠀⠀⠠⠔⠒⣲⡶⢻⡇⠀⠀⠀⠀⠘⢿⡜⢣⢌⡋⡝ +⣹⡖⢦⡴⢀⠞⣲⢏⡞⡡⢻⡀⠟⣫⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣶⣦⣴⣦⣽⣷⣾⠟⠋⠁⣸⠀⠀⠀⠀⠹⡄⠘⢧⢡⡘⠲⣉ +⡣⣽⢲⡍⢯⡘⣷⢫⠔⠡⢻⡆⠀⠐⣿⣿⣽⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠋⠀⠀⢀⡇⠀⠀⠀⠀⠀⠠⣉⢚⣤⢂⠱⡶ +⣣⡙⢶⣘⣧⢼⡳⠃⡌⠐⣉⣇⠀⠀⠘⣿⣲⢻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠋⠀⠀⠀⡼⠀⠀⠀⠀⠀⠀⠀⢐⠎⣀⠉⠀⡈ +⢳⣏⢿⣹⣚⢧⡏⠡⢀⠃⢄⢻⡀⠀⠀⠘⢧⢋⢎⠻⡽⢿⢿⣿⣿⢿⡿⡟⢿⣹⡿⠁⠀⠀⠀⣸⠃⠀⠀⠀⠀⠀⠀⠀⠨⢆⡕⡘⠐⣃ +⣳⡾⣯⠷⠏⣿⠨⠁⠀⠈⢀⠊⢷⡀⠀⠀⠀⠁⠈⠁⠳⠌⠖⠌⠆⠃⠢⠽⠖⠉⠀⠀⠀⢀⣼⠃⢀⠀⠀⠀⠀⠀⠀⠀⠨⢇⠰⠉⠂⠀ +⣏⢷⡱⣎⢣⣏⠧⡀⠀⠀⠀⡜⢠⠿⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣴⠟⠡⠈⠀⠀⠀⠀⠀⠀⠀⠀⢘⡆⠑⡂⠀⠀ +⡞⣦⢖⡫⣅⡾⢣⠅⡀⠀⡐⠤⢣⣻⢿⣿⣿⣶⣶⣤⣄⣀⣀⣀⣀⣀⣀⣠⣤⣶⡾⣟⡿⣥⢃⠂⠄⠀⠀⠀⠀⠀⠀⠀⡜⠤⢄⠀⠀⠀ +⣺⡅⢋⡑⣀⡿⣳⠌⡐⠀⠀⠀⠑⠸⢯⣿⣿⣿⢿⣿⢿⣿⢿⡿⣟⡿⣯⣟⣳⢧⣿⡿⣝⠢⣁⠂⠀⠀⠀⠀⠀⠀⠀⢀⠞⠀⠠⠔⠀⠂ +⡓⣆⢦⠳⡱⣹⢧⡷⣀⡀⠀⠀⠀⣀⠀⡀⣙⣿⣿⡿⣿⢾⣻⣽⣻⣽⣳⣯⣟⣿⣟⡳⠌⠂⠀⠀⠀⠀⠀⠀⠀⠀⠠⣜⠊⠤⠀⠀⠀⠀ +⣵⡼⣩⢮⣱⢯⣟⡷⣯⡽⣯⣻⡵⣮⣟⣽⣛⣿⣿⡿⣽⣯⣟⣾⣳⢯⣷⣻⣿⣿⣯⣷⡲⣄⡄⣠⣀⡀⣀⣀⡤⣔⠻⡄⢋⠜⠀⢠⡀⠀ +*/ +// Five at nit of fredyer +// Hor hor +export abstract class Plugin { + abstract name: string; + abstract rewriteTriggers: string[]; + renameTo?: string; + abstract longLasting: boolean; + + abstract rewriteFile( + file: string, + filePath: string + ): Promise; +} + +import * as fs from "fs"; +import * as path from "path"; + +if (!fs.existsSync("dist")) fs.mkdirSync("dist"); + +const plugins: Plugin[] = []; + +for await (const file of fs.readdirSync(path.join("src", "plugins"))) { + const clas = (await import(path.join(__dirname, "plugins", file))).default; + const plug = new clas(); + + plugins.push(plug); +} + +export async function build() { + try { + fs.rmdirSync("dist"); + } catch {} + + const sourceFiles = fs.readdirSync(path.join("website"), { + recursive: true, + withFileTypes: true, + }); + const globalPlugins = plugins.filter((z) => z.rewriteTriggers.includes("*")); + + for await (const file of sourceFiles) { + if (!file.isFile()) continue; + + const type = file.name.split(".").at(-1); + if (!type) continue; + + const shortname = file.name.slice(0, file.name.length - (type.length + 1)); + const availablePlugins = plugins.filter((z) => + z.rewriteTriggers.includes(type) + ); + + if (availablePlugins.length == 0) { + const oldPath = path.join(file.parentPath, file.name); + fs.cpSync(oldPath, oldPath.replace("website", "dist")); + } + + for await (const plugin of availablePlugins) { + const oldPath = path.join(file.parentPath, file.name); + const newPath = path + .join( + file.parentPath, + shortname + + "." + + (plugin.rewriteTriggers.includes("*") ? type : plugin.renameTo) + ) + .replace("website", "dist"); + let data = fs.readFileSync(oldPath).toString("utf8"); + + for await (const globalPlugin of globalPlugins) { + const rewritten = await globalPlugin.rewriteFile(data, oldPath); + if (!rewritten) continue; + data = rewritten; + } + + let rewrite = await plugin.rewriteFile(data, oldPath); + + if (!rewrite) continue; + + fs.mkdirSync(path.dirname(newPath), { recursive: true }); + fs.writeFileSync(newPath, rewrite); + } + } +} + +await build(); diff --git a/src/plugins/dev.ts b/src/plugins/dev.ts new file mode 100644 index 0000000..7fc1305 --- /dev/null +++ b/src/plugins/dev.ts @@ -0,0 +1,93 @@ +import type { Server, ServerWebSocket } from "bun"; +import { Plugin, build } from ".."; +import * as fs from "fs"; +import mime from "mime-types"; + +const script = `let reconnectTimeout;function connect(){console.log("[--dev] connecting to dev server");let ws=new WebSocket("ws://localhost:8080");ws.addEventListener("message",message=>{if(message.data=="refresh"){location.reload()}});ws.addEventListener("open",()=>{console.log("[--dev] connected")});ws.addEventListener("close",()=>{console.log("[--dev] socket closed, restarting in 1s");clearTimeout(reconnectTimeout);reconnectTimeout=setTimeout(()=>{connect()},1e3)})}window.addEventListener("load",()=>connect());`; + +export default class DevPlugin extends Plugin { + name = "dev"; + rewriteTriggers = []; + renameTo = undefined; + longLasting = true; + server!: Server; + allConnections: ServerWebSocket[] = []; + + constructor() { + super(); + if (!process.argv.includes("--dev")) return; + + fs.watch( + "./website", + { + recursive: true, + }, + async (e, f) => { + console.log("[dev] Noticed update in " + f + ", of type " + e + "."); + this.allConnections.forEach((z) => z.send("refresh")); + await build(); + } + ); + + this.server = Bun.serve({ + fetch(req, server) { + const success = server.upgrade(req); + if (success) { + return undefined; + } + + const url = new URL(req.url); + + let cleanedPath = url.pathname; + if (cleanedPath == "/") cleanedPath = "/index.html"; + if (cleanedPath.endsWith("/")) cleanedPath = cleanedPath.slice(0, -1); + + let fsPath = "./dist" + cleanedPath; + + if (fsPath.match(/\.\.\//g) !== null) { + return undefined; + } + let rawFile; + try { + rawFile = fs.readFileSync(fsPath); + } catch { + return new Response("404 Not Found", { + status: 404, + }); + } + const type = fsPath.split(".").at(-1); + if (!type) return; + if (type == "html") { + + rawFile = rawFile.toString().replace( + "", + `` + ); + } + return new Response(rawFile, { + headers: { + "Content-Type": (mime.lookup(type) || "application/octet-stream") + "; charset=utf-8", + }, + }); + }, + websocket: { + open: (ws) => { + ws.data = Math.random(); + + this.allConnections.push(ws); + }, + message(ws, message) {}, + close: (ws) => { + this.allConnections = this.allConnections.filter( + (z) => z.data != ws.data + ); + }, + }, + port: 8080, + }); + } + + async rewriteFile(file: string, filePath: string) { + return undefined; + } +} diff --git a/src/plugins/markdown-compiler.ts b/src/plugins/markdown-compiler.ts new file mode 100644 index 0000000..f1a136b --- /dev/null +++ b/src/plugins/markdown-compiler.ts @@ -0,0 +1,22 @@ +import { Plugin } from ".."; +import { marked } from "marked"; +import { parseMetadata } from "./markdown-metadata"; + +export default class MarkdownCompiler extends Plugin { + name = "markdown-compiler"; + rewriteTriggers = ["md"] + renameTo = "html" + longLasting = false; + + async rewriteFile(file: string, filePath: string) { + let text = file; + const metadata = parseMetadata(text); + if(metadata) { + let textSplit = text.split('\n'); + textSplit.splice(0, Object.keys(metadata).length); + textSplit.unshift(metadata.title) + text = textSplit.join("\n"); + } + return await marked.parse(text); + } +} \ No newline at end of file diff --git a/src/plugins/markdown-metadata.ts b/src/plugins/markdown-metadata.ts new file mode 100644 index 0000000..2b970e2 --- /dev/null +++ b/src/plugins/markdown-metadata.ts @@ -0,0 +1,29 @@ +import { Plugin } from ".."; + +export function parseMetadata(file: string) { + if (!/^=+$/gm.test(file)) return; + const splitfile = file.split("\n"); + let properties: Record | undefined; + for (let i = 0; i < splitfile.length; i++) { + if (!properties) properties = {}; + const line = splitfile[i]; + if (/^=+$/gm.test(line)) break; + const parts = line.split("="); + if (parts.length !== 2) break; + properties[parts[0].trim()] = parts[1].trim(); + } + return properties; +} + +export default class MarkdownMetadataGenerator extends Plugin { + name = "markdown-metadata"; + rewriteTriggers = ["md"]; + renameTo = "json"; + longLasting = false; + + async rewriteFile(file: string, filePath: string) { + const metadata = parseMetadata(file); + if (!metadata) return; + return JSON.stringify(metadata); + } +} diff --git a/src/plugins/ts-compiler.ts b/src/plugins/ts-compiler.ts new file mode 100644 index 0000000..c16539a --- /dev/null +++ b/src/plugins/ts-compiler.ts @@ -0,0 +1,41 @@ +import { Plugin } from ".."; +import * as fs from "fs"; +import * as esbuild from "esbuild"; + +export default class TSCompiler extends Plugin { + name = "ts-compiler"; + rewriteTriggers = ["ts", "tsx", "jsx"]; + renameTo = "js"; + longLasting = false; + + minify = false; + constructor() { + super(); + if(process.argv.includes("--prod")) { + this.minify = true; + } + } + async rewriteFile(file: string, filePath: string) { + + const result = await esbuild.build({ + stdin: { + contents: file, + sourcefile: filePath.split("/").at(-1), + loader: "ts" + }, + write: false, + outdir: 'out', + minify: this.minify + }); + + if(result.errors.length != 0) { + console.log("TS compiler errored.") + result.errors.forEach(element => { + console.error(element); + }); + } else { + const output = result.outputFiles[0].contents; + return (new TextDecoder()).decode(output); + } + } +} diff --git a/src/plugins/variables.ts b/src/plugins/variables.ts new file mode 100644 index 0000000..91bd8ce --- /dev/null +++ b/src/plugins/variables.ts @@ -0,0 +1,36 @@ +import { Plugin } from ".."; +import * as fs from "fs"; +import * as path from "path"; + +export default class Variables extends Plugin { + name = "variables"; + rewriteTriggers = ["html", "*"]; + renameTo = undefined; + longLasting = false; + + variables: Record = {}; + + constructor() { + super(); + this.variables["__BLOG_POSTS__"] = JSON.stringify( + fs.readdirSync("./website/blogs") + ); + const templatePath = path.resolve(__dirname, "../../website/templates"); + if (fs.existsSync(templatePath)) { + for (const file of fs.readdirSync(templatePath)) { + const id = file.toUpperCase().replace(".HTML", ""); + this.variables["__TEMPLATE_" + id + "__"] = fs + .readFileSync(path.join(templatePath, file)) + .toString("utf8"); + } + } + } + + async rewriteFile(file: string, filePath: string): Promise { + let prevfile = file; + for (const a of Object.entries(this.variables)) { + prevfile = prevfile.replaceAll(a[0], a[1]); + } + return prevfile; + } +} diff --git a/src/readme.md b/src/readme.md new file mode 100644 index 0000000..4bf7df4 --- /dev/null +++ b/src/readme.md @@ -0,0 +1,97 @@ +# sad.ovh build system + +design goals: +1. rewrite and generate custom HTML/TS/JS/whatever.. +2. allow for variables and other important features in buildsystem->html +3. plugins, this ties together the top two +4. HMR and HTML/CSS reloading (in the Dev plugin) +5. Rewriteable file renaming +6. Every plugin runs on the same set of files, and can rename and reinject multiple times + +Psudeo-code build.ts + +```ts +class Plugin { + .. whatever's needed to support the plugin system .. +} + +if(.. not exist dist ..) + .. make dist .. +const plugins: Plugin[] = []; +.. dynamically load plugins into plugins .. + +const srcFiles: File[] = [] +.. get files into file .. + + +export function build () { + for(const file of srcFiles) { + const plugins = plugins.filter(z=>z.rewriteTriggers(file.type)); + if(plugins.length == 0) continue; + + for (const plugin of plugins) { + let filename = file.name + "." + file.type; + let newFilename = path.join("dist", file.name + "." + plugin.renameTo || file.type); + + fs.writeFileSync(newFilename, plugin.rewriteFile(fs.readFileSync(filename), filename)) + } + } +} + +build(); + +``` +Psudeo-code plugins +```ts +class DevPlugin extends Plugin { + rewriteTriggers: ["html"] + renameTo: undefined + longLasting: false; + .. websocket server .. + constructor(.. options from argv of the main executable..) { + .. ran on start of main index.ts executable .. + .. this would be long lasting, so leave if not using --dev .. + + .. use a method on the server that rebuilds if required .. + .. Would run a web server too .. + + } + + rewriteFile(file: string, filePath: string) { + return file.replace("", ``) + } +} +``` + +```ts +class TSCompiler extends Plugin { + rewriteTriggers: ["ts"] + renameTo: "js" + + rewriteFile(file: string, filePath: string) { + // use SWC or TS or esbuild, whatever + } +} +``` + +```ts +class MarkdownMetadataGenerator extends Plugin { + rewriteTriggers: ["md"] + renameTo: "json" + + rewriteFile(file: string, filePath: string) { + return marked.parse(file); + } +} +``` + +```ts +class MarkdownCompiler extends Plugin { + rewriteTriggers: ["md"] + renameTo: "html" + + rewriteFile(file: string, filePath: string) { + return marked.parse(file); + } +} +``` \ No newline at end of file diff --git a/src/web/blog.html b/src/web/blog.html deleted file mode 100644 index 7cdee12..0000000 --- a/src/web/blog.html +++ /dev/null @@ -1,106 +0,0 @@ - - - - - - - - - soph's blog and information - - - - - - - - - - - - - - - - - - - - - -

sophie's blog

- -
Scroll to bottom for comments ↓
- -
- -
- - - - - \ No newline at end of file diff --git a/src/web/index.html b/src/web/index.html deleted file mode 100644 index 0bb7df8..0000000 --- a/src/web/index.html +++ /dev/null @@ -1,119 +0,0 @@ - - - - - - - - - - - sophie's personal site - - - - - - - - - - - - - - - - - - - - - - - - - -
- | | - -
- - I'm Latvian, 17. My name's Sophie. I love listening to music, I have <loading...> song plays. -
- I am a JS/TS developer, mostly specializing in backend work. -
- I play minecraft, and upgun with friends. I have developed many bukkit plugins for Paper/Folia/Spigot - before, and am pretty well versed in them. -
- Contact me at matrix, discord, github (view projects here), sadgit, or mastodon -
- Here's my PGP key. -
- -
- - - Click spacebar to change the themes. - - - - \ No newline at end of file diff --git a/website/blog.html b/website/blog.html new file mode 100644 index 0000000..93cc179 --- /dev/null +++ b/website/blog.html @@ -0,0 +1,24 @@ +__TEMPLATE_HEAD__ + + + + +

sophie's blog

+ +
Scroll to bottom for comments ↓
+ +
+ +
+ + + + + \ No newline at end of file diff --git a/website/blog.ts b/website/blog.ts new file mode 100644 index 0000000..fb0e580 --- /dev/null +++ b/website/blog.ts @@ -0,0 +1,34 @@ +const uriParams = new URLSearchParams(location.search); +if (uriParams.has("md")) { + const error = document.getElementById("error")!; + const renderer = document.getElementById("renderer")!; + const return_back = document.getElementById("return_back")!; + const req = await fetch("/blogs/" + uriParams.get("md") + ".html"); + const giscus = document.querySelector(".giscus")! as HTMLDivElement; + if (req.status != 200) { + error.style.display = "block"; + giscus.style.display = "none"; + } else { + let text = await req.text(); + renderer.innerHTML = text; + } + return_back.style.display = "block"; +} else { + //@ts-expect-error + const blog_posts = __BLOG_POSTS__.map(z => z.replace(".md", "")) + const html_list = document.getElementById("html_list")!; + html_list.style.display = "block"; + for (const blog_post of blog_posts) { + const req = await fetch("/blogs/" + blog_post + ".json"); + const metadata = await req.json(); + const li = document.createElement("li"); + const a = document.createElement("a"); + a.href = "/blog.html?md=" + encodeURIComponent(blog_post); + a.innerText = `${metadata.title} (created ${new Date( + metadata.time * 1000 + //@ts-expect-error + ).toGMTString()})`; + li.appendChild(a); + html_list.appendChild(li); + } +} diff --git a/src/web/blogs/opensource-watch-comparison.md b/website/blogs/opensource-watch-comparison.md similarity index 100% rename from src/web/blogs/opensource-watch-comparison.md rename to website/blogs/opensource-watch-comparison.md diff --git a/src/web/blogs/raspberry-pi-struggles.md b/website/blogs/raspberry-pi-struggles.md similarity index 100% rename from src/web/blogs/raspberry-pi-struggles.md rename to website/blogs/raspberry-pi-struggles.md diff --git a/src/web/blogs/why-i-syncthing.md b/website/blogs/why-i-syncthing.md similarity index 100% rename from src/web/blogs/why-i-syncthing.md rename to website/blogs/why-i-syncthing.md diff --git a/website/index.html b/website/index.html new file mode 100644 index 0000000..d0811f9 --- /dev/null +++ b/website/index.html @@ -0,0 +1,54 @@ +__TEMPLATE_HEAD__ + + + + + + + + + + +
+ | | + +
+ + I'm Latvian, 17. My name's Sophie. I love listening to music, I have <loading...> song plays. +
+ I am a JS/TS developer, mostly specializing in backend work. +
+ I play minecraft, and upgun with friends. I have developed many bukkit plugins for Paper/Folia/Spigot + before, and am pretty well versed in them. +
+ Contact me at matrix, discord, github (view projects here), sadgit, or mastodon +
+ Here's my PGP key. +
+ +
+ + + Click spacebar to change the themes. + + + + \ No newline at end of file diff --git a/src/web/ts/index.ts b/website/index.ts similarity index 99% rename from src/web/ts/index.ts rename to website/index.ts index 205ddf2..33a5593 100644 --- a/src/web/ts/index.ts +++ b/website/index.ts @@ -378,4 +378,4 @@ function mouseDragged() { } } } -} +} \ No newline at end of file diff --git a/src/web/key.txt b/website/key.txt similarity index 100% rename from src/web/key.txt rename to website/key.txt diff --git a/src/web/sticker.webp b/website/sticker.webp similarity index 100% rename from src/web/sticker.webp rename to website/sticker.webp diff --git a/website/style.css b/website/style.css new file mode 100644 index 0000000..5bfef93 --- /dev/null +++ b/website/style.css @@ -0,0 +1,36 @@ +body[data-theme="light"] { + color: #31363F; +} + +body[data-theme="dark"] { + color: #eeeeee; +} + +body[data-theme="dark"]>.center>a { + color: #eeeeee !important; +} + +body[data-theme="light"]>.center>a { + color: #31363F !important; +} + +:root { + font-family: Inter, sans-serif; + font-feature-settings: 'liga' 1, 'calt' 1; +} + +@supports (font-variation-settings: normal) { + :root { + font-family: InterVariable, sans-serif; + } +} + +.center { + position: absolute; + top: 10px; + left: 10px; +} + +.selected { + font-weight: bold; +} \ No newline at end of file diff --git a/website/templates/head.html b/website/templates/head.html new file mode 100644 index 0000000..2c20eca --- /dev/null +++ b/website/templates/head.html @@ -0,0 +1,26 @@ + + + + + + + + + soph's blog and information + + + + + + + + + + + + + + + + + \ No newline at end of file