simple_ext 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5f972070633ea700b9c69fc42ed84258ed68bbfe3fb95df8284c62dc3342db42
4
- data.tar.gz: 7e19bc443f5f7ddc6658aaf20936ccfce95e108e4e6498e489d68ec1f7da9973
3
+ metadata.gz: cf6ae6ea43d968052f7497699c79073dbce1b9c1dff9646bd40b05176daf17ca
4
+ data.tar.gz: 779f743a29f86ed1d2ea8b0c779c7f9875efc3fc88ab1497074a65d13eb9c0d8
5
5
  SHA512:
6
- metadata.gz: 8778c40b09e43907f4da9cbfb7473a2d6add060632025925a77553daf61eb58249fe3f4afea0238d59ca0a29596207284d2388682c7fc70a7092d108247cfaa4
7
- data.tar.gz: 8723bbf6360f6637382acae47b95d82bb1b7f6dddfcf8e0605670c449960ac0c36edb60621ed8d480c3fdbc441106cecb77655126328d8b4e58e72d385ea9f65
6
+ metadata.gz: e7b212f5eb4cf9701be6aa5701bcf1c953e1c665fcae644f6f6bbf629a51ccc862fbc3ed9231be337e35feec5e2d4f208072465d917c890c41cf292c08d4250f
7
+ data.tar.gz: 4e3c0499391f114534b282f0db21b28858facd3821f16dde161e369231024d4096784bacf3b014d5c0a3baa1774523033116f26a82a1a54ecdd4b097a73cae07
@@ -23,4 +23,6 @@ class Hash
23
23
  def extract!(*keys)
24
24
  keys.each_with_object(self.class.new) { |key, result| result[key] = delete(key) if has_key?(key) }
25
25
  end
26
+
27
+ alias_method :extract, :slice
26
28
  end
@@ -0,0 +1,105 @@
1
+ # frozen_string_literal: true
2
+
3
+ class String
4
+ # If you pass a single integer, returns a substring of one character at that
5
+ # position. The first character of the string is at position 0, the next at
6
+ # position 1, and so on. If a range is supplied, a substring containing
7
+ # characters at offsets given by the range is returned. In both cases, if an
8
+ # offset is negative, it is counted from the end of the string. Returns +nil+
9
+ # if the initial offset falls outside the string. Returns an empty string if
10
+ # the beginning of the range is greater than the end of the string.
11
+ #
12
+ # str = "hello"
13
+ # str.at(0) # => "h"
14
+ # str.at(1..3) # => "ell"
15
+ # str.at(-2) # => "l"
16
+ # str.at(-2..-1) # => "lo"
17
+ # str.at(5) # => nil
18
+ # str.at(5..-1) # => ""
19
+ #
20
+ # If a Regexp is given, the matching portion of the string is returned.
21
+ # If a String is given, that given string is returned if it occurs in
22
+ # the string. In both cases, +nil+ is returned if there is no match.
23
+ #
24
+ # str = "hello"
25
+ # str.at(/lo/) # => "lo"
26
+ # str.at(/ol/) # => nil
27
+ # str.at("lo") # => "lo"
28
+ # str.at("ol") # => nil
29
+ def at(position)
30
+ self[position]
31
+ end
32
+
33
+ # Returns a substring from the given position to the end of the string.
34
+ # If the position is negative, it is counted from the end of the string.
35
+ #
36
+ # str = "hello"
37
+ # str.from(0) # => "hello"
38
+ # str.from(3) # => "lo"
39
+ # str.from(-2) # => "lo"
40
+ #
41
+ # You can mix it with +to+ method and do fun things like:
42
+ #
43
+ # str = "hello"
44
+ # str.from(0).to(-1) # => "hello"
45
+ # str.from(1).to(-2) # => "ell"
46
+ def from(position)
47
+ self[position, length]
48
+ end
49
+
50
+ # Returns a substring from the beginning of the string to the given position.
51
+ # If the position is negative, it is counted from the end of the string.
52
+ #
53
+ # str = "hello"
54
+ # str.to(0) # => "h"
55
+ # str.to(3) # => "hell"
56
+ # str.to(-2) # => "hell"
57
+ #
58
+ # You can mix it with +from+ method and do fun things like:
59
+ #
60
+ # str = "hello"
61
+ # str.from(0).to(-1) # => "hello"
62
+ # str.from(1).to(-2) # => "ell"
63
+ def to(position)
64
+ position += size if position < 0
65
+ self[0, position + 1] || +""
66
+ end
67
+
68
+ # Returns the first character. If a limit is supplied, returns a substring
69
+ # from the beginning of the string until it reaches the limit value. If the
70
+ # given limit is greater than or equal to the string length, returns a copy of self.
71
+ #
72
+ # str = "hello"
73
+ # str.first # => "h"
74
+ # str.first(1) # => "h"
75
+ # str.first(2) # => "he"
76
+ # str.first(0) # => ""
77
+ # str.first(6) # => "hello"
78
+ def first(limit = 1)
79
+ self[0, limit] || raise(ArgumentError, "negative limit")
80
+ end
81
+
82
+ # Returns the last character of the string. If a limit is supplied, returns a substring
83
+ # from the end of the string until it reaches the limit value (counting backwards). If
84
+ # the given limit is greater than or equal to the string length, returns a copy of self.
85
+ #
86
+ # str = "hello"
87
+ # str.last # => "o"
88
+ # str.last(1) # => "o"
89
+ # str.last(2) # => "lo"
90
+ # str.last(0) # => ""
91
+ # str.last(6) # => "hello"
92
+ def last(limit = 1)
93
+ self[[length - limit, 0].max, limit] || raise(ArgumentError, "negative limit")
94
+ end
95
+
96
+ # The inverse of <tt>String#include?</tt>. Returns true if the string
97
+ # does not include the other string.
98
+ #
99
+ # "hello".exclude? "lo" # => false
100
+ # "hello".exclude? "ol" # => true
101
+ # "hello".exclude? ?h # => false
102
+ def exclude?(string)
103
+ !include?(string)
104
+ end
105
+ end
@@ -0,0 +1,145 @@
1
+ # frozen_string_literal: true
2
+
3
+ class String
4
+ # Returns the string, first removing all whitespace on both ends of
5
+ # the string, and then changing remaining consecutive whitespace
6
+ # groups into one space each.
7
+ #
8
+ # Note that it handles both ASCII and Unicode whitespace.
9
+ #
10
+ # %{ Multi-line
11
+ # string }.squish # => "Multi-line string"
12
+ # " foo bar \n \t boo".squish # => "foo bar boo"
13
+ def squish
14
+ dup.squish!
15
+ end
16
+
17
+ # Performs a destructive squish. See String#squish.
18
+ # str = " foo bar \n \t boo"
19
+ # str.squish! # => "foo bar boo"
20
+ # str # => "foo bar boo"
21
+ def squish!
22
+ gsub!(/[[:space:]]+/, " ")
23
+ strip!
24
+ self
25
+ end
26
+
27
+ # Returns a new string with all occurrences of the patterns removed.
28
+ # str = "foo bar test"
29
+ # str.remove(" test") # => "foo bar"
30
+ # str.remove(" test", /bar/) # => "foo "
31
+ # str # => "foo bar test"
32
+ def remove(*patterns)
33
+ dup.remove!(*patterns)
34
+ end
35
+
36
+ # Alters the string by removing all occurrences of the patterns.
37
+ # str = "foo bar test"
38
+ # str.remove!(" test", /bar/) # => "foo "
39
+ # str # => "foo "
40
+ def remove!(*patterns)
41
+ patterns.each do |pattern|
42
+ gsub! pattern, ""
43
+ end
44
+
45
+ self
46
+ end
47
+
48
+ # Truncates a given +text+ after a given <tt>length</tt> if +text+ is longer than <tt>length</tt>:
49
+ #
50
+ # 'Once upon a time in a world far far away'.truncate(27)
51
+ # # => "Once upon a time in a wo..."
52
+ #
53
+ # Pass a string or regexp <tt>:separator</tt> to truncate +text+ at a natural break:
54
+ #
55
+ # 'Once upon a time in a world far far away'.truncate(27, separator: ' ')
56
+ # # => "Once upon a time in a..."
57
+ #
58
+ # 'Once upon a time in a world far far away'.truncate(27, separator: /\s/)
59
+ # # => "Once upon a time in a..."
60
+ #
61
+ # The last characters will be replaced with the <tt>:omission</tt> string (defaults to "...")
62
+ # for a total length not exceeding <tt>length</tt>:
63
+ #
64
+ # 'And they found that many people were sleeping better.'.truncate(25, omission: '... (continued)')
65
+ # # => "And they f... (continued)"
66
+ def truncate(truncate_at, options = {})
67
+ return dup unless length > truncate_at
68
+
69
+ omission = options[:omission] || "..."
70
+ length_with_room_for_omission = truncate_at - omission.length
71
+ stop = \
72
+ if options[:separator]
73
+ rindex(options[:separator], length_with_room_for_omission) || length_with_room_for_omission
74
+ else
75
+ length_with_room_for_omission
76
+ end
77
+
78
+ +"#{self[0, stop]}#{omission}"
79
+ end
80
+
81
+ # Truncates +text+ to at most <tt>bytesize</tt> bytes in length without
82
+ # breaking string encoding by splitting multibyte characters or breaking
83
+ # grapheme clusters ("perceptual characters") by truncating at combining
84
+ # characters.
85
+ #
86
+ # >> "🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪".size
87
+ # => 20
88
+ # >> "🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪".bytesize
89
+ # => 80
90
+ # >> "🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪".truncate_bytes(20)
91
+ # => "🔪🔪🔪🔪…"
92
+ #
93
+ # The truncated text ends with the <tt>:omission</tt> string, defaulting
94
+ # to "…", for a total length not exceeding <tt>bytesize</tt>.
95
+ def truncate_bytes(truncate_at, omission: "…")
96
+ omission ||= ""
97
+
98
+ case
99
+ when bytesize <= truncate_at
100
+ dup
101
+ when omission.bytesize > truncate_at
102
+ raise ArgumentError, "Omission #{omission.inspect} is #{omission.bytesize}, larger than the truncation length of #{truncate_at} bytes"
103
+ when omission.bytesize == truncate_at
104
+ omission.dup
105
+ else
106
+ self.class.new.tap do |cut|
107
+ cut_at = truncate_at - omission.bytesize
108
+
109
+ scan(/\X/) do |grapheme|
110
+ if cut.bytesize + grapheme.bytesize <= cut_at
111
+ cut << grapheme
112
+ else
113
+ break
114
+ end
115
+ end
116
+
117
+ cut << omission
118
+ end
119
+ end
120
+ end
121
+
122
+ # Truncates a given +text+ after a given number of words (<tt>words_count</tt>):
123
+ #
124
+ # 'Once upon a time in a world far far away'.truncate_words(4)
125
+ # # => "Once upon a time..."
126
+ #
127
+ # Pass a string or regexp <tt>:separator</tt> to specify a different separator of words:
128
+ #
129
+ # 'Once<br>upon<br>a<br>time<br>in<br>a<br>world'.truncate_words(5, separator: '<br>')
130
+ # # => "Once<br>upon<br>a<br>time<br>in..."
131
+ #
132
+ # The last characters will be replaced with the <tt>:omission</tt> string (defaults to "..."):
133
+ #
134
+ # 'And they found that many people were sleeping better.'.truncate_words(5, omission: '... (continued)')
135
+ # # => "And they found that many... (continued)"
136
+ def truncate_words(words_count, options = {})
137
+ sep = options[:separator] || /\s+/
138
+ sep = Regexp.escape(sep.to_s) unless Regexp === sep
139
+ if self =~ /\A((?>.+?#{sep}){#{words_count - 1}}.+?)#{sep}.*/m
140
+ $1 + (options[:omission] || "...")
141
+ else
142
+ dup
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'string/access.rb'
4
+ require_relative 'string/filters.rb'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_ext
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tushar Hawaldar
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-05 00:00:00.000000000 Z
11
+ date: 2020-02-06 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Core ruby extentions extracted from Rails ActiveSupport
14
14
  email:
@@ -38,6 +38,9 @@ files:
38
38
  - lib/simple_ext/object/instance_variables.rb
39
39
  - lib/simple_ext/object/to_query.rb
40
40
  - lib/simple_ext/object/try.rb
41
+ - lib/simple_ext/string.rb
42
+ - lib/simple_ext/string/access.rb
43
+ - lib/simple_ext/string/filters.rb
41
44
  homepage: https://github.com/kumartushar/simple_ext.git
42
45
  licenses:
43
46
  - MIT