diff --git a/README.md b/README.md index d80199d..7e0381a 100644 --- a/README.md +++ b/README.md @@ -8,12 +8,14 @@ Demo: https://icy-beach-00f5be01e.6.azurestaticapps.net/ ## 🌌 Features - Minimal, terminal like -- Ship only necessary JavaScript -- Full text search based on `Fuse.js` +- Ship only necessary JavaScript (even can be no JavaScript at all) +- Full text search ~~based on `Fuse.js`~~ - Full text RSS - Create Blogrolls via a yaml file - Your status at Fediverse, now at your home - Comments powered by multiple engines +- Umami/Goatcounter statics support +- TeX formulas support ## 🚀 Getting Started clone the repo and install dependencies: diff --git a/astro.config.mjs b/astro.config.mjs index b778f5c..3e85640 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -6,6 +6,8 @@ import mdx from '@astrojs/mdx'; import cloudflare from '@astrojs/cloudflare'; +import remarkMath from "remark-math"; +import rehypeKatex from "rehype-katex"; export default defineConfig({ site: 'https://terminal-blog.example.com', @@ -25,6 +27,8 @@ export default defineConfig({ theme: 'nord', wrap: true }, + remarkPlugins: [ remarkMath ], + rehypePlugins: [ rehypeKatex ] }, integrations: [sitemap(), mdx()], diff --git a/package.json b/package.json index b409a5e..914a9bf 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,9 @@ "@fontsource-variable/jetbrains-mono": "^5.2.5", "astro": "^5.2.5", "ico-endec": "^0.1.6", + "katex": "^0.16.22", + "rehype-katex": "^7.0.1", + "remark-math": "^6.0.0", "sharp": "^0.34.1", "ultrahtml": "^1.6.0" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 320fe3a..20e9a9a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -32,6 +32,15 @@ importers: ico-endec: specifier: ^0.1.6 version: 0.1.6 + katex: + specifier: ^0.16.22 + version: 0.16.22 + rehype-katex: + specifier: ^7.0.1 + version: 7.0.1 + remark-math: + specifier: ^6.0.0 + version: 6.0.0 sharp: specifier: ^0.34.1 version: 0.34.1 @@ -980,6 +989,9 @@ packages: '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + '@types/katex@0.16.7': + resolution: {integrity: sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==} + '@types/lodash@4.17.16': resolution: {integrity: sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g==} @@ -1281,6 +1293,10 @@ packages: commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + commander@9.5.0: resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} engines: {node: ^12.20.0 || >=14} @@ -1776,6 +1792,12 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} + hast-util-from-dom@5.0.1: + resolution: {integrity: sha512-N+LqofjR2zuzTjCPzyDUdSshy4Ma6li7p/c3pA78uTwzFgENbgbUrm2ugwsOdcjI1muO+o6Dgzp9p8WHtn/39Q==} + + hast-util-from-html-isomorphic@2.0.0: + resolution: {integrity: sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==} + hast-util-from-html@2.0.3: resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==} @@ -2000,6 +2022,10 @@ packages: resolution: {integrity: sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==} engines: {node: '>=18'} + katex@0.16.22: + resolution: {integrity: sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg==} + hasBin: true + keytar@7.9.0: resolution: {integrity: sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==} @@ -2100,6 +2126,9 @@ packages: mdast-util-gfm@3.1.0: resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + mdast-util-math@3.0.0: + resolution: {integrity: sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==} + mdast-util-mdx-expression@2.0.1: resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} @@ -2154,6 +2183,9 @@ packages: micromark-extension-gfm@3.0.0: resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + micromark-extension-math@3.1.0: + resolution: {integrity: sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==} + micromark-extension-mdx-expression@3.0.1: resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==} @@ -2588,6 +2620,9 @@ packages: resolution: {integrity: sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==} engines: {node: '>=12'} + rehype-katex@7.0.1: + resolution: {integrity: sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==} + rehype-parse@9.0.1: resolution: {integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==} @@ -2606,6 +2641,9 @@ packages: remark-gfm@4.0.1: resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + remark-math@6.0.0: + resolution: {integrity: sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==} + remark-mdx@3.1.0: resolution: {integrity: sha512-Ngl/H3YXyBV9RcRNdlYsZujAmhsxwzxpDzpDEhFBVAGthS4GDgnctpDjgFl/ULx5UEDzqtW1cyBSNKqYYrqLBA==} @@ -4165,6 +4203,8 @@ snapshots: dependencies: '@types/unist': 3.0.3 + '@types/katex@0.16.7': {} + '@types/lodash@4.17.16': {} '@types/mdast@4.0.4': @@ -4529,6 +4569,8 @@ snapshots: commander@2.20.3: {} + commander@8.3.0: {} + commander@9.5.0: {} common-ancestor-path@1.0.1: {} @@ -5059,6 +5101,19 @@ snapshots: dependencies: function-bind: 1.1.2 + hast-util-from-dom@5.0.1: + dependencies: + '@types/hast': 3.0.4 + hastscript: 9.0.1 + web-namespaces: 2.0.1 + + hast-util-from-html-isomorphic@2.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-from-dom: 5.0.1 + hast-util-from-html: 2.0.3 + unist-util-remove-position: 5.0.0 + hast-util-from-html@2.0.3: dependencies: '@types/hast': 3.0.4 @@ -5375,6 +5430,10 @@ snapshots: jwt-decode@4.0.0: {} + katex@0.16.22: + dependencies: + commander: 8.3.0 + keytar@7.9.0: dependencies: node-addon-api: 4.3.0 @@ -5524,6 +5583,18 @@ snapshots: transitivePeerDependencies: - supports-color + mdast-util-math@3.0.0: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + longest-streak: 3.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + unist-util-remove-position: 5.0.0 + transitivePeerDependencies: + - supports-color + mdast-util-mdx-expression@2.0.1: dependencies: '@types/estree-jsx': 1.0.5 @@ -5687,6 +5758,16 @@ snapshots: micromark-util-combine-extensions: 2.0.1 micromark-util-types: 2.0.2 + micromark-extension-math@3.1.0: + dependencies: + '@types/katex': 0.16.7 + devlop: 1.1.0 + katex: 0.16.22 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + micromark-extension-mdx-expression@3.0.1: dependencies: '@types/estree': 1.0.7 @@ -6246,6 +6327,16 @@ snapshots: dependencies: rc: 1.2.8 + rehype-katex@7.0.1: + dependencies: + '@types/hast': 3.0.4 + '@types/katex': 0.16.7 + hast-util-from-html-isomorphic: 2.0.0 + hast-util-to-text: 4.0.2 + katex: 0.16.22 + unist-util-visit-parents: 6.0.1 + vfile: 6.0.3 + rehype-parse@9.0.1: dependencies: '@types/hast': 3.0.4 @@ -6290,6 +6381,15 @@ snapshots: transitivePeerDependencies: - supports-color + remark-math@6.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-math: 3.0.0 + micromark-extension-math: 3.1.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + remark-mdx@3.1.0: dependencies: mdast-util-mdx: 3.0.0 diff --git a/src/content/posts/markdown-example/index.mdx b/src/content/posts/markdown-example/index.mdx index 322b2ab..d61157f 100644 --- a/src/content/posts/markdown-example/index.mdx +++ b/src/content/posts/markdown-example/index.mdx @@ -246,4 +246,35 @@ Xn + Yn = Zn Press CTRL+ALT+Delete to end the session. -Most salamanders are nocturnal, and hunt for insects, worms, and other small creatures. \ No newline at end of file +Most salamanders are nocturnal, and hunt for insects, worms, and other small creatures. + +### Formulas +Thanks to the [remark-math](https://github.com/remarkjs/remark-math) and [KaTeX](https://katex.org/) , you can write mathematical formulas using LaTeX syntax. + +Both inline and block formulas are supported (see example below). Inline formulas can be written like `$$L$$` or `$L$`, + +while block formulas can be written like this: + +```latex +$$ +-\frac{\hbar^2}{2m}\nabla^2\psi + V\psi = E\psi +$$ +``` + +or + +````markdown +```math +-\frac{\hbar^2}{2m}\nabla^2\psi + V\psi = E\psi +``` +```` + +By default, the reader can copy the formulas in LaTeX format by copy the rendered formulas, unless you set `noClientJavaScript` to `true` in the `config.ts` file. + + +Lift($$L$$) can be determined by Lift Coefficient ($$C_L$$) like the following +equation: + +$$ +L = \frac{1}{2} \rho v^2 S C_L +$$ \ No newline at end of file diff --git a/src/pages/blog/[...slug].astro b/src/pages/blog/[...slug].astro index 45598b4..4f2fee2 100644 --- a/src/pages/blog/[...slug].astro +++ b/src/pages/blog/[...slug].astro @@ -9,6 +9,7 @@ import ReplyViaEmail from "../../components/ReplyViaEmail.astro"; import { ExtractFirstImage } from '../../plugins/extract-images'; import AuthorInfo from "../../components/helper/authors/Info.astro"; import TableOfContents from "../../components/TableOfContents.astro"; +import "katex/dist/katex.css" export async function getStaticPaths() { const blogEntries = await getCollection('posts'); @@ -61,7 +62,12 @@ const cover = customFeaturedImage || matchedImage_src?.src || firstImageURL || `
← Back to posts - {noscript &&

Comments

} + {!noscript &&

Comments

} + {!noscript && + + }