diff --git a/help-beta/astro.config.mjs b/help-beta/astro.config.mjs index 4c78145eb0..9d8e7c7314 100644 --- a/help-beta/astro.config.mjs +++ b/help-beta/astro.config.mjs @@ -1,9 +1,22 @@ import starlight from "@astrojs/starlight"; import {defineConfig} from "astro/config"; +import Icons from "unplugin-icons/vite"; // https://astro.build/config export default defineConfig({ base: "help-beta", + vite: { + plugins: [ + // eslint-disable-next-line new-cap + Icons({ + compiler: "astro", + // Icons had a default scale of 1.2, which was making + // them look larger than the text around them. + scale: 1, + defaultStyle: "display: inline; vertical-align: text-bottom;", + }), + ], + }, integrations: [ starlight({ title: "Zulip help center", diff --git a/help-beta/package.json b/help-beta/package.json index 046a416b0e..76da7db7ff 100644 --- a/help-beta/package.json +++ b/help-beta/package.json @@ -12,11 +12,13 @@ "dependencies": { "@astrojs/check": "^0.9.3", "@astrojs/starlight": "^0.34.2", + "@iconify-json/fa": "^1.2.1", "@types/hast": "^3.0.4", "astro": "^5.1.2", "hast-util-from-html": "^2.0.3", "hast-util-to-html": "^9.0.5", "sharp": "^0.34.1", - "typescript": "^5.4.5" + "typescript": "^5.4.5", + "unplugin-icons": "^22.1.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f8ac970722..576e9c0ec6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -506,6 +506,9 @@ importers: '@astrojs/starlight': specifier: ^0.34.2 version: 0.34.2(astro@5.7.10(@types/node@22.15.6)(encoding@0.1.13)(jiti@1.21.7)(rollup@4.40.1)(sass@1.87.0)(terser@5.39.0)(typescript@5.8.3)(yaml@2.7.1)) + '@iconify-json/fa': + specifier: ^1.2.1 + version: 1.2.1 '@types/hast': specifier: ^3.0.4 version: 3.0.4 @@ -524,6 +527,9 @@ importers: typescript: specifier: ^5.4.5 version: 5.8.3 + unplugin-icons: + specifier: ^22.1.0 + version: 22.1.0 packages: @@ -534,6 +540,12 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} + '@antfu/install-pkg@1.1.0': + resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} + + '@antfu/utils@8.1.1': + resolution: {integrity: sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ==} + '@apidevtools/json-schema-ref-parser@9.0.9': resolution: {integrity: sha512-GBD2Le9w2+lVFoc4vswGI/TjkNIZSVp7+9xPf+X3uidBfWnAeUWmquteSyt0+VCrhNMWj/FTABISQrD3Z/YA+w==} @@ -1804,6 +1816,15 @@ packages: resolution: {integrity: sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==} engines: {node: '>=18.18'} + '@iconify-json/fa@1.2.1': + resolution: {integrity: sha512-aY2+tQNWq5ch+ShtAz3KKbNrFfwf4BPrXvyN7S4/lcf6Wms+kIxsd7C7KortzHZhoBnbhVN+qo+YUWLW7rLs9Q==} + + '@iconify/types@2.0.0': + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + + '@iconify/utils@2.3.0': + resolution: {integrity: sha512-GmQ78prtwYW6EtzXRU1rY+KwOKfz32PD7iJh6Iyqw68GiKuoZ2A6pRtzWONz5VQJbp50mEjXh/7NkumtrAgRKA==} + '@img/sharp-darwin-arm64@0.33.5': resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -3800,6 +3821,12 @@ packages: resolution: {integrity: sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==} engines: {'0': node >= 6.0} + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + + confbox@0.2.2: + resolution: {integrity: sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==} + confusing-browser-globals@1.0.11: resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==} @@ -4769,6 +4796,9 @@ packages: expressive-code@0.41.2: resolution: {integrity: sha512-aLZiZaqorRtNExtGpUjK9zFH9aTpWeoTXMyLo4b4IcuXfPqtLPPxhRm/QlPb8QqIcMMXnSiGRHSFpQfX0m7HJw==} + exsolve@1.0.5: + resolution: {integrity: sha512-pz5dvkYYKQ1AHVrgOzBKWeP4u4FRb3a6DNK2ucr0OoNwYIU4QWsJ+NM36LLzORT+z845MzKHHhpXiUF5nvQoJg==} + ext@1.7.0: resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} @@ -5153,6 +5183,10 @@ packages: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} + globals@15.15.0: + resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} + engines: {node: '>=18'} + globals@16.0.0: resolution: {integrity: sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A==} engines: {node: '>=18'} @@ -6079,6 +6113,9 @@ packages: resolution: {integrity: sha512-umfX9d3iuSxTQP4pnzLOz0HKnPg0FaUUIKcye2lOiz3KPu1Y3M3xlz76dISdFPQs37P9eJz1wUpcTS6KDPn9fA==} engines: {node: ^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4} + kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + kuler@2.0.0: resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==} @@ -6120,6 +6157,10 @@ packages: resolution: {integrity: sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==} engines: {node: '>= 12.13.0'} + local-pkg@1.1.1: + resolution: {integrity: sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==} + engines: {node: '>=14'} + locate-path@3.0.0: resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} engines: {node: '>=6'} @@ -6617,6 +6658,9 @@ packages: engines: {node: '>=10'} hasBin: true + mlly@1.7.4: + resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==} + mockdate@3.0.5: resolution: {integrity: sha512-iniQP4rj1FhBdBYS/+eQv7j1tadJ9lJtdzgOpvsOHng/GbcDh2Fhdeq+ZRldrPYdXvCyfFUmFeEwEGXZB5I/AQ==} @@ -7049,6 +7093,9 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + pbf@3.3.0: resolution: {integrity: sha512-XDF38WCH3z5OV/OVa8GKUNtLAyneuzbCisx7QUCF8Q6Nutx0WnJrQe5O+kOtBlLfRNUws98Y58Lblp+NJG5T4Q==} hasBin: true @@ -7097,6 +7144,12 @@ packages: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + + pkg-types@2.1.0: + resolution: {integrity: sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==} + plotly.js@3.0.1: resolution: {integrity: sha512-eWEUkqdv4sblmUQJ7xGlEA+LghzEVPJOlPBZMJuagG0CsQxlmBb+7rd0UFVig5jhRnN8PQqRQaLv6qXIjnvzgg==} engines: {node: '>=18.0.0'} @@ -7662,6 +7715,9 @@ packages: resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} engines: {node: '>=0.6'} + quansync@0.2.10: + resolution: {integrity: sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==} + querystringify@2.2.0: resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} @@ -8604,6 +8660,9 @@ packages: tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + tinyexec@1.0.1: + resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==} + tinyglobby@0.2.13: resolution: {integrity: sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==} engines: {node: '>=12.0.0'} @@ -8904,6 +8963,33 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} + unplugin-icons@22.1.0: + resolution: {integrity: sha512-ect2ZNtk1Zgwb0NVHd0C1IDW/MV+Jk/xaq4t8o6rYdVS3+L660ZdD5kTSQZvsgdwCvquRw+/wYn75hsweRjoIA==} + peerDependencies: + '@svgr/core': '>=7.0.0' + '@svgx/core': ^1.0.1 + '@vue/compiler-sfc': ^3.0.2 || ^2.7.0 + svelte: ^3.0.0 || ^4.0.0 || ^5.0.0 + vue-template-compiler: ^2.6.12 + vue-template-es2015-compiler: ^1.9.0 + peerDependenciesMeta: + '@svgr/core': + optional: true + '@svgx/core': + optional: true + '@vue/compiler-sfc': + optional: true + svelte: + optional: true + vue-template-compiler: + optional: true + vue-template-es2015-compiler: + optional: true + + unplugin@2.3.2: + resolution: {integrity: sha512-3n7YA46rROb3zSj8fFxtxC/PqoyvYQ0llwz9wtUPUutr9ig09C8gGo5CWCwHrUzlqC1LLR43kxp5vEIyH1ac1w==} + engines: {node: '>=18.12.0'} + unquote@1.1.1: resolution: {integrity: sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==} @@ -9303,6 +9389,9 @@ packages: resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} engines: {node: '>=10.13.0'} + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + webpack@5.99.7: resolution: {integrity: sha512-CNqKBRMQjwcmKR0idID5va1qlhrqVUKpovi+Ec79ksW8ux7iS1+A6VqzfZXgVYCFRKl7XL5ap3ZoMpwBJxcg0w==} engines: {node: '>=10.13.0'} @@ -9579,6 +9668,13 @@ snapshots: '@jridgewell/gen-mapping': 0.3.8 '@jridgewell/trace-mapping': 0.3.25 + '@antfu/install-pkg@1.1.0': + dependencies: + package-manager-detector: 1.3.0 + tinyexec: 1.0.1 + + '@antfu/utils@8.1.1': {} + '@apidevtools/json-schema-ref-parser@9.0.9': dependencies: '@jsdevtools/ono': 7.1.3 @@ -11087,6 +11183,25 @@ snapshots: '@humanwhocodes/retry@0.4.2': {} + '@iconify-json/fa@1.2.1': + dependencies: + '@iconify/types': 2.0.0 + + '@iconify/types@2.0.0': {} + + '@iconify/utils@2.3.0': + dependencies: + '@antfu/install-pkg': 1.1.0 + '@antfu/utils': 8.1.1 + '@iconify/types': 2.0.0 + debug: 4.4.0 + globals: 15.15.0 + kolorist: 1.8.0 + local-pkg: 1.1.1 + mlly: 1.7.4 + transitivePeerDependencies: + - supports-color + '@img/sharp-darwin-arm64@0.33.5': optionalDependencies: '@img/sharp-libvips-darwin-arm64': 1.0.4 @@ -13359,6 +13474,10 @@ snapshots: readable-stream: 3.6.2 typedarray: 0.0.6 + confbox@0.1.8: {} + + confbox@0.2.2: {} + confusing-browser-globals@1.0.11: {} connect-history-api-fallback@2.0.0: {} @@ -14536,6 +14655,8 @@ snapshots: '@expressive-code/plugin-shiki': 0.41.2 '@expressive-code/plugin-text-markers': 0.41.2 + exsolve@1.0.5: {} + ext@1.7.0: dependencies: type: 2.7.3 @@ -15012,6 +15133,8 @@ snapshots: globals@14.0.0: {} + globals@15.15.0: {} + globals@16.0.0: {} globalthis@1.0.4: @@ -16112,6 +16235,8 @@ snapshots: transitivePeerDependencies: - supports-color + kolorist@1.8.0: {} + kuler@2.0.0: {} launch-editor@2.10.0: @@ -16152,6 +16277,12 @@ snapshots: loader-utils@3.3.1: {} + local-pkg@1.1.1: + dependencies: + mlly: 1.7.4 + pkg-types: 2.1.0 + quansync: 0.2.10 + locate-path@3.0.0: dependencies: p-locate: 3.0.0 @@ -16972,6 +17103,13 @@ snapshots: mkdirp@1.0.4: {} + mlly@1.7.4: + dependencies: + acorn: 8.14.1 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.1 + mockdate@3.0.5: {} mouse-change@1.4.0: @@ -17463,6 +17601,8 @@ snapshots: path-type@4.0.0: {} + pathe@2.0.3: {} + pbf@3.3.0: dependencies: ieee754: 1.2.1 @@ -17496,6 +17636,18 @@ snapshots: dependencies: find-up: 4.1.0 + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.7.4 + pathe: 2.0.3 + + pkg-types@2.1.0: + dependencies: + confbox: 0.2.2 + exsolve: 1.0.5 + pathe: 2.0.3 + plotly.js@3.0.1(mapbox-gl@1.13.3)(webpack@5.99.7): dependencies: '@plotly/d3': 3.8.2 @@ -18171,6 +18323,8 @@ snapshots: dependencies: side-channel: 1.1.0 + quansync@0.2.10: {} + querystringify@2.2.0: {} queue-microtask@1.2.3: {} @@ -19486,6 +19640,8 @@ snapshots: tinyexec@0.3.2: {} + tinyexec@1.0.1: {} + tinyglobby@0.2.13: dependencies: fdir: 6.4.4(picomatch@4.0.2) @@ -19814,6 +19970,22 @@ snapshots: unpipe@1.0.0: {} + unplugin-icons@22.1.0: + dependencies: + '@antfu/install-pkg': 1.1.0 + '@iconify/utils': 2.3.0 + debug: 4.4.0 + local-pkg: 1.1.1 + unplugin: 2.3.2 + transitivePeerDependencies: + - supports-color + + unplugin@2.3.2: + dependencies: + acorn: 8.14.1 + picomatch: 4.0.2 + webpack-virtual-modules: 0.6.2 + unquote@1.1.1: {} unstorage@1.16.0: @@ -20200,6 +20372,8 @@ snapshots: webpack-sources@3.2.3: {} + webpack-virtual-modules@0.6.2: {} + webpack@5.99.7(webpack-cli@6.0.1): dependencies: '@types/eslint-scope': 3.7.7 diff --git a/tools/convert-help-center-docs-to-mdx b/tools/convert-help-center-docs-to-mdx index 001b72fcbb..6a6d861070 100755 --- a/tools/convert-help-center-docs-to-mdx +++ b/tools/convert-help-center-docs-to-mdx @@ -95,10 +95,32 @@ def append_str_to_line(text: str, destination_str: str, n: int) -> str: lines = destination_str.splitlines() if 1 <= n <= len(lines): lines[n - 1] += "\n" + text - return "\n".join(lines) +def replace_icons(markdown_string: str, import_statement_set: set[str]) -> str: + """ + Write some examples here and some assumptions we made about + the icon tags. + """ + font_awesome_pattern = re.compile( + r']*class="(?:[^"]*\s)?fa(?:\s+fa-([a-z0-9\-]+))(?:\s[^"]*)?"[^>]*>(?:\s[^<]*)?', + ) + + def replace_font_awesome_icon_with_unplugin_component(match: re.Match[str]) -> str: + icon_name = match.group(1) + component_name = "Fa" + to_pascal(icon_name).replace("-", "") + import_statement = f'import {component_name} from "~icons/fa/{icon_name}"' + import_statement_set.add(import_statement) + return f"<{component_name} />" + + result = re.sub( + font_awesome_pattern, replace_font_awesome_icon_with_unplugin_component, markdown_string + ) + + return result + + def insert_imports(markdown_string: str, import_statement_set: set[str]) -> str: if len(import_statement_set) == 0: return markdown_string @@ -140,6 +162,7 @@ def convert_string_to_mdx(markdown_string: str) -> str: result = fix_relative_path(result) result = replace_emoticon_translation_table(result, import_statement_set) result = replace_image_path(result) + result = replace_icons(result, import_statement_set) result = insert_imports(result, import_statement_set) result = insert_frontmatter(result) return result diff --git a/version.py b/version.py index 71e599ce61..174e51f2bc 100644 --- a/version.py +++ b/version.py @@ -49,4 +49,4 @@ API_FEATURE_LEVEL = 384 # historical commits sharing the same major version, in which case a # minor version bump suffices. -PROVISION_VERSION = (326, 2) # bumped 2025-05-05 to upgrade JavaScript dependencies +PROVISION_VERSION = (326, 3) # bumped 2025-05-12 to add unplugin-icons