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">
|
<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'
|
import { theme, setTheme } from '$lib/theme'
|
||||||
|
|
||||||
function toggleTheme() {
|
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.
|
// 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[]> {
|
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);
|
const iterablePostFiles = Object.entries(allPostFiles);
|
||||||
|
|
||||||
let posts: Post[] = await Promise.all(
|
let posts: Post[] = await Promise.all(
|
||||||
iterablePostFiles.map(async ([pathMarkdown, resolver]) => {
|
iterablePostFiles.map(async ([pathMarkdown, resolver]) => {
|
||||||
const { metadata } = await resolver();
|
const { metadata } = await resolver();
|
||||||
|
console.log(await resolver());
|
||||||
const slug = pathMarkdown.slice(pathMarkdown.lastIndexOf("/") + 1, -".md".length);
|
const slug = pathMarkdown.slice(pathMarkdown.lastIndexOf("/") + 1, -".md".length);
|
||||||
|
|
||||||
return transformPostMeta(metadata, slug);
|
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>> {
|
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 iterablePostFiles = Object.entries(allPostFiles);
|
||||||
|
|
||||||
const allPosts: string[][] = await Promise.all(
|
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">
|
<script lang="ts">
|
||||||
import { routes } from "$lib/sitemap.ts"
|
import { routes } from "$lib/sitemap"
|
||||||
import { Separator } from "$lib/components/ui/separator/index.js";
|
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"
|
import ThemeSwitch from "$lib/components/ThemeSwitch.svelte"
|
||||||
let scrollPosition: number = .5;
|
let scrollPosition: number = .5;
|
||||||
let scrollHeight: number = 1;
|
let scrollHeight: number = 1;
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
import { routes } from "$lib/sitemap.ts"
|
import { routes } from "$lib/sitemap.ts"
|
||||||
import ThemeSwitch from "$lib/components/ThemeSwitch.svelte"
|
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) {
|
function isCurrentLink(pathname, route) {
|
||||||
return route != "/" && pathname.startsWith(route)
|
return route != "/" && pathname.startsWith(route)
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
|
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
|
||||||
import adapter from '@sveltejs/adapter-static';
|
import adapter from '@sveltejs/adapter-static'
|
||||||
import fs from 'fs';
|
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 remarkAlert from './src/lib/markdown.js'
|
||||||
import relativeImages from 'mdsvex-relative-images'
|
import relativeImages from 'mdsvex-relative-images'
|
||||||
import remarkToc from 'remark-toc'
|
import remarkToc from 'remark-toc'
|
||||||
import rehypeSlug from 'rehype-slug'
|
import rehypeSlug from 'rehype-slug'
|
||||||
import { getHighlighter } from 'shiki'
|
import { getHighlighter } from 'shiki'
|
||||||
import rehypeKatexSvelte from "rehype-katex-svelte";
|
import rehypeKatexSvelte from "rehype-katex-svelte"
|
||||||
import remarkMath from 'remark-math'
|
import remarkMath from 'remark-math'
|
||||||
|
|
||||||
const contentDir = process.env?.CHRYSOBLOG_CONTENT ?? "src/content";
|
const contentDir = process.env?.CHRYSOBLOG_CONTENT ?? "src/content";
|
||||||
|
@ -77,9 +78,12 @@ const config = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
typstPreprocess({
|
||||||
|
extensions: ['.typ'],
|
||||||
|
}),
|
||||||
vitePreprocess(),
|
vitePreprocess(),
|
||||||
],
|
],
|
||||||
extensions: [".svelte", ".md"],
|
extensions: [".svelte", ".typ", ".md"],
|
||||||
|
|
||||||
kit: {
|
kit: {
|
||||||
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
|
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
|
||||||
|
|
Loading…
Reference in New Issue