require "yaml" require "relaton/cli/base_convertor" require "relaton_bib" module Relaton module Cli class YAMLConvertor < Relaton::Cli::BaseConvertor def to_xml if writable convert_and_write(file_content, :to_xml) else convert_content(file_content).to_xml date_format: :full, bibdata: true end end class << self # Convert to XML # # This interface allow us to convert any YAML file to XML. # It only require us to provide a valid YAML file and it can # do converstion using default attributes, but it also allow # us to provide custom options to customize this converstion # process. # # @param file [File] The complete path to a YAML file # @param options [Hash] Options as hash key, value pairs. # def to_xml(file, options = {}) new(file, options).to_xml end # @param content [Hash] document in YAML format # @return [RelatonBib::BibliographicItem, # RelatonIso::IsoBiblioraphicItem] def convert_single_file(content) if (processor = Registry.instance.by_type(doctype(content["docid"]))) processor.hash_to_bib content else RelatonBib::BibliographicItem.new( **RelatonBib::HashConverter::hash_to_bib(content) ) end end private # @param content [Hash] # @return [String] def doctype(docid) did = docid.is_a?(Array) ? docid.fetch(0) : docid return unless did did["type"] || did.fetch("id")&.match(/^\w+/)&.to_s end end private def default_ext "rxl" end def file_content date_to_string(YAML.load_file(file)) end def date_to_string(obj) if obj.is_a? Hash obj.reduce({}) do |memo, (k, v)| memo[k] = date_to_string(v) memo end elsif obj.is_a? Array obj.reduce([]) { |memo, v| memo << date_to_string(v) } else obj.is_a?(Date) ? obj.to_s : obj end end def convert_collection(content) if content.has_key?("root") content["root"]["items"] = content["root"]["items"].map do |i| # RelatonBib::HashConverter::hash_to_bib(i) self.class.convert_single_file(i) end Relaton::Bibcollection.new(content["root"]) end end def xml_content(_raw_file) convert_content(file_content).to_xml(date_format: :full, bibdata: true) end def convert_content(content) convert_collection(content) || self.class.convert_single_file(content) end end end end