From 0467326d5c082c42c0ede88ee2d3472f5fb65600 Mon Sep 17 00:00:00 2001 From: NN708 Date: Sun, 15 Feb 2026 20:53:36 +0800 Subject: [PATCH] fix: render equations in markdown preview (#5745) --- frontend/package.json | 1 + frontend/pnpm-lock.yaml | 28 ++++++++++++++++++++++++++++ frontend/src/views/files/Editor.vue | 6 ++++++ 3 files changed, 35 insertions(+) diff --git a/frontend/package.json b/frontend/package.json index a79a930d..aedaa499 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -30,6 +30,7 @@ "jwt-decode": "^4.0.0", "lodash-es": "^4.17.21", "marked": "^17.0.0", + "marked-katex-extension": "^5.1.6", "material-icons": "^1.13.14", "normalize.css": "^8.0.1", "pinia": "^3.0.4", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 1039909d..daa46285 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -47,6 +47,9 @@ importers: marked: specifier: ^17.0.0 version: 17.0.2 + marked-katex-extension: + specifier: ^5.1.6 + version: 5.1.6(katex@0.16.28)(marked@17.0.2) material-icons: specifier: ^1.13.14 version: 1.13.14 @@ -1663,6 +1666,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'} + confbox@0.1.8: resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} @@ -2058,6 +2065,10 @@ packages: resolution: {integrity: sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==} engines: {node: '>=18'} + katex@0.16.28: + resolution: {integrity: sha512-YHzO7721WbmAL6Ov1uzN/l5mY5WWWhJBSW+jq4tkfZfsxmo1hu6frS0EOswvjBUnWE6NtjEs48SFn5CQESRLZg==} + hasBin: true + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -2128,6 +2139,12 @@ packages: magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + marked-katex-extension@5.1.6: + resolution: {integrity: sha512-vYpLXwmlIDKILIhJtiRTgdyZRn5sEYdFBuTmbpjD7lbCIzg0/DWyK3HXIntN3Tp8zV6hvOUgpZNLWRCgWVc24A==} + peerDependencies: + katex: '>=0.16 <0.17' + marked: '>=4 <18' + marked@17.0.2: resolution: {integrity: sha512-s5HZGFQea7Huv5zZcAGhJLT3qLpAfnY7v7GWkICUr0+Wd5TFEtdlRR2XUL5Gg+RH7u2Df595ifrxR03mBaw7gA==} engines: {node: '>= 20'} @@ -4219,6 +4236,8 @@ snapshots: commander@2.20.3: {} + commander@8.3.0: {} + confbox@0.1.8: {} confbox@0.2.4: {} @@ -4640,6 +4659,10 @@ snapshots: jwt-decode@4.0.0: {} + katex@0.16.28: + dependencies: + commander: 8.3.0 + keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -4721,6 +4744,11 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + marked-katex-extension@5.1.6(katex@0.16.28)(marked@17.0.2): + dependencies: + katex: 0.16.28 + marked: 17.0.2 + marked@17.0.2: {} marks-pane@1.0.9: {} diff --git a/frontend/src/views/files/Editor.vue b/frontend/src/views/files/Editor.vue index 4ce7b427..dbde609e 100644 --- a/frontend/src/views/files/Editor.vue +++ b/frontend/src/views/files/Editor.vue @@ -94,6 +94,7 @@ import { useFileStore } from "@/stores/file"; import { useLayoutStore } from "@/stores/layout"; import { getEditorTheme } from "@/utils/theme"; import { marked } from "marked"; +import markedKatex from "marked-katex-extension"; import { inject, onBeforeUnmount, onMounted, ref, watchEffect } from "vue"; import { useI18n } from "vue-i18n"; import { onBeforeRouteUpdate, useRoute, useRouter } from "vue-router"; @@ -118,6 +119,11 @@ const previewContent = ref(""); const isMarkdownFile = fileStore.req?.name.endsWith(".md") || fileStore.req?.name.endsWith(".markdown"); +const katexOptions = { + output: "mathml" as const, + throwOnError: false +}; +marked.use(markedKatex(katexOptions)); const isSelectionEmpty = ref(true);