diff --git a/package-lock.json b/package-lock.json index 4e980c5..70b9b73 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,6 +39,8 @@ "prettier": "^3.1.1", "prettier-plugin-svelte": "^3.1.2", "prettier-plugin-tailwindcss": "^0.6.5", + "rehype-katex-svelte": "^1.2.0", + "remark-math": "^3.0.0", "svelte": "^4.2.7", "svelte-check": "^4.0.0", "tailwindcss": "^3.4.9", @@ -1741,6 +1743,17 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "node_modules/bcp-47-match": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-2.0.3.tgz", + "integrity": "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", @@ -1768,6 +1781,13 @@ "svelte": "^4.0.0 || ^5.0.0-next.118" } }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true, + "license": "ISC" + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -2054,6 +2074,13 @@ "node": ">= 8" } }, + "node_modules/css-selector-parser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-1.4.1.tgz", + "integrity": "sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g==", + "dev": true, + "license": "MIT" + }, "node_modules/css-tree": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", @@ -2151,6 +2178,20 @@ "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" }, + "node_modules/direction": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/direction/-/direction-2.0.1.tgz", + "integrity": "sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==", + "dev": true, + "license": "MIT", + "bin": { + "direction": "cli.js" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/dlv": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", @@ -2804,6 +2845,41 @@ "node": ">= 0.4" } }, + "node_modules/hast-util-from-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hast-util-from-string/-/hast-util-from-string-2.0.0.tgz", + "integrity": "sha512-9JlBGWh+RXbT8PDrdwYZloN6poib8xg7Vq+LgN5TTqnaMDO0YqfX4EyZd3Myel6yIXlDsgysiRB1CTjH2K+1Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-string/node_modules/@types/hast": { + "version": "2.3.10", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", + "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/hast-util-has-property": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hast-util-has-property/-/hast-util-has-property-2.0.1.tgz", + "integrity": "sha512-X2+RwZIMTMKpXUzlotatPzWj8bspCymtXH3cfG3iQKV+wPF53Vgaqxi/eLqGck0wKq1kS9nvoB1wchbCPEL8sg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-heading-rank": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hast-util-heading-rank/-/hast-util-heading-rank-3.0.0.tgz", @@ -2817,6 +2893,114 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-select": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/hast-util-select/-/hast-util-select-5.0.5.tgz", + "integrity": "sha512-QQhWMhgTFRhCaQdgTKzZ5g31GLQ9qRb1hZtDPMqQaOhpLBziWcshUS0uCR5IJ0U1jrK/mxg35fmcq+Dp/Cy2Aw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/unist": "^2.0.0", + "bcp-47-match": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "css-selector-parser": "^1.0.0", + "direction": "^2.0.0", + "hast-util-has-property": "^2.0.0", + "hast-util-to-string": "^2.0.0", + "hast-util-whitespace": "^2.0.0", + "not": "^0.1.0", + "nth-check": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "unist-util-visit": "^4.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-select/node_modules/@types/hast": { + "version": "2.3.10", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", + "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/hast-util-select/node_modules/hast-util-to-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-2.0.0.tgz", + "integrity": "sha512-02AQ3vLhuH3FisaMM+i/9sm4OXGSq1UhOOCpTLLQtHdL3tZt7qil69r8M8iDkZYyC0HCFylcYoP+8IO7ddta1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-select/node_modules/hast-util-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz", + "integrity": "sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-select/node_modules/unist-util-is": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", + "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-select/node_modules/unist-util-visit": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", + "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.1.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-select/node_modules/unist-util-visit-parents": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", + "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-to-html": { "version": "9.0.3", "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.3.tgz", @@ -3088,6 +3272,33 @@ "dev": true, "license": "MIT" }, + "node_modules/katex": { + "version": "0.16.11", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.11.tgz", + "integrity": "sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ==", + "dev": true, + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "license": "MIT", + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/katex/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -3576,6 +3787,12 @@ "node": ">=0.10.0" } }, + "node_modules/not": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/not/-/not-0.1.0.tgz", + "integrity": "sha512-5PDmaAsVfnWUgTUbJ3ERwn7u79Z0dYxN9ErxCpVJJqe2RK0PJ3z+iFUxuqjwtlDDegXvtWoxD/3Fzxox7tFGWA==", + "dev": true + }, "node_modules/npm-run-path": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", @@ -3603,6 +3820,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -4247,6 +4477,43 @@ "integrity": "sha512-r/AadFO7owAq1QJVeZ/nq9jNS1vyZt+6t1p/E59B56Rn2GCya+gr1KSyOzNL/er+r+B7phv5jG2xU2Nz1YkmJg==", "license": "MIT" }, + "node_modules/rehype-katex-svelte": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/rehype-katex-svelte/-/rehype-katex-svelte-1.2.0.tgz", + "integrity": "sha512-3mAa0J7LgMfaoU3oj9XLBIn5H/MyvWcOQcItoWhww/sABkcLpY73WsAs5mwH0c6cwYDYwJKaVVl2vNuL3wokeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hast-util-from-string": "^2.0.0", + "hast-util-select": "^5.0.5", + "hast-util-to-string": "^2.0.0", + "katex": "^0.16.7" + } + }, + "node_modules/rehype-katex-svelte/node_modules/@types/hast": { + "version": "2.3.10", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", + "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/rehype-katex-svelte/node_modules/hast-util-to-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-2.0.0.tgz", + "integrity": "sha512-02AQ3vLhuH3FisaMM+i/9sm4OXGSq1UhOOCpTLLQtHdL3tZt7qil69r8M8iDkZYyC0HCFylcYoP+8IO7ddta1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/rehype-slug": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/rehype-slug/-/rehype-slug-6.0.0.tgz", @@ -4279,6 +4546,17 @@ "url": "https://jaywcjlove.github.io/#/sponsor" } }, + "node_modules/remark-math": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-math/-/remark-math-3.0.0.tgz", + "integrity": "sha512-1ptXVKQaxexoS1pywvbtoRofKenkulyWa7trXUh2LR5NCdzmqfUlM/aA8qyke7h63BGMFXVjPNjOZmD8oWkKDg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/remark-toc": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/remark-toc/-/remark-toc-9.0.0.tgz", diff --git a/package.json b/package.json index a77664f..447f1af 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,8 @@ "prettier": "^3.1.1", "prettier-plugin-svelte": "^3.1.2", "prettier-plugin-tailwindcss": "^0.6.5", + "rehype-katex-svelte": "^1.2.0", + "remark-math": "^3.0.0", "svelte": "^4.2.7", "svelte-check": "^4.0.0", "tailwindcss": "^3.4.9", diff --git a/src/app.html b/src/app.html index 108d3e6..936c4a3 100644 --- a/src/app.html +++ b/src/app.html @@ -5,6 +5,7 @@ %sveltekit.head% +
%sveltekit.body%
diff --git a/src/content/post/placeholder1.md b/src/content/post/placeholder1.md index 72a5f65..7c79577 100644 --- a/src/content/post/placeholder1.md +++ b/src/content/post/placeholder1.md @@ -7,7 +7,7 @@ series: ["placeholder"] --- # 1st Level Heading -Here is some placeholder text +Here is some placeholder text. Here is some **bold text**. ## 2nd Level Heading diff --git a/src/content/post/the-perfect-math-class.md b/src/content/post/the-perfect-math-class.md index f50b7cd..ce1e00e 100644 --- a/src/content/post/the-perfect-math-class.md +++ b/src/content/post/the-perfect-math-class.md @@ -16,3 +16,13 @@ theorem perfect_number_theorem (n: Nat), > :>WARNING > The proof is elusive! + +Some KaTeX: $a^n + b^n = c^n$. + +$$ +\Gamma(z) = \int_0^\infty e^{-t} t^{z-1}\,\mathrm dz +$$ + +$$ +\vec z^{(l+1)} = \mat M\vec z^{(l)} + \vec b +$$ diff --git a/src/hooks.ts b/src/hooks.ts index 7ea2285..ac5feb1 100644 --- a/src/hooks.ts +++ b/src/hooks.ts @@ -1,7 +1,6 @@ import type { Reroute } from '@sveltejs/kit'; const translated: Record = { - '/post': '/page/1', }; export const reroute: Reroute = ({ url }) => { diff --git a/src/lib/components/PostHeader.svelte b/src/lib/components/PostHeader.svelte index aefa5b2..b09de62 100644 --- a/src/lib/components/PostHeader.svelte +++ b/src/lib/components/PostHeader.svelte @@ -1,7 +1,7 @@ + + + +{#if maxPageN} +
+ +{/if} + + diff --git a/src/routes/page/[slug]/+page.svelte b/src/routes/page/[slug]/+page.svelte index 09996f0..4e5e710 100644 --- a/src/routes/page/[slug]/+page.svelte +++ b/src/routes/page/[slug]/+page.svelte @@ -1,14 +1,10 @@ @@ -16,49 +12,7 @@
- -
- + diff --git a/src/routes/page/[slug]/+page.ts b/src/routes/page/[slug]/+page.ts index dd9e8c7..c4753bb 100644 --- a/src/routes/page/[slug]/+page.ts +++ b/src/routes/page/[slug]/+page.ts @@ -1,7 +1,7 @@ -import { error } from '@sveltejs/kit'; -import type { PageLoad } from './$types'; -import { getPosts } from '$lib/posts'; -import siteMetadata from '$content/metadata.json'; +import { error } from '@sveltejs/kit' +import type { PageLoad } from './$types' +import { getPosts } from '$lib/posts' +import siteMetadata from '$content/metadata.json' export const load: PageLoad = async ({ params }) => { const pageN: number = +params.slug; diff --git a/src/routes/post/+page.server.ts b/src/routes/post/+page.server.ts index fc78cd1..f4fffc8 100644 --- a/src/routes/post/+page.server.ts +++ b/src/routes/post/+page.server.ts @@ -1,7 +1,14 @@ -import type { PageLoad } from './$types'; -import { getPosts } from '$lib/posts'; +import type { PageLoad } from './$types' +import { getPosts } from '$lib/posts' +import siteMetadata from '$content/metadata.json' -export const load: PageLoad = async (_) => { - const allPosts = await getPosts(); - return { allPosts }; -}; +export const load: PageLoad = async () => { + const posts = await getPosts(); + const pageSize = siteMetadata?.pageSize || 3; + const maxPageN = Math.ceil(posts.length / pageSize); + + return { + maxPageN, + posts: posts.slice(0, pageSize), + }; +} diff --git a/src/routes/post/+page.svelte b/src/routes/post/+page.svelte index 249c48f..62a29e4 100644 --- a/src/routes/post/+page.svelte +++ b/src/routes/post/+page.svelte @@ -1,9 +1,10 @@ @@ -11,17 +12,4 @@
- -
- - + diff --git a/src/routes/tag/[slug]/+page.svelte b/src/routes/tag/[slug]/+page.svelte index 42ad300..ef8521c 100644 --- a/src/routes/tag/[slug]/+page.svelte +++ b/src/routes/tag/[slug]/+page.svelte @@ -1,9 +1,9 @@ @@ -11,19 +11,9 @@

{name} ({posts.length})

-
-
    - {#each posts as post} -
  • - -
  • - {/each} -
+
diff --git a/svelte.config.js b/svelte.config.js index 9820d65..deabdb8 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -7,6 +7,8 @@ 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 remarkMath from 'remark-math' const contentDir = process.env?.CHRYSOBLOG_CONTENT ?? "src/content"; @@ -28,6 +30,15 @@ const highlightingThemes = { light: 'vitesse-light', dark: 'vitesse-dark', }; +const katexOptions = { + macros: { + "\\Nat": "\\mathbb N", + "\\Complex": "\\mathbb C", + "\\vec": "\\boldsymbol", + "\\mat": "\\boldsymbol", + "\\rv": "\\mathrm", + }, +}; const themes = Object.keys(highlightingThemes).map(function(k){ return highlightingThemes[k] }); const highlighter = await getHighlighter({ @@ -47,8 +58,10 @@ const config = { remarkAlert, relativeImages, [remarkToc, {tight: true}], + remarkMath, ], rehypePlugins: [ + [ rehypeKatexSvelte, katexOptions ], rehypeSlug, ], highlight: { @@ -78,9 +91,7 @@ const config = { }), prerender: { crawl: true, - entries: [ - "/page/1/", - ], + entries: ['*'], }, alias: { $content: contentDir, diff --git a/tests/post.spec.ts b/tests/post.spec.ts index bcd1052..fde2be8 100644 --- a/tests/post.spec.ts +++ b/tests/post.spec.ts @@ -5,3 +5,15 @@ test('Navigate to blog post', async ({ page }) => { await page.getByText('The Perfect Math Class').click(); await expect(page).toHaveURL("/post/the-perfect-math-class/"); }); + +test('Navigate to page 2', async ({ page }) => { + await page.goto('/post'); + await page.getByRole('link', { name: 'Next Page' }).click(); + await expect(page).toHaveURL("/page/2/"); + await page.getByRole('link', { name: 'Prev Page' }).click(); + await expect(page).toHaveURL("/post/"); + await page.getByRole('link', { name: 'Last Page' }).click(); + await expect(page).toHaveURL("/page/2/"); + await page.getByRole('link', { name: 'First Page' }).click(); + await expect(page).toHaveURL("/post/"); +});