From aa87051c15a77457a816f588b24ce164722da40e Mon Sep 17 00:00:00 2001 From: biss Date: Thu, 18 Jun 2026 17:48:17 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=87=E7=AB=A0-=E4=BB=A3=E7=A0=81-=E8=A1=A8?= =?UTF-8?q?=E6=A0=BC-=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- astro.config.mjs | 5 +- package-lock.json | 186 ++++++++++++++++++++++++- package.json | 4 +- src/layouts/BaseLayout.astro | 2 + src/pages/posts/[slug].astro | 120 ++++++++++++++++ src/styles/site.css | 262 ++++++++++++++++++++++++++++++++++- 6 files changed, 574 insertions(+), 5 deletions(-) diff --git a/astro.config.mjs b/astro.config.mjs index bdc3539..d4faba4 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,6 +1,8 @@ import { defineConfig } from 'astro/config'; import sitemap from '@astrojs/sitemap'; import { unified } from '@astrojs/markdown-remark'; +import rehypeMathjax from 'rehype-mathjax'; +import remarkMath from 'remark-math'; import remarkHexoLinkCards from './src/lib/remarkHexoLinkCards.mjs'; export default defineConfig({ @@ -11,7 +13,8 @@ export default defineConfig({ integrations: [sitemap()], markdown: { processor: unified({ - remarkPlugins: [remarkHexoLinkCards], + remarkPlugins: [remarkMath, remarkHexoLinkCards], + rehypePlugins: [rehypeMathjax], }), shikiConfig: { theme: 'github-dark', diff --git a/package-lock.json b/package-lock.json index 233f906..1f1618e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,9 @@ "dependencies": { "@astrojs/rss": "^4.0.18", "@astrojs/sitemap": "^3.7.3", - "astro": "^6.4.8" + "astro": "^6.4.8", + "rehype-mathjax": "^7.1.0", + "remark-math": "^6.0.0" } }, "node_modules/@astrojs/compiler": { @@ -1753,6 +1755,18 @@ "@types/unist": "*" } }, + "node_modules/@types/katex": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.8.tgz", + "integrity": "sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==", + "license": "MIT" + }, + "node_modules/@types/mathjax": { + "version": "0.0.40", + "resolved": "https://registry.npmjs.org/@types/mathjax/-/mathjax-0.0.40.tgz", + "integrity": "sha512-rHusx08LCg92WJxrsM3SPjvLTSvK5C+gealtSuhKbEOcUZfWlwigaFoPLf6Dfxhg4oryN5qP9Sj7zOQ4HYXINw==", + "license": "MIT" + }, "node_modules/@types/mdast": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", @@ -1807,6 +1821,15 @@ "integrity": "sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==", "license": "ISC" }, + "node_modules/@xmldom/xmldom": { + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.10.tgz", + "integrity": "sha512-A9gOqLdi6cV4ibazAjcQufGj0B1y/vDqYrcuP6d/6x8P27gRS8643Dj9o1dEKtB6O7fwxb2FgBmJS2mX7gpvdw==", + "license": "MIT", + "engines": { + "node": ">=14.6" + } + }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -2185,6 +2208,15 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/common-ancestor-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-2.0.0.tgz", @@ -2503,6 +2535,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/esm": { + "version": "3.2.25", + "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", + "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/eventemitter3": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", @@ -2930,6 +2971,22 @@ "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", "license": "MIT" }, + "node_modules/katex": { + "version": "0.16.47", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.47.tgz", + "integrity": "sha512-Eeo8Ys1doU1z+x8AZsPpQu+p/QcZBI5PeOo7QGQdy2x2m0MU/hYagBbGOmXwr5KVbEfVuWv9LpnQWeehogurjg==", + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "license": "MIT", + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" + } + }, "node_modules/longest-streak": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", @@ -2970,6 +3027,18 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/mathjax-full": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/mathjax-full/-/mathjax-full-3.2.1.tgz", + "integrity": "sha512-aUz9o16MGZdeiIBwZjAfUBTiJb7LRqzZEl1YOZ8zQMGYIyh1/nxRebxKxjDe9L+xcZCr2OHdzoFBMcd6VnLv9Q==", + "license": "Apache-2.0", + "dependencies": { + "esm": "^3.2.25", + "mhchemparser": "^4.1.0", + "mj-context-menu": "^0.6.1", + "speech-rule-engine": "^4.0.6" + } + }, "node_modules/mdast-util-definitions": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-6.0.0.tgz", @@ -3126,6 +3195,25 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/mdast-util-math": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-math/-/mdast-util-math-3.0.0.tgz", + "integrity": "sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "longest-streak": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.1.0", + "unist-util-remove-position": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdast-util-phrasing": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", @@ -3201,6 +3289,12 @@ "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", "license": "CC0-1.0" }, + "node_modules/mhchemparser": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/mhchemparser/-/mhchemparser-4.2.1.tgz", + "integrity": "sha512-kYmyrCirqJf3zZ9t/0wGgRZ4/ZJw//VwaRVGA75C4nhE60vtnIzhl9J9ndkX/h6hxSN7pjg/cE0VxbnNM+bnDQ==", + "license": "Apache-2.0" + }, "node_modules/micromark": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", @@ -3391,6 +3485,25 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/micromark-extension-math": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz", + "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==", + "license": "MIT", + "dependencies": { + "@types/katex": "^0.16.0", + "devlop": "^1.0.0", + "katex": "^0.16.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/micromark-factory-destination": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", @@ -3787,6 +3900,12 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, + "node_modules/mj-context-menu": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/mj-context-menu/-/mj-context-menu-0.6.1.tgz", + "integrity": "sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA==", + "license": "Apache-2.0" + }, "node_modules/mrmime": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", @@ -4139,6 +4258,26 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/rehype-mathjax": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/rehype-mathjax/-/rehype-mathjax-7.1.0.tgz", + "integrity": "sha512-mJHNpoqCC5UZ24OKx0wNjlzV18qeJz/Q/LtEjxXzt8vqrZ1Z3GxQnVrHcF5/PogcXUK8cWwJ4U/LWOQWEiABHw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mathjax": "^0.0.40", + "hast-util-to-text": "^4.0.0", + "hastscript": "^9.0.0", + "mathjax-full": "^3.0.0", + "unified": "^11.0.0", + "unist-util-visit-parents": "^6.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/rehype-parse": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-9.0.1.tgz", @@ -4202,6 +4341,22 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/remark-math": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/remark-math/-/remark-math-6.0.0.tgz", + "integrity": "sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-math": "^3.0.0", + "micromark-extension-math": "^3.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/remark-parse": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", @@ -4520,6 +4675,29 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/speech-rule-engine": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/speech-rule-engine/-/speech-rule-engine-4.1.4.tgz", + "integrity": "sha512-i/VCLG1fvRc95pMHRqG4aQNscv+9aIsqA2oI7ZQS51sTdUcDHYX6cpT8/tqZ+enjs1tKVwbRBWgxut9SWn+f9g==", + "license": "Apache-2.0", + "dependencies": { + "@xmldom/xmldom": "0.9.10", + "commander": "13.1.0", + "wicked-good-xpath": "1.3.0" + }, + "bin": { + "sre": "bin/sre" + } + }, + "node_modules/speech-rule-engine/node_modules/commander": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", + "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/stream-replace-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/stream-replace-string/-/stream-replace-string-2.0.0.tgz", @@ -5054,6 +5232,12 @@ "node": ">=4" } }, + "node_modules/wicked-good-xpath": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz", + "integrity": "sha512-Gd9+TUn5nXdwj/hFsPVx5cuHHiF5Bwuc30jZ4+ronF1qHK5O7HD0sgmXWSEgwKquT3ClLoKPVbO6qGwVwLzvAw==", + "license": "MIT" + }, "node_modules/xml-naming": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/xml-naming/-/xml-naming-0.1.0.tgz", diff --git a/package.json b/package.json index 2839978..7929bff 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,8 @@ "dependencies": { "@astrojs/rss": "^4.0.18", "@astrojs/sitemap": "^3.7.3", - "astro": "^6.4.8" + "astro": "^6.4.8", + "rehype-mathjax": "^7.1.0", + "remark-math": "^6.0.0" } } diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro index fabe069..3ddc814 100644 --- a/src/layouts/BaseLayout.astro +++ b/src/layouts/BaseLayout.astro @@ -20,6 +20,7 @@ const currentYear = new Date().getFullYear(); + {pageTitle} @@ -102,6 +103,7 @@ const currentYear = new Date().getFullYear(); + + + diff --git a/src/styles/site.css b/src/styles/site.css index 5d4472a..3e6c6b0 100644 --- a/src/styles/site.css +++ b/src/styles/site.css @@ -1182,20 +1182,262 @@ time { } .prose img { + display: block; max-width: 100%; + height: auto; + margin: 1.4em auto; border-radius: 8px; } -.prose pre { - overflow-x: auto; +.prose .fancybox { + display: block; + width: fit-content; + max-width: 100%; + margin: 1.4em auto; border-radius: 8px; + text-decoration: none; +} + +.prose .fancybox img { + margin: 0 auto; + box-shadow: 0 12px 32px rgba(44, 55, 63, 0.12); + transition: + box-shadow 0.2s ease, + transform 0.2s ease; +} + +.prose .fancybox:hover img { + box-shadow: 0 16px 38px rgba(15, 118, 110, 0.16); + transform: translateY(-1px); +} + +.prose pre { + margin: 0; + overflow-x: auto; padding: 18px; + overscroll-behavior-inline: contain; + scrollbar-color: rgba(102, 200, 245, 0.58) rgba(255, 255, 255, 0.08); + scrollbar-width: thin; } .prose code { font-family: "JetBrains Mono", Consolas, monospace; } +.prose .code-block { + position: relative; + margin: 1.25em 0; + overflow: hidden; + border: 1px solid rgba(15, 118, 110, 0.16); + border-radius: 8px; + background: rgba(22, 31, 36, 0.96); + box-shadow: 0 14px 32px rgba(44, 55, 63, 0.12); +} + +.prose .code-block pre::-webkit-scrollbar, +.table-scroll::-webkit-scrollbar { + height: 10px; +} + +.prose .code-block pre::-webkit-scrollbar-track, +.table-scroll::-webkit-scrollbar-track { + border-radius: 999px; + background: rgba(255, 255, 255, 0.08); +} + +.prose .code-block pre::-webkit-scrollbar-thumb, +.table-scroll::-webkit-scrollbar-thumb { + border: 2px solid rgba(255, 255, 255, 0.08); + border-radius: 999px; + background: + linear-gradient(90deg, rgba(102, 200, 245, 0.72), rgba(62, 184, 190, 0.76)), + rgba(62, 184, 190, 0.72); +} + +.prose .code-block pre::-webkit-scrollbar-thumb:hover, +.table-scroll::-webkit-scrollbar-thumb:hover { + background: + linear-gradient(90deg, rgba(102, 200, 245, 0.9), rgba(62, 184, 190, 0.94)), + rgba(62, 184, 190, 0.9); +} + +.prose .code-block pre { + max-height: none; + padding: 46px 18px 18px; + background: transparent; + transition: max-height 0.24s ease; +} + +.prose .code-block pre code { + display: block; + min-width: max-content; +} + +.prose .code-block.is-collapsible:not(.is-expanded) pre { + max-height: 15.5em; +} + +.prose .code-block.is-collapsible:not(.is-expanded)::after { + content: ""; + position: absolute; + right: 0; + bottom: 0; + left: 0; + height: 58px; + background: linear-gradient(rgba(22, 31, 36, 0), rgba(22, 31, 36, 0.98)); + pointer-events: none; +} + +.prose .code-block code { + color: #e8edf2; + line-height: 1.65; +} + +.code-block-toolbar { + position: absolute; + top: 8px; + right: 8px; + z-index: 2; + display: flex; + gap: 8px; +} + +.code-block-copy, +.code-block-toggle { + appearance: none; + -webkit-appearance: none; + display: inline-flex; + align-items: center; + justify-content: center; + min-height: 30px; + border: 1px solid rgba(255, 255, 255, 0.18); + border-radius: 8px; + padding: 5px 9px; + color: rgba(255, 255, 255, 0.86); + font: 700 0.78rem/1 Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; + background: rgba(255, 255, 255, 0.1); + cursor: pointer; + backdrop-filter: blur(8px); + -webkit-backdrop-filter: blur(8px); + transition: + color 0.2s ease, + border-color 0.2s ease, + background-color 0.2s ease, + transform 0.2s ease; +} + +.code-block-copy:hover, +.code-block-toggle:hover { + color: #fff; + border-color: rgba(255, 255, 255, 0.34); + background: rgba(62, 184, 190, 0.72); + transform: translateY(-1px); +} + +.code-block-toggle { + display: none; +} + +.code-block.is-collapsible .code-block-toggle { + display: inline-flex; +} + +.table-scroll { + max-width: 100%; + margin: 1.35em 0; + overflow-x: auto; + border: 1px solid rgba(15, 118, 110, 0.14); + border-radius: 8px; + background: + linear-gradient(135deg, rgba(255, 255, 255, 0.72), rgba(236, 253, 245, 0.42)), + rgba(255, 253, 248, 0.78); + box-shadow: 0 14px 34px rgba(44, 55, 63, 0.1); + overscroll-behavior-inline: contain; + scrollbar-color: rgba(62, 184, 190, 0.58) rgba(15, 118, 110, 0.08); + scrollbar-width: thin; +} + +.prose table { + width: 100%; + min-width: 620px; + border-collapse: separate; + border-spacing: 0; + color: #33433f; + font-size: 0.95rem; + line-height: 1.6; +} + +.prose th, +.prose td { + border-right: 1px solid rgba(15, 118, 110, 0.1); + border-bottom: 1px solid rgba(15, 118, 110, 0.1); + padding: 12px 14px; + vertical-align: top; +} + +.prose th:last-child, +.prose td:last-child { + border-right: 0; +} + +.prose tr:last-child td { + border-bottom: 0; +} + +.prose thead th { + color: #2f4a43; + font-weight: 800; + text-align: left; + background: + linear-gradient(135deg, rgba(236, 253, 245, 0.88), rgba(220, 246, 240, 0.72)), + rgba(255, 255, 255, 0.66); +} + +.prose tbody tr:nth-child(even) td { + background: rgba(236, 253, 245, 0.36); +} + +.prose tbody tr:hover td { + background: rgba(102, 200, 245, 0.13); +} + +.fancybox__container { + --fancybox-bg: rgba(32, 36, 42, 0.72); + --fancybox-accent-color: #3eb8be; + backdrop-filter: blur(18px) saturate(145%); + -webkit-backdrop-filter: blur(18px) saturate(145%); +} + +.prose mjx-container { + color: #223833; +} + +.prose mjx-container[display="true"] { + max-width: 100%; + margin: 1.35em 0; + overflow-x: auto; + overflow-y: hidden; + padding: 10px 0; + scrollbar-color: rgba(62, 184, 190, 0.58) rgba(15, 118, 110, 0.08); + scrollbar-width: thin; +} + +.prose mjx-container[display="true"]::-webkit-scrollbar { + height: 8px; +} + +.prose mjx-container[display="true"]::-webkit-scrollbar-track { + border-radius: 999px; + background: rgba(15, 118, 110, 0.08); +} + +.prose mjx-container[display="true"]::-webkit-scrollbar-thumb { + border-radius: 999px; + background: + linear-gradient(90deg, rgba(102, 200, 245, 0.72), rgba(62, 184, 190, 0.76)), + rgba(62, 184, 190, 0.72); +} + .post-copyright-card { position: relative; overflow: hidden; @@ -1826,6 +2068,22 @@ time { gap: 8px; } + .prose .code-block, + .table-scroll { + margin-right: calc(var(--article-padding) * -0.5); + margin-left: calc(var(--article-padding) * -0.5); + } + + .prose .code-block pre { + padding-right: 16px; + padding-left: 16px; + } + + .prose table { + min-width: 560px; + font-size: 0.9rem; + } + .post-copyright-card { padding: 22px 18px 18px; }