website

Personal website
git clone https://github.com/michaelneuper/website.git
README | Files | Log | Refs

website/src/lib/posts.js (1803B)


// Shared by the home page's posts list, the post pages and the feeds.

import { getCollection } from "astro:content";

/** Published posts, newest first. */
export async function publishedPosts() {
  const posts = await getCollection("posts", (p) => !p.data.draft);
  return posts.sort((a, b) => b.data.date - a.data.date);
}

// Dates are in South African time, as the posts were written.
const day = new Intl.DateTimeFormat("en-CA", { timeZone: "Africa/Johannesburg", year: "numeric", month: "2-digit", day: "2-digit" });
const dow = new Intl.DateTimeFormat("en-GB", { timeZone: "Africa/Johannesburg", weekday: "short" });
/** 2024-11-22 */
export const ymd = (date) => day.format(date);
/** Fri */
export const weekday = (date) => dow.format(date);

/** Words in the Markdown source, about what wc -w says. */
export const wordCount = (body) => body.split(/\s+/).filter(Boolean).length;

/**
 * The opening of a post as plain text, for meta descriptions and the feeds:
 * everything above Hugo's <!--more--> marker, or else the first paragraph.
 */
export function summary(body, max = 220) {
  const blocks = body.trim().split(/\n\s*\n/);
  const head = body.includes("<!--more-->")
    ? body.split("<!--more-->")[0]
    : blocks.find((b) => !/^\s*([#!<>|`-]|\d+\.|\[\^)/.test(b)) ?? "";
  const text = head
    .split("\n")
    .filter((line) => !/^\[\^[^\]]+\]:/.test(line)) // footnote definitions
    .join(" ")
    .replace(/!\[[^\]]*\]\([^)]*\)/g, "") // images
    .replace(/\[([^\]]+)\]\([^)]*\)/g, "$1") // links
    .replace(/\[\^[^\]]+\]/g, "") // footnote references
    .replace(/<[^>]+>/g, "")
    .replace(/[`*_]/g, "")
    .replace(/\s+/g, " ")
    .trim();
  if (text.length <= max) return text;
  return `${text.slice(0, text.lastIndexOf(" ", max)).replace(/[,.;:]$/, "")}…`;
}