1 ! Copyright (C) 2015 John Benediktsson
2 ! See http://factorcode.org/license.txt for BSD license
3 USING: assocs assocs.extras combinators formatting kernel literals
4 locals math math.parser sequences splitting unicode ;
11 ! Irregular pluralizations
12 CONSTANT: singular-to-plural H{
15 { "alumnus" "alumni" }
19 { "nucleus" "nuclei" }
21 { "stimulus" "stimuli" }
24 { "analysis" "analyses" }
28 { "diagnosis" "diagnoses" }
29 { "ellipsis" "ellipses" }
30 { "hypothesis" "hypotheses" }
32 { "paralysis" "paralyses" }
33 { "parenthesis" "parentheses" }
34 { "synopsis" "synopses" }
35 { "synthesis" "syntheses" }
39 { "appendix" "appendices" }
41 { "matrix" "matrices" }
45 { "bureau" "bureaus" }
46 { "tableau" "tableaux" }
49 { "child" "children" }
55 { "bacterium" "bacteria" }
56 { "corpus" "corpora" }
57 { "criterion" "criteria" }
58 { "curriculum" "curricula" }
62 { "memorandum" "memoranda" }
63 { "phenomenon" "phenomena" }
64 { "stratum" "strata" }
72 { "offspring" "offspring" }
75 { "species" "species" }
84 { "antenna" "antennae" }
85 { "formula" "formulae" }
86 { "nebula" "nebulae" }
87 { "vertebra" "vertebrae" }
96 CONSTANT: plural-to-singular $[ singular-to-plural assoc-invert ]
98 :: match-case ( master disciple -- master' )
100 { [ master >lower master = ] [ disciple >lower ] }
101 { [ master >upper master = ] [ disciple >upper ] }
102 { [ master >title master = ] [ disciple >title ] }
108 : singularize ( word -- singular )
110 { [ dup empty? ] [ ] }
111 { [ dup singular-to-plural key? ] [ ] }
112 { [ plural-to-singular ?at ] [ ] }
113 { [ dup "s" tail? not ] [ ] }
117 last "aeiou" member? not
119 ] [ 3 head* "y" append ]
121 { [ dup "es" tail? ] [ 2 head* ] }
125 : pluralize ( word -- plural )
127 { [ dup empty? ] [ ] }
128 { [ dup plural-to-singular key? ] [ ] }
129 { [ singular-to-plural ?at ] [ ] }
133 last "aeiou" member? not
135 ] [ but-last "ies" append ]
138 [ dup { "s" "ch" "sh" } [ tail? ] with any? ]
139 [ dup "es" tail? [ "es" append ] unless ]
144 : count-of-things ( count word -- str )
145 over 1 = [ pluralize ] unless "%d %s" sprintf ;
147 : a10n ( str -- str' )
149 [ 1 head ] [ length 2 - number>string ] [ 1 tail* ] tri