lib/nameable.rb in nameable-0.5.1 vs lib/nameable.rb in nameable-1.0.0
- old
+ new
@@ -1,220 +1,10 @@
-# Copyright (c) 2012 Chris Horn http://chorn.com/
-# See MIT-LICENSE.txt
+require "nameable/version"
+require "nameable/error"
+require "nameable/latin"
+require "nameable/extensions"
-# TODO: Make this less sucky.
-
module Nameable
- class Latin
-
- ##
- # Raised if something other than a valid Name is supplied
- class InvalidNameError < StandardError
- end
-
- ##
- # Regex's to match the detritus that people add to their names
- module Patterns
- PREFIX = {
- "Mr." => /^\(*(mr\.*|mister)\)*$/i,
- "Mrs." => /^\(*(mrs\.*|misses)\)*$/i,
- "Ms." => /^\(*(ms\.*|miss)\)*$/i,
- "Dr." => /^\(*(dr\.*|doctor)\)*$/i,
- "Rev." => /^\(*(rev\.*|reverand)\)*$/i,
- "Fr." => /^\(*(fr\.*|friar)\)*$/i,
- "Master" => /^\(*(master)\)*$/i,
- "Sir" => /^\(*(sir)\)*$/i
- }
-
- SUFFIX = {
- "Sr." => /^\(*(sr\.?|senior)\)*$/i,
- "Jr." => /^\(*(jr\.?|junior)\)*$/i,
- "Esq." => /^\(*(esq\.?|esquire)\)*$/i,
- "Ph.D." => /^\(*(phd\.?)\)*$/i
- }
-
- SUFFIX_GENERATIONAL_ROMAN = /^\(*[IVX.]+\)*$/i
- SUFFIX_ACADEMIC = /^(APR|RPh|MD|MA|DMD|DDS|PharmD|EngD|DPhil|JD|DD|DO|BA|BS|BSc|BE|BFA|MA|MS|MSc|MFA|MLA|MBA)$/i
- SUFFIX_PROFESSIONAL = /^(PE|CSA|CPA|CPL|CME|CEng|OFM|CSV|Douchebag)$/i
- SUFFIX_ABBREVIATION = /^[A-Z.]+[A-Z.]+$/ # It should be at least 2 letters
-
- LAST_NAME_PRE_DANGLERS = /^(mc|vere|von|van|da|de|del|della|di|da|pietro|vanden|du|st|la|ter|ten)$/i
- O_LAST_NAME_PRE_CONCATS = /^(o'|o`)$/i
- # MC_LAST_NAME_PRE_CONCAT = /^(mc|da|de)$/i
- # ST_LAST_NAME_PRE_CONCAT = /^(st)\.*$/i
- end
-
- attr_accessor :prefix, :first, :middle, :last, :suffix
-
- ##
- #
- def initialize(parts={})
- self.prefix = parts[:prefix] ? parts[:prefix] : nil
- self.first = parts[:first] ? parts[:first] : nil
- self.middle = parts[:middle] ? parts[:middle] : nil
- self.last = parts[:last] ? parts[:last] : nil
- self.suffix = parts[:suffix] ? parts[:suffix] : nil
- end
-
- ##
- # name is an Array
- def extract_prefix(name)
- return unless name and name.size > 1 and @prefix.nil? and @first.nil?
- Patterns::PREFIX.each_pair do |pretty, regex|
- if name.first =~ regex
- @prefix = pretty
- name.delete(name.first)
- return
- end
- end
- end
-
- ##
- # name is an Array
- def extract_suffix(name)
- return unless name and name.size >= 3
-
- (name.size - 1).downto(2) do |n|
- suff = nil
-
- Patterns::SUFFIX.each_pair do |pretty, regex|
- suff = pretty if name[n] =~ regex
- end
-
- if name[n] =~ Patterns::SUFFIX_ACADEMIC or name[n] =~ Patterns::SUFFIX_PROFESSIONAL or name[n] =~ Patterns::SUFFIX_GENERATIONAL_ROMAN
- suff = name[n].upcase.gsub(/\./,'')
- end
-
- if name.join != name.join.upcase and name[n].length > 1 and name[n] =~ Patterns::SUFFIX_ABBREVIATION
- suff = name[n].upcase.gsub(/\./,'')
- end
-
- if suff
- @suffix = @suffix ? "#{suff}, #{@suffix}" : suff
- name.delete_at(n)
- end
-
- end
- end
-
- ##
- # name is an Array
- def extract_first(name)
- return unless name and name.size >= 1
-
- @first = name.first
- name.delete_at(0)
-
- @first.capitalize! unless @first =~ /[a-z]/ and @first =~ /[A-Z]/
- end
-
- ##
- # name is an Array
- def extract_last(name)
- return unless name and name.size >= 1
-
- @last = name.last
- name.delete_at(name.size - 1)
-
- @last.capitalize! unless @last =~ /[a-z]/ and @last =~ /[A-Z]/
- end
-
- ##
- # name is an Array
- def extract_middle(name)
- return unless name and name.size >= 1
-
- (name.size - 1).downto(0) do |n|
- next unless name[n]
-
- if name[n] =~ Patterns::LAST_NAME_PRE_DANGLERS
- @last = "#{name[n].downcase.capitalize} #{@last}"
- elsif name[n] =~ Patterns::O_LAST_NAME_PRE_CONCATS
- @last = "O'#{@last}"
- # elsif name[n] =~ Patterns::MC_LAST_NAME_PRE_CONCAT
- # @last = "#{name[n].downcase.capitalize} #{@last}"
- # elsif name[n] =~ Patterns::ST_LAST_NAME_PRE_CONCAT
- # @last = "St. #{@last}"
- elsif name[n] =~ /-+/ and n > 0 and name[n-1]
- @last = "#{name[n-1]}-#{@last}"
- name[n-1] = nil
- else
- @middle = @middle ? "#{name[n]} #{@middle}" : name[n]
- end
-
- name.delete_at(n)
- end
-
- @middle.capitalize! if @middle and !(@middle =~ /[a-z]/ and @middle =~ /[A-Z]/)
- @middle = "#{@middle}." if @middle and @middle.size == 1
- end
-
- def parse(name)
- raise InvalidNameError unless name
- if name.class == String
- if name.index(',')
- name = "#{$2} #{$1}" if name =~ /^([a-z]+)\s*,\s*,*(.*)/i
- end
-
- name = name.strip.split(/\s+/)
- end
-
- name = name.first.split(/[^[:alnum:]]+/) if name.size == 1 and name.first.split(/[^[:alnum:]]+/)
-
- extract_prefix(name)
- extract_suffix(name)
- extract_first(name)
- extract_last(name)
- extract_middle(name)
-
- raise InvalidNameError, "A parseable name was not found. #{name.inspect}" unless @first
-
- self
- end
-
- def to_s
- [@prefix, @first, @middle, @last].compact.join(' ') + (@suffix ? ", #{@suffix}" : "")
- end
-
- def to_name
- to_nameable
- end
-
- def to_fullname
- to_s
- end
-
- def to_prefix
- @prefix
- end
-
- def to_firstname
- @first
- end
-
- def to_lastname
- @last
- end
-
- def to_middlename
- @middle
- end
-
- def to_suffix
- @suffix
- end
-
- def to_nameable
- [@first, @last].compact.join(' ')
- end
-
- def to_hash
- return {
- :prefix => @prefix,
- :first => @first,
- :middle => @middle,
- :last => @last,
- :suffix => @suffix
- }
- end
+ def self.parse(name)
+ Nameable::Latin.new.parse(name)
end
end