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,41 @@
|
|
|
1
|
+
module Relaton
|
|
2
|
+
module Bib
|
|
3
|
+
class Relation < Lutaml::Model::Serializable
|
|
4
|
+
attribute :type, :string, values: %w[
|
|
5
|
+
includes includedIn hasPart partOf merges mergedInto splits splitInto
|
|
6
|
+
instanceOf hasInstance exemplarOf hasExemplar manifestationOf
|
|
7
|
+
hasManifestation reproductionOf hasReproduction reprintOf hasReprint
|
|
8
|
+
expressionOf hasExpression translatedFrom hasTranslation arrangementOf
|
|
9
|
+
hasArrangement abridgementOf hasAbridgement annotationOf hasAnnotation
|
|
10
|
+
draftOf hasDraft predecessorDraftOf hasPredecessorDraft successorDraftOf
|
|
11
|
+
hasSuccessorDraft editionOf hasEdition updates updatedBy derivedFrom
|
|
12
|
+
derives describes describedBy catalogues cataloguedBy hasSuccessor
|
|
13
|
+
successorOf adaptedFrom hasAdaptation adoptedFrom adoptedAs reviewOf
|
|
14
|
+
hasReview commentaryOf hasCommentary related hasComplement complementOf
|
|
15
|
+
obsoletes obsoletedBy cites isCitedIn
|
|
16
|
+
]
|
|
17
|
+
attribute :description, LocalizedMarkedUpString
|
|
18
|
+
attribute :bibitem, ItemBase
|
|
19
|
+
choice(min: 1, max: 1) do
|
|
20
|
+
attribute :locality, Locality, collection: true, initialize_empty: true
|
|
21
|
+
attribute :locality_stack, LocalityStack, collection: true, initialize_empty: true
|
|
22
|
+
end
|
|
23
|
+
choice(min: 1, max: 1) do
|
|
24
|
+
attribute :source_locality, Locality, collection: true, initialize_empty: true
|
|
25
|
+
attribute :source_locality_stack, SourceLocalityStack, collection: true, initialize_empty: true
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
xml do
|
|
29
|
+
root "relation"
|
|
30
|
+
|
|
31
|
+
map_attribute "type", to: :type
|
|
32
|
+
map_element "description", to: :description
|
|
33
|
+
map_element "bibitem", to: :bibitem
|
|
34
|
+
map_element "locality", to: :locality
|
|
35
|
+
map_element "localityStack", to: :locality_stack
|
|
36
|
+
map_element "sourceLocality", to: :source_locality
|
|
37
|
+
map_element "sourceLocalityStack", to: :source_locality_stack
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module Relaton
|
|
2
|
+
module Bib
|
|
3
|
+
class Series < Lutaml::Model::Serializable
|
|
4
|
+
attribute :type, :string, values: %w[main alt]
|
|
5
|
+
attribute :formattedref, Formattedref
|
|
6
|
+
attribute :title, Title, collection: (1..)
|
|
7
|
+
attribute :place, Place
|
|
8
|
+
attribute :organization, :string
|
|
9
|
+
attribute :abbreviation, LocalizedString
|
|
10
|
+
attribute :from, StringDate
|
|
11
|
+
attribute :to, StringDate
|
|
12
|
+
attribute :number, :string
|
|
13
|
+
attribute :partnumber, :string
|
|
14
|
+
attribute :run, :string
|
|
15
|
+
|
|
16
|
+
xml do
|
|
17
|
+
root "series"
|
|
18
|
+
map_attribute "type", to: :type
|
|
19
|
+
map_element "formattedref", to: :formattedref
|
|
20
|
+
map_element "title", to: :title
|
|
21
|
+
map_element "place", to: :place
|
|
22
|
+
map_element "organization", to: :organization
|
|
23
|
+
map_element "abbreviation", to: :abbreviation
|
|
24
|
+
map_element "from", to: :from
|
|
25
|
+
map_element "to", to: :to
|
|
26
|
+
map_element "number", to: :number
|
|
27
|
+
map_element "partnumber", to: :partnumber
|
|
28
|
+
map_element "run", to: :run
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Relaton
|
|
2
|
+
module Bib
|
|
3
|
+
class Size < Lutaml::Model::Serializable
|
|
4
|
+
class Value < Lutaml::Model::Serializable
|
|
5
|
+
attribute :type, :string
|
|
6
|
+
attribute :content, :string
|
|
7
|
+
|
|
8
|
+
xml do
|
|
9
|
+
root "value"
|
|
10
|
+
map_attribute "type", to: :type
|
|
11
|
+
map_content to: :content
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
attribute :value, Value, collection: (1..)
|
|
16
|
+
|
|
17
|
+
xml do
|
|
18
|
+
root "size"
|
|
19
|
+
map_element "value", to: :value
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Relaton
|
|
2
|
+
module Bib
|
|
3
|
+
class SourceLocalityStack < Lutaml::Model::Serializable
|
|
4
|
+
attribute :connective, :string, values: %w[and or from to]
|
|
5
|
+
attribute :source_locality, Locality, collection: true, initialize_empty: true
|
|
6
|
+
|
|
7
|
+
xml do
|
|
8
|
+
root "sourceLocalityStack"
|
|
9
|
+
map_attribute "connective", to: :connective
|
|
10
|
+
map_element "sourceLocality", to: :source_locality
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Relaton
|
|
2
|
+
module Bib
|
|
3
|
+
class Status < Lutaml::Model::Serializable
|
|
4
|
+
class Stage < Lutaml::Model::Serializable
|
|
5
|
+
attribute :abbreviation, :string
|
|
6
|
+
attribute :content, :string
|
|
7
|
+
|
|
8
|
+
xml do
|
|
9
|
+
root "stage"
|
|
10
|
+
map_attribute "abbreviation", to: :abbreviation
|
|
11
|
+
map_content to: :content
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
attribute :stage, Stage
|
|
16
|
+
attribute :substage, Stage
|
|
17
|
+
attribute :iteration, :string
|
|
18
|
+
|
|
19
|
+
xml do
|
|
20
|
+
root "status"
|
|
21
|
+
map_element "stage", to: :stage
|
|
22
|
+
map_element "substage", to: :substage
|
|
23
|
+
map_element "iteration", to: :iteration
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module Relaton
|
|
2
|
+
module Bib
|
|
3
|
+
class StructuredIdentifier < Lutaml::Model::Serializable
|
|
4
|
+
attribute :type, :string
|
|
5
|
+
attribute :agency, :string, collection: (1..)
|
|
6
|
+
attribute :klass, :string
|
|
7
|
+
attribute :docnumber, :string
|
|
8
|
+
attribute :partnumber, :string
|
|
9
|
+
attribute :edition, :string
|
|
10
|
+
attribute :version, :string
|
|
11
|
+
attribute :supplementtype, :string
|
|
12
|
+
attribute :supplementnumber, :string
|
|
13
|
+
attribute :amendment, :string
|
|
14
|
+
attribute :corrigendum, :string
|
|
15
|
+
attribute :language, :string
|
|
16
|
+
attribute :year, :string
|
|
17
|
+
|
|
18
|
+
xml do
|
|
19
|
+
root "structuredidentifier"
|
|
20
|
+
map_attribute "type", to: :type
|
|
21
|
+
map_element "agency", to: :agency
|
|
22
|
+
map_element "class", to: :klass
|
|
23
|
+
map_element "docnumber", to: :docnumber
|
|
24
|
+
map_element "partnumber", to: :partnumber
|
|
25
|
+
map_element "edition", to: :edition
|
|
26
|
+
map_element "version", to: :version
|
|
27
|
+
map_element "supplementtype", to: :supplementtype
|
|
28
|
+
map_element "supplementnumber", to: :supplementnumber
|
|
29
|
+
map_element "amendment", to: :amendment
|
|
30
|
+
map_element "corrigendum", to: :corrigendum
|
|
31
|
+
map_element "language", to: :language
|
|
32
|
+
map_element "year", to: :year
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def remove_part!
|
|
36
|
+
raise NotImplementedError, "`remove_part!` method not implemented in #{self.class}"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def to_all_parts!
|
|
40
|
+
raise NotImplementedError, "`to_all_parts!` method not implemented in #{self.class}"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def remove_date!
|
|
44
|
+
raise NotImplementedError, "`remove_date!` method not implemented in #{self.class}"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Relaton
|
|
2
|
+
module Bib
|
|
3
|
+
class Subdivision < Lutaml::Model::Serializable
|
|
4
|
+
include OrganizationType
|
|
5
|
+
|
|
6
|
+
attribute :type, :string
|
|
7
|
+
attribute :subtype, :string
|
|
8
|
+
|
|
9
|
+
xml do
|
|
10
|
+
root "subdivision"
|
|
11
|
+
map_attribute "type", to: :type
|
|
12
|
+
map_attribute "subtype", to: :subtype
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
module Relaton
|
|
2
|
+
module Bib
|
|
3
|
+
class Title < LocalizedMarkedUpString
|
|
4
|
+
attribute :type, :string
|
|
5
|
+
attribute :format, :string # @DEPRECATED
|
|
6
|
+
|
|
7
|
+
xml do
|
|
8
|
+
map_attribute "type", to: :type
|
|
9
|
+
map_attribute "format", to: :format
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
key_value do
|
|
13
|
+
map "type", to: :type
|
|
14
|
+
map "format", to: :format
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class << self
|
|
18
|
+
def from_string(title, lang = nil, script = nil)
|
|
19
|
+
types = %w[title-intro title-main title-part]
|
|
20
|
+
ttls = split_title(title)
|
|
21
|
+
tts = ttls.map.with_index do |p, i|
|
|
22
|
+
next unless p
|
|
23
|
+
|
|
24
|
+
new type: types[i], content: p, language: lang, script: script
|
|
25
|
+
end.compact
|
|
26
|
+
tts << new(type: "main", content: ttls.compact.join(" - "), language: lang, script: script)
|
|
27
|
+
tts
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
# @param title [String]
|
|
33
|
+
# @return [Array<String, nil>]
|
|
34
|
+
def split_title(title)
|
|
35
|
+
ttls = title.sub(/\w\.Imp\s?\d+\u00A0:\u00A0/, "").split " - "
|
|
36
|
+
case ttls.size
|
|
37
|
+
when 0, 1 then [nil, ttls.first.to_s, nil]
|
|
38
|
+
else intro_or_part ttls
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# @param ttls [Array<String>]
|
|
43
|
+
# @return [Array<String, nil>]
|
|
44
|
+
def intro_or_part(ttls)
|
|
45
|
+
if /^(Part|Partie) \d+:/.match? ttls[1]
|
|
46
|
+
[nil, ttls[0], ttls[1..].join(" -- ")]
|
|
47
|
+
else
|
|
48
|
+
parts = ttls.slice(2..-1)
|
|
49
|
+
part = parts.join " -- " if parts.any?
|
|
50
|
+
[ttls[0], ttls[1], part]
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require "date"
|
|
2
|
+
|
|
3
|
+
module Relaton
|
|
4
|
+
module Bib
|
|
5
|
+
# xs:date value type that always casts to ::Date, dropping any time and
|
|
6
|
+
# timezone component. Without this, lutaml-model's built-in Date type
|
|
7
|
+
# promotes inputs like "2018-04-15T00:00:00Z" to ::DateTime and serializes
|
|
8
|
+
# them back as "2018-04-15Z" — valid xs:date, but not valid ISO 8601.
|
|
9
|
+
class PlainDate < Lutaml::Model::Type::Date
|
|
10
|
+
def self.cast(value, options = {})
|
|
11
|
+
result = super
|
|
12
|
+
result.is_a?(::DateTime) ? result.to_date : result
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require "forwardable"
|
|
2
|
+
|
|
3
|
+
module Relaton
|
|
4
|
+
module Bib
|
|
5
|
+
class StringDate < Lutaml::Model::Type::Value
|
|
6
|
+
class Value
|
|
7
|
+
include Comparable
|
|
8
|
+
extend Forwardable
|
|
9
|
+
extend Core::DateParser
|
|
10
|
+
include Core::DateParser
|
|
11
|
+
|
|
12
|
+
def_delegators :@value, :split, :to_s
|
|
13
|
+
|
|
14
|
+
def initialize(value)
|
|
15
|
+
@value = value
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.parse_date(date)
|
|
19
|
+
value = super
|
|
20
|
+
new value if value
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def <=>(other)
|
|
24
|
+
return nil unless other.is_a?(Value)
|
|
25
|
+
|
|
26
|
+
@value <=> other.to_s
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def to_date
|
|
30
|
+
parse_date(@value, str: false)
|
|
31
|
+
rescue ArgumentError
|
|
32
|
+
nil
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.cast(value)
|
|
37
|
+
case value
|
|
38
|
+
when Value then value
|
|
39
|
+
when String then Value.parse_date(value)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def to_yaml
|
|
44
|
+
value.to_s
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Relaton
|
|
2
|
+
module Bib
|
|
3
|
+
class Uri < LocalizedStringAttrs
|
|
4
|
+
attribute :type, :string
|
|
5
|
+
attribute :content, :string
|
|
6
|
+
|
|
7
|
+
xml do
|
|
8
|
+
map_attribute "type", to: :type
|
|
9
|
+
map_content to: :content
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
key_value do
|
|
13
|
+
map "type", to: :type
|
|
14
|
+
map "content", to: :content
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Relaton
|
|
2
|
+
module Bib
|
|
3
|
+
class Validity < Lutaml::Model::Serializable
|
|
4
|
+
attribute :begins, :date_time
|
|
5
|
+
attribute :ends, :date_time
|
|
6
|
+
attribute :revision, :date_time
|
|
7
|
+
|
|
8
|
+
xml do
|
|
9
|
+
root "validity"
|
|
10
|
+
map_element "validityBegins", to: :begins
|
|
11
|
+
map_element "validityEnds", to: :ends
|
|
12
|
+
map_element "revision", to: :revision
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Relaton
|
|
2
|
+
module Bib
|
|
3
|
+
class Version < Lutaml::Model::Serializable
|
|
4
|
+
attribute :type, :string
|
|
5
|
+
attribute :content, :string
|
|
6
|
+
attribute :revision_date, :string
|
|
7
|
+
attribute :draft, :string
|
|
8
|
+
|
|
9
|
+
xml do
|
|
10
|
+
root "version"
|
|
11
|
+
map_attribute "type", to: :type
|
|
12
|
+
map_content to: :content
|
|
13
|
+
map_element "revision-date", to: :revision_date
|
|
14
|
+
map_element "draft", to: :draft
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
key_value do
|
|
18
|
+
map "type", to: :type
|
|
19
|
+
map "content", to: :content
|
|
20
|
+
map "revision_date", to: :revision_date
|
|
21
|
+
map "draft", to: :draft
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def content
|
|
25
|
+
return @content if @content && !@content.empty?
|
|
26
|
+
|
|
27
|
+
parts = [@draft, @revision_date].compact
|
|
28
|
+
case parts.size
|
|
29
|
+
when 2 then "#{@draft} (#{@revision_date})"
|
|
30
|
+
when 1 then parts.first
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def revision_date
|
|
35
|
+
nil
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def draft
|
|
39
|
+
nil
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Central autoload manifest for the model + converter layer.
|
|
2
|
+
#
|
|
3
|
+
# Declaring these as autoloads (instead of a require_relative chain) makes load
|
|
4
|
+
# order irrelevant and removes the circular require between OrganizationType and
|
|
5
|
+
# Subdivision (issue #120): a constant is loaded on first reference rather than
|
|
6
|
+
# at file-load time, so mutually-referencing classes resolve each other lazily.
|
|
7
|
+
#
|
|
8
|
+
# lutaml-model must be available before the first model autoload fires, and the
|
|
9
|
+
# XML adapter must be configured eagerly here (not inside item.rb) so that
|
|
10
|
+
# serializing through any model class works regardless of which one is
|
|
11
|
+
# referenced first.
|
|
12
|
+
require "lutaml/model"
|
|
13
|
+
require "lutaml/xml"
|
|
14
|
+
|
|
15
|
+
Lutaml::Model::Config.configure do |config|
|
|
16
|
+
config.xml_adapter_type = :nokogiri
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
module Relaton
|
|
20
|
+
module Bib
|
|
21
|
+
autoload :Abstract, "relaton/bib/model/abstract"
|
|
22
|
+
autoload :Address, "relaton/bib/model/address"
|
|
23
|
+
autoload :Affiliation, "relaton/bib/model/affiliation"
|
|
24
|
+
autoload :Bibdata, "relaton/bib/model/bibdata"
|
|
25
|
+
autoload :BibdataShared, "relaton/bib/model/bibdata_shared"
|
|
26
|
+
autoload :Bibitem, "relaton/bib/model/bibitem"
|
|
27
|
+
autoload :BibitemShared, "relaton/bib/model/bibitem_shared"
|
|
28
|
+
autoload :Contact, "relaton/bib/model/contact"
|
|
29
|
+
autoload :ContributionInfo, "relaton/bib/model/contribution_info"
|
|
30
|
+
autoload :Contributor, "relaton/bib/model/contributor"
|
|
31
|
+
autoload :Copyright, "relaton/bib/model/copyright"
|
|
32
|
+
autoload :Date, "relaton/bib/model/date"
|
|
33
|
+
autoload :Depiction, "relaton/bib/model/depiction"
|
|
34
|
+
autoload :Docidentifier, "relaton/bib/model/docidentifier"
|
|
35
|
+
autoload :Doctype, "relaton/bib/model/doctype"
|
|
36
|
+
autoload :Edition, "relaton/bib/model/edition"
|
|
37
|
+
autoload :Ext, "relaton/bib/model/ext"
|
|
38
|
+
autoload :Extent, "relaton/bib/model/extent"
|
|
39
|
+
autoload :Formattedref, "relaton/bib/model/formattedref"
|
|
40
|
+
autoload :FullName, "relaton/bib/model/fullname"
|
|
41
|
+
autoload :FullNameType, "relaton/bib/model/full_name_type"
|
|
42
|
+
autoload :ICS, "relaton/bib/model/ics"
|
|
43
|
+
autoload :Image, "relaton/bib/model/image"
|
|
44
|
+
autoload :Item, "relaton/bib/model/item"
|
|
45
|
+
autoload :ItemBase, "relaton/bib/model/item_base"
|
|
46
|
+
autoload :ItemShared, "relaton/bib/model/item_shared"
|
|
47
|
+
autoload :Keyword, "relaton/bib/model/keyword"
|
|
48
|
+
autoload :Locality, "relaton/bib/model/locality"
|
|
49
|
+
autoload :LocalityStack, "relaton/bib/model/locality_stack"
|
|
50
|
+
# localized_string.rb defines three top-level constants:
|
|
51
|
+
autoload :LocalizedString, "relaton/bib/model/localized_string"
|
|
52
|
+
autoload :TypedLocalizedString, "relaton/bib/model/localized_string"
|
|
53
|
+
autoload :LocalizedMarkedUpString, "relaton/bib/model/localized_string"
|
|
54
|
+
autoload :LocalizedStringAttrs, "relaton/bib/model/localized_string_attrs"
|
|
55
|
+
autoload :Logo, "relaton/bib/model/logo"
|
|
56
|
+
autoload :Medium, "relaton/bib/model/medium"
|
|
57
|
+
autoload :Note, "relaton/bib/model/note"
|
|
58
|
+
autoload :Organization, "relaton/bib/model/organization"
|
|
59
|
+
autoload :OrganizationType, "relaton/bib/model/organization_type"
|
|
60
|
+
autoload :Person, "relaton/bib/model/person"
|
|
61
|
+
autoload :Phone, "relaton/bib/model/phone"
|
|
62
|
+
autoload :Place, "relaton/bib/model/place"
|
|
63
|
+
# type/ is only a directory; these constants are top-level under Bib:
|
|
64
|
+
autoload :PlainDate, "relaton/bib/model/type/plain_date"
|
|
65
|
+
autoload :StringDate, "relaton/bib/model/type/string_date"
|
|
66
|
+
autoload :Price, "relaton/bib/model/price"
|
|
67
|
+
autoload :Relation, "relaton/bib/model/relation"
|
|
68
|
+
autoload :Series, "relaton/bib/model/series"
|
|
69
|
+
autoload :Size, "relaton/bib/model/size"
|
|
70
|
+
autoload :SourceLocalityStack, "relaton/bib/model/source_locality_stack"
|
|
71
|
+
autoload :Status, "relaton/bib/model/status"
|
|
72
|
+
autoload :StructuredIdentifier, "relaton/bib/model/structured_identifier"
|
|
73
|
+
autoload :Subdivision, "relaton/bib/model/subdivision"
|
|
74
|
+
autoload :Title, "relaton/bib/model/title"
|
|
75
|
+
autoload :Uri, "relaton/bib/model/uri"
|
|
76
|
+
autoload :Validity, "relaton/bib/model/validity"
|
|
77
|
+
autoload :Version, "relaton/bib/model/version"
|
|
78
|
+
|
|
79
|
+
module Converter
|
|
80
|
+
autoload :BibXml, "relaton/bib/converter/bibxml"
|
|
81
|
+
autoload :Bibtex, "relaton/bib/converter/bibtex"
|
|
82
|
+
autoload :Asciibib, "relaton/bib/converter/asciibib"
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Relaton
|
|
2
|
+
module Bib
|
|
3
|
+
module NamespaceHelper
|
|
4
|
+
def self.included(base)
|
|
5
|
+
base.extend(ClassMethods)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
module ClassMethods
|
|
9
|
+
def namespace
|
|
10
|
+
@namespace = Object.const_get name.split("::")[0..1].join("::")
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def namespace
|
|
17
|
+
self.class.namespace
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
require "nokogiri"
|
|
2
|
+
|
|
3
|
+
module Relaton
|
|
4
|
+
module Bib
|
|
5
|
+
# Strips inline markup not in the basicdoc PureTextElement set
|
|
6
|
+
# (plus <p>, <eref>, <xref>, <fn>, <link>) from raw marked-up content
|
|
7
|
+
# strings. Disallowed elements are unwrapped: tags removed, inner text
|
|
8
|
+
# kept.
|
|
9
|
+
#
|
|
10
|
+
# <link> is admitted because basicdoc expresses external hyperlinks as
|
|
11
|
+
# <link target="...">; without it a from_xml -> to_xml round-trip drops
|
|
12
|
+
# the tag and its target URL, keeping only the link text (see #122,
|
|
13
|
+
# which broke metanorma amend()).
|
|
14
|
+
#
|
|
15
|
+
# <fn> is admitted beyond strict PureTextElement because bibliographic
|
|
16
|
+
# titles in real Metanorma input routinely carry footnotes (e.g. ISO
|
|
17
|
+
# standards titles with a disclaimer footnote), and downstream
|
|
18
|
+
# consumers — notably relaton-render's own inline-tag allow-list —
|
|
19
|
+
# already accept <fn> as a legitimate child of <title>. Stripping it
|
|
20
|
+
# here would break the round-trip.
|
|
21
|
+
#
|
|
22
|
+
# OPAQUE elements (currently <stem>) are also allowed, but the
|
|
23
|
+
# sanitiser does not descend into them: their contents are out-of-band
|
|
24
|
+
# inline notation (MathML, AsciiMath, LaTeX) rather than basicdoc
|
|
25
|
+
# markup, and must be preserved verbatim. Without the opaque-skip,
|
|
26
|
+
# the recursive walk would unwrap MathML / AsciiMath elements down to
|
|
27
|
+
# bare text nodes — see #116 for the round-trip-loss symptom.
|
|
28
|
+
module Sanitizer
|
|
29
|
+
ALLOWED = %w[
|
|
30
|
+
em strong sub sup tt underline strike smallcap br stem
|
|
31
|
+
p eref xref fn link
|
|
32
|
+
].freeze
|
|
33
|
+
|
|
34
|
+
# Elements whose children are non-basicdoc inline notation
|
|
35
|
+
# (MathML, AsciiMath, LaTeX, …) and must be preserved verbatim
|
|
36
|
+
# rather than sanitised against ALLOWED.
|
|
37
|
+
OPAQUE = %w[stem].freeze
|
|
38
|
+
|
|
39
|
+
RENAME = {
|
|
40
|
+
"italic" => "em",
|
|
41
|
+
}.freeze
|
|
42
|
+
|
|
43
|
+
TAG_RX = %r{<[a-zA-Z/!?]}
|
|
44
|
+
|
|
45
|
+
def self.sanitize(content)
|
|
46
|
+
return content unless sanitizable?(content)
|
|
47
|
+
|
|
48
|
+
fragment = Nokogiri::XML::DocumentFragment.parse(content)
|
|
49
|
+
return content if fragment.errors.any?
|
|
50
|
+
|
|
51
|
+
sanitize_children(fragment)
|
|
52
|
+
fragment.children.map { |c| c.to_xml(encoding: "UTF-8") }.join
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def self.sanitizable?(content)
|
|
56
|
+
content.is_a?(::String) && !content.empty? && content.match?(TAG_RX)
|
|
57
|
+
end
|
|
58
|
+
private_class_method :sanitizable?
|
|
59
|
+
|
|
60
|
+
def self.sanitize_children(node)
|
|
61
|
+
node.children.to_a.each do |child|
|
|
62
|
+
next unless child.element?
|
|
63
|
+
|
|
64
|
+
child.name = RENAME[child.name] if RENAME.key?(child.name)
|
|
65
|
+
next if OPAQUE.include?(child.name)
|
|
66
|
+
|
|
67
|
+
sanitize_children(child)
|
|
68
|
+
child.replace(child.children) unless ALLOWED.include?(child.name)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
private_class_method :sanitize_children
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Relaton
|
|
2
|
+
module Bib
|
|
3
|
+
module Util
|
|
4
|
+
extend self
|
|
5
|
+
|
|
6
|
+
PROGNAME = "relaton-bib".freeze
|
|
7
|
+
|
|
8
|
+
def method_missing(method_name, msg = nil, prog = nil, **opts, &block)
|
|
9
|
+
prog ||= self::PROGNAME
|
|
10
|
+
Relaton.logger_pool.send method_name, msg, prog, **opts, &block
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def respond_to_missing?(method_name, include_private = false)
|
|
14
|
+
Relaton.logger_pool.respond_to?(method_name) || super
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"relaton-models": "v1.5.6",
|
|
3
|
+
"basicdoc-models": "v1.2.5",
|
|
4
|
+
"metanorma-requirements-models": "v1.0.2",
|
|
5
|
+
"relaton-model-ieee": "v1.1.3",
|
|
6
|
+
"relaton-model-iso": "v1.1.2",
|
|
7
|
+
"relaton-model-iec": "v1.1.2",
|
|
8
|
+
"relaton-model-bsi": "v1.1.3",
|
|
9
|
+
"relaton-model-gb": "v1.1.2",
|
|
10
|
+
"relaton-model-mpfa": "v1.0.0",
|
|
11
|
+
"relaton-model-bipm": "v1.1.2",
|
|
12
|
+
"relaton-model-w3c": "v1.0.0",
|
|
13
|
+
"relaton-model-3gpp": "v1.0.4",
|
|
14
|
+
"relaton-model-cc": "v1.1.2",
|
|
15
|
+
"relaton-model-ietf": "v1.1.2",
|
|
16
|
+
"relaton-model-iho": "v1.1.2",
|
|
17
|
+
"relaton-model-itu": "v1.1.3",
|
|
18
|
+
"relaton-model-m3aawg": "v1.0.1",
|
|
19
|
+
"relaton-model-nist": "v1.1.2",
|
|
20
|
+
"relaton-model-ribose": "v1.1.2",
|
|
21
|
+
"relaton-model-ogc": "v1.1.2",
|
|
22
|
+
"relaton-model-cen": "v1.0.1",
|
|
23
|
+
"relaton-model-ecma": "v1.0.0",
|
|
24
|
+
"relaton-model-cie": "v1.0.0",
|
|
25
|
+
"relaton-model-iana": "v1.0.0",
|
|
26
|
+
"relaton-model-omg": "v1.0.0",
|
|
27
|
+
"relaton-model-oasis": "v1.0.4",
|
|
28
|
+
"relaton-model-jis": "v1.0.2",
|
|
29
|
+
"relaton-model-etsi": "v0.1.2",
|
|
30
|
+
"relaton-model-plateau": "v0.1.0",
|
|
31
|
+
"relaton-model-ccsds": "",
|
|
32
|
+
"relaton-model-un": "v1.0.2",
|
|
33
|
+
"metanorma-model": "v2.1.6",
|
|
34
|
+
"date": "2026-04-30T03:49:24Z"
|
|
35
|
+
}
|