Bladeren bron

refac/fix: table markdown input

Timothy Jaeryang Baek 2 maanden geleden
bovenliggende
commit
88ff0b952e
3 gewijzigde bestanden met toevoegingen van 505 en 9 verwijderingen
  1. 460 8
      package-lock.json
  2. 1 0
      package.json
  3. 44 1
      src/lib/components/common/RichTextInput.svelte

+ 460 - 8
package-lock.json

@@ -15,6 +15,7 @@
 				"@codemirror/theme-one-dark": "^6.1.2",
 				"@floating-ui/dom": "^1.7.2",
 				"@huggingface/transformers": "^3.0.0",
+				"@joplin/turndown-plugin-gfm": "^1.0.62",
 				"@mediapipe/tasks-vision": "^0.10.17",
 				"@pyscript/core": "^0.4.32",
 				"@sveltejs/adapter-node": "^2.0.0",
@@ -183,6 +184,22 @@
 				"url": "https://github.com/sponsors/antfu"
 			}
 		},
+		"node_modules/@asamuzakjp/css-color": {
+			"version": "3.2.0",
+			"resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz",
+			"integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==",
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"peer": true,
+			"dependencies": {
+				"@csstools/css-calc": "^2.1.3",
+				"@csstools/css-color-parser": "^3.0.9",
+				"@csstools/css-parser-algorithms": "^3.0.4",
+				"@csstools/css-tokenizer": "^3.0.3",
+				"lru-cache": "^10.4.3"
+			}
+		},
 		"node_modules/@azure/msal-browser": {
 			"version": "4.5.0",
 			"resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-4.5.0.tgz",
@@ -645,6 +662,131 @@
 				"node": ">=0.1.90"
 			}
 		},
+		"node_modules/@csstools/color-helpers": {
+			"version": "5.0.2",
+			"resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.2.tgz",
+			"integrity": "sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==",
+			"dev": true,
+			"funding": [
+				{
+					"type": "github",
+					"url": "https://github.com/sponsors/csstools"
+				},
+				{
+					"type": "opencollective",
+					"url": "https://opencollective.com/csstools"
+				}
+			],
+			"license": "MIT-0",
+			"optional": true,
+			"peer": true,
+			"engines": {
+				"node": ">=18"
+			}
+		},
+		"node_modules/@csstools/css-calc": {
+			"version": "2.1.4",
+			"resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz",
+			"integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==",
+			"dev": true,
+			"funding": [
+				{
+					"type": "github",
+					"url": "https://github.com/sponsors/csstools"
+				},
+				{
+					"type": "opencollective",
+					"url": "https://opencollective.com/csstools"
+				}
+			],
+			"license": "MIT",
+			"optional": true,
+			"peer": true,
+			"engines": {
+				"node": ">=18"
+			},
+			"peerDependencies": {
+				"@csstools/css-parser-algorithms": "^3.0.5",
+				"@csstools/css-tokenizer": "^3.0.4"
+			}
+		},
+		"node_modules/@csstools/css-color-parser": {
+			"version": "3.0.10",
+			"resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.10.tgz",
+			"integrity": "sha512-TiJ5Ajr6WRd1r8HSiwJvZBiJOqtH86aHpUjq5aEKWHiII2Qfjqd/HCWKPOW8EP4vcspXbHnXrwIDlu5savQipg==",
+			"dev": true,
+			"funding": [
+				{
+					"type": "github",
+					"url": "https://github.com/sponsors/csstools"
+				},
+				{
+					"type": "opencollective",
+					"url": "https://opencollective.com/csstools"
+				}
+			],
+			"license": "MIT",
+			"optional": true,
+			"peer": true,
+			"dependencies": {
+				"@csstools/color-helpers": "^5.0.2",
+				"@csstools/css-calc": "^2.1.4"
+			},
+			"engines": {
+				"node": ">=18"
+			},
+			"peerDependencies": {
+				"@csstools/css-parser-algorithms": "^3.0.5",
+				"@csstools/css-tokenizer": "^3.0.4"
+			}
+		},
+		"node_modules/@csstools/css-parser-algorithms": {
+			"version": "3.0.5",
+			"resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz",
+			"integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==",
+			"dev": true,
+			"funding": [
+				{
+					"type": "github",
+					"url": "https://github.com/sponsors/csstools"
+				},
+				{
+					"type": "opencollective",
+					"url": "https://opencollective.com/csstools"
+				}
+			],
+			"license": "MIT",
+			"optional": true,
+			"peer": true,
+			"engines": {
+				"node": ">=18"
+			},
+			"peerDependencies": {
+				"@csstools/css-tokenizer": "^3.0.4"
+			}
+		},
+		"node_modules/@csstools/css-tokenizer": {
+			"version": "3.0.4",
+			"resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz",
+			"integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==",
+			"dev": true,
+			"funding": [
+				{
+					"type": "github",
+					"url": "https://github.com/sponsors/csstools"
+				},
+				{
+					"type": "opencollective",
+					"url": "https://opencollective.com/csstools"
+				}
+			],
+			"license": "MIT",
+			"optional": true,
+			"peer": true,
+			"engines": {
+				"node": ">=18"
+			}
+		},
 		"node_modules/@cypress/request": {
 			"version": "3.0.5",
 			"resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.5.tgz",
@@ -1841,6 +1983,12 @@
 				"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
 			}
 		},
+		"node_modules/@joplin/turndown-plugin-gfm": {
+			"version": "1.0.62",
+			"resolved": "https://registry.npmjs.org/@joplin/turndown-plugin-gfm/-/turndown-plugin-gfm-1.0.62.tgz",
+			"integrity": "sha512-Ts7cZ0Y9rIRgNkPtpXYB3BVjjSP2eeWzrPnQvJgNTC+FpopSjoaYjLQvPcEj1d6JcTMegnYoZK98/WJhm02Uaw==",
+			"license": "MIT"
+		},
 		"node_modules/@jridgewell/gen-mapping": {
 			"version": "0.3.5",
 			"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
@@ -4440,6 +4588,18 @@
 				"node": ">=0.4.0"
 			}
 		},
+		"node_modules/agent-base": {
+			"version": "7.1.4",
+			"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
+			"integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"peer": true,
+			"engines": {
+				"node": ">= 14"
+			}
+		},
 		"node_modules/aggregate-error": {
 			"version": "3.1.0",
 			"resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
@@ -5680,6 +5840,31 @@
 				"node": ">=4"
 			}
 		},
+		"node_modules/cssstyle": {
+			"version": "4.6.0",
+			"resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz",
+			"integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==",
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"peer": true,
+			"dependencies": {
+				"@asamuzakjp/css-color": "^3.2.0",
+				"rrweb-cssom": "^0.8.0"
+			},
+			"engines": {
+				"node": ">=18"
+			}
+		},
+		"node_modules/cssstyle/node_modules/rrweb-cssom": {
+			"version": "0.8.0",
+			"resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz",
+			"integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==",
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"peer": true
+		},
 		"node_modules/cypress": {
 			"version": "13.15.0",
 			"resolved": "https://registry.npmjs.org/cypress/-/cypress-13.15.0.tgz",
@@ -6305,6 +6490,22 @@
 				"node": ">=0.10"
 			}
 		},
+		"node_modules/data-urls": {
+			"version": "5.0.0",
+			"resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz",
+			"integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==",
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"peer": true,
+			"dependencies": {
+				"whatwg-mimetype": "^4.0.0",
+				"whatwg-url": "^14.0.0"
+			},
+			"engines": {
+				"node": ">=18"
+			}
+		},
 		"node_modules/dayjs": {
 			"version": "1.11.13",
 			"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz",
@@ -6327,6 +6528,15 @@
 				}
 			}
 		},
+		"node_modules/decimal.js": {
+			"version": "10.6.0",
+			"resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz",
+			"integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==",
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"peer": true
+		},
 		"node_modules/deep-eql": {
 			"version": "4.1.4",
 			"resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz",
@@ -7718,6 +7928,21 @@
 				"node": ">=12.0.0"
 			}
 		},
+		"node_modules/html-encoding-sniffer": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz",
+			"integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==",
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"peer": true,
+			"dependencies": {
+				"whatwg-encoding": "^3.1.1"
+			},
+			"engines": {
+				"node": ">=18"
+			}
+		},
 		"node_modules/html-entities": {
 			"version": "2.5.3",
 			"resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.3.tgz",
@@ -7786,6 +8011,22 @@
 				"entities": "^4.5.0"
 			}
 		},
+		"node_modules/http-proxy-agent": {
+			"version": "7.0.2",
+			"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
+			"integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"peer": true,
+			"dependencies": {
+				"agent-base": "^7.1.0",
+				"debug": "^4.3.4"
+			},
+			"engines": {
+				"node": ">= 14"
+			}
+		},
 		"node_modules/http-signature": {
 			"version": "1.4.0",
 			"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.4.0.tgz",
@@ -7800,6 +8041,22 @@
 				"node": ">=0.10"
 			}
 		},
+		"node_modules/https-proxy-agent": {
+			"version": "7.0.6",
+			"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
+			"integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"peer": true,
+			"dependencies": {
+				"agent-base": "^7.1.2",
+				"debug": "4"
+			},
+			"engines": {
+				"node": ">= 14"
+			}
+		},
 		"node_modules/human-signals": {
 			"version": "1.1.1",
 			"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
@@ -8147,6 +8404,15 @@
 				"url": "https://github.com/sponsors/sindresorhus"
 			}
 		},
+		"node_modules/is-potential-custom-element-name": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
+			"integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"peer": true
+		},
 		"node_modules/is-reference": {
 			"version": "1.2.1",
 			"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz",
@@ -8250,6 +8516,73 @@
 			"integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==",
 			"dev": true
 		},
+		"node_modules/jsdom": {
+			"version": "24.1.1",
+			"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.1.1.tgz",
+			"integrity": "sha512-5O1wWV99Jhq4DV7rCLIoZ/UIhyQeDR7wHVyZAHAshbrvZsLs+Xzz7gtwnlJTJDjleiTKh54F4dXrX70vJQTyJQ==",
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"peer": true,
+			"dependencies": {
+				"cssstyle": "^4.0.1",
+				"data-urls": "^5.0.0",
+				"decimal.js": "^10.4.3",
+				"form-data": "^4.0.0",
+				"html-encoding-sniffer": "^4.0.0",
+				"http-proxy-agent": "^7.0.2",
+				"https-proxy-agent": "^7.0.5",
+				"is-potential-custom-element-name": "^1.0.1",
+				"nwsapi": "^2.2.12",
+				"parse5": "^7.1.2",
+				"rrweb-cssom": "^0.7.1",
+				"saxes": "^6.0.0",
+				"symbol-tree": "^3.2.4",
+				"tough-cookie": "^4.1.4",
+				"w3c-xmlserializer": "^5.0.0",
+				"webidl-conversions": "^7.0.0",
+				"whatwg-encoding": "^3.1.1",
+				"whatwg-mimetype": "^4.0.0",
+				"whatwg-url": "^14.0.0",
+				"ws": "^8.18.0",
+				"xml-name-validator": "^5.0.0"
+			},
+			"engines": {
+				"node": ">=18"
+			},
+			"peerDependencies": {
+				"canvas": "^2.11.2"
+			},
+			"peerDependenciesMeta": {
+				"canvas": {
+					"optional": true
+				}
+			}
+		},
+		"node_modules/jsdom/node_modules/ws": {
+			"version": "8.18.3",
+			"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
+			"integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"peer": true,
+			"engines": {
+				"node": ">=10.0.0"
+			},
+			"peerDependencies": {
+				"bufferutil": "^4.0.1",
+				"utf-8-validate": ">=5.0.2"
+			},
+			"peerDependenciesMeta": {
+				"bufferutil": {
+					"optional": true
+				},
+				"utf-8-validate": {
+					"optional": true
+				}
+			}
+		},
 		"node_modules/json-buffer": {
 			"version": "3.0.1",
 			"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
@@ -9001,6 +9334,12 @@
 				"url": "https://github.com/sponsors/wooorm"
 			}
 		},
+		"node_modules/lru-cache": {
+			"version": "10.4.3",
+			"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+			"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+			"license": "ISC"
+		},
 		"node_modules/magic-string": {
 			"version": "0.30.11",
 			"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz",
@@ -9440,6 +9779,15 @@
 				"url": "https://github.com/fb55/nth-check?sponsor=1"
 			}
 		},
+		"node_modules/nwsapi": {
+			"version": "2.2.21",
+			"resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.21.tgz",
+			"integrity": "sha512-o6nIY3qwiSXl7/LuOU0Dmuctd34Yay0yeuZRLFmDPrrdHpXKFndPj3hM+YEPVHYC5fx2otBx4Ilc/gyYSAUaIA==",
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"peer": true
+		},
 		"node_modules/object-assign": {
 			"version": "4.1.1",
 			"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -9745,14 +10093,6 @@
 				"url": "https://github.com/sponsors/isaacs"
 			}
 		},
-		"node_modules/path-scurry/node_modules/lru-cache": {
-			"version": "10.2.0",
-			"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz",
-			"integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==",
-			"engines": {
-				"node": "14 || >=16.14"
-			}
-		},
 		"node_modules/pathe": {
 			"version": "1.1.2",
 			"resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz",
@@ -10834,6 +11174,15 @@
 				"points-on-path": "^0.2.1"
 			}
 		},
+		"node_modules/rrweb-cssom": {
+			"version": "0.7.1",
+			"resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz",
+			"integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==",
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"peer": true
+		},
 		"node_modules/rsvp": {
 			"version": "4.8.5",
 			"resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz",
@@ -11349,6 +11698,21 @@
 				"url": "https://github.com/chalk/supports-color?sponsor=1"
 			}
 		},
+		"node_modules/saxes": {
+			"version": "6.0.0",
+			"resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz",
+			"integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==",
+			"dev": true,
+			"license": "ISC",
+			"optional": true,
+			"peer": true,
+			"dependencies": {
+				"xmlchars": "^2.2.0"
+			},
+			"engines": {
+				"node": ">=v12.22.7"
+			}
+		},
 		"node_modules/semver": {
 			"version": "7.6.3",
 			"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
@@ -12019,6 +12383,15 @@
 				"node": ">=12.0.0"
 			}
 		},
+		"node_modules/symbol-tree": {
+			"version": "3.2.4",
+			"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
+			"integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"peer": true
+		},
 		"node_modules/symlink-or-copy": {
 			"version": "1.3.1",
 			"resolved": "https://registry.npmjs.org/symlink-or-copy/-/symlink-or-copy-1.3.1.tgz",
@@ -12260,6 +12633,21 @@
 				"node": ">= 4.0.0"
 			}
 		},
+		"node_modules/tr46": {
+			"version": "5.1.1",
+			"resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz",
+			"integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==",
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"peer": true,
+			"dependencies": {
+				"punycode": "^2.3.1"
+			},
+			"engines": {
+				"node": ">=18"
+			}
+		},
 		"node_modules/ts-api-utils": {
 			"version": "2.1.0",
 			"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
@@ -13317,6 +13705,21 @@
 			"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
 			"integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ=="
 		},
+		"node_modules/w3c-xmlserializer": {
+			"version": "5.0.0",
+			"resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
+			"integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==",
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"peer": true,
+			"dependencies": {
+				"xml-name-validator": "^5.0.0"
+			},
+			"engines": {
+				"node": ">=18"
+			}
+		},
 		"node_modules/walk-sync": {
 			"version": "2.2.0",
 			"resolved": "https://registry.npmjs.org/walk-sync/-/walk-sync-2.2.0.tgz",
@@ -13354,6 +13757,18 @@
 				"node": "*"
 			}
 		},
+		"node_modules/webidl-conversions": {
+			"version": "7.0.0",
+			"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
+			"integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
+			"dev": true,
+			"license": "BSD-2-Clause",
+			"optional": true,
+			"peer": true,
+			"engines": {
+				"node": ">=12"
+			}
+		},
 		"node_modules/whatwg-encoding": {
 			"version": "3.1.1",
 			"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
@@ -13377,6 +13792,22 @@
 				"node": ">=18"
 			}
 		},
+		"node_modules/whatwg-url": {
+			"version": "14.2.0",
+			"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz",
+			"integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==",
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"peer": true,
+			"dependencies": {
+				"tr46": "^5.1.0",
+				"webidl-conversions": "^7.0.0"
+			},
+			"engines": {
+				"node": ">=18"
+			}
+		},
 		"node_modules/wheel": {
 			"version": "1.0.0",
 			"resolved": "https://registry.npmjs.org/wheel/-/wheel-1.0.0.tgz",
@@ -13524,6 +13955,27 @@
 				}
 			}
 		},
+		"node_modules/xml-name-validator": {
+			"version": "5.0.0",
+			"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz",
+			"integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==",
+			"dev": true,
+			"license": "Apache-2.0",
+			"optional": true,
+			"peer": true,
+			"engines": {
+				"node": ">=18"
+			}
+		},
+		"node_modules/xmlchars": {
+			"version": "2.2.0",
+			"resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
+			"integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"peer": true
+		},
 		"node_modules/xmlhttprequest-ssl": {
 			"version": "2.0.0",
 			"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz",

+ 1 - 0
package.json

@@ -59,6 +59,7 @@
 		"@codemirror/theme-one-dark": "^6.1.2",
 		"@floating-ui/dom": "^1.7.2",
 		"@huggingface/transformers": "^3.0.0",
+		"@joplin/turndown-plugin-gfm": "^1.0.62",
 		"@mediapipe/tasks-vision": "^0.10.17",
 		"@pyscript/core": "^0.4.32",
 		"@sveltejs/adapter-node": "^2.0.0",

+ 44 - 1
src/lib/components/common/RichTextInput.svelte

@@ -27,15 +27,58 @@
 	});
 
 	import TurndownService from 'turndown';
-	import { gfm } from 'turndown-plugin-gfm';
+	import { gfm } from '@joplin/turndown-plugin-gfm';
 	const turndownService = new TurndownService({
 		codeBlockStyle: 'fenced',
 		headingStyle: 'atx'
 	});
 	turndownService.escape = (string) => string;
+
 	// Use turndown-plugin-gfm for proper GFM table support
 	turndownService.use(gfm);
 
+	// Add custom table header rule before using GFM plugin
+	turndownService.addRule('tableHeaders', {
+		filter: 'th',
+		replacement: function (content, node) {
+			return content;
+		}
+	});
+
+	// Add custom table rule to handle headers properly
+	turndownService.addRule('tables', {
+		filter: 'table',
+		replacement: function (content, node) {
+			// Extract rows
+			const rows = Array.from(node.querySelectorAll('tr'));
+			if (rows.length === 0) return content;
+
+			let markdown = '\n';
+
+			rows.forEach((row, rowIndex) => {
+				const cells = Array.from(row.querySelectorAll('th, td'));
+				const cellContents = cells.map((cell) => {
+					// Get the text content and clean it up
+					let cellContent = turndownService.turndown(cell.innerHTML).trim();
+					// Remove extra paragraph tags that might be added
+					cellContent = cellContent.replace(/^\n+|\n+$/g, '');
+					return cellContent;
+				});
+
+				// Add the row
+				markdown += '| ' + cellContents.join(' | ') + ' |\n';
+
+				// Add separator after first row (which should be headers)
+				if (rowIndex === 0) {
+					const separator = cells.map(() => '---').join(' | ');
+					markdown += '| ' + separator + ' |\n';
+				}
+			});
+
+			return markdown + '\n';
+		}
+	});
+
 	turndownService.addRule('taskListItems', {
 		filter: (node) =>
 			node.nodeName === 'LI' &&