module RelatonBib class TypedTitleString # @return [String] attr_reader :type # @return [RelatonBib::FormattedString] attr_reader :title # rubocop:disable Metrics/MethodLength # @param type [String] # @param title [RelatonBib::FormattedString, Hash] # @param content [String] # @param language [String] # @param script [String] def initialize(**args) unless args[:title] || args[:content] raise ArgumentError, %{Keyword "title" or "content" should be passed.} end @type = args[:type] if args[:title] @title = args[:title] else fsargs = args.select do |k, _v| %i[content language script format].include? k end @title = FormattedString.new(fsargs) end end # rubocop:enable Metrics/MethodLength # @param title [String] # @return [Array] def self.from_string(title, lang = nil, script = nil) types = %w[title-intro title-main title-part] ttls = split_title(title) tts = ttls.map.with_index do |p, i| new type: types[i], content: p, language: lang, script: script if p end.compact tts << new(type: "main", content: ttls.compact.join(" - "), language: lang, script: script) end # @param title [String] # @return [Array] def self.split_title(title) ttls = title.sub(/\w\.Imp\s?\d+\u00A0:\u00A0/, "").split " - " case ttls.size when 0, 1 then [nil, ttls.first.to_s, nil] else intro_or_part ttls # when 2, 3 then intro_or_part ttls # else [ttls[0], ttls[1], ttls[2..-1].join(" -- ")] end end # @param ttls [Array] # @return [Array] def self.intro_or_part(ttls) if /^(Part|Partie) \d+:/ =~ ttls[1] [nil, ttls[0], ttls[1..-1].join(" -- ")] else parts = ttls.slice(2..-1) part = parts.join " -- " if parts.any? [ttls[0], ttls[1], part] end end # @param builder [Nokogiri::XML::Builder] def to_xml(builder) builder.parent[:type] = type if type title.to_xml builder end # @return [Hash] def to_hash th = title.to_hash return th unless type hash = { "type" => type } if th.is_a? String hash["content"] = th else hash.merge! th end hash end end end