random-words 1.0.5 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec_status +148 -39
  3. data/.rubocop.yml +1 -0
  4. data/CHANGELOG.md +42 -0
  5. data/Gemfile.lock +4 -1
  6. data/README.md +153 -4
  7. data/bin/randw +195 -49
  8. data/lib/random-words/array.rb +51 -0
  9. data/lib/random-words/config.rb +248 -0
  10. data/lib/random-words/generator.rb +239 -93
  11. data/lib/random-words/hash.rb +16 -0
  12. data/lib/random-words/html2markdown.rb +205 -0
  13. data/lib/random-words/lorem-markdown.rb +398 -0
  14. data/lib/random-words/number-to-word.rb +137 -0
  15. data/lib/random-words/source.rb +105 -0
  16. data/lib/random-words/string.rb +221 -47
  17. data/lib/random-words/table-cleanup.rb +210 -0
  18. data/lib/random-words/version.rb +1 -1
  19. data/lib/random-words/words/1984/adjectives.txt +103 -0
  20. data/lib/random-words/words/1984/adverbs.txt +92 -0
  21. data/lib/random-words/words/1984/articles-plural.txt +10 -0
  22. data/lib/random-words/words/1984/articles-singular.txt +10 -0
  23. data/lib/random-words/words/1984/clauses.txt +79 -0
  24. data/lib/random-words/words/1984/config.yml +4 -0
  25. data/lib/random-words/words/1984/conjunctions-coordinating.txt +20 -0
  26. data/lib/random-words/words/1984/conjunctions-subordinate.txt +29 -0
  27. data/lib/random-words/words/1984/names.txt +74 -0
  28. data/lib/random-words/words/1984/nouns-plural.txt +89 -0
  29. data/lib/random-words/words/1984/nouns-singular.txt +74 -0
  30. data/lib/random-words/words/1984/numbers.yml +5 -0
  31. data/lib/random-words/words/1984/prepositions.txt +89 -0
  32. data/lib/random-words/words/1984/terminators.txt +16 -0
  33. data/lib/random-words/words/1984/verbs-passive.txt +83 -0
  34. data/lib/random-words/words/1984/verbs-plural.txt +91 -0
  35. data/lib/random-words/words/1984/verbs-singular.txt +110 -0
  36. data/lib/random-words/words/alice/adjectives.txt +80 -0
  37. data/lib/random-words/words/alice/adverbs.txt +87 -0
  38. data/lib/random-words/words/alice/articles-plural.txt +10 -0
  39. data/lib/random-words/words/alice/articles-singular.txt +10 -0
  40. data/lib/random-words/words/alice/clauses.txt +81 -0
  41. data/lib/random-words/words/alice/config.yml +4 -0
  42. data/lib/random-words/words/alice/conjunctions-coordinating.txt +20 -0
  43. data/lib/random-words/words/alice/conjunctions-subordinate.txt +29 -0
  44. data/lib/random-words/words/alice/names.txt +74 -0
  45. data/lib/random-words/words/alice/nouns-plural.txt +95 -0
  46. data/lib/random-words/words/alice/nouns-singular.txt +82 -0
  47. data/lib/random-words/words/alice/numbers.yml +5 -0
  48. data/lib/random-words/words/alice/prepositions.txt +45 -0
  49. data/lib/random-words/words/alice/terminators.txt +16 -0
  50. data/lib/random-words/words/alice/verbs-passive.txt +495 -0
  51. data/lib/random-words/words/alice/verbs-plural.txt +115 -0
  52. data/lib/random-words/words/alice/verbs-singular.txt +97 -0
  53. data/lib/random-words/words/bacon/clauses.txt +592 -592
  54. data/lib/random-words/words/bacon/config.yml +4 -0
  55. data/lib/random-words/words/bacon/conjunctions-coordinating.txt +20 -0
  56. data/lib/random-words/words/bacon/names.txt +74 -0
  57. data/lib/random-words/words/bacon/numbers.yml +5 -0
  58. data/lib/random-words/words/bacon/prepositions.txt +45 -0
  59. data/lib/random-words/words/bacon/terminators.txt +16 -0
  60. data/lib/random-words/words/corporate/config.yml +4 -0
  61. data/lib/random-words/words/corporate/conjunctions-coordinating.txt +20 -0
  62. data/lib/random-words/words/corporate/names.txt +74 -0
  63. data/lib/random-words/words/corporate/numbers.yml +5 -0
  64. data/lib/random-words/words/corporate/prepositions.txt +45 -0
  65. data/lib/random-words/words/corporate/terminators.txt +16 -0
  66. data/lib/random-words/words/doctor/adjectives.txt +92 -0
  67. data/lib/random-words/words/doctor/adverbs.txt +92 -0
  68. data/lib/random-words/words/doctor/articles-plural.txt +10 -0
  69. data/lib/random-words/words/doctor/articles-singular.txt +10 -0
  70. data/lib/random-words/words/doctor/clauses.txt +83 -0
  71. data/lib/random-words/words/doctor/config.yml +10 -0
  72. data/lib/random-words/words/doctor/conjunctions-coordinating.txt +20 -0
  73. data/lib/random-words/words/doctor/conjunctions-subordinate.txt +29 -0
  74. data/lib/random-words/words/doctor/names.txt +74 -0
  75. data/lib/random-words/words/doctor/nouns-plural.txt +84 -0
  76. data/lib/random-words/words/doctor/nouns-singular.txt +84 -0
  77. data/lib/random-words/words/doctor/numbers.yml +5 -0
  78. data/lib/random-words/words/doctor/prepositions.txt +45 -0
  79. data/lib/random-words/words/doctor/terminators.txt +16 -0
  80. data/lib/random-words/words/doctor/verbs-passive.txt +83 -0
  81. data/lib/random-words/words/doctor/verbs-plural.txt +88 -0
  82. data/lib/random-words/words/doctor/verbs-singular.txt +83 -0
  83. data/lib/random-words/words/english/clauses.txt +592 -592
  84. data/lib/random-words/words/english/config.yml +4 -0
  85. data/lib/random-words/words/english/conjunctions-coordinating.txt +20 -0
  86. data/lib/random-words/words/english/names.txt +74 -0
  87. data/lib/random-words/words/english/numbers.yml +5 -0
  88. data/lib/random-words/words/english/prepositions.txt +45 -0
  89. data/lib/random-words/words/english/terminators.txt +16 -0
  90. data/lib/random-words/words/english/verbs-plural.txt +1 -0
  91. data/lib/random-words/words/english/verbs-singular.txt +1 -0
  92. data/lib/random-words/words/foulmouth/adjectives.txt +89 -0
  93. data/lib/random-words/words/foulmouth/adverbs.txt +97 -0
  94. data/lib/random-words/words/foulmouth/articles-plural.txt +10 -0
  95. data/lib/random-words/words/foulmouth/articles-singular.txt +10 -0
  96. data/lib/random-words/words/foulmouth/clauses.txt +74 -0
  97. data/lib/random-words/words/foulmouth/config.yml +4 -0
  98. data/lib/random-words/words/foulmouth/conjunctions-coordinating.txt +20 -0
  99. data/lib/random-words/words/foulmouth/conjunctions-subordinate.txt +29 -0
  100. data/lib/random-words/words/foulmouth/names.txt +74 -0
  101. data/lib/random-words/words/foulmouth/nouns-plural.txt +96 -0
  102. data/lib/random-words/words/foulmouth/nouns-singular.txt +99 -0
  103. data/lib/random-words/words/foulmouth/numbers.yml +5 -0
  104. data/lib/random-words/words/foulmouth/prepositions.txt +35 -0
  105. data/lib/random-words/words/foulmouth/terminators.txt +16 -0
  106. data/lib/random-words/words/foulmouth/verbs-passive.txt +143 -0
  107. data/lib/random-words/words/foulmouth/verbs-plural.txt +91 -0
  108. data/lib/random-words/words/foulmouth/verbs-singular.txt +104 -0
  109. data/lib/random-words/words/hipster/adjectives.txt +100 -0
  110. data/lib/random-words/words/hipster/adverbs.txt +89 -0
  111. data/lib/random-words/words/hipster/articles-plural.txt +10 -0
  112. data/lib/random-words/words/hipster/articles-singular.txt +10 -0
  113. data/lib/random-words/words/hipster/clauses.txt +180 -0
  114. data/lib/random-words/words/hipster/config.yml +4 -0
  115. data/lib/random-words/words/hipster/conjunctions-coordinating.txt +20 -0
  116. data/lib/random-words/words/hipster/conjunctions-subordinate.txt +29 -0
  117. data/lib/random-words/words/hipster/names.txt +74 -0
  118. data/lib/random-words/words/hipster/nouns-plural.txt +96 -0
  119. data/lib/random-words/words/hipster/nouns-singular.txt +100 -0
  120. data/lib/random-words/words/hipster/numbers.yml +5 -0
  121. data/lib/random-words/words/hipster/prepositions.txt +45 -0
  122. data/lib/random-words/words/hipster/terminators.txt +16 -0
  123. data/lib/random-words/words/hipster/verbs-passive.txt +88 -0
  124. data/lib/random-words/words/hipster/verbs-plural.txt +106 -0
  125. data/lib/random-words/words/hipster/verbs-singular.txt +114 -0
  126. data/lib/random-words/words/latin/config.yml +4 -0
  127. data/lib/random-words/words/latin/conjunctions-coordinating.txt +15 -0
  128. data/lib/random-words/words/latin/names.txt +74 -0
  129. data/lib/random-words/words/latin/numbers.yml +5 -0
  130. data/lib/random-words/words/latin/prepositions.txt +18 -0
  131. data/lib/random-words/words/latin/terminators.txt +16 -0
  132. data/lib/random-words/words/spanish/adjectives.txt +81 -0
  133. data/lib/random-words/words/spanish/adverbs.txt +87 -0
  134. data/lib/random-words/words/spanish/articles-plural.txt +4 -0
  135. data/lib/random-words/words/spanish/articles-singular.txt +4 -0
  136. data/lib/random-words/words/spanish/clauses.txt +74 -0
  137. data/lib/random-words/words/spanish/config.yml +4 -0
  138. data/lib/random-words/words/spanish/conjunctions-coordinating.txt +8 -0
  139. data/lib/random-words/words/spanish/conjunctions-subordinate.txt +16 -0
  140. data/lib/random-words/words/spanish/names.txt +74 -0
  141. data/lib/random-words/words/spanish/nouns-plural.txt +92 -0
  142. data/lib/random-words/words/spanish/nouns-singular.txt +125 -0
  143. data/lib/random-words/words/spanish/numbers.yml +5 -0
  144. data/lib/random-words/words/spanish/prepositions.txt +31 -0
  145. data/lib/random-words/words/spanish/terminators.txt +17 -0
  146. data/lib/random-words/words/spanish/verbs-passive.txt +495 -0
  147. data/lib/random-words/words/spanish/verbs-plural.txt +326 -0
  148. data/lib/random-words/words/spanish/verbs-singular.txt +351 -0
  149. data/lib/random-words/words/veggie/adjectives.txt +111 -0
  150. data/lib/random-words/words/veggie/adverbs.txt +81 -0
  151. data/lib/random-words/words/veggie/articles-plural.txt +10 -0
  152. data/lib/random-words/words/veggie/articles-singular.txt +10 -0
  153. data/lib/random-words/words/veggie/clauses.txt +57 -0
  154. data/lib/random-words/words/veggie/config.yml +4 -0
  155. data/lib/random-words/words/veggie/conjunctions-coordinating.txt +20 -0
  156. data/lib/random-words/words/veggie/conjunctions-subordinate.txt +29 -0
  157. data/lib/random-words/words/veggie/names.txt +74 -0
  158. data/lib/random-words/words/veggie/nouns-plural.txt +78 -0
  159. data/lib/random-words/words/veggie/nouns-singular.txt +105 -0
  160. data/lib/random-words/words/veggie/numbers.yml +5 -0
  161. data/lib/random-words/words/veggie/prepositions.txt +45 -0
  162. data/lib/random-words/words/veggie/terminators.txt +16 -0
  163. data/lib/random-words/words/veggie/verbs-passive.txt +56 -0
  164. data/lib/random-words/words/veggie/verbs-plural.txt +79 -0
  165. data/lib/random-words/words/veggie/verbs-singular.txt +79 -0
  166. data/lib/random-words.rb +28 -0
  167. data/random-words.gemspec +2 -0
  168. data/src/_README.md +153 -4
  169. metadata +168 -7
  170. data/lib/random-words/words/bacon/numbers.txt +0 -21
  171. data/lib/random-words/words/corporate/numbers.txt +0 -21
  172. data/lib/random-words/words/english/numbers.txt +0 -21
  173. data/lib/random-words/words/latin/numbers.txt +0 -21
@@ -0,0 +1,137 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Original code by Mike Burns
4
+
5
+ # Copyright 2007 Mike Burns
6
+
7
+ # This program is free software; you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation; either version 2 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
+
21
+ module RandomWords
22
+ # This class extends the Integer class with methods to convert numbers
23
+ # into their word representations. It provides methods for converting
24
+ # numbers to words in various languages, including English.
25
+ #
26
+ # @example
27
+ # 1.to_word # => "one"
28
+ # 126620.to_word # => "one hundred twenty six thousand six hundred twenty"
29
+ #
30
+ class ::Integer
31
+ # Turn a number into the word representation of that number.
32
+ # 1.to_word # => "one"
33
+ # 126620.to_word # => "one hundred twenty six thousand six hundred twenty"
34
+ def to_word(numbers)
35
+ tmp = self / 1000
36
+ final = (self % 1000).hundred_to_word(2, numbers)
37
+ place = 3 # special-case the tens and below
38
+ until tmp.zero? do
39
+ final = (tmp%1000).hundred_to_word(place, numbers) + ' ' + final
40
+ place += 1
41
+ tmp = tmp / 1000
42
+ end
43
+ final == '' ? 'zero' : final.sub(/\s+$/,'')
44
+ end
45
+
46
+
47
+ # For testing edge cases
48
+ def additional_tests(numbers)
49
+ teen_to_word(numbers)
50
+ digit_to_word(numbers)
51
+ tens_place_to_word(numbers)
52
+ true
53
+ end
54
+
55
+ protected
56
+
57
+ # Convert a number to its word representation for the hundreds place.
58
+ def hundred_to_word(place = 0, numbers)
59
+ if self.zero?
60
+ ''
61
+ elsif self < 10
62
+ self.append_place(self.digit_to_word(numbers), place, numbers)
63
+ elsif self < 20
64
+ self.append_place(self.teen_to_word(numbers), place, numbers)
65
+ elsif self < 100
66
+ self.append_place(self.tens_place_to_word(numbers), place, numbers)
67
+ else
68
+ (hundreds,tens) = [self / 100, self % 100]
69
+ if tens.zero?
70
+ self.append_place(hundreds.digit_to_word(numbers) + " #{numbers[:places][2]}", place, numbers)
71
+ else
72
+ self.append_place(hundreds.digit_to_word(numbers) + " #{numbers[:places][2]} " + tens.tens_place_to_word(numbers), place, numbers)
73
+ end
74
+ end
75
+ end
76
+
77
+ # Append the appropriate place value to a word based on its position.
78
+ # @param word [String] The word representation of the number.
79
+ # @param place [Integer] The place value (e.g., hundreds, thousands).
80
+ # @param numbers [Hash] A hash containing number words.
81
+ # @return [String] The word with the appropriate place value appended.
82
+ def append_place(word, place, numbers)
83
+ places = numbers[:places]
84
+ if place > 2
85
+ word + ' ' + places[place]
86
+ else
87
+ word
88
+ end
89
+ end
90
+
91
+ # Convert a number to its word representation for the tens place.
92
+ # This is a special case for numbers 20-99.
93
+ # @param numbers [Hash] A hash containing number words.
94
+ # @return [String] The word representation of the number.
95
+ # @example
96
+ # 45.tens_place_to_word(numbers) # => "forty five"
97
+ def tens_place_to_word(numbers)
98
+ if self > 19
99
+ (tens, ones) = [self/10, self%10]
100
+ ten = numbers[:tens][tens-2]
101
+ ten+(ones.zero? ? '' : ' ' + ones.digit_to_word(numbers))
102
+ else
103
+ self.teen_to_word(numbers)
104
+ end
105
+ end
106
+
107
+ # Convert a number to its word representation for the teens place.
108
+ # This is a special case for numbers 10-19.
109
+ # @param numbers [Hash] A hash containing number words.
110
+ # @return [String] The word representation of the number.
111
+ # @example
112
+ # 12.teen_to_word(numbers) # => "twelve"
113
+ def teen_to_word(numbers)
114
+ if self < 10
115
+ self.digit_to_word(numbers)
116
+ elsif self < 20
117
+ numbers[:teens][self-10]
118
+ else
119
+ self.tens_place_to_word(numbers)
120
+ end
121
+ end
122
+
123
+ # Convert a number to its word representation for the digits place.
124
+ # This is a special case for numbers 0-9.
125
+ # @param numbers [Hash] A hash containing number words.
126
+ # @return [String] The word representation of the number.
127
+ # @example
128
+ # 5.digit_to_word(numbers) # => "five"
129
+ def digit_to_word(numbers)
130
+ if self.zero?
131
+ ''
132
+ else
133
+ numbers[:digits][self]
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,105 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ module RandomWords
5
+ # A class representing a source of words for the RandomWords library.
6
+ class Source
7
+ attr_reader :name, :names, :config, :dictionary, :description
8
+
9
+ # Initializes a new Source instance.
10
+ # @param name [Symbol] The name of the source
11
+ # @param path [String] The path to the source directory
12
+ def initialize(name, path)
13
+ @name = name.to_sym
14
+ @path = path
15
+ config = IO.read(File.join(path, 'config.yml'))
16
+ @config = YAML.safe_load(config, aliases: true)
17
+ @names = @config['triggers'] || [name]
18
+ @description = @config['description'] || 'No description available'
19
+ @dictionary = from_files
20
+ @dictionary[:all_words] = @dictionary.values.flatten.uniq
21
+ @dictionary[:terminators], @dictionary[:extended_punctuation] = from_file("terminators").split_terminators
22
+ @dictionary[:first_names], @dictionary[:last_names] = from_file("names").split_names
23
+ rescue StandardError
24
+ @name = name.to_sym
25
+ @config = {}
26
+ @names = [name]
27
+ @description = 'No description available'
28
+ @dictionary = from_files
29
+ @dictionary[:all_words] = @dictionary.values.flatten.uniq
30
+ @dictionary[:terminators], @dictionary[:extended_punctuation] = from_file("terminators").split_terminators
31
+ @dictionary[:first_names], @dictionary[:last_names] = from_file("names").split_names
32
+ end
33
+
34
+ # def to_sym
35
+ # name.to_sym
36
+ # end
37
+
38
+ # Bad init method for testing purposes
39
+ # @!visibility private
40
+ def bad_init
41
+ from_file('nouns-noent.txt')
42
+ end
43
+
44
+ private
45
+
46
+ # Load words from all dictionary files
47
+ # @return [Hash] A hash containing arrays of words for each part of speech
48
+ # @example
49
+ # from_files # Loads words from all dictionary files
50
+ def from_files
51
+ {
52
+ nouns: from_file('nouns-singular'),
53
+ plural_nouns: from_file('nouns-plural'),
54
+ verbs: from_file('verbs-singular'),
55
+ plural_verbs: from_file('verbs-plural'),
56
+ passive_verbs: from_file('verbs-passive'),
57
+ adverbs: from_file('adverbs'),
58
+ adjectives: from_file('adjectives'),
59
+ articles: from_file('articles-singular'),
60
+ plural_articles: from_file('articles-plural'),
61
+ prepositions: from_file('prepositions'),
62
+ clauses: from_file('clauses'),
63
+ coordinating_conjunctions: from_file('conjunctions-coordinating'),
64
+ subordinate_conjunctions: from_file('conjunctions-subordinate'),
65
+ numbers: from_yaml('numbers')
66
+ }
67
+ end
68
+
69
+ # Load words from a dictionary file
70
+ # Files are plain text with one word or phrase per line
71
+ # The @source variable defines which dictionary to be used and should be defined before calling this method
72
+ # @param filename [String] The name of the file to load
73
+ # @return [Array] An array of words loaded from the file
74
+ # @example
75
+ # from_file('nouns.txt') # Loads words from words/[source]/nouns.txt
76
+ def from_file(filename)
77
+ filename = "#{filename.sub(/\.txt$/, '')}.txt"
78
+ path = File.join(@path, filename)
79
+
80
+ File.read(path).split("\n").map(&:strip) # Changed from split_lines to split("\n")
81
+ rescue Errno::ENOENT
82
+ warn "File not found: #{path}"
83
+ []
84
+ end
85
+
86
+ # Load words from a YAML file
87
+ # @param filename [String] The name of the YAML file to load
88
+ # @return [Hash] A hash of words loaded from the YAML file
89
+ def from_yaml(filename)
90
+ path = File.join(@path, "#{filename}.yml")
91
+ return {} unless File.exist?(path)
92
+ begin
93
+ nums = YAML.safe_load(File.read(path), aliases: true).symbolize_keys
94
+ nums.keys.each do |key|
95
+ nums[key] = nums[key].split(" ").map(&:strip) if nums[key].is_a?(String)
96
+ end
97
+ nums
98
+ rescue Psych::SyntaxError => e
99
+ warn "YAML syntax error in #{path}: #{e.message}"
100
+ {}
101
+ end
102
+
103
+ end
104
+ end
105
+ end
@@ -1,56 +1,230 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
-
4
- # String extensions for RandomWords
5
- # This module extends the String class with additional methods for cleaning,
6
- # compressing, and manipulating strings.
7
- #
8
- # @example
9
- # str = " Hello, World! "
10
- # str.clean # => "Hello World"
11
- # str.compress # => "Hello World"
12
- # str.terminate # => "Hello World."
13
- #
14
- class ::String
15
- # Remove unwanted characters and whitespace from a string.
16
- # @return [String] The string with unwanted characters removed.
17
- # @example
18
- # "Hello, World!".clean # => "Hello World"
3
+ module RandomWords
4
+ # String extensions for RandomWords
5
+ # This module extends the String class with additional methods for cleaning,
6
+ # compressing, and manipulating strings.
19
7
  #
20
- # @return [String] The cleaned string.
21
- def clean
22
- gsub(/[^-a-zA-Z0-9\s]/, '').strip
23
- end
24
-
25
- # Split a string by newlines, clean each line, and remove empty lines.
26
- # @return [Array<String>] The string split into lines, cleaned, and empty lines removed.
27
8
  # @example
28
- # "Hello, World!\n\nThis is a test.".split_lines # => ["Hello World", "This is a test"]
9
+ # str = " Hello, World! "
10
+ # str.clean # => "Hello World"
11
+ # str.compress # => "Hello World"
12
+ # str.terminate # => "Hello World."
29
13
  #
30
- def split_lines
31
- strip.split("\n").map(&:clean).reject(&:empty?)
32
- end
14
+ class ::String
15
+ # Remove unwanted characters and whitespace from a string.
16
+ # @return [String] The string with unwanted characters removed.
17
+ # @example
18
+ # "Hello, World!".clean # => "Hello World"
19
+ #
20
+ # @return [String] The cleaned string.
21
+ def clean
22
+ gsub(/[^-a-zA-Z0-9\s]/, '').strip
23
+ end
33
24
 
34
- # Compress multiple spaces into a single space and remove leading/trailing spaces.
35
- # @return [String] The string with extra spaces compressed.
36
- def compress
37
- gsub(/\s+/, ' ').strip
38
- end
25
+ # Captialize instances of "i" in a string.
26
+ # @return [String] The string with "i" capitalized.
27
+ # @example
28
+ # "this is an i".capitalize_i # => "this is an I"
29
+ # @example
30
+ # "this is an iPhone".capitalize_i # => "this is an iPhone"
31
+ #
32
+ def capitalize_i
33
+ gsub(/\bi\b/, 'I')
34
+ end
39
35
 
40
- # Terminate a string with a random punctuation mark.
41
- # @return [String] The string with a random punctuation mark at the end.
42
- # @example
43
- # "Hello World".terminate # => "Hello World."
44
- #
45
- def terminate
46
- terminators = %w[. . . ! ! ?]
47
- terminator = terminators.sample
48
- sub(/[.!?;,-]*$/, terminator)
49
- end
36
+ # Capitalize the first letter of a string, respcting punctuation.
37
+ # @return [String] The string with the first letter capitalized.
38
+ # @example
39
+ # "hello world".capitalize # => "Hello world"
40
+ def capitalize
41
+ return self if empty?
42
+
43
+ letters = split('')
44
+ string = []
45
+ while letters[0] !~ /[[:word:]]/
46
+ string << letters.shift
47
+ end
48
+ string << letters.shift.upcase
49
+ string.concat(letters)
50
+ string.join("")
51
+ end
52
+
53
+ # Downcase the first letter of a string, respecting punctuation.
54
+ # @return [String] The string with the first letter downcased.
55
+ def downcase_first
56
+ return self if empty?
57
+
58
+ letters = split('')
59
+ string = []
60
+ while letters[0] !~ /[[:word:]]/
61
+ string << letters.shift
62
+ end
63
+ string << letters.shift.downcase
64
+ string.concat(letters)
65
+ string.join("")
66
+ end
67
+
68
+ # Capitalize the first letter of each sentence in a string.
69
+ # Scans for all known terminators followed by a space and capitalizes the next letter.
70
+ # @param terminators [Array<Array>] An array of beginning and ending punctuation mark arrays.
71
+ # @return [String] The string with the first letter of each sentence capitalized.
72
+ # @example
73
+ # "hello world. this is a test.".fix_caps([[".", "."]]) # => "Hello world. This is a test."
74
+ #
75
+ def fix_caps(terminators)
76
+ return self if empty?
77
+
78
+ terminator_ends = terminators.map { |t| t[1].split("").last }.delete_if(&:empty?)
79
+ return capitalize if terminator_ends.empty?
80
+
81
+ terminator_regex = Regexp.new("[#{Regexp.escape(terminator_ends.join)}]")
82
+ return capitalize unless self =~ terminator_regex
83
+
84
+ split(/(?<=#{terminator_regex}) /).map do |sentence|
85
+ sentence.capitalize
86
+ end.join(" ")
87
+ end
88
+
89
+ # Remove duplicate commas
90
+ # @return [String] The string with duplicate commas removed.
91
+ # @example
92
+ # "Hello, , World!".remove_duplicate_commas # => "Hello, World!"
93
+ def dedup_commas
94
+ gsub(/(, *)+/, ',').gsub(/,/, ', ')
95
+ end
96
+
97
+ # Generate a sentence with capitalization and terminator
98
+ # @param terminator [Array<String>] An array of beginning and ending punctuation marks.
99
+ # @return [String] The string with a random punctuation mark at the end.
100
+ def to_sent(terminator)
101
+ capitalize.compress.capitalize_i.dedup_commas.terminate(terminator)
102
+ end
103
+
104
+ # Split a string by newlines, clean each line, and remove empty lines.
105
+ # @return [Array<String>] The string split into lines, cleaned, and empty lines removed.
106
+ # @example
107
+ # "Hello, World!\n\nThis is a test.".split_lines # => ["Hello World", "This is a test"]
108
+ #
109
+ def split_lines
110
+ strip.split("\n").map(&:clean).reject(&:empty?)
111
+ end
112
+
113
+ # Compress multiple spaces into a single space and remove leading/trailing spaces.
114
+ # @return [String] The string with extra spaces compressed.
115
+ def compress
116
+ gsub(/\s+/, ' ').strip
117
+ end
118
+
119
+ # Terminate a string with a random punctuation mark.
120
+ # @param terminator [Array<String>] An array of beginning and ending punctuation marks.
121
+ # @return [String] The string with a random punctuation mark at the end.
122
+ # @example
123
+ # "Hello World".terminate(["", "."]) # => "Hello World."
124
+ #
125
+ def terminate(terminator)
126
+ sub(/^/, terminator[0]).sub(/[^a-zA-Z0-9]*$/, terminator[1])
127
+ end
128
+
129
+ # Remove any punctuation mark from the end of a string.
130
+ # @return [String] The string with the last punctuation mark removed.
131
+ def no_term
132
+ sub(/[.!?;,:-]+$/, '')
133
+ end
134
+
135
+ # Indent every line in a string with a specified string.
136
+ # @param [String] string The string to indent with.
137
+ # @return [String] The indented string.
138
+ def indent(string)
139
+ gsub(/^/, string)
140
+ end
141
+
142
+ # Capitalize the first letter of a string.
143
+ # @return [String] The string with the first letter capitalized.
144
+ def cap_first
145
+ # Capitalizes the first letter of a string.
146
+ self[0] = self[0].upcase
147
+ self
148
+ end
149
+
150
+ # Add a specified character to the end of a string, avoiding repeated punctuation.
151
+ # @param [String] char The character to add (default: '.').
152
+ # @return [String] The string with the specified character at the end.
153
+ def term(char = '.')
154
+ # Adds a specified character to the end of a string.
155
+ sub(/[.?!,;]?$/, "#{char}")
156
+ end
157
+
158
+ # Remove extra newlines from the output.
159
+ # @return [String] The string with extra newlines removed.
160
+ def compress_newlines
161
+ # Removes extra newlines from the output.
162
+ gsub(/\n{2,}/, "\n\n").strip
163
+ end
164
+
165
+ # Compress newlines in the output, destructive.
166
+ # @see #compress_newlines
167
+ # @return [String] The string with newlines compressed.
168
+ def compress_newlines!
169
+ # Removes extra newlines from the output.
170
+ replace compress_newlines
171
+ end
172
+
173
+ # Preserve spaces in the output by replacing multiple spaces with %%.
174
+ # @return [String] The string with spaces preserved.
175
+ def preserve_spaces
176
+ # Preserves spaces in the output.
177
+ gsub(/ +/, '%%')
178
+ end
179
+
180
+ # Restore spaces in the output by replacing %% with spaces.
181
+ # @return [String] The string with spaces restored.
182
+ def restore_spaces
183
+ # Restores spaces in the output.
184
+ gsub(/%%/, ' ')
185
+ end
186
+
187
+ # Check if the string is trueish (starts with 't', 'y', or '1').
188
+ # @return [Boolean] true if the string is trueish, false otherwise.
189
+ def trueish?
190
+ to_s =~ /^[ty1]/i
191
+ end
192
+
193
+ # Convert the string to a source symbol based on its name.
194
+ # @return [Symbol] The symbolized name of the source.
195
+ def to_source
196
+ new_source = nil
197
+ sources = RandomWords::Generator.new.sources
198
+
199
+ sources.each do |k, v|
200
+ v.names.each do |name|
201
+ next unless name.to_s =~ /^#{self}/i
202
+
203
+ new_source = v.name
204
+ break
205
+ end
206
+ break if new_source
207
+ end
208
+
209
+ new_source || :latin
210
+ end
211
+
212
+ # Convert the string to a length symbol based on its name.
213
+ # @return [Symbol] The symbolized length of the string.
214
+ def to_length
215
+ case self
216
+ when /^s/i
217
+ :short
218
+ when /^m/i
219
+ :medium
220
+ when /^l/i
221
+ :long
222
+ when /^v/i
223
+ :very_long
224
+ else
225
+ :medium
226
+ end
50
227
 
51
- # Remove any punctuation mark from the end of a string.
52
- # @return [String] The string with the last punctuation mark removed.
53
- def no_term
54
- sub(/[.!?;,-]*$/, '')
228
+ end
55
229
  end
56
- end
230
+ end