Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions website/.vitepress/blog.data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { createContentLoader } from 'vitepress';

export interface Post {
title: string;
url: string;
date: {
time: number;
string: string;
};
author: string;
tags: string[];
excerpt?: string;
}

declare const data: Post[];
export { data };

// extractExcerpt renders the whole document first so that links which have
// `[ref]: url` style definitions outside of the excerpt still resolve. The
// rendered HTML is then cut at the `<!-- more -->` marker leaving just the
// excerpt text.
function extractExcerpt(html: string): string | undefined {
const markerIndex = html.indexOf('<!-- more -->');
if (markerIndex === -1) return undefined;
return html
.slice(0, markerIndex)
.replace(/<h1[^>]*>[\s\S]*?<\/h1>/, '')
.replace(/<AuthorCard\b[^>]*\/?>/gi, '')
.trim();
}

export default createContentLoader('blog/*.md', {
render: true,
transform(raw) {
return raw
.filter(({ url }) => url !== '/blog/')
.map(({ frontmatter, html, url }) => {
const date = new Date(frontmatter.date);
return {
title: frontmatter.title,
url,
date: {
time: date.getTime(),
string: date.toISOString().slice(0, 10)
},
author: frontmatter.author,
tags: frontmatter.tags ?? [],
excerpt: html ? extractExcerpt(html) : undefined
};
})
.sort((a, b) => b.date.time - a.date.time);
}
});
2 changes: 1 addition & 1 deletion website/.vitepress/components/BlogPost.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<div class="post-text">
<AuthorCard :author="author" />

<p class="post-description">{{ description }}</p>
<div class="post-description" v-html="description"></div>

<div class="post-footer">
<div class="post-tags" v-if="tags?.length">
Expand Down
87 changes: 36 additions & 51 deletions website/.vitepress/config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { defineConfig, HeadConfig } from 'vitepress';
import githubLinksPlugin from './plugins/github-links';
import { readFileSync } from 'fs';
import { readdirSync, readFileSync } from 'fs';
import { resolve } from 'path';
import matter from 'gray-matter';
import { tabsMarkdownPlugin } from 'vitepress-plugin-tabs';
import {
groupIconMdPlugin,
Expand All @@ -19,6 +20,39 @@ const version = readFileSync(
'utf8'
).trim();

// Builds the "/blog/" sidebar from each blog post's frontmatter.
function buildBlogSidebar() {
const blogDir = resolve(__dirname, '../src/blog');
const posts = readdirSync(blogDir)
.filter((file) => file.endsWith('.md') && file !== 'index.md')
.map((file) => {
const { data: frontmatter } = matter(
readFileSync(resolve(blogDir, file), 'utf8')
);
return {
slug: file.replace(/\.md$/, ''),
title: frontmatter.sidebarTitle ?? frontmatter.title,
date: new Date(frontmatter.date)
};
})
.sort((a, b) => b.date.getTime() - a.date.getTime());

const byYear = new Map<number, { text: string; link: string }[]>();
for (const post of posts) {
const year = post.date.getFullYear();
if (!byYear.has(year)) byYear.set(year, []);
byYear.get(year)!.push({ text: post.title, link: `/blog/${post.slug}` });
}

return [...byYear.entries()]
.sort((a, b) => b[0] - a[0])
.map(([year, items]) => ({
text: String(year),
collapsed: false,
items
}));
}

const urlVersion =
process.env.NODE_ENV === 'development'
? {
Expand Down Expand Up @@ -311,56 +345,7 @@ export default defineConfig({
],

sidebar: {
'/blog/': [
{
text: '2026',
collapsed: false,
items: [
{
text: 'GitHub SOSF',
link: '/blog/github-secure-open-source-program'
},
{
text: 'Using `go tool task`',
link: '/blog/go-tool-task'
},
{
text: 'Conditionals Statements',
link: '/blog/if-and-variable-prompt'
}
]
},
{
text: '2025',
collapsed: false,
items: [
{
text: 'Built-in Core Utilities',
link: '/blog/windows-core-utils'
}
]
},
{
text: '2024',
collapsed: false,
items: [
{
text: 'Any Variables',
link: '/blog/any-variables'
}
]
},
{
text: '2023',
collapsed: false,
items: [
{
text: 'Introducing Experiments',
link: '/blog/task-in-2023'
}
]
}
],
'/blog/': buildBlogSidebar(),
'/': [
{
text: 'Installation',
Expand Down
1 change: 1 addition & 0 deletions website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"devDependencies": {
"@types/markdown-it": "^14.1.2",
"@types/node": "^24.1.0",
"gray-matter": "^4.0.3",
"netlify-cli": "^27.0.0",
"prettier": "^3.6.2",
"vitepress": "^1.6.3",
Expand Down
60 changes: 42 additions & 18 deletions website/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions website/src/blog/any-variables.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
---
title: Any Variables
description:
Task now supports most variable types, including booleans, integers, floats
and arrays!
author: pd93
date: 2024-05-09
tags: ['experiments', 'variables']
outline: deep
editLink: false
---
Expand All @@ -17,6 +21,8 @@ simple problems. Starting from [v3.37.0][v3.37.0], this is no longer the case!
Task now supports most variable types, including **booleans**, **integers**,
**floats** and **arrays**!

<!-- more -->

## What's the big deal?

These changes allow you to use variables in a much more natural way and opens up
Expand Down
Loading