capitalize-names 1.0.5 → 1.2.0

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
- SHA1:
3
- metadata.gz: 952173c8584a6003c41afbb6fed489192388cd33
4
- data.tar.gz: 0d041067c287a94e95b37793a937049cf1968dcd
2
+ SHA256:
3
+ metadata.gz: d5c58d13e6411f8264d9b0ea09069999d61bdd1fa5fb3abc0fa08eb2c2bf42aa
4
+ data.tar.gz: cead79413582058ea0c34f3f67efdcf323d4cfd62f78b9e61000f7b9b719ab09
5
5
  SHA512:
6
- metadata.gz: 13356663ebb5fc5153cecb45dfe0222061bcefe27a21ec4c93c9e5abad001dac72f235215c2ec1927690a4e0904952675096661df6e0b49a96793b03e6238f4e
7
- data.tar.gz: 9733023e31a9859ba77b4c4f04e9ff872be83d7cb2c13b4801ecf29c6f705529e7dc4620e10a0a2206075c29b2283794f69ce4a280b8aa78bcf2dbd39d6a1456
6
+ metadata.gz: 480a2b269eb27e44d8999e2e9753e7edf0f35a9e3dd1416d7c21269b4a8813622486c084d038f24db5438e0d7e666fc2bfc61a5b754b20955ae9051f92eb5f74
7
+ data.tar.gz: b0bcf24008f2b9d107284964582b20b17d7c52d7861ff563ee5c38f1fe548c3e999bb4a2c46c11779b5ee3998f1862c514fddb646ce5d4de0452b54c94b735f1
@@ -1,84 +1,171 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CapitalizeNames
2
4
  class Capitalizer
3
- attr_accessor :name
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
4
30
 
5
- MC = /^Mc(\w)(?=\w)/i
6
- MAC = /^Mac(\w)(?=\w)/i
7
- O_APOSTROPHE = /^O'(\w)(?=\w)/i
31
+ VALID_FORMATS = [:fullname, :firstname, :givenname, :lastname, :surname]
8
32
 
9
- def initialize(name)
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 = {})
10
48
  @name = name
49
+ @options = DEFAULT_OPTIONS.merge(options)
11
50
  end
12
51
 
13
52
  def capitalize!
14
53
  can_process?
15
- _capitalize
54
+ capitalize_name
16
55
  end
17
56
 
18
57
  def capitalize
19
- begin
20
- capitalize!
21
- rescue CapitalizeNames::Errors::GenericError
22
- name
23
- end
58
+ capitalize!
59
+ rescue CapitalizeNames::Errors::GenericError
60
+ name
24
61
  end
25
62
 
26
63
  private
27
- def can_process?
28
- raise CapitalizeNames::Errors::InvalidName, "Cannot capitalize nil" unless name
29
- true
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(", ")}"
30
79
  end
31
80
 
32
- def surname_suffix_position?(position, name, surname_or_suffix)
33
- # surname/suffix must be:
34
- # 1. at start of name or after a space or a -
35
- # -and-
36
- # 2. followed by the end of string or a space or a -
37
- (
38
- (position == 0) || \
39
- (
40
- position > 0 && (name[position-1] == ' ' || name[position-1] == '-')
41
- )
42
- ) && (
43
- (name.length == position+surname_or_suffix.length) || \
44
- (name[position+surname_or_suffix.length] == ' ') || (name[position+surname_or_suffix.length] == '-')
45
- )
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
+ }
46
90
  end
91
+ end
47
92
 
48
- def _capitalize
49
- _name = name
93
+ def suffix?(str)
94
+ SUFFIX_MAP.key?(str.downcase)
95
+ end
50
96
 
51
- hyphens_index = []
97
+ def surname?(str)
98
+ SURNAME_MAP.key?(str.downcase)
99
+ end
52
100
 
53
- while _name.index('-') do
54
- index = _name.index('-')
55
- hyphens_index << index
56
- _name = _name[0...index] << ' ' << _name[index+1..-1]
57
- end
101
+ def capitalize_str(str, surname_rules)
102
+ str.split(/(\s|-)/).map do |word|
103
+ next word if word.match?(/(\s|-)/)
58
104
 
59
- _name = _name.split.map{ |w|
60
- w.mb_chars.capitalize.to_str
61
- }.map{ |w|
62
- w.gsub(MC) { "Mc#{$1.upcase}" }\
63
- .gsub(MAC) { "Mac#{$1.upcase}" }\
64
- .gsub(O_APOSTROPHE) { "O'#{$1.upcase}" }
65
- }
105
+ output = word.capitalize
106
+ next output unless surname_rules
107
+ next capitalize_surname(output) if surname?(output)
66
108
 
67
- _name = _name.join(' ')
68
- hyphens_index.each do |idx|
69
- _name = _name[0...idx] << '-' << (_name[idx+1..-1] || "")
70
- end
71
-
72
- _name = _name.gsub("Van ", "van ").gsub("De ", "de ").gsub("Dit ", "dit ")
73
- _name << ' '
74
-
75
- (CapitalizeNames::SURNAMES + CapitalizeNames::SUFFIXES).each do |surname_or_suffix|
76
- position = _name.downcase.index(surname_or_suffix.downcase)
77
- if position and surname_suffix_position?(position, _name, surname_or_suffix)
78
- _name = _name[0...position] << surname_or_suffix << _name[position+surname_or_suffix.length..-1]
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]
112
+
113
+ output
114
+ end.join("")
115
+ end
116
+
117
+ def capitalize_givenname(str)
118
+ capitalize_str(str, false)
119
+ end
120
+
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
142
+
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)
163
+ else
164
+ has_capitalized_last_name = !suffix?(token_value)
165
+ capitalize_lastname(token_value)
79
166
  end
80
167
  end
81
- _name.strip
82
- end
168
+ end.reverse.join("")
169
+ end
83
170
  end
84
- end
171
+ end
@@ -1,6 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CapitalizeNames
2
4
  module Errors
3
- class GenericError < Exception; end
5
+ class GenericError < StandardError; end
4
6
  class InvalidName < GenericError; end
7
+ class InvalidOption < GenericError; end
5
8
  end
6
9
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CapitalizeNames
2
4
  SUFFIXES = [
3
5
  "II",
@@ -17,6 +19,6 @@ module CapitalizeNames
17
19
  "4th",
18
20
  "(4th)",
19
21
  "5th",
20
- "(5th)"
22
+ "(5th)",
21
23
  ]
22
- end
24
+ 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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CapitalizeNames
2
- VERSION = "1.0.5"
4
+ VERSION = "1.2.0"
3
5
  end
@@ -1,20 +1,19 @@
1
- #based on http://dzone.com/snippets/capitalize-proper-names
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
- module CapitalizeNames
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
- def capitalize!(name)
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,43 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capitalize-names
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.5
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: 2016-04-17 00:00:00.000000000 Z
11
+ date: 2022-07-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: activesupport
14
+ name: minitest
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '3'
20
- type: :runtime
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: '3'
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: minitest
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubocop
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
- - - "~>"
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
+ - - ">="
32
53
  - !ruby/object:Gem::Version
33
- version: 5.8.4
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop-shopify
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
34
62
  type: :development
35
63
  prerelease: false
36
64
  version_requirements: !ruby/object:Gem::Requirement
37
65
  requirements:
38
- - - "~>"
66
+ - - ">="
39
67
  - !ruby/object:Gem::Version
40
- version: 5.8.4
68
+ version: '0'
41
69
  description: 'A simple gem to capitalize names, based off of: http://dzone.com/snippets/capitalize-proper-names'
42
70
  email: kbt.tate@gmail.com
43
71
  executables: []
@@ -54,24 +82,23 @@ homepage: http://github.com/infiton/capitalize-names
54
82
  licenses:
55
83
  - MIT
56
84
  metadata: {}
57
- post_install_message:
85
+ post_install_message:
58
86
  rdoc_options: []
59
87
  require_paths:
60
88
  - lib
61
89
  required_ruby_version: !ruby/object:Gem::Requirement
62
90
  requirements:
63
- - - "~>"
91
+ - - ">="
64
92
  - !ruby/object:Gem::Version
65
- version: '2.0'
93
+ version: '2.4'
66
94
  required_rubygems_version: !ruby/object:Gem::Requirement
67
95
  requirements:
68
96
  - - ">="
69
97
  - !ruby/object:Gem::Version
70
98
  version: '0'
71
99
  requirements: []
72
- rubyforge_project:
73
- rubygems_version: 2.4.5.1
74
- signing_key:
100
+ rubygems_version: 3.3.7
101
+ signing_key:
75
102
  specification_version: 4
76
103
  summary: Capitalizes names; handles edge cases.
77
104
  test_files: []