mirror of https://github.com/knative/pkg.git
Bump github.com/gobuffalo/flect from 0.2.4 to 1.0.2 (#2786)
* Bump github.com/gobuffalo/flect from 0.2.4 to 1.0.2 Bumps [github.com/gobuffalo/flect](https://github.com/gobuffalo/flect) from 0.2.4 to 1.0.2. - [Release notes](https://github.com/gobuffalo/flect/releases) - [Commits](https://github.com/gobuffalo/flect/compare/v0.2.4...v1.0.2) --- updated-dependencies: - dependency-name: github.com/gobuffalo/flect dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * Run ./hack/update-codegen.sh --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
parent
936112b9f8
commit
ea6c1f29b6
2
go.mod
2
go.mod
|
|
@ -13,7 +13,7 @@ require (
|
|||
github.com/census-instrumentation/opencensus-proto v0.4.1
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/evanphx/json-patch/v5 v5.6.0
|
||||
github.com/gobuffalo/flect v0.2.4
|
||||
github.com/gobuffalo/flect v1.0.2
|
||||
github.com/golang/protobuf v1.5.3
|
||||
github.com/google/go-cmp v0.5.9
|
||||
github.com/google/go-github/v27 v27.0.6
|
||||
|
|
|
|||
4
go.sum
4
go.sum
|
|
@ -143,8 +143,8 @@ github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyr
|
|||
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/gobuffalo/flect v0.2.4 h1:BSYA8+T60cdyq+vynaSUjqSVI9mDEg9ZfQUXKmfjo4I=
|
||||
github.com/gobuffalo/flect v0.2.4/go.mod h1:1ZyCLIbg0YD7sDkzvFdPoOydPtD8y9JQnrOROolUcM8=
|
||||
github.com/gobuffalo/flect v1.0.2 h1:eqjPGSo2WmjgY2XlpGwo2NXgL3RucAKo4k4qQMNA5sA=
|
||||
github.com/gobuffalo/flect v1.0.2/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs=
|
||||
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
|
|
|
|||
|
|
@ -1,25 +1,53 @@
|
|||
# Flect
|
||||
|
||||
<p align="center">
|
||||
<a href="https://godoc.org/github.com/gobuffalo/flect"><img src="https://godoc.org/github.com/gobuffalo/flect?status.svg" alt="GoDoc" /></a>
|
||||
<a href="https://dev.azure.com/markbates/buffalo/_build/latest?definitionId=51&branchName=master"><img src="https://dev.azure.com/markbates/buffalo/_apis/build/status/gobuffalo.flect?branchName=master" alt="CI" /></a>
|
||||
<a href="https://goreportcard.com/report/github.com/gobuffalo/flect"><img src="https://goreportcard.com/badge/github.com/gobuffalo/flect" alt="Go Report Card" /></a>
|
||||
</p>
|
||||
[](https://pkg.go.dev/github.com/gobuffalo/flect)
|
||||
[](https://github.com/gobuffalo/flect/actions/workflows/standard-go-test.yml)
|
||||
[](https://goreportcard.com/report/github.com/gobuffalo/flect)
|
||||
|
||||
This is a new inflection engine to replace [https://github.com/markbates/inflect](https://github.com/markbates/inflect) designed to be more modular, more readable, and easier to fix issues on than the original.
|
||||
|
||||
Flect provides word inflection features such as `Singularize` and `Pluralize`
|
||||
for English nouns and text utility features such as `Camelize`, `Capitalize`,
|
||||
`Humanize`, and more.
|
||||
|
||||
Due to the flexibly-complex nature of English noun inflection, it is almost
|
||||
impossible to cover all exceptions (such as identical/irregular plural).
|
||||
With this reason along with the main purpose of Flect, which is to make it
|
||||
easy to develop web application in Go, Flect has limitations with its own
|
||||
rules.
|
||||
|
||||
* It covers regular rule (adding -s or -es and of the word)
|
||||
* It covers well-known irregular rules (such as -is to -es, -f to -ves, etc)
|
||||
* https://en.wiktionary.org/wiki/Appendix:English_irregular_nouns#Rules
|
||||
* It covers well-known irregular words (such as children, men, etc)
|
||||
* If a word can be countable and uncountable like milk or time, it will be
|
||||
treated as countable.
|
||||
* If a word has more than one plural forms, which means it has at least one
|
||||
irregular plural, we tried to find most popular one. (The selected plural
|
||||
could be odd to you, please feel free to open an issue with back data)
|
||||
* For example, we selected "stadiums" over "stadia", "dwarfs" over "dwarves"
|
||||
* One or combination of en.wiktionary.org, britannica.com, and
|
||||
trends.google.com are used to check the recent usage trends.
|
||||
* However, we cannot cover all cases and some of our cases could not fit with
|
||||
your situation. You can override the default with functions such as
|
||||
`InsertPlural()`, `InsertSingular()`, or `LoadInfrections()`.
|
||||
* If you have a json file named `inflections.json` in your application root,
|
||||
the file will be automatically loaded as your custom inflection dictionary.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
$ go get -u -v github.com/gobuffalo/flect
|
||||
```console
|
||||
$ go get github.com/gobuffalo/flect
|
||||
```
|
||||
|
||||
## `github.com/gobuffalo/flect`
|
||||
<a href="https://godoc.org/github.com/gobuffalo/flect"><img src="https://godoc.org/github.com/gobuffalo/flect?status.svg" alt="GoDoc" /></a>
|
||||
|
||||
## Packages
|
||||
|
||||
### `github.com/gobuffalo/flect`
|
||||
|
||||
The `github.com/gobuffalo/flect` package contains "basic" inflection tools, like pluralization, singularization, etc...
|
||||
|
||||
### The `Ident` Type
|
||||
#### The `Ident` Type
|
||||
|
||||
In addition to helpful methods that take in a `string` and return a `string`, there is an `Ident` type that can be used to create new, custom, inflection rules.
|
||||
|
||||
|
|
@ -30,7 +58,6 @@ The `Ident` type contains two fields.
|
|||
|
||||
Examples of creating new inflection rules using `Ident` can be found in the `github.com/gobuffalo/flect/name` package.
|
||||
|
||||
## `github.com/gobuffalo/flect/name`
|
||||
<a href="https://godoc.org/github.com/gobuffalo/flect/name"><img src="https://godoc.org/github.com/gobuffalo/flect/name?status.svg" alt="GoDoc" /></a>
|
||||
### `github.com/gobuffalo/flect/name`
|
||||
|
||||
The `github.com/gobuffalo/flect/name` package contains more "business" inflection rules like creating proper names, table names, etc...
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
# github.com/gobuffalo/flect Stands on the Shoulders of Giants
|
||||
# Flect Stands on the Shoulders of Giants
|
||||
|
||||
github.com/gobuffalo/flect does not try to reinvent the wheel! Instead, it uses the already great wheels developed by the Go community and puts them all together in the best way possible. Without these giants, this project would not be possible. Please make sure to check them out and thank them for all of their hard work.
|
||||
Flect does not try to reinvent the wheel! Instead, it uses the already great wheels developed by the Go community and puts them all together in the best way possible. Without these giants, this project would not be possible. Please make sure to check them out and thank them for all of their hard work.
|
||||
|
||||
Thank you to the following **GIANTS**:
|
||||
|
||||
|
||||
* [github.com/davecgh/go-spew](https://godoc.org/github.com/davecgh/go-spew)
|
||||
|
||||
* [github.com/pmezard/go-difflib](https://godoc.org/github.com/pmezard/go-difflib)
|
||||
* [github.com/stretchr/objx](https://godoc.org/github.com/stretchr/objx)
|
||||
* [github.com/stretchr/testify](https://godoc.org/github.com/stretchr/testify)
|
||||
* [gopkg.in/check.v1](https://godoc.org/gopkg.in/check.v1)
|
||||
* [gopkg.in/yaml.v3](https://godoc.org/gopkg.in/yaml.v3)
|
||||
|
|
|
|||
|
|
@ -22,10 +22,6 @@ func (i Ident) Camelize() Ident {
|
|||
for i, part := range i.Parts {
|
||||
var x string
|
||||
var capped bool
|
||||
if strings.ToLower(part) == "id" {
|
||||
out = append(out, "ID")
|
||||
continue
|
||||
}
|
||||
for _, c := range part {
|
||||
if unicode.IsLetter(c) || unicode.IsDigit(c) {
|
||||
if i == 0 {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
|
@ -75,6 +76,10 @@ func LoadInflections(r io.Reader) error {
|
|||
defer singularMoot.Unlock()
|
||||
|
||||
for s, p := range m {
|
||||
if strings.Contains(s, " ") || strings.Contains(p, " ") {
|
||||
// flect works with parts, so multi-words should not be allowed
|
||||
return fmt.Errorf("inflection elements should be a single word")
|
||||
}
|
||||
singleToPlural[s] = p
|
||||
pluralToSingle[p] = s
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,13 +22,9 @@ func (i Ident) Humanize() Ident {
|
|||
return New("")
|
||||
}
|
||||
|
||||
var parts []string
|
||||
for index, part := range i.Parts {
|
||||
if index == 0 {
|
||||
part = strings.Title(i.Parts[0])
|
||||
}
|
||||
|
||||
parts = xappend(parts, part)
|
||||
parts := xappend([]string{}, Titleize(i.Parts[0]))
|
||||
if len(i.Parts) > 1 {
|
||||
parts = xappend(parts, i.Parts[1:]...)
|
||||
}
|
||||
|
||||
return New(strings.Join(parts, " "))
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package flect
|
||||
|
||||
import (
|
||||
"unicode"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Pascalize returns a string with each segment capitalized
|
||||
|
|
@ -21,5 +21,12 @@ func (i Ident) Pascalize() Ident {
|
|||
if len(c.String()) == 0 {
|
||||
return c
|
||||
}
|
||||
return New(string(unicode.ToUpper(rune(c.Original[0]))) + c.Original[1:])
|
||||
if len(i.Parts) == 0 {
|
||||
return i
|
||||
}
|
||||
capLen := 1
|
||||
if _, ok := baseAcronyms[strings.ToUpper(i.Parts[0])]; ok {
|
||||
capLen = len(i.Parts[0])
|
||||
}
|
||||
return New(string(strings.ToUpper(c.Original[0:capLen])) + c.Original[capLen:])
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,153 +1,255 @@
|
|||
package flect
|
||||
|
||||
import "fmt"
|
||||
|
||||
var pluralRules = []rule{}
|
||||
|
||||
// AddPlural adds a rule that will replace the given suffix with the replacement suffix.
|
||||
// The name is confusing. This function will be deprecated in the next release.
|
||||
func AddPlural(suffix string, repl string) {
|
||||
InsertPluralRule(suffix, repl)
|
||||
}
|
||||
|
||||
// InsertPluralRule inserts a rule that will replace the given suffix with
|
||||
// the repl(acement) at the begining of the list of the pluralize rules.
|
||||
func InsertPluralRule(suffix, repl string) {
|
||||
pluralMoot.Lock()
|
||||
defer pluralMoot.Unlock()
|
||||
pluralRules = append(pluralRules, rule{
|
||||
suffix: suffix,
|
||||
fn: func(s string) string {
|
||||
s = s[:len(s)-len(suffix)]
|
||||
return s + repl
|
||||
},
|
||||
})
|
||||
|
||||
pluralRules = append(pluralRules, rule{
|
||||
pluralRules = append([]rule{{
|
||||
suffix: suffix,
|
||||
fn: simpleRuleFunc(suffix, repl),
|
||||
}}, pluralRules...)
|
||||
|
||||
pluralRules = append([]rule{{
|
||||
suffix: repl,
|
||||
fn: noop,
|
||||
})
|
||||
}}, pluralRules...)
|
||||
}
|
||||
|
||||
var singleToPlural = map[string]string{
|
||||
"aircraft": "aircraft",
|
||||
"alias": "aliases",
|
||||
"alumna": "alumnae",
|
||||
"alumnus": "alumni",
|
||||
"analysis": "analyses",
|
||||
"antenna": "antennas",
|
||||
"antithesis": "antitheses",
|
||||
"apex": "apexes",
|
||||
"appendix": "appendices",
|
||||
"axis": "axes",
|
||||
"bacillus": "bacilli",
|
||||
"bacterium": "bacteria",
|
||||
"basis": "bases",
|
||||
"beau": "beaus",
|
||||
"bison": "bison",
|
||||
"bureau": "bureaus",
|
||||
"bus": "buses",
|
||||
"campus": "campuses",
|
||||
"caucus": "caucuses",
|
||||
"child": "children",
|
||||
"château": "châteaux",
|
||||
"circus": "circuses",
|
||||
"codex": "codices",
|
||||
"concerto": "concertos",
|
||||
"corpus": "corpora",
|
||||
"crisis": "crises",
|
||||
"curriculum": "curriculums",
|
||||
"datum": "data",
|
||||
"deer": "deer",
|
||||
"diagnosis": "diagnoses",
|
||||
"die": "dice",
|
||||
"dwarf": "dwarves",
|
||||
"ellipsis": "ellipses",
|
||||
"equipment": "equipment",
|
||||
"erratum": "errata",
|
||||
"faux pas": "faux pas",
|
||||
"fez": "fezzes",
|
||||
"fish": "fish",
|
||||
"focus": "foci",
|
||||
"foo": "foos",
|
||||
"foot": "feet",
|
||||
"formula": "formulas",
|
||||
"fungus": "fungi",
|
||||
"genus": "genera",
|
||||
"goose": "geese",
|
||||
"graffito": "graffiti",
|
||||
"grouse": "grouse",
|
||||
"half": "halves",
|
||||
"halo": "halos",
|
||||
"hoof": "hooves",
|
||||
"human": "humans",
|
||||
"hypothesis": "hypotheses",
|
||||
"index": "indices",
|
||||
"information": "information",
|
||||
"jeans": "jeans",
|
||||
"larva": "larvae",
|
||||
"libretto": "librettos",
|
||||
"loaf": "loaves",
|
||||
"locus": "loci",
|
||||
"louse": "lice",
|
||||
"matrix": "matrices",
|
||||
"minutia": "minutiae",
|
||||
"money": "money",
|
||||
"moose": "moose",
|
||||
"mouse": "mice",
|
||||
"nebula": "nebulae",
|
||||
"news": "news",
|
||||
"nucleus": "nuclei",
|
||||
"oasis": "oases",
|
||||
"octopus": "octopi",
|
||||
"offspring": "offspring",
|
||||
"opus": "opera",
|
||||
"ovum": "ova",
|
||||
"ox": "oxen",
|
||||
"parenthesis": "parentheses",
|
||||
"phenomenon": "phenomena",
|
||||
"photo": "photos",
|
||||
"phylum": "phyla",
|
||||
"piano": "pianos",
|
||||
"plus": "pluses",
|
||||
"police": "police",
|
||||
"prognosis": "prognoses",
|
||||
"prometheus": "prometheuses",
|
||||
"quiz": "quizzes",
|
||||
"quota": "quotas",
|
||||
"radius": "radiuses",
|
||||
"referendum": "referendums",
|
||||
"ress": "resses",
|
||||
"rice": "rice",
|
||||
"salmon": "salmon",
|
||||
"sex": "sexes",
|
||||
"series": "series",
|
||||
"sheep": "sheep",
|
||||
"shoe": "shoes",
|
||||
"shrimp": "shrimp",
|
||||
"species": "species",
|
||||
"stimulus": "stimuli",
|
||||
"stratum": "strata",
|
||||
"swine": "swine",
|
||||
"syllabus": "syllabi",
|
||||
"symposium": "symposiums",
|
||||
"synapse": "synapses",
|
||||
"synopsis": "synopses",
|
||||
"tableau": "tableaus",
|
||||
"testis": "testes",
|
||||
"thesis": "theses",
|
||||
"thief": "thieves",
|
||||
"tooth": "teeth",
|
||||
"trout": "trout",
|
||||
"tuna": "tuna",
|
||||
"vedalia": "vedalias",
|
||||
"vertebra": "vertebrae",
|
||||
"vertix": "vertices",
|
||||
"vita": "vitae",
|
||||
"vortex": "vortices",
|
||||
"wharf": "wharves",
|
||||
"wife": "wives",
|
||||
"woman": "women",
|
||||
"wolf": "wolves",
|
||||
"you": "you",
|
||||
type word struct {
|
||||
singular string
|
||||
plural string
|
||||
alternative string
|
||||
unidirectional bool // plural to singular is not possible (or bad)
|
||||
uncountable bool
|
||||
exact bool
|
||||
}
|
||||
|
||||
// dictionary is the main table for singularize and pluralize.
|
||||
// All words in the dictionary will be added to singleToPlural, pluralToSingle
|
||||
// and singlePluralAssertions by init() functions.
|
||||
var dictionary = []word{
|
||||
// identicals https://en.wikipedia.org/wiki/English_plurals#Nouns_with_identical_singular_and_plural
|
||||
{singular: "aircraft", plural: "aircraft"},
|
||||
{singular: "beef", plural: "beef", alternative: "beefs"},
|
||||
{singular: "bison", plural: "bison"},
|
||||
{singular: "blues", plural: "blues", unidirectional: true},
|
||||
{singular: "chassis", plural: "chassis"},
|
||||
{singular: "deer", plural: "deer"},
|
||||
{singular: "fish", plural: "fish", alternative: "fishes"},
|
||||
{singular: "moose", plural: "moose"},
|
||||
{singular: "police", plural: "police"},
|
||||
{singular: "salmon", plural: "salmon", alternative: "salmons"},
|
||||
{singular: "series", plural: "series"},
|
||||
{singular: "sheep", plural: "sheep"},
|
||||
{singular: "shrimp", plural: "shrimp", alternative: "shrimps"},
|
||||
{singular: "species", plural: "species"},
|
||||
{singular: "swine", plural: "swine", alternative: "swines"},
|
||||
{singular: "trout", plural: "trout", alternative: "trouts"},
|
||||
{singular: "tuna", plural: "tuna", alternative: "tunas"},
|
||||
{singular: "you", plural: "you"},
|
||||
// -en https://en.wikipedia.org/wiki/English_plurals#Plurals_in_-(e)n
|
||||
{singular: "child", plural: "children"},
|
||||
{singular: "ox", plural: "oxen", exact: true},
|
||||
// apophonic https://en.wikipedia.org/wiki/English_plurals#Apophonic_plurals
|
||||
{singular: "foot", plural: "feet"},
|
||||
{singular: "goose", plural: "geese"},
|
||||
{singular: "man", plural: "men"},
|
||||
{singular: "human", plural: "humans"}, // not humen
|
||||
{singular: "louse", plural: "lice", exact: true},
|
||||
{singular: "mouse", plural: "mice"},
|
||||
{singular: "tooth", plural: "teeth"},
|
||||
{singular: "woman", plural: "women"},
|
||||
// misc https://en.wikipedia.org/wiki/English_plurals#Miscellaneous_irregular_plurals
|
||||
{singular: "die", plural: "dice", exact: true},
|
||||
{singular: "person", plural: "people"},
|
||||
|
||||
// Words from French that end in -u add an x; in addition to eau to eaux rule
|
||||
{singular: "adieu", plural: "adieux", alternative: "adieus"},
|
||||
{singular: "fabliau", plural: "fabliaux"},
|
||||
{singular: "bureau", plural: "bureaus", alternative: "bureaux"}, // popular
|
||||
|
||||
// Words from Greek that end in -on change -on to -a; in addition to hedron rule
|
||||
{singular: "criterion", plural: "criteria"},
|
||||
{singular: "ganglion", plural: "ganglia", alternative: "ganglions"},
|
||||
{singular: "lexicon", plural: "lexica", alternative: "lexicons"},
|
||||
{singular: "mitochondrion", plural: "mitochondria", alternative: "mitochondrions"},
|
||||
{singular: "noumenon", plural: "noumena"},
|
||||
{singular: "phenomenon", plural: "phenomena"},
|
||||
{singular: "taxon", plural: "taxa"},
|
||||
|
||||
// Words from Latin that end in -um change -um to -a; in addition to some rules
|
||||
{singular: "media", plural: "media"}, // popular case: media -> media
|
||||
{singular: "medium", plural: "media", alternative: "mediums", unidirectional: true},
|
||||
{singular: "stadium", plural: "stadiums", alternative: "stadia"},
|
||||
{singular: "aquarium", plural: "aquaria", alternative: "aquariums"},
|
||||
{singular: "auditorium", plural: "auditoria", alternative: "auditoriums"},
|
||||
{singular: "symposium", plural: "symposia", alternative: "symposiums"},
|
||||
{singular: "curriculum", plural: "curriculums", alternative: "curricula"}, // ulum
|
||||
{singular: "quota", plural: "quotas"},
|
||||
|
||||
// Words from Latin that end in -us change -us to -i or -era
|
||||
{singular: "alumnus", plural: "alumni", alternative: "alumnuses"}, // -i
|
||||
{singular: "bacillus", plural: "bacilli"},
|
||||
{singular: "cactus", plural: "cacti", alternative: "cactuses"},
|
||||
{singular: "coccus", plural: "cocci"},
|
||||
{singular: "focus", plural: "foci", alternative: "focuses"},
|
||||
{singular: "locus", plural: "loci", alternative: "locuses"},
|
||||
{singular: "nucleus", plural: "nuclei", alternative: "nucleuses"},
|
||||
{singular: "octopus", plural: "octupuses", alternative: "octopi"},
|
||||
{singular: "radius", plural: "radii", alternative: "radiuses"},
|
||||
{singular: "syllabus", plural: "syllabi"},
|
||||
{singular: "corpus", plural: "corpora", alternative: "corpuses"}, // -ra
|
||||
{singular: "genus", plural: "genera"},
|
||||
|
||||
// Words from Latin that end in -a change -a to -ae
|
||||
{singular: "alumna", plural: "alumnae"},
|
||||
{singular: "vertebra", plural: "vertebrae"},
|
||||
{singular: "differentia", plural: "differentiae"}, // -tia
|
||||
{singular: "minutia", plural: "minutiae"},
|
||||
{singular: "vita", plural: "vitae"}, // -ita
|
||||
{singular: "larva", plural: "larvae"}, // -va
|
||||
{singular: "postcava", plural: "postcavae"},
|
||||
{singular: "praecava", plural: "praecavae"},
|
||||
{singular: "uva", plural: "uvae"},
|
||||
|
||||
// Words from Latin that end in -ex change -ex to -ices
|
||||
{singular: "apex", plural: "apices", alternative: "apexes"},
|
||||
{singular: "codex", plural: "codices", alternative: "codexes"},
|
||||
{singular: "index", plural: "indices", alternative: "indexes"},
|
||||
{singular: "latex", plural: "latices", alternative: "latexes"},
|
||||
{singular: "vertex", plural: "vertices", alternative: "vertexes"},
|
||||
{singular: "vortex", plural: "vortices", alternative: "vortexes"},
|
||||
|
||||
// Words from Latin that end in -ix change -ix to -ices (eg, matrix becomes matrices)
|
||||
{singular: "appendix", plural: "appendices", alternative: "appendixes"},
|
||||
{singular: "radix", plural: "radices", alternative: "radixes"},
|
||||
{singular: "helix", plural: "helices", alternative: "helixes"},
|
||||
|
||||
// Words from Latin that end in -is change -is to -es
|
||||
{singular: "axis", plural: "axes", exact: true},
|
||||
{singular: "crisis", plural: "crises"},
|
||||
{singular: "ellipsis", plural: "ellipses", unidirectional: true}, // ellipse
|
||||
{singular: "genesis", plural: "geneses"},
|
||||
{singular: "oasis", plural: "oases"},
|
||||
{singular: "thesis", plural: "theses"},
|
||||
{singular: "testis", plural: "testes"},
|
||||
{singular: "base", plural: "bases"}, // popular case
|
||||
{singular: "basis", plural: "bases", unidirectional: true},
|
||||
|
||||
{singular: "alias", plural: "aliases", exact: true}, // no alia, no aliasis
|
||||
{singular: "vedalia", plural: "vedalias"}, // no vedalium, no vedaliases
|
||||
|
||||
// Words that end in -ch, -o, -s, -sh, -x, -z (can be conflict with the others)
|
||||
{singular: "use", plural: "uses", exact: true}, // us vs use
|
||||
{singular: "abuse", plural: "abuses"},
|
||||
{singular: "cause", plural: "causes"},
|
||||
{singular: "clause", plural: "clauses"},
|
||||
{singular: "cruse", plural: "cruses"},
|
||||
{singular: "excuse", plural: "excuses"},
|
||||
{singular: "fuse", plural: "fuses"},
|
||||
{singular: "house", plural: "houses"},
|
||||
{singular: "misuse", plural: "misuses"},
|
||||
{singular: "muse", plural: "muses"},
|
||||
{singular: "pause", plural: "pauses"},
|
||||
{singular: "ache", plural: "aches"},
|
||||
{singular: "topaz", plural: "topazes"},
|
||||
{singular: "buffalo", plural: "buffaloes", alternative: "buffalos"},
|
||||
{singular: "potato", plural: "potatoes"},
|
||||
{singular: "tomato", plural: "tomatoes"},
|
||||
|
||||
// uncountables
|
||||
{singular: "equipment", uncountable: true},
|
||||
{singular: "information", uncountable: true},
|
||||
{singular: "jeans", uncountable: true},
|
||||
{singular: "money", uncountable: true},
|
||||
{singular: "news", uncountable: true},
|
||||
{singular: "rice", uncountable: true},
|
||||
|
||||
// exceptions: -f to -ves, not -fe
|
||||
{singular: "dwarf", plural: "dwarfs", alternative: "dwarves"},
|
||||
{singular: "hoof", plural: "hoofs", alternative: "hooves"},
|
||||
{singular: "thief", plural: "thieves"},
|
||||
// exceptions: instead of -f(e) to -ves
|
||||
{singular: "chive", plural: "chives"},
|
||||
{singular: "hive", plural: "hives"},
|
||||
{singular: "move", plural: "moves"},
|
||||
|
||||
// exceptions: instead of -y to -ies
|
||||
{singular: "movie", plural: "movies"},
|
||||
{singular: "cookie", plural: "cookies"},
|
||||
|
||||
// exceptions: instead of -um to -a
|
||||
{singular: "pretorium", plural: "pretoriums"},
|
||||
{singular: "agenda", plural: "agendas"}, // instead of plural of agendum
|
||||
// exceptions: instead of -um to -a (chemical element names)
|
||||
|
||||
// Words from Latin that end in -a change -a to -ae
|
||||
{singular: "formula", plural: "formulas", alternative: "formulae"}, // also -um/-a
|
||||
|
||||
// exceptions: instead of -o to -oes
|
||||
{singular: "shoe", plural: "shoes"},
|
||||
{singular: "toe", plural: "toes", exact: true},
|
||||
{singular: "graffiti", plural: "graffiti"},
|
||||
|
||||
// abbreviations
|
||||
{singular: "ID", plural: "IDs", exact: true},
|
||||
}
|
||||
|
||||
// singleToPlural is the highest priority map for Pluralize().
|
||||
// singularToPluralSuffixList is used to build pluralRules for suffixes and
|
||||
// compound words.
|
||||
var singleToPlural = map[string]string{}
|
||||
|
||||
// pluralToSingle is the highest priority map for Singularize().
|
||||
// singularToPluralSuffixList is used to build singularRules for suffixes and
|
||||
// compound words.
|
||||
var pluralToSingle = map[string]string{}
|
||||
|
||||
// NOTE: This map should not be built as reverse map of singleToPlural since
|
||||
// there are words that has the same plurals.
|
||||
|
||||
// build singleToPlural and pluralToSingle with dictionary
|
||||
func init() {
|
||||
for k, v := range singleToPlural {
|
||||
pluralToSingle[v] = k
|
||||
for _, wd := range dictionary {
|
||||
if singleToPlural[wd.singular] != "" {
|
||||
panic(fmt.Errorf("map singleToPlural already has an entry for %s", wd.singular))
|
||||
}
|
||||
|
||||
if wd.uncountable && wd.plural == "" {
|
||||
wd.plural = wd.singular
|
||||
}
|
||||
|
||||
if wd.plural == "" {
|
||||
panic(fmt.Errorf("plural for %s is not provided", wd.singular))
|
||||
}
|
||||
|
||||
singleToPlural[wd.singular] = wd.plural
|
||||
|
||||
if !wd.unidirectional {
|
||||
if pluralToSingle[wd.plural] != "" {
|
||||
panic(fmt.Errorf("map pluralToSingle already has an entry for %s", wd.plural))
|
||||
}
|
||||
pluralToSingle[wd.plural] = wd.singular
|
||||
|
||||
if wd.alternative != "" {
|
||||
if pluralToSingle[wd.alternative] != "" {
|
||||
panic(fmt.Errorf("map pluralToSingle already has an entry for %s", wd.alternative))
|
||||
}
|
||||
pluralToSingle[wd.alternative] = wd.singular
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -156,133 +258,160 @@ type singularToPluralSuffix struct {
|
|||
plural string
|
||||
}
|
||||
|
||||
// singularToPluralSuffixList is a list of "bidirectional" suffix rules for
|
||||
// the irregular plurals follow such rules.
|
||||
//
|
||||
// NOTE: IMPORTANT! The order of items in this list is the rule priority, not
|
||||
// alphabet order. The first match will be used to inflect.
|
||||
var singularToPluralSuffixList = []singularToPluralSuffix{
|
||||
{"iterion", "iteria"},
|
||||
{"campus", "campuses"},
|
||||
{"genera", "genus"},
|
||||
{"person", "people"},
|
||||
{"phylum", "phyla"},
|
||||
{"randum", "randa"},
|
||||
{"actus", "acti"},
|
||||
{"adium", "adia"},
|
||||
{"basis", "basis"},
|
||||
{"child", "children"},
|
||||
{"chive", "chives"},
|
||||
{"focus", "foci"},
|
||||
{"hello", "hellos"},
|
||||
{"jeans", "jeans"},
|
||||
{"louse", "lice"},
|
||||
{"media", "media"},
|
||||
{"mouse", "mice"},
|
||||
{"movie", "movies"},
|
||||
{"oasis", "oasis"},
|
||||
{"atum", "ata"},
|
||||
{"atus", "atuses"},
|
||||
{"base", "bases"},
|
||||
{"cess", "cesses"},
|
||||
{"dium", "diums"},
|
||||
{"eses", "esis"},
|
||||
{"half", "halves"},
|
||||
{"hive", "hives"},
|
||||
{"iano", "ianos"},
|
||||
{"irus", "iri"},
|
||||
{"isis", "ises"},
|
||||
{"leus", "li"},
|
||||
{"mnus", "mni"},
|
||||
{"move", "moves"},
|
||||
{"news", "news"},
|
||||
{"odex", "odice"},
|
||||
{"oose", "eese"},
|
||||
{"ouse", "ouses"},
|
||||
{"ovum", "ova"},
|
||||
{"rion", "ria"},
|
||||
{"shoe", "shoes"},
|
||||
{"stis", "stes"},
|
||||
{"tive", "tives"},
|
||||
{"vice", "vices"},
|
||||
{"wife", "wives"},
|
||||
{"afe", "aves"},
|
||||
{"bfe", "bves"},
|
||||
{"box", "boxes"},
|
||||
{"cfe", "cves"},
|
||||
{"dfe", "dves"},
|
||||
{"dge", "dges"},
|
||||
{"efe", "eves"},
|
||||
{"gfe", "gves"},
|
||||
{"hfe", "hves"},
|
||||
{"ife", "ives"},
|
||||
{"itz", "itzes"},
|
||||
{"ium", "ia"},
|
||||
{"ize", "izes"},
|
||||
{"jfe", "jves"},
|
||||
{"kfe", "kves"},
|
||||
{"man", "men"},
|
||||
{"mfe", "mves"},
|
||||
{"nfe", "nves"},
|
||||
{"nna", "nnas"},
|
||||
// https://en.wiktionary.org/wiki/Appendix:English_irregular_nouns#Rules
|
||||
// Words that end in -f or -fe change -f or -fe to -ves
|
||||
{"tive", "tives"}, // exception
|
||||
{"eaf", "eaves"},
|
||||
{"oaf", "oaves"},
|
||||
{"oci", "ocus"},
|
||||
{"ode", "odes"},
|
||||
{"ofe", "oves"},
|
||||
{"oot", "eet"},
|
||||
{"pfe", "pves"},
|
||||
{"pse", "psis"},
|
||||
{"qfe", "qves"},
|
||||
{"quy", "quies"},
|
||||
{"afe", "aves"},
|
||||
{"arf", "arves"},
|
||||
{"rfe", "rves"},
|
||||
{"sfe", "sves"},
|
||||
{"tfe", "tves"},
|
||||
{"tum", "ta"},
|
||||
{"tus", "tuses"},
|
||||
{"ufe", "uves"},
|
||||
{"ula", "ulae"},
|
||||
{"ula", "ulas"},
|
||||
{"uli", "ulus"},
|
||||
{"use", "uses"},
|
||||
{"uss", "usses"},
|
||||
{"vfe", "vves"},
|
||||
{"wfe", "wves"},
|
||||
{"xfe", "xves"},
|
||||
{"yfe", "yves"},
|
||||
{"you", "you"},
|
||||
{"zfe", "zves"},
|
||||
{"by", "bies"},
|
||||
{"ch", "ches"},
|
||||
{"cy", "cies"},
|
||||
{"dy", "dies"},
|
||||
{"ex", "ices"},
|
||||
{"fy", "fies"},
|
||||
{"gy", "gies"},
|
||||
{"hy", "hies"},
|
||||
{"io", "ios"},
|
||||
{"jy", "jies"},
|
||||
{"ky", "kies"},
|
||||
{"lf", "lves"},
|
||||
{"ly", "lies"},
|
||||
{"my", "mies"},
|
||||
{"ny", "nies"},
|
||||
{"py", "pies"},
|
||||
{"qy", "qies"},
|
||||
{"rf", "rves"},
|
||||
{"ry", "ries"},
|
||||
{"lf", "lves"},
|
||||
{"fe", "ves"}, // previously '[a-eg-km-z]fe' TODO: regex support
|
||||
|
||||
// Words that end in -y preceded by a consonant change -y to -ies
|
||||
{"ay", "ays"},
|
||||
{"ey", "eys"},
|
||||
{"oy", "oys"},
|
||||
{"quy", "quies"},
|
||||
{"uy", "uys"},
|
||||
{"y", "ies"}, // '[^aeiou]y'
|
||||
|
||||
// Words from French that end in -u add an x (eg, château becomes châteaux)
|
||||
{"eau", "eaux"}, // it seems like 'eau' is the most popular form of this rule
|
||||
|
||||
// Words from Latin that end in -a change -a to -ae; before -on to -a and -um to -a
|
||||
{"bula", "bulae"},
|
||||
{"dula", "bulae"},
|
||||
{"lula", "bulae"},
|
||||
{"nula", "bulae"},
|
||||
{"vula", "bulae"},
|
||||
|
||||
// Words from Greek that end in -on change -on to -a (eg, polyhedron becomes polyhedra)
|
||||
// https://en.wiktionary.org/wiki/Category:English_irregular_plurals_ending_in_"-a"
|
||||
{"hedron", "hedra"},
|
||||
|
||||
// Words from Latin that end in -um change -um to -a (eg, minimum becomes minima)
|
||||
// https://en.wiktionary.org/wiki/Category:English_irregular_plurals_ending_in_"-a"
|
||||
{"ium", "ia"}, // some exceptions especially chemical element names
|
||||
{"seum", "seums"},
|
||||
{"eum", "ea"},
|
||||
{"oum", "oa"},
|
||||
{"stracum", "straca"},
|
||||
{"dum", "da"},
|
||||
{"elum", "ela"},
|
||||
{"ilum", "ila"},
|
||||
{"olum", "ola"},
|
||||
{"ulum", "ula"},
|
||||
{"llum", "lla"},
|
||||
{"ylum", "yla"},
|
||||
{"imum", "ima"},
|
||||
{"ernum", "erna"},
|
||||
{"gnum", "gna"},
|
||||
{"brum", "bra"},
|
||||
{"crum", "cra"},
|
||||
{"terum", "tera"},
|
||||
{"serum", "sera"},
|
||||
{"trum", "tra"},
|
||||
{"antum", "anta"},
|
||||
{"atum", "ata"},
|
||||
{"entum", "enta"},
|
||||
{"etum", "eta"},
|
||||
{"itum", "ita"},
|
||||
{"otum", "ota"},
|
||||
{"utum", "uta"},
|
||||
{"ctum", "cta"},
|
||||
{"ovum", "ova"},
|
||||
|
||||
// Words from Latin that end in -us change -us to -i or -era
|
||||
// not easy to make a simple rule. just add them all to the dictionary
|
||||
|
||||
// Words from Latin that end in -ex change -ex to -ices (eg, vortex becomes vortices)
|
||||
// Words from Latin that end in -ix change -ix to -ices (eg, matrix becomes matrices)
|
||||
// for example, -dix, -dex, and -dice will have the same plural form so
|
||||
// making a simple rule is not possible for them
|
||||
{"trix", "trices"}, // ignore a few words end in trice
|
||||
|
||||
// Words from Latin that end in -is change -is to -es (eg, thesis becomes theses)
|
||||
// -sis and -se has the same plural -ses so making a rule is not easy too.
|
||||
{"iasis", "iases"},
|
||||
{"mesis", "meses"},
|
||||
{"kinesis", "kineses"},
|
||||
{"resis", "reses"},
|
||||
{"gnosis", "gnoses"}, // e.g. diagnosis
|
||||
{"opsis", "opses"}, // e.g. synopsis
|
||||
{"ysis", "yses"}, // e.g. analysis
|
||||
|
||||
// Words that end in -ch, -o, -s, -sh, -x, -z
|
||||
{"ouse", "ouses"},
|
||||
{"lause", "lauses"},
|
||||
{"us", "uses"}, // use/uses is in the dictionary
|
||||
|
||||
{"ch", "ches"},
|
||||
{"io", "ios"},
|
||||
{"sh", "shes"},
|
||||
{"ss", "sses"},
|
||||
{"sy", "sies"},
|
||||
{"ty", "ties"},
|
||||
{"ez", "ezzes"},
|
||||
{"iz", "izzes"},
|
||||
{"tz", "tzes"},
|
||||
{"va", "vae"},
|
||||
{"vy", "vies"},
|
||||
{"wy", "wies"},
|
||||
{"xy", "xies"},
|
||||
{"zy", "zies"},
|
||||
{"zz", "zzes"},
|
||||
{"ano", "anos"},
|
||||
{"lo", "los"},
|
||||
{"to", "tos"},
|
||||
{"oo", "oos"},
|
||||
{"o", "oes"},
|
||||
{"x", "xes"},
|
||||
|
||||
// for abbreviations
|
||||
{"S", "Ses"},
|
||||
|
||||
// excluded rules: seems rare
|
||||
// Words from Hebrew that add -im or -ot (eg, cherub becomes cherubim)
|
||||
// - cherub (cherubs or cherubim), seraph (seraphs or seraphim)
|
||||
// Words from Greek that end in -ma change -ma to -mata
|
||||
// - The most of words end in -ma are in this category but it looks like
|
||||
// just adding -s is more popular.
|
||||
// Words from Latin that end in -nx change -nx to -nges
|
||||
// - The most of words end in -nx are in this category but it looks like
|
||||
// just adding -es is more popular. (sphinxes)
|
||||
|
||||
// excluded rules: don't care at least for now:
|
||||
// Words that end in -ful that add an s after the -ful
|
||||
// Words that end in -s or -ese denoting a national of a particular country
|
||||
// Symbols or letters, which often add -'s
|
||||
}
|
||||
|
||||
func init() {
|
||||
for _, suffix := range singularToPluralSuffixList {
|
||||
AddPlural(suffix.singular, suffix.plural)
|
||||
AddSingular(suffix.plural, suffix.singular)
|
||||
for i := len(singularToPluralSuffixList) - 1; i >= 0; i-- {
|
||||
InsertPluralRule(singularToPluralSuffixList[i].singular, singularToPluralSuffixList[i].plural)
|
||||
InsertSingularRule(singularToPluralSuffixList[i].plural, singularToPluralSuffixList[i].singular)
|
||||
}
|
||||
|
||||
// build pluralRule and singularRule with dictionary for compound words
|
||||
for _, wd := range dictionary {
|
||||
if wd.exact {
|
||||
continue
|
||||
}
|
||||
|
||||
if wd.uncountable && wd.plural == "" {
|
||||
wd.plural = wd.singular
|
||||
}
|
||||
|
||||
InsertPluralRule(wd.singular, wd.plural)
|
||||
|
||||
if !wd.unidirectional {
|
||||
InsertSingularRule(wd.plural, wd.singular)
|
||||
|
||||
if wd.alternative != "" {
|
||||
InsertSingularRule(wd.alternative, wd.singular)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,15 +38,28 @@ func (i Ident) Pluralize() Ident {
|
|||
pluralMoot.RLock()
|
||||
defer pluralMoot.RUnlock()
|
||||
|
||||
// check if the Original has an explicit entry in the map
|
||||
if p, ok := singleToPlural[i.Original]; ok {
|
||||
return i.ReplaceSuffix(i.Original, p)
|
||||
}
|
||||
if _, ok := pluralToSingle[i.Original]; ok {
|
||||
return i
|
||||
}
|
||||
|
||||
ls := strings.ToLower(s)
|
||||
if _, ok := pluralToSingle[ls]; ok {
|
||||
return i
|
||||
}
|
||||
|
||||
if p, ok := singleToPlural[ls]; ok {
|
||||
if s == Capitalize(s) {
|
||||
p = Capitalize(p)
|
||||
}
|
||||
return i.ReplaceSuffix(s, p)
|
||||
}
|
||||
|
||||
for _, r := range pluralRules {
|
||||
if strings.HasSuffix(ls, r.suffix) {
|
||||
if strings.HasSuffix(s, r.suffix) {
|
||||
return i.ReplaceSuffix(s, r.fn(s))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,4 +7,11 @@ type rule struct {
|
|||
fn ruleFn
|
||||
}
|
||||
|
||||
func simpleRuleFunc(suffix, repl string) func(string) string {
|
||||
return func(s string) string {
|
||||
s = s[:len(s)-len(suffix)]
|
||||
return s + repl
|
||||
}
|
||||
}
|
||||
|
||||
func noop(s string) string { return s }
|
||||
|
|
|
|||
|
|
@ -3,21 +3,24 @@ package flect
|
|||
var singularRules = []rule{}
|
||||
|
||||
// AddSingular adds a rule that will replace the given suffix with the replacement suffix.
|
||||
// The name is confusing. This function will be deprecated in the next release.
|
||||
func AddSingular(ext string, repl string) {
|
||||
InsertSingularRule(ext, repl)
|
||||
}
|
||||
|
||||
// InsertSingularRule inserts a rule that will replace the given suffix with
|
||||
// the repl(acement) at the beginning of the list of the singularize rules.
|
||||
func InsertSingularRule(suffix, repl string) {
|
||||
singularMoot.Lock()
|
||||
defer singularMoot.Unlock()
|
||||
singularRules = append(singularRules, rule{
|
||||
suffix: ext,
|
||||
fn: func(s string) string {
|
||||
s = s[:len(s)-len(ext)]
|
||||
return s + repl
|
||||
},
|
||||
})
|
||||
|
||||
singularRules = append(singularRules, rule{
|
||||
singularRules = append([]rule{{
|
||||
suffix: suffix,
|
||||
fn: simpleRuleFunc(suffix, repl),
|
||||
}}, singularRules...)
|
||||
|
||||
singularRules = append([]rule{{
|
||||
suffix: repl,
|
||||
fn: func(s string) string {
|
||||
return s
|
||||
},
|
||||
})
|
||||
fn: noop,
|
||||
}}, singularRules...)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,10 +19,7 @@ func Singularize(s string) string {
|
|||
// SingularizeWithSize("user", 1) = user
|
||||
// SingularizeWithSize("user", 2) = users
|
||||
func SingularizeWithSize(s string, i int) string {
|
||||
if i == 1 || i == -1 {
|
||||
return New(s).Singularize().String()
|
||||
}
|
||||
return New(s).Pluralize().String()
|
||||
return PluralizeWithSize(s, i)
|
||||
}
|
||||
|
||||
// Singularize returns a singular version of the string
|
||||
|
|
@ -30,28 +27,43 @@ func SingularizeWithSize(s string, i int) string {
|
|||
// data = datum
|
||||
// people = person
|
||||
func (i Ident) Singularize() Ident {
|
||||
s := i.Original
|
||||
s := i.LastPart()
|
||||
if len(s) == 0 {
|
||||
return i
|
||||
}
|
||||
|
||||
singularMoot.RLock()
|
||||
defer singularMoot.RUnlock()
|
||||
|
||||
// check if the Original has an explicit entry in the map
|
||||
if p, ok := pluralToSingle[i.Original]; ok {
|
||||
return i.ReplaceSuffix(i.Original, p)
|
||||
}
|
||||
if _, ok := singleToPlural[i.Original]; ok {
|
||||
return i
|
||||
}
|
||||
|
||||
ls := strings.ToLower(s)
|
||||
if p, ok := pluralToSingle[ls]; ok {
|
||||
return New(p)
|
||||
if s == Capitalize(s) {
|
||||
p = Capitalize(p)
|
||||
}
|
||||
return i.ReplaceSuffix(s, p)
|
||||
}
|
||||
|
||||
if _, ok := singleToPlural[ls]; ok {
|
||||
return i
|
||||
}
|
||||
|
||||
for _, r := range singularRules {
|
||||
if strings.HasSuffix(ls, r.suffix) {
|
||||
return New(r.fn(s))
|
||||
if strings.HasSuffix(s, r.suffix) {
|
||||
return i.ReplaceSuffix(s, r.fn(s))
|
||||
}
|
||||
}
|
||||
|
||||
if strings.HasSuffix(s, "s") {
|
||||
return New(s[:len(s)-1])
|
||||
return i.ReplaceSuffix("s", "")
|
||||
}
|
||||
|
||||
return i
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,12 +19,20 @@ func Titleize(s string) string {
|
|||
// "This is `code` ok" = "This Is `code` OK"
|
||||
func (i Ident) Titleize() Ident {
|
||||
var parts []string
|
||||
|
||||
// TODO: we need to reconsider the design.
|
||||
// this approach preserves inline code block as is but it also
|
||||
// preserves the other words start with a special character.
|
||||
// I would prefer: "*wonderful* world" to be "*Wonderful* World"
|
||||
for _, part := range i.Parts {
|
||||
x := string(unicode.ToTitle(rune(part[0])))
|
||||
if len(part) > 1 {
|
||||
x += part[1:]
|
||||
// CAUTION: in unicode, []rune(str)[0] is not rune(str[0])
|
||||
runes := []rune(part)
|
||||
x := string(unicode.ToTitle(runes[0]))
|
||||
if len(runes) > 1 {
|
||||
x += string(runes[1:])
|
||||
}
|
||||
parts = append(parts, x)
|
||||
}
|
||||
|
||||
return New(strings.Join(parts, " "))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,17 +6,17 @@ import (
|
|||
)
|
||||
|
||||
// Underscore a string
|
||||
// bob dylan = bob_dylan
|
||||
// Nice to see you! = nice_to_see_you
|
||||
// widgetID = widget_id
|
||||
// bob dylan --> bob_dylan
|
||||
// Nice to see you! --> nice_to_see_you
|
||||
// widgetID --> widget_id
|
||||
func Underscore(s string) string {
|
||||
return New(s).Underscore().String()
|
||||
}
|
||||
|
||||
// Underscore a string
|
||||
// bob dylan = bob_dylan
|
||||
// Nice to see you! = nice_to_see_you
|
||||
// widgetID = widget_id
|
||||
// bob dylan --> bob_dylan
|
||||
// Nice to see you! --> nice_to_see_you
|
||||
// widgetID --> widget_id
|
||||
func (i Ident) Underscore() Ident {
|
||||
out := make([]string, 0, len(i.Parts))
|
||||
for _, part := range i.Parts {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package flect
|
||||
|
||||
//Version holds Flect version number
|
||||
const Version = "v0.1.6"
|
||||
const Version = "v1.0.0"
|
||||
|
|
|
|||
|
|
@ -85,8 +85,8 @@ github.com/go-openapi/jsonreference/internal
|
|||
# github.com/go-openapi/swag v0.19.15
|
||||
## explicit; go 1.11
|
||||
github.com/go-openapi/swag
|
||||
# github.com/gobuffalo/flect v0.2.4
|
||||
## explicit; go 1.13
|
||||
# github.com/gobuffalo/flect v1.0.2
|
||||
## explicit; go 1.16
|
||||
github.com/gobuffalo/flect
|
||||
# github.com/gogo/protobuf v1.3.2
|
||||
## explicit; go 1.15
|
||||
|
|
|
|||
Loading…
Reference in New Issue