Commit 5241be8
Changed files (7)
src
contents
_lib
components
pages
posts
utils
src/contents/_lib/components/fullwidth.typ
@@ -6,5 +6,7 @@
class: "fullwidth",
content,
)
+ } else {
+ return content
}
}
src/contents/_lib/components/marginnote.typ
@@ -6,5 +6,7 @@
class: "marginnote",
content,
)
+ } else {
+ return footnote(numbering: (..i) => "", content)
}
}
src/contents/home.typ
@@ -1,8 +1,32 @@
#import "./_lib/lib.typ": *
#show: tybios.post-template
-#lorem(50)
+Tybios is a Tufted style inspired static blog template
+powered by #link("https://astro.build/")[Astro] and #link("https://typst.app/")[Typst].
-#lorem(30)
+= Installation
-#lorem(40)
+To get started with Tybios, follow these steps:
+
++ Clone the repository:
+ ```bash
+ git clone https://codeberg.org/HPCesia/Tybios.git
+ ```
++ Navigate to the project directory:
+ ```bash
+ cd Tybios
+ ```
++ Install dependencies:
+ ```bash
+ pnpm install
+ ```
++ Configure your site by editing the `src/config.ts` file
+ to set your site's metadata and preferences.
++ Start the development server:
+ ```bash
+ pnpm dev
+ ```
++ Build for production:
+ ```bash
+ pnpm build
+ ```
src/pages/posts/[slug]/archive.pdf.ts
@@ -0,0 +1,30 @@
+import { getCollection } from "astro:content";
+import type { APIRoute, GetStaticPaths, InferGetStaticPropsType } from "astro";
+import { renderTypstToPdf } from "@/utils/render-typst";
+
+export const getStaticPaths = (async () => {
+ const entries = await getCollection("posts");
+ return entries.map((entry) => ({
+ params: {
+ slug: entry.id,
+ },
+ props: { entry },
+ }));
+}) satisfies GetStaticPaths;
+
+type Props = InferGetStaticPropsType<typeof getStaticPaths>;
+
+export const GET: APIRoute = async ({ props }) => {
+ const entry = (props as Props).entry;
+ const filePath = entry.filePath;
+ if (typeof filePath !== "string") {
+ return new Response("Not found", { status: 404 });
+ }
+ const pdfBuffer = renderTypstToPdf(filePath);
+
+ return new Response(pdfBuffer as Buffer<ArrayBuffer>, {
+ headers: {
+ "Content-Type": "application/pdf",
+ },
+ });
+};
src/pages/posts/[slug].astro → src/pages/posts/[slug]/index.astro
@@ -2,6 +2,7 @@
import { getCollection, render } from "astro:content";
import type { GetStaticPaths, InferGetStaticPropsType } from "astro";
import GlobalLayout from "@/layouts/GlobalLayout.astro";
+import { url } from "@/utils/url";
type Props = InferGetStaticPropsType<typeof getStaticPaths>;
@@ -30,4 +31,9 @@ const { Content } = await render(entry);
<h1>{data.title}</h1>
<Content />
</article>
+ <footer class="mt-8 article-anchor">
+ <a href={url(`posts/${entry.id}/archive.pdf`)}>
+ <span>PDF archive of this post</span>
+ </a>
+ </footer>
</GlobalLayout>
src/pages/feed.atom.ts
@@ -1,11 +1,12 @@
import { getCollection } from "astro:content";
+import type { APIRoute } from "astro";
import { Feed } from "feed";
import { SITE_CONFIG } from "@/config";
import { rehypeExternalLinks } from "@/plugins/rehype-external-links";
-import { renderTypst } from "@/utils/render-typst";
import { rehypeExtractImage } from "@/plugins/rehype-extract-image";
+import { renderTypstToHtml } from "@/utils/render-typst";
-export async function GET() {
+export const GET: APIRoute = async () => {
const posts = await getCollection("posts");
const siteUrl = SITE_CONFIG.website;
@@ -35,7 +36,7 @@ export async function GET() {
id: url,
link: url,
description: post.data.desc,
- content: await renderTypst(post.filePath, [
+ content: await renderTypstToHtml(post.filePath, [
rehypeExtractImage,
rehypeExternalLinks,
]),
@@ -50,4 +51,4 @@ export async function GET() {
"Content-Type": "application/xml",
},
});
-}
+};
src/utils/render-typst.ts
@@ -3,8 +3,8 @@ import { fileURLToPath } from "node:url";
import type { RehypePlugins } from "@astrojs/markdown-remark";
import { NodeCompiler } from "@myriaddreamin/typst-ts-node-compiler";
import { rehypeIt } from "astro-typst/dist/lib/rehype";
-import type { Root } from "hast";
import * as cheerio from "cheerio";
+import type { Root } from "hast";
const rootPath = fileURLToPath(root);
const $typst = NodeCompiler.create({
@@ -12,7 +12,7 @@ const $typst = NodeCompiler.create({
inputs: { "x-renderer": "tybios" },
});
-export async function renderTypst(
+export async function renderTypstToHtml(
mainfilePath: string,
plugins?: RehypePlugins,
): Promise<string> {
@@ -33,3 +33,14 @@ export async function renderTypst(
return $("body").html() || "";
}
+
+export function renderTypstToPdf(mainfilePath: string): Buffer {
+ const docRes = $typst.compile({ mainFilePath: mainfilePath });
+ if (!docRes.result) {
+ docRes.printDiagnostics();
+ throw new Error("Failed to compile Typst document.");
+ }
+ const doc = docRes.result;
+ const pdf = $typst.pdf(doc);
+ return pdf;
+}