iso-bib-item 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Isobib module
4
+ module IsoBibItem
5
+ # Contributor's role.
6
+ class ContributorRole
7
+ # @return [Array<IsoBibItem::FormattedString>]
8
+ attr_reader :description
9
+
10
+ # @return [ContributorRoleType]
11
+ attr_reader :type
12
+
13
+ # @param type [ContributorRoleType] allowed types "author", "editor",
14
+ # "cartographer", "publisher"
15
+ def initialize(type, description = [])
16
+ @type = type
17
+ @description = description.map { |d| FormattedString.new d }
18
+ end
19
+
20
+ def to_xml(builder)
21
+ builder.role(type: type) do
22
+ description.each do |d|
23
+ builder.description do |desc|
24
+ d.to_xml(desc)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ # Contribution info.
32
+ class ContributionInfo
33
+ # @return [Array<IsoBibItem::ContributorRole>]
34
+ attr_reader :role
35
+
36
+ # @return
37
+ # [IsoBibItem::Person, IsoBibItem::Organization,
38
+ # IsoBibItem::IsoProjectGroup]
39
+ attr_reader :entity
40
+
41
+ # @param entity [IsoBibItem::Person, IsoBibItem::Organization,
42
+ # IsoBibItem::IsoProjectGroup]
43
+ # @param role [Array<String>]
44
+ def initialize(entity:, role: ['publisher'])
45
+ @entity = entity
46
+ @role = role.map { |r| ContributorRole.new(r) }
47
+ end
48
+
49
+ def to_xml(builder)
50
+ entity.to_xml builder
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uri'
4
+
5
+ module IsoBibItem
6
+ # Contact method.
7
+ class ContactMethod
8
+ # @return [String] @todo TBD
9
+ attr_reader :contact
10
+ end
11
+
12
+ # Affilation.
13
+ class Affilation
14
+ # @return [IsoBibItem::LocalizedString]
15
+ attr_reader :name
16
+
17
+ # @return [Array<IsoBibItem::FormattedString>]
18
+ attr_reader :description
19
+
20
+ # @return [IsoBibItem::Organization]
21
+ attr_reader :organization
22
+
23
+ # @param organization [IsoBibItem::Organization]
24
+ def initialize(organization)
25
+ @organization = organization
26
+ @description = []
27
+ end
28
+ end
29
+
30
+ # Contributor.
31
+ class Contributor
32
+ # @return [URI]
33
+ attr_reader :uri
34
+
35
+ # @return [Array<IsoBibItem::ContactMethod>]
36
+ attr_reader :contacts
37
+
38
+ # @param url [String]
39
+ def initialize(url = nil)
40
+ @uri = URI url if url
41
+ @contacts = []
42
+ end
43
+
44
+ # @return [String]
45
+ # def url
46
+ # @uri.to_s
47
+ # end
48
+
49
+ def to_xml(builder)
50
+ contacts.each { |contact| contact.to_xml builder }
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IsoBibItem
4
+ # module DocumentRelationType
5
+ # PARENT = 'parent'
6
+ # CHILD = 'child'
7
+ # OBSOLETES = 'obsoletes'
8
+ # UPDATES = 'updates'
9
+ # COMPLEMENTS = 'complements'
10
+ # DERIVED_FORM = 'derivedForm'
11
+ # ADOPTED_FORM = 'adoptedForm'
12
+ # EQUIVALENT = 'equivalent'
13
+ # IDENTICAL = 'identical'
14
+ # NONEQUIVALENT = 'nonequivalent'
15
+ # end
16
+
17
+ # class SpecificLocalityType
18
+ # SECTION = 'section'
19
+ # CLAUSE = 'clause'
20
+ # PART = 'part'
21
+ # PARAGRAPH = 'paragraph'
22
+ # CHAPTER = 'chapter'
23
+ # PAGE = 'page'
24
+ # WHOLE = 'whole'
25
+ # TABLE = 'table'
26
+ # ANNEX = 'annex'
27
+ # FIGURE = 'figure'
28
+ # NOTE = 'note'
29
+ # EXAMPLE = 'example'
30
+ # # generic String is allowed
31
+ # end
32
+
33
+ # Bibliographic item locality.
34
+ class BibItemLocality
35
+ # @return [IsoBibItem::SpecificLocalityType]
36
+ attr_reader :type
37
+
38
+ # @return [IsoBibItem::LocalizedString]
39
+ attr_reader :reference_from
40
+
41
+ # @return [IsoBibItem::LocalizedString]
42
+ attr_reader :reference_to
43
+
44
+ # @param type [String]
45
+ # @param referenceFrom [IsoBibItem::LocalizedString]
46
+ # @param referenceTo [IsoBibItem::LocalizedString]
47
+ def initialize(type, reference_from, reference_to = nil)
48
+ @type = type
49
+ @reference_from = reference_from
50
+ @reference_to = reference_to
51
+ end
52
+ end
53
+
54
+ # Documett relation
55
+ class DocumentRelation
56
+ # @return [String]
57
+ attr_reader :type
58
+
59
+ # @return [String]
60
+ attr_reader :identifier, :url
61
+
62
+ # @return [IsoBibItem::BibliographicItem]
63
+ attr_reader :bibitem
64
+
65
+ # @return [Array<IsoBibItem::BibItemLocality>]
66
+ attr_reader :bib_locality
67
+
68
+ # @param type [String]
69
+ # @param identifier [String]
70
+ def initialize(type:, identifier:, url:, bib_locality: [])
71
+ @type = type
72
+ @identifier = identifier
73
+ @url = url
74
+ @bib_locality = bib_locality
75
+ end
76
+
77
+ def to_xml(builder)
78
+ builder.relation(type: type) do
79
+ builder.bibitem do
80
+ builder.formattedref identifier
81
+ builder.docidentifier identifier
82
+ end
83
+ # builder.url url
84
+ end
85
+ end
86
+ end
87
+
88
+ # Document relations collection
89
+ class DocRelationCollection < Array
90
+ # @param [Array<Hash{type=>String, identifier=>String}>]
91
+ def initialize(relations)
92
+ super relations.map { |r| DocumentRelation.new(r) }
93
+ end
94
+
95
+ # @return [Array<IsoBibItem::DocumentRelation>]
96
+ def replaces
97
+ select { |r| r.type == 'replace' }
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'iso_bib_item/localized_string'
4
+
5
+ module IsoBibItem
6
+ # Dovument status.
7
+ class DocumentStatus
8
+ # @return [IsoBibItem::LocalizedString]
9
+ attr_reader :status
10
+
11
+ # @param status [IsoBibItem::LocalizedString]
12
+ def initialize(status)
13
+ @status = status
14
+ end
15
+
16
+ def to_xml(builder)
17
+ builder.status do
18
+ # FormattedString.instance_method(:to_xml).bind(status).call builder
19
+ status.to_xml builder
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'iso_bib_item/localized_string'
4
+
5
+ module IsoBibItem
6
+ # Formatted string
7
+ class FormattedString < LocalizedString
8
+ # @return [String]
9
+ attr_reader :type
10
+
11
+ # @param content [String]
12
+ # @param language [String] language code Iso639
13
+ # @param script [String] script code Iso15924
14
+ # @param type [String] the format type, default "plain"
15
+ # available types "plain", "html", "dockbook", "tei", "asciidoc",
16
+ # "markdown", "isodoc"
17
+ def initialize(content:, language:, script:, type: 'plain')
18
+ super(content, language, script)
19
+ @type = type
20
+ end
21
+
22
+ def to_xml(builder)
23
+ builder.parent['format'] = type
24
+ super
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,207 @@
1
+ # frozen_string_literal: false
2
+
3
+ require 'nokogiri'
4
+ require 'isoics'
5
+ require 'iso_bib_item/bibliographic_item'
6
+ require 'iso_bib_item/iso_document_status'
7
+ require 'iso_bib_item/iso_localized_title'
8
+ require 'iso_bib_item/iso_project_group'
9
+ require 'iso_bib_item/document_relation_collection'
10
+
11
+ # Add filter method to Array.
12
+ # class Array
13
+ # def filter(type:)
14
+ # select { |e| e.type == type }
15
+ # end
16
+ # end
17
+
18
+ module IsoBibItem
19
+ # Iso document id.
20
+ class IsoDocumentId
21
+ # @return [Integer]
22
+ attr_reader :tc_document_number
23
+
24
+ # @return [Integer]
25
+ attr_reader :project_number
26
+
27
+ # @return [Integer]
28
+ attr_reader :part_number
29
+
30
+ # @param project_number [Integer]
31
+ # @param part_number [Integer]
32
+ def initialize(project_number:, part_number:)
33
+ @project_number = project_number
34
+ @part_number = part_number
35
+ end
36
+
37
+ def to_xml(builder)
38
+ builder.docidentifier(project_number + '-' + part_number)
39
+ end
40
+ end
41
+
42
+ # module IsoDocumentType
43
+ # INTERNATIONAL_STANDART = "internationalStandard"
44
+ # TECHNICAL_SPECIFICATION = "techinicalSpecification"
45
+ # TECHNICAL_REPORT = "technicalReport"
46
+ # PUPLICLY_AVAILABLE_SPECIFICATION = "publiclyAvailableSpecification"
47
+ # INTERNATIONAL_WORKSHOP_AGREEMENT = "internationalWorkshopAgreement"
48
+ # end
49
+
50
+ # Iso ICS classificator.
51
+ class Ics < Isoics::ICS
52
+ # @param field [Integer]
53
+ # @param group [Integer]
54
+ # @param subgroup [Integer]
55
+ def initialize(field:, group:, subgroup:)
56
+ super fieldcode: field, groupcode: group, subgroupcode: subgroup
57
+ end
58
+ end
59
+
60
+ # Bibliographic item.
61
+ class IsoBibliographicItem < BibliographicItem
62
+ # @return [IsoBibItem::IsoDocumentId]
63
+ attr_reader :docidentifier
64
+
65
+ # @return [String]
66
+ attr_reader :edition
67
+
68
+ # @!attribute [r] title
69
+ # @return [Array<IsoBibItem::IsoLocalizedTitle>]
70
+
71
+ # @return [IsoBibItem::IsoDocumentType]
72
+ attr_reader :type
73
+
74
+ # @return [IsoBibItem::IsoDocumentStatus]
75
+ attr_reader :status
76
+
77
+ # @return [IsoBibItem::IsoProjectGroup]
78
+ attr_reader :workgroup
79
+
80
+ # @return [Array<IsoBibItem::Ics>]
81
+ attr_reader :ics
82
+
83
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
84
+ # @param docid [Hash{project_number=>Integer, part_number=>Integer}]
85
+ # @param titles [Array<Hash{title_intro=>String, title_main=>String,
86
+ # title_part=>String, language=>String, script=>String}>]
87
+ # @param edition [String]
88
+ # @param language [Array<String>]
89
+ # @param script [Arrra<String>]
90
+ # @param type [String]
91
+ # @param docstatus [Hash{status=>String, stage=>String, substage=>String}]
92
+ # @param workgroup [Hash{name=>String, abbreviation=>String, url=>String,
93
+ # technical_committee=>Hash{name=>String, type=>String, number=>Integer}}]
94
+ # @param ics [Array<Hash{field=>Integer, group=>Integer,
95
+ # subgroup=>Integer}>]
96
+ # @param dates [Array<Hash{type=>String, from=>String, to=>String}>]
97
+ # @param abstract [Array<Hash{content=>String, language=>String,
98
+ # script=>String, type=>String}>]
99
+ # @param contributors [Array<Hash{entity=>Hash{name=>String, url=>String,
100
+ # abbreviation=>String}, roles=>Array<String>}>]
101
+ # @param copyright [Hash{owner=>Hash{name=>String, abbreviation=>String,
102
+ # url=>String}, form=>String, to=>String}]
103
+ # @param source [Array<Hash{type=>String, content=>String}>]
104
+ # @param relations [Array<Hash{type=>String, identifier=>String}>]
105
+ def initialize(**args)
106
+ super_args = args.select do |k|
107
+ %i[language script dates abstract contributors relations].include? k
108
+ end
109
+ super(super_args)
110
+ @docidentifier = IsoDocumentId.new args[:docid]
111
+ @edition = args[:edition]
112
+ @title = args[:titles].map { |t| IsoLocalizedTitle.new(t) }
113
+ @type = args[:type]
114
+ @status = IsoDocumentStatus.new(args[:docstatus])
115
+ @workgroup = IsoProjectGroup.new(args[:workgroup])
116
+ @ics = args[:ics].map { |i| Ics.new(i) }
117
+ if args[:copyright]
118
+ @copyright = CopyrightAssociation.new(args[:copyright])
119
+ end
120
+ @source = args[:source].map { |s| TypedUri.new(s) }
121
+ end
122
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
123
+
124
+ # @param lang [String] language code Iso639
125
+ # @return [IsoBibItem::IsoLocalizedTitle]
126
+ def title(lang: nil)
127
+ if lang
128
+ @title.find { |t| t.language == lang }
129
+ else
130
+ @title
131
+ end
132
+ end
133
+
134
+ # @todo need to add ISO/IEC/IEEE
135
+ # @return [String]
136
+ def shortref(**opts)
137
+ year = if opts[:all_parts] then ':All Parts'
138
+ elsif opts[:no_year] then ''
139
+ else ':' + @copyright.from&.year&.to_s
140
+ end
141
+
142
+ "#{id(' ')}#{year}"
143
+ end
144
+
145
+ # @param type [Symbol] type of url, can be :src/:obp/:rss
146
+ # @return [String]
147
+ def url(type = :src)
148
+ @source.find { |s| s.type == type.to_s }.content.to_s
149
+ end
150
+
151
+ # @return [String]
152
+ def to_xml(builder = nil, **opts)
153
+ if builder
154
+ render_xml builder, opts
155
+ else
156
+ Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
157
+ render_xml xml, opts
158
+ end.doc.root.to_xml
159
+ end
160
+ end
161
+
162
+ private
163
+
164
+ def publishers
165
+ @contributors.select do |c|
166
+ c.role.select { |r| r.type == 'publisher' }.any?
167
+ end
168
+ end
169
+
170
+ def id(delim = '')
171
+ contribs = publishers.map { |p| p&.entity&.abbreviation }.join '/'
172
+ idstr = "#{contribs}#{delim}#{@docidentifier.project_number}"
173
+ if @docidentifier.part_number&.size&.positive?
174
+ idstr << "-#{@docidentifier.part_number}"
175
+ end
176
+ idstr
177
+ end
178
+
179
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
180
+ def render_xml(builder, **opts)
181
+ builder.send(:bibitem, type: type, id: id) do
182
+ title.each { |t| t.to_xml builder }
183
+ source.each { |s| s.to_xml builder }
184
+ # docidentifier.to_xml builder
185
+ builder.docidentifier shortref(opts.merge(no_year: true))
186
+ dates.each { |d| d.to_xml builder, opts }
187
+ contributors.each do |c|
188
+ builder.contributor do
189
+ c.role.each { |r| r.to_xml builder }
190
+ c.to_xml builder
191
+ end
192
+ end
193
+ builder.edition edition
194
+ language.each { |l| builder.language l }
195
+ script.each { |s| builder.script s }
196
+ abstract.each { |a| builder.abstract { a.to_xml(builder) } }
197
+ status.to_xml builder
198
+ copyright.to_xml builder
199
+ relations.each { |r| r.to_xml builder }
200
+ if opts[:note]
201
+ builder.note("ISO DATE: #{opts[:note]}", format: 'text/plain')
202
+ end
203
+ end
204
+ end
205
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
206
+ end
207
+ end