| 1 | # A collection of English-language specific utility methods. |
|---|
| 2 | class English |
|---|
| 3 | # Turns a camel-case string ("camel_case_to_english") to plain English ("camel |
|---|
| 4 | # case to english"). Each word is decapitalized. |
|---|
| 5 | def self.camel_case_to_english(camelCaseStr) |
|---|
| 6 | words = [] |
|---|
| 7 | nextCapIndex =(camelCaseStr =~ /[A-Z]/) |
|---|
| 8 | while nextCapIndex != nil |
|---|
| 9 | words << $` if $`.size > 0 |
|---|
| 10 | camelCaseStr = $& + $' |
|---|
| 11 | camelCaseStr[0] = camelCaseStr[0..0].downcase |
|---|
| 12 | nextCapIndex =(camelCaseStr =~ /[A-Z]/) |
|---|
| 13 | end |
|---|
| 14 | words << camelCaseStr |
|---|
| 15 | words.join ' ' |
|---|
| 16 | end |
|---|
| 17 | |
|---|
| 18 | # Turns an English language string into camel case. |
|---|
| 19 | def self.english_to_camel_case(englishStr) |
|---|
| 20 | cc = "" |
|---|
| 21 | englishStr.split.each { |word| |
|---|
| 22 | word = word.capitalize unless cc == '' |
|---|
| 23 | cc = cc += word |
|---|
| 24 | } |
|---|
| 25 | cc |
|---|
| 26 | end |
|---|
| 27 | |
|---|
| 28 | # Given a singular noun, returns the plural form. |
|---|
| 29 | def self.plural(singular) |
|---|
| 30 | consonantYPattern = Regexp.new("([^aeiou])y$", Regexp::IGNORECASE) |
|---|
| 31 | if singular =~ consonantYPattern |
|---|
| 32 | singular.gsub consonantYPattern, '\1ies' |
|---|
| 33 | elsif singular =~ /[xs]$/ |
|---|
| 34 | singular + "es" |
|---|
| 35 | else |
|---|
| 36 | singular + "s" |
|---|
| 37 | end |
|---|
| 38 | end |
|---|
| 39 | |
|---|
| 40 | # Returns the proper noun form of a string by capitalizing most of the |
|---|
| 41 | # words. |
|---|
| 42 | # |
|---|
| 43 | # Examples: |
|---|
| 44 | # English.proper_noun("bosnia and herzegovina") -> |
|---|
| 45 | # "Bosnia and Herzegovina" |
|---|
| 46 | # English.proper_noun("macedonia, the former yugoslav republic of") -> |
|---|
| 47 | # "Macedonia, the Former Yugoslav Republic of" |
|---|
| 48 | # English.proper_noun("virgin islands, u.s.") -> |
|---|
| 49 | # "Virgin Islands, U.S." |
|---|
| 50 | def self.proper_noun(string) |
|---|
| 51 | proper_noun = "" |
|---|
| 52 | while(matchIndex = string =~ /[\. ]/) |
|---|
| 53 | word = string[0..matchIndex-1] |
|---|
| 54 | word = word.capitalize unless [ 'and', 'the', 'of' ].index(word) != nil |
|---|
| 55 | proper_noun += word + $& |
|---|
| 56 | string = string[matchIndex+1..string.length] |
|---|
| 57 | end |
|---|
| 58 | word = string |
|---|
| 59 | word = word.capitalize unless [ 'and', 'the', 'of' ].index(word) != nil |
|---|
| 60 | proper_noun += word |
|---|
| 61 | proper_noun |
|---|
| 62 | end |
|---|
| 63 | |
|---|
| 64 | # Given a format for a template sentence, generates the sentence while |
|---|
| 65 | # accounting for details such as pluralization and whether to use "a" or |
|---|
| 66 | # "an". |
|---|
| 67 | # [format] The format string. Format codes are: |
|---|
| 68 | # * %num: Number |
|---|
| 69 | # * %is: Transitive verb. This will be turned into "is" or "are", |
|---|
| 70 | # depending on <tt>number</tt>. |
|---|
| 71 | # * %nam: Name. This will be rendered as either singular or |
|---|
| 72 | # plural, depending on <tt>number</tt>. |
|---|
| 73 | # * %a: Indefinite article. This will be turned into "a" or "an", |
|---|
| 74 | # depending on <tt>name</tt>. |
|---|
| 75 | # [name] The name of the object being described. |
|---|
| 76 | # [number] The number of the objects being describes. |
|---|
| 77 | # |
|---|
| 78 | # Examples: |
|---|
| 79 | # English.sentence("There %is currently %num %nam", "product category", |
|---|
| 80 | # 0) -> "There are currently 0 product categories" |
|---|
| 81 | # English.sentence("There %is currently %num %nam", "product category", |
|---|
| 82 | # 1) -> "There is currently 1 product category" |
|---|
| 83 | # English.sentence("Add %a %nam", "invoice") -> "Add an invoice" |
|---|
| 84 | def self.sentence(format, name, number = 1) |
|---|
| 85 | sentence = format |
|---|
| 86 | sentence.gsub!( /%num/, number.to_s ) |
|---|
| 87 | isVerb = number == 1 ? "is" : "are" |
|---|
| 88 | sentence.gsub!( /%is/, isVerb ) |
|---|
| 89 | name = English.plural name if number != 1 |
|---|
| 90 | sentence.gsub!( /%nam/, name ) |
|---|
| 91 | article = starts_with_vowel_sound(name) ? 'an' : 'a' |
|---|
| 92 | sentence.gsub!( /%a/, article ) |
|---|
| 93 | sentence |
|---|
| 94 | end |
|---|
| 95 | |
|---|
| 96 | def self.singular(plural) |
|---|
| 97 | if plural =~ /(.*)ies/ |
|---|
| 98 | $1 + 'y' |
|---|
| 99 | elsif plural =~ /(.*s)es/ |
|---|
| 100 | $1 |
|---|
| 101 | else |
|---|
| 102 | plural =~ /(.*)s/ |
|---|
| 103 | $1 |
|---|
| 104 | end |
|---|
| 105 | end |
|---|
| 106 | |
|---|
| 107 | # Does this word start with a vowel sound? "User" and "usury" don't, but |
|---|
| 108 | # "ugly" does. |
|---|
| 109 | def self.starts_with_vowel_sound(word) |
|---|
| 110 | uSomethingUMatch = word =~ /^u[^aeiuo][aeiou]/ |
|---|
| 111 | # 'user' and 'usury' don't start with a vowel sound |
|---|
| 112 | word =~ /^[aeiou]/ && !uSomethingUMatch |
|---|
| 113 | end |
|---|
| 114 | end |
|---|