{"id":13879674,"url":"https://github.com/piotrmurach/strings-inflection","last_synced_at":"2025-06-12T13:09:25.966Z","repository":{"id":54134993,"uuid":"222158323","full_name":"piotrmurach/strings-inflection","owner":"piotrmurach","description":"Convert between singular and plural forms of English nouns","archived":false,"fork":false,"pushed_at":"2024-03-11T22:06:12.000Z","size":232,"stargazers_count":31,"open_issues_count":2,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-05-26T16:13:54.223Z","etag":null,"topics":["inflection","ruby","rubygem","strings"],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/piotrmurach.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null},"funding":{"github":"piotrmurach"}},"created_at":"2019-11-16T20:55:53.000Z","updated_at":"2023-09-30T14:29:39.000Z","dependencies_parsed_at":"2022-08-13T07:20:11.944Z","dependency_job_id":"35b83f6e-00af-4696-aee3-f216b7317361","html_url":"https://github.com/piotrmurach/strings-inflection","commit_stats":{"total_commits":92,"total_committers":2,"mean_commits":46.0,"dds":"0.010869565217391353","last_synced_commit":"e91ecc65ade5761a80b62bebe93012cc4d3caf2f"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/piotrmurach/strings-inflection","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piotrmurach%2Fstrings-inflection","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piotrmurach%2Fstrings-inflection/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piotrmurach%2Fstrings-inflection/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piotrmurach%2Fstrings-inflection/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/piotrmurach","download_url":"https://codeload.github.com/piotrmurach/strings-inflection/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piotrmurach%2Fstrings-inflection/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259470951,"owners_count":22862999,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["inflection","ruby","rubygem","strings"],"created_at":"2024-08-06T08:02:28.513Z","updated_at":"2025-06-12T13:09:25.948Z","avatar_url":"https://github.com/piotrmurach.png","language":"Ruby","readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg width=\"225\" src=\"https://github.com/piotrmurach/strings/blob/master/assets/strings_logo.png\" alt=\"strings logo\" /\u003e\n\u003c/div\u003e\n\n# Strings::Inflection\n\n[![Gem Version](https://badge.fury.io/rb/strings-inflection.svg)][gem]\n[![Actions CI](https://github.com/piotrmurach/strings-inflection/actions/workflows/ci.yml/badge.svg)][gh_actions_ci]\n[![Build status](https://ci.appveyor.com/api/projects/status/huj82599jbk2quv2?svg=true)][appveyor]\n[![Maintainability](https://api.codeclimate.com/v1/badges/f7ecb5bf87696e522ccb/maintainability)][codeclimate]\n[![Coverage Status](https://coveralls.io/repos/github/piotrmurach/strings-inflection/badge.svg?branch=master)][coverage]\n\n[gem]: http://badge.fury.io/rb/strings-inflection\n[gh_actions_ci]: https://github.com/piotrmurach/strings-inflection/actions/workflows/ci.yml\n[appveyor]: https://ci.appveyor.com/project/piotrmurach/strings-inflection\n[codeclimate]: https://codeclimate.com/github/piotrmurach/strings-inflection/maintainability\n[coverage]: https://coveralls.io/github/piotrmurach/strings-inflection?branch=master\n\n\u003e Inflects English nouns and verbs.\n\n**Strings::Inflection** provides English inflections of nouns and verbs component for [Strings](https://github.com/piotrmurach/strings).\n\n## Motivation\n\nThe goal is to provide a comprehensive way to inflect most nouns and verbs in English. The algorithms that this gem uses are based on the analysis of 7,000 most frequently used nouns and 6,000 most used verbs in English language. Because of this you will get correct inflections for most words:\n\n```ruby\nStrings::Inflection.pluralize(\"cod\") # =\u003e \"cod\"\nStrings::Inflection.pluralize(\"codex\") # =\u003e \"codices\"\nStrings::Inflection.pluralize(\"criterion\") # =\u003e \"criteria\"\nStrings::Inflection.pluralize(\"vertebra\") # =\u003e \"vertebrae\"\n```\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'strings-inflection'\n```\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install strings-inflection\n\n## Contents\n\n* [1. Usage](#1-usage)\n* [2. API](#2-api)\n  * [2.1 inflect](#21-inflect)\n    * [2.1.1 template](#211-template)\n  * [2.2 singularize](#22-singularize)\n  * [2.3 singular?](#23-singular)\n  * [2.4 pluralize](#24-pluralize)\n  * [2.5 plural?](#25-plural)\n  * [2.6 join_words](#26-join_words)\n  * [2.7 configure](#27-configure)\n* [3. Extending String class](#3-extending-string-class)\n\n## 1. Usage\n\n**Strings::Inflection** provides a generic `inflect` method for transforming noun or verb inflections. In the most common case, it assumes that you wish to transform a noun to another form based on count:\n\n```ruby\nStrings::Inflection.inflect(\"error\", 3)\n# =\u003e \"errors\"\n```\n\nAs a shortcut, when you wish to always convert a word to singular form use `singularize` or `pluralize` for the opposite:\n\n```ruby\nStrings::Inflection.singularize(\"errors\") # =\u003e \"error\"\nStrings::Inflection.pluralize(\"error\") # =\u003e \"errors\"\nStrings::Inflection.singularize(\"try\", term: :verb) # =\u003e \"tries\"\nStrings::Inflection.pluralize(\"tries\", term: :verb) # =\u003e \"try\"\n```\n\nAlternatively, you can convert words into a noun or verb object. This way you gain access to `singular`and `plural` methods:\n\n```ruby\nStrings::Inflection::Noun(\"errors\").singular # =\u003e \"error\"\nStrings::Inflection::Noun(\"error\").plural # =\u003e \"errors\"\nStrings::Inflection::Verb(\"try\").singular # =\u003e \"tries\"\nStrings::Inflection::Verb(\"tries\").plural # =\u003e \"try\"\n```\n\nThe `inflect` method also accepts a mustache-like template to inflect more complex phrases and sentences:\n\n```ruby\nStrings::Inflection.inflect(\"{{#:count}} {{N:error}} {{V:was}} found\", 3)\n# =\u003e \"3 errors were found\"\n```\n\nTo change any inflection rules, you can change them using `configure`. By default the rules only apply to nouns.\n\n```ruby\nStrings::Inflection.configure do |config|\n  config.plural \"index\", \"indexes\"\n  config.singular \"axes\", \"ax\"\nend\n```\n\nThen the inflection will behave like this:\n\n```ruby\nStrings::Inflection.pluralize(\"index\") # =\u003e \"indexes\"\nStrings::Inflection.singularize(\"axes\") # =\u003e \"ax\"\n```\n\n## 2. API\n\n### 2.1 inflect\n\nIn the most common case, to change a noun's inflection use `inflect` method with the word and a count. By default `inflect` assumes a noun.\n\nFor example, to inflect the noun `error` to its plural form do:\n\n```ruby\nStrings::Inflection.inflect(\"error\", 2) # =\u003e \"errors\"\n```\n\nAnd to inflect a verb, use the `:term` option:\n\n```ruby\nStrings::Inflection.inflect(\"tries\", 2, term: :verb) # =\u003e \"try\"\n```\n\nFor more complex cases when you want to inflect parts of a sentence, the `inflect` provides tags in a template.\n\nFor example, you can inflect a noun and a verb to display information based on the count:\n\n```ruby\nStrings::Inflection.inflect(\"{{#:count}} {{N:error}} {{V:was}} found\", 2)\n# =\u003e \"2 errors were found\"\n```\n\n#### 2.1.1 template\n\nThe template inflects any content inside mustache-like braces `{{...}}`. The general form of content inside tag is `{{Xmod:word}}` where:\n\n* `X` informs a grammatical function to apply to word out of `N` or `V` and `#`.\n* `mod` apply zero or more modifiers to word transformation.\n* `word` represents the string to inflect.\n\nThe available tags are:\n\n`{{#: count }}`\n\nThe first type of tag is the count tag. By default, this tag will display the count inside the evaluated string.\n\n```ruby\nString::Inflection.inflect(\"{{#:count}} found\", 2)\n# =\u003e \"2 found\"\n```\n\nThere is an `f` option that will provide a fuzzy estimation of the count:\n\n```ruby\nString::Inflection.inflect(\"{{#f:count}}\", 0) # =\u003e \"no\"\nString::Inflection.inflect(\"{{#f:count}}\", 1) # =\u003e \"one\"\nString::Inflection.inflect(\"{{#f:count}}\", 2) # =\u003e \"a couple of\"\nString::Inflection.inflect(\"{{#f:count}}\", 3) # =\u003e \"a few\"\nString::Inflection.inflect(\"{{#f:count}}\", 6) # =\u003e \"several\"\nString::Inflection.inflect(\"{{#f:count}}\", 12) # =\u003e \"many\"\n```\n\n`{{N: word }}`\n\nThis tag inflects a noun into a singular or plural form based on the provided count.\n\n```ruby\nStrings::Inflection.inflect(\"{{#:count}} {{N:error}} found\", 3)\n# =\u003e \"3 errors found\"\n```\n\nYou can supply `s` or `p` options to always force a noun to be singular or plural form.\n\n```ruby\nStrings::Inflection.inflect(\"{{#:count}} {{Ns:error}} found\", 3)\n# =\u003e \"3 error found\"\n```\n\n`{{V: word }}`\n\nThis tag inflects a verb into appropriate form based on the provided count.\n\n```ruby\nStrings::Inflection.inflect(\"There {{V:were}} {{#:count}} {{N:match}} found\", 1)\n# =\u003e \"There was 1 match found\"\n```\n\n### 2.2 singularize\n\nYou can transform a noun or a verb into singular form with `singularize` method. By default it assumes a noun but you can change this with `:term` option:\n\n```ruby\nStrings::Inflection.singularize(\"errors\") # =\u003e \"error\"\nStrings::Inflection.singularize(\"indices\") # =\u003e \"index\"\nStrings::Inflection.singularize(\"index\", term: :verb) # =\u003e \"indexes\"\nStrings::Inflection.singularize(\"try\", term: :verb) # =\u003e \"tries\"\n```\n\nIt will handle inflecting irregular nouns or verbs as well:\n\n```ruby\nStrings::Inflection.singularize(\"feet\") # =\u003e \"foot\"\nStrings::Inflection.singularize(\"are\", term: :verb) # =\u003e \"is\"\nStrings::Inflection.singularize(\"go\", term: :verb) # =\u003e \"goes\"\n```\n\nThis method won't change inflection if it already is in the correct form:\n\n```ruby\nStrings::Inflection.singularize(\"index\") # =\u003e \"index\"\nStrings::Inflection.singularize(\"sees\") # =\u003e \"sees\"\n```\n\n### 2.3 singular?\n\nTo check if a noun or a verb is in a singular form use `singular?`:\n\n```ruby\nStrings::Inflection.singular?(\"errors\") # =\u003e false\nStrings::Inflection.singular?(\"index\") # =\u003e true\nStrings::Inflection.singular?(\"try\", term: :verb) # =\u003e false\nStrings::Inflection.singular?(\"goes\", term: :verb) # =\u003e true\n```\n\nYou can also convert a word to a noun or verb object:\n\n```ruby\nStrings::Inflection::Noun(\"errors\").singular? # =\u003e false\nStrings::Inflection::Noun(\"index\").singular? # =\u003e true\nStrings::Inflection::Verb(\"try\").singular? # =\u003e false\nStrings::Inflection::Verb(\"goes\").singular? # =\u003e true\n```\n\n### 2.4 pluralize\n\nYou can transform a noun or a verb into plural form with `pluralize` method. By default it assumes a noun but you can change this with `:term` option:\n\n```ruby\nStrings::Inflection.pluralize(\"error\") # =\u003e \"errors\"\nStrings::Inflection.pluralize(\"index\") # =\u003e \"indices\"\nStrings::Inflection.pluralize(\"indexes\", term: :verb) # =\u003e \"index\"\nStrings::Inflection.pluralize(\"tries\", term: :verb) # =\u003e \"try\"\n```\n\nIt will handle inflecting irregular nouns or verbs as well:\n\n```ruby\nStrings::Inflection.pluralize(\"foot\") # =\u003e \"feet\"\nStrings::Inflection.pluralize(\"is\", term: :verb) # =\u003e \"are\"\nStrings::Inflection.pluralize(\"goes\", term: :verb) # =\u003e \"go\"\n```\n\nThis method won't change inflection if it already is in the correct form:\n\n```ruby\nStrings::Inflection.pluralize(\"indices\") # =\u003e \"indices\"\nStrings::Inflection.pluralize(\"go\") # =\u003e \"go\"\n```\n\n### 2.5 plural?\n\nTo check if a noun or a verb is in a plural form use `plural?`:\n\n```ruby\nStrings::Inflection.plural?(\"errors\") # =\u003e true\nStrings::Inflection.plural?(\"index\") # =\u003e false\nStrings::Inflection.plural?(\"try\", term: :verb) # =\u003e true\nStrings::Inflection.plural?(\"goes\", term: :verb) # =\u003e false\n```\n\nYou can also convert a word to a noun or verb object:\n\n```ruby\nStrings::Inflection::Noun(\"errors\").plural? # =\u003e true\nStrings::Inflection::Noun(\"index\").plural? # =\u003e false\nStrings::Inflection::Verb(\"try\").plural? # =\u003e true\nStrings::Inflection::Verb(\"goes\").plural? # =\u003e false\n```\n\n### 2.6 join_words\n\nTo join an array of words into a single sentence use `join_words` method.\n\nFor example, to join three words:\n\n```ruby\nStrings::Inflection.join_words(\"one\", \"two\", \"three\")\n# =\u003e \"one, two, and three\"\n```\n\nTo join words without Oxford style comma use `:final_separator`:\n\n```ruby\nStrings::Inflection.join_words(\"one\", \"two\", \"three\", final_separator: \"\")\n# =\u003e \"one, two and three\"\n```\n\nTo join words with custom separators:\n\n```ruby\noptions = {\n  separator: \" or \",\n  final_separator: \" or at least \",\n  conjunctive: \"\"\n}\nStrings::Inflection.join_words(\"one\", \"two\", \"three\", **options)\n# =\u003e \"one or two or at least three\"\n```\n\nYou can also use noun objects to join words. We could do the above:\n\n```ruby\nN = Strings::Inflection::Noun\n(N(\"one\") + \"two\" + \"three\").join_words\n# =\u003e \"one, two, and three\"\n```\n\n### 2.7 configure\n\nTo change any inflection rules use `configure` with a block. By default the rules only apply to nouns.\n\nInside the block, the configuration exposes few methods:\n\n* `plural` - add plural form inflection rule\n* `singular` - add singular form inflection rule\n* `rule` - add singular and plural form inflection rule\n* `uncountable` - add uncountable nouns\n\nFor example, to add new plural and singular rules for the `index` and `ax` nouns do:\n\n```ruby\nStrings::Inflection.configure do |config|\n  config.plural \"index\", \"indexes\"\n  config.singular \"axes\", \"ax\"\nend\n```\n\nTo add a rule for both singular and plural inflections do:\n\n```ruby\nStrings::Inflection.configure do |config|\n  config.rule \"ax\", \"axes\"\nend\n```\n\nTo add an uncountable noun do:\n\n```ruby\nStrings::Inflection.configure do |config|\n  config.uncountable \"east\", \"earnings\"\nend\n```\n\nNow, no inflection will be applied:\n\n```ruby\nStrings::Inflection.inflect(\"earnings\", 1) # =\u003e \"earnings\"\nStrings::Inflection.inflect(\"east\", 2) # =\u003e \"east\"\n```\n\n## 3. Extending String class\n\nThough it is highly discouraged to pollute core Ruby classes, you can add the required methods to `String` class by using refinements.\n\nFor example, if you wish to only extend strings with `inflect` method do:\n\n```ruby\nmodule MyStringExt\n  refine String do\n    def inflect(*args, **options)\n      Strings::Inflection.inflect(self, *args, **options)\n    end\n  end\nend\n```\n\nThen `inflect` method will be available for any strings where refinement is applied:\n\n```ruby\nusing MyStringExt\n\n\"error\".inflect(2) # =\u003e \"errors\"\n\"are\".inflect(1, term: :verb) # =\u003e \"is\"\n```\n\nHowever, if you want to include all the **Strings::Inflection** methods, you can use provided extensions file:\n\n```ruby\nrequire \"strings/inflection/extensions\"\n\nusing Strings::Inflection::Extensions\n```\n\n## Development\n\nAfter checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.\n\nTo install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/piotrmurach/strings-inflect. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n\n## Code of Conduct\n\nEveryone interacting in the Strings::Inflection project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/piotrmurach/strings-inflect/blob/master/CODE_OF_CONDUCT.md).\n\n## Copyright\n\nCopyright (c) 2019 Piotr Murach. See LICENSE for further details.\n","funding_links":["https://github.com/sponsors/piotrmurach"],"categories":["Ruby"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpiotrmurach%2Fstrings-inflection","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpiotrmurach%2Fstrings-inflection","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpiotrmurach%2Fstrings-inflection/lists"}