dry-inflector 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/lib/dry/inflector.rb +31 -17
- data/lib/dry/inflector/acronyms.rb +42 -0
- data/lib/dry/inflector/inflections.rb +32 -0
- data/lib/dry/inflector/inflections/defaults.rb +8 -1
- data/lib/dry/inflector/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7cccc4cd092473c4c5dfefd8830e97c987fbb6cd6039b6253fd973a0b4d5b8ac
|
4
|
+
data.tar.gz: 6aca715e9ab5497c0f325691783e92a10035b27a3e6fdf483df38b7fb306d6ad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c9c21e1611fe3bafd8cf7e303b5030c1ba3f777fd397a58f2dfba77f8be05b49fdece384e49d82d43043e388ca3fc1f1c6c84508fdfdac02ce9851edfee1dba
|
7
|
+
data.tar.gz: c83c9d597c611194642fe6aed04b3c5f6e37ec9fa212b3501a13c93010305f9c339875a09ba123b8a97fa89f567e90c110af9ac76317f4c16749a5e91601b57e
|
data/CHANGELOG.md
CHANGED
@@ -2,10 +2,20 @@
|
|
2
2
|
|
3
3
|
Inflector for Ruby
|
4
4
|
|
5
|
+
## v0.1.2 - to be released
|
6
|
+
|
7
|
+
### Added
|
8
|
+
|
9
|
+
- [Gustavo Caso & Nikita Shilnikov] Added support for acronyms
|
10
|
+
|
11
|
+
[Compare v0.1.1...master](https://github.com/dry-rb/dry-inflector/compare/v0.1.1...master)
|
12
|
+
|
5
13
|
## v0.1.1 - 2017-11-18
|
6
14
|
### Fixed
|
7
15
|
- [Luca Guidi & Abinoam P. Marques Jr.] Ensure `Dry::Inflector#ordinalize` to work for all the numbers from 0 to 100
|
8
16
|
|
17
|
+
[Compare v0.1.0...v0.1.1](https://github.com/dry-rb/dry-inflector/compare/v0.1.0...v0.1.1)
|
18
|
+
|
9
19
|
## v0.1.0 - 2017-11-17
|
10
20
|
### Added
|
11
21
|
- [Luca Guidi] Introduced `Dry::Inflector#pluralize`
|
data/lib/dry/inflector.rb
CHANGED
@@ -47,7 +47,15 @@ module Dry
|
|
47
47
|
# inflector = Dry::Inflector.new
|
48
48
|
# inflector.camelize("dry/inflector") # => "Dry::Inflector"
|
49
49
|
def camelize(input)
|
50
|
-
input
|
50
|
+
input = input.to_s.dup
|
51
|
+
input.sub!(/^[a-z\d]*/) { |match| inflections.acronyms.apply_to(match) }
|
52
|
+
input.gsub!(%r{(?:_|(/))([a-z\d]*)}i) do
|
53
|
+
m1 = Regexp.last_match(1)
|
54
|
+
m2 = Regexp.last_match(2)
|
55
|
+
"#{m1}#{inflections.acronyms.apply_to(m2)}"
|
56
|
+
end
|
57
|
+
input.gsub!("/", "::")
|
58
|
+
input
|
51
59
|
end
|
52
60
|
|
53
61
|
# Find a constant with the name specified in the argument string
|
@@ -134,10 +142,13 @@ module Dry
|
|
134
142
|
def humanize(input)
|
135
143
|
input = input.to_s
|
136
144
|
result = inflections.humans.apply_to(input)
|
137
|
-
result.
|
145
|
+
result.chomp!("_id")
|
138
146
|
result.tr!("_", " ")
|
139
|
-
result
|
140
|
-
|
147
|
+
match = /(?<separator>\W)/.match(result)
|
148
|
+
separator = match ? match[:separator] : DEFAULT_SEPARATOR
|
149
|
+
result.split(separator).map.with_index { |word, index|
|
150
|
+
inflections.acronyms.apply_to(word, index.zero?)
|
151
|
+
}.join(separator)
|
141
152
|
end
|
142
153
|
|
143
154
|
# Creates a foreign key name
|
@@ -151,7 +162,7 @@ module Dry
|
|
151
162
|
# inflector = Dry::Inflector.new
|
152
163
|
# inflector.foreign_key("Message") => "message_id"
|
153
164
|
def foreign_key(input)
|
154
|
-
"#{
|
165
|
+
"#{underscore(demodulize(input))}_id"
|
155
166
|
end
|
156
167
|
|
157
168
|
# Ordinalize a number
|
@@ -237,7 +248,7 @@ module Dry
|
|
237
248
|
# inflector.tableize("Book") # => "books"
|
238
249
|
def tableize(input)
|
239
250
|
input = input.to_s.gsub(/::/, "_")
|
240
|
-
pluralize(
|
251
|
+
pluralize(underscore(input))
|
241
252
|
end
|
242
253
|
|
243
254
|
# Underscore a string
|
@@ -253,8 +264,17 @@ module Dry
|
|
253
264
|
# inflector = Dry::Inflector.new
|
254
265
|
# inflector.underscore("dry-inflector") # => "dry_inflector"
|
255
266
|
def underscore(input)
|
256
|
-
input = input.to_s.gsub(
|
257
|
-
|
267
|
+
input = input.to_s.gsub("::", "/")
|
268
|
+
input.gsub!(inflections.acronyms.regex) do
|
269
|
+
m1 = Regexp.last_match(1)
|
270
|
+
m2 = Regexp.last_match(2)
|
271
|
+
"#{m1 ? '_' : '' }#{m2.downcase}"
|
272
|
+
end
|
273
|
+
input.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
|
274
|
+
input.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
275
|
+
input.tr!("-", "_")
|
276
|
+
input.downcase!
|
277
|
+
input
|
258
278
|
end
|
259
279
|
|
260
280
|
# Check if the input is an uncountable word
|
@@ -274,18 +294,12 @@ module Dry
|
|
274
294
|
# @api private
|
275
295
|
ORDINALIZE_TH = (11..13).each_with_object({}) { |n, ret| ret[n] = true }.freeze
|
276
296
|
|
277
|
-
# @since 0.1.
|
297
|
+
# @since 0.1.2
|
278
298
|
# @api private
|
279
|
-
|
299
|
+
DEFAULT_SEPARATOR = " "
|
280
300
|
|
281
301
|
# @since 0.1.0
|
282
302
|
# @api private
|
283
|
-
|
284
|
-
input.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
285
|
-
input.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
286
|
-
input.tr!("-", "_")
|
287
|
-
input.downcase!
|
288
|
-
input
|
289
|
-
end
|
303
|
+
attr_reader :inflections
|
290
304
|
end
|
291
305
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dry
|
4
|
+
class Inflector
|
5
|
+
# A set of acronyms
|
6
|
+
#
|
7
|
+
# @since 0.1.2
|
8
|
+
# @api private
|
9
|
+
class Acronyms
|
10
|
+
attr_reader :regex
|
11
|
+
|
12
|
+
# @since 0.1.2
|
13
|
+
# @api private
|
14
|
+
def initialize
|
15
|
+
@rules = {}
|
16
|
+
define_regex_patterns
|
17
|
+
end
|
18
|
+
|
19
|
+
# @since 0.1.2
|
20
|
+
# @api private
|
21
|
+
def apply_to(word, capitalize = true)
|
22
|
+
@rules[word.downcase] || (capitalize ? word.capitalize : word)
|
23
|
+
end
|
24
|
+
|
25
|
+
# @since 0.1.2
|
26
|
+
# @api private
|
27
|
+
def add(rule, replacement)
|
28
|
+
@rules[rule] = replacement
|
29
|
+
define_regex_patterns
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
# @since 0.1.2
|
35
|
+
# @api private
|
36
|
+
def define_regex_patterns
|
37
|
+
regex = @rules.empty? ? /(?=a)b/ : /#{@rules.values.join("|")}/
|
38
|
+
@regex = /(?:(?<=([A-Za-z\d]))|\b)(#{regex})(?=\b|[^a-z])/
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require "set"
|
4
4
|
require "dry/inflector/rules"
|
5
|
+
require "dry/inflector/acronyms"
|
5
6
|
|
6
7
|
module Dry
|
7
8
|
class Inflector
|
@@ -57,6 +58,14 @@ module Dry
|
|
57
58
|
# @api private
|
58
59
|
attr_reader :humans
|
59
60
|
|
61
|
+
# Acronyms
|
62
|
+
#
|
63
|
+
# @return [Dry::Inflector::Acronyms]
|
64
|
+
#
|
65
|
+
# @since 0.1.2
|
66
|
+
# @api private
|
67
|
+
attr_reader :acronyms
|
68
|
+
|
60
69
|
# Instantiate the rules
|
61
70
|
#
|
62
71
|
# @return [Dry::Inflector::Inflections]
|
@@ -69,6 +78,7 @@ module Dry
|
|
69
78
|
@singulars = Rules.new
|
70
79
|
@humans = Rules.new
|
71
80
|
@uncountables = Set[]
|
81
|
+
@acronyms = Acronyms.new
|
72
82
|
|
73
83
|
yield(self) if block_given?
|
74
84
|
end
|
@@ -160,6 +170,28 @@ module Dry
|
|
160
170
|
uncountables.merge(words.flatten)
|
161
171
|
end
|
162
172
|
|
173
|
+
# Add one or more acronyms
|
174
|
+
#
|
175
|
+
# Acronyms affect how basic operations are performed, such
|
176
|
+
# as camelize/underscore.
|
177
|
+
#
|
178
|
+
# @param words [Array<String>] a list of acronyms
|
179
|
+
#
|
180
|
+
# @since 0.1.2
|
181
|
+
#
|
182
|
+
# @example
|
183
|
+
# require "dry/inflector"
|
184
|
+
#
|
185
|
+
# inflector = Dry::Inflector.new do |inflections|
|
186
|
+
# inflections.acronym "HTML"
|
187
|
+
# end
|
188
|
+
#
|
189
|
+
# inflector.camelize("html") # => "HTML"
|
190
|
+
# inflector.underscore("HTMLIsFun") # => "html_is_fun"
|
191
|
+
def acronym(*words)
|
192
|
+
words.each { |word| @acronyms.add(word.downcase, word) }
|
193
|
+
end
|
194
|
+
|
163
195
|
# Add a custom humanize rule
|
164
196
|
#
|
165
197
|
# Specifies a humanized form of a string by a regular expression rule or by a string mapping.
|
@@ -18,6 +18,7 @@ module Dry
|
|
18
18
|
singular(inflect)
|
19
19
|
irregular(inflect)
|
20
20
|
uncountable(inflect)
|
21
|
+
acronyms(inflect)
|
21
22
|
end
|
22
23
|
|
23
24
|
# @since 0.1.0
|
@@ -101,7 +102,13 @@ module Dry
|
|
101
102
|
inflect.uncountable(%w[hovercraft moose deer milk rain Swiss grass equipment information rice money species series fish sheep jeans])
|
102
103
|
end
|
103
104
|
|
104
|
-
|
105
|
+
# @since 0.1.2
|
106
|
+
# @api private
|
107
|
+
def self.acronyms(inflect)
|
108
|
+
inflect.acronym(*%w[JSON HTTP OpenSSL HMAC])
|
109
|
+
end
|
110
|
+
|
111
|
+
private_class_method :plural, :singular, :irregular, :uncountable, :acronyms
|
105
112
|
end
|
106
113
|
# rubocop:enable Metrics/MethodLength
|
107
114
|
# rubocop:enable Metrics/AbcSize
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dry-inflector
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luca Guidi
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2018-04-25 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|
@@ -82,6 +82,7 @@ files:
|
|
82
82
|
- README.md
|
83
83
|
- dry-inflector.gemspec
|
84
84
|
- lib/dry/inflector.rb
|
85
|
+
- lib/dry/inflector/acronyms.rb
|
85
86
|
- lib/dry/inflector/inflections.rb
|
86
87
|
- lib/dry/inflector/inflections/defaults.rb
|
87
88
|
- lib/dry/inflector/rules.rb
|
@@ -107,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
107
108
|
version: '0'
|
108
109
|
requirements: []
|
109
110
|
rubyforge_project:
|
110
|
-
rubygems_version: 2.7.
|
111
|
+
rubygems_version: 2.7.6
|
111
112
|
signing_key:
|
112
113
|
specification_version: 4
|
113
114
|
summary: DRY Inflector
|