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.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/integration-tests.yml +54 -0
  3. data/.github/workflows/rake.yml +15 -0
  4. data/.github/workflows/release.yml +24 -0
  5. data/.gitignore +4 -1
  6. data/.rubocop.yml +3 -1
  7. data/CLAUDE.md +108 -0
  8. data/Gemfile +11 -0
  9. data/README.adoc +229 -314
  10. data/bin/console +1 -1
  11. data/docs/hash.adoc +132 -83
  12. data/lib/relaton/bib/converter/asciibib/to_asciibib.rb +663 -0
  13. data/lib/relaton/bib/converter/asciibib.rb +13 -0
  14. data/lib/relaton/bib/converter/bibtex/from_bibtex.rb +245 -0
  15. data/lib/relaton/bib/converter/bibtex/to_bibtex.rb +341 -0
  16. data/lib/relaton/bib/converter/bibtex.rb +23 -0
  17. data/lib/relaton/bib/converter/bibxml/from_rfcxml.rb +386 -0
  18. data/lib/relaton/bib/converter/bibxml/from_rfcxml_referencegroup.rb +71 -0
  19. data/lib/relaton/bib/converter/bibxml/to_rfcxml.rb +308 -0
  20. data/lib/relaton/bib/converter/bibxml/to_rfcxml_referencegroup.rb +52 -0
  21. data/lib/relaton/bib/converter/bibxml.rb +51 -0
  22. data/lib/relaton/bib/hash_parser_v1.rb +767 -0
  23. data/lib/relaton/bib/item_data.rb +229 -0
  24. data/lib/relaton/bib/model/abstract.rb +16 -0
  25. data/lib/relaton/bib/model/address.rb +22 -0
  26. data/lib/relaton/bib/model/affiliation.rb +16 -0
  27. data/lib/relaton/bib/model/bibdata.rb +9 -0
  28. data/lib/relaton/bib/model/bibdata_shared.rb +10 -0
  29. data/lib/relaton/bib/model/bibitem.rb +9 -0
  30. data/lib/relaton/bib/model/bibitem_shared.rb +10 -0
  31. data/lib/relaton/bib/model/contact.rb +14 -0
  32. data/lib/relaton/bib/model/contribution_info.rb +16 -0
  33. data/lib/relaton/bib/model/contributor.rb +29 -0
  34. data/lib/relaton/bib/model/copyright.rb +27 -0
  35. data/lib/relaton/bib/model/date.rb +29 -0
  36. data/lib/relaton/bib/model/depiction.rb +16 -0
  37. data/lib/relaton/bib/model/docidentifier.rb +34 -0
  38. data/lib/relaton/bib/model/doctype.rb +14 -0
  39. data/lib/relaton/bib/model/edition.rb +14 -0
  40. data/lib/relaton/bib/model/ext.rb +35 -0
  41. data/lib/relaton/bib/model/extent.rb +16 -0
  42. data/lib/relaton/bib/model/formattedref.rb +43 -0
  43. data/lib/relaton/bib/model/full_name_type.rb +64 -0
  44. data/lib/relaton/bib/model/fullname.rb +11 -0
  45. data/lib/relaton/bib/model/ics.rb +49 -0
  46. data/lib/relaton/bib/model/image.rb +28 -0
  47. data/lib/relaton/bib/model/item.rb +44 -0
  48. data/lib/relaton/bib/model/item_base.rb +20 -0
  49. data/lib/relaton/bib/model/item_shared.rb +88 -0
  50. data/lib/relaton/bib/model/keyword.rb +30 -0
  51. data/lib/relaton/bib/model/locality.rb +18 -0
  52. data/lib/relaton/bib/model/locality_stack.rb +14 -0
  53. data/lib/relaton/bib/model/localized_string.rb +48 -0
  54. data/lib/relaton/bib/model/localized_string_attrs.rb +24 -0
  55. data/lib/relaton/bib/model/logo.rb +14 -0
  56. data/lib/relaton/bib/model/medium.rb +22 -0
  57. data/lib/relaton/bib/model/note.rb +16 -0
  58. data/lib/relaton/bib/model/organization.rb +11 -0
  59. data/lib/relaton/bib/model/organization_type.rb +40 -0
  60. data/lib/relaton/bib/model/person.rb +36 -0
  61. data/lib/relaton/bib/model/phone.rb +14 -0
  62. data/lib/relaton/bib/model/place.rb +33 -0
  63. data/lib/relaton/bib/model/price.rb +14 -0
  64. data/lib/relaton/bib/model/relation.rb +41 -0
  65. data/lib/relaton/bib/model/series.rb +32 -0
  66. data/lib/relaton/bib/model/size.rb +23 -0
  67. data/lib/relaton/bib/model/source_locality_stack.rb +14 -0
  68. data/lib/relaton/bib/model/status.rb +27 -0
  69. data/lib/relaton/bib/model/structured_identifier.rb +48 -0
  70. data/lib/relaton/bib/model/subdivision.rb +16 -0
  71. data/lib/relaton/bib/model/title.rb +56 -0
  72. data/lib/relaton/bib/model/type/plain_date.rb +16 -0
  73. data/lib/relaton/bib/model/type/string_date.rb +48 -0
  74. data/lib/relaton/bib/model/uri.rb +18 -0
  75. data/lib/relaton/bib/model/validity.rb +16 -0
  76. data/lib/relaton/bib/model/version.rb +43 -0
  77. data/lib/relaton/bib/model_autoload.rb +85 -0
  78. data/lib/relaton/bib/namespace_helper.rb +21 -0
  79. data/lib/relaton/bib/sanitizer.rb +74 -0
  80. data/lib/relaton/bib/util.rb +18 -0
  81. data/lib/relaton/bib/version.rb +5 -0
  82. data/lib/relaton/bib/versions.json +35 -0
  83. data/lib/relaton/bib.rb +41 -0
  84. data/relaton-bib.gemspec +12 -16
  85. metadata +118 -129
  86. data/.github/workflows/macos.yml +0 -38
  87. data/.github/workflows/ubuntu.yml +0 -39
  88. data/.github/workflows/windows.yml +0 -41
  89. data/grammars/basicdoc.rng +0 -986
  90. data/grammars/biblio.rng +0 -1237
  91. data/grammars/isodoc.rng +0 -1613
  92. data/grammars/reqt.rng +0 -165
  93. data/lib/relaton_bib/bib_item_locality.rb +0 -107
  94. data/lib/relaton_bib/biblio_note.rb +0 -44
  95. data/lib/relaton_bib/biblio_version.rb +0 -49
  96. data/lib/relaton_bib/bibliographic_date.rb +0 -90
  97. data/lib/relaton_bib/bibliographic_item.rb +0 -726
  98. data/lib/relaton_bib/bibtex_parser.rb +0 -245
  99. data/lib/relaton_bib/classification.rb +0 -40
  100. data/lib/relaton_bib/contribution_info.rb +0 -109
  101. data/lib/relaton_bib/contributor.rb +0 -215
  102. data/lib/relaton_bib/copyright_association.rb +0 -77
  103. data/lib/relaton_bib/deep_dup.rb +0 -30
  104. data/lib/relaton_bib/document_identifier.rb +0 -95
  105. data/lib/relaton_bib/document_relation.rb +0 -94
  106. data/lib/relaton_bib/document_relation_collection.rb +0 -46
  107. data/lib/relaton_bib/document_status.rb +0 -93
  108. data/lib/relaton_bib/editorial_group.rb +0 -41
  109. data/lib/relaton_bib/formatted_ref.rb +0 -17
  110. data/lib/relaton_bib/formatted_string.rb +0 -55
  111. data/lib/relaton_bib/hash_converter.rb +0 -497
  112. data/lib/relaton_bib/hit.rb +0 -46
  113. data/lib/relaton_bib/hit_collection.rb +0 -73
  114. data/lib/relaton_bib/ics.rb +0 -37
  115. data/lib/relaton_bib/localized_string.rb +0 -93
  116. data/lib/relaton_bib/medium.rb +0 -44
  117. data/lib/relaton_bib/organization.rb +0 -135
  118. data/lib/relaton_bib/person.rb +0 -206
  119. data/lib/relaton_bib/place.rb +0 -49
  120. data/lib/relaton_bib/series.rb +0 -134
  121. data/lib/relaton_bib/structured_identifier.rb +0 -171
  122. data/lib/relaton_bib/technical_committee.rb +0 -36
  123. data/lib/relaton_bib/typed_title_string.rb +0 -96
  124. data/lib/relaton_bib/typed_uri.rb +0 -47
  125. data/lib/relaton_bib/validity.rb +0 -52
  126. data/lib/relaton_bib/version.rb +0 -3
  127. data/lib/relaton_bib/workers_pool.rb +0 -43
  128. data/lib/relaton_bib/workgroup.rb +0 -46
  129. data/lib/relaton_bib/xml_parser.rb +0 -463
  130. 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,5 @@
1
+ module Relaton
2
+ module Bib
3
+ VERSION = "2.1.7".freeze
4
+ end
5
+ 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
+ }