Squashed commit of the following:

commit 429917d51c569b28d43b64f3b116e6b750e77c72
Author: Cat Stevens <catb0t@protonmail.ch>
Date:   Thu Feb 15 15:54:50 2018 -0500

    fix <PRIVATE> inside ARTICLE: ?!?!

commit b93243511c40ca7fd06120d089ead172df46c8b7
Author: Cat Stevens <catb0t@protonmail.ch>
Date:   Wed Feb 14 18:11:26 2018 -0500

    pluralize definition fix

commit e461c08166f98b974ae0e9075331dd388c1bcb48
Author: Cat Stevens <catb0t@protonmail.ch>
Date:   Wed Feb 14 16:28:05 2018 -0500

    update some words

commit 573ba01d6310d64788d13685dfc46099ffddb01b
Author: Cat Stevens <catb0t@protonmail.ch>
Date:   Wed Feb 14 16:06:42 2018 -0500

    remove a useless comment

commit 7733ade275a904449a3c691f4142329aaf73081e
Author: Cat Stevens <catb0t@protonmail.ch>
Date:   Wed Feb 14 14:30:06 2018 -0500

    extra/help.lint.coverage: update doctests because of new 100% coverage in basis/english

commit 9f89d2f5a261188dbd030b868323e3a0e95fb6c8
Author: Cat Stevens <catb0t@protonmail.ch>
Date:   Tue Feb 13 18:51:33 2018 -0500

    basis/english: new words; full help and test coverage
windows-high-dpi
John Benediktsson 2018-02-15 13:21:27 -08:00
parent 42b37dcc8a
commit f960c51878
8 changed files with 557 additions and 40 deletions

View File

@ -1 +1,2 @@
John Benediktsson
Cat Stevens

View File

@ -0,0 +1,209 @@
! Copyright (C) 2018 Cat Stevens
USING: arrays assocs help.markup help.syntax kernel math multiline
sequences strings ;
IN: english
<PRIVATE
: $0-plurality ( children -- )
drop {
"Due to the unique way in which the English language is structured, the number "
{ $snippet "0" }
" is considered plural; "
{ $snippet "1" }
" is the only singular quantity."
} print-element ;
: $keep-case ( children -- )
drop
"This word attempts to preserve the letter case style of the input." print-element ;
PRIVATE>
ABOUT: "english"
ARTICLE: "english" "English natural language transformations"
"The " { $vocab-link "english" } " vocabulary implements a few simple ways of interacting with text in the English language, for improving generated text."
$nl
"Plural and singular forms:"
{ $subsections plural? pluralize ?pluralize count-of-things singular? singularize }
"Toy grammatical words:"
{ $subsections a/an ?plural-article a10n comma-list-by simple-comma-list }
"An example application:"
{ $subsections or-markup-example $or-markup-example } ;
{ pluralize ?pluralize plural? count-of-things singularize singular? } related-words
{ a/an ?plural-article a10n comma-list-by simple-comma-list $or-markup-example or-markup-example } related-words
HELP: singularize
{ $values { "word" string } { "singular" string } }
{ $description "Determine the singular form of the input English word. If the input is already singular, it is returned unchanged." }
{ $notes $keep-case }
{ $examples
{ $example
"USING: english io ;"
"\"CATS\" singularize print"
"CAT"
}
{ $example
"USING: english io ;"
"\"Octopi\" singularize print"
"Octopus"
}
} ;
HELP: singular?
{ $values { "word" string } { "?" boolean } }
{ $description "Attempt to determine whether the word is in singular form." }
{ $examples
{ $example
"USING: english prettyprint ;"
"\"octopi\" plural? ."
"t"
}
} ;
HELP: pluralize
{ $values { "word" string } { "plural" string } }
{ $description "Determine the plural form of the input English word. If the input is already plural, it " { $emphasis "might" } " be returned unchanged." }
{ $notes { $list { "If the input is already in plural form, an invaid construct such as " { $emphasis "friendses" } " may be generated. This is difficult to avoid due to the unpredictable structure of the English language." } $keep-case } }
{ $examples
{ $example
"USING: english io ;"
"\"CAT\" pluralize print"
"CATS"
}
{ $example
"USING: english io ;"
"\"Octopus\" pluralize print"
"Octopi"
}
} ;
HELP: plural?
{ $values { "word" string } { "?" boolean } }
{ $description "Attempt to determine whether the word is in plural form." }
{ $examples
{ $example
"USING: english prettyprint ;"
"\"octopus\" singular? ."
"t"
}
} ;
HELP: count-of-things
{ $values { "count" number } { "word" string } { "str" string } }
{ $description "Transform a quantity and a word into a construct consisting of the quantity, and the correct plural or singular form of the word. " { $snippet "word" } " is expected to be in singular form." }
{ $notes { $list $keep-case $0-plurality } }
{ $examples
{ $example
"USING: english io ;"
"10 \"baby\" count-of-things print"
"10 babies"
}
{ $example
"USING: english io ;"
"2.5 \"FISH\" count-of-things print"
"2.5 FISH"
}
} ;
HELP: ?pluralize
{ $values { "count" number } { "singular" string } { "singluar/plural" string } }
{ $description "A simpler variant of " { $link count-of-things } " which omits its input value from the output. As with " { $link count-of-things } ", " { $snippet "word" } " is expected to be in singular form." }
{ $notes { $list $keep-case $0-plurality } }
{ $examples
{ $example
"USING: english io ;"
"14 \"criterion\" ?pluralize print"
"criteria"
}
} ;
HELP: a10n
{ $values { "word" string } { "numeronym" string } }
{ $description "Abbreviates a word of more than three characters, by replacing the inner part of the word with the number of omitted letters. The result is an abbreviation (called a " { $emphasis "numeronym" } ") which is pronounced like the original word." }
{ $notes { $list
$keep-case
"When the input is too short, it is returned unchanged."
{ "The name of this word is " { $snippet "abbreviation" } ", abbreviated by its own strategy." }
{ "This style of abbreviation originated with " { $snippet "i18n" } " (the word " { $emphasis "internationalization" } ") in the 1980s." }
} }
{ $examples
{ $example
"USING: english io ;"
"\"dup\" a10n print"
"dup"
}
{ $example
"USING: english io ;"
"\"abbreviationalism\" a10n print"
"a15m"
}
} ;
HELP: a/an
{ $values { "word" string } { "article" { $or-markup-example "\"a\"" "\"an\"" } } }
{ $description "Gives the proper indefinite singular article (" { $emphasis "a" } " or " { $emphasis "an" } ") for the word. For words which begin with a vowel sound, " { $emphasis "an" } " is used, whereas " { $emphasis "a" } " is used for words which begin with a consonant sound." }
{ $notes "The output does not contain the input. The output of this word is always a singular article, regardless of the plurality of the input." }
{ $examples
{ $example
"USING: english kernel combinators sequences io ;"
"\"object\" [ a/an ] keep \" \" glue print"
"an object"
}
} ;
HELP: ?plural-article
{ $values { "word" string } { "article" { $or-markup-example "\"a\"" "\"an\"" "\"the\"" } } }
{ $description "Output the proper article given the plurality and first letter of the input. Unlike " { $link a/an } " this word handles plural inputs by outputting the definite " { $emphasis "\"the\"" } ". If the input is singular as determined by " { $link singular? } " this word operates like " { $link a/an } "." }
{ $notes { $list "English lacks a plural indefinite article, so the plural definite is used here instead." $keep-case $0-plurality } }
{ $examples
{ $example
"USING: english sequences kernel io ;"
"\"cat\" [ ?plural-article ] keep \" \" glue print"
"a cat"
}
{ $example
"USING: english sequences kernel io ;"
"\"cats\" [ ?plural-article ] keep \" \" glue print"
"the cats"
}
} ;
HELP: comma-list-by
{ $values
{ "parts" sequence }
{ "quot" { $quotation ( part index -- newpart ) } }
{ "conjunction" string }
{ "clause-seq" sequence }
}
{ $description "Generate a comma-separated list of things from the result of applying " { $snippet "quot" } " to each element in " { $snippet "parts" } ", emplacing " { $snippet "conjunction" } " before the last " { $snippet "part" } " if there are two or more elements in " { $snippet "parts" } "." }
{ $notes $keep-case }
{ $examples { "See the examples in " { $link $or-markup-example } " and " { $link simple-comma-list } "." } } ;
HELP: simple-comma-list
{ $values { "parts" sequence } { "conjunction" string } { "parts'" sequence } }
{ $description "Punctuate and conjunctionize the input words into a comma-separated list construction." }
{ $examples
{ $example
"USING: english io sequences splitting ;"
"{ \"a cat\" \"a peach\" \"an object\" } \"or\" simple-comma-list [ \"\" join ] map \"\" join print"
"a cat, a peach, or an object"
}
} ;
HELP: or-markup-example
{ $values { "markup" "a sequence of markup elements" } { "classes" "a sequence of words" } }
{ $description "Used to implement " { $link $or-markup-example } " and demonstrate " { $link comma-list-by } "." }
{ $examples { "See the examples in " { $link $or-markup-example } "." } } ;
HELP: $or-markup-example
{ $values { "classes" "a sequence of words" } }
{ $description "An example to demonstrate a use-case for " { $link comma-list-by } ". Works like the " { $link $or } " and " { $link ($instance) } " words from " { $vocab-link "help.markup" } "." }
{ $examples
{ $markup-example
{ $or-markup-example "cat" "octopus" "animal" object pair number array string sequence assoc "bird" } print-element
}
} ;

View File

@ -1,16 +1,126 @@
USE: tools.test
USING: accessors arrays assocs english.private help.markup kernel math
math.parser sequences strings tools.test ;
IN: english
{ "record" } [ "records" singularize ] unit-test
{ "FOOT" } [ "FEET" singularize ] unit-test
{ "record" } [ "records" singularize ] unit-test
{ "record" } [ "record" singularize ] unit-test
{ "baby" } [ "babies" singularize ] unit-test
{ "baby" } [ "baby" singularize ] unit-test
{ "FOOT" } [ "FEET" singularize ] unit-test
{ "FOOT" } [ "FOOT" singularize ] unit-test
{ "cactus" } [ "cacti" singularize ] unit-test
{ "cactus" } [ "cactuses" singularize ] unit-test
{ "octopus" } [ "octopi" singularize ] unit-test
{ "octopus" } [ "octopuses" singularize ] unit-test
{ "friends" } [ "friend" pluralize ] unit-test
{ "friendlies" } [ "friendly" pluralize ] unit-test
{ "friendlies" } [ "friendlies" pluralize ] unit-test
{ "enemies" } [ "enemy" pluralize ] unit-test
{ "Sheep" } [ "Sheep" pluralize ] unit-test
{ "Sheep" } [ "Sheep" pluralize ] unit-test
{ "Moose" } [ "Moose" pluralize ] unit-test
{ "cacti" } [ "cactus" pluralize ] unit-test
{ "octopi" } [ "octopus" pluralize ] unit-test
{ "a10n" } [ "abbreviation" a10n ] unit-test
{ "i18n" } [ "internationalization" a10n ] unit-test
{ t } [ "singular" singular? ] unit-test
{ f } [ "singulars" singular? ] unit-test
{ t } [ "singularity" singular? ] unit-test
{ f } [ "singularities" singular? ] unit-test
{ t } [ "thesis" singular? ] unit-test
{ f } [ "theses" singular? ] unit-test
{ t } [ "goose" singular? ] unit-test
{ t } [ "baby" singular? ] unit-test
{ t } [ "bird" singular? ] unit-test
{ f } [ "birds" singular? ] unit-test
{ t } [ "octopus" singular? ] unit-test
{ f } [ "octopi" singular? ] unit-test
{ t } [ "geese" plural? ] unit-test
{ f } [ "goose" plural? ] unit-test
{ t } [ "birds" plural? ] unit-test
{ f } [ "bird" plural? ] unit-test
{ t } [ "cats" plural? ] unit-test
{ f } [ "cat" plural? ] unit-test
{ t } [ "babies" plural? ] unit-test
{ f } [ "baby" plural? ] unit-test
{ t } [ "octopi" plural? ] unit-test
{ f } [ "octopus" plural? ] unit-test
! they are both singular and plural
{ t } [ "moose" plural? ] unit-test
{ t } [ "moose" singular? ] unit-test
{ t } [ "sheep" plural? ] unit-test
{ t } [ "sheep" singular? ] unit-test
{ "3 babies" } [ 3 "baby" count-of-things ] unit-test
{ "1 pipe" } [ 1 "pipe" count-of-things ] unit-test
{ "0 pipes" } [ 0 "pipe" count-of-things ] unit-test
{ "2.5 cats" } [ 2.5 "cat" count-of-things ] unit-test
{ "2.5 CATS" } [ 2.5 "CAT" count-of-things ] unit-test
{ "1 pipe" } [ 1 "pipe" count-of-things ] unit-test
{ "0 pipes" } [ 0 "pipe" count-of-things ] unit-test
{ "babies" } [ 3 "baby" ?pluralize ] unit-test
{ "BABIES" } [ 3 "BABY" ?pluralize ] unit-test
{ "cats" } [ 2.5 "cat" ?pluralize ] unit-test
{ "Cats" } [ 2.5 "Cat" ?pluralize ] unit-test
{ "pipe" } [ 1 "pipe" ?pluralize ] unit-test
{ "pipes" } [ 0 "pipe" ?pluralize ] unit-test
{ "a5s" } [ "address" a10n ] unit-test
{ "a10n" } [ "abbreviation" a10n ] unit-test
{ "l10n" } [ "localization" a10n ] unit-test
{ "i18n" } [ "internationalization" a10n ] unit-test
{ "f28n" } [ "floccinauccinihilipilification" a10n ] unit-test
{ "p43s" } [ "pneumonoultramicroscopicsilicovolcanoconiosis" a10n ] unit-test
{ "a10000c" } [ 10000 CHAR: b <string> "a" "c" surround a10n ] unit-test
{ "an" } [ "object" a/an ] unit-test
{ "an" } [ "elephant" a/an ] unit-test
{ "a" } [ "moose" a/an ] unit-test
{ "a" } [ "xylophone" a/an ] unit-test
{ "the" } [ "objects" ?plural-article ] unit-test
{ "an" } [ "object" ?plural-article ] unit-test
{ "the" } [ "elephants" ?plural-article ] unit-test
{ "an" } [ "elephant" ?plural-article ] unit-test
{ "a" } [ "moose" ?plural-article ] unit-test
{ "a" } [ "goose" ?plural-article ] unit-test
{ "the" } [ "geese" ?plural-article ] unit-test
{ "a" } [ "sheep" ?plural-article ] unit-test
{ { "" } }
[ { } "or" simple-comma-list ] unit-test
{ { { "a" } } }
[ { "a" } "or" simple-comma-list ] unit-test
{ { { "a" } { " or " "b" } } }
[ { "a" "b" } "or" simple-comma-list ] unit-test
{ { { "a" ", " } { "b" } { ", or " "c" } } }
[ { "a" "b" "c" } "or" simple-comma-list ] unit-test
{ { { "a" ", " } { "b" ", " } { "x" } { ", and " "c" } } }
[ { "a" "b" "x" "c" } "and" simple-comma-list ] unit-test
{ {
{ "an " { $link object } ", " }
{ "a " { $link pair } ", " }
{ "a " { $link number } ", " }
{ "an " { $link array } ", " }
{ "a " { $link string } ", " }
{ "a " { $link sequence } }
{ ", or " "an " { $link assoc } }
} } [
{ object pair number array string sequence assoc }
or-markup-example
! an object, a pair, a number, an array, a string, a sequence, or an assoc
] unit-test
{ {
{ "an " { $link object } }
} } [ { object } or-markup-example ] unit-test
{ {
{ "an " { $link object } }
{ " or " "a " { $link pair } }
} } [ { object pair } or-markup-example ] unit-test

View File

@ -1,7 +1,8 @@
! Copyright (C) 2015 John Benediktsson
! Copyright (C) 2015, 2018 John Benediktsson
! See http://factorcode.org/license.txt for BSD license
USING: assocs assocs.extras combinators formatting kernel literals
locals math math.parser sequences splitting unicode ;
USING: arrays accessors assocs assocs.extras combinators fry formatting kernel
literals locals math math.parser sequences splitting words unicode ;
USE: help.markup
IN: english
@ -14,6 +15,7 @@ CONSTANT: singular-to-plural H{
! us -> i
{ "alumnus" "alumni" }
{ "cactus" "cacti" }
{ "octopus" "octopi" }
{ "focus" "foci" }
{ "fungus" "fungi" }
{ "nucleus" "nuclei" }
@ -141,11 +143,57 @@ PRIVATE>
[ "s" append ]
} cond match-case ;
: count-of-things ( count word -- str )
over 1 = [ pluralize ] unless "%d %s" sprintf ;
: singular? ( word -- ? )
[ singularize ] [ = ] bi ;
: a10n ( str -- str' )
: plural? ( word -- ? )
[ singularize pluralize ] [ = ] bi ;
: count-of-things ( count word -- str )
over 1 = [ pluralize ] unless [ number>string ] dip " " glue ;
: ?pluralize ( count singular -- singular/plural )
swap 1 = [ pluralize ] unless ;
: a10n ( word -- numeronym )
dup length 3 > [
[ 1 head ] [ length 2 - number>string ] [ 1 tail* ] tri
3append
] when ;
: a/an ( word -- article )
[ first ] [ length ] bi 1 = "afhilmnorsx" "aeiou" ?
member? "an" "a" ? ;
: ?plural-article ( word -- article )
dup singular? [ a/an ] [ drop "the" ] if ;
: comma-list-by ( parts quot conjunction -- clause-seq )
! using map-index for maximum flexibility
[ '[ _ call( x n -- x ) ] map-index
! not using oxford comma for 2 objects: "a, or b"; instead it's "a or b"
dup length 2 > ", " " " ? " "
] dip glue
over length {
{ [ dup 0 = ] [ 3drop { "" } ] }
{ [ dup 1 = ] [ 2drop ] }
[ drop [ unclip-last [
dup length 1 - '[ _ - zero? [ ", " suffix ] unless ] map-index
] dip ] dip prefix suffix
]
} cond ;
: simple-comma-list ( parts conjunction -- parts' )
[ drop 1array ] swap comma-list-by ;
: or-markup-example ( classes -- markup )
[ drop dup word? [
[ name>> a/an " " append ] [ \ $link swap 2array ] bi 2array
] [
[ "\"" ?head drop a/an ] keep 1array \ $snippet prefix " " swap 3array
] if
] "or" comma-list-by ;
: $or-markup-example ( classes -- )
or-markup-example print-element ;

View File

@ -72,12 +72,21 @@ HELP: vocab-help-coverage.
{ $example
"USING: help.lint.coverage ;"
"\"english\" vocab-help-coverage."
"[english] a10n: needs help sections: $description $examples
[english] count-of-things: needs help sections: $description $examples
[english] pluralize: needs help sections: $description $examples
[english] singularize: needs help sections: $description $examples
"[english] $or-markup-example: full help coverage
[english] ?plural-article: full help coverage
[english] ?pluralize: full help coverage
[english] a/an: full help coverage
[english] a10n: full help coverage
[english] comma-list-by: full help coverage
[english] count-of-things: full help coverage
[english] or-markup-example: full help coverage
[english] plural?: full help coverage
[english] pluralize: full help coverage
[english] simple-comma-list: full help coverage
[english] singular?: full help coverage
[english] singularize: full help coverage
0.0% of words have complete documentation"
100.0% of words have complete documentation"
}
} ;
@ -88,15 +97,26 @@ HELP: prefix-help-coverage.
{ $example
"USING: help.lint.coverage ;"
"\"english\" t prefix-help-coverage."
"[english] a10n: needs help sections: $description $examples
[english] count-of-things: needs help sections: $description $examples
[english] pluralize: needs help sections: $description $examples
[english] singularize: needs help sections: $description $examples
"[english] $or-markup-example: full help coverage
[english] ?plural-article: full help coverage
[english] ?pluralize: full help coverage
[english] a/an: full help coverage
[english] a10n: full help coverage
[english] comma-list-by: full help coverage
[english] count-of-things: full help coverage
[english] or-markup-example: full help coverage
[english] plural?: full help coverage
[english] pluralize: full help coverage
[english] simple-comma-list: full help coverage
[english] singular?: full help coverage
[english] singularize: full help coverage
[english.private] $0-plurality: needs help sections: $description $examples
[english.private] $keep-case: needs help sections: $description $examples
[english.private] match-case: needs help sections: $description $examples
[english.private] plural-to-singular: needs help sections: $description $examples
[english.private] singular-to-plural: needs help sections: $description $examples
0.0% of words have complete documentation"
72.2% of words have complete documentation"
}
} ;
@ -106,22 +126,66 @@ HELP: <prefix-help-coverage>
{ $examples
{ $example
"USING: help.lint.coverage prettyprint ;"
"\"english\" t <prefix-help-coverage> ."
"\"english\" t <prefix-help-coverage> ..."
"{
T{ word-help-coverage
{ word-name $or-markup-example }
{ 100%-coverage? t }
}
T{ word-help-coverage
{ word-name ?plural-article }
{ 100%-coverage? t }
}
T{ word-help-coverage
{ word-name ?pluralize }
{ 100%-coverage? t }
}
T{ word-help-coverage
{ word-name a/an }
{ 100%-coverage? t }
}
T{ word-help-coverage
{ word-name a10n }
{ omitted-sections { $description $examples } }
{ 100%-coverage? t }
}
T{ word-help-coverage
{ word-name comma-list-by }
{ 100%-coverage? t }
}
T{ word-help-coverage
{ word-name count-of-things }
{ omitted-sections { $description $examples } }
{ 100%-coverage? t }
}
T{ word-help-coverage
{ word-name or-markup-example }
{ 100%-coverage? t }
}
T{ word-help-coverage
{ word-name plural? }
{ 100%-coverage? t }
}
T{ word-help-coverage
{ word-name pluralize }
{ omitted-sections { $description $examples } }
{ 100%-coverage? t }
}
T{ word-help-coverage
{ word-name simple-comma-list }
{ 100%-coverage? t }
}
T{ word-help-coverage
{ word-name singular? }
{ 100%-coverage? t }
}
T{ word-help-coverage
{ word-name singularize }
{ 100%-coverage? t }
}
T{ word-help-coverage
{ word-name $0-plurality }
{ omitted-sections { $description $examples } }
}
T{ word-help-coverage
{ word-name $keep-case }
{ omitted-sections { $description $examples } }
}
T{ word-help-coverage
@ -146,7 +210,7 @@ HELP: <word-help-coverage>
{ $examples
{ $example
"USING: help.lint.coverage prettyprint ;"
"\\ <word-help-coverage> <word-help-coverage> ."
"\\ <word-help-coverage> <word-help-coverage> ..."
"T{ word-help-coverage
{ word-name <word-help-coverage> }
{ 100%-coverage? t }
@ -160,23 +224,59 @@ HELP: <vocab-help-coverage>
{ $examples
{ $example
"USING: help.lint.coverage prettyprint ;"
"\"english\" <vocab-help-coverage> ."
"\"english\" <vocab-help-coverage> ..."
"{
T{ word-help-coverage
{ word-name $or-markup-example }
{ 100%-coverage? t }
}
T{ word-help-coverage
{ word-name ?plural-article }
{ 100%-coverage? t }
}
T{ word-help-coverage
{ word-name ?pluralize }
{ 100%-coverage? t }
}
T{ word-help-coverage
{ word-name a/an }
{ 100%-coverage? t }
}
T{ word-help-coverage
{ word-name a10n }
{ omitted-sections { $description $examples } }
{ 100%-coverage? t }
}
T{ word-help-coverage
{ word-name comma-list-by }
{ 100%-coverage? t }
}
T{ word-help-coverage
{ word-name count-of-things }
{ omitted-sections { $description $examples } }
{ 100%-coverage? t }
}
T{ word-help-coverage
{ word-name or-markup-example }
{ 100%-coverage? t }
}
T{ word-help-coverage
{ word-name plural? }
{ 100%-coverage? t }
}
T{ word-help-coverage
{ word-name pluralize }
{ omitted-sections { $description $examples } }
{ 100%-coverage? t }
}
T{ word-help-coverage
{ word-name simple-comma-list }
{ 100%-coverage? t }
}
T{ word-help-coverage
{ word-name singular? }
{ 100%-coverage? t }
}
T{ word-help-coverage
{ word-name singularize }
{ omitted-sections { $description $examples } }
{ 100%-coverage? t }
}
}"
}

View File

@ -3,5 +3,16 @@ IN: math.text.english
HELP: number>text
{ $values { "n" integer } { "str" string } }
{ $description "Converts an integer to a text string representation in English, including appropriate punctuation and conjunctions." }
{ $contract "Converts an integer to a text string representation in English, including appropriate punctuation and conjunctions." }
{ $examples { $example "USING: math.text.english prettyprint ;" "12345 number>text ." "\"twelve thousand, three hundred and forty-five\"" } } ;
HELP: ordinal-suffix
{ $values { "n" number } { "suffix" string } }
{ $description "Determine the ordinal suffix for the input number. Non-integral numbers get the ordinal suffix of their integral part." }
{ $examples
{ $example
"USING: kernel math.parser math.text.english prettyprint sequences ;"
"783 [ number>string ] [ ordinal-suffix ] bi append ."
"\"783rd\""
}
} ;

View File

@ -1,4 +1,5 @@
USING: math.functions math.text.english tools.test ;
USING: kernel math.functions math.parser math.text.english
sequences tools.test ;
{ "zero" } [ 0 number>text ] unit-test
{ "twenty-one" } [ 21 number>text ] unit-test
@ -12,3 +13,30 @@ USING: math.functions math.text.english tools.test ;
{ "one duotrigintillion" } [ 10 99 ^ number>text ] unit-test
{ "negative one hundred and twenty-three" } [ -123 number>text ] unit-test
{ "0th" } [ 0 [ number>string ] [ ordinal-suffix ] bi append ] unit-test
{ "1st" } [ 1 [ number>string ] [ ordinal-suffix ] bi append ] unit-test
{ "2nd" } [ 2 [ number>string ] [ ordinal-suffix ] bi append ] unit-test
{ "3rd" } [ 3 [ number>string ] [ ordinal-suffix ] bi append ] unit-test
{ "4th" } [ 4 [ number>string ] [ ordinal-suffix ] bi append ] unit-test
{ "5th" } [ 5 [ number>string ] [ ordinal-suffix ] bi append ] unit-test
{ "6th" } [ 6 [ number>string ] [ ordinal-suffix ] bi append ] unit-test
{ "7th" } [ 7 [ number>string ] [ ordinal-suffix ] bi append ] unit-test
{ "10th" } [ 10 [ number>string ] [ ordinal-suffix ] bi append ] unit-test
{ "11th" } [ 11 [ number>string ] [ ordinal-suffix ] bi append ] unit-test
{ "12th" } [ 12 [ number>string ] [ ordinal-suffix ] bi append ] unit-test
{ "13th" } [ 13 [ number>string ] [ ordinal-suffix ] bi append ] unit-test
{ "101st" } [ 101 [ number>string ] [ ordinal-suffix ] bi append ] unit-test
{ "110th" } [ 110 [ number>string ] [ ordinal-suffix ] bi append ] unit-test
{ "111th" } [ 111 [ number>string ] [ ordinal-suffix ] bi append ] unit-test
{ "112th" } [ 112 [ number>string ] [ ordinal-suffix ] bi append ] unit-test
{ "113th" } [ 113 [ number>string ] [ ordinal-suffix ] bi append ] unit-test
{ "-101st" } [ -101 [ number>string ] [ ordinal-suffix ] bi append ] unit-test
{ "-110th" } [ -110 [ number>string ] [ ordinal-suffix ] bi append ] unit-test
{ "-111th" } [ -111 [ number>string ] [ ordinal-suffix ] bi append ] unit-test
{ "-112th" } [ -112 [ number>string ] [ ordinal-suffix ] bi append ] unit-test
{ "-113th" } [ -113 [ number>string ] [ ordinal-suffix ] bi append ] unit-test
{ "th" } [ 13.5 ordinal-suffix ] unit-test
{ "th" } [ 9+1/3 ordinal-suffix ] unit-test

View File

@ -1,8 +1,8 @@
! Copyright (c) 2007, 2008 Aaron Schaefer.
! Copyright (c) 2007, 2008, 2018 Aaron Schaefer.
! See http://factorcode.org/license.txt for BSD license.
USING: combinators.short-circuit grouping kernel math
math.functions math.parser math.text.utils namespaces sequences
splitting ;
USING: combinators combinators.short-circuit grouping kernel
math math.functions math.parser math.order math.text.utils namespaces
sequences splitting ;
IN: math.text.english
<PRIVATE
@ -112,3 +112,13 @@ M: complex number>text
[ 0 < " minus " " plus " ? ]
[ abs number>text " i" append ] bi
] bi* 3append ;
: ordinal-suffix ( n -- suffix )
abs dup 100 mod 11 13 between? [ drop "th" ] [
10 mod {
{ 1 [ "st" ] }
{ 2 [ "nd" ] }
{ 3 [ "rd" ] }
[ drop "th" ]
} case
] if ;