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.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/.yardopts +3 -4
- data/Gemfile +1 -0
- data/README.md +1199 -0
- data/README.org +266 -225
- data/Rakefile +3 -7
- data/lib/fat_core/all.rb +1 -0
- data/lib/fat_core/string.rb +56 -39
- data/lib/fat_core/version.rb +2 -2
- data/lib/fat_core.rb +12 -2
- data/spec/lib/string_spec.rb +22 -6
- metadata +3 -2
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
data/lib/fat_core/string.rb
CHANGED
|
@@ -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
|
-
|
|
97
|
-
|
|
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
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
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
|
data/lib/fat_core/version.rb
CHANGED
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
|
-
|
|
7
|
-
|
|
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
|
data/spec/lib/string_spec.rb
CHANGED
|
@@ -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 '
|
|
376
|
-
expect("St. Luke's".matches_with('
|
|
377
|
-
expect("St. Luke's Hospital".matches_with('
|
|
378
|
-
expect("St. Luke's
|
|
379
|
-
expect("St. Luke's Hospital".matches_with('/st
|
|
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('/
|
|
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.
|
|
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:
|
|
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
|