plurals / pluralize

Pluralize or singularize any word based on a count
MIT License
2.16k stars 184 forks source link

Preserve case #184

Closed Tobbe closed 3 years ago

Tobbe commented 3 years ago

Hi

We use this library to automatically provide plural and singular forms of data model names.

Typical input would be User -> Users Posts -> Post Comment -> Comments etc

Those all work great

Problem is with multi-word model names where we need to provide our own rules, like UserNews. "News" is the same in singular and plural. So in our use case we need to make up a plural form. So we do pluralize.addIrregularRule('UserNews', 'UserNewses'). However, now when we do pluralize('UserNews') we get 'Usernewses'. For us it's important to keep the casing of all letters as they are. Our models are case sensitive. So we need the plural in this case to be UserNewses.

I found a related issue at #131 and PR at #136 but nothing has unfortunately come out of them yet.

@blakeembrey I'm happy to work on a PR this weekend if you can provide some guidance on how you want this solved.

Tobbe commented 3 years ago

Same issue with for example addPluralRule. I modified one of the tests

it('should allow new plural matching rules', function () {
  expect(pluralize.plural('regex')).to.equal('regexes');

  pluralize.addPluralRule(/gex$/i, 'gexii');
  pluralize.addPluralRule(/^FooBar$/, 'FooBarii');

  expect(pluralize.plural('regex')).to.equal('regexii');
  expect(pluralize.plural('FooBar')).to.equal('FooBarii');
});

It fails because it gets "Foobarii"

Tobbe commented 3 years ago

Digging in to the code a bit more I've figured out a workaround that works for us. addIrregularRule won't work, because it always does toLowerCase. But combining addPluralRule and addSingularRule with just the last word of the multi-word names works.

So instead of

pluralize.addIrregularRule('UserNews', 'UserNewses')

I can do

pluralize.addPluralRule(/News$/, 'Newses')
pluralize.addSingularlRule(/Newses$/, 'News')
blakeembrey commented 3 years ago

This doesn’t sound so much like you want to preserve case as you want this library to actually understand that UserNews is two words and apply the pluralization as if the suffix is “news”? This sounds out-of-scope for the library and pretty difficult to achieve. If you have a specific format, I’d suggest giving it the parts you want to pluralize and then formatting it back yourself.

Tobbe commented 3 years ago

I noticed you had tests for both PascalCase and camelCase, so I thought that was something you wanted to support

  ['camelCase', 'camelCases'],
  ['PascalCase', 'PascalCases'],

Regardless, I found another scenario where my workaround where I only look at the last word doesn't work. That's when the plural should be e.g. UserNewsList.

The way it works is I parse a file with singular names. When I find a word I don't know how to pluralize I ask the user. So: "I don't know how to make UserNews plural. Please provide the plural form:" And the user inputs "UserNewsList". Internally I now just look at the last word, News, and ask your pluralize library for the plural and singular form of that. With this input, just looking at the last word I'd think the plural form of "News" is "List", so the final plural is "UserList" 🙁 But even if I realized to input "NewsList" as the plural it would come out as "Newslist" from pluralize and would still break my implementation.

I realize that making NewsList the plural of News is even more out of scope for pluralize.

So yeah, I will definitely have to write some more logic that's specific to our use case on top of pluralize.

blakeembrey commented 3 years ago

I noticed you had tests for both PascalCase and camelCase

IIRC that was more around keeping the casing and not supporting pluralization, but it's a good flag. I'll probably look at eliminating some of that logic since it causes a lot of confusion for people.

Tobbe commented 3 years ago

@blakeembrey Thanks for your input in this thread. I'll close this issue now as what I want to do is out of scope for pluralize and is much better handled by the consumer of your library (i.e. my own app)

Thanks for creating and maintaining this library!

arossert commented 4 months ago

I also had this issue now that I'm trying to add a rule, it looks like

pluralize.addSingularRule('record', 'feedRecord');

But the output is all lowercase

pluralize.addSingularRule('record', 'feedRecord');
console.log(pluralize.singular('record'));

The output is feedrecord and not feedRecord, is this expected?