relaton-bib 1.9.2 → 1.9.6

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: 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