relaton-bib 1.4.0 → 2.1.7
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 +4 -4
- data/.github/workflows/integration-tests.yml +54 -0
- data/.github/workflows/rake.yml +15 -0
- data/.github/workflows/release.yml +24 -0
- data/.gitignore +4 -1
- data/.rubocop.yml +3 -1
- data/CLAUDE.md +108 -0
- data/Gemfile +11 -0
- data/README.adoc +229 -314
- data/bin/console +1 -1
- data/docs/hash.adoc +132 -83
- data/lib/relaton/bib/converter/asciibib/to_asciibib.rb +663 -0
- data/lib/relaton/bib/converter/asciibib.rb +13 -0
- data/lib/relaton/bib/converter/bibtex/from_bibtex.rb +245 -0
- data/lib/relaton/bib/converter/bibtex/to_bibtex.rb +341 -0
- data/lib/relaton/bib/converter/bibtex.rb +23 -0
- data/lib/relaton/bib/converter/bibxml/from_rfcxml.rb +386 -0
- data/lib/relaton/bib/converter/bibxml/from_rfcxml_referencegroup.rb +71 -0
- data/lib/relaton/bib/converter/bibxml/to_rfcxml.rb +308 -0
- data/lib/relaton/bib/converter/bibxml/to_rfcxml_referencegroup.rb +52 -0
- data/lib/relaton/bib/converter/bibxml.rb +51 -0
- data/lib/relaton/bib/hash_parser_v1.rb +767 -0
- data/lib/relaton/bib/item_data.rb +229 -0
- data/lib/relaton/bib/model/abstract.rb +16 -0
- data/lib/relaton/bib/model/address.rb +22 -0
- data/lib/relaton/bib/model/affiliation.rb +16 -0
- data/lib/relaton/bib/model/bibdata.rb +9 -0
- data/lib/relaton/bib/model/bibdata_shared.rb +10 -0
- data/lib/relaton/bib/model/bibitem.rb +9 -0
- data/lib/relaton/bib/model/bibitem_shared.rb +10 -0
- data/lib/relaton/bib/model/contact.rb +14 -0
- data/lib/relaton/bib/model/contribution_info.rb +16 -0
- data/lib/relaton/bib/model/contributor.rb +29 -0
- data/lib/relaton/bib/model/copyright.rb +27 -0
- data/lib/relaton/bib/model/date.rb +29 -0
- data/lib/relaton/bib/model/depiction.rb +16 -0
- data/lib/relaton/bib/model/docidentifier.rb +34 -0
- data/lib/relaton/bib/model/doctype.rb +14 -0
- data/lib/relaton/bib/model/edition.rb +14 -0
- data/lib/relaton/bib/model/ext.rb +35 -0
- data/lib/relaton/bib/model/extent.rb +16 -0
- data/lib/relaton/bib/model/formattedref.rb +43 -0
- data/lib/relaton/bib/model/full_name_type.rb +64 -0
- data/lib/relaton/bib/model/fullname.rb +11 -0
- data/lib/relaton/bib/model/ics.rb +49 -0
- data/lib/relaton/bib/model/image.rb +28 -0
- data/lib/relaton/bib/model/item.rb +44 -0
- data/lib/relaton/bib/model/item_base.rb +20 -0
- data/lib/relaton/bib/model/item_shared.rb +88 -0
- data/lib/relaton/bib/model/keyword.rb +30 -0
- data/lib/relaton/bib/model/locality.rb +18 -0
- data/lib/relaton/bib/model/locality_stack.rb +14 -0
- data/lib/relaton/bib/model/localized_string.rb +48 -0
- data/lib/relaton/bib/model/localized_string_attrs.rb +24 -0
- data/lib/relaton/bib/model/logo.rb +14 -0
- data/lib/relaton/bib/model/medium.rb +22 -0
- data/lib/relaton/bib/model/note.rb +16 -0
- data/lib/relaton/bib/model/organization.rb +11 -0
- data/lib/relaton/bib/model/organization_type.rb +40 -0
- data/lib/relaton/bib/model/person.rb +36 -0
- data/lib/relaton/bib/model/phone.rb +14 -0
- data/lib/relaton/bib/model/place.rb +33 -0
- data/lib/relaton/bib/model/price.rb +14 -0
- data/lib/relaton/bib/model/relation.rb +41 -0
- data/lib/relaton/bib/model/series.rb +32 -0
- data/lib/relaton/bib/model/size.rb +23 -0
- data/lib/relaton/bib/model/source_locality_stack.rb +14 -0
- data/lib/relaton/bib/model/status.rb +27 -0
- data/lib/relaton/bib/model/structured_identifier.rb +48 -0
- data/lib/relaton/bib/model/subdivision.rb +16 -0
- data/lib/relaton/bib/model/title.rb +56 -0
- data/lib/relaton/bib/model/type/plain_date.rb +16 -0
- data/lib/relaton/bib/model/type/string_date.rb +48 -0
- data/lib/relaton/bib/model/uri.rb +18 -0
- data/lib/relaton/bib/model/validity.rb +16 -0
- data/lib/relaton/bib/model/version.rb +43 -0
- data/lib/relaton/bib/model_autoload.rb +85 -0
- data/lib/relaton/bib/namespace_helper.rb +21 -0
- data/lib/relaton/bib/sanitizer.rb +74 -0
- data/lib/relaton/bib/util.rb +18 -0
- data/lib/relaton/bib/version.rb +5 -0
- data/lib/relaton/bib/versions.json +35 -0
- data/lib/relaton/bib.rb +41 -0
- data/relaton-bib.gemspec +12 -16
- metadata +118 -129
- data/.github/workflows/macos.yml +0 -38
- data/.github/workflows/ubuntu.yml +0 -39
- data/.github/workflows/windows.yml +0 -41
- data/grammars/basicdoc.rng +0 -986
- data/grammars/biblio.rng +0 -1237
- data/grammars/isodoc.rng +0 -1613
- data/grammars/reqt.rng +0 -165
- data/lib/relaton_bib/bib_item_locality.rb +0 -107
- data/lib/relaton_bib/biblio_note.rb +0 -44
- data/lib/relaton_bib/biblio_version.rb +0 -49
- data/lib/relaton_bib/bibliographic_date.rb +0 -90
- data/lib/relaton_bib/bibliographic_item.rb +0 -726
- data/lib/relaton_bib/bibtex_parser.rb +0 -245
- data/lib/relaton_bib/classification.rb +0 -40
- data/lib/relaton_bib/contribution_info.rb +0 -109
- data/lib/relaton_bib/contributor.rb +0 -215
- data/lib/relaton_bib/copyright_association.rb +0 -77
- data/lib/relaton_bib/deep_dup.rb +0 -30
- data/lib/relaton_bib/document_identifier.rb +0 -95
- data/lib/relaton_bib/document_relation.rb +0 -94
- data/lib/relaton_bib/document_relation_collection.rb +0 -46
- data/lib/relaton_bib/document_status.rb +0 -93
- data/lib/relaton_bib/editorial_group.rb +0 -41
- data/lib/relaton_bib/formatted_ref.rb +0 -17
- data/lib/relaton_bib/formatted_string.rb +0 -55
- data/lib/relaton_bib/hash_converter.rb +0 -497
- data/lib/relaton_bib/hit.rb +0 -46
- data/lib/relaton_bib/hit_collection.rb +0 -73
- data/lib/relaton_bib/ics.rb +0 -37
- data/lib/relaton_bib/localized_string.rb +0 -93
- data/lib/relaton_bib/medium.rb +0 -44
- data/lib/relaton_bib/organization.rb +0 -135
- data/lib/relaton_bib/person.rb +0 -206
- data/lib/relaton_bib/place.rb +0 -49
- data/lib/relaton_bib/series.rb +0 -134
- data/lib/relaton_bib/structured_identifier.rb +0 -171
- data/lib/relaton_bib/technical_committee.rb +0 -36
- data/lib/relaton_bib/typed_title_string.rb +0 -96
- data/lib/relaton_bib/typed_uri.rb +0 -47
- data/lib/relaton_bib/validity.rb +0 -52
- data/lib/relaton_bib/version.rb +0 -3
- data/lib/relaton_bib/workers_pool.rb +0 -43
- data/lib/relaton_bib/workgroup.rb +0 -46
- data/lib/relaton_bib/xml_parser.rb +0 -463
- data/lib/relaton_bib.rb +0 -44
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
module Relaton
|
|
2
|
+
module Bib
|
|
3
|
+
module Converter
|
|
4
|
+
module Bibtex
|
|
5
|
+
class FromBibtex
|
|
6
|
+
# @param entry [BibTeX::Entry]
|
|
7
|
+
def initialize(entry)
|
|
8
|
+
@entry = entry
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# @return [Relaton::Bib::ItemData]
|
|
12
|
+
def transform # rubocop:disable Metrics/MethodLength
|
|
13
|
+
ItemData.new(
|
|
14
|
+
id: @entry.key,
|
|
15
|
+
docidentifier: fetch_docid,
|
|
16
|
+
fetched: fetch_fetched,
|
|
17
|
+
type: fetch_type,
|
|
18
|
+
title: fetch_title,
|
|
19
|
+
contributor: fetch_contributor,
|
|
20
|
+
date: fetch_date,
|
|
21
|
+
place: fetch_place,
|
|
22
|
+
note: fetch_note,
|
|
23
|
+
relation: fetch_relation,
|
|
24
|
+
extent: fetch_extent,
|
|
25
|
+
edition: fetch_edition,
|
|
26
|
+
series: fetch_series,
|
|
27
|
+
source: fetch_link,
|
|
28
|
+
language: fetch_language,
|
|
29
|
+
classification: fetch_classification,
|
|
30
|
+
keyword: fetch_keyword,
|
|
31
|
+
)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
# @return [Array<Relaton::Bib::Docidentifier>]
|
|
37
|
+
def fetch_docid # rubocop:disable Metrics/AbcSize
|
|
38
|
+
docid = [Docidentifier.new(content: @entry.key.to_s, primary: true)]
|
|
39
|
+
docid << Docidentifier.new(content: @entry.isbn.to_s, type: "isbn") if @entry["isbn"]
|
|
40
|
+
docid << Docidentifier.new(content: @entry.lccn.to_s, type: "lccn") if @entry["lccn"]
|
|
41
|
+
docid << Docidentifier.new(content: @entry.issn.to_s, type: "issn") if @entry["issn"]
|
|
42
|
+
docid
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# @return [String, nil]
|
|
46
|
+
def fetch_fetched
|
|
47
|
+
::Date.parse(@entry.timestamp.to_s) if @entry["timestamp"]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# @return [String]
|
|
51
|
+
def fetch_type
|
|
52
|
+
case @entry.type
|
|
53
|
+
when :mastersthesis, :phdthesis then "thesis"
|
|
54
|
+
when :conference then "inproceedings"
|
|
55
|
+
when :misc then "standard"
|
|
56
|
+
else @entry.type.to_s
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# @return [Array<Relaton::Bib::Place>]
|
|
61
|
+
def fetch_place
|
|
62
|
+
@entry["address"] ? [Place.new(formatted_place: @entry.address.to_s)] : []
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# @return [Array<Relaton::Bib::Title>]
|
|
66
|
+
def fetch_title
|
|
67
|
+
title = []
|
|
68
|
+
title << Title.new(type: "main", content: @entry.convert(:latex).title.to_s) if @entry["title"]
|
|
69
|
+
title << Title.new(type: "main", content: @entry.convert(:latex).subtitle.to_s) if @entry["subtitle"]
|
|
70
|
+
title
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# @return [Array<Relaton::Bib::Contributor>]
|
|
74
|
+
def fetch_contributor # rubocop:disable Metrics/AbcSize
|
|
75
|
+
contribs = []
|
|
76
|
+
fetch_person("author") { |c| contribs << c }
|
|
77
|
+
fetch_person("editor") { |c| contribs << c }
|
|
78
|
+
|
|
79
|
+
fetch_org(@entry["publisher"], "publisher") { |c| contribs << c }
|
|
80
|
+
fetch_org(@entry["institution"], "distributor", "sponsor") { |c| contribs << c }
|
|
81
|
+
fetch_org(@entry["organization"], "distributor", "sponsor") { |c| contribs << c }
|
|
82
|
+
fetch_org(@entry["school"], "distributor", "sponsor") { |c| contribs << c }
|
|
83
|
+
|
|
84
|
+
fetch_howpublished { |c| contribs << c }
|
|
85
|
+
|
|
86
|
+
contribs
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def fetch_howpublished(&_)
|
|
90
|
+
return unless @entry["howpublished"]
|
|
91
|
+
|
|
92
|
+
/\\publisher\{(?<name>.+)\},\\url\{(?<url>.+)\}/ =~ @entry.howpublished.to_s
|
|
93
|
+
return unless name && url
|
|
94
|
+
|
|
95
|
+
name.gsub!(/\{\\?([^\\]+)\}/, '\1')
|
|
96
|
+
org = Organization.new(name: [TypedLocalizedString.new(content: name)], url: url)
|
|
97
|
+
yield Contributor.new(
|
|
98
|
+
organization: org,
|
|
99
|
+
role: [Contributor::Role.new(type: "publisher")],
|
|
100
|
+
)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# @param org [String, nil] organization name
|
|
104
|
+
# @param type [String] role type
|
|
105
|
+
# @param desc [String, nil] role description
|
|
106
|
+
def fetch_org(org, type, desc = nil, &_)
|
|
107
|
+
return unless org
|
|
108
|
+
|
|
109
|
+
role_obj = Contributor::Role.new(type: type)
|
|
110
|
+
role_obj.description = [LocalizedMarkedUpString.new(content: desc)] if desc
|
|
111
|
+
yield Contributor.new(organization: Organization.new(name: [TypedLocalizedString.new(content: org.to_s)]), role: [role_obj])
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# @param role [String] contributor role
|
|
115
|
+
def fetch_person(role, &_) # rubocop:disable Metrics/AbcSize
|
|
116
|
+
@entry[role]&.each do |name|
|
|
117
|
+
parts = name.split ", "
|
|
118
|
+
surname = LocalizedString.new(content: parts.first)
|
|
119
|
+
fname = parts.size > 1 ? parts[1].split : []
|
|
120
|
+
forename = fname.map { |fn| FullNameType::Forename.new(content: fn) }
|
|
121
|
+
name = FullName.new(surname: surname, forename: forename)
|
|
122
|
+
yield Contributor.new(
|
|
123
|
+
person: Person.new(name: name),
|
|
124
|
+
role: [Contributor::Role.new(type: role)],
|
|
125
|
+
)
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# @return [Array<Relaton::Bib::Date>]
|
|
130
|
+
def fetch_date
|
|
131
|
+
date = []
|
|
132
|
+
if @entry["year"]
|
|
133
|
+
on = ::Date.new(@entry.year.to_i, @entry["month_numeric"]&.to_i || 1).to_s
|
|
134
|
+
date << Bib::Date.new(type: "published", at: on)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
if @entry["urldate"]
|
|
138
|
+
date << Bib::Date.new(type: "accessed", at: ::Date.parse(@entry.urldate.to_s).to_s)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
date
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# @return [Array<Relaton::Bib::Note>]
|
|
145
|
+
def fetch_note # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength
|
|
146
|
+
@entry.select do |k, _v|
|
|
147
|
+
%i[annote howpublished comment note content].include? k
|
|
148
|
+
end.reduce([]) do |mem, note|
|
|
149
|
+
type = case note[0]
|
|
150
|
+
when :note then nil
|
|
151
|
+
when :content then "tableOfContents"
|
|
152
|
+
else note[0].to_s
|
|
153
|
+
end
|
|
154
|
+
next mem if type == "howpublished" && note[1].to_s.match?(/^\\publisher\{.+\},\\url\{.+\}$/)
|
|
155
|
+
|
|
156
|
+
mem << Note.new(type: type, content: note[1].to_s)
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# @return [Array<Relaton::Bib::Relation>]
|
|
161
|
+
def fetch_relation
|
|
162
|
+
return [] unless @entry["booktitle"]
|
|
163
|
+
|
|
164
|
+
ttl = Title.new(type: "main", content: @entry.booktitle.to_s)
|
|
165
|
+
[Relation.new(type: "partOf", bibitem: ItemData.new(title: [ttl]))]
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# @return [Array<Relaton::Bib::Extent>]
|
|
169
|
+
def fetch_extent # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
|
|
170
|
+
locs = @entry.select do |k, _v|
|
|
171
|
+
%i[chapter pages volume].include? k
|
|
172
|
+
end.reduce([]) do |mem, loc|
|
|
173
|
+
if loc[0] == :pages
|
|
174
|
+
type = "page"
|
|
175
|
+
from, to = loc[1].to_s.split "-"
|
|
176
|
+
else
|
|
177
|
+
type = loc[0].to_s
|
|
178
|
+
from = loc[1].to_s
|
|
179
|
+
to = nil
|
|
180
|
+
end
|
|
181
|
+
mem << Locality.new(type: type, reference_from: from, reference_to: to)
|
|
182
|
+
end
|
|
183
|
+
[Extent.new(locality: locs)]
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# @return [Array<Relaton::Bib::Series>]
|
|
187
|
+
def fetch_series # rubocop:disable Metrics/MethodLength
|
|
188
|
+
series = []
|
|
189
|
+
if @entry["journal"]
|
|
190
|
+
series << Series.new(
|
|
191
|
+
type: "journal",
|
|
192
|
+
title: Title.new(content: @entry.journal.to_s),
|
|
193
|
+
number: @entry["number"]&.to_s,
|
|
194
|
+
)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
if @entry["series"]
|
|
198
|
+
title = Title.new content: @entry.series.to_s
|
|
199
|
+
series << Series.new(title: title)
|
|
200
|
+
end
|
|
201
|
+
series
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
# @return [Array<Relaton::Bib::Uri>]
|
|
205
|
+
def fetch_link # rubocop:disable Metrics/AbcSize
|
|
206
|
+
link = []
|
|
207
|
+
link << Uri.new(type: "src", content: @entry.url.to_s) if @entry["url"]
|
|
208
|
+
link << Uri.new(type: "doi", content: @entry.doi.to_s) if @entry["doi"]
|
|
209
|
+
link << Uri.new(type: "file", content: @entry.file2.to_s) if @entry["file2"]
|
|
210
|
+
link
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# @return [Array<String>]
|
|
214
|
+
def fetch_language
|
|
215
|
+
return [] unless @entry["language"]
|
|
216
|
+
|
|
217
|
+
[Iso639[@entry.language.to_s].alpha2]
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
# @return [Array<Relaton::Bib::Docidentifier>]
|
|
221
|
+
def fetch_classification
|
|
222
|
+
cls = []
|
|
223
|
+
cls << Docidentifier.new(type: "type", content: @entry["type"].to_s) if @entry["type"]
|
|
224
|
+
if @entry["mendeley-tags"]
|
|
225
|
+
cls << Docidentifier.new(type: "mendeley", content: @entry["mendeley-tags"].to_s)
|
|
226
|
+
end
|
|
227
|
+
cls
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
# @return [Array<Relaton::Bib::Keyword>]
|
|
231
|
+
def fetch_keyword
|
|
232
|
+
@entry["keywords"]&.split(/,\s?/)&.map do |kw|
|
|
233
|
+
Keyword.new(vocab: LocalizedString.new(content: kw))
|
|
234
|
+
end || []
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
# @return [Relaton::Bib::Edition, nil]
|
|
238
|
+
def fetch_edition
|
|
239
|
+
Edition.new(content: @entry["edition"].to_s) if @entry["edition"]
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
end
|
|
@@ -0,0 +1,341 @@
|
|
|
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 # rubocop:disable Style/OneClassPerFile
|
|
19
|
+
module Bib
|
|
20
|
+
module Converter
|
|
21
|
+
module Bibtex
|
|
22
|
+
class ToBibtex
|
|
23
|
+
include Core::ArrayWrapper
|
|
24
|
+
|
|
25
|
+
ATTRS = %i[
|
|
26
|
+
type id title author editor booktitle series number edition contributor
|
|
27
|
+
date address note relation extent classification keyword docidentifier
|
|
28
|
+
timestamp link
|
|
29
|
+
].freeze
|
|
30
|
+
|
|
31
|
+
#
|
|
32
|
+
# Initialize ToBibtex.
|
|
33
|
+
#
|
|
34
|
+
# @param bib [Relaton::Bib::ItemData]
|
|
35
|
+
def initialize(bib)
|
|
36
|
+
@bib = bib
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
#
|
|
40
|
+
# Build BibTeX bibliography.
|
|
41
|
+
#
|
|
42
|
+
# @param bibtex [BibTeX::Bibliography, nil] BibTeX bibliography
|
|
43
|
+
#
|
|
44
|
+
# @return [BibTeX::Bibliography] BibTeX bibliography
|
|
45
|
+
#
|
|
46
|
+
def transform(bibtex = nil)
|
|
47
|
+
@item = BibTeX::Entry.new
|
|
48
|
+
ATTRS.each { |a| send("add_#{a}") }
|
|
49
|
+
bibtex ||= BibTeX::Bibliography.new
|
|
50
|
+
bibtex << @item
|
|
51
|
+
bibtex
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
|
|
56
|
+
#
|
|
57
|
+
# Add type to BibTeX item
|
|
58
|
+
#
|
|
59
|
+
def add_type
|
|
60
|
+
@item.type = bibtex_type
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# @return [String] BibTeX type
|
|
64
|
+
def bibtex_type
|
|
65
|
+
case @bib.type
|
|
66
|
+
when "standard", nil then "misc"
|
|
67
|
+
else @bib.type
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
#
|
|
72
|
+
# Add ID to BibTeX item
|
|
73
|
+
#
|
|
74
|
+
def add_id
|
|
75
|
+
@item.key = @bib.id
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
#
|
|
79
|
+
# Add title to BibTeX item
|
|
80
|
+
#
|
|
81
|
+
def add_title
|
|
82
|
+
return unless @bib.title&.any?
|
|
83
|
+
|
|
84
|
+
title = @bib.title.find { |t| t.type == "main" } || @bib.title.first
|
|
85
|
+
return unless title
|
|
86
|
+
|
|
87
|
+
@item .title = title.content
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
#
|
|
91
|
+
# Add booktitle to BibTeX item
|
|
92
|
+
#
|
|
93
|
+
def add_booktitle # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity
|
|
94
|
+
return unless @bib.relation&.any?
|
|
95
|
+
|
|
96
|
+
included_in = @bib.relation.detect { |r| r.type == "includedIn" }
|
|
97
|
+
return unless included_in && included_in.bibitem.title&.any?
|
|
98
|
+
|
|
99
|
+
@item.booktitle = included_in.bibitem.title.first.content
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
#
|
|
103
|
+
# Add author to BibTeX item
|
|
104
|
+
#
|
|
105
|
+
def add_author
|
|
106
|
+
add_author_editor "author"
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
#
|
|
110
|
+
# Add editor to BibTeX item
|
|
111
|
+
#
|
|
112
|
+
def add_editor
|
|
113
|
+
add_author_editor "editor"
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
#
|
|
117
|
+
# Add author or editor to BibTeX item
|
|
118
|
+
#
|
|
119
|
+
# @param [String] type "author" or "editor"
|
|
120
|
+
#
|
|
121
|
+
def add_author_editor(type) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
|
122
|
+
return unless @bib.contributor&.any?
|
|
123
|
+
|
|
124
|
+
contribs = @bib.contributor.select do |c|
|
|
125
|
+
c.person && c.role.any? { |e| e.type == type }
|
|
126
|
+
end.map &:person
|
|
127
|
+
|
|
128
|
+
return unless contribs.any?
|
|
129
|
+
|
|
130
|
+
@item.send "#{type}=", concat_names(contribs)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
#
|
|
134
|
+
# Concatenate names of contributors
|
|
135
|
+
#
|
|
136
|
+
# @param [Array<Relaton::Bib::Person>] contribs contributors
|
|
137
|
+
#
|
|
138
|
+
# @return [String] concatenated names
|
|
139
|
+
#
|
|
140
|
+
def concat_names(contribs)
|
|
141
|
+
contribs.map do |p|
|
|
142
|
+
if p.name.surname
|
|
143
|
+
"#{p.name.surname.content}, #{p.name.forename.map(&:content).join(' ')}"
|
|
144
|
+
else
|
|
145
|
+
p.name.completename.content
|
|
146
|
+
end
|
|
147
|
+
end.join(" and ")
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
#
|
|
151
|
+
# Add series to BibTeX item
|
|
152
|
+
#
|
|
153
|
+
def add_series # rubocop:disable Metrics/AbcSize
|
|
154
|
+
return unless @bib.series
|
|
155
|
+
|
|
156
|
+
@bib.series.each do |s|
|
|
157
|
+
case s.type
|
|
158
|
+
when "journal"
|
|
159
|
+
@item.journal = s.title.first.content
|
|
160
|
+
@item.number = s.number if s.number
|
|
161
|
+
when nil then @item.series = s.title.first.content
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
#
|
|
167
|
+
# Add number to BibTeX item
|
|
168
|
+
#
|
|
169
|
+
def add_number
|
|
170
|
+
return unless %w[techreport manual].include? @bib.type
|
|
171
|
+
|
|
172
|
+
did = @bib.docidentifier.detect { |i| i.primary == true }
|
|
173
|
+
did ||= @bib.docidentifier.first
|
|
174
|
+
@item.number = did.content if did
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
#
|
|
178
|
+
# Add edition to BibTeX item
|
|
179
|
+
#
|
|
180
|
+
def add_edition
|
|
181
|
+
@item.edition = @bib.edition.content if @bib.edition
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
#
|
|
185
|
+
# Add contributor to BibTeX item
|
|
186
|
+
#
|
|
187
|
+
def add_contributor # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
|
188
|
+
@bib.contributor.each do |c|
|
|
189
|
+
rls = c.role.map(&:type)
|
|
190
|
+
if rls.include?("publisher") then @item.publisher = c.organization.name.first.content
|
|
191
|
+
elsif rls.include?("distributor")
|
|
192
|
+
case @bib.type
|
|
193
|
+
when "techreport" then @item.institution = c.organization.name.first.content
|
|
194
|
+
when "inproceedings", "conference", "manual", "proceedings"
|
|
195
|
+
@item.organization = c.organization.name.first.content
|
|
196
|
+
when "mastersthesis", "phdthesis" then @item.school = c.organization.name.first.content
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
#
|
|
203
|
+
# Add date to BibTeX item
|
|
204
|
+
#
|
|
205
|
+
def add_date
|
|
206
|
+
array(@bib.date).each do |d|
|
|
207
|
+
case d.type
|
|
208
|
+
when "published"
|
|
209
|
+
year, month, = d.at.split("-")
|
|
210
|
+
@item.year = year
|
|
211
|
+
@item.month = month if month
|
|
212
|
+
when "accessed" then @item.urldate = d.at.to_s
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
#
|
|
218
|
+
# Add address to BibTeX item
|
|
219
|
+
#
|
|
220
|
+
def add_address # rubocop:disable Metrics/AbcSize
|
|
221
|
+
return unless @bib.place&.any?
|
|
222
|
+
|
|
223
|
+
reg = @bib.place[0].region[0].content if @bib.place[0].region.any?
|
|
224
|
+
addr = [@bib.place[0].formatted_place, @bib.place[0].city, reg]
|
|
225
|
+
@item.address = addr.compact.join(", ")
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
#
|
|
229
|
+
# Add note to BibTeX item
|
|
230
|
+
#
|
|
231
|
+
def add_note # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
|
232
|
+
array(@bib.note).each do |n|
|
|
233
|
+
case n.type
|
|
234
|
+
when "annote" then @item.annote = n.content
|
|
235
|
+
when "howpublished" then @item.howpublished = n.content
|
|
236
|
+
when "comment" then @item.comment = n.content
|
|
237
|
+
when "tableOfContents" then @item.content = n.content
|
|
238
|
+
when nil then @item.note = n.content
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
#
|
|
244
|
+
# Add relation to BibTeX item
|
|
245
|
+
#
|
|
246
|
+
def add_relation # rubocop:disable Metrics/AbcSize
|
|
247
|
+
rel = array(@bib.relation).detect { |r| r.type == "partOf" }
|
|
248
|
+
if rel && rel.bibitem.title&.any?
|
|
249
|
+
title_main = rel.bibitem.title.detect { |t| t.type == "main" }
|
|
250
|
+
@item.booktitle = title_main.content
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
#
|
|
255
|
+
# Add extent to BibTeX item
|
|
256
|
+
#
|
|
257
|
+
def add_extent # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
|
258
|
+
@bib.extent&.each do |extent|
|
|
259
|
+
extent.locality&.each { |loc| add_locality loc } ||
|
|
260
|
+
extent.locality_stack&.each { |locs| add_locality_stack locs }
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
def add_locality_stack(locs)
|
|
265
|
+
return unless locs
|
|
266
|
+
|
|
267
|
+
locs.locality.each { |loc| add_locality loc }
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def add_locality(loc)
|
|
271
|
+
case loc.type
|
|
272
|
+
when "chapter" then @item.chapter = loc.reference_from
|
|
273
|
+
when "page"
|
|
274
|
+
value = [loc.reference_from]
|
|
275
|
+
value << loc.reference_to if loc.reference_to
|
|
276
|
+
@item.pages = value.join("--")
|
|
277
|
+
when "volume" then @item.volume = loc.reference_from
|
|
278
|
+
when "issue" then @item.issue = loc.reference_from
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
#
|
|
283
|
+
# Add classification to BibTeX item
|
|
284
|
+
#
|
|
285
|
+
def add_classification
|
|
286
|
+
@bib.classification&.each do |c|
|
|
287
|
+
case c.type
|
|
288
|
+
when "type" then @item["type"] = c.content
|
|
289
|
+
when "mendeley" then @item["mendeley-tags"] = c.content
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
#
|
|
295
|
+
# Add keywords to BibTeX item
|
|
296
|
+
#
|
|
297
|
+
def add_keyword
|
|
298
|
+
if @bib.keyword&.any?
|
|
299
|
+
@item.keywords = @bib.keyword.reduce([]) do |m, kw|
|
|
300
|
+
m + (kw.vocab ? [kw.vocab.content] : kw.taxon.map(&:content))
|
|
301
|
+
end.join(", ")
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
#
|
|
306
|
+
# Add docidentifier to BibTeX item
|
|
307
|
+
#
|
|
308
|
+
def add_docidentifier
|
|
309
|
+
@bib.docidentifier&.each do |i|
|
|
310
|
+
case i.type
|
|
311
|
+
when "isbn" then @item.isbn = i.content
|
|
312
|
+
when "lccn" then @item.lccn = i.content
|
|
313
|
+
when "issn" then @item.issn = i.content
|
|
314
|
+
end
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
#
|
|
319
|
+
# Add identifier to BibTeX item
|
|
320
|
+
#
|
|
321
|
+
def add_timestamp
|
|
322
|
+
@item.timestamp = @bib.fetched.to_s if @bib.fetched
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
#
|
|
326
|
+
# Add link to BibTeX item
|
|
327
|
+
#
|
|
328
|
+
def add_link # rubocop:disable Metrics/CyclomaticComplexity
|
|
329
|
+
@bib.source&.each do |l|
|
|
330
|
+
case l.type&.downcase
|
|
331
|
+
when "doi" then @item.doi = l.content
|
|
332
|
+
when "file" then @item.file2 = l.content
|
|
333
|
+
when "src" then @item.url = l.content
|
|
334
|
+
end
|
|
335
|
+
end
|
|
336
|
+
end
|
|
337
|
+
end
|
|
338
|
+
end
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require_relative "bibtex/from_bibtex"
|
|
2
|
+
require_relative "bibtex/to_bibtex"
|
|
3
|
+
|
|
4
|
+
module Relaton
|
|
5
|
+
module Bib
|
|
6
|
+
module Converter
|
|
7
|
+
module Bibtex
|
|
8
|
+
# ItemData -> BibTeX::Bibliography
|
|
9
|
+
def self.from_item(item, bibtex = nil)
|
|
10
|
+
ToBibtex.new(item).transform(bibtex)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# BibTeX string -> Hash{String=>ItemData}
|
|
14
|
+
def self.to_item(bibtex_str)
|
|
15
|
+
BibTeX.parse(bibtex_str).reduce({}) do |h, bt|
|
|
16
|
+
h[bt.key] = FromBibtex.new(bt).transform
|
|
17
|
+
h
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|