diff --git a/resources/js/singles/sommaire.ts b/resources/js/singles/sommaire.ts index 4d4f763..c8eb343 100644 --- a/resources/js/singles/sommaire.ts +++ b/resources/js/singles/sommaire.ts @@ -4,16 +4,118 @@ export function handleSmoothScrollToTitle(targetId: string): void { targetElement.scrollIntoView({ behavior: 'smooth' }); } +// Fonction équivalente à sanitize_title() de WordPress +function sanitizeTitle(title: string): string { + // Convertir en minuscules + let slug = title.toLowerCase(); + + // Remplacer les caractères spéciaux français et autres + const replacements: { [key: string]: string } = { + à: 'a', + á: 'a', + â: 'a', + ã: 'a', + ä: 'a', + å: 'a', + è: 'e', + é: 'e', + ê: 'e', + ë: 'e', + ì: 'i', + í: 'i', + î: 'i', + ï: 'i', + ò: 'o', + ó: 'o', + ô: 'o', + õ: 'o', + ö: 'o', + ù: 'u', + ú: 'u', + û: 'u', + ü: 'u', + ý: 'y', + ÿ: 'y', + ñ: 'n', + ç: 'c', + œ: 'oe', + æ: 'ae', + '«': '', + '»': '', + '"': '', + '"': '', + '?': '', + '!': '', + ':': '', + ';': '', + '.': '', + ',': '', + '(': '', + ')': '', + '[': '', + ']': '', + '{': '', + '}': '', + '/': '-', + '\\': '-', + '|': '-', + '&': 'et', + '@': 'at', + '#': '', + $: '', + '%': '', + '*': '', + '+': '', + '=': '', + '<': '', + '>': '', + '~': '', + '`': '', + '^': '', + '°': '', + '…': '', + '—': '-', + '–': '-', + '−': '-', + ' ': '-', + '\t': '-', + '\n': '-', + '\r': '-', + }; + + // Appliquer les remplacements + for (const [char, replacement] of Object.entries(replacements)) { + slug = slug.replace(new RegExp(char.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'), replacement); + } + + // Supprimer les caractères non alphanumériques restants (sauf tirets) + slug = slug.replace(/[^a-z0-9\-]/g, ''); + + // Remplacer les tirets multiples par un seul tiret + slug = slug.replace(/-+/g, '-'); + + // Supprimer les tirets en début et fin + slug = slug.replace(/^-+|-+$/g, ''); + + // S'assurer que l'ancre n'est pas vide + if (!slug) { + slug = 'anchor'; + } + + // Limiter la longueur (comme sanitize_title() de WordPress - 200 caractères) + if (slug.length > 200) { + slug = slug.substring(0, 200); + slug = slug.replace(/-+$/, ''); + } + + return slug; +} + export function injectIdToNativeTitles(): void { const titles = document.querySelectorAll('.content-area h2, .content-area h3'); titles.forEach((title) => { const titleText = title.textContent || ''; - const slug = titleText - .toLowerCase() - .normalize('NFD') - .replace(/[\u0300-\u036f]/g, '') - .replace(/\s+/g, '-') - .replace(/[^\w-]+/g, ''); + const slug = sanitizeTitle(titleText); title.setAttribute('id', slug); }); }