first
This commit is contained in:
127
node_modules/@sindresorhus/slugify/index.js
generated
vendored
Normal file
127
node_modules/@sindresorhus/slugify/index.js
generated
vendored
Normal file
@ -0,0 +1,127 @@
|
||||
import escapeStringRegexp from 'escape-string-regexp';
|
||||
import transliterate from '@sindresorhus/transliterate';
|
||||
import builtinOverridableReplacements from './overridable-replacements.js';
|
||||
|
||||
const decamelize = string => {
|
||||
return string
|
||||
// Separate capitalized words.
|
||||
.replace(/([A-Z]{2,})(\d+)/g, '$1 $2')
|
||||
.replace(/([a-z\d]+)([A-Z]{2,})/g, '$1 $2')
|
||||
|
||||
.replace(/([a-z\d])([A-Z])/g, '$1 $2')
|
||||
// `[a-rt-z]` matches all lowercase characters except `s`.
|
||||
// This avoids matching plural acronyms like `APIs`.
|
||||
.replace(/([A-Z]+)([A-Z][a-rt-z\d]+)/g, '$1 $2');
|
||||
};
|
||||
|
||||
const removeMootSeparators = (string, separator) => {
|
||||
const escapedSeparator = escapeStringRegexp(separator);
|
||||
|
||||
return string
|
||||
.replace(new RegExp(`${escapedSeparator}{2,}`, 'g'), separator)
|
||||
.replace(new RegExp(`^${escapedSeparator}|${escapedSeparator}$`, 'g'), '');
|
||||
};
|
||||
|
||||
const buildPatternSlug = options => {
|
||||
let negationSetPattern = 'a-z\\d';
|
||||
negationSetPattern += options.lowercase ? '' : 'A-Z';
|
||||
|
||||
if (options.preserveCharacters.length > 0) {
|
||||
for (const character of options.preserveCharacters) {
|
||||
if (character === options.separator) {
|
||||
throw new Error(`The separator character \`${options.separator}\` cannot be included in preserved characters: ${options.preserveCharacters}`);
|
||||
}
|
||||
|
||||
negationSetPattern += escapeStringRegexp(character);
|
||||
}
|
||||
}
|
||||
|
||||
return new RegExp(`[^${negationSetPattern}]+`, 'g');
|
||||
};
|
||||
|
||||
export default function slugify(string, options) {
|
||||
if (typeof string !== 'string') {
|
||||
throw new TypeError(`Expected a string, got \`${typeof string}\``);
|
||||
}
|
||||
|
||||
options = {
|
||||
separator: '-',
|
||||
lowercase: true,
|
||||
decamelize: true,
|
||||
customReplacements: [],
|
||||
preserveLeadingUnderscore: false,
|
||||
preserveTrailingDash: false,
|
||||
preserveCharacters: [],
|
||||
...options
|
||||
};
|
||||
|
||||
const shouldPrependUnderscore = options.preserveLeadingUnderscore && string.startsWith('_');
|
||||
const shouldAppendDash = options.preserveTrailingDash && string.endsWith('-');
|
||||
|
||||
const customReplacements = new Map([
|
||||
...builtinOverridableReplacements,
|
||||
...options.customReplacements
|
||||
]);
|
||||
|
||||
string = transliterate(string, {customReplacements});
|
||||
|
||||
if (options.decamelize) {
|
||||
string = decamelize(string);
|
||||
}
|
||||
|
||||
const patternSlug = buildPatternSlug(options);
|
||||
|
||||
if (options.lowercase) {
|
||||
string = string.toLowerCase();
|
||||
}
|
||||
|
||||
// Detect contractions/possessives by looking for any word followed by a `'t`
|
||||
// or `'s` in isolation and then remove it.
|
||||
string = string.replace(/([a-zA-Z\d]+)'([ts])(\s|$)/g, '$1$2$3');
|
||||
|
||||
string = string.replace(patternSlug, options.separator);
|
||||
string = string.replace(/\\/g, '');
|
||||
|
||||
if (options.separator) {
|
||||
string = removeMootSeparators(string, options.separator);
|
||||
}
|
||||
|
||||
if (shouldPrependUnderscore) {
|
||||
string = `_${string}`;
|
||||
}
|
||||
|
||||
if (shouldAppendDash) {
|
||||
string = `${string}-`;
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
export function slugifyWithCounter() {
|
||||
const occurrences = new Map();
|
||||
|
||||
const countable = (string, options) => {
|
||||
string = slugify(string, options);
|
||||
|
||||
if (!string) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const stringLower = string.toLowerCase();
|
||||
const numberless = occurrences.get(stringLower.replace(/(?:-\d+?)+?$/, '')) || 0;
|
||||
const counter = occurrences.get(stringLower);
|
||||
occurrences.set(stringLower, typeof counter === 'number' ? counter + 1 : 1);
|
||||
const newCounter = occurrences.get(stringLower) || 2;
|
||||
if (newCounter >= 2 || numberless > 2) {
|
||||
string = `${string}-${newCounter}`;
|
||||
}
|
||||
|
||||
return string;
|
||||
};
|
||||
|
||||
countable.reset = () => {
|
||||
occurrences.clear();
|
||||
};
|
||||
|
||||
return countable;
|
||||
}
|
||||
Reference in New Issue
Block a user