UNPKG

@kevinoid/dotnet-identifier-case

Version:

Transform a string to PascalCase according to Microsoft's .NET Capitalization Conventions.

49 lines (45 loc) 2.09 kB
/** * @copyright Copyright 2019-2024 Kevin Locke <kevin@kevinlocke.name> * @license MIT * @module dotnet-identifier-case */ /** Transforms a string with any case convention to one using {@link * https://docs.microsoft.com/dotnet/standard/design-guidelines/capitalization-conventions|Microsoft's * .NET Capitalization Conventions.} * * @param {string} value String value to be transformed. * @returns {string} value converted to PascalCase. */ export default function dotnetIdentifierCase(value) { // Split words with changing capitalization similarly to how change-case does // https://github.com/blakeembrey/change-case/blob/38e6b4f9115cf93b18ca9b1b4a620a32751499cb/packages/change-case/src/index.ts#L46-L53 return String(value) // Don't treat apostrophe as a word break (unlike no-case) .replaceAll('\'', '') // Split camelCase words .replaceAll(/(?<=[\p{Ll}\d])(?=\p{Lu})/gu, ' ') // Split CAMELCase words .replaceAll(/(?<=\p{Lu})(?=\p{Lu}\p{Ll})/gu, ' ') // Capitalize words .replaceAll(/([\p{L}\p{N}])([\p{L}\p{N}]*)/gu, (word, first, rest) => { // "A special case is made for two-letter acronyms in which both letters // are capitalized" // https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/capitalization-conventions#capitalization-rules-for-identifiers if (word.length === 2 && word === word.toUpperCase()) { return word; } // If the word is a roman numeral, leave it capitalized // https://stackoverflow.com/a/267405 if (/^M{0,4}(?:D?C{0,3}|CD|CM)(?:L?X{0,3}|XC|XL)(?:V?I{0,3}|IV|IX)$/.test( word, )) { return word; } return first.toUpperCase() + rest.toLowerCase(); }) // Remove non-alnum characters // Note: C# identifiers can have [\p{L}\p{Nl}\p{Nd}\p{Pc}\p{Mn}\p{Mc}\p{Cf}] // Stick with [\p{L}\d] for consistency with change-case // https://github.com/blakeembrey/change-case/blob/38e6b4f9115cf93b18ca9b1b4a620a32751499cb/packages/change-case/src/index.ts#L9 .replaceAll(/[^\p{L}\d]+/gu, ''); }