relaton-bib 1.9.4 → 1.9.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3f54471913accf8362c7e96a1679e62e7f73092d12cb24156797837084371f06
4
- data.tar.gz: b9c94af722de0e6fd41064aa1a15a7f604698f525c24bb611ddc3430eea0b4ac
3
+ metadata.gz: cea4f63e62a2c6abff013361c4851294799cee45bcbe44a52ee8158501505f5f
4
+ data.tar.gz: 1d973d98047232ff7167257beafc0ed339177b27eb878918d9bcf0cc8f7d7301
5
5
  SHA512:
6
- metadata.gz: 38dccc66a7bf1f7b49b471d1f3dd97e75a925d86dde075a1778b065bcfd6767406e26e5c38a954d17ea824ba06a43ee4eacada09ceeabf91f38615fccd480dc0
7
- data.tar.gz: 8339ccfb65c672dd5f1a3928696cc1ca9e0f055b605c4ec631046a668603f756bd1f7e56547863453cddfdde3950538d48c2e6ad6990cbefbdb459bd6ce31d48
6
+ metadata.gz: e21ef90933920055d91d952e2b5513279d4dd61559ead7aebef9db0d7df4b15283bdd5d2cf77decb16d4e4f8d573f38c4c872582dfcdfbd0899703e4b8a9b152
7
+ data.tar.gz: 471d57586461900b6805df5c8d536591a2d0377e3da455af5708dbfa37aa13a4960bdee00f7c54de052763332de81b31f862dc9b4acc21a9992c3c52eba08d7a
data/.rubocop.yml CHANGED
@@ -2,6 +2,8 @@
2
2
  # https://github.com/riboseinc/oss-guides
3
3
  # All project-specific additions and overrides should be specified in this file.
4
4
 
5
+ require: rubocop-rails
6
+
5
7
  inherit_from:
6
8
  - https://raw.githubusercontent.com/riboseinc/oss-guides/master/ci/rubocop.yml
7
9
  AllCops:
data/README.adoc CHANGED
@@ -366,6 +366,18 @@ RelatonBib::BibliographicItem.from_hash hash
366
366
  ...
367
367
  ----
368
368
 
369
+ === Create bibliographic item from BibXML
370
+
371
+ [source,ruby]
372
+ ----
373
+ bibxml = File.read "spec/examples/rfc.xml"
374
+ => <reference anchor=...
375
+
376
+ RelatonBib::BibXMLParser.parse bibxml
377
+ => #<RelatonBib::BibliographicItem:0x00007f9d0c75b268
378
+ ...
379
+ ----
380
+
369
381
  === Export bibliographic item to Hash
370
382
 
371
383
  [source,ruby]
@@ -159,10 +159,11 @@ module RelatonBib
159
159
  # @option copyright [String, NilClass] :to
160
160
  # @option copyright [String, NilClass] :scope
161
161
  #
162
- # @param date [Array<Hash>]
162
+ # @param date [Array<Hash, RelatonBib::BibliographicDate>]
163
163
  # @option date [String] :type
164
- # @option date [String] :from
165
- # @option date [String] :to
164
+ # @option date [String, nil] :from required if :on is nil
165
+ # @option date [String, nil] :to
166
+ # @option date [String, nil] :on required if :from is nil
166
167
  #
167
168
  # @param contributor [Array<Hash>]
168
169
  # @option contributor [RealtonBib::Organization, RelatonBib::Person]
@@ -176,7 +177,7 @@ module RelatonBib
176
177
  # @option abstract [String] :content
177
178
  # @option abstract [String] :language
178
179
  # @option abstract [String] :script
179
- # @option abstract [String] :type
180
+ # @option abstract [String] :format
180
181
  #
181
182
  # @param relation [Array<Hash>]
182
183
  # @option relation [String] :type
@@ -766,17 +767,48 @@ module RelatonBib
766
767
  #
767
768
  def render_bibxml(builder)
768
769
  target = link.detect { |l| l.type == "src" } || link.detect { |l| l.type == "doi" }
769
- bxml = builder.reference(anchor: id) do |xml|
770
+ bxml = builder.reference(anchor: anchor) do |xml|
770
771
  xml.front do
771
772
  xml.title title[0].title.content if title.any?
772
773
  render_seriesinfo xml
773
774
  render_authors xml
774
775
  render_date xml
776
+ render_workgroup xml
777
+ render_keyword xml
778
+ render_abstract xml
775
779
  end
776
780
  end
777
781
  bxml[:target] = target.content.to_s if target
778
782
  end
779
783
 
784
+ def anchor
785
+ did = docidentifier.detect { |di| di.type == "rfc-anchor" }
786
+ return did.id if did
787
+
788
+ type = docidentifier[0].type
789
+ "#{type}.#{docnumber}"
790
+ end
791
+
792
+ def render_keyword(builder)
793
+ keyword.each do |kw|
794
+ builder.keyword kw.content
795
+ end
796
+ end
797
+
798
+ def render_workgroup(builder)
799
+ editorialgroup&.technical_committee&.each do |tc|
800
+ builder.workgroup tc.workgroup.name
801
+ end
802
+ end
803
+
804
+ # @param [Nokogiri::XML::Builder] builder
805
+ def render_abstract(builder)
806
+ return unless abstract.any?
807
+
808
+ builder.abstract { |xml| xml << abstract[0].content.gsub(/(<\/?)p(>)/, '\1t\2') }
809
+ end
810
+
811
+ # @param [Nokogiri::XML::Builder] builder
780
812
  def render_date(builder)
781
813
  dt = date.detect { |d| d.type == "published" }
782
814
  return unless dt
@@ -790,22 +822,24 @@ module RelatonBib
790
822
  elm[:day] = d if d
791
823
  end
792
824
 
825
+ # @param [Nokogiri::XML::Builder] builder
793
826
  def render_seriesinfo(builder)
794
- names = ["DOI", "Internet-Draft"]
795
827
  docidentifier.each do |di|
796
- if names.include? di.type
828
+ if BibXMLParser::SERIESINFONAMES.include? di.type
797
829
  builder.seriesInfo(name: di.type, value: di.id)
798
830
  end
799
831
  end
800
- snames = ["ANSI", "BCP", "RFC", "STD"]
801
- series.each do |s|
802
- next unless s.title && snames.include?(s.title.title.to_s)
803
-
832
+ di_types = docidentifier.map(&:type)
833
+ series.select do |s|
834
+ s.title && !di_types.include?(s.title.title.to_s) &&
835
+ !BibXMLParser::SERIESINFONAMES.include?(s.title.title.to_s)
836
+ end.uniq { |s| s.title.title.to_s }.each do |s|
804
837
  si = builder.seriesInfo(name: s.title.title.to_s)
805
838
  si[:value] = s.number if s.number
806
839
  end
807
840
  end
808
841
 
842
+ # @param [Nokogiri::XML::Builder] builder
809
843
  def render_authors(builder)
810
844
  contributor.each do |c|
811
845
  builder.author do |xml|
@@ -818,26 +852,40 @@ module RelatonBib
818
852
  end
819
853
  end
820
854
 
855
+ # @param [Nokogiri::XML::Builder] builder
856
+ # @param [RelatonBib::ContributionInfo] contrib
821
857
  def render_address(builder, contrib)
822
- addr = contrib.entity.contact.reject do |cn|
823
- cn.is_a?(Address) && cn.postcode.nil?
824
- end
825
- if addr.any?
858
+ # addr = contrib.entity.contact.reject do |cn|
859
+ # cn.is_a?(Address) && cn.postcode.nil?
860
+ # end
861
+ if contrib.entity.contact.any?
826
862
  builder.address do |xml|
827
- address = addr.detect { |cn| cn.is_a? Address }
828
- xml.postal address.postcode if address.postcode
829
- render_contact xml, addr
863
+ address = contrib.entity.contact.detect { |cn| cn.is_a? Address }
864
+ if address
865
+ xml.postal do
866
+ xml.city address.city if address.city
867
+ xml.code address.postcode if address.postcode
868
+ xml.country address.country if address.country
869
+ xml.region address.state if address.state
870
+ xml.street address.street[0] if address.street.any?
871
+ end
872
+ end
873
+ render_contact xml, contrib.entity.contact
830
874
  end
831
875
  end
832
876
  end
833
877
 
878
+ # @param [Nokogiri::XML::Builder] builder
879
+ # @param [Array<RelatonBib::Address, RelatonBib::Contact>] addr
834
880
  def render_contact(builder, addr)
835
881
  %w[phone email uri].each do |type|
836
882
  cont = addr.detect { |cn| cn.is_a?(Contact) && cn.type == type }
837
- builder.phone cont.value if cont
883
+ builder.send type, cont.value if cont
838
884
  end
839
885
  end
840
886
 
887
+ # @param [Nokogiri::XML::Builder] builder
888
+ # @param [RelatonBib::Person] person
841
889
  def render_person(builder, person)
842
890
  render_organization builder, person.affiliation.first&.organization
843
891
  if person.name.completename
@@ -851,11 +899,13 @@ module RelatonBib
851
899
  end
852
900
  end
853
901
 
902
+ # @param [Nokogiri::XML::Builder] builder
903
+ # @param [RelatonBib::Organization] org
854
904
  def render_organization(builder, org)
855
905
  return unless org
856
906
 
857
907
  o = builder.organization org.name.first&.content
858
- o[:abbrev] = org.abbreviation if org.abbreviation
908
+ o[:abbrev] = org.abbreviation.content if org.abbreviation
859
909
  end
860
910
  # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
861
911
  # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
@@ -0,0 +1,348 @@
1
+ module RelatonBib
2
+ module BibXMLParser
3
+ SERIESINFONAMES = ["DOI", "Internet-Draft"].freeze
4
+ FLAVOR = nil
5
+
6
+ def parse(bibxml, url: nil, is_relation: false, ver: nil)
7
+ doc = Nokogiri::XML bibxml
8
+ fetch_rfc doc.at("/referencegroup", "/reference"), url: url, is_relation: is_relation, ver: ver
9
+ end
10
+
11
+ # @param reference [Nokogiri::XML::Element, nil]
12
+ # @param is_relation [Boolean] don't add fetched date for relation if true
13
+ # @param url [String, nil]
14
+ # @param ver [String, nil] Internet Draft version
15
+ # @return [RelatonBib::BibliographicItem]
16
+ def fetch_rfc(reference, is_relation: false, url: nil, ver: nil) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
17
+ return unless reference
18
+
19
+ hash = {
20
+ is_relation: is_relation,
21
+ docnumber: docnumber(reference),
22
+ type: "standard",
23
+ docid: docids(reference, ver),
24
+ status: status(reference),
25
+ language: [language(reference)],
26
+ script: ["Latn"],
27
+ link: link(reference, url, ver),
28
+ title: titles(reference),
29
+ formattedref: formattedref(reference),
30
+ abstract: abstracts(reference),
31
+ contributor: contributors(reference),
32
+ relation: relations(reference),
33
+ date: dates(reference),
34
+ editorialgroup: editorialgroup(reference),
35
+ series: series(reference),
36
+ keyword: reference.xpath("front/keyword").map(&:text),
37
+ doctype: doctype(reference[:anchor]),
38
+ }
39
+ # hash[:fetched] = Date.today.to_s unless is_relation
40
+ bib_item(**hash)
41
+ end
42
+
43
+ def docnumber(reference)
44
+ reference[:anchor]&.sub(/^\w+\./, "")
45
+ end
46
+
47
+ # @param attrs [Hash]
48
+ # @return [RelatonBib::IetfBibliographicItem]
49
+ def bib_item(**attrs)
50
+ # attrs[:place] = ["Fremont, CA"]
51
+ BibliographicItem.new(**attrs)
52
+ end
53
+
54
+ # @param reference [Nokogiri::XML::Element]
55
+ # @return [String]
56
+ def language(reference)
57
+ reference[:lang] || "en"
58
+ end
59
+
60
+ #
61
+ # Extract document identifiers from reference
62
+ #
63
+ # @param reference [Nokogiri::XML::Element]
64
+ # @param ver [String, nil] Internet Draft version
65
+ #
66
+ # @return [Array<RelatonBib::DocumentIdentifier>]
67
+ #
68
+ def docids(reference, ver) # rubocop:disable Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity,Metrics/AbcSize
69
+ ret = []
70
+ sfid = reference.at("./seriesInfo[@name='#{self::FLAVOR}']",
71
+ "./front/seriesInfo[@name='#{self::FLAVOR}']")
72
+ if sfid
73
+ ret << DocumentIdentifier.new(type: sfid[:name], id: sfid[:value])
74
+ elsif self::FLAVOR && (id = (reference[:anchor] || reference[:docName] || reference[:number]))
75
+ ret << DocumentIdentifier.new(type: self::FLAVOR, id: id.sub(/^(RFC)/, "\\1 "))
76
+ end
77
+ if (id = reference[:anchor])
78
+ ret << DocumentIdentifier.new(type: "rfc-anchor", id: id)
79
+ end
80
+ ret + reference.xpath("./seriesInfo", "./front/seriesInfo").map do |si|
81
+ next unless SERIESINFONAMES.include? si[:name]
82
+
83
+ id = si[:value]
84
+ id.sub!(/(?<=-)\d{2}$/, ver) if ver && si[:name] == "Internet-Draft"
85
+ DocumentIdentifier.new(id: id, type: si[:name])
86
+ end.compact
87
+ end
88
+
89
+ #
90
+ # extract status
91
+ # @param reference [Nokogiri::XML::Element]
92
+ #
93
+ # @return [RelatonBib::DocumentStatus]
94
+ #
95
+ def status(reference)
96
+ st = reference.at("./seriesinfo[@status]")
97
+ DocumentStatus.new(stage: st[:status]) if st
98
+ end
99
+
100
+ # @param reference [Nokogiri::XML::Element]
101
+ # @param url [String]
102
+ # @param ver [String, nil] Internet Draft version
103
+ # @return [Array<Hash>]
104
+ def link(reference, url, ver)
105
+ l = []
106
+ l << { type: "xml", content: url } if url
107
+ l << { type: "src", content: reference[:target] } if reference[:target]
108
+ if /^I-D/.match? reference[:anchor]
109
+ reference.xpath("format").each do |f|
110
+ c = ver ? f[:target].sub(/(?<=-)\d{2}(?=\.)/, ver) : f[:target]
111
+ l << { type: f[:type], content: c }
112
+ end
113
+ end
114
+ l
115
+ end
116
+
117
+ # @param reference [Nokogiri::XML::Element]
118
+ # @return [Array<Hash>]
119
+ def titles(reference)
120
+ reference.xpath("./front/title").map do |title|
121
+ { content: title.text, language: language(reference), script: "Latn" }
122
+ end
123
+ end
124
+
125
+ # @param reference [Nokogiri::XML::Element]
126
+ # @return [RelatonBib::FormattedRef, nil]
127
+ def formattedref(reference)
128
+ return if reference.at "./front/title"
129
+
130
+ cont = (reference[:anchor] || reference[:docName] || reference[:number])
131
+ if cont
132
+ FormattedRef.new(
133
+ content: cont, language: language(reference), script: "Latn",
134
+ )
135
+ end
136
+ end
137
+
138
+ # @param reference [Nokogiri::XML::Element]
139
+ # @return [Array<RelatonBib::FormattedString>]
140
+ def abstracts(ref)
141
+ ref.xpath("./front/abstract").map do |a|
142
+ FormattedString.new(
143
+ content: a.children.to_s.gsub(/(<\/?)t(>)/, '\1p\2'),
144
+ language: language(ref), script: "Latn", format: "text/html"
145
+ )
146
+ end
147
+ end
148
+
149
+ # @param reference [Nokogiri::XML::Element]
150
+ # @return [Array<Hash>]
151
+ def contributors(reference)
152
+ reference.xpath("./front/author").map do |contrib|
153
+ if contrib[:fullname] || contrib[:surname] then person(contrib, reference)
154
+ else organization(contrib)
155
+ end
156
+ end.compact
157
+ # persons(reference) + organizations(reference)
158
+ end
159
+
160
+ # @param author [Nokogiri::XML::Element]
161
+ # @param reference [Nokogiri::XML::Element]
162
+ # @return [Array<Hash{Symbol=>RelatonBib::Person,Symbol=>Array<String>}>]
163
+ def person(author, reference)
164
+ # reference.xpath("./front/author[@surname]|./front/author[@fullname]")
165
+ # .map do |author|
166
+ entity = Person.new(
167
+ name: full_name(author, reference),
168
+ affiliation: affiliation(author),
169
+ contact: contacts(author.at("./address")),
170
+ )
171
+ { entity: entity, role: [contributor_role(author)] }
172
+ # end
173
+ end
174
+
175
+ # @param contrib [Nokogiri::XML::Element]
176
+ # @return [Array<Hash{Symbol=>RelatonBib::Organization,
177
+ # Symbol=>Array<String>}>]
178
+ def organization(contrib)
179
+ # publisher = { entity: new_org, role: [type: "publisher"] }
180
+ # orgs = reference.xpath("./seriesinfo").reduce([]) do |mem, si|
181
+ # next mem unless si[:stream]
182
+
183
+ # mem << { entity: new_org(si[:stream], nil), role: [type: "author"] }
184
+ # end
185
+ # orgs + reference.xpath(
186
+ # "front/author[not(@surname)][not(@fullname)]/organization",
187
+ # ).map do |org|
188
+ org = contrib.at("./organization")
189
+ { entity: new_org(org.text, org[:abbrev]), role: [contributor_role(contrib)] }
190
+ # end
191
+ end
192
+
193
+ # @param author [Nokogiri::XML::Element]
194
+ # @param reference [Nokogiri::XML::Element]
195
+ # @return [RelatonBib::FullName]
196
+ def full_name(author, reference)
197
+ lang = language reference
198
+ FullName.new(
199
+ completename: localized_string(author[:fullname], lang),
200
+ initial: [localized_string(author[:initials], lang)].compact,
201
+ surname: localized_string(author[:surname], lang),
202
+ )
203
+ end
204
+
205
+ # @param author [Nokogiri::XML::Element]
206
+ # @return [Array<RelatonBib::Affiliation>]
207
+ def affiliation(author)
208
+ o = author.at("./organization")
209
+ return [] if o.nil? || o.text.empty?
210
+
211
+ org = new_org o.text, o[:abbrev]
212
+ [Affiliation.new(organization: org)]
213
+ end
214
+
215
+ # @param name [String]
216
+ # @param abbr [String]
217
+ # @return [RelatonBib::Organization]
218
+ def new_org(name, abbr)
219
+ # (name = "Internet Engineering Task Force", abbr = "IETF")
220
+ Organization.new name: name, abbreviation: abbr
221
+ end
222
+
223
+ # @param content [String, nil]
224
+ # @param lang [String, nil]
225
+ # @return [RelatonBib::LocalizedString, nil]
226
+ def localized_string(content, lang)
227
+ LocalizedString.new(content, lang) if content
228
+ end
229
+
230
+ # @param postal [Nokogiri::XML::Element]
231
+ # @return [Array<RelatonBib::Address, RelatonBib::Phone>]
232
+ def contacts(addr)
233
+ conts = []
234
+ return conts unless addr
235
+
236
+ postal = addr.at("./postal")
237
+ conts << address(postal) if postal
238
+ add_contact(conts, "phone", addr.at("./phone"))
239
+ add_contact(conts, "email", addr.at("./email"))
240
+ add_contact(conts, "uri", addr.at("./uri"))
241
+ conts
242
+ end
243
+
244
+ # @param postal [Nokogiri::XML::Element]
245
+ # @rerurn [RelatonBib::Address]
246
+ def address(postal) # rubocop:disable Metrics/CyclomaticComplexity
247
+ street = [
248
+ (postal.at("./postalLine") || postal.at("./street"))&.text
249
+ ].compact
250
+ Address.new(
251
+ street: street,
252
+ city: postal.at("./city")&.text,
253
+ postcode: postal.at("./code")&.text,
254
+ country: postal.at("./country")&.text,
255
+ state: postal.at("./region")&.text,
256
+ )
257
+ end
258
+
259
+ # @param conts [Array<RelatonBib::Address, RelatonBib::Contact>]
260
+ # @param type [String] allowed "phone", "email" or "uri"
261
+ # @param value [String]
262
+ def add_contact(conts, type, value)
263
+ conts << Contact.new(type: type, value: value.text) if value
264
+ end
265
+
266
+ # @param author [Nokogiri::XML::Document]
267
+ # @return [Hash]
268
+ def contributor_role(author)
269
+ { type: author[:role] || "author" }
270
+ end
271
+
272
+ # @param reference [Nokogiri::XML::Element]
273
+ # @return [Hash]
274
+ def relations(reference)
275
+ reference.xpath("reference").map do |ref|
276
+ { type: "includes", bibitem: fetch_rfc(ref, is_relation: true) }
277
+ end
278
+ end
279
+
280
+ #
281
+ # Extract date from reference.
282
+ #
283
+ # @param reference [Nokogiri::XML::Element]
284
+ # @return [Array<RelatonBib::BibliographicDate>] published data.
285
+ #
286
+ def dates(reference)
287
+ return unless (date = reference.at "./front/date")
288
+
289
+ d = [date[:year], month(date[:month]), (date[:day] || 1)].compact.join "-"
290
+ date = Time.parse(d).strftime "%Y-%m-%d"
291
+ [BibliographicDate.new(type: "published", on: date)]
292
+ rescue ArgumentError
293
+ []
294
+ end
295
+
296
+ # @param reference [Nokogiri::XML::Element]
297
+ # @return [RelatonBib::EditorialGroup, nil]
298
+ def editorialgroup(reference)
299
+ tc = reference.xpath("./front/workgroup").map do |ed|
300
+ wg = WorkGroup.new name: ed.text
301
+ committee wg
302
+ end
303
+ EditorialGroup.new tc if tc.any?
304
+ end
305
+
306
+ # @param [RelatonBib::WorkGroup]
307
+ # @return [RelatonBib::TechnicalCommittee]
308
+ def committee(wgr)
309
+ TechnicalCommittee.new wgr
310
+ end
311
+
312
+ def month(mon)
313
+ return 1 if !mon || mon.empty?
314
+ return mon if /^\d+$/.match? mon
315
+
316
+ Date::MONTHNAMES.index(mon)
317
+ end
318
+
319
+ #
320
+ # Extract series form reference
321
+ # @param reference [Nokogiri::XML::Element]
322
+ #
323
+ # @return [Array<RelatonBib::Series>]
324
+ #
325
+ def series(reference)
326
+ reference.xpath("./seriesInfo", "./front/seriesInfo").map do |si|
327
+ next if si[:name] == "DOI" || si[:stream] || si[:status]
328
+
329
+ t = TypedTitleString.new(
330
+ content: si[:name], language: language(reference), script: "Latn",
331
+ )
332
+ Series.new(title: t, number: si[:value], type: "main")
333
+ end.compact
334
+ end
335
+
336
+ # @param anchor [String]
337
+ # @return [String]
338
+ def doctype(anchor)
339
+ case anchor
340
+ when /I-D/ then "internet-draft"
341
+ when /IEEE/ then "ieee"
342
+ else "rfc"
343
+ end
344
+ end
345
+
346
+ extend BibXMLParser
347
+ end
348
+ end
@@ -82,6 +82,8 @@ module RelatonBib
82
82
 
83
83
  # @param entity [RelatonBib::Person, RelatonBib::Organization]
84
84
  # @param role [Array<Hash>]
85
+ # @option role [String] :type
86
+ # @option role [Array<String>] :description
85
87
  def initialize(entity:, role: [])
86
88
  if role.empty?
87
89
  role << { type: entity.is_a?(Person) ? "author" : "publisher" }
@@ -94,7 +96,7 @@ module RelatonBib
94
96
  # @option opts [Nokogiri::XML::Builder] :builder XML builder
95
97
  # @option opts [String, Symbol] :lang language
96
98
  def to_xml(**opts)
97
- entity.to_xml **opts
99
+ entity.to_xml(**opts)
98
100
  end
99
101
 
100
102
  # @return [Hash]
@@ -138,7 +138,7 @@ module RelatonBib
138
138
  desc = description.select { |d| d.language&.include? opts[:lang] }
139
139
  desc = description unless desc.any?
140
140
  desc.each { |d| builder.description { d.to_xml builder } }
141
- organization.to_xml **opts
141
+ organization.to_xml(**opts)
142
142
  end
143
143
  end
144
144
 
@@ -35,7 +35,7 @@ module RelatonBib
35
35
 
36
36
  # @return [true]
37
37
  def presence?
38
- true
38
+ technical_committee.any?
39
39
  end
40
40
  end
41
41
  end
@@ -56,7 +56,7 @@ module RelatonBib
56
56
  else
57
57
  builder.parent["language"] = language.join(",") if language&.any?
58
58
  builder.parent["script"] = script.join(",") if script&.any?
59
- builder.text content.encode(xml: :text)
59
+ builder.parent << content # .encode(xml: :text)
60
60
  end
61
61
  end
62
62
 
@@ -72,6 +72,8 @@ module RelatonBib
72
72
  end
73
73
 
74
74
  class TypedTitleString
75
+ ARGS = %i[content language script format].freeze
76
+
75
77
  # @return [String]
76
78
  attr_reader :type
77
79
 
@@ -93,9 +95,7 @@ module RelatonBib
93
95
  if args[:title]
94
96
  @title = args[:title]
95
97
  else
96
- fsargs = args.select do |k, _v|
97
- %i[content language script format].include? k
98
- end
98
+ fsargs = args.select { |k, _v| ARGS.include? k }
99
99
  @title = FormattedString.new(**fsargs)
100
100
  end
101
101
  end
@@ -5,7 +5,7 @@ module RelatonBib
5
5
  class TypedUri
6
6
  # @return [Symbol] :src/:obp/:rss
7
7
  attr_reader :type
8
- # @retutn [URI]
8
+ # @retutn [Addressable::URI]
9
9
  attr_reader :content
10
10
 
11
11
  # @param type [String, NilClass] src/obp/rss
@@ -37,7 +37,7 @@ module RelatonBib
37
37
  # @param count [Integer] number of links
38
38
  # @return [String]
39
39
  def to_asciibib(prefix = "", count = 1)
40
- pref = prefix.empty? ? "link" : prefix + ".link"
40
+ pref = prefix.empty? ? "link" : "#{prefix}.link"
41
41
  out = count > 1 ? "#{pref}::\n" : ""
42
42
  out += "#{pref}.type:: #{type}\n" if type
43
43
  out += "#{pref}.content:: #{content}\n"
@@ -1,3 +1,3 @@
1
1
  module RelatonBib
2
- VERSION = "1.9.4".freeze
2
+ VERSION = "1.9.8".freeze
3
3
  end
@@ -320,7 +320,7 @@ module RelatonBib
320
320
  # @return [Array<RelatonBib::FormattedString>]
321
321
  def fetch_abstract(item)
322
322
  item.xpath("./abstract").map do |a|
323
- FormattedString.new(content: a.text, language: a[:language],
323
+ FormattedString.new(content: a.children.to_s, language: a[:language],
324
324
  script: a[:script], format: a[:format])
325
325
  end
326
326
  end
data/lib/relaton_bib.rb CHANGED
@@ -6,6 +6,7 @@ require "relaton_bib/localized_string"
6
6
  require "relaton_bib/bibliographic_item"
7
7
  require "relaton_bib/hit_collection"
8
8
  require "relaton_bib/hit"
9
+ require "relaton_bib/bibxml_parser"
9
10
 
10
11
  module RelatonBib
11
12
  class Error < StandardError; end
@@ -13,9 +14,9 @@ module RelatonBib
13
14
  class RequestError < StandardError; end
14
15
 
15
16
  class << self
16
- # @param date [String, Integer, Date]
17
- # @param str [Boolean]
18
- # @return [Date, nil]
17
+ # @param date [String, Integer, Date] date
18
+ # @param str [Boolean] return string or Date
19
+ # @return [Date, String, nil] date
19
20
  def parse_date(date, str = true) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity,Metrics/AbcSize
20
21
  return date if date.is_a?(Date)
21
22
 
data/relaton-bib.gemspec CHANGED
@@ -27,6 +27,9 @@ Gem::Specification.new do |spec|
27
27
  spec.add_development_dependency "equivalent-xml", "~> 0.6"
28
28
  spec.add_development_dependency "rake", "~> 13.0"
29
29
  spec.add_development_dependency "rspec", "~> 3.0"
30
+ spec.add_development_dependency "rubocop"
31
+ spec.add_development_dependency "rubocop-performance"
32
+ spec.add_development_dependency "rubocop-rails"
30
33
  spec.add_development_dependency "ruby-jing"
31
34
  spec.add_development_dependency "simplecov"
32
35
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: relaton-bib
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.4
4
+ version: 1.9.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-10-08 00:00:00.000000000 Z
11
+ date: 2021-12-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: byebug
@@ -66,6 +66,48 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop-performance
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop-rails
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
69
111
  - !ruby/object:Gem::Dependency
70
112
  name: ruby-jing
71
113
  requirement: !ruby/object:Gem::Requirement
@@ -182,6 +224,7 @@ files:
182
224
  - lib/relaton_bib/bibliographic_date.rb
183
225
  - lib/relaton_bib/bibliographic_item.rb
184
226
  - lib/relaton_bib/bibtex_parser.rb
227
+ - lib/relaton_bib/bibxml_parser.rb
185
228
  - lib/relaton_bib/classification.rb
186
229
  - lib/relaton_bib/contribution_info.rb
187
230
  - lib/relaton_bib/contributor.rb