diff options
| author | Joe Carstairs <me@joeac.net> | 2026-03-21 22:24:08 +0000 |
|---|---|---|
| committer | Joe Carstairs <me@joeac.net> | 2026-03-21 22:24:08 +0000 |
| commit | 65464e8ee5ea5b91bdfffa2d30f0ebae8fdf0fc9 (patch) | |
| tree | 7b578b6610de60942622af33903d1820a1a220e7 /website/src/pages | |
| parent | a09f874bba31567c0c758e67e6e6d6c2cbb06e7a (diff) | |
render .gmi posts as gemtext
Diffstat (limited to 'website/src/pages')
| -rw-r--r-- | website/src/pages/blog/[...slug].astro | 42 |
1 files changed, 40 insertions, 2 deletions
diff --git a/website/src/pages/blog/[...slug].astro b/website/src/pages/blog/[...slug].astro index 0754ea7..f5d9763 100644 --- a/website/src/pages/blog/[...slug].astro +++ b/website/src/pages/blog/[...slug].astro @@ -1,6 +1,7 @@ --- import { type CollectionEntry, getCollection, render } from 'astro:content'; import BlogPost from '../../layouts/BlogPost.astro'; +import * as Gemtext from 'gemtext'; export async function getStaticPaths() { const posts = await getCollection('blog'); @@ -11,10 +12,47 @@ export async function getStaticPaths() { } type Props = CollectionEntry<'blog'>; +function htmlEscape(str: string) { + return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>'); +} + +const GemtextHTMLRenderer: Gemtext.Renderer<string> = { + preamble: function (): string { + return ''; + }, + postamble: function (): string { + return ''; + }, + text: function (content: string): string { + content = content.trim(); + if (content === '') { + return ''; + } + return `<p>${htmlEscape(content)}</p>` + }, + link: function (url: string, alt: string): string { + return `<p>=> <a href="${url}">${alt}</a></p>`; + }, + preformatted: function (content: string[], alt: string): string { + return `<pre alt="${alt}">${htmlEscape(content.join('\n'))}</pre>` + }, + heading: function (level: number, text: string): string { + return `<h${level}>${htmlEscape(text)}</h${level}>`; + }, + unorderedList: function (content: string[]): string { + return `<ul>${content.map(li=>`<li>${htmlEscape(li)}</li>`).join('')}</ul>`; + }, + quote: function (content: string): string { + return `<blockquote>${htmlEscape(content)}</blockquote>`; + } +}; + const post = Astro.props; -const { Content } = await render(post); +const Content = post.filePath?.endsWith('.gmi') + ? Gemtext.parse(post.body ?? '').generate(GemtextHTMLRenderer) + : (await render(post)).Content; --- <BlogPost {...post.data}> - <Content /> + { post.filePath?.endsWith('.gmi') ? <Fragment set:html={Content}></Fragment> : <Content />} </BlogPost> |
