diff --git a/astro.config.ts b/astro.config.ts index 59baf3ce..78516bca 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -5,6 +5,8 @@ import { defineConfig } from 'astro/config' import robotsTxt from 'astro-robots-txt' import UnoCSS from 'unocss/astro' import { themeConfig } from './src/.config' +import remarkMath from 'remark-math' +import rehypeKatex from 'rehype-katex' // https://astro.build/config export default defineConfig({ @@ -12,8 +14,12 @@ export default defineConfig({ prefetch: true, base: '/', markdown: { - remarkPlugins: [], - rehypePlugins: [], + remarkPlugins: [ + remarkMath, + ], + rehypePlugins: [ + rehypeKatex, + ], shikiConfig: { theme: 'dracula', wrap: true, @@ -21,7 +27,14 @@ export default defineConfig({ }, integrations: [ UnoCSS({ injectReset: true }), - mdx(), + mdx({ + remarkPlugins: [ + remarkMath, + ], + rehypePlugins: [ + rehypeKatex, + ], + }), robotsTxt(), sitemap(), swup({ diff --git a/package.json b/package.json index 55818ba3..a7a80a1a 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,9 @@ "astro-robots-txt": "^1.0.0", "astro-seo": "^0.8.4", "giscus": "^1.5.0", + "katex": "^0.16.11", + "rehype-katex": "^7.0.1", + "remark-math": "^6.0.0", "typescript": "~5.5.4", "vite": "^5.4.6" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 03027ac0..7e3d9978 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -38,6 +38,15 @@ importers: giscus: specifier: ^1.5.0 version: 1.5.0 + katex: + specifier: ^0.16.11 + version: 0.16.11 + rehype-katex: + specifier: ^7.0.1 + version: 7.0.1 + remark-math: + specifier: ^6.0.0 + version: 6.0.0 typescript: specifier: ~5.5.4 version: 5.5.4 @@ -2070,6 +2079,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/linkify-it@5.0.0': resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} @@ -2747,6 +2759,10 @@ packages: resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} engines: {node: '>= 10'} + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + comment-parser@1.4.1: resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==} engines: {node: '>= 12.0.0'} @@ -3619,6 +3635,12 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} + hast-util-from-dom@5.0.0: + resolution: {integrity: sha512-d6235voAp/XR3Hh5uy7aGLbM3S4KamdW0WEgOaU1YoewnuYw4HXb5eRtv9g65m/RFGEfUY1Mw4UqCc5Y8L4Stg==} + + hast-util-from-html-isomorphic@2.0.0: + resolution: {integrity: sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==} + hast-util-from-html@2.0.1: resolution: {integrity: sha512-RXQBLMl9kjKVNkJTIO6bZyb2n+cUH8LFaSSzo82jiLT6Tfc+Pt7VQCS+/h3YwG4jaNE2TA2sdJisGWR+aJrp0g==} @@ -3993,6 +4015,10 @@ packages: jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + katex@0.16.11: + resolution: {integrity: sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ==} + hasBin: true + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -4161,6 +4187,9 @@ packages: mdast-util-gfm@3.0.0: resolution: {integrity: sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==} + mdast-util-math@3.0.0: + resolution: {integrity: sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==} + mdast-util-mdx-expression@2.0.0: resolution: {integrity: sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==} @@ -4229,6 +4258,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.0: resolution: {integrity: sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==} @@ -4998,6 +5030,9 @@ packages: resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} hasBin: true + rehype-katex@7.0.1: + resolution: {integrity: sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==} + rehype-parse@9.0.0: resolution: {integrity: sha512-WG7nfvmWWkCR++KEkZevZb/uw41E8TsH4DsY9UxsTbIXCVGbAs4S+r8FrQ+OtH5EEQAs+5UxKC42VinkmpA1Yw==} @@ -5013,6 +5048,9 @@ packages: remark-gfm@4.0.0: resolution: {integrity: sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==} + remark-math@6.0.0: + resolution: {integrity: sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==} + remark-mdx@3.0.1: resolution: {integrity: sha512-3Pz3yPQ5Rht2pM5R+0J2MrGoBSrzf+tJG94N+t/ilfdh8YLyyKYtidAYwTveB20BoHAcwIopOUqhcmh2F7hGYA==} @@ -8125,6 +8163,8 @@ snapshots: dependencies: '@types/unist': 3.0.2 + '@types/katex@0.16.7': {} + '@types/linkify-it@5.0.0': {} '@types/markdown-it@14.1.2': @@ -9090,6 +9130,8 @@ snapshots: commander@7.2.0: {} + commander@8.3.0: {} + comment-parser@1.4.1: {} common-ancestor-path@1.0.1: {} @@ -10202,6 +10244,19 @@ snapshots: dependencies: function-bind: 1.1.2 + hast-util-from-dom@5.0.0: + dependencies: + '@types/hast': 3.0.4 + hastscript: 8.0.0 + 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.0 + hast-util-from-html: 2.0.1 + unist-util-remove-position: 5.0.0 + hast-util-from-html@2.0.1: dependencies: '@types/hast': 3.0.4 @@ -10617,6 +10672,10 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 + katex@0.16.11: + dependencies: + commander: 8.3.0 + keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -10881,6 +10940,18 @@ snapshots: transitivePeerDependencies: - supports-color + mdast-util-math@3.0.0: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.3 + devlop: 1.1.0 + longest-streak: 3.1.0 + mdast-util-from-markdown: 2.0.1 + mdast-util-to-markdown: 2.1.0 + unist-util-remove-position: 5.0.0 + transitivePeerDependencies: + - supports-color + mdast-util-mdx-expression@2.0.0: dependencies: '@types/estree-jsx': 1.0.5 @@ -11098,6 +11169,16 @@ snapshots: micromark-util-combine-extensions: 2.0.0 micromark-util-types: 2.0.0 + micromark-extension-math@3.1.0: + dependencies: + '@types/katex': 0.16.7 + devlop: 1.1.0 + katex: 0.16.11 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + micromark-extension-mdx-expression@3.0.0: dependencies: '@types/estree': 1.0.5 @@ -11946,6 +12027,16 @@ snapshots: dependencies: jsesc: 0.5.0 + 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.11 + unist-util-visit-parents: 6.0.1 + vfile: 6.0.3 + rehype-parse@9.0.0: dependencies: '@types/hast': 3.0.4 @@ -11982,6 +12073,15 @@ snapshots: transitivePeerDependencies: - supports-color + remark-math@6.0.0: + dependencies: + '@types/mdast': 4.0.3 + mdast-util-math: 3.0.0 + micromark-extension-math: 3.1.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + remark-mdx@3.0.1: dependencies: mdast-util-mdx: 3.0.0 diff --git a/src/.config/default.ts b/src/.config/default.ts index 9a9e2ceb..46c0f138 100644 --- a/src/.config/default.ts +++ b/src/.config/default.ts @@ -84,5 +84,9 @@ export const defaultConfig: ThemeConfig = { }, analytics: { googleAnalyticsId: '', + umamiAnalyticsId: '', + }, + latex: { + katex: false, }, } diff --git a/src/components/Analytics.astro b/src/components/Analytics.astro index 4cd9f3d7..0539e594 100644 --- a/src/components/Analytics.astro +++ b/src/components/Analytics.astro @@ -1,9 +1,14 @@ --- import GoogleAnalytics from '~/components/analytics/GoogleAnalytics.astro' +import UmamiAnalytics from '~/components/analytics/UmamiAnalytics.astro' import { themeConfig } from '~/.config' const PUBLIC_GOOGLE_ANALYTICS_ID = import.meta.env.PUBLIC_GOOGLE_ANALYTICS_ID const googleAnalyticsId = themeConfig.analytics.googleAnalyticsId || PUBLIC_GOOGLE_ANALYTICS_ID + +const PUBLIC_UMAMI_ANALYTICS_ID = import.meta.env.PUBLIC_UMAMI_ANALYTICS_ID +const umamiAnalyticsId = themeConfig.analytics.umamiAnalyticsId || PUBLIC_UMAMI_ANALYTICS_ID --- {googleAnalyticsId && } +{umamiAnalyticsId && } diff --git a/src/components/LaTeX.astro b/src/components/LaTeX.astro new file mode 100644 index 00000000..2df7ce63 --- /dev/null +++ b/src/components/LaTeX.astro @@ -0,0 +1,17 @@ +--- +import { themeConfig } from '~/.config' + +const { latex } = themeConfig + +const katex = latex.katex +--- + +{katex && ( + <> + + + + +)} + diff --git a/src/components/analytics/UmamiAnalytics.astro b/src/components/analytics/UmamiAnalytics.astro new file mode 100644 index 00000000..d68645f2 --- /dev/null +++ b/src/components/analytics/UmamiAnalytics.astro @@ -0,0 +1,10 @@ +--- +interface Props { + id: string +} + +const { id } = Astro.props +--- + + + diff --git a/src/env.d.ts b/src/env.d.ts index f66083a9..8f7a23b4 100644 --- a/src/env.d.ts +++ b/src/env.d.ts @@ -8,6 +8,7 @@ declare namespace App { interface ImportMetaEnv { readonly PUBLIC_GOOGLE_ANALYTICS_ID: string + readonly PUBLIC_UMAMI_ANALYTICS_ID: string } interface ImportMeta { diff --git a/src/layouts/LayoutDefault.astro b/src/layouts/LayoutDefault.astro index ab2fa4dc..569905b3 100644 --- a/src/layouts/LayoutDefault.astro +++ b/src/layouts/LayoutDefault.astro @@ -4,6 +4,7 @@ import SiteFooter from '~/components/SiteFooter.astro' import SiteNavigation from '~/components/SiteNavigation.astro' import SiteTitle from '~/components/SiteTitle.astro' import SiteSeo from '~/components/SiteSeo.astro' +import LaTeX from '~/components/LaTeX.astro' import Analytics from '~/components/Analytics.astro' import '~/styles/global.css' @@ -14,6 +15,7 @@ const dark = themeConfig.appearance.theme === 'dark' + diff --git a/src/types/themeConfig.ts b/src/types/themeConfig.ts index d5acd226..3a76cd58 100644 --- a/src/types/themeConfig.ts +++ b/src/types/themeConfig.ts @@ -21,6 +21,7 @@ export interface ThemeConfig { comment: Partial rss: ConfigRSS analytics: ConfigAnalytics + latex: ConfigLaTeX } export type UserConfig = DeepPartial @@ -67,6 +68,11 @@ export interface ConfigRSS { export interface ConfigAnalytics { /** google analytics */ googleAnalyticsId: string + umamiAnalyticsId: string +} + +export interface ConfigLaTeX { + katex: boolean } interface Colors {