relaton-bib 1.17.1 → 1.18.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a507a7fa74bc5be4e5148c8f80f91dc77a602b356187168d412beb958d30ad67
4
- data.tar.gz: 41d821df9469b709f76d98288d6ec80fa0959d3d6e7ab867f08095283ed3eaf9
3
+ metadata.gz: 197eed529f341b3a7ab7a6338c16d8710368b98c92895bdc821e26b3957d73d3
4
+ data.tar.gz: be9700cd1bbe4c537d4e2f70069ce3e53d3ebd6beaca7b2cde9a267734babf5c
5
5
  SHA512:
6
- metadata.gz: 0d1daace14ed81e05633e2340d26c1f591afcb8d5ea8b742c3cabe66e74f92def40966a20fadbd182b1b4808e6cbfa3cae9f1abb3dd40035ad2c2bc118392d85
7
- data.tar.gz: a08ae4ae1f9c3563c242d8940172cf44bd23e182237b39d91a37f572719694695bbaf9b5805bfcafb76e201eaead8506a8bd878ec8f0aed7722c7d6815e19441
6
+ metadata.gz: 0b32e72e09b9be3d0baeec2d45ef8bc8923d042c6280743edd6544204e6a67f0ad0af3aede78b48149cfcd308ef0a262978e1077a5ba02c0ca94114401c0ca5b
7
+ data.tar.gz: 8367c7d376ebbae8a555cb135bd14f0b1fc3d16bb3aa2233f39b015c81d68118701540655139c6922137487e7bd59701c44d8d9763072a21f5065b7064db2db7
@@ -10,4 +10,4 @@ on:
10
10
 
11
11
  jobs:
12
12
  rake:
13
- uses: relaton/support/.github/workflows/rake.yml@master
13
+ uses: relaton/support/.github/workflows/rake.yml@main
@@ -17,7 +17,7 @@ on:
17
17
 
18
18
  jobs:
19
19
  release:
20
- uses: relaton/support/.github/workflows/release.yml@master
20
+ uses: relaton/support/.github/workflows/release.yml@main
21
21
  with:
22
22
  next_version: ${{ github.event.inputs.next_version }}
23
23
  secrets:
@@ -95,8 +95,89 @@
95
95
  <ref name="pagebreak"/>
96
96
  <ref name="hr"/>
97
97
  <ref name="bookmark"/>
98
+ <ref name="amend"/>
98
99
  </choice>
99
100
  </define>
101
+ <define name="amend">
102
+ <element name="amend">
103
+ <ref name="AmendType"/>
104
+ </element>
105
+ </define>
106
+ <define name="AmendType">
107
+ <optional>
108
+ <attribute name="id">
109
+ <data type="ID"/>
110
+ </attribute>
111
+ </optional>
112
+ <attribute name="change">
113
+ <choice>
114
+ <value>add</value>
115
+ <value>modify</value>
116
+ <value>delete</value>
117
+ <value>replace</value>
118
+ </choice>
119
+ </attribute>
120
+ <optional>
121
+ <attribute name="path"/>
122
+ </optional>
123
+ <optional>
124
+ <attribute name="path_end"/>
125
+ </optional>
126
+ <optional>
127
+ <attribute name="title"/>
128
+ </optional>
129
+ <optional>
130
+ <element name="location">
131
+ <zeroOrMore>
132
+ <choice>
133
+ <ref name="locality"/>
134
+ <ref name="localityStack"/>
135
+ </choice>
136
+ </zeroOrMore>
137
+ </element>
138
+ </optional>
139
+ <optional>
140
+ <element name="description">
141
+ <zeroOrMore>
142
+ <ref name="BasicBlock"/>
143
+ </zeroOrMore>
144
+ </element>
145
+ </optional>
146
+ <optional>
147
+ <element name="newcontent">
148
+ <optional>
149
+ <attribute name="id">
150
+ <data type="ID"/>
151
+ </attribute>
152
+ </optional>
153
+ <zeroOrMore>
154
+ <ref name="BasicBlock"/>
155
+ </zeroOrMore>
156
+ </element>
157
+ </optional>
158
+ <zeroOrMore>
159
+ <ref name="classification"/>
160
+ </zeroOrMore>
161
+ <zeroOrMore>
162
+ <ref name="contributor"/>
163
+ </zeroOrMore>
164
+ </define>
165
+ <define name="classification">
166
+ <element name="classification">
167
+ <ref name="classification_tag"/>
168
+ <ref name="classification_value"/>
169
+ </element>
170
+ </define>
171
+ <define name="classification_tag">
172
+ <element name="tag">
173
+ <text/>
174
+ </element>
175
+ </define>
176
+ <define name="classification_value">
177
+ <element name="value">
178
+ <text/>
179
+ </element>
180
+ </define>
100
181
  <define name="paragraph">
101
182
  <element name="p">
102
183
  <ref name="ParagraphType"/>
@@ -715,27 +796,36 @@
715
796
  </define>
716
797
  <define name="ruby">
717
798
  <element name="ruby">
718
- <zeroOrMore>
719
- <choice>
720
- <ref name="PureTextElement"/>
721
- <ref name="rp"/>
722
- <ref name="rt"/>
723
- </choice>
724
- </zeroOrMore>
799
+ <choice>
800
+ <ref name="ruby_pronunciation"/>
801
+ <ref name="ruby_annotation"/>
802
+ </choice>
803
+ <choice>
804
+ <text/>
805
+ <ref name="ruby"/>
806
+ </choice>
725
807
  </element>
726
808
  </define>
727
- <define name="rp">
728
- <element name="rp">
729
- <zeroOrMore>
730
- <ref name="PureTextElement"/>
731
- </zeroOrMore>
809
+ <define name="ruby_pronunciation">
810
+ <element name="pronunciation">
811
+ <attribute name="value"/>
812
+ <optional>
813
+ <attribute name="script"/>
814
+ </optional>
815
+ <optional>
816
+ <attribute name="lang"/>
817
+ </optional>
732
818
  </element>
733
819
  </define>
734
- <define name="rt">
735
- <element name="rt">
736
- <zeroOrMore>
737
- <ref name="PureTextElement"/>
738
- </zeroOrMore>
820
+ <define name="ruby_annotation">
821
+ <element name="annotation">
822
+ <attribute name="value"/>
823
+ <optional>
824
+ <attribute name="script"/>
825
+ </optional>
826
+ <optional>
827
+ <attribute name="lang"/>
828
+ </optional>
739
829
  </element>
740
830
  </define>
741
831
  <define name="br">
@@ -930,18 +1020,12 @@
930
1020
  </optional>
931
1021
  <optional>
932
1022
  <attribute name="width">
933
- <choice>
934
- <data type="int"/>
935
- <value>auto</value>
936
- </choice>
1023
+ <ref name="ImageSize"/>
937
1024
  </attribute>
938
1025
  </optional>
939
1026
  <optional>
940
1027
  <attribute name="height">
941
- <choice>
942
- <data type="int"/>
943
- <value>auto</value>
944
- </choice>
1028
+ <ref name="ImageSize"/>
945
1029
  </attribute>
946
1030
  </optional>
947
1031
  <optional>
@@ -956,6 +1040,14 @@
956
1040
  </attribute>
957
1041
  </optional>
958
1042
  </define>
1043
+ <define name="ImageSize">
1044
+ <choice>
1045
+ <data type="string">
1046
+ <param name="pattern">\d+([.]\d+)?(%?)</param>
1047
+ </data>
1048
+ <value>auto</value>
1049
+ </choice>
1050
+ </define>
959
1051
  <define name="video">
960
1052
  <element name="video">
961
1053
  <attribute name="id">
@@ -9,11 +9,42 @@
9
9
  -->
10
10
  <include href="biblio.rng">
11
11
  <define name="BibData">
12
- <ref name="BibliographicItem"/>
12
+ <ref name="StandardBibliographicItem"/>
13
13
  <optional>
14
14
  <ref name="ext"/>
15
15
  </optional>
16
16
  </define>
17
+ <define name="docrelation">
18
+ <element name="relation">
19
+ <attribute name="type">
20
+ <ref name="DocRelationType"/>
21
+ </attribute>
22
+ <optional>
23
+ <element name="description">
24
+ <ref name="FormattedString"/>
25
+ </element>
26
+ </optional>
27
+ <element name="bibitem">
28
+ <ref name="StandardReducedBibliographicItem"/>
29
+ </element>
30
+ <choice>
31
+ <zeroOrMore>
32
+ <ref name="locality"/>
33
+ </zeroOrMore>
34
+ <zeroOrMore>
35
+ <ref name="localityStack"/>
36
+ </zeroOrMore>
37
+ </choice>
38
+ <choice>
39
+ <zeroOrMore>
40
+ <ref name="sourceLocality"/>
41
+ </zeroOrMore>
42
+ <zeroOrMore>
43
+ <ref name="sourceLocalityStack"/>
44
+ </zeroOrMore>
45
+ </choice>
46
+ </element>
47
+ </define>
17
48
  </include>
18
49
  <define name="ext">
19
50
  <element name="ext">
@@ -161,4 +192,16 @@
161
192
  </optional>
162
193
  </element>
163
194
  </define>
195
+ <define name="StandardBibliographicItem">
196
+ <ref name="BibliographicItem"/>
197
+ <zeroOrMore>
198
+ <ref name="amend"/>
199
+ </zeroOrMore>
200
+ </define>
201
+ <define name="StandardReducedBibliographicItem">
202
+ <ref name="ReducedBibliographicItem"/>
203
+ <zeroOrMore>
204
+ <ref name="amend"/>
205
+ </zeroOrMore>
206
+ </define>
164
207
  </grammar>
data/grammars/biblio.rng CHANGED
@@ -241,6 +241,9 @@
241
241
  </element>
242
242
  </define>
243
243
  <define name="FullNameType">
244
+ <optional>
245
+ <ref name="name_abbreviation"/>
246
+ </optional>
244
247
  <choice>
245
248
  <group>
246
249
  <zeroOrMore>
@@ -266,6 +269,11 @@
266
269
  <ref name="variantname"/>
267
270
  </zeroOrMore>
268
271
  </define>
272
+ <define name="name_abbreviation">
273
+ <element name="abbreviation">
274
+ <ref name="LocalizedString"/>
275
+ </element>
276
+ </define>
269
277
  <define name="prefix">
270
278
  <element name="prefix">
271
279
  <ref name="LocalizedString"/>
@@ -870,6 +878,9 @@
870
878
  <optional>
871
879
  <ref name="validity"/>
872
880
  </optional>
881
+ <optional>
882
+ <ref name="depiction"/>
883
+ </optional>
873
884
  </define>
874
885
  <define name="btitle">
875
886
  <element name="title">
@@ -1,7 +1,7 @@
1
1
  {
2
- "relaton-models": "v1.2.7",
3
- "basicdoc-models": "v1.0.3",
4
- "metanorma-requirements-models": "v1.0.0",
2
+ "relaton-models": "v1.2.8",
3
+ "basicdoc-models": "v1.1.2",
4
+ "metanorma-requirements-models": "v1.0.1",
5
5
  "relaton-model-ieee": "v1.0.1",
6
6
  "relaton-model-iso": "v1.0.0",
7
7
  "relaton-model-iec": "v1.0.0",
@@ -29,6 +29,6 @@
29
29
  "relaton-model-oasis": "v1.0.1",
30
30
  "relaton-model-jis": "v0.0.1",
31
31
  "relaton-model-etsi": "v0.0.3",
32
- "metanorma-model": "v1.2.9",
33
- "date": "2023-12-02T16:19:25Z"
32
+ "metanorma-model": "v1.2.11",
33
+ "date": "2024-01-04T03:55:06Z"
34
34
  }
@@ -78,54 +78,50 @@ module RelatonBib
78
78
 
79
79
  # @param bibtex [BibTeX::Entry]
80
80
  # @return [Array<Hash>]
81
- def fetch_contributor(bibtex) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength
82
- contributor = []
83
- fetch_person(bibtex["author"]).each do |entity|
84
- contributor << { entity: entity, role: [{ type: "author" }] }
85
- end
81
+ def fetch_contributor(bibtex) # rubocop:disable Metrics/AbcSize
82
+ contribs = []
83
+ fetch_person(bibtex, "author") { |author| contribs << author }
84
+ fetch_person(bibtex, "editor") { |editor| contribs << editor }
86
85
 
87
- fetch_person(bibtex["editor"]).each do |entity|
88
- contributor << { entity: entity, role: [{ type: "editor" }] }
89
- end
86
+ fetch_org(bibtex["publisher"], "publisher") { |pub| contribs << pub }
87
+ fetch_org(bibtex["institution"], "distributor", "sponsor") { |distr| contribs << distr }
88
+ fetch_org(bibtex["organization"], "distributor", "sponsor") { |org| contribs << org }
89
+ fetch_org(bibtex["school"], "distributor", "sponsor") { |school| contribs << school }
90
90
 
91
- if bibtex["publisher"]
92
- contributor << { entity: { name: bibtex.publisher.to_s }, role: [{ type: "publisher" }] }
93
- end
91
+ fetch_howpublished(bibtex) { |pub| contribs << pub }
94
92
 
95
- if bibtex["institution"]
96
- contributor << {
97
- entity: { name: bibtex.institution.to_s },
98
- role: [{ type: "distributor", description: ["sponsor"] }],
99
- }
100
- end
93
+ contribs
94
+ end
101
95
 
102
- if bibtex["organization"]
103
- contributor << {
104
- entity: { name: bibtex.organization.to_s },
105
- role: [{ type: "distributor", description: ["sponsor"] }],
106
- }
107
- end
96
+ def fetch_howpublished(bibtex, &_)
97
+ return unless bibtex["howpublished"]
108
98
 
109
- if bibtex["school"]
110
- contributor << {
111
- entity: { name: bibtex.school.to_s },
112
- role: [{ type: "distributor", description: ["sponsor"] }],
113
- }
114
- end
115
- contributor
99
+ /\\publisher\{(?<name>.+)\},\\url\{(?<url>.+)\}/ =~ bibtex.howpublished.to_s
100
+ return unless name && url
101
+
102
+ name.gsub!(/\{\\?([^\\]+)\}/, '\1')
103
+ org = Organization.new(name: name, url: url)
104
+ yield entity: org, role: [{ type: "publisher" }]
105
+ end
106
+
107
+ def fetch_org(org, type, desc = nil, &_)
108
+ return unless org
109
+
110
+ role = { type: type }
111
+ role[:description] = [desc] if desc
112
+ yield entity: Organization.new(name: org.to_s), role: [role]
116
113
  end
117
114
 
118
115
  # @param bibtex [BibTeX::Entry]
119
116
  # @return [Array<RelatonBib::Person>]
120
- def fetch_person(person)
121
- return [] unless person
122
-
123
- person.map do |name|
117
+ def fetch_person(bibtex, role, &_) # rubocop:disable Metrics/AbcSize
118
+ bibtex[role]&.each do |name|
124
119
  parts = name.split ", "
125
120
  surname = LocalizedString.new parts.first
126
121
  fname = parts.size > 1 ? parts[1].split : []
127
122
  forename = fname.map { |fn| Forename.new content: fn }
128
- Person.new name: FullName.new(surname: surname, forename: forename)
123
+ name = FullName.new(surname: surname, forename: forename)
124
+ yield entity: Person.new(name: name), role: [{ type: role }]
129
125
  end
130
126
  end
131
127
 
@@ -147,7 +143,7 @@ module RelatonBib
147
143
 
148
144
  # @param bibtex [BibTeX::Entry]
149
145
  # @return [RelatonBib::BiblioNoteCollection]
150
- def fetch_note(bibtex)
146
+ def fetch_note(bibtex) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength
151
147
  bibtex.select do |k, _v|
152
148
  %i[annote howpublished comment note content].include? k
153
149
  end.reduce(BiblioNoteCollection.new([])) do |mem, note|
@@ -156,6 +152,8 @@ module RelatonBib
156
152
  when :content then "tableOfContents"
157
153
  else note[0].to_s
158
154
  end
155
+ next mem if type == "howpublished" && note[1].to_s.match?(/^\\publisher\{.+\},\\url\{.+\}$/)
156
+
159
157
  mem << BiblioNote.new(type: type, content: note[1].to_s)
160
158
  end
161
159
  end
@@ -84,24 +84,33 @@ module RelatonBib
84
84
  # @return [String] allowed "phone", "email" or "uri"
85
85
  attr_reader :type
86
86
 
87
+ # @return [String, nil]
88
+ attr_reader :subtype
89
+
87
90
  # @return [String]
88
91
  attr_reader :value
89
92
 
90
93
  # @param type [String] allowed "phone", "email" or "uri"
94
+ # @param subtype [String, nil] i.e. "fax", "mobile", "landline" for "phone"
95
+ # or "work", "personal" for "uri" type
91
96
  # @param value [String]
92
- def initialize(type:, value:)
93
- @type = type
94
- @value = value
97
+ def initialize(type:, value:, subtype: nil)
98
+ @type = type
99
+ @subtype = subtype
100
+ @value = value
95
101
  end
96
102
 
97
103
  # @param builder [Nokogiri::XML::Document]
98
- def to_xml(doc)
99
- doc.send type, value
104
+ def to_xml(builder)
105
+ node = builder.send type, value
106
+ node["type"] = subtype if subtype
100
107
  end
101
108
 
102
109
  # @return [Hash]
103
110
  def to_hash
104
- { type => value }
111
+ hash = { type => value }
112
+ hash["type"] = subtype if subtype
113
+ hash
105
114
  end
106
115
 
107
116
  # @param prefix [String]
@@ -110,8 +119,8 @@ module RelatonBib
110
119
  def to_asciibib(prefix = "", count = 1)
111
120
  pref = prefix.empty? ? prefix : "#{prefix}."
112
121
  out = count > 1 ? "#{pref}contact::\n" : ""
113
- # out += "#{pref}contact.type:: #{type}\n"
114
122
  out += "#{pref}contact.#{type}:: #{value}\n"
123
+ out += "#{pref}contact.type:: #{subtype}\n" if subtype
115
124
  out
116
125
  end
117
126
  end
@@ -42,7 +42,7 @@ module RelatonBib
42
42
  # @return [String] AsciiBib representation
43
43
  #
44
44
  def to_asciibib(prefix = "")
45
- pref = prefix.empty? ? prefix : prefix + "."
45
+ pref = prefix.empty? ? prefix : "#{prefix}."
46
46
  pref += "doctype."
47
47
  out = "#{pref}type:: #{@type}\n"
48
48
  out += "#{pref}abbreviation:: #{@abbreviation}\n" if @abbreviation
@@ -7,35 +7,29 @@ module RelatonBib
7
7
  attr_accessor :forename
8
8
 
9
9
  # @return [Array<RelatonBib::LocalizedString>]
10
- attr_accessor :initials
10
+ attr_accessor :initials, :addition, :prefix
11
11
 
12
12
  # @return [RelatonBib::LocalizedString, nil]
13
- attr_accessor :surname, :completename
14
-
15
- # @return [Array<RelatonBib::LocalizedString>]
16
- attr_accessor :addition
17
-
18
- # @return [Array<RelatonBib::LocalizedString>]
19
- attr_accessor :prefix
13
+ attr_accessor :surname, :abbreviation, :completename
20
14
 
21
15
  #
22
16
  # Initialize FullName instance
23
17
  #
24
- # @param surname [RelatonBib::LocalizedString, nil] surname or completename
25
- # should be present
18
+ # @param surname [RelatonBib::LocalizedString, nil] surname or completename should be present
19
+ # @param abbreviation [RelatonBib::LocalizedString, nil] abbreviation
26
20
  # @param forename [Array<RelatonBib::Forename>] forename
27
21
  # @param initials [RelatonBib::LocalizedString, String, nil] string of initials
28
22
  # @param addition [Array<RelatonBib::LocalizedString>] array of additions
29
23
  # @param prefix [Array<RelatonBib::LocalizedString>] array of prefixes
30
- # @param completename [RelatonBib::LocalizedString, nil] completename or
31
- # surname should be present
24
+ # @param completename [RelatonBib::LocalizedString, nil] completename or surname should be present
32
25
  #
33
- def initialize(**args)
26
+ def initialize(**args) # rubocop:disable Metrics/AbcSize
34
27
  unless args[:surname] || args[:completename]
35
28
  raise ArgumentError, "Should be given :surname or :completename"
36
29
  end
37
30
 
38
31
  @surname = args[:surname]
32
+ @abbreviation = args[:abbreviation]
39
33
  @forename = args.fetch :forename, []
40
34
  @initials = args[:initials].is_a?(String) ? LocalizedString.new(args[:initials]) : args[:initials]
41
35
  @addition = args.fetch :addition, []
@@ -48,6 +42,7 @@ module RelatonBib
48
42
  # @option opts [String] :lang language
49
43
  def to_xml(**opts) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
50
44
  opts[:builder].name do |builder|
45
+ builder.abbreviation { abbreviation.to_xml builder } if abbreviation
51
46
  if completename
52
47
  builder.completename { completename.to_xml builder }
53
48
  else
@@ -69,6 +64,7 @@ module RelatonBib
69
64
  # @return [Hash]
70
65
  def to_hash # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity,Metrics/MethodLength
71
66
  hash = {}
67
+ hash["abbreviation"] = abbreviation.to_hash if abbreviation
72
68
  if forename.any? || initials
73
69
  hash["given"] = {}
74
70
  hash["given"]["forename"] = single_element_array(forename) if forename&.any?
@@ -86,8 +82,10 @@ module RelatonBib
86
82
  def to_asciibib(pref) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
87
83
  prf = pref.empty? ? pref : "#{pref}."
88
84
  prf += "name"
85
+ out = ""
86
+ out += abbreviation.to_asciibib "#{prf}.abbreviation" if abbreviation
89
87
  given = "#{pref}.given"
90
- out = forename.map do |fn|
88
+ out += forename.map do |fn|
91
89
  fn.to_asciibib given, forename.size
92
90
  end.join
93
91
  out += initials.to_asciibib "#{given}.formatted-initials" if initials
@@ -232,12 +232,14 @@ module RelatonBib
232
232
  LocalizedString.new sd
233
233
  end
234
234
  org[:contact] = contacts_hash_to_bib(org)
235
+ org[:logo] = Image.new(**org[:logo][:image]) if org[:logo]
235
236
  org
236
237
  end
237
238
 
238
239
  def person_hash_to_bib(person)
239
240
  Person.new(
240
241
  name: fullname_hash_to_bib(person),
242
+ credential: RelatonBib.array(person[:credential]),
241
243
  affiliation: affiliation_hash_to_bib(person),
242
244
  contact: contacts_hash_to_bib(person),
243
245
  identifier: person_identifiers_hash_to_bib(person),
@@ -248,6 +250,7 @@ module RelatonBib
248
250
  n = person[:name]
249
251
  fname, inits = given_hash_to_bib n[:given] || n # `n` is for backward compatibility
250
252
  FullName.new(
253
+ abbreviation: localizedstring(n[:abbreviation]),
251
254
  forename: fname, initials: inits,
252
255
  addition: RelatonBib.array(n[:addition])&.map { |f| localizedstring(f) },
253
256
  prefix: RelatonBib.array(n[:prefix])&.map { |f| localizedstring(f) },
@@ -289,31 +292,29 @@ module RelatonBib
289
292
  end
290
293
  FormattedString.new(**cnt)
291
294
  end
292
- name = LocalizedString.new(a[:name][:content], a[:name][:language], a[:name][:script]) if a[:name]
293
295
  Affiliation.new(
294
296
  organization: Organization.new(**org_hash_to_bib(a[:organization])),
295
- description: a[:description], name: name
297
+ description: a[:description], name: localizedstring(a[:name])
296
298
  )
297
299
  end
298
300
  end
299
301
 
300
- def contacts_hash_to_bib(entity) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength,Metrics/PerceivedComplexity,Metrics/CyclomaticComplexity
302
+ def contacts_hash_to_bib(entity) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/CyclomaticComplexity
301
303
  return [] unless entity[:contact]
302
304
 
303
305
  RelatonBib.array(entity[:contact]).map do |a|
304
- if a[:city] || a[:country] # it's for old version compatibility, should be removed in the future
305
- RelatonBib::Address.new(
306
- street: Array(a[:street]), city: a[:city], postcode: a[:postcode],
307
- country: a[:country], state: a[:state]
308
- )
309
- elsif a[:address]
306
+ type, value = a.reject { |k, _| k == :type }.flatten
307
+ case type
308
+ when :street, :city, :state, :country, :postcode # it's for old version compatibility, should be removed in the future
309
+ a[:street] = RelatonBib.array(a[:street])
310
+ Address.new(**a)
311
+ when :address
310
312
  a[:address][:street] = RelatonBib.array(a[:address][:street])
311
- RelatonBib::Address.new(**a[:address])
312
- elsif a[:type] # it's for old version compatibility, should be removed in the future
313
- RelatonBib::Contact.new(type: a[:type], value: a[:value])
314
- else
315
- type, value = a.flatten
316
- RelatonBib::Contact.new(type: type.to_s, value: value)
313
+ Address.new(**a[:address])
314
+ when :phone, :email, :uri
315
+ Contact.new(type: type.to_s, value: value, subtype: a[:type])
316
+ else # it's for old version compatibility, should be removed in the future
317
+ Contact.new(**a)
317
318
  end
318
319
  end
319
320
  end
@@ -0,0 +1,90 @@
1
+ module RelatonBib
2
+ class Image
3
+ # @return [String]
4
+ attr_reader :id, :src, :mimetype, :filename, :width, :height, :alt, :title, :longdesc
5
+
6
+ #
7
+ # Initializes a new Image object.
8
+ #
9
+ # @param id [String] the ID of the image
10
+ # @param src [String] the source URL of the image
11
+ # @param mimetype [String] the MIME type of the image
12
+ # @param args [Hash] additional arguments
13
+ # @option args [String] :filename the filename of the image
14
+ # @option args [String] :width the width of the image
15
+ # @option args [String] :height the height of the image
16
+ # @option args [String] :alt the alternative text for the image
17
+ # @option args [String] :title the title of the image
18
+ # @option args [String] :longdesc the long description of the image
19
+ #
20
+ def initialize(id:, src:, mimetype:, **args)
21
+ @id = id
22
+ @src = src
23
+ @mimetype = mimetype
24
+ @filename = args[:filename]
25
+ @width = args[:width]
26
+ @height = args[:height]
27
+ @alt = args[:alt]
28
+ @title = args[:title]
29
+ @longdesc = args[:longdesc]
30
+ end
31
+
32
+ #
33
+ # Converts the image object to XML format.
34
+ #
35
+ # @param [Nokogiri::XML::Builder] builder The XML builder object.
36
+ #
37
+ # @return [void]
38
+ #
39
+ def to_xml(builder) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength
40
+ builder.image do
41
+ builder.parent[:id] = id
42
+ builder.parent[:src] = src
43
+ builder.parent[:mimetype] = mimetype
44
+ builder.parent[:filename] = filename if filename
45
+ builder.parent[:width] = width if width
46
+ builder.parent[:height] = height if height
47
+ builder.parent[:alt] = alt if alt
48
+ builder.parent[:title] = title if title
49
+ builder.parent[:longdesc] = longdesc if longdesc
50
+ end
51
+ end
52
+
53
+ #
54
+ # Converts the Image object to a hash representation.
55
+ #
56
+ # @return [Hash] The hash representation of the Image object.
57
+ #
58
+ def to_hash # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity
59
+ hash = { "image" => { "id" => id, "src" => src, "mimetype" => mimetype } }
60
+ hash["image"]["filename"] = filename if filename
61
+ hash["image"]["width"] = width if width
62
+ hash["image"]["height"] = height if height
63
+ hash["image"]["alt"] = alt if alt
64
+ hash["image"]["title"] = title if title
65
+ hash["image"]["longdesc"] = longdesc if longdesc
66
+ hash
67
+ end
68
+
69
+ #
70
+ # Converts the image object to AsciiBib format.
71
+ #
72
+ # @param prefix [String] The prefix to be added to the AsciiBib output.
73
+ #
74
+ # @return [String] The image object converted to AsciiBib format.
75
+ #
76
+ def to_asciibib(prefix = "") # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity,Metrics/MethodLength
77
+ pref = prefix.empty? ? "image." : "#{prefix}.image."
78
+ out = "#{pref}id:: #{id}\n"
79
+ out += "#{pref}src:: #{src}\n"
80
+ out += "#{pref}mimetype:: #{mimetype}\n"
81
+ out += "#{pref}filename:: #{filename}\n" if filename
82
+ out += "#{pref}width:: #{width}\n" if width
83
+ out += "#{pref}height:: #{height}\n" if height
84
+ out += "#{pref}alt:: #{alt}\n" if alt
85
+ out += "#{pref}title:: #{title}\n" if title
86
+ out += "#{pref}longdesc:: #{longdesc}\n" if longdesc
87
+ out
88
+ end
89
+ end
90
+ end
@@ -61,12 +61,16 @@ module RelatonBib
61
61
  # @return [Array<RelatonBib::OrgIdentifier>]
62
62
  attr_reader :identifier
63
63
 
64
+ # @return [RelatonBib::Image, nil]
65
+ attr_reader :logo
66
+
64
67
  # @param name [String, Hash, Array<String, Hash>]
65
68
  # @param abbreviation [RelatoBib::LocalizedString, String]
66
69
  # @param subdivision [Array<RelatoBib::LocalizedString>]
67
70
  # @param url [String]
68
71
  # @param identifier [Array<RelatonBib::OrgIdentifier>]
69
72
  # @param contact [Array<RelatonBib::Address, RelatonBib::Contact>]
73
+ # @param logo [RelatonBib::Image, nil]
70
74
  def initialize(**args) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
71
75
  raise ArgumentError, "missing keyword: name" unless args[:name]
72
76
 
@@ -83,6 +87,7 @@ module RelatonBib
83
87
  localized_string sd
84
88
  end
85
89
  @identifier = args.fetch(:identifier, [])
90
+ @logo = args[:logo]
86
91
  end
87
92
 
88
93
  # @param opts [Hash]
@@ -100,24 +105,26 @@ module RelatonBib
100
105
  builder.uri url if uri
101
106
  identifier.each { |identifier| identifier.to_xml builder }
102
107
  super builder
108
+ builder.logo { |b| logo.to_xml b } if logo
103
109
  end
104
110
  end
105
111
 
106
112
  # @return [Hash]
107
- def to_hash # rubocop:disable Metrics/AbcSize
113
+ def to_hash # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity
108
114
  hash = { "name" => single_element_array(name) }
109
115
  hash["abbreviation"] = abbreviation.to_hash if abbreviation
110
116
  hash["identifier"] = single_element_array(identifier) if identifier&.any?
111
117
  if subdivision&.any?
112
118
  hash["subdivision"] = single_element_array(subdivision)
113
119
  end
120
+ hash["logo"] = logo.to_hash if logo
114
121
  { "organization" => hash.merge(super) }
115
122
  end
116
123
 
117
124
  # @param prefix [String]
118
125
  # @param count [Integer]
119
126
  # @return [String]
120
- def to_asciibib(prefix = "", count = 1) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength
127
+ def to_asciibib(prefix = "", count = 1) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
121
128
  pref = prefix.sub(/\*$/, "organization")
122
129
  out = count > 1 ? "#{pref}::\n" : ""
123
130
  name.each { |n| out += n.to_asciibib "#{pref}.name", name.size }
@@ -128,6 +135,7 @@ module RelatonBib
128
135
  end
129
136
  identifier.each { |n| out += n.to_asciibib pref, identifier.size }
130
137
  out += super pref
138
+ out += logo.to_asciibib "#{pref}.logo" if logo
131
139
  out
132
140
  end
133
141
 
@@ -66,6 +66,9 @@ module RelatonBib
66
66
  # @return [RelatonBib::FullName]
67
67
  attr_accessor :name
68
68
 
69
+ # @return [Array<String>]
70
+ attr_reader :credential
71
+
69
72
  # @return [Array<RelatonBib::Affiliation>]
70
73
  attr_accessor :affiliation
71
74
 
@@ -73,24 +76,27 @@ module RelatonBib
73
76
  attr_accessor :identifier
74
77
 
75
78
  # @param name [RelatonBib::FullName]
79
+ # @param credential [Array<String>]
76
80
  # @param affiliation [Array<RelatonBib::Affiliation>]
77
81
  # @param contact [Array<RelatonBib::Address, RelatonBib::Contact>]
78
82
  # @param identifier [Array<RelatonBib::PersonIdentifier>]
79
83
  # @param url [String, nil]
80
- def initialize(name:, affiliation: [], contact: [], identifier: [],
81
- url: nil)
82
- super(contact: contact, url: url)
84
+ def initialize(name:, **args)
85
+ contact = args[:contact] || []
86
+ super(contact: contact, url: args[:url])
83
87
  @name = name
84
- @affiliation = affiliation
85
- @identifier = identifier
88
+ @credential = args[:credential] || []
89
+ @affiliation = args[:affiliation] || []
90
+ @identifier = args[:identifier] || []
86
91
  end
87
92
 
88
93
  # @param opts [Hash]
89
94
  # @option opts [Nokogiri::XML::Builder] :builder XML builder
90
95
  # @option opts [String, Symbol] :lang language
91
- def to_xml(**opts)
96
+ def to_xml(**opts) # rubocop:disable Metrics/AbcSize
92
97
  opts[:builder].person do |builder|
93
98
  name.to_xml(**opts)
99
+ credential.each { |c| builder.credential c }
94
100
  affiliation.each { |a| a.to_xml(**opts) }
95
101
  identifier.each { |id| id.to_xml builder }
96
102
  contact.each { |contact| contact.to_xml builder }
@@ -98,12 +104,11 @@ module RelatonBib
98
104
  end
99
105
 
100
106
  # @return [Hash]
101
- def to_hash
107
+ def to_hash # rubocop:disable Metrics/AbcSize
102
108
  hash = { "name" => name.to_hash }
103
- if affiliation&.any?
104
- hash["affiliation"] = single_element_array(affiliation)
105
- end
106
- hash["identifier"] = single_element_array(identifier) if identifier&.any?
109
+ hash["credential"] = credential if credential.any?
110
+ hash["affiliation"] = affiliation.map &:to_hash if affiliation.any?
111
+ hash["identifier"] = identifier.map &:to_hash if identifier.any?
107
112
  { "person" => hash.merge(super) }
108
113
  end
109
114
 
@@ -114,6 +119,7 @@ module RelatonBib
114
119
  pref = prefix.sub(/\*$/, "person")
115
120
  out = count > 1 ? "#{pref}::\n" : ""
116
121
  out += name.to_asciibib pref
122
+ credential.each { |c| out += "#{pref}.credential:: #{c}\n" }
117
123
  affiliation.each { |af| out += af.to_asciibib pref, affiliation.size }
118
124
  identifier.each { |id| out += id.to_asciibib pref, identifier.size }
119
125
  out += super pref
@@ -1,3 +1,3 @@
1
1
  module RelatonBib
2
- VERSION = "1.17.1".freeze
2
+ VERSION = "1.18.0".freeze
3
3
  end
@@ -379,13 +379,20 @@ module RelatonBib
379
379
  end
380
380
  subdiv = org.xpath("subdivision").map &:text
381
381
  contact = parse_contact org
382
+ logo = fetch_image org.at("./logo/image")
382
383
  Organization.new(
383
384
  name: names, abbreviation: org.at("abbreviation")&.text,
384
385
  subdivision: subdiv, # url: org.at("uri")&.text,
385
- identifier: identifier, contact: contact
386
+ identifier: identifier, contact: contact, logo: logo
386
387
  )
387
388
  end
388
389
 
390
+ def fetch_image(elm)
391
+ return unless elm
392
+
393
+ Image.new(**elm.to_h.transform_keys(&:to_sym))
394
+ end
395
+
389
396
  #
390
397
  # Parse person from XML
391
398
  #
@@ -403,25 +410,27 @@ module RelatonBib
403
410
  PersonIdentifier.new pi[:type], pi.text
404
411
  end
405
412
 
406
- cname = localized_string person.at("./name/completename")
407
- sname = localized_string person.at("./name/surname")
408
-
409
- name = FullName.new(
410
- completename: cname, surname: sname,
411
- initials: parse_initials(person),
412
- forename: parse_forename(person),
413
- addition: name_part(person, "addition"),
414
- prefix: name_part(person, "prefix")
415
- )
416
-
417
413
  Person.new(
418
- name: name,
414
+ name: full_name(person.at("./name")),
415
+ credential: person.xpath("./credential").map(&:text),
419
416
  affiliation: affiliations,
420
417
  contact: contact,
421
418
  identifier: identifier,
422
419
  )
423
420
  end
424
421
 
422
+ def full_name(name)
423
+ cname = localized_string name.at("./completename")
424
+ sname = localized_string name.at("./surname")
425
+ abbreviation = localized_string name.at("./abbreviation")
426
+
427
+ FullName.new(
428
+ completename: cname, surname: sname, abbreviation: abbreviation,
429
+ initials: parse_initials(name), forename: parse_forename(name),
430
+ addition: name_part(name, "addition"), prefix: name_part(name, "prefix")
431
+ )
432
+ end
433
+
425
434
  def fetch_affiliation(elm)
426
435
  org = get_org elm.at("./organization")
427
436
  desc = elm.xpath("./description").map do |e|
@@ -447,7 +456,7 @@ module RelatonBib
447
456
  #
448
457
  def parse_contact(contrib)
449
458
  contrib.xpath("./address|./phone|./email|./uri").map do |c|
450
- parse_address(c) || Contact.new(type: c.name, value: c.text)
459
+ parse_address(c) || Contact.new(type: c.name, value: c.text, subtype: c[:type])
451
460
  end
452
461
  end
453
462
 
@@ -474,23 +483,23 @@ module RelatonBib
474
483
  #
475
484
  # Parse initials
476
485
  #
477
- # @param [Nokogiri::XML::Element] person person element
486
+ # @param [Nokogiri::XML::Element] name person name element
478
487
  #
479
488
  # @return [RelatonBib::LocalizedString, nil] initials
480
489
  #
481
- def parse_initials(person)
482
- localized_string person.at("./name/formatted-initials")
490
+ def parse_initials(name)
491
+ localized_string name.at("./formatted-initials")
483
492
  end
484
493
 
485
494
  #
486
495
  # Parse forename
487
496
  #
488
- # @param [Nokogiri::XML::Element] person person element
497
+ # @param [Nokogiri::XML::Element] name person name element
489
498
  #
490
499
  # @return [Array<RelatonBib::Forename>] forenames
491
500
  #
492
- def parse_forename(person)
493
- person.xpath("./name/forename").map do |np|
501
+ def parse_forename(name)
502
+ name.xpath("./forename").map do |np|
494
503
  args = np.attributes.each_with_object({}) { |(k, v), h| h[k.to_sym] = v.to_s }
495
504
  args[:content] = np.text
496
505
  Forename.new(**args)
@@ -500,13 +509,13 @@ module RelatonBib
500
509
  #
501
510
  # Parse name part
502
511
  #
503
- # @param [Nokogiri::XML::Element] person person element
512
+ # @param [Nokogiri::XML::Element] name person name element
504
513
  # @param [String] part name part
505
514
  #
506
515
  # @return [Array<RelatonBib::LocalizedString>] name parts
507
516
  #
508
- def name_part(person, part)
509
- person.xpath("./name/#{part}").map { |np| localized_string np }
517
+ def name_part(name, part)
518
+ name.xpath("./#{part}").map { |np| localized_string np }
510
519
  end
511
520
 
512
521
  # @param item [Nokogiri::XML::Element]
data/lib/relaton_bib.rb CHANGED
@@ -10,6 +10,7 @@ require "relaton_bib/forename"
10
10
  require "relaton_bib/full_name"
11
11
  require "relaton_bib/contributor"
12
12
  require "relaton_bib/document_type"
13
+ require "relaton_bib/image"
13
14
  require "relaton_bib/bibliographic_item"
14
15
  require "relaton_bib/hit_collection"
15
16
  require "relaton_bib/hit"
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.17.1
4
+ version: 1.18.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-12-03 00:00:00.000000000 Z
11
+ date: 2024-01-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -138,6 +138,7 @@ files:
138
138
  - lib/relaton_bib/hit.rb
139
139
  - lib/relaton_bib/hit_collection.rb
140
140
  - lib/relaton_bib/ics.rb
141
+ - lib/relaton_bib/image.rb
141
142
  - lib/relaton_bib/localized_string.rb
142
143
  - lib/relaton_bib/medium.rb
143
144
  - lib/relaton_bib/organization.rb