relaton-bib 2.0.0.pre.alpha.1 → 2.0.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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -1
  3. data/.rubocop.yml +1 -1
  4. data/CLAUDE.md +96 -0
  5. data/Gemfile +1 -0
  6. data/README.adoc +14 -2
  7. data/grammars/basicdoc.rng +75 -45
  8. data/grammars/biblio-standoc.rng +37 -56
  9. data/grammars/biblio.rng +68 -36
  10. data/grammars/versions.json +25 -25
  11. data/lib/relaton/bib/converter/asciibib/to_asciibib.rb +663 -0
  12. data/lib/relaton/bib/converter/asciibib.rb +13 -0
  13. data/lib/relaton/bib/converter/bibtex/from_bibtex.rb +245 -0
  14. data/lib/relaton/bib/converter/bibtex/to_bibtex.rb +341 -0
  15. data/lib/relaton/bib/converter/bibtex.rb +23 -0
  16. data/lib/relaton/bib/converter/bibxml/from_rfcxml.rb +383 -0
  17. data/lib/relaton/bib/converter/bibxml/from_rfcxml_referencegroup.rb +71 -0
  18. data/lib/relaton/bib/{renderer/rfc.rb → converter/bibxml/to_rfcxml.rb} +100 -92
  19. data/lib/relaton/bib/converter/bibxml/to_rfcxml_referencegroup.rb +52 -0
  20. data/lib/relaton/bib/converter/bibxml.rb +51 -0
  21. data/lib/relaton/bib/hash_parser_v1.rb +121 -78
  22. data/lib/relaton/bib/item_data.rb +83 -22
  23. data/lib/relaton/bib/model/abstract.rb +16 -0
  24. data/lib/relaton/bib/model/date.rb +6 -4
  25. data/lib/relaton/bib/model/depiction.rb +2 -0
  26. data/lib/relaton/bib/model/ext.rb +0 -3
  27. data/lib/relaton/bib/model/formattedref.rb +43 -0
  28. data/lib/relaton/bib/model/ics.rb +9 -0
  29. data/lib/relaton/bib/model/item.rb +12 -4
  30. data/lib/relaton/bib/model/item_base.rb +17 -9
  31. data/lib/relaton/bib/model/keyword.rb +3 -3
  32. data/lib/relaton/bib/model/logo.rb +2 -0
  33. data/lib/relaton/bib/model/organization_type.rb +1 -1
  34. data/lib/relaton/bib/model/relation.rb +2 -2
  35. data/lib/relaton/bib/model/series.rb +5 -3
  36. data/lib/relaton/bib/model/subdivision.rb +2 -0
  37. data/lib/relaton/bib/model/title.rb +38 -0
  38. data/lib/relaton/bib/model/type/string_date.rb +48 -0
  39. data/lib/relaton/bib/model/validity.rb +3 -3
  40. data/lib/relaton/bib/namespace_helper.rb +21 -0
  41. data/lib/relaton/bib/version.rb +1 -1
  42. data/lib/relaton/bib.rb +5 -82
  43. data/relaton-bib.gemspec +5 -2
  44. metadata +63 -29
  45. data/lib/relaton/bib/model/editorial_group.rb +0 -14
  46. data/lib/relaton/bib/model/technical_committee.rb +0 -14
  47. data/lib/relaton/bib/model/workgroup.rb +0 -20
  48. data/lib/relaton/bib/parser/rfc_address.rb +0 -60
  49. data/lib/relaton/bib/parser/rfc_contacts.rb +0 -35
  50. data/lib/relaton/bib/parser/rfc_docidentifier.rb +0 -70
  51. data/lib/relaton/bib/parser/rfc_organization.rb +0 -31
  52. data/lib/relaton/bib/parser/rfc_person.rb +0 -42
  53. data/lib/relaton/bib/parser/rfc_reference.rb +0 -143
  54. data/lib/relaton/bib/parser/rfc_referencegroup.rb +0 -45
  55. data/lib/relaton/bib/parser/rfc_shared.rb +0 -23
  56. data/lib/relaton/bib/renderer/bibtex_builder.rb +0 -348
  57. data/lib/relaton/bibtex_parser.rb +0 -243
  58. data/lib/relaton/bibxml_parser.rb +0 -419
  59. data/lib/relaton/deep_dup.rb +0 -30
  60. data/lib/relaton/hit.rb +0 -52
  61. data/lib/relaton/hit_collection.rb +0 -105
  62. data/lib/relaton/workers_pool.rb +0 -43
  63. data/lib/relaton/xml_parser.rb +0 -716
@@ -1,143 +0,0 @@
1
- require_relative "rfc_shared"
2
- require_relative "rfc_contacts"
3
- require_relative "rfc_person"
4
- require_relative "rfc_organization"
5
- require_relative "rfc_docidentifier"
6
-
7
- module Relaton
8
- module Bib
9
- module Parser
10
- class RfcReference
11
- include RfcShared
12
-
13
- def initialize(reference)
14
- @reference = reference
15
- end
16
-
17
- def self.from_xml(xml)
18
- reference = Rfcxml::V3::Reference.from_xml xml
19
- new(reference).transform
20
- end
21
-
22
- def transform # rubocop:disable Metrics/MethodLength
23
- ItemData.new(
24
- docnumber: @reference.anchor.sub(/^\w+\./, ""),
25
- type: "standard",
26
- docidentifier: RfcDocidentifier.new(@reference).transform,
27
- status: status,
28
- language: ["en"],
29
- script: ["Latn"],
30
- source: source,
31
- title: title,
32
- formattedref: formattedref,
33
- abstract: abstract,
34
- contributor: contributor,
35
- date: date,
36
- series: series,
37
- keyword: keyword,
38
- ext: ext,
39
- )
40
- end
41
-
42
- def status
43
- si = @reference.front.series_info&.find(&:status) || @reference.series_info&.status
44
- return unless si
45
-
46
- stage = Status::Stage.new(content: si.status)
47
- Status.new(stage: stage)
48
- end
49
-
50
- def title
51
- [Title.new(content: @reference.front.title.content, language: "en", script: "Latn")]
52
- end
53
-
54
- def formattedref
55
- return if @reference.front.title
56
-
57
- @reference.anchor
58
- end
59
-
60
- def abstract
61
- return [] unless @reference.front.abstract
62
-
63
- @reference.front.abstract.t.map do |t|
64
- LocalizedMarkedUpString.new(content: t.content, language: "en", script: "Latn")
65
- end
66
- end
67
-
68
- def contributor
69
- (@reference.front.author || []).reduce([]) do |acc, author|
70
- p = person(author)
71
- o = organization(author)
72
- next acc unless p || o
73
-
74
- acc << Contributor.new(person: p, organization: o, role: [contributor_role(author)])
75
- end
76
- end
77
-
78
- def contributor_role(author)
79
- type = author.role || "author"
80
- Contributor::Role.new(type: type)
81
- end
82
-
83
- def person(author) = RfcPerson.transform(author)
84
- def organization(author) = RfcOrganization.transform(author)
85
-
86
- def date # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
87
- dt = @reference.front&.date
88
- return [] unless dt || dt.year || dt.month || dt.day
89
-
90
- dparts = [dt.year, month_to_num(dt.month), dt.day].compact.reject(&:empty?)
91
- at = dt.content.empty? ? dparts.join("-") : dt.content
92
- [Date.new(type: "published", at: at)]
93
- end
94
-
95
- def month_to_num(month)
96
- return unless month
97
-
98
- ::Date::MONTHNAMES.index(month.capitalize).to_s
99
- end
100
-
101
- def series # rubocop:disable Metrics/CyclomaticComplexity
102
- ((@reference.series_info || []) + (@reference.front.series_info || [])).map do |si|
103
- next if si.name == "DOI" || si.stream || si.status
104
-
105
- t = Title.new(content: si.name, language: "en", script: "Latn")
106
- Series.new(title: [t], number: si.value, type: "main")
107
- end.compact
108
- end
109
-
110
- def keyword
111
- (@reference.front.keyword || []).map do |kw|
112
- taxon = LocalizedString.new(content: kw.content, language: "en", script: "Latn")
113
- Keyword.new(taxon: [taxon])
114
- end
115
- end
116
-
117
- def ext
118
- eg = editorialgroup
119
- dt = doctype
120
- return unless eg || dt
121
-
122
- Bib::Ext.new editorialgroup: eg, doctype: dt
123
- end
124
-
125
- def editorialgroup
126
- return unless @reference.front.workgroup
127
-
128
- tc = @reference.front.workgroup.map { |wg| WorkGroup.new content: wg.content }
129
- EditorialGroup.new(technical_committee: tc) if tc.any?
130
- end
131
-
132
- def doctype
133
- type = case @reference.anchor
134
- when /I-D/ then "internet-draft"
135
- when /IEEE/ then "ieee"
136
- else "rfc"
137
- end
138
- Doctype.new content: type
139
- end
140
- end
141
- end
142
- end
143
- end
@@ -1,45 +0,0 @@
1
- require_relative "rfc_shared"
2
-
3
- module Relaton
4
- module Bib
5
- module Parser
6
- # Class for transforming RFC ReferenceGroup to Relaton ReferenceGroup
7
- class RfcReferencegroup
8
- include RfcShared
9
-
10
- def initialize(reference)
11
- @reference = reference
12
- end
13
-
14
- #
15
- # Transform reference group from RFC ReferenceGroup to Relaton ReferenceGroup
16
- #
17
- # @param [Rfcxml::V3::ReferenceGroup] reference_group RFC ReferenceGroup
18
- #
19
- # @return [Relaton::Bib::ReferenceGroup]
20
- #
21
- def self.from_xml(xml) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
22
- reference = Rfcxml::V3::Referencegroup.from_xml xml
23
- new(reference).transform
24
- end
25
-
26
- def transform
27
- ItemData.new(
28
- docnumber: @reference.anchor.sub(/^\w+\./, ""),
29
- type: "standard",
30
- docidentifier: RfcDocidentifier.new(@reference).transform,
31
- source: source,
32
- relation: relation,
33
- )
34
- end
35
-
36
- def relation
37
- (@reference.reference || []).map do |ref|
38
- item = RfcReference.new(ref).transform
39
- Relation.new(type: "includes", bibitem: item)
40
- end
41
- end
42
- end
43
- end
44
- end
45
- end
@@ -1,23 +0,0 @@
1
- module Relaton
2
- module Bib
3
- module Parser
4
- module RfcShared
5
- def source # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
6
- s = []
7
- s << Uri.new(type: "src", content: @reference.target) if @reference.target
8
- # if /^I-D/.match? @reference.anchor
9
- # @reference.format.each do |f|
10
- # s << Uri.new(type: f.type, content: f.target)
11
- # end
12
- # end
13
- return s unless @reference.respond_to?(:front) && @reference.front
14
-
15
- (@reference.format || []).each do |fr|
16
- s << Uri.new(type: fr.type, content: fr.target)
17
- end
18
- s
19
- end
20
- end
21
- end
22
- end
23
- end
@@ -1,348 +0,0 @@
1
- # Monkey patch to fix the issue with month quotes in BibTeX
2
- module BibTeX
3
- class Value
4
- def to_s(options = {}) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
5
- if options.key?(:filter)
6
- opts = options.reject { |k,| k == :filter || (k == :quotes && (!atomic? || symbol?)) }
7
- return convert(options[:filter]).to_s(opts)
8
- end
9
-
10
- return value.to_s unless options.key?(:quotes) && atomic?
11
-
12
- q = Array(options[:quotes])
13
- [q[0], value, q[-1]].compact.join
14
- end
15
- end
16
- end
17
-
18
- module Relaton
19
- module Bib
20
- module Renderer
21
- # BibTeX builder.
22
- class BibtexBuilder
23
- ATTRS = %i[
24
- type id title author editor booktitle series number edition contributor
25
- date address note relation extent classification keyword docidentifier
26
- timestamp link
27
- ].freeze
28
-
29
- #
30
- # Build BibTeX bibliography.
31
- #
32
- # @param bib [Relaton::Bib::Item]
33
- # @param bibtex [BibTeX::Bibliography, nil] BibTeX bibliography
34
- #
35
- # @return [BibTeX::Bibliography] BibTeX bibliography
36
- #
37
- def self.build(bib, bibtex = nil)
38
- new(bib).build bibtex
39
- end
40
-
41
- #
42
- # Initialize BibTeX builder.
43
- #
44
- # @param bib [Relaton::Bib::Item]
45
- def initialize(bib)
46
- @bib = bib
47
- end
48
-
49
- #
50
- # Build BibTeX bibliography.
51
- #
52
- # @param bibtex [BibTeX::Bibliography, nil] BibTeX bibliography
53
- #
54
- # @return [BibTeX::Bibliography] BibTeX bibliography
55
- #
56
- def build(bibtex = nil)
57
- @item = BibTeX::Entry.new
58
- ATTRS.each { |a| send("add_#{a}") }
59
- bibtex ||= BibTeX::Bibliography.new
60
- bibtex << @item
61
- bibtex
62
- end
63
-
64
- private
65
-
66
- #
67
- # Add type to BibTeX item
68
- #
69
- def add_type
70
- @item.type = bibtex_type
71
- end
72
-
73
- # @return [String] BibTeX type
74
- def bibtex_type
75
- case @bib.type
76
- when "standard", nil then "misc"
77
- else @bib.type
78
- end
79
- end
80
-
81
- #
82
- # Add ID to BibTeX item
83
- #
84
- def add_id
85
- @item.key = @bib.id
86
- end
87
-
88
- #
89
- # Add title to BibTeX item
90
- #
91
- def add_title
92
- return unless @bib.title&.any?
93
-
94
- title = @bib.title.find { |t| t.type == "main" } || @bib.title.first
95
- return unless title
96
-
97
- @item .title = title.content
98
- end
99
-
100
- #
101
- # Add booktitle to BibTeX item
102
- #
103
- def add_booktitle # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity
104
- return unless @bib.relation&.any?
105
-
106
- included_in = @bib.relation.detect { |r| r.type == "includedIn" }
107
- return unless included_in && included_in.bibitem.title&.any?
108
-
109
- @item.booktitle = included_in.bibitem.title.first.content
110
- end
111
-
112
- #
113
- # Add author to BibTeX item
114
- #
115
- def add_author
116
- add_author_editor "author"
117
- end
118
-
119
- #
120
- # Add editor to BibTeX item
121
- #
122
- def add_editor
123
- add_author_editor "editor"
124
- end
125
-
126
- #
127
- # Add author or editor to BibTeX item
128
- #
129
- # @param [String] type "author" or "editor"
130
- #
131
- def add_author_editor(type) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
132
- retur unless @bib.contributor&.any?
133
-
134
- contribs = @bib.contributor.select do |c|
135
- c.person && c.role.any? { |e| e.type == type }
136
- end.map &:person
137
-
138
- return unless contribs.any?
139
-
140
- @item.send "#{type}=", concat_names(contribs)
141
- end
142
-
143
- #
144
- # Concatenate names of contributors
145
- #
146
- # @param [Array<Relaton::Bib::Person>] contribs contributors
147
- #
148
- # @return [String] concatenated names
149
- #
150
- def concat_names(contribs)
151
- contribs.map do |p|
152
- if p.name.surname
153
- "#{p.name.surname.content}, #{p.name.forename.map(&:content).join(' ')}"
154
- else
155
- p.name.completename.content
156
- end
157
- end.join(" and ")
158
- end
159
-
160
- #
161
- # Add series to BibTeX item
162
- #
163
- def add_series # rubocop:disable Metrics/AbcSize
164
- return unless @bib.series
165
-
166
- @bib.series.each do |s|
167
- case s.type
168
- when "journal"
169
- @item.journal = s.title.first.content
170
- @item.number = s.number if s.number
171
- when nil then @item.series = s.title.first.content
172
- end
173
- end
174
- end
175
-
176
- #
177
- # Add number to BibTeX item
178
- #
179
- def add_number
180
- return unless %w[techreport manual].include? @bib.type
181
-
182
- did = @bib.docidentifier.detect { |i| i.primary == true }
183
- did ||= @bib.docidentifier.first
184
- @item.number = did.content if did
185
- end
186
-
187
- #
188
- # Add edition to BibTeX item
189
- #
190
- def add_edition
191
- @item.edition = @bib.edition.content if @bib.edition
192
- end
193
-
194
- #
195
- # Add contributor to BibTeX item
196
- #
197
- def add_contributor # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
198
- @bib.contributor.each do |c|
199
- rls = c.role.map(&:type)
200
- if rls.include?("publisher") then @item.publisher = c.organization.name.first.content
201
- elsif rls.include?("distributor")
202
- case @bib.type
203
- when "techreport" then @item.institution = c.organization.name.first.content
204
- when "inproceedings", "conference", "manual", "proceedings"
205
- @item.organization = c.organization.name.first.content
206
- when "mastersthesis", "phdthesis" then @item.school = c.organization.name.first.content
207
- end
208
- end
209
- end
210
- end
211
-
212
- #
213
- # Add date to BibTeX item
214
- #
215
- def add_date
216
- Relaton.array(@bib.date).each do |d|
217
- case d.type
218
- when "published"
219
- year, month, = d.at.split("-")
220
- @item.year = year
221
- @item.month = month if month
222
- when "accessed" then @item.urldate = d.at
223
- end
224
- end
225
- end
226
-
227
- #
228
- # Add address to BibTeX item
229
- #
230
- def add_address # rubocop:disable Metrics/AbcSize
231
- return unless @bib.place&.any?
232
-
233
- reg = @bib.place[0].region[0].content if @bib.place[0].region.any?
234
- addr = [@bib.place[0].formatted_place, @bib.place[0].city, reg]
235
- @item.address = addr.compact.join(", ")
236
- end
237
-
238
- #
239
- # Add note to BibTeX item
240
- #
241
- def add_note # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
242
- Relaton.array(@bib.note).each do |n|
243
- case n.type
244
- when "annote" then @item.annote = n.content
245
- when "howpublished" then @item.howpublished = n.content
246
- when "comment" then @item.comment = n.content
247
- when "tableOfContents" then @item.content = n.content
248
- when nil then @item.note = n.content
249
- end
250
- end
251
- end
252
-
253
- #
254
- # Add relation to BibTeX item
255
- #
256
- def add_relation # rubocop:disable Metrics/AbcSize
257
- rel = Relaton.array(@bib.relation).detect { |r| r.type == "partOf" }
258
- if rel && rel.bibitem.title&.any?
259
- title_main = rel.bibitem.title.detect { |t| t.type == "main" }
260
- @item.booktitle = title_main.content
261
- end
262
- end
263
-
264
- #
265
- # Add extent to BibTeX item
266
- #
267
- def add_extent # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
268
- @bib.extent&.each do |extent|
269
- extent.locality&.each { |loc| add_locality loc } ||
270
- extent.locality_stack&.each { |locs| add_locality_stack locs }
271
- end
272
- end
273
-
274
- def add_locality_stack(locs)
275
- return unless locs
276
-
277
- locs.locality.each { |loc| add_locality loc }
278
- end
279
-
280
- def add_locality(loc)
281
- case loc.type
282
- when "chapter" then @item.chapter = loc.reference_from
283
- when "page"
284
- value = [loc.reference_from]
285
- value << loc.reference_to if loc.reference_to
286
- @item.pages = value.join("--")
287
- when "volume" then @item.volume = loc.reference_from
288
- when "issue" then @item.issue = loc.reference_from
289
- end
290
- end
291
-
292
- #
293
- # Add classification to BibTeX item
294
- #
295
- def add_classification
296
- @bib.classification&.each do |c|
297
- case c.type
298
- when "type" then @item["type"] = c.content
299
- when "mendeley" then @item["mendeley-tags"] = c.content
300
- end
301
- end
302
- end
303
-
304
- #
305
- # Add keywords to BibTeX item
306
- #
307
- def add_keyword
308
- if @bib.keyword&.any?
309
- @item.keywords = @bib.keyword.reduce([]) { |m, kw| m + kw.taxon.map(&:content) }.join(", ")
310
- end
311
- end
312
-
313
- #
314
- # Add docidentifier to BibTeX item
315
- #
316
- def add_docidentifier
317
- @bib.docidentifier&.each do |i|
318
- case i.type
319
- when "isbn" then @item.isbn = i.content
320
- when "lccn" then @item.lccn = i.content
321
- when "issn" then @item.issn = i.content
322
- end
323
- end
324
- end
325
-
326
- #
327
- # Add identifier to BibTeX item
328
- #
329
- def add_timestamp
330
- @item.timestamp = @bib.fetched.to_s if @bib.fetched
331
- end
332
-
333
- #
334
- # Add link to BibTeX item
335
- #
336
- def add_link # rubocop:disable Metrics/CyclomaticComplexity
337
- @bib.source&.each do |l|
338
- case l.type&.downcase
339
- when "doi" then @item.doi = l.content
340
- when "file" then @item.file2 = l.content
341
- when "src" then @item.url = l.content
342
- end
343
- end
344
- end
345
- end
346
- end
347
- end
348
- end