From 8fb809fa95cc7be0dabc6f47da9b7f96a683c1ef Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Wed, 22 Jan 2025 04:54:03 +0100 Subject: [PATCH] Scaffold basic page layout and site generation Set up the basic layout of the site and greybox its content based on statically generated pages. Content pages uses general base layouts defined centrally to avoid duplicating code. --- cli.js | 24 +++++++++--- content/bases.tsx | 23 +++++++++++ content/index.tsx | 34 ++++++++++++++++ content/pages.tsx | 12 ++++++ content/projects.tsx | 47 ++++++++++++++++++++++ content/types.ts | 7 ++++ content/updates.tsx | 32 +++++++++++++++ index.tsx | 15 -------- public/style.css | 92 ++++++++++++++++++++++++++++++++++++++++++++ tsconfig.json | 3 +- 10 files changed, 268 insertions(+), 21 deletions(-) create mode 100644 content/bases.tsx create mode 100644 content/index.tsx create mode 100644 content/pages.tsx create mode 100644 content/projects.tsx create mode 100644 content/types.ts create mode 100644 content/updates.tsx delete mode 100644 index.tsx create mode 100644 public/style.css diff --git a/cli.js b/cli.js index f54821c..28b5f61 100644 --- a/cli.js +++ b/cli.js @@ -1,9 +1,23 @@ -import { index } from "./build/node/index.js" +import { pages } from "./build/node/content/pages.js" +import { prettify, htmlDocument } from "antihtml"; import * as fs from "node:fs" -if (!fs.existsSync("build/web")) { - fs.mkdirSync("build/web"); +const outDir = "build/web"; +if (!fs.existsSync(outDir)) { + fs.mkdirSync(outDir); } -console.log("writing build/web/index.html"); -fs.writeFileSync("build/web/index.html", index); +for (const page of pages) { + const dirSep = page.ref.indexOf("/"); + if (dirSep !== -1) { + const dir = `${outDir}/${page.ref.slice(0, dirSep)}`; + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir); + } + } + console.log(`writing ${outDir}/${page.ref}`); + fs.writeFileSync(`${outDir}/${page.ref}`, htmlDocument(prettify(page.content))); +} + +console.log(`writing ${outDir}/style.css`); +fs.writeFileSync(`${outDir}/style.css`, fs.readFileSync("public/style.css")); diff --git a/content/bases.tsx b/content/bases.tsx new file mode 100644 index 0000000..cf9f3ae --- /dev/null +++ b/content/bases.tsx @@ -0,0 +1,23 @@ +import type { Node } from "antihtml"; + +interface BaseProps { + title: string; + children: Node | Node[], +} +export function BasePage(props: BaseProps) { + return + + + {props.title} + + + +
+ +
+ {props.children} + + +} diff --git a/content/index.tsx b/content/index.tsx new file mode 100644 index 0000000..e4cef5f --- /dev/null +++ b/content/index.tsx @@ -0,0 +1,34 @@ +import { BasePage } from "./bases.js"; +import { projects } from "./projects.js" +import { updates } from "./updates.js" + +const title = "Hornwitser's Site"; +export const index = { + title, + ref: "index.html", + content: +
+
+
+
+
+

Hi, I'm Hornwitser!

+

+ Grown up, he/him, aro, gray ace +

+
+
+

+ I'm a red dragon that mostly dabble in hobby programming and the occasional artwork. +

+

Latest Updates

+ +

Projects

+ +
+
, +}; diff --git a/content/pages.tsx b/content/pages.tsx new file mode 100644 index 0000000..4b77366 --- /dev/null +++ b/content/pages.tsx @@ -0,0 +1,12 @@ +import type { Page } from "./types.js"; +import { index } from "./index.js"; +import { updates, updatesIndex } from "./updates.js"; +import { projects, projectsIndex } from "./projects.js"; + +export const pages: Page[] = [ + index, + updatesIndex, + ...updates, + projectsIndex, + ...projects, +]; diff --git a/content/projects.tsx b/content/projects.tsx new file mode 100644 index 0000000..a5f0493 --- /dev/null +++ b/content/projects.tsx @@ -0,0 +1,47 @@ +import { BasePage } from "./bases.js"; +import type { Page } from "./types.js"; + +export const projects: Page[] = [ + { + title: "Buddhabrot renderer", + ref: "projects/buddhabrot.html", + }, + { + title: "Wooden Drawing Board", + ref: "projects/drafting-board.html", + }, + { + title: "Flying Hornwitser Paper Craft", + ref: "projects/paper-hornwitser.html", + }, + { + title: "Prototype Soren Plush", + ref: "projects/plush-soren.html", + }, + { + title: "Blender to CSS export script", + ref: "projects/blender-css.html", + }, +].map(page => ({ + title: page.title, + ref: page.ref, + content: +

{page.title}

+

Placeholder content

+
+})); + + +const title = "Hornwitser's Projects"; +export const projectsIndex: Page = { + title, + ref: "projects.html", + content: +
+

{title}

+ +
+
+} diff --git a/content/types.ts b/content/types.ts new file mode 100644 index 0000000..0ee1b88 --- /dev/null +++ b/content/types.ts @@ -0,0 +1,7 @@ +import { Element } from "antihtml"; + +export interface Page { + title: string, + ref: string, + content: Element, +} diff --git a/content/updates.tsx b/content/updates.tsx new file mode 100644 index 0000000..6c5d095 --- /dev/null +++ b/content/updates.tsx @@ -0,0 +1,32 @@ +import { BasePage } from "./bases.js"; +import type { Page } from "./types.js"; + +export const updates: Page[] = [ + { + published: "2025-xx-xx", + title: "Website Launch", + ref: "updates/site-launch.html", + } +].map(page => ({ + title: page.title, + ref: page.ref, + content: +

{page.title}

+

Published: {page.published}

+

Placeholder content

+
+})); + +const title = "Website Updates"; +export const updatesIndex: Page = { + title, + ref: "updates.html", + content: +
+

{title}

+ +
+
+} diff --git a/index.tsx b/index.tsx deleted file mode 100644 index 617144c..0000000 --- a/index.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { htmlDocument, prettify } from "antihtml"; - -export const index = htmlDocument( - prettify( - - - My Website - - -

My Website

-

Hello world!

- - - ) -); diff --git a/public/style.css b/public/style.css new file mode 100644 index 0000000..2a364a9 --- /dev/null +++ b/public/style.css @@ -0,0 +1,92 @@ +/* CSS Reset based on https://piccalil.li/blog/a-more-modern-css-reset/ */ +*, +*::before, +*::after { + box-sizing: border-box; + /* Kill all default margins and paddings */ + margin: 0; + padding: 0; +} + +html { + -moz-text-size-adjust: none; + -webkit-text-size-adjust: none; + text-size-adjust: none; +} + +h1, h2, h3, h4, button, input, label { + line-height: 1.1; +} + +img, svg, picture { + max-width: 100%; + display: block; +} + +input, button, textarea, select { + font-family: inherit; + font-size: inherit; +} + +textarea:not([rows]) { + min-height: 10em; +} + +:target { + scroll-margin-block: 2.5em; +} + +/* Overall styling */ +html { + color-scheme: light dark; + font-family: sans-serif; +} + +hgroup h1 { + margin-bottom: 0.1em; +} +hgroup p { + font-style: italic; + margin-bottom: 1em; +} + +h1, h2, h3, h4 { + margin-block-start: 1.25em; + margin-block-end: 0.5em; +} + +ol, ul { + padding-inline-start: 1.25em; +} + +/* Base Page Layout */ +body { + max-width: 50rem; + padding: 0; + margin-block: 0; + margin-inline: auto; +} + +.header { + padding-block: 1em; +} + +.hero { + height: 30em; + background-color: grey; +} + +/* index */ +.author { + display: grid; + grid-template-columns: auto 1fr; + align-items: center; + gap: 1em; + margin-block: 1em; +} +.author h1 { + margin-block-start: 0; +} +.author p { + margin-block-end: 0; +} diff --git a/tsconfig.json b/tsconfig.json index 7a63bc6..69df90b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,8 @@ { - "files": ["index.tsx"], + "include": ["content"], "compilerOptions": { "outDir": "build/node", + "rootDir": ".", "jsx": "react-jsx", "jsxImportSource": "antihtml",