The rest of the owl

This commit is contained in:
2026-02-28 12:13:24 -06:00
parent 54222db887
commit fdba0fdf8c
60 changed files with 1524 additions and 377 deletions

50
scripts/eleventy/blog.js Normal file
View File

@@ -0,0 +1,50 @@
import fs from "fs";
import * as opml from "opml";
export const setupBlogCollections = eleventyConfig => {
eleventyConfig.addCollection("blogByYear", api => {
const postsByYear = {}
const posts = api.getFilteredByTag('blog')
const years = []
for ( const post of posts ) {
const year = post.date.getFullYear()
if ( !postsByYear[year] ) postsByYear[year] = []
postsByYear[year] = [post, ...postsByYear[year]]
if ( !years.includes(year) ) years.push(year)
}
return years.sort().reverse().map(year => ({
year,
posts: postsByYear[year],
}))
})
eleventyConfig.addCollection("blogByTag", api => {
const postsByTag = {}
const posts = api.getFilteredByTag('blog')
const tags = []
for ( const post of posts ) {
for ( const tag of post.data.blogtags || [] ) {
if ( !postsByTag[tag] ) postsByTag[tag] = []
postsByTag[tag].push(post)
if ( !tags.includes(tag) ) tags.push(tag)
}
}
return tags
.sort()
.map(tag => ({
tag,
posts: postsByTag[tag].reverse(),
}))
})
eleventyConfig.addCollection("opmlByCategory", async api => {
const xml = fs.readFileSync("./src/assets/rss_opml.xml")
const parsed = await new Promise((res, rej) => {
opml.parse(xml, (err, doc) => err ? rej(err) : res(doc))
})
return parsed.opml.body.subs
})
}

10
scripts/eleventy/feed.js Normal file
View File

@@ -0,0 +1,10 @@
export const setupFeedCollections = eleventyConfig => {
eleventyConfig.addCollection("feedDesc", api => {
const posts = api.getFilteredByTag('feed')
return posts
.sort((a, b) => {
return b.date < a.date ? -1 : 1
})
})
}

33
scripts/favicons.js Normal file
View File

@@ -0,0 +1,33 @@
import { favicons } from 'favicons'
import fs from 'fs'
const source = 'src/assets/logo/logo.png'
const cfg = {
path: 'assets/logo/favicon',
appName: 'Garrett Mills',
appDescription: '',
background: '#111111',
theme_color: '#111111',
}
// Generate the favicons and metadata:
const res = await favicons(source, cfg)
// Write out the favicon images:
for ( const img of res.images ) {
fs.writeFileSync(`src/assets/logo/favicon/${img.name}`, img.contents)
if ( img.name === 'favicon.ico' ) {
// Write the favicon to the root to support older browsers
fs.writeFileSync('src/favicon.ico', img.contents)
}
}
// Filter out the WebManifest & friends from the HTML, since we're not using it currently:
const fileNames = res.files.map(x => x.name)
const htmlLines = res.html.filter(line =>
fileNames.every(name => !line.includes(name)))
// Write the favicon metadata to a file to be picked up by Eleventy
fs.writeFileSync('src/_includes/meta.html', htmlLines.join('\n'))

42
scripts/logo.js Normal file
View File

@@ -0,0 +1,42 @@
import { createCanvas, registerFont } from 'canvas'
import fs from 'fs'
const cfg = {
width: 400,
height: 400,
fontPath: 'src/assets/font/obsidian/Obsidian-Roman.otf',
fontName: 'Obsidian',
fontWeight: 'bold',
fontSize: '350pt',
color: '#fffbe3',
background: '#111111',
text: 'g.',
yOffset: 115,
}
if ( cfg.fontPath ) {
registerFont(cfg.fontPath, { family: cfg.fontName })
}
const canvas = createCanvas(cfg.width, cfg.height)
const ctx = canvas.getContext('2d')
// set the background
ctx.fillStyle = cfg.background
ctx.fillRect(0, 0, cfg.width, cfg.height)
// set the font
ctx.font = `${cfg.fontWeight} ${cfg.fontSize} ${cfg.fontName}`
ctx.fillStyle = cfg.color
ctx.textAlign = 'center'
ctx.textBaseline = 'middle'
// add the text to the canvas
ctx.fillText(cfg.text, cfg.width / 2, cfg.yOffset)
// write out logo.png
const png = fs.createWriteStream('src/assets/logo/logo.png')
canvas.createPNGStream().pipe(png)
const jpg = fs.createWriteStream('src/assets/logo/logo.jpg')
canvas.createJPEGStream().pipe(jpg)