relaton-bib 1.9.2 → 1.9.6

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: 159e7430eaae042b7130807811e748afeede73d727c865d06a3acedd03e5de08
4
- data.tar.gz: 69c3efa7687a851d14aee6a22878b4359928eb692371313384f4332bd1dee068
3
+ metadata.gz: 04d616ee7971147c734b6e0520531c4e9b529e76b53c22a98dca1c36b6f49285
4
+ data.tar.gz: 2762c1d26b7a07888c3605939ae18de1b6f2ef44da7f1513dc779e3207ff176f
5
5
  SHA512:
6
- metadata.gz: 02bc4eceac45f0e63be85121b73a68db0c66625b917d108a5ebde58a6e975373a0e95f9e2b30a056f1551de18357cfeb49c89804758385cbf5e324513fe6037c
7
- data.tar.gz: b2cebd03f70db311a4839c4543f02d2011dbed485d79c7823023dd088381424fc9070bf885cd5232d8eef6841c8d8fdd7cb434d61ba93b9c8457635684cbc601
6
+ metadata.gz: beffce777ed3ef33181363edaf57a8e1efced984bcc19ffae88eaa8087a92e48d044b042686dc4b5e6e545f41fe7f67c1eb573abaddc4e056adc439643f0b12a
7
+ data.tar.gz: 44d2809601f70d17db2f5601a29614720fa13a0cfa3fbb1665406e0c4396390862688fc41cbd26de421e19efb5643a61e184b73bf2cb47be567c7aa4788ad4a4
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]
@@ -416,6 +428,45 @@ title.format:: text/plain
416
428
  ...
417
429
  ----
418
430
 
431
+ === Export bibliographic item to BibXML (RFC)
432
+
433
+ [source,ruby]
434
+ ----
435
+ item.to_bibxml
436
+ <reference anchor="ISOTC211" target="https://www.iso.org/standard/53798.html">
437
+ <front>
438
+ <title>Geographic information</title>
439
+ <seriesInfo name="DOI" value="10.17487/rfc1149"/>
440
+ <seriesInfo name="Internet-Draft" value="draft-ietf-somewg-someprotocol-07"/>
441
+ <seriesInfo name="RFC" value="4"/>
442
+ <author>
443
+ <organization abbrev="ISO">International Organization for Standardization</organization>
444
+ </author>
445
+ <author fullname="A. Bierman">
446
+ <organization abbrev="IETF">IETF</organization>
447
+ <address>
448
+ <postal>123456</postal>
449
+ <phone>223322</phone>
450
+ </address>
451
+ </author>
452
+ <author role="editor">
453
+ <organization abbrev="IETF">IETF</organization>
454
+ </author>
455
+ <author initials="A." surname="Bierman">
456
+ <organization abbrev="IETF">IETF</organization>
457
+ <address>
458
+ <postal>123456</postal>
459
+ <phone>223322</phone>
460
+ </address>
461
+ </author>
462
+ <author>
463
+ <organization>Institution</organization>
464
+ </author>
465
+ <date year="2014" month="April" day="1"/>
466
+ </front>
467
+ </reference>
468
+ ----
469
+
419
470
  == Development
420
471
 
421
472
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -429,4 +480,3 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/metano
429
480
  == License
430
481
 
431
482
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
432
-
@@ -325,6 +325,23 @@ module RelatonBib
325
325
  end
326
326
  end
327
327
 
328
+ #
329
+ # Render BibXML (RFC)
330
+ #
331
+ # @param [Nokogiri::XML::Builder, nil] builder
332
+ #
333
+ # @return [String] <description>
334
+ #
335
+ def to_bibxml(builder = nil)
336
+ if builder
337
+ render_bibxml builder
338
+ else
339
+ Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml|
340
+ render_bibxml xml
341
+ end
342
+ end.doc.root.to_xml
343
+ end
344
+
328
345
  # @return [Hash]
329
346
  def to_hash # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
330
347
  hash = {}
@@ -740,8 +757,155 @@ module RelatonBib
740
757
  xml[:type] = type if type
741
758
  xml
742
759
  end
760
+ # rubocop:enable Style/NestedParenthesizedCalls, Metrics/BlockLength
761
+
762
+ #
763
+ # Render BibXML (RFC)
764
+ #
765
+ # @param [Nokogiri::XML::Builder] builder
766
+ #
767
+ def render_bibxml(builder)
768
+ target = link.detect { |l| l.type == "src" } || link.detect { |l| l.type == "doi" }
769
+ bxml = builder.reference(anchor: anchor) do |xml|
770
+ xml.front do
771
+ xml.title title[0].title.content if title.any?
772
+ render_seriesinfo xml
773
+ render_authors xml
774
+ render_date xml
775
+ render_workgroup xml
776
+ render_keyword xml
777
+ render_abstract xml
778
+ end
779
+ end
780
+ bxml[:target] = target.content.to_s if target
781
+ end
782
+
783
+ def anchor
784
+ did = docidentifier.detect { |di| di.type == "rfc-anchor" }
785
+ return did.id if did
786
+
787
+ type = docidentifier[0].type
788
+ "#{type}.#{docnumber}"
789
+ end
790
+
791
+ def render_keyword(builder)
792
+ keyword.each do |kw|
793
+ builder.keyword kw.content
794
+ end
795
+ end
796
+
797
+ def render_workgroup(builder)
798
+ editorialgroup&.technical_committee&.each do |tc|
799
+ builder.workgroup tc.workgroup.name
800
+ end
801
+ end
802
+
803
+ # @param [Nokogiri::XML::Builder] builder
804
+ def render_abstract(builder)
805
+ return unless abstract.any?
806
+
807
+ builder.abstract { |xml| xml << abstract[0].content.gsub(/(<\/?)p(>)/, '\1t\2') }
808
+ end
809
+
810
+ # @param [Nokogiri::XML::Builder] builder
811
+ def render_date(builder)
812
+ dt = date.detect { |d| d.type == "published" }
813
+ return unless dt
814
+
815
+ elm = builder.date
816
+ y = dt.on(:year) || dt.from(:year) || dt.to(:year)
817
+ elm[:year] = y if y
818
+ m = dt.on(:month) || dt.from(:month) || dt.to(:month)
819
+ elm[:month] = Date::MONTHNAMES[m] if m
820
+ d = dt.on(:day) || dt.from(:day) || dt.to(:day)
821
+ elm[:day] = d if d
822
+ end
823
+
824
+ # @param [Nokogiri::XML::Builder] builder
825
+ def render_seriesinfo(builder)
826
+ docidentifier.each do |di|
827
+ if BibXMLParser::SERIESINFONAMES.include? di.type
828
+ builder.seriesInfo(name: di.type, value: di.id)
829
+ end
830
+ end
831
+ snames = ["ANSI", "BCP", "RFC", "STD"]
832
+ series.each do |s|
833
+ next unless s.title && snames.include?(s.title.title.to_s)
834
+
835
+ si = builder.seriesInfo(name: s.title.title.to_s)
836
+ si[:value] = s.number if s.number
837
+ end
838
+ end
839
+
840
+ # @param [Nokogiri::XML::Builder] builder
841
+ def render_authors(builder)
842
+ contributor.each do |c|
843
+ builder.author do |xml|
844
+ xml.parent[:role] = "editor" if c.role.detect { |r| r.type == "editor" }
845
+ if c.entity.is_a?(Person) then render_person xml, c.entity
846
+ else render_organization xml, c.entity
847
+ end
848
+ render_address xml, c
849
+ end
850
+ end
851
+ end
852
+
853
+ # @param [Nokogiri::XML::Builder] builder
854
+ # @param [RelatonBib::ContributionInfo] contrib
855
+ def render_address(builder, contrib)
856
+ # addr = contrib.entity.contact.reject do |cn|
857
+ # cn.is_a?(Address) && cn.postcode.nil?
858
+ # end
859
+ if contrib.entity.contact.any?
860
+ builder.address do |xml|
861
+ address = contrib.entity.contact.detect { |cn| cn.is_a? Address }
862
+ if address
863
+ xml.postal do
864
+ xml.city address.city if address.city
865
+ xml.code address.postcode if address.postcode
866
+ xml.country address.country if address.country
867
+ xml.region address.state if address.state
868
+ xml.street address.street[0] if address.street.any?
869
+ end
870
+ end
871
+ render_contact xml, contrib.entity.contact
872
+ end
873
+ end
874
+ end
875
+
876
+ # @param [Nokogiri::XML::Builder] builder
877
+ # @param [Array<RelatonBib::Address, RelatonBib::Contact>] addr
878
+ def render_contact(builder, addr)
879
+ %w[phone email uri].each do |type|
880
+ cont = addr.detect { |cn| cn.is_a?(Contact) && cn.type == type }
881
+ builder.send type, cont.value if cont
882
+ end
883
+ end
884
+
885
+ # @param [Nokogiri::XML::Builder] builder
886
+ # @param [RelatonBib::Person] person
887
+ def render_person(builder, person)
888
+ render_organization builder, person.affiliation.first&.organization
889
+ if person.name.completename
890
+ builder.parent[:fullname] = person.name.completename
891
+ end
892
+ if person.name.initial.any?
893
+ builder.parent[:initials] = person.name.initial.map(&:content).join
894
+ end
895
+ if person.name.surname
896
+ builder.parent[:surname] = person.name.surname
897
+ end
898
+ end
899
+
900
+ # @param [Nokogiri::XML::Builder] builder
901
+ # @param [RelatonBib::Organization] org
902
+ def render_organization(builder, org)
903
+ return unless org
904
+
905
+ o = builder.organization org.name.first&.content
906
+ o[:abbrev] = org.abbreviation.content if org.abbreviation
907
+ end
743
908
  # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
744
909
  # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
745
- # rubocop:enable Style/NestedParenthesizedCalls, Metrics/BlockLength
746
910
  end
747
911
  end
@@ -0,0 +1,345 @@
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}']", "./front/seriesInfo[@name='#{self::FLAVOR}']")
71
+ if sfid
72
+ ret << DocumentIdentifier.new(type: sfid[:name], id: sfid[:value])
73
+ elsif self::FLAVOR && (id = (reference[:anchor] || reference[:docName] || reference[:number]))
74
+ ret << DocumentIdentifier.new( type: self::FLAVOR, id: id.sub(/^(RFC)/, "\\1 "))
75
+ end
76
+ if (id = reference[:anchor])
77
+ ret << DocumentIdentifier.new(type: "rfc-anchor", id: id)
78
+ end
79
+ ret + reference.xpath("./seriesInfo", "./front/seriesInfo").map do |si|
80
+ next unless SERIESINFONAMES.include? si[:name]
81
+
82
+ id = si[:value]
83
+ id.sub!(/(?<=-)\d{2}$/, ver) if ver && si[:name] == "Internet-Draft"
84
+ DocumentIdentifier.new(id: id, type: si[:name])
85
+ end.compact
86
+ end
87
+
88
+ #
89
+ # extract status
90
+ # @param reference [Nokogiri::XML::Element]
91
+ #
92
+ # @return [RelatonBib::DocumentStatus]
93
+ #
94
+ def status(reference)
95
+ st = reference.at("./seriesinfo[@status]")
96
+ DocumentStatus.new(stage: st[:status]) if st
97
+ end
98
+
99
+ # @param reference [Nokogiri::XML::Element]
100
+ # @param url [String]
101
+ # @param ver [String, nil] Internet Draft version
102
+ # @return [Array<Hash>]
103
+ def link(reference, url, ver)
104
+ l = []
105
+ l << { type: "xml", content: url } if url
106
+ l << { type: "src", content: reference[:target] } if reference[:target]
107
+ if /^I-D/.match? reference[:anchor]
108
+ reference.xpath("format").each do |f|
109
+ c = ver ? f[:target].sub(/(?<=-)\d{2}(?=\.)/, ver) : f[:target]
110
+ l << { type: f[:type], content: c }
111
+ end
112
+ end
113
+ l
114
+ end
115
+
116
+ # @param reference [Nokogiri::XML::Element]
117
+ # @return [Array<Hash>]
118
+ def titles(reference)
119
+ reference.xpath("./front/title").map do |title|
120
+ { content: title.text, language: language(reference), script: "Latn" }
121
+ end
122
+ end
123
+
124
+ # @param reference [Nokogiri::XML::Element]
125
+ # @return [RelatonBib::FormattedRef, nil]
126
+ def formattedref(reference)
127
+ return if reference.at "./front/title"
128
+
129
+ cont = (reference[:anchor] || reference[:docName] || reference[:number])
130
+ if cont
131
+ FormattedRef.new(
132
+ content: cont, language: language(reference), script: "Latn",
133
+ )
134
+ end
135
+ end
136
+
137
+ # @param reference [Nokogiri::XML::Element]
138
+ # @return [Array<RelatonBib::FormattedString>]
139
+ def abstracts(ref)
140
+ ref.xpath("./front/abstract").map do |a|
141
+ FormattedString.new(
142
+ content: a.children.to_s.gsub(/(<\/?)t(>)/, '\1p\2'),
143
+ language: language(ref), script: "Latn", format: "text/html"
144
+ )
145
+ end
146
+ end
147
+
148
+ # @param reference [Nokogiri::XML::Element]
149
+ # @return [Array<Hash>]
150
+ def contributors(reference)
151
+ reference.xpath("./front/author").map do |contrib|
152
+ if contrib[:fullname] || contrib[:surname] then person(contrib, reference)
153
+ else organization(contrib)
154
+ end
155
+ end.compact
156
+ # persons(reference) + organizations(reference)
157
+ end
158
+
159
+ # @param author [Nokogiri::XML::Element]
160
+ # @param reference [Nokogiri::XML::Element]
161
+ # @return [Array<Hash{Symbol=>RelatonBib::Person,Symbol=>Array<String>}>]
162
+ def person(author, reference)
163
+ # reference.xpath("./front/author[@surname]|./front/author[@fullname]")
164
+ # .map do |author|
165
+ entity = Person.new(
166
+ name: full_name(author, reference),
167
+ affiliation: affiliation(author),
168
+ contact: contacts(author.at("./address")),
169
+ )
170
+ { entity: entity, role: [contributor_role(author)] }
171
+ # end
172
+ end
173
+
174
+ # @param contrib [Nokogiri::XML::Element]
175
+ # @return [Array<Hash{Symbol=>RelatonBib::Organization,
176
+ # Symbol=>Array<String>}>]
177
+ def organization(contrib)
178
+ # publisher = { entity: new_org, role: [type: "publisher"] }
179
+ # orgs = reference.xpath("./seriesinfo").reduce([]) do |mem, si|
180
+ # next mem unless si[:stream]
181
+
182
+ # mem << { entity: new_org(si[:stream], nil), role: [type: "author"] }
183
+ # end
184
+ # orgs + reference.xpath(
185
+ # "front/author[not(@surname)][not(@fullname)]/organization",
186
+ # ).map do |org|
187
+ org = contrib.at("./organization")
188
+ { entity: new_org(org.text, org[:abbrev]), role: [contributor_role(contrib)] }
189
+ # end
190
+ end
191
+
192
+ # @param author [Nokogiri::XML::Element]
193
+ # @param reference [Nokogiri::XML::Element]
194
+ # @return [RelatonBib::FullName]
195
+ def full_name(author, reference)
196
+ lang = language reference
197
+ FullName.new(
198
+ completename: localized_string(author[:fullname], lang),
199
+ initial: [localized_string(author[:initials], lang)].compact,
200
+ surname: localized_string(author[:surname], lang),
201
+ )
202
+ end
203
+
204
+ # @param author [Nokogiri::XML::Element]
205
+ # @return [Array<RelatonBib::Affiliation>]
206
+ def affiliation(author)
207
+ o = author.at("./organization")
208
+ return [] if o.nil? || o.text.empty?
209
+
210
+ org = new_org o.text, o[:abbrev]
211
+ [Affiliation.new(organization: org)]
212
+ end
213
+
214
+ # @param name [String]
215
+ # @param abbr [String]
216
+ # @return [RelatonBib::Organization]
217
+ def new_org(name, abbr)
218
+ # (name = "Internet Engineering Task Force", abbr = "IETF")
219
+ Organization.new name: name, abbreviation: abbr
220
+ end
221
+
222
+ # @param content [String, nil]
223
+ # @param lang [String, nil]
224
+ # @return [RelatonBib::LocalizedString, nil]
225
+ def localized_string(content, lang)
226
+ LocalizedString.new(content, lang) if content
227
+ end
228
+
229
+ # @param postal [Nokogiri::XML::Element]
230
+ # @return [Array<RelatonBib::Address, RelatonBib::Phone>]
231
+ def contacts(addr)
232
+ conts = []
233
+ return conts unless addr
234
+
235
+ postal = addr.at("./postal")
236
+ conts << address(postal) if postal
237
+ add_contact(conts, "phone", addr.at("./phone"))
238
+ add_contact(conts, "email", addr.at("./email"))
239
+ add_contact(conts, "uri", addr.at("./uri"))
240
+ conts
241
+ end
242
+
243
+ # @param postal [Nokogiri::XML::Element]
244
+ # @rerurn [RelatonBib::Address]
245
+ def address(postal) # rubocop:disable Metrics/CyclomaticComplexity
246
+ street = [
247
+ (postal.at("./postalLine") || postal.at("./street"))&.text
248
+ ].compact
249
+ Address.new(
250
+ street: street,
251
+ city: postal.at("./city")&.text,
252
+ postcode: postal.at("./code")&.text,
253
+ country: postal.at("./country")&.text,
254
+ state: postal.at("./region")&.text,
255
+ )
256
+ end
257
+
258
+ # @param conts [Array<RelatonBib::Address, RelatonBib::Contact>]
259
+ # @param type [String] allowed "phone", "email" or "uri"
260
+ # @param value [String]
261
+ def add_contact(conts, type, value)
262
+ conts << Contact.new(type: type, value: value.text) if value
263
+ end
264
+
265
+ # @param author [Nokogiri::XML::Document]
266
+ # @return [Hash]
267
+ def contributor_role(author)
268
+ { type: author[:role] || "author" }
269
+ end
270
+
271
+ # @param reference [Nokogiri::XML::Element]
272
+ # @return [Hash]
273
+ def relations(reference)
274
+ reference.xpath("reference").map do |ref|
275
+ { type: "includes", bibitem: fetch_rfc(ref, is_relation: true) }
276
+ end
277
+ end
278
+
279
+ #
280
+ # Extract date from reference.
281
+ #
282
+ # @param reference [Nokogiri::XML::Element]
283
+ # @return [Array<RelatonBib::BibliographicDate>] published data.
284
+ #
285
+ def dates(reference)
286
+ return unless (date = reference.at "./front/date")
287
+
288
+ d = [date[:year], month(date[:month]), (date[:day] || 1)].compact.join "-"
289
+ date = Time.parse(d).strftime "%Y-%m-%d"
290
+ [BibliographicDate.new(type: "published", on: date)]
291
+ end
292
+
293
+ # @param reference [Nokogiri::XML::Element]
294
+ # @return [RelatonBib::EditorialGroup, nil]
295
+ def editorialgroup(reference)
296
+ tc = reference.xpath("./front/workgroup").map do |ed|
297
+ wg = WorkGroup.new name: ed.text
298
+ committee wg
299
+ end
300
+ EditorialGroup.new tc if tc.any?
301
+ end
302
+
303
+ # @param [RelatonBib::WorkGroup]
304
+ # @return [RelatonBib::TechnicalCommittee]
305
+ def committee(wgr)
306
+ TechnicalCommittee.new wgr
307
+ end
308
+
309
+ def month(mon)
310
+ return 1 if !mon || mon.empty?
311
+ return mon if /^\d+$/.match? mon
312
+
313
+ Date::MONTHNAMES.index(mon)
314
+ end
315
+
316
+ #
317
+ # Extract series form reference
318
+ # @param reference [Nokogiri::XML::Element]
319
+ #
320
+ # @return [Array<RelatonBib::Series>]
321
+ #
322
+ def series(reference)
323
+ reference.xpath("./seriesInfo", "./front/seriesInfo").map do |si|
324
+ next if si[:name] == "DOI" || si[:stream] || si[:status]
325
+
326
+ t = TypedTitleString.new(
327
+ content: si[:name], language: language(reference), script: "Latn",
328
+ )
329
+ Series.new(title: t, number: si[:value], type: "main")
330
+ end.compact
331
+ end
332
+
333
+ # @param anchor [String]
334
+ # @return [String]
335
+ def doctype(anchor)
336
+ case anchor
337
+ when /I-D/ then "internet-draft"
338
+ when /IEEE/ then "ieee"
339
+ else "rfc"
340
+ end
341
+ end
342
+
343
+ extend BibXMLParser
344
+ end
345
+ end
@@ -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
 
@@ -7,7 +7,7 @@ module RelatonBib
7
7
  # @return [Array<RelatonBib::TechnicalCommittee>]
8
8
  attr_accessor :technical_committee
9
9
 
10
- # @param technical_committee [Array<RelatonBib::TecnicalCommittee>]
10
+ # @param technical_committee [Array<RelatonBib::TechnicalCommittee>]
11
11
  def initialize(technical_committee)
12
12
  @technical_committee = technical_committee
13
13
  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
 
@@ -99,7 +99,7 @@ module RelatonBib
99
99
  builder.abbreviation { |a| abbreviation.to_xml a } if abbreviation
100
100
  builder.uri url if uri
101
101
  identifier.each { |identifier| identifier.to_xml builder }
102
- super
102
+ super builder
103
103
  end
104
104
  end
105
105
 
@@ -1,3 +1,3 @@
1
1
  module RelatonBib
2
- VERSION = "1.9.2".freeze
2
+ VERSION = "1.9.6".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
@@ -1,10 +1,12 @@
1
1
  require "forwardable"
2
+ require "yaml"
2
3
  require "relaton_bib/version"
3
4
  require "relaton_bib/deep_dup"
4
5
  require "relaton_bib/localized_string"
5
6
  require "relaton_bib/bibliographic_item"
6
7
  require "relaton_bib/hit_collection"
7
8
  require "relaton_bib/hit"
9
+ require "relaton_bib/bibxml_parser"
8
10
 
9
11
  module RelatonBib
10
12
  class Error < StandardError; end
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.2
4
+ version: 1.9.6
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-09-22 00:00:00.000000000 Z
11
+ date: 2021-10-25 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