relaton-bipm 1.19.1 → 1.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6169158d13f03ec83666123ca52d0e87b7960ba13fe5b6d5051228c54158f93c
4
- data.tar.gz: 46236ffb5e1f875fd042dd89fe866251962a553497dd9a8a474edcd6aa18e2fa
3
+ metadata.gz: 98f4b8a04eb9738b1302ff84f91c11f5e604adfdefc2fdfac999279f4d62bf0d
4
+ data.tar.gz: 4e6dad8f65ca0472b24d178474b69a78fe20b3d784adbc1512d4c79aad576de0
5
5
  SHA512:
6
- metadata.gz: d1b01efea043f825d7e08dcecc6396e21b56c75ab0131dffd6b5e936ea10e185e9f8412ddf9c30fa21f64eaf9e97408da92e06fedc2a7cbb1d9da581151ab0ea
7
- data.tar.gz: 8cc33bc1d0b431ecd6d55c640ddcf5d715e640dfd2a926a5e2db5d72f442fefe93f527275f17236e2a815302cdb65ec9c47f71dd970b9d0eb708133765654d92
6
+ metadata.gz: d07764ecb8ffba9c394eb01fb17ec617c1209038390cd37e6035a897616e1f717b69ced0830da7d6b721733eeeb8d3ae503bb65a7efc9228142dd90852f1f665
7
+ data.tar.gz: a97d282c516026bd083a7ec534a0d1357e8eb4ab09f01495aff28e6be8fbabf78b071c422aa572690f12d5700d287ebb5cc2e34a23c7a1c88f041813834b7571
@@ -86,12 +86,16 @@ module RelatonBipm
86
86
  #
87
87
  def to_hash(embedded: false)
88
88
  hash = super
89
- hash["comment_period"] = comment_period.to_hash if comment_period
90
- hash["si_aspect"] = si_aspect if si_aspect
91
- hash["meeting_note"] = meeting_note if meeting_note
89
+ hash["ext"]["comment_period"] = comment_period.to_hash if comment_period
90
+ hash["ext"]["si_aspect"] = si_aspect if si_aspect
91
+ hash["ext"]["meeting_note"] = meeting_note if meeting_note
92
92
  hash
93
93
  end
94
94
 
95
+ def has_ext?
96
+ super || comment_period || si_aspect || meeting_note
97
+ end
98
+
95
99
  # @param prefix [String]
96
100
  # @return [String]
97
101
  def to_asciibib(prefix = "")
@@ -1,27 +1,31 @@
1
1
  module RelatonBipm
2
- class Committee
2
+ class Committee < RelatonBib::LocalizedString
3
+ ACRONYMS = YAML.load_file File.join(__dir__, "acronyms.yaml")
4
+
3
5
  # @return [String]
4
6
  attr_reader :acronym
5
7
 
6
8
  # @return [RelatonBib::LocalizedString]
7
9
  attr_reader :content
8
10
 
9
- # @param acronym [String]
10
- # @param content [RelatonBib::LocalisedString, String, nil]
11
- def initialize(acronym:, content: nil)
12
- acronyms = YAML.load_file File.join(__dir__, "acronyms.yaml")
13
- unless acronyms[acronym]
11
+ # @param [String] acronym
12
+ # @param [Hash] args
13
+ # @option args [RelatonBib::LocalisedString, String, nil] :content
14
+ # @option args [String, nil] :language
15
+ # @option args [String, nil] :script
16
+ def initialize(acronym:, **args)
17
+ unless ACRONYMS[acronym]
14
18
  Util.warn "Invalid acronym: `#{acronym}`. Allowed " \
15
- "values: `#{acronyms.map { |k, _v| k }.join '`, `'}`"
19
+ "values: `#{ACRONYMS.map { |k, _v| k }.join '`, `'}`"
16
20
  end
17
21
 
18
22
  @acronym = acronym
19
- @content = localized_content content, acronyms[acronym]
23
+ super(*localized_args(acronym, **args))
20
24
  end
21
25
 
22
26
  # @param builder [Nokogiri::XML::Builder]
23
27
  def to_xml(builder)
24
- builder.committee(acronym: acronym) { |b| content.to_xml b }
28
+ builder.committee(acronym: acronym) { |b| super b }
25
29
  end
26
30
 
27
31
  # @param prefix [String]
@@ -32,13 +36,13 @@ module RelatonBipm
32
36
  pref += "committee"
33
37
  out = count > 1 ? "#{pref}::\n" : ""
34
38
  out += "#{pref}.acronym:: #{acronym}\n"
35
- out + content.to_asciibib(pref)
39
+ out + super(pref)
36
40
  end
37
41
 
38
42
  # @return [Hash]
39
43
  def to_hash
40
44
  hash = { "acronym" => acronym }
41
- cnt = content.to_hash
45
+ cnt = super
42
46
  case cnt
43
47
  when Array then hash["variants"] = cnt
44
48
  when Hash then hash.merge! cnt
@@ -49,12 +53,14 @@ module RelatonBipm
49
53
 
50
54
  private
51
55
 
52
- def localized_content(cnt, acr)
53
- if cnt.is_a? String
54
- RelatonBib::LocalizedString.new cnt
55
- elsif (cnt.nil? || cnt.empty?) && acr && acr["en"]
56
- RelatonBib::LocalizedString.new(acr["en"], "en", "Latn")
57
- else cnt
56
+ def localized_args(accronym, **args)
57
+ if args[:content].is_a? String
58
+ [args[:content], args[:language], args[:script]]
59
+ elsif args[:content].nil?
60
+ lang = args[:language] || ACRONYMS.dig(acronym, "en") ? "en" : ACRONYMS[acronym]&.keys&.first
61
+ script = args[:script] || lang == "en" ? "Latn" : nil
62
+ [ACRONYMS.dig(accronym, lang), lang, script]
63
+ else [args[:content]]
58
64
  end
59
65
  end
60
66
  end
@@ -17,6 +17,7 @@ module RelatonBipm
17
17
 
18
18
  # project_group_hash_to_bib ret
19
19
  commentperiod_hash_to_bib ret
20
+ ret[:si_aspect] = args["ext"]["si_aspect"] if args.dig("ext", "si_aspect")
20
21
  ret
21
22
  end
22
23
 
@@ -42,7 +43,10 @@ module RelatonBipm
42
43
 
43
44
  # @param ret [Hash]
44
45
  def commentperiod_hash_to_bib(ret)
45
- ret[:comment_period] &&= CommentPeriond.new(**ret[:comment_period])
46
+ compr = ret.dig(:ext, :comment_period) || ret[:comment_period] # @TODO: remove ret[:comment_period] after all data is updated
47
+ return unless compr
48
+
49
+ ret[:comment_period] &&= CommentPeriond.new(**compr)
46
50
  end
47
51
 
48
52
  # @param ret [Hash]
@@ -69,17 +73,17 @@ module RelatonBipm
69
73
 
70
74
  # @param ret [Hash]
71
75
  def editorialgroup_hash_to_bib(ret) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
72
- return unless ret[:editorialgroup]
76
+ ed = ret.dig(:ext, :editorialgroup) || ret[:editorialgroup] # @TODO: remove ret[:editorialgroup] after all data is updated
77
+ return unless ed
73
78
 
74
- cmt = ret[:editorialgroup][:committee].map do |c|
79
+ cmt = ed[:committee].map do |c|
75
80
  if (vars = committee_variants c).any?
76
- content = RelatonBib::LocalizedString.new vars
77
- Committee.new acronym: c[:acronym], content: content
81
+ Committee.new acronym: c[:acronym], content: vars
78
82
  else
79
83
  Committee.new(**c)
80
84
  end
81
85
  end
82
- wg = RelatonBib.array(ret[:editorialgroup][:workgroup]).map do |w|
86
+ wg = RelatonBib.array(ed[:workgroup]).map do |w|
83
87
  w.is_a?(Hash) ? WorkGroup.new(**w) : WorkGroup.new(content: w)
84
88
  end
85
89
  ret[:editorialgroup] = EditorialGroup.new committee: cmt, workgroup: wg
@@ -98,9 +102,10 @@ module RelatonBipm
98
102
 
99
103
  # @param ret [Hash]
100
104
  def structuredidentifier_hash_to_bib(ret)
101
- ret[:structuredidentifier] &&= StructuredIdentifier.new(
102
- **ret[:structuredidentifier],
103
- )
105
+ struct_id = ret.dig(:ext, :structuredidentifier) || ret[:structuredidentifier] # @TODO: remove ret[:structuredidentifier] after all data is updated
106
+ return unless struct_id
107
+
108
+ ret[:structuredidentifier] = StructuredIdentifier.new(**struct_id)
104
109
  end
105
110
 
106
111
  def create_doctype(**args)
@@ -0,0 +1,111 @@
1
+ module RelatonBipm
2
+ module RawdataBipmMetrologia
3
+ class Affiliations
4
+ attr_reader :affiliations
5
+
6
+ #
7
+ # Initialize parser
8
+ #
9
+ # @param [Array<RelatonBib::Affiliation>] affiliations directory with affiliations
10
+ #
11
+ def initialize(affiliations)
12
+ @affiliations = affiliations
13
+ end
14
+
15
+ #
16
+ # Parse affiliations
17
+ #
18
+ # @return [RelatonBipm::RawdataBipmMetrologia::Affiliations] affiliations
19
+ #
20
+ def self.parse(dir)
21
+ affiliations = Dir["#{dir}/*.xml"].each_with_object([]) do |path, m|
22
+ doc = Nokogiri::XML(File.read(path, encoding: "UTF-8"))
23
+ doc.xpath("//aff").each do |aff|
24
+ m << parse_affiliation(aff) if aff.at("institution")
25
+ end
26
+ end.uniq { |a| a.organization.name.first.content }
27
+ new affiliations
28
+ end
29
+
30
+ #
31
+ # Parse affiliation organization
32
+ # https://github.com/relaton/relaton-data-bipm/issues/17#issuecomment-1367035444
33
+ #
34
+ # @param [Nokogiri::XML::Element] aff
35
+ #
36
+ # @return [RelatonBib::Affiliation] Organization name, country, division, street address
37
+ #
38
+ def self.parse_affiliation(aff)
39
+ text = aff.at("text()").text
40
+ return if text.include? "Permanent address:" || text.include?("1005 Southover Lane") ||
41
+ text == "Germany" || text.starts_with?("Guest") || text.starts_with?("Deceased") ||
42
+ text.include?("Author to whom any correspondence should be addressed")
43
+
44
+ args = {}
45
+ institution = aff.at('institution')
46
+ if institution
47
+ name = institution.text
48
+ return if name == "1005 Southover Lane"
49
+
50
+ args[:subdivision] = parse_division(aff)
51
+ args[:contact] = parse_address(aff)
52
+ else
53
+ # div, name, city, country = aff.xpath("text()").text.strip.split(", ")
54
+ # div, name = name, div if name.nil?
55
+ # args[:subdivision] = [RelatonBib::LocalizedString.new(div)] if div
56
+ # args[:contact] = [RelatonBib::Address.new(city: city, country: country)] if city && country
57
+ name = aff.text
58
+ end
59
+ args[:name] = [RelatonBib::LocalizedString.new(name)]
60
+ org = RelatonBib::Organization.new(**args)
61
+ RelatonBib::Affiliation.new(organization: org)
62
+ end
63
+
64
+ def self.parse_division(aff)
65
+ div = aff.xpath("text()[following-sibling::institution]").text.gsub(/^\W*|\W*$/, "")
66
+ return [] if div.empty?
67
+
68
+ [RelatonBib::LocalizedString.new(div)]
69
+ end
70
+
71
+ def self.parse_address(aff)
72
+ address = []
73
+ addr = aff.xpath("text()[preceding-sibling::institution]").text.gsub(/^\W*|\W*$/, "")
74
+ address << addr unless addr.empty?
75
+ country = aff.at('country')
76
+ address << country.text if country && !country.text.empty?
77
+ address = address.join(", ")
78
+ return [] if address.empty?
79
+
80
+ [RelatonBib::Address.new(formatted_address: address)]
81
+ end
82
+
83
+ def self.parse_elements(aff)
84
+ elements = aff.xpath("text()").text.strip.split(", ")
85
+ case elements.size
86
+ when 1 then { name: RelatonBib::LocalizedString.new(elements[0]) }
87
+ when 2
88
+ # name, country
89
+ { name: RelatonBib::LocalizedString.new(elements[0]),
90
+ contact: [RelatonBib::Address.new(formatted_address: elements[1])] }
91
+ when 3
92
+ # it can be name, country, city or name, city, country
93
+ # so use formatted_address instead of city and country
94
+ { name: RelatonBib::LocalizedString.new(elements[0]),
95
+ contact: RelatonBib::Address.new(formatted_address: elements[1, 2].join(", ")) }
96
+ end
97
+ end
98
+
99
+ #
100
+ # Find affiliation by organization name
101
+ #
102
+ # @param [Strign] text string with organization name in it
103
+ #
104
+ # @return [RelatonBib::Affiliation]
105
+ #
106
+ def find(text)
107
+ @affiliations.select { |a| text.include?(a.organization.name[0].content) }.sort.last
108
+ end
109
+ end
110
+ end
111
+ end
@@ -59,12 +59,9 @@ module RelatonBipm
59
59
  #
60
60
  # Parse volume, issue and page
61
61
  #
62
- # @return [Array<String>] array of volume, issue and page
62
+ # @return [String] volume issue page
63
63
  #
64
64
  def volume_issue_article
65
- # volume = @meta.at("./volume").text
66
- # issue = @meta.at("./issue").text
67
- # page = @doc.at("./front/article-meta/fpage")&.text || manuscript
68
65
  [@journal, @volume, @article].compact.join(" ")
69
66
  end
70
67
 
@@ -140,17 +137,53 @@ module RelatonBipm
140
137
  #
141
138
  # @return [Array<RelatonBib::Affiliation>] array of affiliations
142
139
  #
143
- def affiliation(contrib) # rubocop:disable Metrics/AbcSize
140
+ def affiliation(contrib)
144
141
  contrib.xpath("./xref[@ref-type='aff']").map do |x|
145
- a = @meta.at("./contrib-group/aff[@id='#{x[:rid]}']/label/following-sibling::node()")
146
- parts = a.text.split(", ")
147
- orgname = parts[0..-3].join(", ")
148
- city, country = parts[-2..]
149
- address = []
150
- address << RelatonBib::Address.new(city: city, country: country) if city && country
151
- org = RelatonBib::Organization.new name: orgname, contact: address
152
- RelatonBib::Affiliation.new organization: org
142
+ a = @meta.at("./contrib-group/aff[@id='#{x[:rid]}']") # /label/following-sibling::node()")
143
+ parse_affiliation a
144
+ end.compact
145
+ end
146
+
147
+ def parse_affiliation(aff)
148
+ text = aff.xpath("text()|sup|sub").to_xml.split(",").map(&:strip).reject(&:empty?).join(", ")
149
+ text = CGI::unescapeHTML(text)
150
+ return if text.include?("Permanent address:") || text == "Germany" ||
151
+ text.start_with?("Guest") || text.start_with?("Deceased") ||
152
+ text.include?("Author to whom any correspondence should be addressed")
153
+
154
+ args = {}
155
+ institution = aff.at('institution')
156
+ if institution
157
+ name = institution.text
158
+ return if name == "1005 Southover Lane"
159
+
160
+ args[:subdivision] = parse_division(aff)
161
+ args[:contact] = parse_address(aff)
162
+ else
163
+ name = text
153
164
  end
165
+ args[:name] = [RelatonBib::LocalizedString.new(name)]
166
+ org = RelatonBib::Organization.new(**args)
167
+ RelatonBib::Affiliation.new(organization: org)
168
+ end
169
+
170
+ def parse_division(aff)
171
+ div = aff.xpath("text()[following-sibling::institution]").text.gsub(/^\W*|\W*$/, "")
172
+ return [] if div.empty?
173
+
174
+ [RelatonBib::LocalizedString.new(div)]
175
+ end
176
+
177
+ def parse_address(aff)
178
+ address = []
179
+ addr = aff.xpath("text()[preceding-sibling::institution]").text.gsub(/^\W*|\W*$/, "")
180
+ address << addr unless addr.empty?
181
+ country = aff.at('country')
182
+ address << country.text if country && !country.text.empty?
183
+ address = address.join(", ")
184
+ return [] if address.empty?
185
+
186
+ [RelatonBib::Address.new(formatted_address: address)]
154
187
  end
155
188
 
156
189
  #
@@ -173,20 +206,20 @@ module RelatonBipm
173
206
  #
174
207
  # @return [Array<RelatonBib::Forename>] array of forenames
175
208
  #
176
- def forename(given_name) # rubocop:disable Metrics/MethodLength
177
- return [] unless given_name
209
+ # def forename(given_name) # rubocop:disable Metrics/MethodLength
210
+ # return [] unless given_name
178
211
 
179
- given_name.text.scan(/(\w+)(?:\s(\w)(?:\s|$))?/).map do |nm, int|
180
- if nm.size == 1
181
- name = nil
182
- init = nm
183
- else
184
- name = nm
185
- init = int
186
- end
187
- RelatonBib::Forename.new(content: name, language: ["en"], script: ["Latn"], initial: init)
188
- end
189
- end
212
+ # given_name.text.scan(/(\w+)(?:\s(\w)(?:\s|$))?/).map do |nm, int|
213
+ # if nm.size == 1
214
+ # name = nil
215
+ # init = nm
216
+ # else
217
+ # name = nm
218
+ # init = int
219
+ # end
220
+ # RelatonBib::Forename.new(content: name, language: ["en"], script: ["Latn"], initial: init)
221
+ # end
222
+ # end
190
223
 
191
224
  #
192
225
  # Parse date
@@ -29,8 +29,9 @@ module RelatonBipm
29
29
  # Fetch articles from rawdata-bipm-metrologia and save to files
30
30
  #
31
31
  def fetch_articles # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
32
+ # aff = Affiliations.parse DIR
32
33
  Dir["#{DIR}/**/*.xml"].each do |path|
33
- item = ArticleParser.parse path
34
+ item = ArticleParser.parse path # , aff
34
35
  file = "#{item.docidentifier.first.id.downcase.tr(' ', '-')}.#{@data_fetcher.ext}"
35
36
  out_path = File.join(@data_fetcher.output, file)
36
37
  key = Id.new.parse(item.docidentifier.first.id).to_hash
@@ -1,3 +1,3 @@
1
1
  module RelatonBipm
2
- VERSION = "1.19.1".freeze
2
+ VERSION = "1.20.0".freeze
3
3
  end
@@ -58,12 +58,9 @@ module RelatonBipm
58
58
 
59
59
  cm = eg.xpath("committee").map do |c|
60
60
  vars = variants c
61
- cnt = if vars.any?
62
- RelatonBib::LocalizedString.new vars
63
- else
64
- RelatonBib::LocalizedString.new c.text, c[:language], c[:script]
65
- end
66
- Committee.new acronym: c[:acronym], content: cnt
61
+ cnt = vars.any? ? vars : c.text
62
+ args = c.to_h.transform_keys(&:to_sym).select { |k, _| %i[language script locale].include?(k) }
63
+ Committee.new acronym: c[:acronym], content: cnt, **args
67
64
  end
68
65
  wg = eg.xpath("workgroup").map do |w|
69
66
  WorkGroup.new content: w.text, acronym: w[:acronym]
data/relaton_bipm.gemspec CHANGED
@@ -35,7 +35,7 @@ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
35
35
  spec.add_dependency "faraday", "~> 2.7.0"
36
36
  spec.add_dependency "mechanize", "~> 2.10"
37
37
  spec.add_dependency "parslet", "~> 2.0.0"
38
- spec.add_dependency "relaton-bib", "~> 1.19.0"
38
+ spec.add_dependency "relaton-bib", "~> 1.20.0"
39
39
  spec.add_dependency "relaton-index", "~> 0.2.2"
40
40
  spec.add_dependency "rubyzip", "~> 2.3.0"
41
41
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: relaton-bipm
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.19.1
4
+ version: 1.20.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-07-31 00:00:00.000000000 Z
11
+ date: 2024-12-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 1.19.0
61
+ version: 1.20.0
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 1.19.0
68
+ version: 1.20.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: relaton-index
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -135,6 +135,7 @@ files:
135
135
  - lib/relaton_bipm/hash_converter.rb
136
136
  - lib/relaton_bipm/id_parser.rb
137
137
  - lib/relaton_bipm/processor.rb
138
+ - lib/relaton_bipm/rawdata_bipm_metrologia/affiliations.rb
138
139
  - lib/relaton_bipm/rawdata_bipm_metrologia/article_parser.rb
139
140
  - lib/relaton_bipm/rawdata_bipm_metrologia/fetcher.rb
140
141
  - lib/relaton_bipm/structured_identifier.rb
@@ -149,7 +150,7 @@ licenses:
149
150
  metadata:
150
151
  homepage_uri: https://github.com/relaton/relaton-bipm
151
152
  source_code_uri: https://github.com/relaton/relaton-bipm
152
- post_install_message:
153
+ post_install_message:
153
154
  rdoc_options: []
154
155
  require_paths:
155
156
  - lib
@@ -165,7 +166,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
165
166
  version: '0'
166
167
  requirements: []
167
168
  rubygems_version: 3.3.27
168
- signing_key:
169
+ signing_key:
169
170
  specification_version: 4
170
171
  summary: 'RelatonBipm: retrieve BIPM Standards for bibliographic use using the BibliographicItem
171
172
  model'