1 ! Copyright (C) 2015, 2018 John Benediktsson
2 ! See http://factorcode.org/license.txt for BSD license
3 USING: accessors arrays assocs assocs.extras combinators
4 help.markup kernel literals locals math math.parser sequences
5 sequences.extras splitting unicode words ;
12 ! Irregular pluralizations
13 CONSTANT: singular-to-plural H{
16 { "alumnus" "alumni" }
18 { "octopus" "octopi" }
21 { "nucleus" "nuclei" }
23 { "stimulus" "stimuli" }
26 { "analysis" "analyses" }
30 { "diagnosis" "diagnoses" }
31 { "ellipsis" "ellipses" }
32 { "hypothesis" "hypotheses" }
34 { "paralysis" "paralyses" }
35 { "parenthesis" "parentheses" }
36 { "synopsis" "synopses" }
37 { "synthesis" "syntheses" }
41 { "appendix" "appendices" }
43 { "matrix" "matrices" }
47 { "bureau" "bureaus" }
48 { "tableau" "tableaux" }
51 { "child" "children" }
57 { "bacterium" "bacteria" }
58 { "corpus" "corpora" }
59 { "criterion" "criteria" }
60 { "curriculum" "curricula" }
64 { "memorandum" "memoranda" }
65 { "phenomenon" "phenomena" }
66 { "stratum" "strata" }
74 { "offspring" "offspring" }
77 { "species" "species" }
86 { "antenna" "antennae" }
87 { "formula" "formulae" }
88 { "nebula" "nebulae" }
89 { "vertebra" "vertebrae" }
98 CONSTANT: plural-to-singular $[ singular-to-plural assoc-invert ]
100 :: match-case ( master disciple -- master' )
102 { [ master >lower master = ] [ disciple >lower ] }
103 { [ master >upper master = ] [ disciple >upper ] }
104 { [ master >title master = ] [ disciple >title ] }
110 : singularize ( word -- singular )
112 { [ dup empty? ] [ ] }
113 { [ dup singular-to-plural key? ] [ ] }
114 { [ plural-to-singular ?at ] [ ] }
115 { [ dup "s" tail? not ] [ ] }
119 last "aeiou" member? not
121 ] [ 3 head* "y" append ]
123 { [ dup "es" tail? ] [ 2 head* ] }
127 : pluralize ( word -- plural )
129 { [ dup empty? ] [ ] }
130 { [ dup plural-to-singular key? ] [ ] }
131 { [ singular-to-plural ?at ] [ ] }
135 last "aeiou" member? not
137 ] [ but-last "ies" append ]
140 [ dup { "s" "ch" "sh" } [ tail? ] with any? ]
141 [ dup "es" tail? [ "es" append ] unless ]
146 : singular? ( word -- ? )
147 [ singularize ] [ = ] bi ;
149 : plural? ( word -- ? )
150 [ singularize pluralize ] [ = ] bi ;
152 : ?pluralize ( count singular -- singular/plural )
153 swap 1 = [ pluralize ] unless ;
155 : count-of-things ( count word -- str )
156 dupd ?pluralize [ number>string ] dip " " glue ;
158 : a10n ( word -- numeronym )
160 [ 1 head ] [ length 2 - number>string ] [ 1 tail* ] tri
164 : a/an ( word -- article )
165 [ first ] [ length ] bi 1 = "afhilmnorsx" "aeiou" ?
168 : ?plural-article ( word -- article )
169 dup singular? [ a/an ] [ drop "the" ] if ;
171 : comma-list ( parts conjunction -- clause-seq )
172 [ ", " join-with ] dip over length dup 3 >= [
173 [ 3 > ", " " " ? " " surround ] [ 2 - pick set-nth ] bi
176 : or-markup-example ( classes -- markup )
179 [ name>> ] keep \ $link
182 ] if swap 2array [ a/an " " append ] dip 2array
183 ] map "or" comma-list ;
185 : $or-markup-example ( classes -- )
186 or-markup-example print-element ;