Documentation
¶
Overview ¶
Package plural provides simple support for localising plurals in a flexible range of different styles.
There are considerable differences around the world in the way plurals are handled. This is a simple but competent API for catering with these differences when presenting formatted text with numbers to people.
This package is able to format countable things and continuous values. It can handle integers and floating point numbers equally and this allows you to decide to what extent each is appropriate.
For example, "2 cars" (countable) might weigh "1.6 tonnes" (continuous); both categories are covered.
This API is deliberately simple; it doesn't address the full gamut of internationalisation. If that's what you need, you might consider products such as https://pkg.go.dev/github.com/nicksnyder/go-i18n/v2/i18n instead.
This package is not intended to format negative quantities. Such values may be better handled as physical values, e.g. using https://pkg.go.dev/periph.io/x/conn/v3/physic.
Please see the examples and associated api documentation.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var AddS = func(noun string) string { return noun + "s" }
AddS is a pluggable function that appends "s" to a noun. This is used by Regular. Replace this with whatever your own language needs.
var Zero = func(noun string) string { return "no " + noun + "s" }
Zero is a pluggable function that prepends "no " and appends "s" to a noun. This is used by Regular. Replace this with whatever your own language needs.
Functions ¶
This section is empty.
Types ¶
type Cases ¶
type Cases struct {
// contains filtered or unexported fields
}
Cases provides a list of plural cases in the order they will be searched. The cases must be listed in ascending number order. They are contiguous (i.e. without gaps) and monotonic (i.e. always rising).
func ByOrdinal ¶
ByOrdinal is an alias for FromZero.
Example ¶
package main
import (
"fmt"
"github.com/rickb777/plural/v2"
)
func main() {
// ByOrdinal is easy to use for any collection of counting phrases, even with nouns that have irregular
// plurals. In this case, "lolly" and "lollies" are used.
//
// ByOrdinal creates Cases that hold a sequence of cardinal cases where the
// first matching case is used. Otherwise, if there's no match, the last one is used.
var lollyPlurals = plural.ByOrdinal("no ice lollies", "1 ice lolly", "%v ice lollies")
for d := 0; d < 4; d++ {
s := lollyPlurals.Countable(d)
fmt.Println(s)
}
}
Output: no ice lollies 1 ice lolly 2 ice lollies 3 ice lollies
func FromOne ¶
FromOne constructs a simple set of cases using small positive numbers (1, 2, 3 etc), which is a common requirement. The last case will be used for all subsequent numbers. Any cases may include a fmt.Sprintf number placeholder, Usually, this will be %v, which will support the countable and continuous cases effectively.
For example
plural.FromOne("%v cat", "%v cats")
plural.FromOne("one", "two", "many")
can then be used via Cases.Countable or Cases.Continuous to produce descriptive formatted values.
Note the behaviour of formatting when the count is zero. As a consequence of Cases.Countable evaluating its cases in ascending order, FromOne(...).Countable(0) will return a blank string. If this might arise, use FromZero instead.
Example ¶
package main
import (
"fmt"
"github.com/rickb777/plural/v2"
)
func main() {
// FromOne creates Cases that hold a sequence of cardinal cases where the
// first matching case is used. Otherwise, if there's no match, the last one is used.
//
// Often, the last case will include a "%d", "%g" or "%v" placeholder for the number,
// but placeholders are not mandatory in any of the cases.
// mugPlurals and volumePlurals provide English formatted cases for some number of mugs and their volume.
var mugPlurals = plural.FromOne("%d mug holds", "%d mugs hold")
// Note %g, %f etc should be chosen appropriately
var volumePlurals = plural.FromOne("%g litre", "%g litres")
for d := 1; d < 6; d++ {
s := mugPlurals.Countable(d)
w := volumePlurals.Continuous(float64(d) * 0.25)
fmt.Println(s, w)
}
}
Output: 1 mug holds 0.25 litre 2 mugs hold 0.5 litre 3 mugs hold 0.75 litre 4 mugs hold 1 litre 5 mugs hold 1.25 litres
func FromZero ¶
FromZero constructs a simple set of cases using small ordinals (0, 1, 2, 3 etc), which is a common requirement. The last case will be used for all subsequent numbers. Any cases may include a fmt.Sprintf number placeholder, Usually, this will be %v, which will support the countable and continuous cases effectively.
For example
plural.FromZero("nothing", "%v caddy", "%v caddies")
plural.FromZero("none", "one", "two", "many")
can then be used via Cases.Countable or Cases.Continuous to produce descriptive formatted values.
Example ¶
package main
import (
"fmt"
"github.com/rickb777/plural/v2"
)
func main() {
// FromZero creates Cases that hold a sequence of cardinal cases where the
// first matching case is used. Otherwise, if there's no match, the last one is used.
//
// Often, the last case will include a "%d", "%g" or "%v" placeholder for the number,
// but placeholders are not mandatory in any of the cases.
//
// ByOrdinal could be used instead of FromZero (they are aliases);
// it builds simple common kinds of plurals using small ordinals (0, 1, 2, 3 etc).
// bikePlurals and weightPlurals provide English formatted cases for some number of bikes and their weight.
var bikePlurals = plural.FromZero("no bikes weigh", "%d bike weighs", "%d bikes weigh")
var weightPlurals = plural.FromZero("nothing", "%1.1f tonne", "%1.1f tonnes")
for d := 0; d < 5; d++ {
s := bikePlurals.Countable(d)
w := weightPlurals.Continuous(float64(d) * 0.5)
fmt.Println(s, w)
}
}
Output: no bikes weigh nothing 1 bike weighs 0.5 tonne 2 bikes weigh 1.0 tonne 3 bikes weigh 1.5 tonnes 4 bikes weigh 2.0 tonnes
func Irregular ¶ added in v2.1.0
Irregular returns plurals for irregular nouns typical in English such as words like "caddy" ("caddies"), for which noun has a singular and a plural form but the plural form is irregular.
It uses FromOne, passing the singular noun for the unit case, and the plural noun for all counts above one. This allows irregular nouns to be pluralised with little effort.
For example
plural.Irregular("caddy", "caddies")
can then be used via Cases.Countable or Cases.Continuous to produce descriptive formatted values.
Like Regular, Irregular is too simplistic for phrases instead of nouns and for any language that uses more than two variants; for these, FromZero or FromOne will be more appropriate.
Both Irregular(s, p).Countable(0) and FromOne(...).Countable(0) will return a blank string for zero. If this might arise, use FromZero instead.
Example ¶
package main
import (
"fmt"
"github.com/rickb777/plural/v2"
)
func main() {
// Irregular is similar to Regular, but differs by catering for the case of nouns that have different
// forms in the singular and in the plural.
var lollyPlurals = plural.Irregular("lolly", "lollies")
for d := 1; d < 4; d++ {
s := lollyPlurals.Countable(d)
fmt.Println(s)
}
}
Output: 1 lolly 2 lollies 3 lollies
func Regular ¶
Regular returns plurals for regular nouns typical in English such as words like "cat", "tree", for which the plural form is simply by adding letter 's'.
It uses FromZero, passing the noun with Zero for the zero case, the noun itself for the unit case, and with AddS for all counts above one. This allows the many easy regular nouns to be pluralised with little effort.
For example
plural.Regular("thing")
can then be used via Cases.Countable or Cases.Continuous to produce descriptive formatted values.
Irregular nouns such as "caddy" should not use this function (unless "caddys" really is the plural form you want). Instead, use Irregular, FromZero or FromOne.
Also, Regular is too simplistic for phrases instead of nouns; for these, FromZero or FromOne will be more appropriate.
Example ¶
package main
import (
"fmt"
"github.com/rickb777/plural/v2"
)
func main() {
// Regular caters for the common simple case of a noun that is easy to pluralise, e.g. by appending "s".
// It uses the Zero and AddS functions, which can be altered if required.
var catPlurals = plural.Regular("cat")
for d := 0; d < 4; d++ {
s := catPlurals.Countable(d)
fmt.Println(s)
}
}
Output: no cats 1 cat 2 cats 3 cats
func (Cases) Continuous ¶
Continuous expresses a continuous number in plural form. If no match is found, the last case will be used. It is recommended that any case placeholders should be the %v general value, but floating point placeholders such as %f or %g may be used instead.
Integer placeholders such as %d will render incorrectly and should not be used. Negative values are not supported.
func (Cases) Countable ¶
Countable expresses a countable number in plural form. If no match is found, the last case will be used. It is recommended that any case placeholders should be the %v general value, but integer placeholders such as %d may be used instead.
Floating point placeholders such as %f or %g will render incorrectly and should not be used. Negative values are not supported.