fat_core 7.1.2 → 7.2.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.
data/Rakefile CHANGED
@@ -24,16 +24,12 @@ RSpec::Core::RakeTask.new(:spec, :tag) do |t|
24
24
  t.rspec_opts = '--tag ~online -f d'
25
25
  end
26
26
 
27
+ require "gem_docs"
28
+ GemDocs.install
29
+
27
30
  ########################################################################
28
31
  # Rubocop tasks
29
32
  ########################################################################
30
- # Option A (recommended): Keep using Bundler and run rubocop via `bundle exec`.
31
- # This wrapper task ensures the rubocop run uses the gems from your Gemfile,
32
- # even when you invoke `rake rubocop` (no need to remember `bundle exec rake`).
33
- #
34
- # You can pass extra RuboCop CLI flags with the RUBOCOP_OPTS environment variable:
35
- # RUBOCOP_OPTS="--format simple" rake rubocop
36
-
37
33
  desc "Run rubocop under `bundle exec`"
38
34
  task :rubocop do
39
35
  opts = (ENV['RUBOCOP_OPTS'] || '').split
data/lib/fat_core/all.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative '../fat_core'
3
4
  require_relative 'array'
4
5
  require_relative 'bigdecimal'
5
6
  require_relative 'enumerable'
@@ -8,6 +8,9 @@ require_relative 'numeric'
8
8
 
9
9
  module FatCore
10
10
  module String
11
+ UPPERS = ('A'..'Z').to_a
12
+ REGEXP_META_CHARACTERS = "\\$()*+.<>?[]^{|}".chars.freeze
13
+
11
14
  # @group Transforming
12
15
  # :section: Transforming
13
16
 
@@ -93,22 +96,29 @@ module FatCore
93
96
  r.gsub('XzXzXcbXzXzX', '\\}')
94
97
  end
95
98
 
96
- UPPERS = ('A'..'Z').to_a
97
- REGEXP_META_CHARACTERS = "\\$()*+.<>?[]^{|}".chars.freeze
99
+ # Rather than truncate a String to make it fit a given length, this method
100
+ # removes characters from the middle of the string to make it fit the
101
+ # given size. This is often preferable to truncating at the end or
102
+ # beginning of a String because the most important information is often at
103
+ # the start or end of a String. By default the missing middle is
104
+ # indicated by a single '~' character, but you can set it to any string,
105
+ # even the empty string with the `ellipsis:` parameter.
106
+ def gut(max_size, ellipsis: '~', squeeze: nil)
107
+ return self if size <= max_size
98
108
 
99
- private
100
-
101
- def upper?
102
- UPPERS.include?(self[0])
103
- end
104
-
105
- # Return true if all the letters in self are upper case
106
- def all_upper?
107
- tr('^A-Za-z', '').split('').all? { |c| ('A'..'Z').to_a.include? c }
109
+ s =
110
+ if squeeze
111
+ tr(squeeze, '')
112
+ else
113
+ self
114
+ end
115
+ chars_to_cut = (s.size - max_size) + ellipsis.size
116
+ chars_to_keep = s.size - chars_to_cut
117
+ start_chars = chars_to_keep / 2 + (chars_to_keep.odd? ? 1 : 0)
118
+ end_chars = chars_to_keep - start_chars
119
+ s[0..start_chars - 1] + ellipsis + s[-end_chars..-1]
108
120
  end
109
121
 
110
- public
111
-
112
122
  # Return self capitalized according to the conventions for capitalizing
113
123
  # titles of books or articles. Tries to follow the rules of the University
114
124
  # of Chicago's *A Manual of Style*, Section 7.123, except to the extent that
@@ -215,32 +225,6 @@ module FatCore
215
225
  DamerauLevenshtein.distance(self, other.to_s, 1, 10)
216
226
  end
217
227
 
218
- # Test whether self matches the `matcher` treating `matcher` as a
219
- # case-insensitive regular expression if it is of the form '/.../' or as a
220
- # string to #fuzzy_match against otherwise.
221
- #
222
- # @param matcher [String] regexp if looks like /.../; #fuzzy_match pattern otherwise
223
- # @return [nil] if no match
224
- # @return [String] the matched portion of self, with punctuation stripped in
225
- # case of #fuzzy_match
226
- # @see #fuzzy_match #fuzzy_match for the specifics of string matching
227
- # @see #as_regexp #as_regexp for conversion of `matcher` to regular expression
228
- def matches_with(matcher)
229
- # Replace periods and commas with a space (so they are still word
230
- # separators, e.g. 'WWW.WOLFRAM' -> 'WWW WOLFRAM' and 'AMZON,INC.' ->
231
- # 'AMAZON INC') and remove asterisks and apostrophes
232
- target = gsub(/[.,]/, ' ').gsub(/[\*']/, '').clean
233
- if matcher.nil?
234
- nil
235
- elsif matcher.match?(%r{^\s*/})
236
- re = matcher.as_regexp
237
- md = target.match(re)
238
- md[0] if md
239
- else
240
- to_s.fuzzy_match(matcher)
241
- end
242
- end
243
-
244
228
  # Return the matched portion of self, minus punctuation characters, if self
245
229
  # matches the string `matcher` using the following notion of matching:
246
230
  #
@@ -304,6 +288,28 @@ module FatCore
304
288
  matched_text
305
289
  end
306
290
 
291
+ # Test whether self matches the `matcher` treating `matcher` as a
292
+ # case-insensitive regular expression if it is of the form '/.../' or as a
293
+ # string to #fuzzy_match against otherwise.
294
+ #
295
+ # @param matcher [String] regexp if looks like /.../; #fuzzy_match pattern otherwise
296
+ # @return [nil] if no match
297
+ # @return [String] the matched portion of self, with punctuation stripped in
298
+ # case of #fuzzy_match
299
+ # @see #fuzzy_match #fuzzy_match for the specifics of string matching
300
+ # @see #as_regexp #as_regexp for conversion of `matcher` to regular expression
301
+ def matches_with(matcher)
302
+ return if matcher.nil?
303
+
304
+ if matcher.match?(%r{^\s*/})
305
+ re = matcher.as_regexp
306
+ md = match(re)
307
+ md[0] if md
308
+ else
309
+ fuzzy_match(matcher)
310
+ end
311
+ end
312
+
307
313
  # Convert a string of the form '/.../Iixm' to a regular
308
314
  # expression. However, make the regular expression case-insensitive by
309
315
  # default and extend the modifier syntax to allow '/I' to indicate
@@ -377,6 +383,17 @@ module FatCore
377
383
  to_f.commas(places)
378
384
  end
379
385
 
386
+ private
387
+
388
+ def upper?
389
+ UPPERS.include?(self[0])
390
+ end
391
+
392
+ # Return true if all the letters in self are upper case
393
+ def all_upper?
394
+ tr('^A-Za-z', '').split('').all? { |c| ('A'..'Z').to_a.include? c }
395
+ end
396
+
380
397
  module ClassMethods
381
398
  # @group Generating
382
399
  # :section: Generating
@@ -2,8 +2,8 @@
2
2
 
3
3
  module FatCore
4
4
  MAJOR = 7
5
- MINOR = 1
6
- PATCH = 2
5
+ MINOR = 2
6
+ PATCH = 0
7
7
 
8
8
  # FatCore version number
9
9
  VERSION = [MAJOR, MINOR, PATCH].compact.join('.')
data/lib/fat_core.rb CHANGED
@@ -3,5 +3,15 @@
3
3
  require 'active_support/core_ext/object/blank'
4
4
  require 'active_support/core_ext/object/deep_dup'
5
5
 
6
- require 'fat_core/version'
7
- require 'fat_core/patches'
6
+ # Gem Overview (extracted from README.org by gem_docs)
7
+ #
8
+ # * Introduction
9
+ # ~fat-core~ is somewhat of a grab bag of core class extensions that I have
10
+ # found useful across several projects. It's higgeldy-piggeldy nature reflects
11
+ # the fact that none of them are important enough to deserve a gem of their own,
12
+ # but nonetheless need to be collected in one place to reduce redundancy across
13
+ # projects and provide a focused place to develop and test them.
14
+ module FatCore
15
+ require 'fat_core/version'
16
+ require 'fat_core/patches'
17
+ end
@@ -158,6 +158,15 @@ the people, for the people, shall not perish from the earth."
158
158
  end
159
159
  end
160
160
 
161
+ it 'guts a string in the middle' do
162
+ expect('hello'.gut(10)).to eq('hello')
163
+ expect('helloworld'.gut(6)).to eq('hel~ld')
164
+ expect('Class A Common Stock'.gut(15)).to eq("Class A~n Stock")
165
+ expect('Class A Common Stock'.gut(15, ellipsis: '...')).to eq("Class ... Stock")
166
+ expect('Class A Common Stock'.gut(15, ellipsis: '')).to eq("Class A n Stock")
167
+ expect('Class A Common Stock'.gut(16, ellipsis: '', squeeze: ' ')).to eq("ClassAComonStock")
168
+ end
169
+
161
170
  it 'converts a string to a regular expression' do
162
171
  # Ignores case by default
163
172
  re = "/hello((\s+)(world))?/".as_regexp
@@ -372,15 +381,22 @@ the people, for the people, shall not perish from the earth."
372
381
  expect("St. Luke's Hospital".matches_with('lukes:hospital')).to eq('Lukes Hospital')
373
382
  end
374
383
 
375
- it 'performs examples in documentation with regexes' do
376
- expect("St. Luke's".matches_with('/st\s*lukes/')).to eq('St Lukes')
377
- expect("St. Luke's Hospital".matches_with('/st lukes/')).to eq('St Lukes')
378
- expect("St. Luke's Hospital".matches_with('/luk.*\bhosp/')).to eq('Lukes Hosp')
379
- expect("St. Luke's Hospital".matches_with('/st(.*)spital\z/')).to eq('St Lukes Hospital')
384
+ it 'does not pre-condition the subject when regexes' do
385
+ expect("St. Luke's Hospital".matches_with('st:lukes')).to eq('St Lukes')
386
+ expect("St. Luke's Hospital".matches_with('lukes')).to eq('Lukes')
387
+ expect("St. Luke's".matches_with('/st.*luke\'s/')).to eq('St. Luke\'s')
388
+ expect("St. Luke's Hospital".matches_with('/st\\. luke/')).to eq('St. Luke')
389
+ expect("St. Luke's Hospital".matches_with('/luk.*\bhosp/')).to eq('Luke\'s Hosp')
390
+ expect("St. Luke's Hospital".matches_with('/st(.*)spital\z/')).to eq('St. Luke\'s Hospital')
380
391
  expect("St. Luke's Hospital".matches_with('/st spital/')).to be_nil
381
392
  expect("St. Luke's Hospital".matches_with('/st.*laks/')).to be_nil
382
393
  expect("St. Luke's Hospital".matches_with('/\Alukes/')).to be_nil
383
- expect("St. Luke's Hospital".matches_with('/lukes hospital/')).to eq('Lukes Hospital')
394
+ expect("St. Luke's Hospital".matches_with('/luke.*hospital/')).to eq('Luke\'s Hospital')
395
+ end
396
+
397
+ it 'makes the regex case insensitive unless option I given' do
398
+ expect("St. Luke's Hospital".matches_with('/LUKE/')).to eq('Luke')
399
+ expect("St. Luke's Hospital".matches_with('/LUKE/I')).to be_nil
384
400
  end
385
401
  end
386
402
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fat_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.1.2
4
+ version: 7.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel E. Doherty
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-11-27 00:00:00.000000000 Z
11
+ date: 2026-05-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -89,6 +89,7 @@ files:
89
89
  - CHANGELOG.org
90
90
  - Gemfile
91
91
  - LICENSE.txt
92
+ - README.md
92
93
  - README.org
93
94
  - Rakefile
94
95
  - TODO.org