# frozen_string_literal: true require "relaton_bib/contributor" module RelatonBib # Person's full name class FullName include RelatonBib # @return [Array] attr_accessor :forename # @return [Array] attr_accessor :initial # @return [RelatonBib::LocalizedString] attr_accessor :surname # @return [Array] attr_accessor :addition # @return [Array] attr_accessor :prefix # @return [RelatonBib::LocalizedString] attr_reader :completename # @param surname [RelatonBib::LocalizedString] # @param forename [Array] # @param initial [Array] # @param addition [Array] # @param prefix [Array] # @param completename [RelatonBib::LocalizedString] def initialize(**args) unless args[:surname] || args[:completename] raise ArgumentError, "Should be given :surname or :completename" end @surname = args[:surname] @forename = args.fetch :forename, [] @initial = args.fetch :initial, [] @addition = args.fetch :addition, [] @prefix = args.fetch :prefix, [] @completename = args[:completename] end # @param builder [Nokogiri::XML::Builder] def to_xml(builder) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength builder.name do if completename builder.completename { completename.to_xml builder } else prefix.each { |p| builder.prefix { p.to_xml builder } } forename.each { |f| builder.forename { f.to_xml builder } } initial.each { |i| builder.initial { i.to_xml builder } } builder.surname { surname.to_xml builder } addition.each { |a| builder.addition { a.to_xml builder } } end end end # @return [Hash] def to_hash # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity hash = {} hash["forename"] = single_element_array(forename) if forename&.any? hash["initial"] = single_element_array(initial) if initial&.any? hash["surname"] = surname.to_hash if surname hash["addition"] = single_element_array(addition) if addition&.any? hash["prefix"] = single_element_array(prefix) if prefix&.any? hash["completename"] = completename.to_hash if completename hash end # @param pref [String] # @return [String] def to_asciibib(pref) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength prf = pref.empty? ? pref : pref + "." prf += "name." out = forename.map do |fn| fn.to_asciibib "#{prf}forename", forename.size end.join initial.each { |i| out += i.to_asciibib "#{prf}initial", initial.size } out += surname.to_asciibib "#{prf}surname" if surname addition.each do |ad| out += ad.to_asciibib "#{prf}addition", addition.size end prefix.each { |pr| out += pr.to_asciibib "#{prf}prefix", prefix.size } out += completename.to_asciibib "#{prf}completename" if completename out end end # Person identifier type. module PersonIdentifierType ISNI = "isni" URI = "uri" # Checks type. # @param type [String] # @raise [ArgumentError] if type isn't "isni" or "uri" def self.check(type) unless [ISNI, URI].include? type raise ArgumentError, 'Invalid type. It should be "isni" or "uri".' end end end # Person identifier. class PersonIdentifier # @return [RelatonBib::PersonIdentifierType::ISNI, # RelatonBib::PersonIdentifierType::URI] attr_accessor :type # @return [String] attr_accessor :value # @param type [RelatonBib::PersonIdentifierType::ISNI, # RelatonBib::PersonIdentifierType::URI] # @param value [String] def initialize(type, value) PersonIdentifierType.check type @type = type @value = value end # @param builser [Nokogiri::XML::Builder] def to_xml(builder) builder.identifier value, type: type end # @return [Hash] def to_hash { "type" => type, "id" => value } end # @param prefix [String] # @param count [Integer] number of ids # @return [String] def to_asciibib(prefix = "", count = 1) pref = prefix.empty? ? prefix : prefix + "." out = count > 1 ? "#{prefix}::\n" : "" out += "#{pref}type:: #{type}\n" out += "#{pref}value:: #{value}\n" out end end # Person class. class Person < Contributor # @return [RelatonBib::FullName] attr_accessor :name # @return [Array] attr_accessor :affiliation # @return [Array] attr_accessor :identifier # @param name [RelatonBib::FullName] # @param affiliation [Array] # @param contact [Array] # @param identifier [Array] # @param url [String, NilClass] def initialize(name:, affiliation: [], contact: [], identifier: [], url: nil) super(contact: contact, url: url) @name = name @affiliation = affiliation @identifier = identifier end # @param builder [Nokogiri::XML::Builder] def to_xml(builder) builder.person do name.to_xml builder affiliation.each { |a| a.to_xml builder } identifier.each { |id| id.to_xml builder } contact.each { |contact| contact.to_xml builder } end end # @return [Hash] def to_hash hash = { "name" => name.to_hash } if affiliation&.any? hash["affiliation"] = single_element_array(affiliation) end hash["identifier"] = single_element_array(identifier) if identifier&.any? { "person" => hash.merge(super) } end # @param prefix [String] # @count [Integer] number of persons # @return [String] def to_asciibib(prefix = "", count = 1) # rubocop:disable Metrics/AbcSize pref = prefix.sub /\*$/, "person" out = count > 1 ? "#{pref}::\n" : "" out += name.to_asciibib pref affiliation.each { |af| out += af.to_asciibib pref, affiliation.size } identifier.each { |id| out += id.to_asciibib pref, identifier.size } out += super pref out end end end