inflect

package module
v0.0.0-...-9a42f43 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 16, 2026 License: MIT Imports: 2 Imported by: 0

README

inflect

A Go library for English word pluralization and singularization, inspired by Rails ActiveRecord's inflector — the kind of smart pluralization that ORM frameworks use for automatic table naming.

Note on Django: Django's built-in auto-pluralization is intentionally primitive — it simply appends "s" to every model name (Person → Persons, Category → Categorys). Developers are expected to override verbose_name_plural manually for anything irregular. This library does what Django doesn't: full English morphology rules so you rarely need to override anything.

Zero dependencies. No reflect. No regexp. Pure stdlib.


Features

Rule class Examples
Irregular words child → children, man → men, foot → feet
Latin/Greek -is analysis → analyses, thesis → theses
Latin -um → -a datum → data, medium → media, curriculum → curricula
Greek -on → -a criterion → criteria, phenomenon → phenomena
Latin -us → -i alumnus → alumni, cactus → cacti, focus → foci
Latin -ex/-ix → -ices index → indices, matrix → matrices, vertex → vertices
Sibilants (-s,-x,-z,-ch,-sh) status → statuses, box → boxes, church → churches
Consonant + -y → -ies category → categories, query → queries
Vowel + -y → -s day → days, key → keys, monkey → monkeys
-fe → -ves knife → knives, wife → wives
-f → -ves leaf → leaves, wolf → wolves
-o endings tomato → tomatoes, video → videos
Uncountables sheep, fish, information, equipment (unchanged)
Default model → models, user → users

Additional utilities:

  • Case preservationCategory → Categories, STATUS → STATUSES
  • Singularize — reverse of all rules above
  • TableName — PascalCase struct name → snake_case plural (GORM/Django convention)
  • PluralizeIf — count-aware form, mirrors Django's {% pluralize %} tag
  • IsPlural / IsSingular — heuristic detection

Install

go get codeberg.org/anarproject/inflect

Usage

import "codeberg.org/anarproject/inflect"

// Pluralize
inflect.Pluralize("category")    // "categories"
inflect.Pluralize("analysis")    // "analyses"
inflect.Pluralize("criterion")   // "criteria"
inflect.Pluralize("status")      // "statuses"
inflect.Pluralize("person")      // "people"
inflect.Pluralize("sheep")       // "sheep"  (uncountable)

// Case preserved
inflect.Pluralize("Category")    // "Categories"
inflect.Pluralize("STATUS")      // "STATUSES"

// Count-aware (Django {% pluralize %} equivalent)
inflect.Pluralize("item", 1)     // "item"
inflect.Pluralize("item", 0)     // "items"
inflect.Pluralize("item", 5)     // "items"

// PluralizeIf — same thing, explicit API
fmt.Sprintf("%d %s", n, inflect.PluralizeIf("category", n))

// Singularize
inflect.Singularize("categories") // "category"
inflect.Singularize("analyses")   // "analysis"
inflect.Singularize("criteria")   // "criterion"
inflect.Singularize("Statuses")   // "Status"

// ORM table name: PascalCase → snake_case plural
inflect.TableName("UserProfile")  // "user_profiles"
inflect.TableName("BlogPost")     // "blog_posts"
inflect.TableName("Category")     // "categories"
inflect.TableName("Analysis")     // "analyses"

// Detection
inflect.IsPlural("models")    // true
inflect.IsSingular("model")   // true
inflect.IsPlural("sheep")     // true  (uncountable = both)

GORM integration

type Category struct {
    gorm.Model
    Name string
}

func (Category) TableName() string {
    return inflect.TableName("Category") // "categories"
}

Rule priority

Pluralize applies rules in this order — first match wins:

  1. Uncountable → return as-is
  2. Irregular lookup (O(1) map)
  3. -is-es
  4. Sibilant suffixes (-s,-x,-z,-ch,-sh) → -es
  5. Consonant+-y-ies; vowel+-y-s
  6. -fe-ves
  7. -f (non-regular) → -ves
  8. -o endings
  9. Default → -s

Singularize applies rules in reverse order with the same irregular table.


Running tests

go test ./... -v

All 100+ sub-tests pass, including:

  • Irregular, Latin/Greek, sibilant, consonant-y, -o, -f/-fe, uncountable
  • Case preservation (lower / Title / UPPER)
  • Full round-trip: word → plural → singular == word
  • TableName for 9 PascalCase struct names
  • PluralizeIf count boundary (0, 1, 2, 5)
  • Edge cases (empty string)

Comparison with Django and Rails

Framework Auto-pluralization How
Django Dumb — appends "s" only Person → Persons, Category → Categorys
Rails ActiveRecord Smart — full inflector Person → People, Category → Categories
inflect (this library) Smart — full inflector Same as Rails

Django developers work around this by setting verbose_name_plural manually in every model's Meta class. This library gives Go projects the Rails-style inflector Django never shipped.


License

MIT

Documentation

Overview

Package inflect provides English word pluralization and singularization, modeled after Django's ORM model-name pluralization engine.

It handles irregular words, classical Latin/Greek forms, suffix-based rules (sibilants, consonant+y, -fe/-f, -o endings), and uncountable words — with full Unicode-safe case preservation.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsPlural

func IsPlural(word string) bool

IsPlural returns true if word appears to be in plural form. This is a heuristic, not a morphological parser.

func IsSingular

func IsSingular(word string) bool

IsSingular returns true if word appears to be in singular form.

func Pluralize

func Pluralize(word string, count ...int) string

Pluralize returns the English plural of word. Case is preserved: "model" → "models", "Model" → "Models", "MODEL" → "MODELS". If count is provided and equals 1, the original word is returned unchanged.

inflect.Pluralize("category")  // "categories"
inflect.Pluralize("Analysis")  // "Analyses"
inflect.Pluralize("STATUS")    // "STATUSES"

func PluralizeIf

func PluralizeIf(word string, count int) string

PluralizeIf returns the plural if count != 1, otherwise singular. Mirrors Django's {% pluralize %} template tag behaviour.

fmt.Sprintf("%d %s", n, inflect.PluralizeIf("item", n))

func Singularize

func Singularize(word string) string

Singularize returns the English singular of word. Case is preserved.

inflect.Singularize("categories") // "category"
inflect.Singularize("Analyses")   // "Analysis"

func TableName

func TableName(structName string) string

TableName returns the conventional database table name for a Go struct name: snake_case + plural, matching Django ORM convention.

inflect.TableName("UserProfile")  // "user_profiles"
inflect.TableName("Category")     // "categories"

Types

This section is empty.

Directories

Path Synopsis
Command example demonstrates the inflect library.
Command example demonstrates the inflect library.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL