blog!
This commit is contained in:
parent
3bae312ec4
commit
1aef9cc9f9
10
index.html
10
index.html
|
@ -10,12 +10,13 @@
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="app">
|
<main>
|
||||||
<div class="info">
|
|
||||||
<h1>hi! i'm august. or kline. </h1>
|
<h1>hi! i'm august. or kline. </h1>
|
||||||
<p>i like to build systems. lately i've been working on
|
<p>lately i've been working on
|
||||||
<a href="https://git.augustkline.com/august/george" target="_blank" rel="noreferer">george</a>.
|
<a href="https://git.augustkline.com/august/george" target="_blank" rel="noreferer">george</a>.
|
||||||
here's my
|
here's my
|
||||||
|
<a href="/blog/">blog</a>
|
||||||
|
and my
|
||||||
<a href="https://git.augustkline.com/august" target="_blank" rel="noreferer">git</a>
|
<a href="https://git.augustkline.com/august" target="_blank" rel="noreferer">git</a>
|
||||||
and my
|
and my
|
||||||
<a href="https://kline.cohost.org" target="_blank" rel="noreferer">cohost</a>
|
<a href="https://kline.cohost.org" target="_blank" rel="noreferer">cohost</a>
|
||||||
|
@ -25,10 +26,9 @@
|
||||||
<a href="/augustklineResume.pdf" target="_blank" rel="noreferer">resume</a>
|
<a href="/augustklineResume.pdf" target="_blank" rel="noreferer">resume</a>
|
||||||
too!)
|
too!)
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</main>
|
||||||
<div id="background">
|
<div id="background">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<script type="module" src="/src/main.ts"></script>
|
<script type="module" src="/src/main.ts"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"watch": ["vite.config.ts","src", "public"],
|
||||||
|
"ext": "js,ts,html,css,md",
|
||||||
|
"exec": "npm run preview"
|
||||||
|
}
|
13
package.json
13
package.json
|
@ -6,10 +6,19 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "tsc && vite build",
|
"build": "tsc && vite build",
|
||||||
"preview": "vite preview"
|
"preview": "npm run build && vite preview"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/node": "^22.7.4",
|
||||||
|
"@types/xml": "^1.0.11",
|
||||||
|
"feed": "^4.2.2",
|
||||||
|
"highlight.js": "^11.10.0",
|
||||||
|
"marked": "^14.1.2",
|
||||||
"typescript": "^5.2.2",
|
"typescript": "^5.2.2",
|
||||||
"vite": "^5.2.0"
|
"vite": "^5.2.0",
|
||||||
|
"gray-matter": "^4.0.3",
|
||||||
|
"http-server": "^14.1.1",
|
||||||
|
"nodemon": "^3.1.7",
|
||||||
|
"xml": "^1.0.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
/*!
|
||||||
|
Theme: GitHub
|
||||||
|
Description: Light theme as seen on github.com
|
||||||
|
Author: github.com
|
||||||
|
Maintainer: @Hirse
|
||||||
|
Updated: 2021-05-15
|
||||||
|
|
||||||
|
Outdated base version: https://github.com/primer/github-syntax-light
|
||||||
|
Current colors taken from GitHub's CSS
|
||||||
|
*/
|
||||||
|
|
||||||
|
.hljs {
|
||||||
|
color: #24292e;
|
||||||
|
background: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-doctag,
|
||||||
|
.hljs-keyword,
|
||||||
|
.hljs-meta .hljs-keyword,
|
||||||
|
.hljs-template-tag,
|
||||||
|
.hljs-template-variable,
|
||||||
|
.hljs-type,
|
||||||
|
.hljs-variable.language_ {
|
||||||
|
/* prettylights-syntax-keyword */
|
||||||
|
color: #d73a49;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-title,
|
||||||
|
.hljs-title.class_,
|
||||||
|
.hljs-title.class_.inherited__,
|
||||||
|
.hljs-title.function_ {
|
||||||
|
/* prettylights-syntax-entity */
|
||||||
|
color: #6f42c1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-attr,
|
||||||
|
.hljs-attribute,
|
||||||
|
.hljs-literal,
|
||||||
|
.hljs-meta,
|
||||||
|
.hljs-number,
|
||||||
|
.hljs-operator,
|
||||||
|
.hljs-variable,
|
||||||
|
.hljs-selector-attr,
|
||||||
|
.hljs-selector-class,
|
||||||
|
.hljs-selector-id {
|
||||||
|
/* prettylights-syntax-constant */
|
||||||
|
color: #005cc5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-regexp,
|
||||||
|
.hljs-string,
|
||||||
|
.hljs-meta .hljs-string {
|
||||||
|
/* prettylights-syntax-string */
|
||||||
|
color: #032f62;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-built_in,
|
||||||
|
.hljs-symbol {
|
||||||
|
/* prettylights-syntax-variable */
|
||||||
|
color: #e36209;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-comment,
|
||||||
|
.hljs-code,
|
||||||
|
.hljs-formula {
|
||||||
|
/* prettylights-syntax-comment */
|
||||||
|
color: #6a737d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-name,
|
||||||
|
.hljs-quote,
|
||||||
|
.hljs-selector-tag,
|
||||||
|
.hljs-selector-pseudo {
|
||||||
|
/* prettylights-syntax-entity-tag */
|
||||||
|
color: #22863a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-subst {
|
||||||
|
/* prettylights-syntax-storage-modifier-import */
|
||||||
|
color: #24292e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-section {
|
||||||
|
/* prettylights-syntax-markup-heading */
|
||||||
|
color: #005cc5;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-bullet {
|
||||||
|
/* prettylights-syntax-markup-list */
|
||||||
|
color: #735c0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-emphasis {
|
||||||
|
/* prettylights-syntax-markup-italic */
|
||||||
|
color: #24292e;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-strong {
|
||||||
|
/* prettylights-syntax-markup-bold */
|
||||||
|
color: #24292e;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-addition {
|
||||||
|
/* prettylights-syntax-markup-inserted */
|
||||||
|
color: #22863a;
|
||||||
|
background-color: #f0fff4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-deletion {
|
||||||
|
/* prettylights-syntax-markup-deleted */
|
||||||
|
color: #b31d28;
|
||||||
|
background-color: #ffeef0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-char.escape_,
|
||||||
|
.hljs-link,
|
||||||
|
.hljs-params,
|
||||||
|
.hljs-property,
|
||||||
|
.hljs-punctuation,
|
||||||
|
.hljs-tag {
|
||||||
|
/* purposely ignored */
|
||||||
|
}
|
|
@ -11,60 +11,101 @@
|
||||||
--link-color: var(--text-color);
|
--link-color: var(--text-color);
|
||||||
--link-shadow-color: rgba(0, 0, 0, 0.5);
|
--link-shadow-color: rgba(0, 0, 0, 0.5);
|
||||||
--border-color: rgba(200, 200, 200, 0.5);
|
--border-color: rgba(200, 200, 200, 0.5);
|
||||||
--text-bg-color: rgba(255, 255, 255, 0.9);
|
--text-bg-color: rgba(255, 255, 255, 0.95);
|
||||||
--text-border-shadow-color: rgba(255, 255, 255, 0.7);
|
--text-border-shadow-color: rgba(255, 255, 255, 0.7);
|
||||||
--text-shadow-color: rgba(0, 0, 0, 0.1);
|
--text-shadow-color: rgba(0, 0, 0, 0.1);
|
||||||
--img-bg-color: rgba(50, 50, 50, 0.2);
|
--img-bg-color: rgba(50, 50, 50, 0.2);
|
||||||
--img-border-color: rgba(255, 255, 255, 0.8);
|
--img-border-color: rgba(255, 255, 255, 0.8);
|
||||||
|
--font-base-size: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
body,
|
body,
|
||||||
html {
|
html {
|
||||||
inline-size: 100%;
|
align-items: center;
|
||||||
block-size: 100%;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
#app {
|
|
||||||
inline-size: 100%;
|
|
||||||
block-size: 100%;
|
block-size: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
inline-size: 100%;
|
||||||
|
justify-content: center;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
overflow: hidden;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
position: relative;
|
position: relative;
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
flex-direction: column;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1,
|
||||||
font-size: 1.5rem;
|
h2,
|
||||||
|
h3 {
|
||||||
margin-block: .5rem;
|
margin-block: .5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: calc(var(--font-base-size) * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: calc(var(--font-base-size) * 1.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: calc(var(--font-base-size) * 1.6);
|
||||||
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
font-size: 1.5rem;
|
font-size: calc(var(--font-base-size) * 1.5);
|
||||||
margin: 0;
|
margin: 0;
|
||||||
text-align: justify;
|
|
||||||
text-align-last: center;
|
|
||||||
inline-size: 100%;
|
inline-size: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: var(--link-color);
|
color: var(--link-color);
|
||||||
text-decoration: none;
|
|
||||||
transition: .2s text-shadow, .2s transform;
|
transition: .2s text-shadow, .2s transform;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:hover {
|
a {
|
||||||
|
color: var(--link-color);
|
||||||
|
transition: .2s text-shadow, .2s transform;
|
||||||
|
display: inline-block;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
transition: .2s text-shadow, .2s box-shadow,
|
||||||
|
.2s transform;
|
||||||
|
|
||||||
|
&:has(> p) {
|
||||||
|
&:hover {
|
||||||
|
box-shadow: 0rem 0.2rem 1rem var(--link-shadow-color);
|
||||||
|
transform: translateY(-7%);
|
||||||
|
}
|
||||||
|
|
||||||
|
color: var(--link-color);
|
||||||
|
display: inline-block;
|
||||||
|
border-radius: 1rem;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(:has(> p)) {
|
||||||
|
&:hover {
|
||||||
text-shadow: 0rem 0.2rem 1rem var(--link-shadow-color);
|
text-shadow: 0rem 0.2rem 1rem var(--link-shadow-color);
|
||||||
transform: translateY(-7%) scale(1.01);
|
transform: translateY(-7%) scale(1.01);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#background {
|
||||||
|
transform-style: preserve-3d;
|
||||||
|
transform: rotateX(var(--rotate-x)) rotateY(var(--rotate-y));
|
||||||
|
inline-size: 100%;
|
||||||
|
block-size: 100%;
|
||||||
|
z-index: -1;
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
&[loaded] img {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
img {
|
img {
|
||||||
transform: translate(-50%, -50%) translateZ(var(--translate-z));
|
transform: translate(-50%, -50%) translateZ(var(--translate-z));
|
||||||
|
@ -80,37 +121,42 @@ img {
|
||||||
-0.05rem 0.05rem 0px var(--img-bg-color),
|
-0.05rem 0.05rem 0px var(--img-bg-color),
|
||||||
0 0 1rem rgba(0, 0, 0, 0.3);
|
0 0 1rem rgba(0, 0, 0, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
#background {
|
|
||||||
transform-style: preserve-3d;
|
|
||||||
transform: rotateX(var(--rotate-x)) rotateY(var(--rotate-y));
|
|
||||||
inline-size: 100%;
|
|
||||||
block-size: 100%;
|
|
||||||
z-index: -1;
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
&[loaded] img {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.info {
|
pre {
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
border-radius: 1rem;
|
||||||
|
box-shadow: 0.05rem 0.05rem 0px var(--img-bg-color),
|
||||||
|
-0.05rem -0.05rem 0px var(--img-bg-color),
|
||||||
|
0.05rem -0.05rem 0px var(--img-bg-color),
|
||||||
|
-0.05rem 0.05rem 0px var(--img-bg-color),
|
||||||
|
0 0 1rem rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.blog {}
|
||||||
|
|
||||||
|
main {
|
||||||
|
overflow-inline: auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
|
||||||
background: var(--text-bg-color);
|
background: var(--text-bg-color);
|
||||||
backdrop-filter: blur(10px);
|
backdrop-filter: blur(10px);
|
||||||
-webkit-backdrop-filter: blur(10px);
|
-webkit-backdrop-filter: blur(10px);
|
||||||
border: 0.01rem solid var(--border-color);
|
border: 0.01rem solid var(--border-color);
|
||||||
margin: 1px;
|
margin: 1px;
|
||||||
padding: .8rem 1.6rem;
|
padding: .8rem 1.6rem;
|
||||||
inline-size: clamp(20rem, 30%, 40rem);
|
max-inline-size: clamp(20rem, 50%, 40rem);
|
||||||
border-radius: 1rem;
|
border-radius: 1rem;
|
||||||
box-shadow: 0.05rem 0.05rem 0px var(--text-border-shadow-color),
|
box-shadow: 0.05rem 0.05rem 0px var(--text-border-shadow-color),
|
||||||
-0.05rem -0.05rem 0px var(--text-border-shadow-color),
|
-0.05rem -0.05rem 0px var(--text-border-shadow-color),
|
||||||
0.05rem -0.05rem 0px var(--text-border-shadow-color),
|
0.05rem -0.05rem 0px var(--text-border-shadow-color),
|
||||||
-0.05rem 0.05rem 0px var(--text-border-shadow-color),
|
-0.05rem 0.05rem 0px var(--text-border-shadow-color),
|
||||||
0rem 0rem 2rem var(--text-shadow-color);
|
0rem 0rem 2rem var(--text-shadow-color);
|
||||||
|
|
||||||
|
img {
|
||||||
|
inline-size: 100%;
|
||||||
|
border-radius: 1rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-reduced-motion: reduce) {
|
@media (prefers-reduced-motion: reduce) {
|
|
@ -0,0 +1,13 @@
|
||||||
|
---
|
||||||
|
title: hello word
|
||||||
|
date: 2024-9-30
|
||||||
|
desc: the first post on my blog! check back in soon cause this is very janky rn lol
|
||||||
|
---
|
||||||
|
|
||||||
|
# hi!
|
||||||
|
|
||||||
|
i just wanted to get something up and running before cohost shuts down
|
||||||
|
|
||||||
|
this will look prettier soon i was just rushing!
|
||||||
|
|
||||||
|
you can subscribe with [rss](/feed.xml) and eventually i think i will add automated instagram posts whenever there's a new update, but that's for later
|
|
@ -191,7 +191,8 @@ window.addEventListener("load", () => {
|
||||||
|
|
||||||
const dpi = window.devicePixelRatio;
|
const dpi = window.devicePixelRatio;
|
||||||
const moveImages = (t: number) => {
|
const moveImages = (t: number) => {
|
||||||
const images = document.body.getElementsByTagName("img");
|
const background = document.getElementById("background")!;
|
||||||
|
const images = background.getElementsByTagName("img");
|
||||||
for (let i = 0; i < images.length; i++) {
|
for (let i = 0; i < images.length; i++) {
|
||||||
const img = images[i];
|
const img = images[i];
|
||||||
let top = toDomPrecision(
|
let top = toDomPrecision(
|
||||||
|
|
|
@ -0,0 +1,186 @@
|
||||||
|
import { defineConfig } from "vite";
|
||||||
|
import fs from "fs";
|
||||||
|
import path from "path";
|
||||||
|
import { marked, Token, Tokens } from "marked";
|
||||||
|
import xml from "xml";
|
||||||
|
import matter from "gray-matter";
|
||||||
|
import highlight from "highlight.js";
|
||||||
|
|
||||||
|
const blogDir = path.resolve(__dirname, "src/blog");
|
||||||
|
const outputDir = path.resolve(__dirname, "dist/blog");
|
||||||
|
const rssFeedPath = path.resolve(__dirname, "dist/feed.xml");
|
||||||
|
|
||||||
|
const hostname = "https://augustkline.com";
|
||||||
|
const blogUrl = `${hostname}/blog`;
|
||||||
|
|
||||||
|
interface Articles {
|
||||||
|
title: string;
|
||||||
|
link: string;
|
||||||
|
description: string;
|
||||||
|
pubDate: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const renderer = new marked.Renderer();
|
||||||
|
|
||||||
|
renderer.code = ({ text, lang }: Tokens.Code) => {
|
||||||
|
const validLang = highlight.getLanguage(lang!) ? lang! : "plaintext";
|
||||||
|
const highlightedCode = highlight.highlight(text!, { language: validLang });
|
||||||
|
return `<pre><code class="language-${validLang}">${highlightedCode.value}</code></pre>`;
|
||||||
|
};
|
||||||
|
|
||||||
|
marked.setOptions({
|
||||||
|
renderer,
|
||||||
|
gfm: true,
|
||||||
|
breaks: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
function generateBlogHtml() {
|
||||||
|
fs.mkdirSync(outputDir, { recursive: true });
|
||||||
|
|
||||||
|
const articles: Articles[] = [];
|
||||||
|
|
||||||
|
let blurbs: { date: string; content: string }[] = [];
|
||||||
|
|
||||||
|
fs.readdirSync(blogDir).forEach((file) => {
|
||||||
|
if (file.endsWith(".md")) {
|
||||||
|
const filePath = path.join(blogDir, file);
|
||||||
|
const str = fs.readFileSync(filePath, "utf-8");
|
||||||
|
let { data, content } = matter(str);
|
||||||
|
|
||||||
|
const slug = `${data.date!}-${data.title!.replace(/ /g, "-")}`;
|
||||||
|
|
||||||
|
const html_content = marked.parse(content);
|
||||||
|
|
||||||
|
const blogPostsPath = path.join(outputDir, `${slug}.html`);
|
||||||
|
|
||||||
|
const postHtml = `
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>${data.title!}</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/style.css">
|
||||||
|
<link rel="stylesheet" type="text/css" href="/github.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main>
|
||||||
|
${html_content}
|
||||||
|
<a href="/">Back to Home</a>
|
||||||
|
</main>
|
||||||
|
<div id="background">
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
<script type="module" src="/main.js"></script>
|
||||||
|
</html>
|
||||||
|
`;
|
||||||
|
|
||||||
|
const link = `/blog/${slug}.html`;
|
||||||
|
const blurbHtml = `
|
||||||
|
<div>
|
||||||
|
<a href="${link}">
|
||||||
|
<h2>${data.title!}</h2>
|
||||||
|
<p>${new Date(data.date!).toDateString()}</p>
|
||||||
|
<p>${data.desc!}</p>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
blurbs.push({ date: data.date!, content: blurbHtml });
|
||||||
|
|
||||||
|
fs.writeFileSync(blogPostsPath, postHtml);
|
||||||
|
|
||||||
|
// Store article data for RSS
|
||||||
|
articles.push({
|
||||||
|
title: data.title!,
|
||||||
|
link: link,
|
||||||
|
description: data.desc!,
|
||||||
|
pubDate: data.date!,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const blogIndexPath = path.join(outputDir, "index.html");
|
||||||
|
blurbs.sort((a, b) => {
|
||||||
|
return new Date(b.date).getTime() - new Date(a.date).getTime();
|
||||||
|
});
|
||||||
|
let blurbsHtml: string = "";
|
||||||
|
for (let blurb in blurbs) {
|
||||||
|
blurbsHtml = blurbsHtml.concat(blurbs[blurb].content);
|
||||||
|
}
|
||||||
|
const blogIndexHtml = `
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>august kline's blog</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/style.css">
|
||||||
|
<link rel="stylesheet" type="text/css" href="/github.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main>
|
||||||
|
<h1>ʕ·ᴥ·ʔ-☆ august kline's blog ☆</h1>
|
||||||
|
${blurbsHtml}
|
||||||
|
</main>
|
||||||
|
<div id="background">
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
<script type="module" src="/main.js"></script>
|
||||||
|
</html>
|
||||||
|
`;
|
||||||
|
fs.writeFileSync(blogIndexPath, blogIndexHtml);
|
||||||
|
return articles;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to generate RSS feed
|
||||||
|
function generateRssFeed(articles: Articles[]) {
|
||||||
|
const feedItems = articles.map((article) => ({
|
||||||
|
item: [
|
||||||
|
{ title: article.title },
|
||||||
|
{ link: article.link },
|
||||||
|
{ description: article.description },
|
||||||
|
{ pubDate: article.pubDate },
|
||||||
|
],
|
||||||
|
}));
|
||||||
|
|
||||||
|
const rss = {
|
||||||
|
rss: [
|
||||||
|
{
|
||||||
|
channel: [
|
||||||
|
{ title: "ʕ·ᴥ·ʔ-☆ august kline's blog ☆" },
|
||||||
|
{ link: `${blogUrl}` }, // Update with your domain
|
||||||
|
{
|
||||||
|
description:
|
||||||
|
"whatever's on my mind, short essays, tech stuff, etc :)",
|
||||||
|
},
|
||||||
|
...feedItems,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const rssXml = xml(rss, { declaration: true });
|
||||||
|
fs.writeFileSync(rssFeedPath, rssXml);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export Vite config
|
||||||
|
export default defineConfig({
|
||||||
|
build: {
|
||||||
|
rollupOptions: {
|
||||||
|
output: {
|
||||||
|
entryFileNames: `main.js`,
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
{
|
||||||
|
name: "generate-blog-html-and-rss",
|
||||||
|
writeBundle() {
|
||||||
|
// parses blog markdown, writes the blog endpoints and returns array of article data
|
||||||
|
const articles = generateBlogHtml();
|
||||||
|
generateRssFeed(articles);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
Loading…
Reference in New Issue