Files
astro-gemtext/src/index.ts
T
2026-03-21 19:58:25 +00:00

68 lines
2.7 KiB
TypeScript

import type {AstroIntegration, ContentEntryType, HookParameters} from "astro"
import {fileURLToPath} from "url"
import gemtextVitePlugin from "./vitePlugin.js"
import { parse as parseYaml } from "yaml";
/** Gemtext configuration options */
export interface GemtextConfig {
/** Absolute import path to the layout to use for all gemtext pages.
* If not provided, HMR and the Astro toolbar will not work. (default: none) */
layout?: string
/** The format to use for the page title. Can be one of:
* - `first-heading`: The first heading in the document will be used as the title. (default)
* - `filename`: The filename of the document will be used as the title.
*/
titleFormat?: "first-heading" | "filename"
}
type SetupHookParams = HookParameters<"astro:config:setup"> & {
// `addPageExtension` and `contentEntryType` are not a public APIs
// Add type defs here
addPageExtension: (extension: string) => void
addContentEntryType: (contentEntryType: ContentEntryType) => void
}
export default function gemtext(config: GemtextConfig = {}): AstroIntegration {
if (!config.titleFormat) {
config.titleFormat = "first-heading"
}
return {
name: "astro-gemtext",
hooks: {
"astro:config:setup": async (_params) => {
const params = _params as SetupHookParams
params.addPageExtension('.gmi')
params.addContentEntryType({
extensions: ['.gmi'],
getEntryInfo: async ({ fileUrl, contents }) => {
const lines = contents.split('\n');
let data: Record<string, unknown> = {};
let frontmatter = '';
let bodyStartLineIndex = 0;
if (lines.at(0) === '---' && lines.lastIndexOf('---') > 0) {
bodyStartLineIndex = lines.indexOf('---', 1) + 1;
frontmatter = lines.slice(1, bodyStartLineIndex).join('\n');
try {
data = { ...data, ...parseYaml(frontmatter, { schema: 'yaml-1.1' }) };
} catch { }
}
return {
data,
rawData: frontmatter,
body: lines.slice(bodyStartLineIndex).join('\n'),
slug: typeof data['slug'] === 'string' ? data['slug'] : fileUrl.pathname,
};
},
})
params.updateConfig({
vite: {
plugins: [gemtextVitePlugin(config)],
},
})
},
},
}
}