diff --git a/.gitignore b/.gitignore index 2aff8c2d5..b7792c119 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,15 @@ node_modules/ src-tauri/target src-tauri/gen/schemas +# KaTeX files +public/*.min.css +public/fonts/KaTeX_**.ttf +public/fonts/KaTeX_**.woff +public/fonts/KaTeX_**.woff2 + +# Twemoji Assets +public/twemoji/*.svg + # Editor directories and files .vscode .idea diff --git a/index.html b/index.html index 14ee21253..7c2a903d6 100644 --- a/index.html +++ b/index.html @@ -63,6 +63,11 @@ +
diff --git a/package-lock.json b/package-lock.json index 76fb6f4b8..5a7dc1c04 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,7 @@ "": { "name": "radicle-desktop", "version": "0.0.0", + "hasInstallScript": true, "license": "MIT", "dependencies": { "@tauri-apps/api": "^2.0.0-beta.15", @@ -16,25 +17,34 @@ }, "devDependencies": { "@eslint/js": "^9.11.1", + "@radicle/gray-matter": "4.1.0", "@sveltejs/vite-plugin-svelte": "^4.0.0-next.6", "@tauri-apps/cli": "^2.0.0-rc.1", "@tsconfig/svelte": "^5.0.4", "@types/dompurify": "^3.0.5", "@types/lodash": "^4.17.9", "@types/node": "^20.9.0", + "@wooorm/starry-night": "^3.5.0", "baconjs": "^3.0.19", "bs58": "^6.0.0", "dompurify": "^3.1.6", "eslint": "^9.11.1", "eslint-config-prettier": "^9.1.0", "eslint-plugin-svelte": "^2.44.0", + "hast-util-to-dom": "^4.0.0", "lodash": "^4.17.21", + "marked": "^14.1.2", + "marked-emoji": "^1.4.2", + "marked-footnote": "^1.2.4", + "marked-katex-extension": "^5.1.2", + "marked-linkify-it": "^3.1.11", "prettier": "^3.3.3", "prettier-plugin-svelte": "^3.2.6", "svelte": "^5.0.0-next.243", "svelte-check": "^4.0.2", "svelte-eslint-parser": "^0.41.1", "tslib": "^2.7.0", + "twemoji": "^14.0.2", "typescript": "^5.6.2", "typescript-eslint": "^8.7.0", "vite": "^5.4.7" @@ -645,6 +655,21 @@ "node": ">= 8" } }, + "node_modules/@radicle/gray-matter": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@radicle/gray-matter/-/gray-matter-4.1.0.tgz", + "integrity": "sha512-Cbdz8QMzIuZXxeGpJtvnNiMYF4YTOJn1EDsEZ0GsgCVWVL96LGPZIu30/bEtw2U8p7anZuQNqa4ugqB+qsEjqw==", + "dev": true, + "dependencies": { + "js-yaml": "^4.1.0", + "kind-of": "^6.0.2", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.22.4", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz", @@ -1133,12 +1158,33 @@ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true }, + "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, + "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", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, + "node_modules/@types/katex": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz", + "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==", + "dev": true + }, + "node_modules/@types/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", + "dev": true + }, "node_modules/@types/lodash": { "version": "4.17.9", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.9.tgz", @@ -1146,9 +1192,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.16.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.6.tgz", - "integrity": "sha512-T7PpxM/6yeDE+AdlVysT62BX6/bECZOmQAgiFg5NoBd5MQheZ3tzal7f1wvzfiEcmrcJNRi2zRr2nY2zF+0uqw==", + "version": "20.16.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.7.tgz", + "integrity": "sha512-QkDQjAY3gkvJNcZOWwzy3BN34RweT0OQ9zJyvLCU0kSK22dO2QYh/NHGfbEAYylPYzRB1/iXcojS79wOg5gFSw==", "dev": true, "dependencies": { "undici-types": "~6.19.2" @@ -1160,6 +1206,12 @@ "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", "dev": true }, + "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 + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.7.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.7.0.tgz", @@ -1378,6 +1430,22 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@wooorm/starry-night": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wooorm/starry-night/-/starry-night-3.5.0.tgz", + "integrity": "sha512-nYnfdeWS0ApqIFqr4ezLjr6pyYuqiG5Ywc2aJ4u1EY3qzf2oCTfLv7sMjEQSuSzPWUIH+a39eVbGUiRrFKZElA==", + "dev": true, + "dependencies": { + "@types/hast": "^3.0.0", + "import-meta-resolve": "^4.0.0", + "vscode-oniguruma": "^2.0.0", + "vscode-textmate": "^9.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/acorn": { "version": "8.12.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", @@ -1637,6 +1705,16 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 12" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1983,6 +2061,18 @@ "node": ">=0.10.0" } }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -2111,6 +2201,29 @@ "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-extra/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -2149,6 +2262,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -2164,6 +2283,21 @@ "node": ">=8" } }, + "node_modules/hast-util-to-dom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-to-dom/-/hast-util-to-dom-4.0.0.tgz", + "integrity": "sha512-oW7RScutPE58LfjuVUNvvH0+6rB89mAm/pkDqD3bdj9g6xKQlMcuW6yBmovbpDKkvYI2apPKmHZMtc9KiZTywA==", + "dev": true, + "dependencies": { + "@types/hast": "^3.0.0", + "property-information": "^6.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -2189,6 +2323,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/import-meta-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", + "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -2210,6 +2354,15 @@ "node": ">=8" } }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -2294,6 +2447,35 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "node_modules/jsonfile": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-5.0.0.tgz", + "integrity": "sha512-NQRZ5CRo74MhMMC3/3r5g2k4fjodJ/wh8MxjFbCViWKFjxrnudWSY5vomh+23ZaXzAS7J3fBZIR2dV6WbmfM0w==", + "dev": true, + "dependencies": { + "universalify": "^0.1.2" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/katex": { + "version": "0.16.11", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.11.tgz", + "integrity": "sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ==", + "dev": true, + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "peer": true, + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -2303,6 +2485,15 @@ "json-buffer": "3.0.1" } }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/kleur": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", @@ -2340,6 +2531,15 @@ "node": ">=10" } }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "dev": true, + "dependencies": { + "uc.micro": "^2.0.0" + } + }, "node_modules/locate-character": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", @@ -2382,6 +2582,62 @@ "@jridgewell/sourcemap-codec": "^1.5.0" } }, + "node_modules/marked": { + "version": "14.1.2", + "resolved": "https://registry.npmjs.org/marked/-/marked-14.1.2.tgz", + "integrity": "sha512-f3r0yqpz31VXiDB/wj9GaOB0a2PRLQl6vJmXiFrniNwjkKdvakqJRULhjFKJpxOchlCRiG5fcacoUZY5Xa6PEQ==", + "dev": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/marked-emoji": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/marked-emoji/-/marked-emoji-1.4.2.tgz", + "integrity": "sha512-2sP+bp2z76dwbILzQ7ijy2PyjjAJR3iAZCzaNGThD2UijFUBeidkn6MoCdX/j47tPIcWt9nwnjqRQPd01ZrfdA==", + "dev": true, + "peerDependencies": { + "marked": ">=4 <15" + } + }, + "node_modules/marked-footnote": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/marked-footnote/-/marked-footnote-1.2.4.tgz", + "integrity": "sha512-DB2Kl+wFh6YwZd70qABMY6WUkG1UuyqoNTFoDfGyG79Pz24neYtLBkB+45a7o72V7gkfvbC3CGzIYFobxfMT1Q==", + "dev": true, + "peerDependencies": { + "marked": ">=7.0.0" + } + }, + "node_modules/marked-katex-extension": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/marked-katex-extension/-/marked-katex-extension-5.1.2.tgz", + "integrity": "sha512-jRtacvDAPULKBWArDno0IGpzzpUw12yb8OaEsv3dTlvcIr21+mF9kD+Bxo2m/ErX/2ZIml6zFVMnpxCpqx3stw==", + "dev": true, + "dependencies": { + "@types/katex": "^0.16.7" + }, + "peerDependencies": { + "katex": ">=0.16 <0.17", + "marked": ">=4 <15" + } + }, + "node_modules/marked-linkify-it": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/marked-linkify-it/-/marked-linkify-it-3.1.11.tgz", + "integrity": "sha512-xcrc9c4PMQdUoEO8dE6HLW80ShrolXBqqmJz1c9XdM5t/D0fzXXZ+FJOM4wqhs1AOfpjLipPQKmkcxA5cSFykw==", + "dev": true, + "dependencies": { + "@types/linkify-it": "^5.0.0", + "linkify-it": "^5.0.0" + }, + "peerDependencies": { + "marked": ">=4 <15" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -2719,6 +2975,16 @@ "svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0" } }, + "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, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -2867,6 +3133,19 @@ "node": ">=6" } }, + "node_modules/section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/semver": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", @@ -2921,6 +3200,15 @@ "node": ">=8" } }, + "node_modules/strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -2946,9 +3234,9 @@ } }, "node_modules/svelte": { - "version": "5.0.0-next.258", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.0.0-next.258.tgz", - "integrity": "sha512-kkIXBIhYRaywZtch4bWfdVlE4uq1SYYHQo05qNlUJzyWemRyVA5jpoA3ezzXN5+ph6rf40IVRHE5jyr7ic6Hdg==", + "version": "5.0.0-next.259", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.0.0-next.259.tgz", + "integrity": "sha512-trRFSjKD+11KbXerGmBT0Uc+ZSNUhxn0aQ02q9tjtig/FV24dpZlXmCrcZTZliOLS0P8JWjw6xaWgNheZZoYOg==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.3.0", @@ -3100,6 +3388,24 @@ "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", "dev": true }, + "node_modules/twemoji": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/twemoji/-/twemoji-14.0.2.tgz", + "integrity": "sha512-BzOoXIe1QVdmsUmZ54xbEH+8AgtOKUiG53zO5vVP2iUu6h5u9lN15NcuS6te4OY96qx0H7JK9vjjl9WQbkTRuA==", + "dev": true, + "dependencies": { + "fs-extra": "^8.0.1", + "jsonfile": "^5.0.0", + "twemoji-parser": "14.0.0", + "universalify": "^0.1.2" + } + }, + "node_modules/twemoji-parser": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/twemoji-parser/-/twemoji-parser-14.0.0.tgz", + "integrity": "sha512-9DUOTGLOWs0pFWnh1p6NF+C3CkQ96PWmEFwhOVmT3WbecRC+68AIqpsnJXygfkFcp4aXbOp8Dwbhh/HQgvoRxA==", + "dev": true + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -3148,12 +3454,27 @@ } } }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "dev": true + }, "node_modules/undici-types": { "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "dev": true }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -3170,9 +3491,9 @@ "dev": true }, "node_modules/vite": { - "version": "5.4.7", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.7.tgz", - "integrity": "sha512-5l2zxqMEPVENgvzTuBpHer2awaetimj2BGkhBPdnwKbPNOlHsODU+oiazEZzLK7KhAnOrO+XGYJYn4ZlUhDtDQ==", + "version": "5.4.8", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz", + "integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==", "dev": true, "dependencies": { "esbuild": "^0.21.3", @@ -3242,6 +3563,28 @@ } } }, + "node_modules/vscode-oniguruma": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-2.0.1.tgz", + "integrity": "sha512-poJU8iHIWnC3vgphJnrLZyI3YdqRlR27xzqDmpPXYzA93R4Gk8z7T6oqDzDoHjoikA2aS82crdXFkjELCdJsjQ==", + "dev": true + }, + "node_modules/vscode-textmate": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-9.1.0.tgz", + "integrity": "sha512-lxKSVp2DkFOx9RDAvpiYUrB9/KT1fAfi1aE8CBGstP8N7rLF+Seifj8kDA198X0mYj1CjQUC+81+nQf8CO0nVA==", + "dev": true + }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index b04a97256..ef5153897 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "type": "module", "scripts": { "start": "vite", - "build": "vite build", + "build": "vite build && scripts/copy-katex-assets && scripts/install-twemoji-assets", + "postinstall": "scripts/copy-katex-assets && scripts/install-twemoji-assets", "preview": "vite preview", "check": "scripts/check-js && scripts/check-rs", "check-js": "scripts/check-js", @@ -27,25 +28,34 @@ }, "devDependencies": { "@eslint/js": "^9.11.1", + "@radicle/gray-matter": "4.1.0", "@sveltejs/vite-plugin-svelte": "^4.0.0-next.6", "@tauri-apps/cli": "^2.0.0-rc.1", "@tsconfig/svelte": "^5.0.4", "@types/dompurify": "^3.0.5", "@types/lodash": "^4.17.9", "@types/node": "^20.9.0", + "@wooorm/starry-night": "^3.5.0", "baconjs": "^3.0.19", "bs58": "^6.0.0", "dompurify": "^3.1.6", "eslint": "^9.11.1", "eslint-config-prettier": "^9.1.0", "eslint-plugin-svelte": "^2.44.0", + "hast-util-to-dom": "^4.0.0", "lodash": "^4.17.21", + "marked": "^14.1.2", + "marked-emoji": "^1.4.2", + "marked-footnote": "^1.2.4", + "marked-katex-extension": "^5.1.2", + "marked-linkify-it": "^3.1.11", "prettier": "^3.3.3", "prettier-plugin-svelte": "^3.2.6", "svelte": "^5.0.0-next.243", "svelte-check": "^4.0.2", "svelte-eslint-parser": "^0.41.1", "tslib": "^2.7.0", + "twemoji": "^14.0.2", "typescript": "^5.6.2", "typescript-eslint": "^8.7.0", "vite": "^5.4.7" diff --git a/public/twemoji/.gitkeep b/public/twemoji/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/scripts/copy-katex-assets b/scripts/copy-katex-assets new file mode 100755 index 000000000..aa83b2535 --- /dev/null +++ b/scripts/copy-katex-assets @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +echo "Copying katex assets into bundle directory" + +cp -r node_modules/katex/dist/katex.min.css public/katex.min.css +cp -r node_modules/katex/dist/fonts/* public/fonts/ diff --git a/scripts/install-twemoji-assets b/scripts/install-twemoji-assets new file mode 100755 index 000000000..96a48b219 --- /dev/null +++ b/scripts/install-twemoji-assets @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -Eeou pipefail + +version="$(node -e 'console.log(require("twemoji/package.json").version)')" + +echo "Installing Twemoji SVG assets v${version}" + +curl -sSL "https://github.com/twitter/twemoji/archive/refs/tags/v${version}.tar.gz" \ + | tar -x -z -C public/twemoji/ --strip-components=3 "twemoji-${version}/assets/svg" diff --git a/src/components/Markdown.svelte b/src/components/Markdown.svelte new file mode 100644 index 000000000..4e8e4f88d --- /dev/null +++ b/src/components/Markdown.svelte @@ -0,0 +1,382 @@ + + + + +{#if frontMatter && frontMatter.length > 0} +| {key} | +{val} | +