UNPKG

@technobuddha/library

Version:
58 lines (46 loc) 1.99 kB
import escapeRegExp from 'lodash/escapeRegExp'; import { empty } from '../constants'; import collapseWhitespace from '../collapseWhitespace'; import clean from '../clean'; const badChars = /[/\\:*?<>|.]+/ug; export type Options = { /** the file name will be truncated to this length */ maxLength?: number; /** character to use to replace "bad" characters */ replacement?: string; /** number of characters to presere at the end of the filename when truncated (for disambiguation) */ disambiguate?: number; /** string to separate the main section from the disambiguated section */ separator?: string; }; /** * Convert a string so that it can be used as a filename * * @param input The string to escape * @param __namedParameters see {@link Options} * @default maxLength 64 * @default replacement - (dash) * @default disambiguate 10 * @default separator … (ellipsis) * @returns the file name */ export function toFilename(input: string, { maxLength = 64, replacement = '-', disambiguate = 10, separator = '…' }: Options = {}): string { let suffix = empty; const compress = new RegExp(`\\s*${escapeRegExp(replacement)}[\\s${escapeRegExp(replacement)}]*`, 'ug'); input = clean(collapseWhitespace(input.normalize('NFC').replace('"', "'").replace(badChars, replacement)).replace(compress, replacement), replacement); if(suffix.length === 0 && input.length > maxLength) { suffix = input.slice(-disambiguate); input = input.slice(0, Math.max(0, input.length - suffix.length)); } if(suffix.length > maxLength) suffix = suffix.slice(0, Math.max(0, maxLength)); const length = maxLength - suffix.length; if(input.length > length) input = input.slice(0, Math.max(0, length)); if(input.length === 0) input = replacement; if(suffix.length > 0) return input + separator + suffix; return input; } export default toFilename;