: null}
>
}
const data: Data = eval(`(${readFileSync("src/content/links.jsonc", "utf8")})`);
data.links.pop(); // Remove template at the end
+
+function compare(a: string, b: string) {
+ return Number(a > b) - Number(b > a);
+}
+
+function* groupBy(items: Iterable, keyFn: (item: T) => K) {
+ let oldKey: K = Symbol() as any;
+ let group: T[] | undefined = undefined;
+ for (const item of items) {
+ let newKey = keyFn(item);
+ if (!Object.is(newKey, oldKey)) {
+ if (group) {
+ yield [oldKey, group] as [K, T[]];
+ }
+ group = [];
+ oldKey = newKey;
+ }
+ group!.push(item);
+ }
+ if (group) {
+ yield [oldKey, group] as [K, T[]];
+ }
+}
+
+const byDate = data.links.filter(link => link.read).sort((a, b) => -compare(a.read!, b.read!));
+const byMonth = groupBy(byDate, link => link.read!.slice(0, 7));
+const byYearMonth = [...groupBy(byMonth, month => month[0].slice(0, 4))];
+const other = data.links.filter(link => !link.read);
+const monthNames = [
+ "", // padding to make mapping start at 1
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December",
+];
+
const title = "Links!";
export const links: Page = {
title,
@@ -37,8 +106,27 @@ export const links: Page = {
content:
{title}
-
- { data.links.map(link => )}
+
+ Here be interesting things I've read, watched, listened to or otherwise found useful as resources over the years. These are ordered by when I read them as that seems most practical to me.
+