feat: add latex rendering (#247)

* feat: add latex rendering

* perf: 提升 css 引入路径

---------

Co-authored-by: ChenZhaoYu <790348264@qq.com>
main
Yule Hou 2 years ago committed by GitHub
parent f7f87e266f
commit 2293969070
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -31,6 +31,7 @@
"GPTAPI", "GPTAPI",
"hljs", "hljs",
"iconify", "iconify",
"katex",
"logprobs", "logprobs",
"nodata", "nodata",
"OPENAI", "OPENAI",

@ -25,6 +25,7 @@
"dependencies": { "dependencies": {
"@vueuse/core": "^9.13.0", "@vueuse/core": "^9.13.0",
"highlight.js": "^11.7.0", "highlight.js": "^11.7.0",
"katex": "^0.16.4",
"marked": "^4.2.12", "marked": "^4.2.12",
"naive-ui": "^2.34.3", "naive-ui": "^2.34.3",
"pinia": "^2.0.32", "pinia": "^2.0.32",
@ -38,6 +39,7 @@
"@commitlint/config-conventional": "^17.4.4", "@commitlint/config-conventional": "^17.4.4",
"@iconify/vue": "^4.1.0", "@iconify/vue": "^4.1.0",
"@types/crypto-js": "^4.1.1", "@types/crypto-js": "^4.1.1",
"@types/katex": "^0.16.0",
"@types/marked": "^4.0.8", "@types/marked": "^4.0.8",
"@types/node": "^18.14.4", "@types/node": "^18.14.4",
"@vitejs/plugin-vue": "^4.0.0", "@vitejs/plugin-vue": "^4.0.0",

@ -6,6 +6,7 @@ specifiers:
'@commitlint/config-conventional': ^17.4.4 '@commitlint/config-conventional': ^17.4.4
'@iconify/vue': ^4.1.0 '@iconify/vue': ^4.1.0
'@types/crypto-js': ^4.1.1 '@types/crypto-js': ^4.1.1
'@types/katex': ^0.16.0
'@types/marked': ^4.0.8 '@types/marked': ^4.0.8
'@types/node': ^18.14.4 '@types/node': ^18.14.4
'@vitejs/plugin-vue': ^4.0.0 '@vitejs/plugin-vue': ^4.0.0
@ -16,6 +17,7 @@ specifiers:
eslint: ^8.35.0 eslint: ^8.35.0
highlight.js: ^11.7.0 highlight.js: ^11.7.0
husky: ^8.0.3 husky: ^8.0.3
katex: ^0.16.4
less: ^4.1.3 less: ^4.1.3
lint-staged: ^13.1.2 lint-staged: ^13.1.2
marked: ^4.2.12 marked: ^4.2.12
@ -35,6 +37,7 @@ specifiers:
dependencies: dependencies:
'@vueuse/core': 9.13.0_vue@3.2.47 '@vueuse/core': 9.13.0_vue@3.2.47
highlight.js: 11.7.0 highlight.js: 11.7.0
katex: 0.16.4
marked: 4.2.12 marked: 4.2.12
naive-ui: 2.34.3_vue@3.2.47 naive-ui: 2.34.3_vue@3.2.47
pinia: 2.0.32_hmuptsblhheur2tugfgucj7gc4 pinia: 2.0.32_hmuptsblhheur2tugfgucj7gc4
@ -48,6 +51,7 @@ devDependencies:
'@commitlint/config-conventional': 17.4.4 '@commitlint/config-conventional': 17.4.4
'@iconify/vue': 4.1.0_vue@3.2.47 '@iconify/vue': 4.1.0_vue@3.2.47
'@types/crypto-js': 4.1.1 '@types/crypto-js': 4.1.1
'@types/katex': 0.16.0
'@types/marked': 4.0.8 '@types/marked': 4.0.8
'@types/node': 18.14.4 '@types/node': 18.14.4
'@vitejs/plugin-vue': 4.0.0_vite@4.1.4+vue@3.2.47 '@vitejs/plugin-vue': 4.0.0_vite@4.1.4+vue@3.2.47
@ -772,6 +776,10 @@ packages:
resolution: {integrity: sha512-+2FW2CcT0K3P+JMR8YG846bmDwplKUTsWgT2ENwdQ1UdVfRk3GQrh6Mi4sTopy30gI8Uau5CEqHTDZ6YvWIUPA==} resolution: {integrity: sha512-+2FW2CcT0K3P+JMR8YG846bmDwplKUTsWgT2ENwdQ1UdVfRk3GQrh6Mi4sTopy30gI8Uau5CEqHTDZ6YvWIUPA==}
dev: false dev: false
/@types/katex/0.16.0:
resolution: {integrity: sha512-hz+S3nV6Mym5xPbT9fnO8dDhBFQguMYpY0Ipxv06JMi1ORgnEM4M1ymWDUhUNer3ElLmT583opRo4RzxKmh9jw==}
dev: true
/@types/lodash-es/4.17.6: /@types/lodash-es/4.17.6:
resolution: {integrity: sha512-R+zTeVUKDdfoRxpAryaQNRKk3105Rrgx2CFRClIgRGaqDTdjsm8h6IYA8ir584W3ePzkZfst5xIgDwYrlh9HLg==} resolution: {integrity: sha512-R+zTeVUKDdfoRxpAryaQNRKk3105Rrgx2CFRClIgRGaqDTdjsm8h6IYA8ir584W3ePzkZfst5xIgDwYrlh9HLg==}
dependencies: dependencies:
@ -1530,6 +1538,11 @@ packages:
delayed-stream: 1.0.0 delayed-stream: 1.0.0
dev: true dev: true
/commander/8.3.0:
resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==}
engines: {node: '>= 12'}
dev: false
/commander/9.5.0: /commander/9.5.0:
resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==}
engines: {node: ^12.20.0 || >=14} engines: {node: ^12.20.0 || >=14}
@ -3076,6 +3089,13 @@ packages:
engines: {'0': node >= 0.2.0} engines: {'0': node >= 0.2.0}
dev: true dev: true
/katex/0.16.4:
resolution: {integrity: sha512-WudRKUj8yyBeVDI4aYMNxhx5Vhh2PjpzQw1GRu/LVGqL4m1AxwD1GcUp0IMbdJaf5zsjtj8ghP0DOQRYhroNkw==}
hasBin: true
dependencies:
commander: 8.3.0
dev: false
/kind-of/6.0.3: /kind-of/6.0.3:
resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}

@ -1,3 +1,4 @@
import 'katex/dist/katex.min.css'
import '@/styles/lib/tailwind.css' import '@/styles/lib/tailwind.css'
import '@/styles/lib/highlight.less' import '@/styles/lib/highlight.less'
import '@/styles/lib/github-markdown.less' import '@/styles/lib/github-markdown.less'

@ -1,5 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed, ref } from 'vue' import { computed, ref } from 'vue'
import katex from 'katex'
import { marked } from 'marked' import { marked } from 'marked'
import hljs from 'highlight.js' import hljs from 'highlight.js'
import { useBasicLayout } from '@/hooks/useBasicLayout' import { useBasicLayout } from '@/hooks/useBasicLayout'
@ -41,6 +42,54 @@ marked.setOptions({
}, },
}) })
const katexOptions = {
throwOnError: false,
}
const katexInline = {
name: 'katexInline',
level: 'inline',
start(src: string) {
return src.indexOf('$')
},
tokenizer(src: string) {
const match = src.match(/^\$+([^$\n]+?)\$+/)
if (match) {
return {
type: 'katexInline',
raw: match[0],
text: match[1].trim(),
}
}
},
renderer(token: marked.Tokens.Generic) {
return katex.renderToString(token.text, katexOptions)
},
}
const katexBlock = {
name: 'katexBlock',
level: 'block',
start(src: string) {
return src.indexOf('\n$$')
},
tokenizer(src: string) {
const match = src.match(/^\$\$+\n([^$]+?)\n\$\$+\n/)
if (match) {
return {
type: 'katexBlock',
raw: match[0],
text: match[1].trim(),
}
}
},
renderer(token: marked.Tokens.Generic) {
return `<p>${katex.renderToString(token.text, katexOptions)}</p>`
},
}
marked.use({ extensions: [katexInline, katexBlock] })
const wrapClass = computed(() => { const wrapClass = computed(() => {
return [ return [
'text-wrap', 'text-wrap',

Loading…
Cancel
Save