text-gen 0.11.2 → 0.12.0

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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/lib/text/gen/context.rb +119 -0
  3. data/lib/text/gen/filter/base.rb +16 -13
  4. data/lib/text/gen/filter/capitalize.rb +19 -0
  5. data/lib/text/gen/filter/censor.rb +52 -0
  6. data/lib/text/gen/filter/clear.rb +19 -0
  7. data/lib/text/gen/filter/distinct.rb +19 -0
  8. data/lib/text/gen/filter/downcase.rb +19 -0
  9. data/lib/text/gen/filter/exclude.rb +19 -0
  10. data/lib/text/gen/filter/locale.rb +44 -0
  11. data/lib/text/gen/filter/match.rb +19 -0
  12. data/lib/text/gen/filter/meta.rb +35 -0
  13. data/lib/text/gen/filter/pluralize.rb +96 -0
  14. data/lib/text/gen/filter/reject.rb +24 -0
  15. data/lib/text/gen/filter/remember.rb +18 -0
  16. data/lib/text/gen/filter/replace.rb +15 -0
  17. data/lib/text/gen/filter/select.rb +24 -0
  18. data/lib/text/gen/filter/swap.rb +50 -0
  19. data/lib/text/gen/filter/titleize.rb +29 -0
  20. data/lib/text/gen/filter/upcase.rb +19 -0
  21. data/lib/text/gen/filter.rb +10 -168
  22. data/lib/text/gen/investigator.rb +38 -0
  23. data/lib/text/gen/meta.rb +46 -0
  24. data/lib/text/gen/result.rb +7 -22
  25. data/lib/text/gen/result_accumulator.rb +6 -11
  26. data/lib/text/gen/runner.rb +113 -174
  27. data/lib/text/gen/store.rb +29 -1
  28. data/lib/text/gen/version.rb +1 -1
  29. data/lib/text/gen.rb +4 -0
  30. metadata +21 -17
  31. data/lib/text/gen/filter/item/locale.rb +0 -29
  32. data/lib/text/gen/filter/item/reject.rb +0 -28
  33. data/lib/text/gen/filter/item/select.rb +0 -28
  34. data/lib/text/gen/filter/item_filter.rb +0 -17
  35. data/lib/text/gen/filter/result/capitalize.rb +0 -17
  36. data/lib/text/gen/filter/result/censor.rb +0 -55
  37. data/lib/text/gen/filter/result/clear.rb +0 -19
  38. data/lib/text/gen/filter/result/downcase.rb +0 -17
  39. data/lib/text/gen/filter/result/exclude.rb +0 -22
  40. data/lib/text/gen/filter/result/match.rb +0 -22
  41. data/lib/text/gen/filter/result/meta.rb +0 -31
  42. data/lib/text/gen/filter/result/pluralize.rb +0 -91
  43. data/lib/text/gen/filter/result/swap.rb +0 -48
  44. data/lib/text/gen/filter/result/titleize.rb +0 -28
  45. data/lib/text/gen/filter/result/upcase.rb +0 -17
  46. data/lib/text/gen/filter/result_filter.rb +0 -35
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../result_filter"
4
-
5
- module Text
6
- module Gen
7
- module Filter
8
- module Result
9
- class Clear < ResultFilter
10
- def apply(result)
11
- transform_with_meta(result) do |new_result|
12
- new_result.clear_meta(key, value)
13
- end
14
- end
15
- end
16
- end
17
- end
18
- end
19
- end
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../result_filter"
4
-
5
- module Text
6
- module Gen
7
- module Filter
8
- module Result
9
- class Downcase < ResultFilter
10
- def apply(result)
11
- transform_text(result, result.text.downcase)
12
- end
13
- end
14
- end
15
- end
16
- end
17
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../result_filter"
4
-
5
- module Text
6
- module Gen
7
- module Filter
8
- module Result
9
- class Exclude < ResultFilter
10
- def apply(result)
11
- return nil if result.nil?
12
- return nil if value == "*" && result.meta.key?(key)
13
- return nil if key == "*" && result.meta.values.any? { |arr| arr.include?(value) }
14
- return nil if result.meta[key]&.include?(value)
15
-
16
- result
17
- end
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../result_filter"
4
-
5
- module Text
6
- module Gen
7
- module Filter
8
- module Result
9
- class Match < ResultFilter
10
- def apply(result)
11
- return nil if result.nil?
12
- return result if value == "*" && result.meta.key?(key)
13
- return result if key == "*" && result.meta.values.any? { |arr| arr.include?(value) }
14
- return result if result.meta[key]&.include?(value)
15
-
16
- nil
17
- end
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../result_filter"
4
-
5
- module Text
6
- module Gen
7
- module Filter
8
- module Result
9
- class Meta < ResultFilter
10
- def apply(result)
11
- transform_with_meta(result) do |new_result|
12
- meta_value = case value
13
- when "_text_"
14
- result.text
15
- when "_value_"
16
- result.value.to_s
17
- when "_multiplier_"
18
- result.multiplier.to_s
19
- when "_length_"
20
- result.text.length.to_s
21
- else
22
- value
23
- end
24
- new_result.merge_kv(key, meta_value)
25
- end
26
- end
27
- end
28
- end
29
- end
30
- end
31
- end
@@ -1,91 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "set"
4
- require_relative "../result_filter"
5
-
6
- module Text
7
- module Gen
8
- module Filter
9
- module Result
10
- class Pluralize < ResultFilter
11
- EXCEPTIONS = {
12
- "foot" => "feet",
13
- "axis" => "axes",
14
- "child" => "children",
15
- "codex" => "codices",
16
- "die" => "dice",
17
- "dwarf" => "dwarves",
18
- "goose" => "geese",
19
- "elf" => "elves",
20
- "man" => "men",
21
- "ox" => "oxen",
22
- "cactus" => "cacti",
23
- "thesis" => "theses",
24
- "criterion" => "criteria",
25
- "thief" => "thieves",
26
- "tooth" => "teeth",
27
- "wolf" => "wolves",
28
- "woman" => "women"
29
- }.freeze
30
-
31
- SINGLE = Set.new(%w[a an the this his her its my your our that their])
32
-
33
- def apply(result)
34
- transform_text(result, pluralize(result.text, result.multiplier))
35
- end
36
-
37
- private
38
-
39
- def pluralize(str, multiplier = 1)
40
- return str if str.empty?
41
-
42
- arr = str.split(/\s+/)
43
- return str if arr.length < 2
44
-
45
- idx = arr.rindex { |s| to_num(s) }
46
-
47
- # Use the multiplier if available, otherwise parse from text
48
- num = multiplier > 1 ? multiplier : (idx ? to_num(arr[idx]) : nil)
49
-
50
- return str if num.nil? || num <= 1
51
- return str if idx && idx >= arr.length - 1
52
-
53
- dc = arr[-1].downcase
54
- arr[-1] = exceptions(dc) || single_letter(dc) || others(dc) || ends_with_y(dc) || simple(dc)
55
- arr.join(" ")
56
- end
57
-
58
- def to_num(str)
59
- return 1 if SINGLE.include?(str.downcase)
60
-
61
- str =~ /\d+/ ? str.to_i : nil
62
- end
63
-
64
- def exceptions(str)
65
- EXCEPTIONS[str]
66
- end
67
-
68
- def single_letter(str)
69
- return unless str =~ /^[a-zA-Z0-9]$/
70
-
71
- "#{str}'s"
72
- end
73
-
74
- def others(str)
75
- if str.end_with?("s") || str.end_with?("x") || str.end_with?("z") || str.end_with?("ch") || str.end_with?("sh")
76
- "#{str}es"
77
- end
78
- end
79
-
80
- def ends_with_y(str)
81
- "#{str[0..-2]}ies" if str.end_with?("y")
82
- end
83
-
84
- def simple(str)
85
- "#{str}s"
86
- end
87
- end
88
- end
89
- end
90
- end
91
- end
@@ -1,48 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../result_filter"
4
-
5
- module Text
6
- module Gen
7
- module Filter
8
- module Result
9
- class Swap < ResultFilter
10
- DIGIT_WORDS = {
11
- "1" => "one", "2" => "two", "3" => "three",
12
- "4" => "four", "5" => "five", "6" => "six",
13
- "7" => "seven", "8" => "eight", "9" => "nine"
14
- }.freeze
15
-
16
- def apply(result)
17
- transform_text(result, swap(result.text, key, value))
18
- end
19
-
20
- private
21
-
22
- def swap(str, key, val)
23
- return str if key.nil? || key.empty?
24
-
25
- arr = str.split(/\s+/)
26
- arr = arr.map do |s|
27
- case key
28
- when "digit"
29
- swap_digit(s)
30
- else
31
- swap_any(s, key, val.to_s)
32
- end
33
- end
34
- arr.join(" ")
35
- end
36
-
37
- def swap_any(str, key, val)
38
- str == key ? val : str
39
- end
40
-
41
- def swap_digit(str)
42
- DIGIT_WORDS.fetch(str, str)
43
- end
44
- end
45
- end
46
- end
47
- end
48
- end
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "set"
4
- require_relative "../result_filter"
5
-
6
- module Text
7
- module Gen
8
- module Filter
9
- module Result
10
- class Titleize < ResultFilter
11
- SKIP_WORDS = Set.new(%w[a an and as at but by for if in of on or the to v via vs])
12
-
13
- def apply(result)
14
- transform_text(result, titleize(result.text))
15
- end
16
-
17
- private
18
-
19
- def titleize(str)
20
- str.split(/\s+/).map.with_index do |word, idx|
21
- idx.zero? || !SKIP_WORDS.include?(word) ? word.capitalize : word
22
- end.join(" ")
23
- end
24
- end
25
- end
26
- end
27
- end
28
- end
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../result_filter"
4
-
5
- module Text
6
- module Gen
7
- module Filter
8
- module Result
9
- class Upcase < ResultFilter
10
- def apply(result)
11
- transform_text(result, result.text.upcase)
12
- end
13
- end
14
- end
15
- end
16
- end
17
- end
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "base"
4
-
5
- module Text
6
- module Gen
7
- module Filter
8
- # Base class for filters that operate on Result objects
9
- # Subclasses should implement #apply(result) -> Result or nil
10
- class ResultFilter < Base
11
- def apply(result)
12
- raise NotImplementedError, "Subclasses must implement #apply(result)"
13
- end
14
-
15
- protected
16
-
17
- # Helper to create a new result preserving metadata
18
- def transform_text(result, new_text)
19
- Text::Gen::Result.from(text: new_text, type: component_key, result: result)
20
- end
21
-
22
- # Helper to create a new result and modify metadata
23
- def transform_with_meta(result, new_text = nil)
24
- new_result = Text::Gen::Result.from(
25
- text: new_text || result.text,
26
- type: component_key,
27
- result: result
28
- )
29
- yield new_result if block_given?
30
- new_result
31
- end
32
- end
33
- end
34
- end
35
- end