From 4dc523acfd9a18c99bdcedb631390436228c616e Mon Sep 17 00:00:00 2001 From: Eamonn de Leastar Date: Tue, 10 Dec 2024 16:38:56 +0000 Subject: [PATCH 1/8] frame around code blocks in dark mode --- src/app.postcss | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/app.postcss b/src/app.postcss index f3fef8333..f0c5b67f3 100644 --- a/src/app.postcss +++ b/src/app.postcss @@ -7,3 +7,8 @@ html, body { @apply h-full overflow-hidden; } + +code, +pre { + @apply rounded-md border dark:border-primary-500; +} From ff20cf66e256a6f09fa4dd744d336e3ea9a74069 Mon Sep 17 00:00:00 2001 From: Eamonn de Leastar Date: Tue, 10 Dec 2024 16:39:17 +0000 Subject: [PATCH 2/8] include shiki libaries --- package-lock.json | 567 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 + 2 files changed, 569 insertions(+) diff --git a/package-lock.json b/package-lock.json index a8a5f288a..8a7f666bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,11 +7,15 @@ "": { "name": "tutors", "version": "0.0.1", + "dependencies": { + "asciimath": "^0.0.0" + }, "devDependencies": { "@auth/core": "^0.37.4", "@auth/sveltekit": "^1.7.4", "@iconify/svelte": "^4.0.2", "@iktakahiro/markdown-it-katex": "^4.0.1", + "@shikijs/markdown-it": "^1.24.1", "@skeletonlabs/skeleton": "^3.0.0-next.9", "@skeletonlabs/skeleton-svelte": "^1.0.0-next.14", "@supabase/supabase-js": "^2.46.1", @@ -45,6 +49,7 @@ "prettier": "^3.4.0", "prettier-plugin-svelte": "^3.3.2", "prettier-plugin-tailwindcss": "^0.6.9", + "shiki": "^1.24.1", "svelte": "^5.2.8", "svelte-check": "^4.1.0", "tailwindcss": "^3.4.15", @@ -1179,6 +1184,73 @@ "win32" ] }, + "node_modules/@shikijs/core": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.24.1.tgz", + "integrity": "sha512-3q/9oarMVcLqJ+NQOdKL40dJVq/UKCsiWXz3QRQPBglHqa8dDJ0p6TuMuk2gHphy5FZcvFtg4UHBgpW0JtZ8+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/engine-javascript": "1.24.1", + "@shikijs/engine-oniguruma": "1.24.1", + "@shikijs/types": "1.24.1", + "@shikijs/vscode-textmate": "^9.3.0", + "@types/hast": "^3.0.4", + "hast-util-to-html": "^9.0.3" + } + }, + "node_modules/@shikijs/engine-javascript": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-1.24.1.tgz", + "integrity": "sha512-lNgUSHYDYaQ6daj4lJJqcY2Ru9LgHwpFoposJkRVRPh21Yg4kaPFRhzaWoSg3PliwcDOpDuMy3xsmQaJp201Fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "1.24.1", + "@shikijs/vscode-textmate": "^9.3.0", + "oniguruma-to-es": "0.7.0" + } + }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-1.24.1.tgz", + "integrity": "sha512-KdrTIBIONWd+Xs61eh8HdIpfigtrseat9dpARvaOe2x0g/FNTbwbkGr3y92VSOVD1XotzEskh3v/nCzyWjkf7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "1.24.1", + "@shikijs/vscode-textmate": "^9.3.0" + } + }, + "node_modules/@shikijs/markdown-it": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@shikijs/markdown-it/-/markdown-it-1.24.1.tgz", + "integrity": "sha512-on33IGJwwmKNQOdhRKP0fBq2jymiCBGRA4tJf5bR708+fzUAW7W0qA+kUiVyU/FYUHv+fttQpx7gTjsh9L10wQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "markdown-it": "^14.1.0", + "shiki": "1.24.1" + } + }, + "node_modules/@shikijs/types": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-1.24.1.tgz", + "integrity": "sha512-ZwZFbShFY/APfKNt3s9Gv8rhTm29GodSKsOW66X6N+HGsZuaHalE1VUEX4fv93UXHTZTLjb3uxn63F96RhGfXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^9.3.0", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-9.3.0.tgz", + "integrity": "sha512-jn7/7ky30idSkd/O5yDBfAnVt+JJpepofP/POZ1iMOxK59cOfqIgg/Dj0eFsjOTMw+4ycJN0uhZH/Eb0bs/EUA==", + "dev": true, + "license": "MIT" + }, "node_modules/@skeletonlabs/skeleton": { "version": "3.0.0-next.9", "resolved": "https://registry.npmjs.org/@skeletonlabs/skeleton/-/skeleton-3.0.0-next.9.tgz", @@ -1470,6 +1542,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -1497,6 +1579,16 @@ "@types/mdurl": "^2" } }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/mdurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", @@ -1522,6 +1614,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/ws": { "version": "8.5.13", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz", @@ -1756,6 +1855,13 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.1.tgz", + "integrity": "sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==", + "dev": true, + "license": "ISC" + }, "node_modules/@zag-js/accordion": { "version": "0.75.0", "resolved": "https://registry.npmjs.org/@zag-js/accordion/-/accordion-0.75.0.tgz", @@ -2397,6 +2503,11 @@ "node": ">= 0.4" } }, + "node_modules/asciimath": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/asciimath/-/asciimath-0.0.0.tgz", + "integrity": "sha512-Gud5mvkqRyZsRyR3LvSk+kjIiChMSJppJZlpd5swSe1x2liT7UWNvELtqQCZgYCgJ0d+S8UqEWiUFkFF3heXnw==" + }, "node_modules/autoprefixer": { "version": "10.4.20", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", @@ -2641,6 +2752,17 @@ "node": "^18.12.0 || >= 20.9.0" } }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -2658,6 +2780,28 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/chokidar": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", @@ -2702,6 +2846,17 @@ "dev": true, "license": "MIT" }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/commander": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", @@ -2824,6 +2979,16 @@ "node": ">=0.10.0" } }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/detect-libc": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", @@ -2842,6 +3007,20 @@ "dev": true, "license": "MIT" }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", @@ -2877,6 +3056,13 @@ "dev": true, "license": "MIT" }, + "node_modules/emoji-regex-xs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex-xs/-/emoji-regex-xs-1.0.0.tgz", + "integrity": "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==", + "dev": true, + "license": "MIT" + }, "node_modules/end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -3583,6 +3769,44 @@ "node": ">= 0.4" } }, + "node_modules/hast-util-to-html": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.3.tgz", + "integrity": "sha512-M17uBDzMJ9RPCqLMO92gNNUDuBSq10a25SDBI08iCCxmorf4Yy6sYHK57n9WAbRAAaU+DuR4W6GN9K4DFZesYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/highlight.js": { "version": "11.10.0", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.10.0.tgz", @@ -3593,6 +3817,17 @@ "node": ">=12.0.0" } }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -4085,6 +4320,28 @@ "node": ">6.4.0" } }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", + "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", @@ -4102,6 +4359,100 @@ "node": ">= 8" } }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.1.tgz", + "integrity": "sha512-534m2WhVTddrcKVepwmVEVnUAmtrx9bfIjNoQHRqfnvdaHQiFytEhJoTgpWJvDEXCO5gLTQh3wYC1PgOJA4NSQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", @@ -4358,6 +4709,18 @@ "wrappy": "1" } }, + "node_modules/oniguruma-to-es": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-0.7.0.tgz", + "integrity": "sha512-HRaRh09cE0gRS3+wi2zxekB+I5L8C/gN60S+vb11eADHUaB/q4u8wGGOX3GvwvitG8ixaeycZfeoyruKQzUgNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex-xs": "^1.0.0", + "regex": "^5.0.2", + "regex-recursion": "^4.3.0" + } + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -4974,6 +5337,17 @@ } } }, + "node_modules/property-information": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", + "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/proxy-compare": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/proxy-compare/-/proxy-compare-3.0.0.tgz", @@ -5102,6 +5476,33 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/regex": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/regex/-/regex-5.0.2.tgz", + "integrity": "sha512-/pczGbKIQgfTMRV0XjABvc5RzLqQmwqxLHdQao2RTXPk+pmTXB2P0IaUHYdYyk412YLwUIkaeMd5T+RzVgTqnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-recursion": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-4.3.0.tgz", + "integrity": "sha512-5LcLnizwjcQ2ALfOj95MjcatxyqF5RPySx9yT+PaXu3Gox2vyAtLDjHB8NTJLtMGkvyau6nI3CfpwFCjPUIs/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-utilities": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz", + "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==", + "dev": true, + "license": "MIT" + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -5281,6 +5682,21 @@ "node": ">=8" } }, + "node_modules/shiki": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.24.1.tgz", + "integrity": "sha512-/qByWMg05+POb63c/OvnrU17FcCUa34WU4F6FCrd/mjDPEDPl8YUNRkRMbo8l3iYMLydfCgxi1r37JFoSw8A4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/core": "1.24.1", + "@shikijs/engine-javascript": "1.24.1", + "@shikijs/engine-oniguruma": "1.24.1", + "@shikijs/types": "1.24.1", + "@shikijs/vscode-textmate": "^9.3.0", + "@types/hast": "^3.0.4" + } + }, "node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", @@ -5354,6 +5770,17 @@ "node": ">=0.10.0" } }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -5429,6 +5856,21 @@ "node": ">=8" } }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "dev": true, + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/strip-ansi": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", @@ -5937,6 +6379,17 @@ "dev": true, "license": "MIT" }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/ts-api-utils": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.2.tgz", @@ -6046,6 +6499,79 @@ "dev": true, "license": "MIT" }, + "node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/update-browserslist-db": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", @@ -6094,6 +6620,36 @@ "dev": true, "license": "MIT" }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/vite": { "version": "5.4.11", "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", @@ -6371,6 +6927,17 @@ "integrity": "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==", "dev": true, "license": "MIT" + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } } } } diff --git a/package.json b/package.json index c2b9dcc7c..6af1cdebb 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "@auth/sveltekit": "^1.7.4", "@iconify/svelte": "^4.0.2", "@iktakahiro/markdown-it-katex": "^4.0.1", + "@shikijs/markdown-it": "^1.24.1", "@skeletonlabs/skeleton": "^3.0.0-next.9", "@skeletonlabs/skeleton-svelte": "^1.0.0-next.14", "@supabase/supabase-js": "^2.46.1", @@ -49,6 +50,7 @@ "prettier": "^3.4.0", "prettier-plugin-svelte": "^3.3.2", "prettier-plugin-tailwindcss": "^0.6.9", + "shiki": "^1.24.1", "svelte": "^5.2.8", "svelte-check": "^4.1.0", "tailwindcss": "^3.4.15", From ac015bbe7b77a8b97ed738b83b841983b264c348 Mon Sep 17 00:00:00 2001 From: Eamonn de Leastar Date: Tue, 10 Dec 2024 19:13:46 +0000 Subject: [PATCH 3/8] first attempt at shiki implementation --- src/lib/runes.ts | 2 + src/lib/services/course.svelte.ts | 20 +++++++++- src/lib/services/models/live-lab.ts | 4 ++ src/lib/services/models/lo-tree.ts | 2 +- ...down-utils.ts => markdown-utils.svelte.ts} | 38 +++++++++++-------- src/lib/services/types.svelte.ts | 1 + .../ui/learning-objects/content/Lab.svelte | 5 ++- .../ui/learning-objects/content/Note.svelte | 2 +- .../navigators/footers/TutorsMessage.svelte | 2 +- src/lib/ui/themes/LayoutMenu.svelte | 20 +++++++++- src/lib/ui/themes/theme-controller.svelte.ts | 22 ++++++++++- src/routes/(auth)/auth/TutorsTerms.svelte | 2 +- .../search/[courseid]/+page.svelte | 6 +-- src/routes/+layout.svelte | 3 ++ 14 files changed, 102 insertions(+), 27 deletions(-) rename src/lib/services/models/{markdown-utils.ts => markdown-utils.svelte.ts} (83%) diff --git a/src/lib/runes.ts b/src/lib/runes.ts index 2b796447e..36854e688 100644 --- a/src/lib/runes.ts +++ b/src/lib/runes.ts @@ -6,6 +6,8 @@ export const transitionKey = rune(""); export const layout = rune("expanded"); export const lightMode = rune("light"); export const currentTheme = rune("tutors"); +export const currentCodeTheme = rune("monokai"); +export const refreshCodeTheme = rune(false); export const currentLo = rune(null); export const currentCourse = rune(null); diff --git a/src/lib/services/course.svelte.ts b/src/lib/services/course.svelte.ts index 275667b11..5a08cefee 100644 --- a/src/lib/services/course.svelte.ts +++ b/src/lib/services/course.svelte.ts @@ -1,8 +1,10 @@ -import { courseUrl, currentCourse, currentLo } from "$lib/runes"; +import { courseUrl, currentCodeTheme, currentCourse, currentLo } from "$lib/runes"; import type { Lo, Course, Lab } from "$lib/services/models/lo-types"; import { decorateCourseTree } from "./models/lo-tree"; import { LiveLab } from "./models/live-lab"; import type { CourseService } from "./types.svelte"; +import { convertLabToHtml } from "./models/markdown-utils.svelte"; +import { themeService } from "$lib/ui/themes/theme-controller.svelte"; export const courseService: CourseService = { courses: new Map(), @@ -14,7 +16,8 @@ export const courseService: CourseService = { let courseUrl = courseId; function isValidURL(url: string) { - const urlPattern = /^(https?:\/\/)?([A-Za-z0-9.-]+\.[A-Za-z]{2,})(:[0-9]+)?(\/[A-Za-z0-9_.-]+)*(\/[A-Za-z0-9_.-]+\?[A-Za-z0-9_=-]+)?(#.*)?$/; + const urlPattern = + /^(https?:\/\/)?([A-Za-z0-9.-]+\.[A-Za-z]{2,})(:[0-9]+)?(\/[A-Za-z0-9_.-]+)*(\/[A-Za-z0-9_.-]+\?[A-Za-z0-9_=-]+)?(#.*)?$/; return urlPattern.test(url); } @@ -75,6 +78,8 @@ export const courseService: CourseService = { let liveLab = this.labs.get(labId); if (!liveLab) { const lab = course.loIndex.get(labId) as Lab; + themeService.initCodeTheme(); + await convertLabToHtml(course, lab, currentCodeTheme.value); liveLab = new LiveLab(course, lab, labId); this.labs.set(labId, liveLab); } @@ -93,6 +98,17 @@ export const courseService: CourseService = { const course = await this.readCourse(courseId, fetchFunction); const lo = course.loIndex.get(loId); if (lo) currentLo.value = lo; + if (lo?.type === "note") { + await convertLabToHtml(course, lo as Lab, currentCodeTheme.value); + } return lo!; + }, + + refreshAllLabs(codeTheme: string) { + for (const liveLab of this.labs.values()) { + convertLabToHtml(liveLab.course, liveLab.lab, codeTheme); + liveLab.convertMdToHtml(); + liveLab.refreshStep(); + } } }; diff --git a/src/lib/services/models/live-lab.ts b/src/lib/services/models/live-lab.ts index 55f67afda..e043aa81b 100644 --- a/src/lib/services/models/live-lab.ts +++ b/src/lib/services/models/live-lab.ts @@ -1,6 +1,7 @@ import type { Lab } from "./lo-types"; import type { Course } from "./lo-types"; import { removeLeadingHashes } from "./lo-utils"; +import { convertLabToHtml } from "./markdown-utils.svelte"; function getKeyIndex(map: Map, targetKey: string) { const keysArray = [...map.keys()]; @@ -51,6 +52,9 @@ export class LiveLab { this.steps = Array.from(this.chaptersHtml.keys()); } + refreshStep() { + this.content = this.chaptersHtml.get(this.currentChapterShortTitle)!; + } refreshNav() { //const number = this.autoNumber ? this.lab.shortTitle + ": " : ""; diff --git a/src/lib/services/models/lo-tree.ts b/src/lib/services/models/lo-tree.ts index b089eefef..521c5cf33 100644 --- a/src/lib/services/models/lo-tree.ts +++ b/src/lib/services/models/lo-tree.ts @@ -1,5 +1,5 @@ import { isCompositeLo, type Course, type Lo, type Composite, type LoType, type Topic } from "./lo-types"; -import { convertLoToHtml } from "./markdown-utils"; +import { convertLoToHtml } from "./markdown-utils.svelte"; import { allVideoLos, crumbs, diff --git a/src/lib/services/models/markdown-utils.ts b/src/lib/services/models/markdown-utils.svelte.ts similarity index 83% rename from src/lib/services/models/markdown-utils.ts rename to src/lib/services/models/markdown-utils.svelte.ts index a5f9ab347..ecd655bd2 100644 --- a/src/lib/services/models/markdown-utils.ts +++ b/src/lib/services/models/markdown-utils.svelte.ts @@ -1,5 +1,4 @@ /* eslint-disable @typescript-eslint/ban-ts-comment */ -import hljs from "highlight.js"; import type { Lab, Lo } from "./lo-types"; // @ts-ignore import MarkdownIt from "markdown-it"; @@ -23,6 +22,19 @@ import footnote from "markdown-it-footnote"; import deflist from "markdown-it-deflist"; import type { Course } from "./lo-types"; +import { bundledLanguages, createHighlighter } from "shiki"; + +let highlighter: any; + +export async function initializeHighlighter() { + highlighter = await createHighlighter({ + themes: ["monokai", "night-owl", "github-dark", "catppuccin-mocha", "solarized-dark", "solarized-light"], + langs: Object.keys(bundledLanguages) + }); +} + +let currentTheme = "monokai"; + const markdownIt: any = new MarkdownIt({ html: true, // Enable HTML tags in source xhtmlOut: false, // Use '/' to close single tags (
). @@ -32,16 +44,7 @@ const markdownIt: any = new MarkdownIt({ typographer: true, quotes: "“”‘’", highlight: function (str: string, lang: string) { - if (lang && hljs.getLanguage(lang)) { - try { - return ( - '
' +
-          hljs.highlight(str, { language: lang, ignoreIllegals: true }).value +
-          "
" - ); - } catch (__) {} - } - return '
' + markdownIt.utils.escapeHtml(str) + "
"; + return highlighter?.codeToHtml(str, { lang, theme: currentTheme }); } }); @@ -103,10 +106,14 @@ function filter(src: string, url: string): string { return filtered; } -export function convertLabToHtml(course: Course, lab: Lab) { +export async function convertLabToHtml(course: Course, lab: Lab, theme: string) { + if (!highlighter) { + await initializeHighlighter(); + } + currentTheme = theme; lab.summary = markdownIt.render(lab.summary); const url = lab.route.replace(`/lab/${course.courseId}`, course.courseUrl); - lab.los.forEach((step) => { + lab?.los?.forEach((step) => { if (course.courseUrl) { step.contentMd = filter(step.contentMd, url); } @@ -116,9 +123,10 @@ export function convertLabToHtml(course: Course, lab: Lab) { }); } -export function convertLoToHtml(course: Course, lo: Lo) { +export async function convertLoToHtml(course: Course, lo: Lo, theme: string) { + currentTheme = theme; if (lo.type === "lab") { - convertLabToHtml(course, lo as Lab); + // convertLabToHtml(course, lo as Lab); } else { if (lo.summary) lo.summary = markdownIt.render(lo.summary); let md = lo.contentMd; diff --git a/src/lib/services/types.svelte.ts b/src/lib/services/types.svelte.ts index befacca34..5362c8225 100644 --- a/src/lib/services/types.svelte.ts +++ b/src/lib/services/types.svelte.ts @@ -68,6 +68,7 @@ export interface CourseService { readLab(courseId: string, labId: string, fetchFunction: typeof fetch): Promise; readWall(courseId: string, type: string, fetchFunction: typeof fetch): Promise; readLo(courseId: string, loId: string, fetchFunction: typeof fetch): Promise; + refreshAllLabs(codeTheme: string): void; } export interface ProfileStore { diff --git a/src/lib/ui/learning-objects/content/Lab.svelte b/src/lib/ui/learning-objects/content/Lab.svelte index e6304b264..a78f81fe3 100644 --- a/src/lib/ui/learning-objects/content/Lab.svelte +++ b/src/lib/ui/learning-objects/content/Lab.svelte @@ -6,6 +6,7 @@ import type { LiveLab } from "$lib/services/models/live-lab"; import { fly } from "svelte/transition"; import { slideFromLeft } from "$lib/ui/themes/animations"; + import { currentCodeTheme, refreshCodeTheme } from "$lib/runes"; interface Props { lab: LiveLab; @@ -80,7 +81,9 @@
- {@html lab.content} + {#key currentCodeTheme.value} + {@html lab.content} + {/key}
diff --git a/src/lib/ui/learning-objects/content/Note.svelte b/src/lib/ui/learning-objects/content/Note.svelte index 19b6bcd2b..9fe098622 100644 --- a/src/lib/ui/learning-objects/content/Note.svelte +++ b/src/lib/ui/learning-objects/content/Note.svelte @@ -7,7 +7,7 @@ let { lo }: Props = $props(); -
+
{@html lo.contentHtml}
diff --git a/src/lib/ui/navigators/footers/TutorsMessage.svelte b/src/lib/ui/navigators/footers/TutorsMessage.svelte index 34c7d2afb..dab720c48 100644 --- a/src/lib/ui/navigators/footers/TutorsMessage.svelte +++ b/src/lib/ui/navigators/footers/TutorsMessage.svelte @@ -1,5 +1,5 @@ -
+