Переглянути джерело

feat: message latex support

Timothy J. Baek 1 рік тому
батько
коміт
a1544dbc97
4 змінених файлів з 75 додано та 3 видалено
  1. 39 0
      package-lock.json
  2. 1 0
      package.json
  3. 4 0
      src/app.css
  4. 31 3
      src/routes/+page.svelte

+ 39 - 0
package-lock.json

@@ -13,6 +13,7 @@
 				"highlight.js": "^11.9.0",
 				"http-server": "^14.1.1",
 				"idb": "^7.1.1",
+				"katex": "^0.16.9",
 				"marked": "^9.1.0",
 				"svelte-french-toast": "^1.2.0",
 				"uuid": "^9.0.1"
@@ -2556,6 +2557,29 @@
 			"integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
 			"dev": true
 		},
+		"node_modules/katex": {
+			"version": "0.16.9",
+			"resolved": "https://registry.npmjs.org/katex/-/katex-0.16.9.tgz",
+			"integrity": "sha512-fsSYjWS0EEOwvy81j3vRA8TEAhQhKiqO+FQaKWp0m39qwOzHVBgAUBIXWj1pB+O2W3fIpNa6Y9KSKCVbfPhyAQ==",
+			"funding": [
+				"https://opencollective.com/katex",
+				"https://github.com/sponsors/katex"
+			],
+			"dependencies": {
+				"commander": "^8.3.0"
+			},
+			"bin": {
+				"katex": "cli.js"
+			}
+		},
+		"node_modules/katex/node_modules/commander": {
+			"version": "8.3.0",
+			"resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
+			"integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
+			"engines": {
+				"node": ">= 12"
+			}
+		},
 		"node_modules/keyv": {
 			"version": "4.5.4",
 			"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
@@ -5913,6 +5937,21 @@
 			"integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
 			"dev": true
 		},
+		"katex": {
+			"version": "0.16.9",
+			"resolved": "https://registry.npmjs.org/katex/-/katex-0.16.9.tgz",
+			"integrity": "sha512-fsSYjWS0EEOwvy81j3vRA8TEAhQhKiqO+FQaKWp0m39qwOzHVBgAUBIXWj1pB+O2W3fIpNa6Y9KSKCVbfPhyAQ==",
+			"requires": {
+				"commander": "^8.3.0"
+			},
+			"dependencies": {
+				"commander": {
+					"version": "8.3.0",
+					"resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
+					"integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww=="
+				}
+			}
+		},
 		"keyv": {
 			"version": "4.5.4",
 			"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",

+ 1 - 0
package.json

@@ -44,6 +44,7 @@
 		"highlight.js": "^11.9.0",
 		"http-server": "^14.1.1",
 		"idb": "^7.1.1",
+		"katex": "^0.16.9",
 		"marked": "^9.1.0",
 		"svelte-french-toast": "^1.2.0",
 		"uuid": "^9.0.1"

+ 4 - 0
src/app.css

@@ -9,6 +9,10 @@ html {
 	word-break: break-word;
 }
 
+math {
+	margin-top: 1rem;
+}
+
 .hljs {
 	@apply rounded-lg;
 }

+ 31 - 3
src/routes/+page.svelte

@@ -1,5 +1,4 @@
 <script lang="ts">
-	import toast from 'svelte-french-toast';
 	import { openDB, deleteDB } from 'idb';
 	import { v4 as uuidv4 } from 'uuid';
 	import { marked } from 'marked';
@@ -7,9 +6,12 @@
 	const { saveAs } = fileSaver;
 	import hljs from 'highlight.js';
 	import 'highlight.js/styles/github-dark.min.css';
+	import katex from 'katex';
+	import auto_render from 'katex/dist/contrib/auto-render.mjs';
+	import toast from 'svelte-french-toast';
+
 	import { API_BASE_URL as BUILD_TIME_API_BASE_URL } from '$lib/constants';
 	import { onMount, tick } from 'svelte';
-
 	import Navbar from '$lib/components/layout/Navbar.svelte';
 	import SettingsModal from '$lib/components/chat/SettingsModal.svelte';
 
@@ -151,6 +153,27 @@
 		}
 	};
 
+	const renderLatex = () => {
+		let chatMessageElements = document.getElementsByClassName('chat-assistant');
+		// let lastChatMessageElement = chatMessageElements[chatMessageElements.length - 1];
+
+		for (const element of chatMessageElements) {
+			auto_render(element, {
+				// customised options
+				// • auto-render specific keys, e.g.:
+				delimiters: [
+					{ left: '$$', right: '$$', display: true },
+					{ left: '$', right: '$', display: false },
+					{ left: '\\(', right: '\\)', display: false },
+					{ left: '\\[', right: '\\]', display: true }
+				],
+				// • rendering keys, e.g.:
+				throwOnError: false,
+				output: 'mathml'
+			});
+		}
+	};
+
 	//////////////////////////
 	// Web functions
 	//////////////////////////
@@ -222,6 +245,7 @@
 			await tick();
 			hljs.highlightAll();
 			createCopyCodeBlockButton();
+			renderLatex();
 		}
 	};
 
@@ -457,6 +481,7 @@
 								messages = messages;
 								hljs.highlightAll();
 								createCopyCodeBlockButton();
+								renderLatex();
 							}
 						}
 					}
@@ -555,6 +580,7 @@
 								messages = messages;
 								hljs.highlightAll();
 								createCopyCodeBlockButton();
+								renderLatex();
 							}
 						}
 					}
@@ -742,7 +768,7 @@
 											</div>
 										{:else}
 											<div
-												class="prose w-full max-w-full prose-invert prose-headings:my-0 prose-p:my-0 prose-pre:my-0 prose-table:my-0 prose-blockquote:my-0 prose-img:my-0 prose-ul:-my-2 prose-ol:-my-2 prose-li:-my-2 whitespace-pre-line"
+												class="prose chat-{message.role} w-full max-w-full prose-invert prose-headings:my-0 prose-p:my-0 prose-pre:my-0 prose-table:my-0 prose-blockquote:my-0 prose-img:my-0 prose-ul:-my-2 prose-ol:-my-2 prose-li:-my-2 whitespace-pre-line"
 											>
 												{#if message.role == 'user'}
 													{#if message?.edit === true}
@@ -1091,6 +1117,8 @@
 			</div>
 		</div>
 
+		<div class=" hidden katex" />
+
 		<!-- <main class="w-full flex justify-center">
 			<div class="max-w-lg w-screen p-5" />
 		</main> -->