Class: RelatonNist::ModsParser

Inherits:
Object
  • Object
show all
Defined in:
lib/relaton_nist/mods_parser.rb

Constant Summary collapse

RELATION_TYPES =
{
  "otherVersion" => "editionOf",
  "preceding" => "updates",
  "succeeding" => "updatedBy",
}.freeze
ATTRS =
%i[type docid title link abstract date doctype contributor relation place series].freeze

Instance Method Summary collapse

Constructor Details

#initialize(doc, series) ⇒ ModsParser

Returns a new instance of ModsParser.



11
12
13
14
# File 'lib/relaton_nist/mods_parser.rb', line 11

def initialize(doc, series)
  @doc = doc
  @series = series
end

Instance Method Details

#create_date(date, type) ⇒ Object



108
109
110
111
# File 'lib/relaton_nist/mods_parser.rb', line 108

def create_date(date, type)
  RelatonBib::BibliographicDate.new type: type, on: decode_date(date)
rescue Date::Error
end

#create_entity(name) ⇒ Object



140
141
142
143
144
145
# File 'lib/relaton_nist/mods_parser.rb', line 140

def create_entity(name)
  case name.type
  when "personal" then [create_person(name), "author"]
  when "corporate" then [create_org(name), "publisher"]
  end
end

#create_org(name) ⇒ Object



157
158
159
160
161
162
# File 'lib/relaton_nist/mods_parser.rb', line 157

def create_org(name)
  names = name.name_part.reject(&:type).map { |n| n.content.gsub("\n", " ").squeeze(" ").strip }
  url = name.name_identifier[0]&.content
  id = RelatonBib::OrgIdentifier.new "uri", url if url
  RelatonBib::Organization.new name: names, identifier: [id]
end

#create_person(name) ⇒ Object



147
148
149
150
151
152
153
154
155
# File 'lib/relaton_nist/mods_parser.rb', line 147

def create_person(name)
  # exclude typed name parts because they are not actual name parts
  cname = name.name_part.reject(&:type).map(&:content).join(" ")
  complatename = RelatonBib::LocalizedString.new cname, "en"
  fname = RelatonBib::FullName.new completename: complatename
  name_id = name.name_identifier[0]
  identifier = RelatonBib::PersonIdentifier.new "uri", name_id.content if name_id
  RelatonBib::Person.new name: fname, identifier: [identifier]
end

#create_region(state) ⇒ Object



194
195
196
197
198
# File 'lib/relaton_nist/mods_parser.rb', line 194

def create_region(state)
  [RelatonBib::Place::RegionType.new(iso: state)]
rescue ArgumentError
  []
end


171
172
173
174
175
176
# File 'lib/relaton_nist/mods_parser.rb', line 171

def create_related_item(item)
  item_id = get_id_from_str related_item_id(item)
  docid = RelatonBib::DocumentIdentifier.new type: "NIST", id: item_id
  fref = RelatonBib::FormattedRef.new content: item_id
  NistBibliographicItem.new(docid: [docid], formattedref: fref)
end

#create_title(title, type, non_sort = nil) ⇒ Object



76
77
78
79
80
# File 'lib/relaton_nist/mods_parser.rb', line 76

def create_title(title, type, non_sort = nil)
  content = title.gsub("\n", " ").squeeze(" ").strip
  content = "#{non_sort.content}#{content}".squeeze(" ") if non_sort
  RelatonBib::TypedTitleString.new content: content, type: type, language: "en", script: "Latn"
end

#decode_date(date) ⇒ Object



113
114
115
116
117
118
119
120
# File 'lib/relaton_nist/mods_parser.rb', line 113

def decode_date(date)
  if date.encoding == "marc" && date.content.size == 6
    Date.strptime(date.content, "%y%m%d").to_s
  elsif date.encoding == "iso8601"
    Date.strptime(date.content, "%Y%m%d").to_s
  else date.content
  end
end

#doiString

Returns:

  • (String)


46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/relaton_nist/mods_parser.rb', line 46

def doi
  url = @doc.location.reduce(nil) { |m, l| m || l.url.detect { |u| u.usage == "primary display" } }
  id = url.content.match(/10\.6028\/.+/)[0]
  case id
  when "10.6028/NBS.CIRC.sup" then "10.6028/NBS.CIRC.24e7sup"
  when "10.6028/NBS.CIRC.supJun1925-Jun1926" then "10.6028/NBS.CIRC.24e7sup2"
  when "10.6028/NBS.CIRC.supJun1925-Jun1927" then "10.6028/NBS.CIRC.24e7sup3"
  when "10.6028/NBS.CIRC.24supJuly1922" then "10.6028/NBS.CIRC.24e6sup"
  when "10.6028/NBS.CIRC.24supJan1924" then "10.6028/NBS.CIRC.24e6sup2"
  else id
  end
end

#get_id_from_str(str) ⇒ Object



41
42
43
# File 'lib/relaton_nist/mods_parser.rb', line 41

def get_id_from_str(str)
  str.match(/\/((?:NBS|NIST).+)/i)[1].gsub(".", " ").sub(/^([^\d]+)/, '\1'.upcase)
end

#parseRelatonNist::NistBibliographicItem



17
18
19
20
21
22
# File 'lib/relaton_nist/mods_parser.rb', line 17

def parse
  args = ATTRS.each_with_object({}) do |attr, hash|
    hash[attr] = send("parse_#{attr}")
  end
  NistBibliographicItem.new(**args)
end

#parse_abstractObject



90
91
92
93
94
95
# File 'lib/relaton_nist/mods_parser.rb', line 90

def parse_abstract
  @doc.abstract.map do |a|
    content = a.content.gsub("\n", " ").squeeze(" ").strip
    RelatonBib::FormattedString.new content: content, language: "en", script: "Latn"
  end
end

#parse_contributorObject



126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/relaton_nist/mods_parser.rb', line 126

def parse_contributor
  # eaxclude primary contributors to avoid duplication
  @doc.name.reject { |n| n.usage == "primary" }.map do |name|
    entity, default_role = create_entity(name)
    next unless entity

    role = name.role.reduce([]) do |a, r|
      a + r.role_term.map { |rt| { type: rt.content } }
    end
    role << { type: default_role } if role.empty?
    RelatonBib::ContributionInfo.new entity: entity, role: role
  end.compact
end

#parse_dateObject



97
98
99
100
101
102
103
104
105
106
# File 'lib/relaton_nist/mods_parser.rb', line 97

def parse_date
  date = @doc.origin_info[0].date_issued.map do |di|
    create_date(di, "issued")
  # end + @doc.record_info[0].record_creation_date.map do |rcd|
  #   create_date(rcd, "created")
  # end + @doc.record_info[0].record_change_date.map do |rcd|
  #   create_date(rcd, "updated")
  end
  date.compact
end

#parse_docidArray<RelatonBib::DocumentIdentifier>

Returns:

  • (Array<RelatonBib::DocumentIdentifier>)


29
30
31
32
33
34
# File 'lib/relaton_nist/mods_parser.rb', line 29

def parse_docid
  [
    { type: "NIST", id: pub_id, primary: true },
    { type: "DOI", id: doi },
  ].map { |id| RelatonBib::DocumentIdentifier.new(**id) }
end

#parse_doctypeObject



122
123
124
# File 'lib/relaton_nist/mods_parser.rb', line 122

def parse_doctype
  RelatonBib::DocumentType.new(type: "standard")
end


82
83
84
85
86
87
88
# File 'lib/relaton_nist/mods_parser.rb', line 82

def parse_link
  @doc.location.map do |location|
    url = location.url.first
    type = url.usage == "primary display" ? "doi" : "src"
    RelatonBib::TypedUri.new content: url.content, type: type
  end
end

#parse_placeObject



186
187
188
189
190
191
192
# File 'lib/relaton_nist/mods_parser.rb', line 186

def parse_place
  @doc.origin_info.select { |p| p.event_type == "publisher"}.map do |p|
    place = p.place[0].place_term[0].content
    /(?<city>\w+), (?<state>\w+)/ =~ place
    RelatonBib::Place.new city: city, region: create_region(state)
  end
end

#parse_relationObject



164
165
166
167
168
169
# File 'lib/relaton_nist/mods_parser.rb', line 164

def parse_relation
  @doc.related_item.reject { |ri| ri.type == "series" }.map do |ri|
    type = RELATION_TYPES[ri.type]
    RelatonBib::DocumentRelation.new(type: type, bibitem: create_related_item(ri))
  end
end

#parse_seriesObject



200
201
202
203
204
205
206
207
# File 'lib/relaton_nist/mods_parser.rb', line 200

def parse_series
  @doc.related_item.select { |ri| ri.type == "series" }.map do |ri|
    tinfo = ri.title_info[0]
    tcontent = tinfo.title[0].strip
    title = RelatonBib::TypedTitleString.new content: tcontent
    RelatonBib::Series.new title: title, number: tinfo.part_number[0]
  end
end

#parse_titleArray<RelatonBib::TypedTitleString>

Returns:

  • (Array<RelatonBib::TypedTitleString>)


60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/relaton_nist/mods_parser.rb', line 60

def parse_title
  title = @doc.title_info.reduce([]) do |a, ti|
    next a if ti.type == "alternative"

    a += ti.title.map { |t| create_title(t, "title-main", ti.non_sort[0]) }
    a + ti.sub_title.map { |t| create_title(t, "title-part") }
  end
  if title.size > 1
    content = title.map { |t| t.title.content }.join(" - ")
    title << create_title(content, "main")
  elsif title.size == 1
    title[0].instance_variable_set :@type, "main"
  end
  title
end

#parse_typeObject



24
25
26
# File 'lib/relaton_nist/mods_parser.rb', line 24

def parse_type
  "standard"
end

#pub_idString

Returns:

  • (String)


37
38
39
# File 'lib/relaton_nist/mods_parser.rb', line 37

def pub_id
  get_id_from_str doi
end


178
179
180
181
182
183
184
# File 'lib/relaton_nist/mods_parser.rb', line 178

def related_item_id(item)
  if item.other_type && item.other_type[0..6] == "10.6028"
    item.other_type
  else
    item.name[0].name_part[0].content
  end
end