* feat(SW-2152): Added improved meta descriptions for hotel pages * feat(SW-2152): Added improved meta descriptions for destination pages * feat(SW-2152): Refactoring metadata description functionality * feat(SW-2152): Improved truncate function and added cities check to country page description Approved-by: Michael Zetterberg Approved-by: Matilda Landström
61 lines
2.4 KiB
TypeScript
61 lines
2.4 KiB
TypeScript
/**
|
|
* Truncates the given text "intelligently" based on the last period found near the max length.
|
|
*
|
|
* - If a period exists within the extended range (`maxLength` to `maxLength + maxExtension`),
|
|
* the function truncates after the closest period to `maxLength`.
|
|
* - If no period is found in the range, it truncates the text after the last period found in the max length of the text.
|
|
* - If no periods exist at all, it truncates at `maxLength` and appends ellipsis (`...`).
|
|
*
|
|
* @param {string} text - The input text to be truncated.
|
|
* @param {number} [maxLength=150] - The desired maximum length of the truncated text.
|
|
* @param {number} [minLength=120] - The minimum allowable length for the truncated text.
|
|
* @param {number} [maxExtension=10] - The maximum number of characters to extend beyond `maxLength` to find a period.
|
|
* @returns {string} - The truncated text.
|
|
*/
|
|
export function truncateTextAfterLastPeriod(
|
|
text: string,
|
|
maxLength: number = 160,
|
|
minLength: number = 120,
|
|
maxExtension: number = 10
|
|
): string {
|
|
if (text.length <= maxLength) {
|
|
return text
|
|
}
|
|
|
|
// Define the extended range
|
|
const extendedEnd = Math.min(text.length, maxLength + maxExtension)
|
|
const extendedText = text.slice(0, extendedEnd)
|
|
|
|
// Find all periods within the extended range and filter after minLength to get valid periods
|
|
const periodsInRange = [...extendedText.matchAll(/\./g)].map(
|
|
({ index }) => index
|
|
)
|
|
const validPeriods = periodsInRange.filter((index) => index + 1 >= minLength)
|
|
|
|
if (validPeriods.length > 0) {
|
|
// Find the period closest to maxLength
|
|
const closestPeriod = validPeriods.reduce((closest, currentIndex) => {
|
|
const distanceFromCurrentToMaxLength = Math.abs(
|
|
currentIndex + 1 - maxLength
|
|
)
|
|
const distanceFromClosestToMaxLength = Math.abs(closest + 1 - maxLength)
|
|
|
|
return distanceFromCurrentToMaxLength < distanceFromClosestToMaxLength
|
|
? currentIndex
|
|
: closest
|
|
}, validPeriods[0])
|
|
|
|
return extendedText.slice(0, closestPeriod + 1)
|
|
}
|
|
|
|
// Fallback: If no period is found within the valid range, look for the last period in the truncated text
|
|
const maxLengthText = text.slice(0, maxLength)
|
|
const lastPeriodIndex = maxLengthText.lastIndexOf(".")
|
|
if (lastPeriodIndex !== -1) {
|
|
return text.slice(0, lastPeriodIndex + 1)
|
|
}
|
|
|
|
// Final fallback: Return maxLength text including ellipsis
|
|
return `${maxLengthText}...`
|
|
}
|