...
1
2 package english
3
4 import (
5 "fmt"
6 "strings"
7
8 humanize "github.com/dustin/go-humanize"
9 )
10
11
12 var specialPlurals = map[string]string{
13 "index": "indices",
14 "matrix": "matrices",
15 "vertex": "vertices",
16 }
17
18 var sibilantEndings = []string{"s", "sh", "tch", "x"}
19
20 var isVowel = map[byte]bool{
21 'A': true, 'E': true, 'I': true, 'O': true, 'U': true,
22 'a': true, 'e': true, 'i': true, 'o': true, 'u': true,
23 }
24
25
26
27
28
29 func PluralWord(quantity int, singular, plural string) string {
30 if quantity == 1 {
31 return singular
32 }
33 if plural != "" {
34 return plural
35 }
36 if plural = specialPlurals[singular]; plural != "" {
37 return plural
38 }
39
40
41
42
43
44
45
46 for _, ending := range sibilantEndings {
47 if strings.HasSuffix(singular, ending) {
48 return singular + "es"
49 }
50 }
51 l := len(singular)
52 if l >= 2 && singular[l-1] == 'o' && !isVowel[singular[l-2]] {
53 return singular + "es"
54 }
55 if l >= 2 && singular[l-1] == 'y' && !isVowel[singular[l-2]] {
56 return singular[:l-1] + "ies"
57 }
58
59 return singular + "s"
60 }
61
62
63
64
65 func Plural(quantity int, singular, plural string) string {
66 return fmt.Sprintf("%s %s", humanize.Comma(int64(quantity)), PluralWord(quantity, singular, plural))
67 }
68
69
70
71
72 func WordSeries(words []string, conjunction string) string {
73 switch len(words) {
74 case 0:
75 return ""
76 case 1:
77 return words[0]
78 default:
79 return fmt.Sprintf("%s %s %s", strings.Join(words[:len(words)-1], ", "), conjunction, words[len(words)-1])
80 }
81 }
82
83
84
85
86
87 func OxfordWordSeries(words []string, conjunction string) string {
88 switch len(words) {
89 case 0:
90 return ""
91 case 1:
92 return words[0]
93 case 2:
94 return strings.Join(words, fmt.Sprintf(" %s ", conjunction))
95 default:
96 return fmt.Sprintf("%s, %s %s", strings.Join(words[:len(words)-1], ", "), conjunction, words[len(words)-1])
97 }
98 }
99
View as plain text