Skip to content

Commit feb5832

Browse files
authored
Merge pull request #90 from jcp/capitalization
Added capitalization rules to Constants class
2 parents be1e851 + f4bbf42 commit feb5832

File tree

5 files changed

+103
-11
lines changed

5 files changed

+103
-11
lines changed

docs/customize.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ Other editable attributes
5757

5858
* :py:obj:`~nameparser.config.Constants.string_format` - controls output from `str()`
5959
* :py:obj:`~nameparser.config.Constants.empty_attribute_default` - value returned by empty attributes, defaults to empty string
60+
* :py:obj:`~nameparser.config.Constants.capitalize_name` - If set, applies :py:meth:`~nameparser.parser.HumanName.capitalize` to :py:class:`~nameparser.parser.HumanName` instance.
61+
* :py:obj:`~nameparser.config.Constants.force_mixed_case_capitalization` - If set, forces the capitalization of mixed case strings when :py:meth:`~nameparser.parser.HumanName.capitalize` is called.
6062

6163

6264

docs/usage.rst

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,8 @@ Capitalization Support
7272

7373
The HumanName class can try to guess the correct capitalization of name
7474
entered in all upper or lower case. By default, it will not adjust
75-
the case of names entered in mixed case. To run capitalization on all names
76-
pass the parameter `force=True`.
77-
75+
the case of names entered in mixed case. To run capitalization on a
76+
`HumanName` instance, pass the parameter `force=True`.
7877

7978
Capitalize the name.
8079

@@ -94,6 +93,31 @@ pass the parameter `force=True`.
9493
>>> str(name)
9594
'Shirley MacLaine'
9695

96+
To apply capitalization to all `HumanName` instances, set
97+
:py:attr:`~nameparser.config.Constants.capitalize_name` to `True`.
98+
99+
.. doctest:: capitalize_name
100+
:options: +NORMALIZE_WHITESPACE
101+
102+
>>> from nameparser.config import CONSTANTS
103+
>>> CONSTANTS.capitalize_name = True
104+
>>> name = HumanName("bob v. de la macdole-eisenhower phd")
105+
>>> str(name)
106+
'Bob V. de la MacDole-Eisenhower Ph.D.'
107+
108+
To force the capitalization of mixed case strings on all `HumanName` instances,
109+
set :py:attr:`~nameparser.config.Constants.force_mixed_case_capitalization` to `True`.
110+
111+
.. doctest:: force_mixed_case_capitalization
112+
:options: +NORMALIZE_WHITESPACE
113+
114+
>>> from nameparser.config import CONSTANTS
115+
>>> CONSTANTS.force_mixed_case_capitalization = True
116+
>>> name = HumanName('Shirley Maclaine')
117+
>>> name.capitalize()
118+
>>> str(name)
119+
'Shirley MacLaine'
120+
97121

98122
Nickname Handling
99123
------------------

nameparser/config/__init__.py

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,37 @@ class Constants(object):
179179
'John'
180180
181181
"""
182-
183-
182+
capitalize_name = False
183+
"""
184+
If set, applies :py:meth:`~nameparser.parser.HumanName.capitalize` to
185+
:py:class:`~nameparser.parser.HumanName` instance.
186+
187+
.. doctest::
188+
189+
>>> from nameparser.config import CONSTANTS
190+
>>> CONSTANTS.capitalize_name = True
191+
>>> name = HumanName("bob v. de la macdole-eisenhower phd")
192+
>>> str(name)
193+
'Bob V. de la MacDole-Eisenhower Ph.D.'
194+
195+
"""
196+
force_mixed_case_capitalization = False
197+
"""
198+
If set, forces the capitalization of mixed case strings when
199+
:py:meth:`~nameparser.parser.HumanName.capitalize` is called.
200+
201+
.. doctest::
202+
203+
>>> from nameparser.config import CONSTANTS
204+
>>> CONSTANTS.force_mixed_case_capitalization = True
205+
>>> name = HumanName('Shirley Maclaine')
206+
>>> name.capitalize()
207+
>>> str(name)
208+
'Shirley MacLaine'
209+
210+
"""
211+
212+
184213
def __init__(self,
185214
prefixes=PREFIXES,
186215
suffix_acronyms=SUFFIX_ACRONYMS,

nameparser/parser.py

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ def pre_process(self):
387387
This method happens at the beginning of the :py:func:`parse_full_name`
388388
before any other processing of the string aside from unicode
389389
normalization, so it's a good place to do any custom handling in a
390-
subclass. Runs :py:func:`parse_nicknames` and py:func:`squash_emoji`.
390+
subclass. Runs :py:func:`parse_nicknames` and :py:func:`squash_emoji`.
391391
392392
"""
393393
self.fix_phd()
@@ -397,9 +397,11 @@ def pre_process(self):
397397
def post_process(self):
398398
"""
399399
This happens at the end of the :py:func:`parse_full_name` after
400-
all other processing has taken place. Runs :py:func:`handle_firstnames`.
400+
all other processing has taken place. Runs :py:func:`handle_firstnames`
401+
and :py:func:`handle_capitalization`.
401402
"""
402403
self.handle_firstnames()
404+
self.handle_capitalization()
403405

404406
def fix_phd(self):
405407
_re = self.C.regexes.phd
@@ -675,9 +677,9 @@ def join_on_conjunctions(self, pieces, additional_parts_count=0):
675677
:param list pieces: name pieces strings after split on spaces
676678
:param int additional_parts_count:
677679
:return: new list with piece next to conjunctions merged into one piece
678-
with spaces in it.
680+
with spaces in it.
679681
:rtype: list
680-
682+
681683
"""
682684
length = len(pieces) + additional_parts_count
683685
# don't join on conjunctions if there's only 2 parts
@@ -833,14 +835,16 @@ def cap_piece(self, piece, attribute):
833835
replacement = lambda m: self.cap_word(m.group(0), attribute)
834836
return self.C.regexes.word.sub(replacement, piece)
835837

836-
def capitalize(self, force=False):
838+
def capitalize(self, force=None):
837839
"""
838840
The HumanName class can try to guess the correct capitalization of name
839841
entered in all upper or lower case. By default, it will not adjust the
840842
case of names entered in mixed case. To run capitalization on all names
841843
pass the parameter `force=True`.
842844
843-
:param bool force: force capitalization of strings that include mixed case
845+
:param bool force: Forces capitalization of mixed case strings. This
846+
parameter overrides rules set within
847+
:py:class:`~nameparser.config.CONSTANTS`.
844848
845849
**Usage**
846850
@@ -861,10 +865,21 @@ def capitalize(self, force=False):
861865
862866
"""
863867
name = u(self)
868+
force = self.C.force_mixed_case_capitalization \
869+
if force is None else force
870+
864871
if not force and not (name == name.upper() or name == name.lower()):
865872
return
866873
self.title_list = self.cap_piece(self.title , 'title').split(' ')
867874
self.first_list = self.cap_piece(self.first , 'first').split(' ')
868875
self.middle_list = self.cap_piece(self.middle, 'middle').split(' ')
869876
self.last_list = self.cap_piece(self.last , 'last').split(' ')
870877
self.suffix_list = self.cap_piece(self.suffix, 'suffix').split(', ')
878+
879+
def handle_capitalization(self):
880+
"""
881+
Handles capitalization configurations set within
882+
:py:class:`~nameparser.config.CONSTANTS`.
883+
"""
884+
if self.C.capitalize_name:
885+
self.capitalize()

tests.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2088,6 +2088,28 @@ def test_formatting_constants_attribute(self):
20882088
self.assertEqual(u(hn), "TEST2")
20892089
CONSTANTS.string_format = _orig
20902090

2091+
def test_capitalize_name_constants_attribute(self):
2092+
from nameparser.config import CONSTANTS
2093+
CONSTANTS.capitalize_name = True
2094+
hn = HumanName("bob v. de la macdole-eisenhower phd")
2095+
self.assertEqual(str(hn), "Bob V. de la MacDole-Eisenhower Ph.D.")
2096+
CONSTANTS.capitalize_name = False
2097+
2098+
def test_force_mixed_case_capitalization_constants_attribute(self):
2099+
from nameparser.config import CONSTANTS
2100+
CONSTANTS.force_mixed_case_capitalization = True
2101+
hn = HumanName('Shirley Maclaine')
2102+
hn.capitalize()
2103+
self.assertEqual(str(hn), "Shirley MacLaine")
2104+
CONSTANTS.force_mixed_case_capitalization = False
2105+
2106+
def test_capitalize_name_and_force_mixed_case_capitalization_constants_attributes(self):
2107+
from nameparser.config import CONSTANTS
2108+
CONSTANTS.capitalize_name = True
2109+
CONSTANTS.force_mixed_case_capitalization = True
2110+
hn = HumanName('Shirley Maclaine')
2111+
self.assertEqual(str(hn), "Shirley MacLaine")
2112+
20912113
def test_quote_nickname_formating(self):
20922114
hn = HumanName("Rev John A. Kenneth Doe III (Kenny)")
20932115
hn.string_format = "{title} {first} {middle} {last} {suffix} '{nickname}'"

0 commit comments

Comments
 (0)