# frozen_string_literal: true module Briard module Readers module RisReader RIS_TO_SO_TRANSLATIONS = { 'BLOG' => 'BlogPosting', 'GEN' => 'CreativeWork', 'CTLG' => 'DataCatalog', 'DATA' => 'Dataset', 'FIGURE' => 'ImageObject', 'THES' => 'Thesis', 'MPCT' => 'Movie', 'JOUR' => 'ScholarlyArticle', 'COMP' => 'SoftwareSourceCode', 'VIDEO' => 'VideoObject', 'ELEC' => 'WebPage' }.freeze RIS_TO_CP_TRANSLATIONS = { 'JOUR' => 'article-journal' }.freeze RIS_TO_BIB_TRANSLATIONS = { 'JOUR' => 'article', 'BOOK' => 'book', 'CHAP' => 'inbook', 'CPAPER' => 'inproceedings', 'GEN' => 'misc', 'THES' => 'phdthesis', 'CONF' => 'proceedings', 'RPRT' => 'techreport', 'UNPD' => 'unpublished' }.freeze def read_ris(string: nil, **options) read_options = ActiveSupport::HashWithIndifferentAccess.new(options.except(:doi, :id, :url, :sandbox, :validate, :ra)) meta = ris_meta(string: string) ris_type = meta.fetch('TY', nil) || 'GEN' schema_org = RIS_TO_SO_TRANSLATIONS[ris_type] || 'CreativeWork' types = { 'resourceTypeGeneral' => Metadata::RIS_TO_DC_TRANSLATIONS[ris_type], 'schemaOrg' => schema_org, 'citeproc' => RIS_TO_CP_TRANSLATIONS[schema_org] || 'misc', 'ris' => ris_type }.compact id = normalize_doi(options[:doi] || meta.fetch('DO', nil)) author = Array.wrap(meta.fetch('AU', nil)).map { |a| { 'creatorName' => a } } date_parts = meta.fetch('PY', nil).to_s.split('/') created_date_parts = meta.fetch('Y1', nil).to_s.split('/') dates = [] if meta.fetch('PY', nil).present? dates << { 'date' => get_date_from_parts(*date_parts), 'dateType' => 'Issued' } end if meta.fetch('Y1', nil).present? dates << { 'date' => get_date_from_parts(*created_date_parts), 'dateType' => 'Created' } end publication_year = get_date_from_parts(*date_parts).to_s[0..3] related_identifiers = if meta.fetch('T2', nil).present? && meta.fetch('SN', nil).present? [{ 'type' => 'Periodical', 'id' => meta.fetch('SN', nil), 'relatedIdentifierType' => 'ISSN', 'relationType' => 'IsPartOf', 'title' => meta.fetch('T2', nil) }.compact] else [] end container = if meta.fetch('T2', nil).present? { 'type' => 'Journal', 'title' => meta.fetch('T2', nil), 'identifier' => meta.fetch('SN', nil), 'volume' => meta.fetch('VL', nil), 'issue' => meta.fetch('IS', nil), 'firstPage' => meta.fetch('SP', nil), 'lastPage' => meta.fetch('EP', nil) }.compact end state = meta.fetch('DO', nil).present? || read_options.present? ? 'findable' : 'not_found' subjects = Array.wrap(meta.fetch('KW', nil)).reduce([]) do |sum, subject| sum += name_to_fos(subject) sum end { 'id' => id, 'types' => types, 'doi' => doi_from_url(id), 'url' => meta.fetch('UR', nil), 'titles' => meta.fetch('T1', nil).present? ? [{ 'title' => meta.fetch('T1', nil) }] : nil, 'creators' => get_authors(author), 'publisher' => meta.fetch('PB', '(:unav)'), 'container' => container, 'related_identifiers' => related_identifiers, 'dates' => dates, 'publication_year' => publication_year, 'descriptions' => if meta.fetch('AB', nil).present? [{ 'description' => sanitize(meta.fetch('AB')), 'descriptionType' => 'Abstract' }] end, 'subjects' => subjects, 'language' => meta.fetch('LA', nil), 'state' => state }.merge(read_options) end def ris_meta(string: nil) h = Hash.new { |h, k| h[k] = [] } string.split("\n").each_with_object(h) do |line, _sum| k, v = line.split('-', 2) h[k.strip] << v.to_s.strip end.transform_values(&:unwrap).compact end end end end