feat: Typst preprocessing
This commit is contained in:
parent
c04e04667c
commit
332082102d
|
@ -0,0 +1,61 @@
|
|||
#import "@preview/cetz:0.3.2"
|
||||
#metadata((
|
||||
title: "Title",
|
||||
date: "2025-01-01",
|
||||
))<post>
|
||||
|
||||
//#set page(width: auto, height: auto, margin: .5cm)
|
||||
|
||||
#show math.equation: block.with(fill: white, inset: 1pt)
|
||||
|
||||
This is a diagram.
|
||||
|
||||
#html.frame(cetz.canvas(length: 3cm, {
|
||||
import cetz.draw: *
|
||||
|
||||
set-style(
|
||||
mark: (fill: black, scale: 2),
|
||||
stroke: (thickness: 0.4pt, cap: "round"),
|
||||
angle: (
|
||||
radius: 0.3,
|
||||
label-radius: .22,
|
||||
fill: green.lighten(80%),
|
||||
stroke: (paint: green.darken(50%))
|
||||
),
|
||||
content: (padding: 1pt)
|
||||
)
|
||||
|
||||
grid((-1.5, -1.5), (1.4, 1.4), step: 0.5, stroke: gray + 0.2pt)
|
||||
|
||||
circle((0,0), radius: 1)
|
||||
|
||||
line((-1.5, 0), (1.5, 0), mark: (end: "stealth"))
|
||||
content((), $ x $, anchor: "west")
|
||||
line((0, -1.5), (0, 1.5), mark: (end: "stealth"))
|
||||
content((), $ y $, anchor: "south")
|
||||
|
||||
for (x, ct) in ((-1, $ -1 $), (-0.5, $ -1/2 $), (1, $ 1 $)) {
|
||||
line((x, 3pt), (x, -3pt))
|
||||
content((), anchor: "north", ct)
|
||||
}
|
||||
|
||||
for (y, ct) in ((-1, $ -1 $), (-0.5, $ -1/2 $), (0.5, $ 1/2 $), (1, $ 1 $)) {
|
||||
line((3pt, y), (-3pt, y))
|
||||
content((), anchor: "east", ct)
|
||||
}
|
||||
|
||||
// Draw the green angle
|
||||
cetz.angle.angle((0,0), (1,0), (1, calc.tan(30deg)),
|
||||
label: text(green, [#sym.alpha]))
|
||||
|
||||
line((0,0), (1, calc.tan(30deg)))
|
||||
|
||||
set-style(stroke: (thickness: 1.2pt))
|
||||
|
||||
line((30deg, 1), ((), "|-", (0,0)), stroke: (paint: red), name: "sin")
|
||||
content(("sin.start", 50%, "sin.end"), text(red)[$ sin alpha $])
|
||||
line("sin.end", (0,0), stroke: (paint: blue), name: "cos")
|
||||
content(("cos.start", 50%, "cos.end"), text(blue)[$ cos alpha $], anchor: "north")
|
||||
line((1, 0), (1, calc.tan(30deg)), name: "tan", stroke: (paint: orange))
|
||||
content("tan.end", $ text(#orange, tan alpha) = text(#red, sin alpha) / text(#blue, cos alpha) $, anchor: "west")
|
||||
}))
|
|
@ -1,5 +1,6 @@
|
|||
<script lang="ts">
|
||||
import { Moon, Sun } from 'lucide-svelte';
|
||||
import Moon from 'lucide-svelte/icons/moon';
|
||||
import Sun from 'lucide-svelte/icons/sun';
|
||||
import { theme, setTheme } from '$lib/theme'
|
||||
|
||||
function toggleTheme() {
|
||||
|
|
|
@ -17,12 +17,13 @@ export function transformPostMeta(metadata: PostMetadata, slug: string) : Post {
|
|||
|
||||
// Generates a list of all posts filtering by tags and series, reverse chronologically ordered.
|
||||
export async function getPosts(filter: { tag?: string, series?: string }) : Promise<Post[]> {
|
||||
const allPostFiles = import.meta.glob('$content/post/*.md');
|
||||
const allPostFiles = import.meta.glob(['$content/post/*.md', '$content/post/*.typ']);
|
||||
const iterablePostFiles = Object.entries(allPostFiles);
|
||||
|
||||
let posts: Post[] = await Promise.all(
|
||||
iterablePostFiles.map(async ([pathMarkdown, resolver]) => {
|
||||
const { metadata } = await resolver();
|
||||
console.log(await resolver());
|
||||
const slug = pathMarkdown.slice(pathMarkdown.lastIndexOf("/") + 1, -".md".length);
|
||||
|
||||
return transformPostMeta(metadata, slug);
|
||||
|
@ -42,7 +43,7 @@ export async function getPosts(filter: { tag?: string, series?: string }) : Prom
|
|||
}
|
||||
|
||||
export async function getTags() : Promise<Map<string, number>> {
|
||||
const allPostFiles = import.meta.glob('$content/post/*.md');
|
||||
const allPostFiles = import.meta.glob(['$content/post/*.md', '$content/post/*.typ']);
|
||||
const iterablePostFiles = Object.entries(allPostFiles);
|
||||
|
||||
const allPosts: string[][] = await Promise.all(
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
import { promisify } from 'util';
|
||||
import { exec } from 'child_process';
|
||||
|
||||
const exec_async = promisify(exec);
|
||||
|
||||
export const typstPreprocess = (config) => {
|
||||
const {
|
||||
extensions,
|
||||
} = config;
|
||||
|
||||
return {
|
||||
name: "typst",
|
||||
markup: async ({content: _, filename}) => {
|
||||
|
||||
const extensionsParts = extensions.map((ext) =>
|
||||
ext.startsWith('.') ? ext : '.' + ext
|
||||
);
|
||||
if (!extensionsParts.some((ext) => filename.endsWith(ext))) return;
|
||||
|
||||
console.log("Processing typst file: ", filename);
|
||||
|
||||
const result_metadata = await exec_async(`typst query --features html ${filename} "<post>" --field value --one`);
|
||||
const payload = String(result_metadata.stdout);
|
||||
const data = JSON.parse(payload);
|
||||
console.log("data", data);
|
||||
|
||||
const result_post = await exec_async(`typst compile --features html ${filename} -`);
|
||||
const code = String(result_post.stdout)
|
||||
|
||||
return {
|
||||
code,
|
||||
metadata: data,
|
||||
data,
|
||||
map: '',
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
<script lang="ts">
|
||||
import { routes } from "$lib/sitemap.ts"
|
||||
import { routes } from "$lib/sitemap"
|
||||
import { Separator } from "$lib/components/ui/separator/index.js";
|
||||
import { Rss } from "lucide-svelte";
|
||||
import Rss from "lucide-svelte/icons/rss";
|
||||
import ThemeSwitch from "$lib/components/ThemeSwitch.svelte"
|
||||
let scrollPosition: number = .5;
|
||||
let scrollHeight: number = 1;
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
import { page } from '$app/stores';
|
||||
import { routes } from "$lib/sitemap.ts"
|
||||
import ThemeSwitch from "$lib/components/ThemeSwitch.svelte"
|
||||
import { Rss, Menu } from "lucide-svelte";
|
||||
import Rss from "lucide-svelte/icons/rss";
|
||||
import Menu from "lucide-svelte/icons/menu";
|
||||
|
||||
function isCurrentLink(pathname, route) {
|
||||
return route != "/" && pathname.startsWith(route)
|
||||
|
|
|
@ -6,7 +6,7 @@ import { getPosts, transformPostMeta } from '$lib/posts';
|
|||
export const load: PageLoad = async ({ params }) => {
|
||||
try {
|
||||
const post = await import(`$content/post/${params.slug}.md`);
|
||||
if (!post) throw error(404);
|
||||
if (!post) throw error(404);
|
||||
const metadata: Post = transformPostMeta(post.metadata, params.slug);
|
||||
const Content = post.default;
|
||||
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
|
||||
import adapter from '@sveltejs/adapter-static';
|
||||
import fs from 'fs';
|
||||
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
|
||||
import adapter from '@sveltejs/adapter-static'
|
||||
import fs from 'fs'
|
||||
|
||||
import { mdsvex, escapeSvelte } from 'mdsvex';
|
||||
import { typstPreprocess } from './src/lib/typst.js'
|
||||
import { mdsvex, escapeSvelte } from 'mdsvex'
|
||||
import remarkAlert from './src/lib/markdown.js'
|
||||
import relativeImages from 'mdsvex-relative-images'
|
||||
import remarkToc from 'remark-toc'
|
||||
import rehypeSlug from 'rehype-slug'
|
||||
import { getHighlighter } from 'shiki'
|
||||
import rehypeKatexSvelte from "rehype-katex-svelte";
|
||||
import rehypeKatexSvelte from "rehype-katex-svelte"
|
||||
import remarkMath from 'remark-math'
|
||||
|
||||
const contentDir = process.env?.CHRYSOBLOG_CONTENT ?? "src/content";
|
||||
|
@ -77,9 +78,12 @@ const config = {
|
|||
}
|
||||
},
|
||||
}),
|
||||
typstPreprocess({
|
||||
extensions: ['.typ'],
|
||||
}),
|
||||
vitePreprocess(),
|
||||
],
|
||||
extensions: [".svelte", ".md"],
|
||||
extensions: [".svelte", ".typ", ".md"],
|
||||
|
||||
kit: {
|
||||
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
|
||||
|
|
Loading…
Reference in New Issue