mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
feat(i18n): 21-language pipeline, landing/docs/API wiring, landing+API translations
Shared Claude Code translation pipeline (scripts/i18n, no API key) plus Astro/VitePress/Scalar i18n wiring. Landing and API reference translated into all 20 languages; docs i18n wiring + English source anchors. The translated docs markdown (apps/docs/<locale>/**, 3,620 files) follows in a companion PR because it exceeds GitHub's per-PR CI file limit.
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
// scripts/i18n/lib/slugify.mjs
|
||||
|
||||
// Exact port of the slugify VitePress uses (mdit-vue @mdit-vue/shared). Keeping
|
||||
// this identical means the {#anchor} we inject equals the auto-slug VitePress
|
||||
// would produce, so pre-existing #deep-links keep resolving after we add
|
||||
// explicit anchors. Regexes copied verbatim from vitepress/dist/node, with
|
||||
// explicit unicode escapes for the control and combining ranges.
|
||||
// biome-ignore lint/suspicious/noControlCharactersInRegex: byte-exact port of mdit-vue slugify; the control-char range is required for VitePress anchor parity.
|
||||
const rControl = /[\u0000-\u001f]/g;
|
||||
const rSpecial = /[\s~`!@#$%^&*()\-_+=[\]{}|\\;:"'“”‘’<>,.?/]+/g;
|
||||
const rCombining = /[\u0300-\u036f]/g;
|
||||
|
||||
/**
|
||||
* @param {string} str
|
||||
* @returns {string}
|
||||
*/
|
||||
export function slugify(str) {
|
||||
return String(str)
|
||||
.normalize("NFKD")
|
||||
.replace(rCombining, "")
|
||||
.replace(rControl, "")
|
||||
.replace(rSpecial, "-")
|
||||
.replace(/-{2,}/g, "-")
|
||||
.replace(/^-+|-+$/g, "")
|
||||
.replace(/^(\d)/, "_$1")
|
||||
.toLowerCase();
|
||||
}
|
||||
Reference in New Issue
Block a user