bolognese 2.0.0 → 2.3.3

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 (66) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +1 -1
  3. data/.github/workflows/release.yml +2 -2
  4. data/Gemfile.lock +13 -12
  5. data/bolognese.gemspec +4 -3
  6. data/lib/bolognese/author_utils.rb +4 -4
  7. data/lib/bolognese/datacite_utils.rb +1 -1
  8. data/lib/bolognese/metadata_utils.rb +2 -1
  9. data/lib/bolognese/readers/citeproc_reader.rb +6 -0
  10. data/lib/bolognese/readers/crossref_reader.rb +37 -3
  11. data/lib/bolognese/readers/datacite_reader.rb +1 -1
  12. data/lib/bolognese/readers/schema_org_reader.rb +26 -4
  13. data/lib/bolognese/utils.rb +14 -9
  14. data/lib/bolognese/version.rb +1 -1
  15. data/lib/bolognese/writers/datacite_json_writer.rb +1 -4
  16. data/lib/bolognese/writers/jats_writer.rb +4 -1
  17. data/lib/bolognese/writers/schema_org_writer.rb +5 -1
  18. data/resources/kernel-4/include/datacite-contributorType-v4.xsd +3 -1
  19. data/resources/kernel-4/include/datacite-dateType-v4.xsd +3 -1
  20. data/resources/kernel-4/include/datacite-relatedIdentifierType-v4.xsd +5 -2
  21. data/resources/kernel-4/include/datacite-relationType-v4.xsd +7 -3
  22. data/resources/kernel-4/include/datacite-resourceType-v4.xsd +5 -1
  23. data/resources/kernel-4/include/datacite-titleType-v4.xsd +1 -1
  24. data/resources/kernel-4/metadata.xsd +2 -1
  25. data/resources/kernel-4.6/include/datacite-contributorType-v4.xsd +37 -0
  26. data/resources/kernel-4.6/include/datacite-dateType-v4.xsd +27 -0
  27. data/resources/kernel-4.6/include/datacite-descriptionType-v4.xsd +19 -0
  28. data/resources/kernel-4.6/include/datacite-funderIdentifierType-v4.xsd +16 -0
  29. data/resources/kernel-4.6/include/datacite-nameType-v4.xsd +10 -0
  30. data/resources/kernel-4.6/include/datacite-numberType-v4.xsd +12 -0
  31. data/resources/kernel-4.6/include/datacite-relatedIdentifierType-v4.xsd +37 -0
  32. data/resources/kernel-4.6/include/datacite-relationType-v4.xsd +57 -0
  33. data/resources/kernel-4.6/include/datacite-resourceType-v4.xsd +49 -0
  34. data/resources/kernel-4.6/include/datacite-titleType-v4.xsd +14 -0
  35. data/resources/kernel-4.6/include/xml.xsd +286 -0
  36. data/resources/kernel-4.6/metadata.xsd +712 -0
  37. data/spec/author_utils_spec.rb +8 -2
  38. data/spec/datacite_utils_spec.rb +151 -1
  39. data/spec/fixtures/citeproc.json +6 -2
  40. data/spec/fixtures/crossref_schema_4.6_values.xml +183 -0
  41. data/spec/fixtures/datacite-example-ROR-nameIdentifiers.xml +8 -0
  42. data/spec/fixtures/datacite-example-full-v4.6.xml +114 -0
  43. data/spec/fixtures/datacite-xml-lang.xml +1 -1
  44. data/spec/fixtures/datacite_blank_name_identifier.xml +22 -0
  45. data/spec/fixtures/datacite_blank_publisher.xml +18 -0
  46. data/spec/fixtures/datacite_journal_article.xml +64 -0
  47. data/spec/fixtures/schema_org.json +1 -0
  48. data/spec/fixtures/schema_org_4.6_attributes.json +108 -0
  49. data/spec/fixtures/vcr_cassettes/Bolognese_Metadata/insert_contributors_Translator/supports_Translator_contributorType.yml +71 -0
  50. data/spec/fixtures/vcr_cassettes/Bolognese_Metadata/insert_dates_with_Coverage/inserts_date_with_dateType_Coverage.yml +71 -0
  51. data/spec/fixtures/vcr_cassettes/Bolognese_Metadata/insert_related_identifiers_CSTR/supports_CSTR_relatedIdentifierType.yml +71 -0
  52. data/spec/fixtures/vcr_cassettes/Bolognese_Metadata/insert_related_identifiers_HasTranslation/supports_HasTranslation_relationType.yml +71 -0
  53. data/spec/fixtures/vcr_cassettes/Bolognese_Metadata/insert_related_identifiers_RRID/supports_RRID_relatedIdentifierType.yml +71 -0
  54. data/spec/fixtures/vcr_cassettes/Bolognese_Metadata/insert_resource_type_with_Award/supports_Award_as_resourceTypeGeneral.yml +71 -0
  55. data/spec/fixtures/vcr_cassettes/Bolognese_Metadata/insert_resource_type_with_Project/supports_Project_as_resourceTypeGeneral.yml +71 -0
  56. data/spec/readers/citeproc_reader_spec.rb +1 -0
  57. data/spec/readers/crossref_reader_spec.rb +31 -0
  58. data/spec/readers/datacite_reader_spec.rb +91 -0
  59. data/spec/readers/schema_org_reader_spec.rb +28 -1
  60. data/spec/writers/citation_writer_spec.rb +9 -0
  61. data/spec/writers/citeproc_writer_spec.rb +9 -0
  62. data/spec/writers/datacite_json_writer_spec.rb +16 -32
  63. data/spec/writers/datacite_writer_spec.rb +71 -0
  64. data/spec/writers/jats_writer_spec.rb +8 -1
  65. data/spec/writers/schema_org_writer_spec.rb +49 -0
  66. metadata +58 -25
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 23ccf372b59b7d9c8919ec7ad7137eef6e99512eed488977e847f938f389aa2f
4
- data.tar.gz: 390e56023d57e637a52776a98dcd0bea4fa0acd8b8459ced05cbc6785f69fe0a
3
+ metadata.gz: 1a86efd4d59883de399bfae917077f97c5f5e33bd698bc70fc4a3daa40736acc
4
+ data.tar.gz: da3ac310e177b6ad9733ff56cb9893cfe107c0beb930167b7b8f392dfb2332f4
5
5
  SHA512:
6
- metadata.gz: 3a7364a75d69846ada1320bc0e8954b72695216d2807ec39ab1694ac4d120d97806addb9ceed8b9da8c1eb06ae28740cf6d2c118cb76a05e15ca993bf81ad470
7
- data.tar.gz: 6281527f6b312d398a96b9f1df9be55de991f6ac939417131633b24ddaa24741c3b86c3b2e4e73408ca1350e0b17addf9439ae30dff998bc6dda07e8c4459db7
6
+ metadata.gz: ee269b568dd16e08da5c10f00155a3e0b55e9725c1d6aa114c6c3a5020dfe05c2df89388a9bc394a6274e86ca81567f4f756dd31bcaf5faa12dff2a7df275308
7
+ data.tar.gz: 26245d3b2e4553616ba0708047b542f4092240e4cc251ae578de502010ba69a3d6700a5df48f59cd427b7f0eaf498a15cc043cd78ad799572bd589dfcbad6784
@@ -7,7 +7,7 @@ jobs:
7
7
  strategy:
8
8
  fail-fast: false
9
9
  matrix:
10
- ruby: ["2.6", "2.7", "3.0", "3.1"]
10
+ ruby: ["3.0", "3.1", "3.2", "3.3"]
11
11
  runs-on: ubuntu-latest
12
12
  steps:
13
13
  - uses: actions/checkout@v3
@@ -11,10 +11,10 @@ jobs:
11
11
  runs-on: ubuntu-latest
12
12
  steps:
13
13
  - uses: actions/checkout@v3
14
- - name: Set up Ruby 2.6
14
+ - name: Set up Ruby 3.1.4
15
15
  uses: ruby/setup-ruby@v1
16
16
  with:
17
- ruby-version: "2.6"
17
+ ruby-version: "3.1.4"
18
18
 
19
19
  - name: Build
20
20
  run: |
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- bolognese (2.0.0)
4
+ bolognese (2.3.3)
5
5
  activesupport (>= 4.2.5)
6
6
  benchmark_methods (~> 0.7)
7
7
  bibtex-ruby (>= 5.1.0)
@@ -16,9 +16,9 @@ PATH
16
16
  json-ld-preloaded (~> 3.1, >= 3.1.3)
17
17
  jsonlint (~> 0.3.0)
18
18
  loofah (~> 2.0, >= 2.0.3)
19
- maremma (>= 4.9.4, < 5)
19
+ maremma (~> 5.0)
20
20
  namae (~> 1.0)
21
- nokogiri (>= 1.13.2, < 1.14)
21
+ nokogiri (~> 1.16, >= 1.16.2)
22
22
  oj (~> 3.10)
23
23
  oj_mimic_json (~> 1.0, >= 1.0.1)
24
24
  postrank-uri (~> 1.0, >= 1.0.18)
@@ -95,10 +95,10 @@ GEM
95
95
  concurrent-ruby (~> 1.0)
96
96
  iso8601 (0.9.1)
97
97
  json (2.6.2)
98
- json-canonicalization (0.3.2)
99
- json-ld (3.2.5)
98
+ json-canonicalization (0.3.1)
99
+ json-ld (3.2.4)
100
100
  htmlentities (~> 4.3)
101
- json-canonicalization (~> 0.3, >= 0.3.2)
101
+ json-canonicalization (~> 0.3)
102
102
  link_header (~> 0.0, >= 0.0.8)
103
103
  multi_json (~> 1.15)
104
104
  rack (>= 2.2, < 4)
@@ -114,7 +114,7 @@ GEM
114
114
  loofah (2.21.3)
115
115
  crass (~> 1.0.2)
116
116
  nokogiri (>= 1.12.0)
117
- maremma (4.9.9)
117
+ maremma (5.0.0)
118
118
  activesupport (>= 4.2.5)
119
119
  addressable (>= 2.3.6)
120
120
  builder (~> 3.2, >= 3.2.2)
@@ -125,17 +125,17 @@ GEM
125
125
  faraday-follow_redirects (~> 0.3.0)
126
126
  faraday-gzip (~> 0.1.0)
127
127
  faraday-multipart (~> 1.0.4)
128
- nokogiri (>= 1.13.1, < 1.14.0)
128
+ nokogiri (~> 1.16, >= 1.16.2)
129
129
  oj (>= 2.8.3)
130
130
  oj_mimic_json (~> 1.0, >= 1.0.1)
131
131
  matrix (0.4.2)
132
- mini_portile2 (2.8.0)
132
+ mini_portile2 (2.8.5)
133
133
  minitest (5.18.0)
134
134
  multi_json (1.15.0)
135
135
  multipart-post (2.3.0)
136
136
  namae (1.1.1)
137
- nokogiri (1.13.9)
138
- mini_portile2 (~> 2.8.0)
137
+ nokogiri (1.16.2)
138
+ mini_portile2 (~> 2.8.2)
139
139
  racc (~> 1.4)
140
140
  oj (3.14.2)
141
141
  oj_mimic_json (1.0.1)
@@ -225,6 +225,7 @@ DEPENDENCIES
225
225
  bundler (>= 1.0)
226
226
  byebug
227
227
  hashdiff (>= 1.0.0.beta1, < 2.0.0)
228
+ json-canonicalization (= 0.3.1)
228
229
  rack-test (~> 0)
229
230
  rake (~> 12.0)
230
231
  rspec (~> 3.4)
@@ -234,4 +235,4 @@ DEPENDENCIES
234
235
  webmock (~> 3.0, >= 3.0.1)
235
236
 
236
237
  BUNDLED WITH
237
- 2.4.20
238
+ 2.5.5
data/bolognese.gemspec CHANGED
@@ -13,12 +13,12 @@ Gem::Specification.new do |s|
13
13
  s.version = Bolognese::VERSION
14
14
  s.extra_rdoc_files = ["README.md"]
15
15
  s.license = 'MIT'
16
- s.required_ruby_version = ['>=2.3']
16
+ s.required_ruby_version = ['>=3.0']
17
17
 
18
18
  # Declare dependencies here, rather than in the Gemfile
19
- s.add_dependency 'maremma', '>= 4.9.4', '< 5'
19
+ s.add_dependency 'maremma', '~> 5.0'
20
20
  #s.add_dependency 'faraday', '~> 0.17.3'
21
- s.add_dependency 'nokogiri', '>= 1.13.2', '< 1.14'
21
+ s.add_dependency 'nokogiri', '~> 1.16', '>= 1.16.2'
22
22
  s.add_dependency 'loofah', '~> 2.0', '>= 2.0.3'
23
23
  s.add_dependency 'builder', '~> 3.2', '>= 3.2.2'
24
24
  s.add_dependency 'activesupport', '>= 4.2.5'
@@ -50,6 +50,7 @@ Gem::Specification.new do |s|
50
50
  s.add_development_dependency 'simplecov', '0.17.1'
51
51
  s.add_development_dependency 'hashdiff', ['>= 1.0.0.beta1', '< 2.0.0']
52
52
  s.add_development_dependency 'byebug'
53
+ s.add_development_dependency 'json-canonicalization', '0.3.1'
53
54
 
54
55
  s.require_paths = ["lib"]
55
56
  s.files = `git ls-files`.split($/)
@@ -30,20 +30,20 @@ module Bolognese
30
30
  name_type = parse_attributes(author.fetch("creatorName", nil), content: "nameType", first: true) || parse_attributes(author.fetch("contributorName", nil), content: "nameType", first: true)
31
31
 
32
32
  name_identifiers = Array.wrap(author.fetch("nameIdentifier", nil)).map do |ni|
33
- ni["__content__"] = ni["__content__"].strip
33
+ name_identifier = ni["__content__"].strip if ni["__content__"].present?
34
34
  if ni["nameIdentifierScheme"] == "ORCID"
35
35
  {
36
- "nameIdentifier" => normalize_orcid(ni["__content__"]),
36
+ "nameIdentifier" => normalize_orcid(name_identifier),
37
37
  "schemeUri" => "https://orcid.org",
38
38
  "nameIdentifierScheme" => "ORCID" }.compact
39
39
  elsif ni["nameIdentifierScheme"] == "ROR"
40
40
  {
41
- "nameIdentifier" => normalize_ror(ni["__content__"]),
41
+ "nameIdentifier" => normalize_ror(name_identifier),
42
42
  "schemeUri" => "https://ror.org",
43
43
  "nameIdentifierScheme" => "ROR" }.compact
44
44
  else
45
45
  {
46
- "nameIdentifier" => ni["__content__"],
46
+ "nameIdentifier" => name_identifier,
47
47
  "schemeUri" => ni.fetch("schemeURI", nil),
48
48
  "nameIdentifierScheme" => ni["nameIdentifierScheme"] }.compact
49
49
  end
@@ -128,7 +128,7 @@ module Bolognese
128
128
  def insert_resource_type(xml)
129
129
  return xml unless types.is_a?(Hash) && (types["schemaOrg"].present? || types["resourceTypeGeneral"])
130
130
 
131
- xml.resourceType(types["resourceType"] || types["schemaOrg"],
131
+ xml.resourceType(types["resourceType"],
132
132
  'resourceTypeGeneral' => types["resourceTypeGeneral"] || Metadata::SO_TO_DC_TRANSLATIONS[types["schemaOrg"]] || "Other")
133
133
  end
134
134
 
@@ -96,7 +96,7 @@ module Bolognese
96
96
  if container.present?
97
97
  container["title"]
98
98
  elsif types["citeproc"] == "article-journal"
99
- publisher
99
+ publisher["name"] if publisher.present?
100
100
  else
101
101
  nil
102
102
  end
@@ -153,6 +153,7 @@ module Bolognese
153
153
  "language" => language,
154
154
  "author" => author,
155
155
  "contributor" => to_citeproc(contributors),
156
+ "translator" => contributors ? to_citeproc(contributors.select { |c| c["contributorType"] == "Translator" }) : nil,
156
157
  "issued" => get_date(dates, "Issued") ? get_date_parts(get_date(dates, "Issued")) : get_date_parts(publication_year.to_s),
157
158
  "submitted" => Array.wrap(dates).find { |d| d["dateType"] == "Submitted" }.to_h.fetch("__content__", nil),
158
159
  "abstract" => parse_attributes(descriptions, content: "description", first: true),
@@ -52,6 +52,12 @@ module Bolognese
52
52
  [{ "nameType" => "Organizational", "name" => ":(unav)" }]
53
53
  end
54
54
  contributors = get_authors(from_citeproc(Array.wrap(meta.fetch("editor", nil))))
55
+ translators = get_authors(from_citeproc(Array.wrap(meta.fetch("translator", nil))))
56
+ translators.each do |translator|
57
+ translator["contributorType"] = "Translator"
58
+ end
59
+ contributors += translators
60
+
55
61
  dates = if date = get_date_from_date_parts(meta.fetch("issued", nil))
56
62
  if Date.edtf(date).present?
57
63
  [{ "date" => date,
@@ -4,6 +4,12 @@ module Bolognese
4
4
  module Readers
5
5
  module CrossrefReader
6
6
  # CrossRef types from https://api.crossref.org/types
7
+
8
+ CR_TO_DC_CONTRIBUTOR_TYPES = {
9
+ "editor" => "Editor",
10
+ "translator" => "Translator",
11
+ }
12
+
7
13
  def get_crossref(id: nil, **options)
8
14
  return { "string" => nil, "state" => "not_found" } unless id.present?
9
15
 
@@ -138,7 +144,7 @@ module Bolognese
138
144
 
139
145
  state = meta.present? || read_options.present? ? "findable" : "not_found"
140
146
 
141
- related_identifiers = Array.wrap(crossref_is_part_of(journal_metadata)) + Array.wrap(crossref_references(bibliographic_metadata))
147
+ related_identifiers = Array.wrap(crossref_is_part_of(journal_metadata)) + Array.wrap(crossref_references(bibliographic_metadata)) + Array.wrap(crossref_has_translation(program_metadata)) + Array.wrap(crossref_is_translation_of(program_metadata))
142
148
 
143
149
  container = if journal_metadata.present?
144
150
  issn = normalize_issn(journal_metadata.to_h.fetch("issn", nil))
@@ -187,7 +193,7 @@ module Bolognese
187
193
  "titles" => titles,
188
194
  "identifiers" => identifiers,
189
195
  "creators" => crossref_people(bibliographic_metadata, "author"),
190
- "contributors" => crossref_people(bibliographic_metadata, "editor"),
196
+ "contributors" => crossref_people(bibliographic_metadata, "editor") + crossref_people(bibliographic_metadata, "translator"),
191
197
  "funding_references" => crossref_funding_reference(program_metadata),
192
198
  "publisher" => publisher,
193
199
  "container" => container,
@@ -276,13 +282,15 @@ module Bolognese
276
282
  end
277
283
  end.compact
278
284
 
285
+ contributor_type = CR_TO_DC_CONTRIBUTOR_TYPES[a["contributor_role"]]
286
+
279
287
  { "nameType" => "Personal",
280
288
  "nameIdentifiers" => name_identifiers,
281
289
  "name" => [family_name, given_name].compact.join(", "),
282
290
  "givenName" => given_name,
283
291
  "familyName" => family_name,
284
292
  "affiliation" => affiliation.presence,
285
- "contributorType" => contributor_role == "editor" ? "Editor" : nil }.compact
293
+ "contributorType" => contributor_type }.compact
286
294
  else
287
295
  { "nameType" => "Organizational",
288
296
  "name" => a["name"] || a["__content__"] }
@@ -362,6 +370,32 @@ module Bolognese
362
370
  end
363
371
  end.compact.unwrap
364
372
  end
373
+
374
+ def crossref_has_translation(program_metadata)
375
+ refs = program_metadata.dig("related_item") if program_metadata.is_a?(Hash)
376
+ Array.wrap(refs).select { |a| a.dig("intra_work_relation", "relationship_type") == "hasTranslation" }.map do |c|
377
+ if c.dig("intra_work_relation", "identifier_type") == "doi"
378
+ { "relatedIdentifier" => parse_attributes(c["intra_work_relation"]).downcase,
379
+ "relationType" => "HasTranslation",
380
+ "relatedIdentifierType" => "DOI" }.compact
381
+ else
382
+ nil
383
+ end
384
+ end.compact.unwrap
385
+ end
386
+
387
+ def crossref_is_translation_of(program_metadata)
388
+ refs = program_metadata.dig("related_item") if program_metadata.is_a?(Hash)
389
+ Array.wrap(refs).select { |a| a.dig("intra_work_relation", "relationship_type") == "isTranslationOf" }.map do |c|
390
+ if c.dig("intra_work_relation", "identifier_type") == "doi"
391
+ { "relatedIdentifier" => parse_attributes(c["intra_work_relation"]).downcase,
392
+ "relationType" => "IsTranslationOf",
393
+ "relatedIdentifierType" => "DOI" }.compact
394
+ else
395
+ nil
396
+ end
397
+ end.compact.unwrap
398
+ end
365
399
  end
366
400
  end
367
401
  end
@@ -101,7 +101,7 @@ module Bolognese
101
101
  { "name" => r.strip }
102
102
  elsif r.is_a?(Hash)
103
103
  {
104
- "name" => r["__content__"].strip,
104
+ "name" => r["__content__"].present? ? r["__content__"].strip : nil,
105
105
  "publisherIdentifier" => r["publisherIdentifierScheme"] == "ROR" ? normalize_ror(r["publisherIdentifier"]) : r["publisherIdentifier"],
106
106
  "publisherIdentifierScheme" => r["publisherIdentifierScheme"],
107
107
  "schemeUri" => r["schemeURI"],
@@ -10,7 +10,9 @@ module Bolognese
10
10
  "isPartOf" => "IsPartOf",
11
11
  "hasPart" => "HasPart",
12
12
  "isPredecessor" => "IsPreviousVersionOf",
13
- "isSuccessor" => "IsNewVersionOf"
13
+ "isSuccessor" => "IsNewVersionOf",
14
+ "workTranslation" => "HasTranslation",
15
+ "translationOfWork" => "IsTranslationOf"
14
16
  }
15
17
 
16
18
  SO_TO_DC_REVERSE_RELATION_TYPES = {
@@ -74,8 +76,17 @@ module Bolognese
74
76
  creators = get_authors(from_schema_org_creators(Array.wrap(authors)))
75
77
  end
76
78
  contributors = get_authors(from_schema_org_contributors(Array.wrap(meta.fetch("editor", nil))))
77
- publisher_name = parse_attributes(meta.fetch("publisher", nil), content: "name", first: true)
78
- publisher = { "name" => publisher_name } if publisher_name.present?
79
+ translators = get_authors(from_schema_org_contributors(Array.wrap(meta.fetch("translator", nil))))
80
+ translators.map! do |translator|
81
+ translator["contributorType"] = "Translator"
82
+ translator
83
+ end
84
+ contributors += translators
85
+
86
+ publisher = {
87
+ "name" => parse_attributes(meta.fetch("publisher", nil), content: "name", first: true),
88
+ "publisherIdentifier" => parse_attributes(meta.fetch("publisher", nil), content: "@id", first: true),
89
+ }.compact if meta.fetch("publisher", nil).present?
79
90
 
80
91
  ct = (schema_org == "Dataset") ? "includedInDataCatalog" : "Periodical"
81
92
  container = if meta.fetch(ct, nil).present?
@@ -103,7 +114,9 @@ module Bolognese
103
114
  Array.wrap(schema_org_references(meta)) +
104
115
  Array.wrap(schema_org_is_referenced_by(meta)) +
105
116
  Array.wrap(schema_org_is_supplement_to(meta)) +
106
- Array.wrap(schema_org_is_supplemented_by(meta))
117
+ Array.wrap(schema_org_is_supplemented_by(meta)) +
118
+ Array.wrap(schema_org_has_translation(meta)) +
119
+ Array.wrap(schema_org_is_translation_of(meta))
107
120
 
108
121
  rights_list = Array.wrap(meta.fetch("license", nil)).compact.map do |rl|
109
122
  hsh_to_spdx("__content__" => rl["name"], "rightsURI" => rl["id"])
@@ -124,6 +137,7 @@ module Bolognese
124
137
  dates << { "date" => meta.fetch("datePublished"), "dateType" => "Issued" } if Date.edtf(meta.fetch("datePublished", nil)).present?
125
138
  dates << { "date" => meta.fetch("dateCreated"), "dateType" => "Created" } if Date.edtf(meta.fetch("dateCreated", nil)).present?
126
139
  dates << { "date" => meta.fetch("dateModified"), "dateType" => "Updated" } if Date.edtf(meta.fetch("dateModified", nil)).present?
140
+ dates << { "date" => meta.fetch("temporalCoverage"), "dateType" => "Coverage" } if Date.edtf(meta.fetch("temporalCoverage", nil)).present?
127
141
  publication_year = meta.fetch("datePublished")[0..3] if meta.fetch("datePublished", nil).present?
128
142
 
129
143
  if meta.fetch("inLanguage", nil).is_a?(String)
@@ -237,6 +251,14 @@ module Bolognese
237
251
  schema_org_related_identifier(meta, relation_type: "isBasedOn")
238
252
  end
239
253
 
254
+ def schema_org_has_translation(meta)
255
+ schema_org_related_identifier(meta, relation_type: "workTranslation", )
256
+ end
257
+
258
+ def schema_org_is_translation_of(meta)
259
+ schema_org_related_identifier(meta, relation_type: "translationOfWork")
260
+ end
261
+
240
262
  end
241
263
  end
242
264
  end
@@ -78,7 +78,9 @@ module Bolognese
78
78
  "Other" => "CreativeWork",
79
79
  # not part of DataCite schema, but used internally
80
80
  "Periodical" => "Periodical",
81
- "DataCatalog" => "DataCatalog"
81
+ "DataCatalog" => "DataCatalog",
82
+ "Award" => "Grant",
83
+ "Project" => "Project"
82
84
  }
83
85
 
84
86
  DC_TO_CP_TRANSLATIONS = {
@@ -600,12 +602,12 @@ module Bolognese
600
602
  end
601
603
 
602
604
  def validate_orcid(orcid)
603
- orcid = Array(/\A(?:(?:http|https):\/\/(?:(?:www|sandbox)?\.)?orcid\.org\/)?(\d{4}[[:space:]-]\d{4}[[:space:]-]\d{4}[[:space:]-]\d{3}[0-9X]+)\z/.match(orcid)).last
605
+ orcid = Array(/\A(?:(?:http|https):\/\/(?:(?:www|sandbox)?\.)?orcid\.org\/)?(\d{4}[[:space:]-]\d{4}[[:space:]-]\d{4}[[:space:]-]\d{3}[0-9X]+)\/{0,1}\z/.match(orcid)).last
604
606
  orcid.gsub(/[[:space:]]/, "-") if orcid.present?
605
607
  end
606
608
 
607
609
  def validate_ror(ror)
608
- Array(/^(?:(?:(?:http|https):\/\/)?ror\.org\/)?(0\w{6}\d{2})$/.match(ror)).last
610
+ Array(/^(?:(?:(?:http|https):\/\/)?ror\.org\/)?(0\w{6}\d{2})\/{0,1}$/.match(ror)).last
609
611
  end
610
612
 
611
613
  def validate_orcid_scheme(orcid_scheme)
@@ -825,7 +827,8 @@ module Bolognese
825
827
 
826
828
  def to_schema_org_contributors(element)
827
829
  element = Array.wrap(element).map do |c|
828
- c["affiliation"] = Array.wrap(c["affiliation"]).map do |a|
830
+ transformed_c = c.dup
831
+ transformed_c["affiliation"] = Array.wrap(c["affiliation"]).map do |a|
829
832
  if a.is_a?(String)
830
833
  name = a
831
834
  affiliation_identifier = nil
@@ -839,10 +842,10 @@ module Bolognese
839
842
  "@id" => affiliation_identifier,
840
843
  "name" => name }.compact
841
844
  end.unwrap
842
- c["@type"] = c["nameType"].present? ? c["nameType"][0..-3] : nil
843
- c["@id"] = Array.wrap(c["nameIdentifiers"]).first.to_h.fetch("nameIdentifier", nil)
844
- c["name"] = c["familyName"].present? ? [c["givenName"], c["familyName"]].join(" ") : c["name"]
845
- c.except("nameIdentifiers", "nameType").compact
845
+ transformed_c["@type"] = c["nameType"].present? ? c["nameType"][0..-3] : nil
846
+ transformed_c["@id"] = Array.wrap(c["nameIdentifiers"]).first.to_h.fetch("nameIdentifier", nil)
847
+ transformed_c["name"] = c["familyName"].present? ? [c["givenName"], c["familyName"]].join(" ") : c["name"]
848
+ transformed_c.except("nameIdentifiers", "nameType").compact
846
849
  end.unwrap
847
850
  end
848
851
 
@@ -1234,7 +1237,9 @@ module Bolognese
1234
1237
  "urn" => "URN",
1235
1238
  "md5" => "md5",
1236
1239
  "minid" => "minid",
1237
- "dataguid" => "dataguid"
1240
+ "dataguid" => "dataguid",
1241
+ "cstr" => "CSTR",
1242
+ "rrid" => "RRID"
1238
1243
  }
1239
1244
 
1240
1245
  identifierTypes[identifier_type.downcase] || identifier_type
@@ -1,3 +1,3 @@
1
1
  module Bolognese
2
- VERSION = "2.0.0"
2
+ VERSION = "2.3.3"
3
3
  end
@@ -4,11 +4,8 @@ module Bolognese
4
4
  module Writers
5
5
  module DataciteJsonWriter
6
6
  def datacite_json
7
- # Remove the following change for the schema 4.5 release
8
7
  if crosscite_hsh.present?
9
- datacite_json_hsh = crosscite_hsh
10
- datacite_json_hsh['publisher'] = self.publisher['name'] if self.publisher&.respond_to?(:to_hash) && self.publisher.has_key?('name') && !self.publisher['name'].blank?
11
- JSON.pretty_generate datacite_json_hsh.transform_keys! { |key| key.camelcase(uppercase_first_letter = :lower) }
8
+ JSON.pretty_generate crosscite_hsh.transform_keys! { |key| key.camelcase(uppercase_first_letter = :lower) }
12
9
  end
13
10
  end
14
11
  end
@@ -86,7 +86,10 @@ module Bolognese
86
86
  end
87
87
 
88
88
  def insert_publisher_name(xml)
89
- xml.send("publisher-name", publisher["name"])
89
+ attributes = {
90
+ "xml:lang" => publisher["lang"]
91
+ }.compact
92
+ xml.send("publisher-name", attributes, publisher["name"])
90
93
  end
91
94
 
92
95
  def insert_publication_date(xml)
@@ -13,6 +13,7 @@ module Bolognese
13
13
  "name" => parse_attributes(titles, content: "title", first: true),
14
14
  "author" => to_schema_org_creators(creators),
15
15
  "editor" => to_schema_org_contributors(contributors),
16
+ "translator" => contributors ? to_schema_org_contributors(contributors.select { |c| c["contributorType"] == "Translator" }) : nil,
16
17
  "description" => parse_attributes(abstract_description, content: "description", first: true),
17
18
  "license" => Array.wrap(rights_list).map { |l| l["rightsUri"] }.compact.unwrap,
18
19
  "version" => version_info,
@@ -23,6 +24,7 @@ module Bolognese
23
24
  "dateCreated" => get_date(dates, "Created"),
24
25
  "datePublished" => get_date(dates, "Issued") || publication_year,
25
26
  "dateModified" => get_date(dates, "Updated"),
27
+ "temporalCoverage" => get_date(dates, "Coverage"),
26
28
  "pageStart" => container.to_h["firstPage"],
27
29
  "pageEnd" => container.to_h["lastPage"],
28
30
  "spatialCoverage" => to_schema_org_spatial_coverage(geo_locations),
@@ -32,12 +34,14 @@ module Bolognese
32
34
  "predecessor_of" => to_schema_org_relation(related_identifiers: related_identifiers, relation_type: "IsPreviousVersionOf"),
33
35
  "successor_of" => to_schema_org_relation(related_identifiers: related_identifiers, relation_type: "IsNewVersionOf"),
34
36
  "citation" => to_schema_org_relation(related_identifiers: related_identifiers, relation_type: "References"),
37
+ "workTranslation" => to_schema_org_relation(related_identifiers: related_identifiers, relation_type: "HasTranslation"),
38
+ "translationOfWork" => to_schema_org_relation(related_identifiers: related_identifiers, relation_type: "IsTranslationOf"),
35
39
  "@reverse" => reverse.presence,
36
40
  "contentUrl" => Array.wrap(content_url).unwrap,
37
41
  "schemaVersion" => schema_version,
38
42
  "periodical" => types.present? ? ((types["schemaOrg"] != "Dataset") && container.present? ? to_schema_org(container) : nil) : nil,
39
43
  "includedInDataCatalog" => types.present? ? ((types["schemaOrg"] == "Dataset") && container.present? ? to_schema_org_container(container, type: "Dataset") : nil) : nil,
40
- "publisher" => publisher.present? ? { "@type" => "Organization", "name" => publisher["name"] } : nil,
44
+ "publisher" => publisher.present? ? { "@type" => "Organization", "@id" => publisher["publisherIdentifier"], "name" => publisher["name"] }.compact : nil,
41
45
  "funder" => to_schema_org_funder(funding_references),
42
46
  "provider" => agency.present? ? { "@type" => "Organization", "name" => agency } : nil
43
47
  }.compact.presence
@@ -2,7 +2,8 @@
2
2
  <!-- Version 1.0 - Created 2011-01-13 - FZ, TIB, Germany
3
3
  2013-05 v3.0: Addition of ID to simpleType element, added values "ResearchGroup" & "Other"
4
4
  2014-08-20 v3.1: Addition of value "DataCurator"
5
- 2015-05-14 v4.0 dropped value "Funder", use new "funderReference" -->
5
+ 2015-05-14 v4.0 dropped value "Funder", use new "funderReference"
6
+ 2024-12-31 v4.6: Addition of value "Translator" -->
6
7
  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://datacite.org/schema/kernel-4" targetNamespace="http://datacite.org/schema/kernel-4" elementFormDefault="qualified">
7
8
  <xs:simpleType name="contributorType" id="contributorType">
8
9
  <xs:annotation>
@@ -29,6 +30,7 @@
29
30
  <xs:enumeration value="Researcher" />
30
31
  <xs:enumeration value="Sponsor" />
31
32
  <xs:enumeration value="Supervisor" />
33
+ <xs:enumeration value="Translator" />
32
34
  <xs:enumeration value="WorkPackageLeader" />
33
35
  </xs:restriction>
34
36
  </xs:simpleType>
@@ -2,7 +2,8 @@
2
2
  <!-- Version 1.0 - Created 2011-01-13 - FZ, TIB, Germany
3
3
  2013-05 v3.0: Addition of ID to simpleType element; addition of value "Collected"; deleted "StartDate" & "EndDate"
4
4
  2017-10-23 v4.1: Addition of value "Other"
5
- 2019-02-14 v4.2: Addition of value "Withdrawn"-->
5
+ 2019-02-14 v4.2: Addition of value "Withdrawn"
6
+ 2024-12-31 v4.6: Addition of value "Coverage"-->
6
7
  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://datacite.org/schema/kernel-4" targetNamespace="http://datacite.org/schema/kernel-4" elementFormDefault="qualified">
7
8
  <xs:simpleType name="dateType" id="dateType">
8
9
  <xs:annotation>
@@ -13,6 +14,7 @@
13
14
  <xs:enumeration value="Available" />
14
15
  <xs:enumeration value="Collected" />
15
16
  <xs:enumeration value="Copyrighted" />
17
+ <xs:enumeration value="Coverage" />
16
18
  <xs:enumeration value="Created" />
17
19
  <xs:enumeration value="Issued" />
18
20
  <xs:enumeration value="Other" />
@@ -2,8 +2,9 @@
2
2
  <!-- Version 1.0 - Created 2011-01-13 - FZ, TIB, Germany
3
3
  2013-05 v3.0: Addition of ID to simpleType element; addition of value "PMID"
4
4
  2014-08-20 v3.1: Addition of values "arxiv" and "bibcode"
5
- 2015-02-12 v4.0 Addition of value "IGSN"
6
- 2019-02-14 v4.2 Addition of value "w3id" -->
5
+ 2015-02-12 v4.0: Addition of value "IGSN"
6
+ 2019-02-14 v4.2: Addition of value "w3id"
7
+ 2024-12-31 v4.5: Addition of values "CSTR", "RRID" -->
7
8
  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://datacite.org/schema/kernel-4" targetNamespace="http://datacite.org/schema/kernel-4" elementFormDefault="qualified">
8
9
  <xs:simpleType name="relatedIdentifierType" id="relatedIdentifierType">
9
10
  <xs:annotation>
@@ -13,6 +14,7 @@
13
14
  <xs:enumeration value="ARK" />
14
15
  <xs:enumeration value="arXiv" />
15
16
  <xs:enumeration value="bibcode" />
17
+ <xs:enumeration value="CSTR" />
16
18
  <xs:enumeration value="DOI" />
17
19
  <xs:enumeration value="EAN13" />
18
20
  <xs:enumeration value="EISSN" />
@@ -25,6 +27,7 @@
25
27
  <xs:enumeration value="LSID" />
26
28
  <xs:enumeration value="PMID" />
27
29
  <xs:enumeration value="PURL" />
30
+ <xs:enumeration value="RRID" />
28
31
  <xs:enumeration value="UPC" />
29
32
  <xs:enumeration value="URL" />
30
33
  <xs:enumeration value="URN" />
@@ -3,9 +3,11 @@
3
3
  2011-01-13 v1.0 - FZ, TIB, Germany
4
4
  2013-05 v3.0: Addition of ID to simpleType element, addition of values "IsIdenticalTo", "HasMetadata" & "IsMetadataFor"
5
5
  2014-08-20 v3.1: Addition of values "Reviews" & "IsReviewedBy" and "IsDerivedFrom" & "IsSourceOf"
6
- 2017-10-23 v.4.1: Addition of values "Describes", "IsDescribedBy", "HasVersion", "IsVersionOf", "Requires", "IsRequiredBy"
7
- 2019-02-14 v.4.2: Addition of values "Obsoletes", "IsObsoletedBy"
8
- 2021-03-05 v.4.4: Addition of value "IsPublishedIn" -->
6
+ 2017-10-23 v4.1: Addition of values "Describes", "IsDescribedBy", "HasVersion", "IsVersionOf", "Requires", "IsRequiredBy"
7
+ 2019-02-14 v4.2: Addition of values "Obsoletes", "IsObsoletedBy"
8
+ 2021-03-05 v4.4: Addition of value "IsPublishedIn"
9
+ 2024-01-22 v4.5: Addition of values "Collects, "IsCollectedBy"
10
+ 2024-12-31 v4.6: Addition of values "HasTranslation", "IsTranslationOf"-->
9
11
  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://datacite.org/schema/kernel-4" targetNamespace="http://datacite.org/schema/kernel-4" elementFormDefault="qualified">
10
12
  <xs:simpleType name="relationType" id="relationType">
11
13
  <xs:annotation>
@@ -48,6 +50,8 @@
48
50
  <xs:enumeration value="IsObsoletedBy" />
49
51
  <xs:enumeration value="Collects" />
50
52
  <xs:enumeration value="IsCollectedBy" />
53
+ <xs:enumeration value="HasTranslation" />
54
+ <xs:enumeration value="IsTranslationOf" />
51
55
  </xs:restriction>
52
56
  </xs:simpleType>
53
57
  </xs:schema>
@@ -3,7 +3,9 @@
3
3
  2013-05 v3.0: Addition of ID to simpleType element; added values "Audiovisual", "Workflow" & "Other"; deleted value "Film"
4
4
  2017-10-23 v4.1: Addition of value "DataPaper"
5
5
  2020-01-14 v4.4: Addition of values "Book", "Book Chapter", "ComputationalNotebook", "ConferencePaper", "ConferenceProceeding".
6
- "Dissertation", "Journal", "JournalArticle", "OutputManagementPlan", "PeerReview", "Preprint", "Report" -->
6
+ "Dissertation", "Journal", "JournalArticle", "OutputManagementPlan", "PeerReview", "Preprint", "Report"
7
+ 2024-01-22 v4.5: Addition of values "Instrument", "StudyRegistration"
8
+ 2024-12-31 v4.6: Addition of values "Award", "Project"-->
7
9
  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://datacite.org/schema/kernel-4" targetNamespace="http://datacite.org/schema/kernel-4" elementFormDefault="qualified">
8
10
  <xs:simpleType name="resourceType" id="resourceType">
9
11
  <xs:annotation>
@@ -11,6 +13,7 @@
11
13
  </xs:annotation>
12
14
  <xs:restriction base="xs:string">
13
15
  <xs:enumeration value="Audiovisual" />
16
+ <xs:enumeration value="Award" />
14
17
  <xs:enumeration value="Book" />
15
18
  <xs:enumeration value="BookChapter" />
16
19
  <xs:enumeration value="Collection" />
@@ -31,6 +34,7 @@
31
34
  <xs:enumeration value="PeerReview" />
32
35
  <xs:enumeration value="PhysicalObject" />
33
36
  <xs:enumeration value="Preprint" />
37
+ <xs:enumeration value="Project" />
34
38
  <xs:enumeration value="Report" />
35
39
  <xs:enumeration value="Service" />
36
40
  <xs:enumeration value="Software" />
@@ -1,7 +1,7 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <!-- Version 1.0 - Created 2011-01-13 - FZ, TIB, Germany
3
3
  2013-05 v3.0: Addition of ID to simpleType element
4
- 2015-02-12 v4.0 Added value "Other" -->
4
+ 2015-02-12 v4.0: Added value "Other" -->
5
5
  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://datacite.org/schema/kernel-4" targetNamespace="http://datacite.org/schema/kernel-4" elementFormDefault="qualified">
6
6
  <xs:simpleType name="titleType" id="titleType">
7
7
  <xs:restriction base="xs:string">
@@ -13,7 +13,8 @@
13
13
  2019-02-14 v4.2: Addition of dateType value "Withdrawn", relationType values "Obsoletes", "isObsoletedBy", addition of new subproperties for Rights: rightsIdentifier, rightsIdentifierScheme, schemeURI, addition of the XML language attribute to the properties Creator, Contributor and Publisher for organizational names, don't check format of DOI
14
14
  2019-07-13 v4.3: Addition of new subproperties for Affiliation: "affiliationIdentifier", "affiliationIdentifierScheme", "schemeURI", addition of new sub-property for funderIdentifier: "schemeURI", addition of new funderIdentifierScheme: "ROR", added documentation for nameIdentifier
15
15
  2021-03-08 v4.4: Addition of new property relatedItem, relationType value "isPublishedIn", subject subproperty "classificationCode", controlled list "numberType", additional 13 properties for controlled list "resourceType"
16
- 2023-??-?? v4.5: Addition of new subproperties for publisher: "publisherIdentifier", "publisherIdentifierScheme", and "schemeURI"; addition of new resourceTypeGeneral values "Instrument" and "StudyRegistration"; addition of new relationType values "Collects" and "IsCollectedBy".-->
16
+ 2024-01-22 v4.5: Addition of new subproperties for publisher: "publisherIdentifier", "publisherIdentifierScheme", and "schemeURI"; addition of new resourceTypeGeneral values "Instrument" and "StudyRegistration"; addition of new relationType values "Collects" and "IsCollectedBy".
17
+ 2024-12-31 v4.6: Addition of new resourceTypeGeneral values "Award" and "Project"; addiition of new relatedIdentifierType values "CSTR" and "RRID"; addition of new contributorType "Translator"; addition of new relationTypes "HasTranslation" and "IsTranslationOf"; addition of new dateType "Coverage".-->
17
18
  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://datacite.org/schema/kernel-4" targetNamespace="http://datacite.org/schema/kernel-4" elementFormDefault="qualified" xml:lang="EN">
18
19
  <xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="include/xml.xsd" />
19
20
  <xs:include schemaLocation="include/datacite-titleType-v4.xsd" />