capitalize-names 1.1.0 → 1.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/lib/capitalize_names/capitalizer.rb +143 -72
- data/lib/capitalize_names/errors.rb +4 -1
- data/lib/capitalize_names/suffixes.rb +4 -2
- data/lib/capitalize_names/surnames.rb +5 -2
- data/lib/capitalize_names/version.rb +3 -1
- data/lib/capitalize_names.rb +12 -13
- metadata +27 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d5c58d13e6411f8264d9b0ea09069999d61bdd1fa5fb3abc0fa08eb2c2bf42aa
|
4
|
+
data.tar.gz: cead79413582058ea0c34f3f67efdcf323d4cfd62f78b9e61000f7b9b719ab09
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 480a2b269eb27e44d8999e2e9753e7edf0f35a9e3dd1416d7c21269b4a8813622486c084d038f24db5438e0d7e666fc2bfc61a5b754b20955ae9051f92eb5f74
|
7
|
+
data.tar.gz: b0bcf24008f2b9d107284964582b20b17d7c52d7861ff563ee5c38f1fe548c3e999bb4a2c46c11779b5ee3998f1862c514fddb646ce5d4de0452b54c94b735f1
|
@@ -1,100 +1,171 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module CapitalizeNames
|
2
4
|
class Capitalizer
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
5
|
+
attr_reader :name, :options
|
6
|
+
|
7
|
+
NAME = %r{
|
8
|
+
( # start capture
|
9
|
+
(?: # start first name token
|
10
|
+
(?:(?:van\ )|(?:de\ (?:la\ )?)|(?:dit\ ))? # optionally match one of van, de, de la, dit and space
|
11
|
+
(?:[[:alnum:]]|'|\(|\))+ # match any unicode character, number, apostrophe or bracket
|
12
|
+
) # end first name token
|
13
|
+
(?: # start optional additional name tokens
|
14
|
+
- # additional name tokens start with -
|
15
|
+
(?: # start additional name token
|
16
|
+
(?:(?:van\ )|(?:de\ (?:la\ )?)|(?:dit\ ))? # optionally match one of van, de, de la, dit and space
|
17
|
+
(?:[[:alnum:]]|'|\(|\))+ # match any unicode character, number, apostrophe or bracket
|
18
|
+
) # end additional name token
|
19
|
+
)* # end optional additional name tokens
|
20
|
+
) # end capture
|
21
|
+
}ix
|
22
|
+
|
23
|
+
MC = /(?<=\A|-)Mc(\w)(?=\w)/i
|
24
|
+
MAC = /(?<=\A|-)Mac(\w)(?=\w)/i
|
25
|
+
O_APOSTROPHE = /(?<=\A|-)O'(\w)(?=\w)/i
|
26
|
+
VAN_SPACE = /(?<=\A|-)Van /i
|
27
|
+
DE_LA_SPACE = /(?<=\A|-)De La /i
|
28
|
+
DE_SPACE = /(?<=\A|-)De /i
|
29
|
+
DIT_SPACE = /(?<=\A|-)Dit /i
|
30
|
+
|
31
|
+
VALID_FORMATS = [:fullname, :firstname, :givenname, :lastname, :surname]
|
32
|
+
|
33
|
+
DEFAULT_OPTIONS = {
|
34
|
+
format: :fullname,
|
35
|
+
skip_mc: false,
|
36
|
+
skip_mac: false,
|
37
|
+
skip_o_apostrophe: false,
|
38
|
+
skip_van_space: false,
|
39
|
+
skip_de_space: false,
|
40
|
+
skip_de_la_space: false,
|
41
|
+
skip_dit_space: false,
|
42
|
+
}
|
43
|
+
|
44
|
+
SUFFIX_MAP = CapitalizeNames::SUFFIXES.each_with_object({}) { |suffix, map| map[suffix.downcase] = suffix }
|
45
|
+
SURNAME_MAP = CapitalizeNames::SURNAMES.each_with_object({}) { |surname, map| map[surname.downcase] = surname }
|
46
|
+
|
47
|
+
def initialize(name, options = {})
|
12
48
|
@name = name
|
49
|
+
@options = DEFAULT_OPTIONS.merge(options)
|
13
50
|
end
|
14
51
|
|
15
52
|
def capitalize!
|
16
53
|
can_process?
|
17
|
-
|
54
|
+
capitalize_name
|
18
55
|
end
|
19
56
|
|
20
57
|
def capitalize
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
name
|
25
|
-
end
|
58
|
+
capitalize!
|
59
|
+
rescue CapitalizeNames::Errors::GenericError
|
60
|
+
name
|
26
61
|
end
|
27
62
|
|
28
63
|
private
|
29
|
-
|
30
|
-
|
31
|
-
|
64
|
+
|
65
|
+
def can_process?
|
66
|
+
raise CapitalizeNames::Errors::InvalidName, "Cannot capitalize nil" unless name
|
67
|
+
|
68
|
+
true
|
69
|
+
end
|
70
|
+
|
71
|
+
def name_format
|
72
|
+
@name_format ||= validate_name_format
|
73
|
+
end
|
74
|
+
|
75
|
+
def validate_name_format
|
76
|
+
unless VALID_FORMATS.include?(options[:format])
|
77
|
+
raise CapitalizeNames::Errors::InvalidOption,
|
78
|
+
"Invalid format: #{@options[:format]}, must be one of #{VALID_FORMATS.join(", ")}"
|
32
79
|
end
|
33
80
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
(
|
42
|
-
|
43
|
-
)
|
44
|
-
) && (
|
45
|
-
(name.length == position+surname_or_suffix.length) || \
|
46
|
-
(name[position+surname_or_suffix.length] == ' ') || (name[position+surname_or_suffix.length] == '-')
|
47
|
-
)
|
81
|
+
options[:format]
|
82
|
+
end
|
83
|
+
|
84
|
+
def tokenize_name
|
85
|
+
name.split(NAME).map do |token|
|
86
|
+
{
|
87
|
+
value: token,
|
88
|
+
is_name: token.match?(NAME),
|
89
|
+
}
|
48
90
|
end
|
91
|
+
end
|
49
92
|
|
50
|
-
|
51
|
-
|
93
|
+
def suffix?(str)
|
94
|
+
SUFFIX_MAP.key?(str.downcase)
|
95
|
+
end
|
52
96
|
|
53
|
-
|
97
|
+
def surname?(str)
|
98
|
+
SURNAME_MAP.key?(str.downcase)
|
99
|
+
end
|
54
100
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
_value = match[1]
|
101
|
+
def capitalize_str(str, surname_rules)
|
102
|
+
str.split(/(\s|-)/).map do |word|
|
103
|
+
next word if word.match?(/(\s|-)/)
|
59
104
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
_name = _name[0..._start] << ' ' << _name[_end..-1]
|
64
|
-
end
|
105
|
+
output = word.capitalize
|
106
|
+
next output unless surname_rules
|
107
|
+
next capitalize_surname(output) if surname?(output)
|
65
108
|
|
66
|
-
|
67
|
-
|
109
|
+
output = output.gsub(MC) { "Mc#{Regexp.last_match(1).upcase}" } unless options[:skip_mc]
|
110
|
+
output = output.gsub(MAC) { "Mac#{Regexp.last_match(1).upcase}" } unless options[:skip_mac]
|
111
|
+
output = output.gsub(O_APOSTROPHE) { "O'#{Regexp.last_match(1).upcase}" } unless options[:skip_o_apostrophe]
|
68
112
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
113
|
+
output
|
114
|
+
end.join("")
|
115
|
+
end
|
116
|
+
|
117
|
+
def capitalize_givenname(str)
|
118
|
+
capitalize_str(str, false)
|
119
|
+
end
|
76
120
|
|
77
|
-
|
121
|
+
def capitalize_suffix(str)
|
122
|
+
SUFFIX_MAP[str.downcase]
|
123
|
+
end
|
124
|
+
|
125
|
+
def capitalize_surname(str)
|
126
|
+
SURNAME_MAP[str.downcase]
|
127
|
+
end
|
128
|
+
|
129
|
+
def capitalize_lastname(str)
|
130
|
+
return capitalize_suffix(str) if suffix?(str)
|
131
|
+
|
132
|
+
output = capitalize_str(str, true)
|
133
|
+
|
134
|
+
output = output.gsub(VAN_SPACE, "van ") unless options[:skip_van_space]
|
135
|
+
output = output.gsub(DIT_SPACE, "dit ") unless options[:skip_dit_space]
|
136
|
+
|
137
|
+
if output.match?(DE_LA_SPACE)
|
138
|
+
output = output.gsub(DE_LA_SPACE, "de la ") unless options[:skip_de_la_space]
|
139
|
+
else
|
140
|
+
output = output.gsub(DE_SPACE, "de ") unless options[:skip_de_space]
|
141
|
+
end
|
78
142
|
|
79
|
-
|
80
|
-
|
81
|
-
|
143
|
+
output
|
144
|
+
end
|
145
|
+
|
146
|
+
def capitalize_name
|
147
|
+
tokens = tokenize_name
|
148
|
+
|
149
|
+
has_capitalized_last_name = false
|
150
|
+
|
151
|
+
tokens.reverse.map do |token|
|
152
|
+
token_value = token[:value]
|
153
|
+
next token_value unless token[:is_name]
|
154
|
+
|
155
|
+
case name_format
|
156
|
+
when :firstname, :givenname
|
157
|
+
capitalize_givenname(token_value)
|
158
|
+
when :lastname, :surname
|
159
|
+
capitalize_lastname(token_value)
|
160
|
+
else
|
161
|
+
if has_capitalized_last_name
|
162
|
+
capitalize_givenname(token_value)
|
82
163
|
else
|
83
|
-
|
164
|
+
has_capitalized_last_name = !suffix?(token_value)
|
165
|
+
capitalize_lastname(token_value)
|
84
166
|
end
|
85
167
|
end
|
86
|
-
|
87
|
-
|
88
|
-
_name << " "
|
89
|
-
|
90
|
-
(CapitalizeNames::SURNAMES + CapitalizeNames::SUFFIXES).each do |surname_or_suffix|
|
91
|
-
position = _name.downcase.index(surname_or_suffix.downcase)
|
92
|
-
if position and surname_suffix_position?(position, _name, surname_or_suffix)
|
93
|
-
_name = _name[0...position] << surname_or_suffix << _name[position+surname_or_suffix.length..-1]
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
_name[0...-1]
|
98
|
-
end
|
168
|
+
end.reverse.join("")
|
169
|
+
end
|
99
170
|
end
|
100
|
-
end
|
171
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module CapitalizeNames
|
2
4
|
SURNAMES = [
|
3
5
|
"ApShaw",
|
@@ -330,6 +332,7 @@ module CapitalizeNames
|
|
330
332
|
"Mackartee",
|
331
333
|
"Mackay",
|
332
334
|
"Macken",
|
335
|
+
"Mackenzie",
|
333
336
|
"Mackert",
|
334
337
|
"Mackey",
|
335
338
|
"Mackie",
|
@@ -584,6 +587,6 @@ module CapitalizeNames
|
|
584
587
|
"VonSeldern",
|
585
588
|
"VonSpringer",
|
586
589
|
"VonVeyelmann",
|
587
|
-
"VonZweidorff"
|
590
|
+
"VonZweidorff",
|
588
591
|
]
|
589
|
-
end
|
592
|
+
end
|
data/lib/capitalize_names.rb
CHANGED
@@ -1,20 +1,19 @@
|
|
1
|
-
#
|
2
|
-
require 'capitalize_names/errors'
|
3
|
-
require 'capitalize_names/capitalizer'
|
4
|
-
require 'capitalize_names/suffixes'
|
5
|
-
require 'capitalize_names/surnames'
|
6
|
-
require 'active_support/core_ext/string/multibyte'
|
1
|
+
# frozen_string_literal: true
|
7
2
|
|
8
|
-
|
3
|
+
# originally based on http://dzone.com/snippets/capitalize-proper-names
|
4
|
+
require "capitalize_names/errors"
|
5
|
+
require "capitalize_names/suffixes"
|
6
|
+
require "capitalize_names/surnames"
|
7
|
+
require "capitalize_names/capitalizer"
|
9
8
|
|
9
|
+
module CapitalizeNames
|
10
10
|
class << self
|
11
|
-
|
12
|
-
|
13
|
-
Capitalizer.new(name).capitalize!
|
11
|
+
def capitalize!(name, options = {})
|
12
|
+
Capitalizer.new(name, options).capitalize!
|
14
13
|
end
|
15
14
|
|
16
|
-
def capitalize(name)
|
17
|
-
Capitalizer.new(name).capitalize
|
15
|
+
def capitalize(name, options = {})
|
16
|
+
Capitalizer.new(name, options).capitalize
|
18
17
|
end
|
19
18
|
end
|
20
|
-
end
|
19
|
+
end
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capitalize-names
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kyle Tate
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-07-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: minitest
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
20
|
-
type: :
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -39,7 +39,21 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: rubocop
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop-shopify
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
59
|
- - ">="
|
@@ -68,24 +82,23 @@ homepage: http://github.com/infiton/capitalize-names
|
|
68
82
|
licenses:
|
69
83
|
- MIT
|
70
84
|
metadata: {}
|
71
|
-
post_install_message:
|
85
|
+
post_install_message:
|
72
86
|
rdoc_options: []
|
73
87
|
require_paths:
|
74
88
|
- lib
|
75
89
|
required_ruby_version: !ruby/object:Gem::Requirement
|
76
90
|
requirements:
|
77
|
-
- - "
|
91
|
+
- - ">="
|
78
92
|
- !ruby/object:Gem::Version
|
79
|
-
version: '2.
|
93
|
+
version: '2.4'
|
80
94
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
95
|
requirements:
|
82
96
|
- - ">="
|
83
97
|
- !ruby/object:Gem::Version
|
84
98
|
version: '0'
|
85
99
|
requirements: []
|
86
|
-
|
87
|
-
|
88
|
-
signing_key:
|
100
|
+
rubygems_version: 3.3.7
|
101
|
+
signing_key:
|
89
102
|
specification_version: 4
|
90
103
|
summary: Capitalizes names; handles edge cases.
|
91
104
|
test_files: []
|