text-gen 0.12.5 → 0.12.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c761d6858b40d475f4514ad9f309a32fbd00bc5ca1dca0be50ecd366cc7eb965
4
- data.tar.gz: c173f8bbe852bfd317f5c634fdd947a7c393089ab18e9467b5dc6a51b59c8736
3
+ metadata.gz: 96d238eb66df5e222ca033cbdcbc4c96a24756e9d3a24b0fedaa3f8b8c71af7f
4
+ data.tar.gz: 2310d7a4f9b6d290d75fefe757be1a766198bed7d5fa6835327500f7f6c11171
5
5
  SHA512:
6
- metadata.gz: 8832ee6825a82219769f67ece7a73c194a4ca2e4370290a633b0b571bbb98cc754243bd7737692249b880288a13482a7d80c77e741054c6aa4a3401899416f8a
7
- data.tar.gz: f78177137d036a701bf92ccae769dfdeddb6b54f9a3d18005f864dac34e25d30976683a640314b8529427de278b78dd642fe29b02749889c3cf722ee94c962e1
6
+ metadata.gz: 24b4e5056f75e5c862ccf4ae21638af665a7ceb0f0a1bdc739ee0ce95f856b398e61a09cc450ed3e5e2329c2c7052765dff3e7ab8daf0dd0c87f91bbe754acff
7
+ data.tar.gz: 4c2b802d548be347b3e674fc174648554a4627944f600a30cd9dca3e6806aa014e71952221db0f0fcd329d154151c6583afdb51d40cf05b564bbb838457a0edf
@@ -64,7 +64,7 @@ module Text
64
64
 
65
65
  def remembered(key = nil)
66
66
  key ||= current_key
67
- @remembered.select {|k, _r| k == key }.map(&:last)
67
+ @remembered.select { |k, _r| k == key }.map(&:last)
68
68
  end
69
69
 
70
70
  def remember_checkpoint
@@ -3,6 +3,8 @@
3
3
  module Text
4
4
  module Gen
5
5
  module Filter
6
+ # Capitalize the result text; first character only by default.
7
+ # Use `capitalize:force` to use the default ruby `capitalize` method
6
8
  class Capitalize < Base
7
9
  def result(context, result)
8
10
  return result if @depth && context.depth != @depth
@@ -3,9 +3,12 @@
3
3
  module Text
4
4
  module Gen
5
5
  module Filter
6
+ # Censor looks up a different builder and rejects the result if
7
+ # the result text is included in the
6
8
  class Censor < Base
7
9
  def result(context, result)
8
10
  return result if @depth && context.depth != @depth
11
+
9
12
  return result if key.nil?
10
13
 
11
14
  builder = context.store.fetch(key)
@@ -3,7 +3,7 @@
3
3
  module Text
4
4
  module Gen
5
5
  module Filter
6
- # Clears result meta
6
+ # Clear removes result meta
7
7
  class Clear < Base
8
8
  def result(context, result)
9
9
  return result if @depth && context.depth != @depth
@@ -9,7 +9,7 @@ module Text
9
9
  return result if key != context.current_key
10
10
 
11
11
  previous = context.remembered(key)
12
- return nil if previous.any? { |r| r.text.strip.downcase == result.text.strip.downcase }
12
+ return if previous.any? { |r| r.text.strip.downcase == result.text.strip.downcase }
13
13
 
14
14
  result
15
15
  end
@@ -3,6 +3,7 @@
3
3
  module Text
4
4
  module Gen
5
5
  module Filter
6
+ # Downcase returns the result text using the default lowercase rules
6
7
  class Downcase < Base
7
8
  def result(context, result)
8
9
  return result if @depth && context.depth != @depth
@@ -3,13 +3,15 @@
3
3
  module Text
4
4
  module Gen
5
5
  module Filter
6
+ # Exclude is the opposite of `match` and returns nil if
7
+ # the result metadata is matches the pattern in this filter.
6
8
  class Exclude < Base
7
9
  def result(context, result)
8
10
  return result if @depth && context.depth != @depth
9
- return nil if result.nil?
10
- return nil if value == "*" && result.meta.key?(key)
11
- return nil if key == "*" && result.meta.values.any? { |arr| arr.include?(value) }
12
- return nil if result.meta[key]&.include?(value)
11
+ return if result.nil?
12
+ return if value == "*" && result.meta.key?(key)
13
+ return if key == "*" && result.meta.values.any? { |arr| arr.include?(value) }
14
+ return if result.meta[key]&.include?(value)
13
15
 
14
16
  result
15
17
  end
@@ -3,6 +3,8 @@
3
3
  module Text
4
4
  module Gen
5
5
  module Filter
6
+ # Match returns `nil` unless the result metadata includes
7
+ # the given pattern.
6
8
  class Match < Base
7
9
  def result(context, result)
8
10
  return result if @depth && context.depth != @depth
@@ -3,6 +3,7 @@
3
3
  module Text
4
4
  module Gen
5
5
  module Filter
6
+ # Meta adds meta tags to the result
6
7
  class Meta < Base
7
8
  def result(context, result)
8
9
  return result if @depth && context.depth != @depth
@@ -30,7 +30,13 @@ module Text
30
30
  return result if @depth && context.depth != @depth
31
31
 
32
32
  text = result.text
33
- text = pluralize(text, result.multiplier)
33
+ text = if key && value
34
+ substitute(text, result.multiplier)
35
+ elsif key
36
+ pluralize_by_key(text, result.multiplier, result)
37
+ else
38
+ pluralize(text, result.multiplier)
39
+ end
34
40
  return result if text == result.text
35
41
 
36
42
  Result.from(result, text:, type: component_key)
@@ -38,27 +44,74 @@ module Text
38
44
 
39
45
  private
40
46
 
47
+ # Splits a string into alternating word and non-word tokens, preserving all characters.
48
+ # e.g. "5 swords." => ["5", " ", "swords", "."]
49
+ def tokenize(str)
50
+ str.scan(/\w+|\W+/)
51
+ end
52
+
53
+ def pluralize_by_key(str, multiplier, result)
54
+ tokens = tokenize(str)
55
+ word_tokens = tokens.select { |t| t.match?(/\w/) }
56
+ idx = word_tokens.rindex { |s| to_num(s) }
57
+ num = multiplier > 1 ? multiplier : (idx ? to_num(word_tokens[idx]) : nil)
58
+ return str if num.nil? || num <= 1
59
+
60
+ component = find_component(result, key)
61
+ return str unless component
62
+
63
+ component_text = component.text
64
+ return str if component_text.nil? || component_text.strip.empty?
65
+
66
+ component_tokens = tokenize(component_text)
67
+ last_word_idx = component_tokens.rindex { |t| t.match?(/\w/) }
68
+ return str unless last_word_idx
69
+
70
+ dc = component_tokens[last_word_idx].downcase
71
+ component_tokens[last_word_idx] = exceptions(dc) || single_letter(dc) || others(dc) || ends_with_y(dc) || simple(dc)
72
+ str.sub(component_text, component_tokens.join)
73
+ end
74
+
75
+ def find_component(result, search_key)
76
+ return result if result.type == search_key
77
+
78
+ result.components.each do |c|
79
+ found = find_component(c, search_key)
80
+ return found if found
81
+ end
82
+ nil
83
+ end
84
+
85
+ def substitute(str, multiplier = 1)
86
+ tokens = tokenize(str)
87
+ word_tokens = tokens.select { |t| t.match?(/\w/) }
88
+ idx = word_tokens.rindex { |s| to_num(s) }
89
+ num = multiplier > 1 ? multiplier : (idx ? to_num(word_tokens[idx]) : nil)
90
+ return str if num.nil? || num <= 1
91
+
92
+ tokens.map! { |t| t.match?(/\A#{Regexp.escape(key)}\z/i) ? value : t }
93
+ tokens.join
94
+ end
95
+
41
96
  def pluralize(str, multiplier = 1)
42
97
  return str if str.empty?
43
98
 
44
- arr = str.split(/\s+/)
45
- return str if arr.length < 2
99
+ tokens = tokenize(str)
100
+ word_tokens = tokens.select { |t| t.match?(/\w/) }
101
+ return str if word_tokens.length < 2
46
102
 
47
- idx = arr.rindex { |s| to_num(s) }
103
+ idx = word_tokens.rindex { |s| to_num(s) }
48
104
 
49
105
  # Use the multiplier if available, otherwise parse from text
50
- num = if multiplier > 1
51
- multiplier
52
- else
53
- (idx ? to_num(arr[idx]) : nil)
54
- end
106
+ num = multiplier > 1 ? multiplier : (idx ? to_num(word_tokens[idx]) : nil)
55
107
 
56
108
  return str if num.nil? || num <= 1
57
- return str if idx && idx >= arr.length - 1
109
+ return str if idx && idx >= word_tokens.length - 1
58
110
 
59
- dc = arr[-1].downcase
60
- arr[-1] = exceptions(dc) || single_letter(dc) || others(dc) || ends_with_y(dc) || simple(dc)
61
- arr.join(" ")
111
+ last_word_idx = tokens.rindex { |t| t.match?(/\w/) }
112
+ dc = tokens[last_word_idx].downcase
113
+ tokens[last_word_idx] = exceptions(dc) || single_letter(dc) || others(dc) || ends_with_y(dc) || simple(dc)
114
+ tokens.join
62
115
  end
63
116
 
64
117
  def to_num(str)
@@ -3,6 +3,8 @@
3
3
  module Text
4
4
  module Gen
5
5
  module Filter
6
+ # Reject reduces the items in the array to **only** those without
7
+ # the given metadata. This is the opposite of `select`.
6
8
  class Reject < Base
7
9
  def items(_context, items)
8
10
  items.select do |item|
@@ -3,8 +3,11 @@
3
3
  module Text
4
4
  module Gen
5
5
  module Filter
6
+ # Select reduces the items in the array to **only** those with passing
7
+ # metadata. This happens before generation as opposed to `match` which
8
+ # applies a pass/fail to the result.
6
9
  class Select < Base
7
- def apply(items)
10
+ def items(_context, items)
8
11
  items.select do |item|
9
12
  pass_select?(item["meta"])
10
13
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Text
4
4
  module Gen
5
- VERSION = "0.12.5"
5
+ VERSION = "0.12.6"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: text-gen
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.5
4
+ version: 0.12.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - G Palmer