class ModsDisplay::Name < ModsDisplay::Field include ModsDisplay::RelatorCodes def fields return_fields = @values.map do |value| roles = process_role(value) person = nil if value.displayForm.length > 0 person = ModsDisplay::Name::Person.new(:name => value.displayForm.text, :roles => roles) elsif !name_parts(value).empty? person = ModsDisplay::Name::Person.new(:name => name_parts(value), :roles => roles) end ModsDisplay::Values.new(:label => displayLabel(value) || name_label(value), :values => [person]) if person end.compact collapse_fields(return_fields) end def to_html return nil if fields.empty? or @config.ignore? output = "" fields.each do |field| output << "#{field.label}" output << "" output << field.values.map do |val| if @config.link txt = link_to_value(val.name) txt << " (#{val.roles.join(', ')})" if val.roles txt else val.to_s end end.join(@config.delimiter) output << "" end output end private def name_label(element) if !has_role?(element) || is_primary?(element) || has_author_or_creator_roles?(element) I18n.t('mods_display.author_creator') else I18n.t('mods_display.contributor') end end def has_role?(element) element.respond_to?(:role) and !element.role.empty? end def is_primary?(element) element.attributes["usage"].respond_to?(:value) and element.attributes["usage"].value == "primary" end def has_author_or_creator_roles?(element) begin ["author", "aut", "creator", "cre", ""].include?(element.role.roleTerm.text.downcase) rescue false end end def name_parts(element) output = "" output << [unqualified_name_parts(element), qualified_name_parts(element, "family"), qualified_name_parts(element, "given")].flatten.compact.join(", ") terms = qualified_name_parts(element, "termsOfAddress") unless terms.empty? term_delimiter = ", " if name_part_begins_with_roman_numeral?(terms.first) term_delimiter = " " end output = [output, terms.join(", ")].flatten.compact.join(term_delimiter) end dates = qualified_name_parts(element, "date") unless dates.empty? output = [output, qualified_name_parts(element, "date")].flatten.compact.join(", ") end output end def unqualified_name_parts(element) element.namePart.map do |part| part.text unless part.attributes["type"] end.compact end def qualified_name_parts(element, type) element.namePart.map do |part| if part.attributes["type"].respond_to?(:value) and part.attributes["type"].value == type part.text end end.compact end def name_part_begins_with_roman_numeral?(part) first_part = part.split(/\s|,/).first.strip first_part.chars.all? do |char| ["I", "X", "C", "L", "V"].include? char end end def process_role(element) if element.role.length > 0 and element.role.roleTerm.length > 0 if unencoded_role_term?(element) unencoded_role_term(element) else element.role.roleTerm.map do |term| if term.attributes["type"].respond_to?(:value) and term.attributes["type"].value == "code" and term.attributes["authority"].respond_to?(:value) and term.attributes["authority"].value == "marcrelator" and relator_codes.include?(term.text.strip) relator_codes[term.text.strip] end end.compact end end end def unencoded_role_term(element) roles = element.role.map do |role| role.roleTerm.find do |term| term.attributes["type"].respond_to?(:value) and term.attributes["type"].value == "text" end end.compact roles = element.role.map do |role| role.roleTerm.find do |term| !term.attributes["type"].respond_to?(:value) end end.compact if roles.empty? roles.map{|t| t.text.strip } end def unencoded_role_term?(element) element.role.roleTerm.any? do |term| !term.attributes["type"].respond_to?(:value) or term.attributes["type"].value == "text" end end class Person attr_accessor :name, :roles def initialize(data) @name = data[:name] @roles = data[:roles] && !data[:roles].empty? ? data[:roles] : nil end def to_s text = @name.dup text << " (#{@roles.join(', ')})" if @roles text end end end