export function slug(text: string, maxWidth = 50): string { // Greek to Latin character mapping const greekToLatinMap: Record = { α: 'a', β: 'b', γ: 'g', δ: 'd', ε: 'e', ζ: 'z', η: 'i', θ: 'th', ι: 'i', κ: 'k', λ: 'l', μ: 'm', ν: 'n', ξ: 'x', ο: 'o', π: 'p', ρ: 'r', σ: 's', τ: 't', υ: 'y', φ: 'f', χ: 'ch', ψ: 'ps', ω: 'o', ά: 'a', έ: 'e', ί: 'i', ό: 'o', ύ: 'y', ή: 'i', ώ: 'o', ς: 's', ϊ: 'i', ΰ: 'y', ϋ: 'y', ΐ: 'i', Α: 'A', Β: 'B', Γ: 'G', Δ: 'D', Ε: 'E', Ζ: 'Z', Η: 'I', Θ: 'TH', Ι: 'I', Κ: 'K', Λ: 'L', Μ: 'M', Ν: 'N', Ξ: 'X', Ο: 'O', Π: 'P', Ρ: 'R', Σ: 'S', Τ: 'T', Υ: 'Y', Φ: 'F', Χ: 'CH', Ψ: 'PS', Ω: 'O', Ά: 'A', Έ: 'E', Ί: 'I', Ό: 'O', Ύ: 'Y', Ή: 'I', Ώ: 'O', Ϊ: 'I', Ϋ: 'Y', }; // Convert Greek characters to Latin const latinText = text .split('') .map((char) => greekToLatinMap[char] || char) .join(''); // Convert to lowercase, replace spaces with hyphens, remove special characters const processedText = latinText .toLowerCase() .replace(/\s+/g, '-') .replace(/[^\w-]+/g, '') .replace(/--+/g, '-') .replace(/^-+/, '') .replace(/-+$/, ''); // Calculate the available width for the slug (subtracting 1 for the hyphen and at least 8 for the ID) // const availableWidth = Math.max(0, maxWidth - 9); // Split the processed text into slug and remaining text for ID let slug = processedText.substring(0, maxWidth); const remainingText = processedText.substring(maxWidth); // Remove trailing hyphens from the slug slug = slug.replace(/-+$/, ''); // Generate ID from the remaining text const id = generateIDFromText(remainingText); // Combine the slug and ID return `${slug}${id && '-'}${id}`; } function generateIDFromText(text: string): string { // If text is empty or maxLength is 0 or less, return a default ID if (!text) return ''; // Remove hyphens and take only alphanumeric characters let processedText = text.replace(/-/g, '').replace(/[^a-z0-9]/g, ''); // If processed text is empty, use a default base if (!processedText) processedText = 'default'; // Calculate a simple hash of the processed text let hash = 0; for (let i = 0; i < processedText.length; i++) { const char = processedText.charCodeAt(i); hash = (hash << 5) - hash + char; hash = hash & hash; // Convert to 32-bit integer } // Convert hash to a positive number and then to base 36 (0-9 and a-z) const id = Math.abs(hash).toString(36); // Ensure the ID is at least 8 characters long, padding with '0' if necessary return id; // return id.padEnd(8, '0').substring(0, maxLength); } // Test the function // console.log(createSlugWithID('Καλημέρα κόσμε! Hello world!', 10)); // console.log(createSlugWithID('Ελληνικά και English mixed', 80)); // console.log( // createSlugWithID( // 'Αυτό είναι ένα πολύ μεγάλο κείμενο για να δοκιμάσουμε το όριο πλάτους', // 90 // ) // );