From fc593e64529675700e002f50dc0512b604829fb8 Mon Sep 17 00:00:00 2001 From: Nils Pukropp Date: Tue, 20 Oct 2026 10:25:26 +0200 Subject: [PATCH] markdown: math set by KaTeX, fetched only when a page has some MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit $x^2$ inline, $$…$$ for display, and a ```math block, the way GitHub writes them, in documents, shared pages and .md files alike. KaTeX loads on first use; until then the math shows as its source. Only the woff2 fonts are bundled. --- README.md | 4 ++- web/bun.lock | 5 +++ web/package.json | 1 + web/src/app.css | 2 ++ web/src/lib/Help.svelte | 2 +- web/src/lib/markdown.ts | 65 ++++++++++++++++++++++++++++++++++++-- web/src/lib/math.svelte.ts | 20 ++++++++++++ web/src/vite-env.d.ts | 2 ++ web/vite.config.ts | 16 +++++++++- 9 files changed, 111 insertions(+), 6 deletions(-) create mode 100644 web/src/lib/math.svelte.ts create mode 100644 web/src/vite-env.d.ts diff --git a/README.md b/README.md index 40609c1..51e7ca1 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,9 @@ one binary. It was called `narl-diary` until it grew everything but the diary. - **Rust + axum** backend, **SQLite** storage, **Svelte 5** frontend. - Spaces (`diary`, `work`, `uni`, …) with folders nested to any depth inside them. -- Markdown documents with full-text search across a whole space (SQLite FTS5). +- Markdown documents with full-text search across a whole space (SQLite FTS5), + and math in them set by KaTeX: `$x^2$` inline, `$$…$$` or a ```` ```math ```` + block on its own. - Import a folder — or a zip of one — as a tree of documents, links and all. - A kanban board per space, so what is open at work is not mixed up with uni. - Drag, drop or paste images, video and audio straight into an entry. diff --git a/web/bun.lock b/web/bun.lock index 7eec19b..9990ec8 100644 --- a/web/bun.lock +++ b/web/bun.lock @@ -15,6 +15,7 @@ "@lezer/highlight": "^1.2.1", "@replit/codemirror-vim": "^6.2.1", "dompurify": "^3.2.4", + "katex": "^0.19.0", "marked": "^15.0.6", }, "devDependencies": { @@ -212,6 +213,8 @@ "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="], + "commander": ["commander@15.0.0", "", {}, "sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg=="], + "crelt": ["crelt@1.0.7", "", {}, "sha512-aK6BbWfhf4U/wCcLHKPJl/xa6VkVstRaPywWtMKGwuOLc/wZTyQYuoxgvZnNsBvv7Kg3YTBQYYBCggcviQczuA=="], "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], @@ -234,6 +237,8 @@ "is-reference": ["is-reference@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.6" } }, "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw=="], + "katex": ["katex@0.19.0", "", { "dependencies": { "commander": "^15.0.0" }, "bin": { "katex": "cli.js" } }, "sha512-v6Tznz3zJ7u3niRCoDTsumM2+HA2XXcCu+WAacCeHD2z3p9A9Ks987o5FzfTGBN0e8A0vjEgIDvLbICrXpdw/Q=="], + "kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="], "locate-character": ["locate-character@3.0.0", "", {}, "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA=="], diff --git a/web/package.json b/web/package.json index 832e774..d35fb19 100644 --- a/web/package.json +++ b/web/package.json @@ -27,6 +27,7 @@ "@lezer/highlight": "^1.2.1", "@replit/codemirror-vim": "^6.2.1", "dompurify": "^3.2.4", + "katex": "^0.19.0", "marked": "^15.0.6" } } diff --git a/web/src/app.css b/web/src/app.css index 845f77c..a30f6ac 100644 --- a/web/src/app.css +++ b/web/src/app.css @@ -517,6 +517,8 @@ input::placeholder { color: var(--muted); } margin: 0 0 1em; } .md pre code { background: none; border: 0; padding: 0; font-size: inherit; } +/* A long equation scrolls on its own rather than widening the page. */ +.md .katex-display { overflow-x: auto; overflow-y: hidden; padding: 2px 0; } .md hr { border: 0; border-top: 1px solid var(--overlay); margin: 2.4em 0; } .md img, .md video { max-width: 100%; diff --git a/web/src/lib/Help.svelte b/web/src/lib/Help.svelte index 64d3e99..f315941 100644 --- a/web/src/lib/Help.svelte +++ b/web/src/lib/Help.svelte @@ -141,7 +141,7 @@