49 lines
1.6 KiB
JavaScript
49 lines
1.6 KiB
JavaScript
import { isObject } from '../predicate/isObject.mjs';
|
|
|
|
const regexMultiByte = /[\u200d\ud800-\udfff\u0300-\u036f\ufe20-\ufe2f\u20d0-\u20ff\ufe0e\ufe0f]/;
|
|
function truncate(string, options) {
|
|
string = string != null ? `${string}` : '';
|
|
let length = 30;
|
|
let omission = '...';
|
|
if (isObject(options)) {
|
|
length = parseLength(options.length);
|
|
omission = 'omission' in options ? `${options.omission}` : '...';
|
|
}
|
|
let i = string.length;
|
|
const lengthOmission = Array.from(omission).length;
|
|
const lengthBase = Math.max(length - lengthOmission, 0);
|
|
let strArray = undefined;
|
|
const unicode = regexMultiByte.test(string);
|
|
if (unicode) {
|
|
strArray = Array.from(string);
|
|
i = strArray.length;
|
|
}
|
|
if (length >= i) {
|
|
return string;
|
|
}
|
|
if (i <= lengthOmission) {
|
|
return omission;
|
|
}
|
|
let base = strArray === undefined ? string.slice(0, lengthBase) : strArray?.slice(0, lengthBase).join('');
|
|
const separator = options?.separator;
|
|
if (!separator) {
|
|
base += omission;
|
|
return base;
|
|
}
|
|
const search = separator instanceof RegExp ? separator.source : separator;
|
|
const flags = 'u' + (separator instanceof RegExp ? separator.flags.replace('u', '') : '');
|
|
const withoutSeparator = new RegExp(`(?<result>.*(?:(?!${search}).))(?:${search})`, flags).exec(base);
|
|
return (!withoutSeparator?.groups ? base : withoutSeparator.groups.result) + omission;
|
|
}
|
|
function parseLength(length) {
|
|
if (length == null) {
|
|
return 30;
|
|
}
|
|
if (length <= 0) {
|
|
return 0;
|
|
}
|
|
return length;
|
|
}
|
|
|
|
export { truncate };
|