glossarist 2.6.6 → 2.6.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 (139) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +90 -29
  3. data/glossarist.gemspec +2 -0
  4. data/lib/glossarist/citation.rb +26 -123
  5. data/lib/glossarist/cli/compare_command.rb +106 -0
  6. data/lib/glossarist/cli/export_command.rb +11 -14
  7. data/lib/glossarist/cli/validate_command.rb +111 -20
  8. data/lib/glossarist/cli.rb +18 -0
  9. data/lib/glossarist/collections/bibliography_collection.rb +4 -2
  10. data/lib/glossarist/collections/localization_collection.rb +2 -0
  11. data/lib/glossarist/comparison_result.rb +35 -0
  12. data/lib/glossarist/concept_collector.rb +44 -0
  13. data/lib/glossarist/concept_comparator.rb +72 -0
  14. data/lib/glossarist/concept_data.rb +16 -0
  15. data/lib/glossarist/concept_diff.rb +15 -0
  16. data/lib/glossarist/concept_document.rb +11 -0
  17. data/lib/glossarist/concept_manager.rb +19 -5
  18. data/lib/glossarist/concept_ref.rb +13 -0
  19. data/lib/glossarist/concept_validator.rb +6 -1
  20. data/lib/glossarist/context_configuration.rb +90 -0
  21. data/lib/glossarist/dataset_validator.rb +8 -4
  22. data/lib/glossarist/designation/prefix.rb +17 -0
  23. data/lib/glossarist/designation/suffix.rb +17 -0
  24. data/lib/glossarist/gcr_metadata.rb +7 -14
  25. data/lib/glossarist/gcr_package.rb +35 -23
  26. data/lib/glossarist/gcr_validator.rb +38 -17
  27. data/lib/glossarist/localized_concept.rb +8 -0
  28. data/lib/glossarist/managed_concept.rb +39 -6
  29. data/lib/glossarist/managed_concept_data.rb +2 -1
  30. data/lib/glossarist/rdf/ext/jsonld_transform_ext.rb +208 -0
  31. data/lib/glossarist/rdf/ext/mapping_ext.rb +37 -0
  32. data/lib/glossarist/rdf/ext/mapping_rule_ext.rb +27 -0
  33. data/lib/glossarist/rdf/ext/member_rule_ext.rb +34 -0
  34. data/lib/glossarist/rdf/ext/turtle_transform_ext.rb +222 -0
  35. data/lib/glossarist/rdf/ext.rb +39 -0
  36. data/lib/glossarist/rdf/gloss_citation.rb +36 -0
  37. data/lib/glossarist/rdf/gloss_concept.rb +58 -0
  38. data/lib/glossarist/rdf/gloss_concept_date.rb +24 -0
  39. data/lib/glossarist/rdf/gloss_concept_reference.rb +29 -0
  40. data/lib/glossarist/rdf/gloss_concept_source.rb +37 -0
  41. data/lib/glossarist/rdf/gloss_designation.rb +146 -0
  42. data/lib/glossarist/rdf/gloss_detailed_definition.rb +24 -0
  43. data/lib/glossarist/rdf/gloss_grammar_info.rb +57 -0
  44. data/lib/glossarist/rdf/gloss_locality.rb +25 -0
  45. data/lib/glossarist/rdf/gloss_localized_concept.rb +67 -0
  46. data/lib/glossarist/rdf/gloss_non_verbal_rep.rb +31 -0
  47. data/lib/glossarist/rdf/gloss_pronunciation.rb +32 -0
  48. data/lib/glossarist/rdf/gloss_reference.rb +55 -0
  49. data/lib/glossarist/rdf/namespaces/glossarist_namespace.rb +12 -0
  50. data/lib/glossarist/rdf/namespaces/iso_thes_namespace.rb +12 -0
  51. data/lib/glossarist/rdf/namespaces/owl_namespace.rb +12 -0
  52. data/lib/glossarist/rdf/namespaces/prov_namespace.rb +12 -0
  53. data/lib/glossarist/rdf/namespaces/rdf_namespace.rb +12 -0
  54. data/lib/glossarist/rdf/namespaces/skosxl_namespace.rb +12 -0
  55. data/lib/glossarist/rdf/namespaces.rb +8 -2
  56. data/lib/glossarist/rdf/relationships.rb +19 -0
  57. data/lib/glossarist/rdf/v3/configuration.rb +15 -0
  58. data/lib/glossarist/rdf/v3.rb +79 -0
  59. data/lib/glossarist/rdf.rb +22 -2
  60. data/lib/glossarist/reference_extractor.rb +12 -19
  61. data/lib/glossarist/reference_resolver.rb +3 -3
  62. data/lib/glossarist/related_concept.rb +2 -10
  63. data/lib/glossarist/schema_migration.rb +39 -0
  64. data/lib/glossarist/sts/term_mapper.rb +2 -2
  65. data/lib/glossarist/transforms/concept_to_gloss_transform.rb +355 -0
  66. data/lib/glossarist/transforms.rb +2 -2
  67. data/lib/glossarist/v1/concept.rb +17 -17
  68. data/lib/glossarist/v2/citation.rb +36 -0
  69. data/lib/glossarist/v2/concept_data.rb +46 -0
  70. data/lib/glossarist/v2/concept_document.rb +18 -0
  71. data/lib/glossarist/v2/concept_ref.rb +8 -0
  72. data/lib/glossarist/v2/concept_source.rb +16 -0
  73. data/lib/glossarist/v2/configuration.rb +13 -0
  74. data/lib/glossarist/v2/detailed_definition.rb +14 -0
  75. data/lib/glossarist/v2/localized_concept.rb +9 -0
  76. data/lib/glossarist/v2/managed_concept.rb +25 -0
  77. data/lib/glossarist/v2/managed_concept_data.rb +49 -0
  78. data/lib/glossarist/v2/related_concept.rb +15 -0
  79. data/lib/glossarist/v2.rb +28 -0
  80. data/lib/glossarist/v3/bibliography_entry.rb +19 -0
  81. data/lib/glossarist/v3/bibliography_file.rb +27 -0
  82. data/lib/glossarist/v3/citation.rb +30 -0
  83. data/lib/glossarist/v3/concept_data.rb +46 -0
  84. data/lib/glossarist/v3/concept_document.rb +18 -0
  85. data/lib/glossarist/v3/concept_ref.rb +8 -0
  86. data/lib/glossarist/v3/concept_source.rb +16 -0
  87. data/lib/glossarist/v3/configuration.rb +13 -0
  88. data/lib/glossarist/v3/detailed_definition.rb +14 -0
  89. data/lib/glossarist/v3/image_entry.rb +21 -0
  90. data/lib/glossarist/v3/image_file.rb +31 -0
  91. data/lib/glossarist/v3/localized_concept.rb +9 -0
  92. data/lib/glossarist/v3/managed_concept.rb +26 -0
  93. data/lib/glossarist/v3/managed_concept_data.rb +34 -0
  94. data/lib/glossarist/v3/related_concept.rb +15 -0
  95. data/lib/glossarist/v3.rb +36 -0
  96. data/lib/glossarist/validation/bibliography_index.rb +61 -30
  97. data/lib/glossarist/validation/rules/asciidoc_xref_rule.rb +2 -15
  98. data/lib/glossarist/validation/rules/authoritative_source_rule.rb +2 -15
  99. data/lib/glossarist/validation/rules/base.rb +5 -0
  100. data/lib/glossarist/validation/rules/bibliography_yaml_rule.rb +2 -3
  101. data/lib/glossarist/validation/rules/citation_completeness_rule.rb +5 -27
  102. data/lib/glossarist/validation/rules/dataset_context.rb +8 -3
  103. data/lib/glossarist/validation/rules/date_validity_rule.rb +1 -1
  104. data/lib/glossarist/validation/rules/designation_status_rule.rb +0 -1
  105. data/lib/glossarist/validation/rules/designation_type_rule.rb +1 -5
  106. data/lib/glossarist/validation/rules/domain_ref_rule.rb +37 -0
  107. data/lib/glossarist/validation/rules/domain_target_rule.rb +56 -0
  108. data/lib/glossarist/validation/rules/gcr_context.rb +12 -13
  109. data/lib/glossarist/validation/rules/image_reference_rule.rb +2 -17
  110. data/lib/glossarist/validation/rules/locality_completeness_rule.rb +58 -0
  111. data/lib/glossarist/validation/rules/localization_consistency_rule.rb +72 -0
  112. data/lib/glossarist/validation/rules/localization_presence_rule.rb +1 -1
  113. data/lib/glossarist/validation/rules/model_validity_rule.rb +71 -0
  114. data/lib/glossarist/validation/rules/orphaned_bibliography_rule.rb +1 -13
  115. data/lib/glossarist/validation/rules/orphaned_images_rule.rb +16 -11
  116. data/lib/glossarist/validation/rules/ref_shape_rule.rb +68 -0
  117. data/lib/glossarist/validation/rules/related_concept_cycle_rule.rb +1 -3
  118. data/lib/glossarist/validation/rules/related_concept_symmetry_rule.rb +1 -3
  119. data/lib/glossarist/validation/rules/related_concept_target_rule.rb +64 -0
  120. data/lib/glossarist/validation/rules/schema_version_rule.rb +41 -0
  121. data/lib/glossarist/validation/rules/source_type_rule.rb +1 -15
  122. data/lib/glossarist/validation/rules/source_urn_format_rule.rb +65 -0
  123. data/lib/glossarist/validation/rules/uuid_format_rule.rb +33 -0
  124. data/lib/glossarist/validation/rules.rb +10 -43
  125. data/lib/glossarist/validation/validation_issue.rb +14 -11
  126. data/lib/glossarist/validation_result.rb +12 -22
  127. data/lib/glossarist/version.rb +1 -1
  128. data/lib/glossarist.rb +9 -0
  129. data/memory/project-status.md +43 -0
  130. data/scripts/migrate_dataset.rb +180 -0
  131. data/scripts/migrate_isotc204_to_v3.rb +134 -0
  132. data/scripts/migrate_isotc211_to_v3.rb +153 -0
  133. data/scripts/migrate_osgeo_to_v3.rb +155 -0
  134. data/scripts/upgrade_dataset_to_v3.rb +47 -0
  135. metadata +111 -6
  136. data/TODO.integration/01-gcr-package-cli.md +0 -180
  137. data/lib/glossarist/rdf/skos_concept.rb +0 -43
  138. data/lib/glossarist/rdf/skos_vocabulary.rb +0 -25
  139. data/lib/glossarist/transforms/concept_to_skos_transform.rb +0 -131
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lutaml/model"
4
+
5
+ module Glossarist
6
+ module Rdf
7
+ class GlossDetailedDefinition < Lutaml::Model::Serializable
8
+ attribute :content, :string
9
+ attribute :sources, GlossConceptSource, collection: true
10
+
11
+ rdf do
12
+ namespace Namespaces::GlossaristNamespace, Namespaces::RdfNamespace
13
+
14
+ subject { |d| "definition/#{d.content.hash.abs}" }
15
+
16
+ types "gloss:DetailedDefinition"
17
+
18
+ predicate :value, namespace: Namespaces::RdfNamespace, to: :content
19
+
20
+ members :sources
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lutaml/model"
4
+
5
+ module Glossarist
6
+ module Rdf
7
+ class GlossGrammarInfo < Lutaml::Model::Serializable
8
+ attribute :gender, :string, collection: true
9
+ attribute :number, :string, collection: true
10
+ attribute :part_of_speech, :string
11
+ attribute :concept_id, :string
12
+ attribute :lang_code, :string
13
+ attribute :index, :string
14
+
15
+ rdf do
16
+ namespace Namespaces::GlossaristNamespace
17
+
18
+ subject { |g| "concept/#{g.concept_id}/#{g.lang_code}/designation/#{g.index}/grammar" }
19
+
20
+ types "gloss:GrammarInfo"
21
+
22
+ predicate :gender, namespace: Namespaces::GlossaristNamespace, to: :gender, as: :uri
23
+ predicate :number, namespace: Namespaces::GlossaristNamespace, to: :number, as: :uri
24
+ predicate :isNoun, namespace: Namespaces::GlossaristNamespace, to: :noun?
25
+ predicate :isVerb, namespace: Namespaces::GlossaristNamespace, to: :verb?
26
+ predicate :isAdjective, namespace: Namespaces::GlossaristNamespace, to: :adjective?
27
+ predicate :isAdverb, namespace: Namespaces::GlossaristNamespace, to: :adverb?
28
+ predicate :isPreposition, namespace: Namespaces::GlossaristNamespace, to: :preposition?
29
+ predicate :isParticiple, namespace: Namespaces::GlossaristNamespace, to: :participle?
30
+ end
31
+
32
+ def noun?
33
+ part_of_speech == "noun"
34
+ end
35
+
36
+ def verb?
37
+ part_of_speech == "verb"
38
+ end
39
+
40
+ def adjective?
41
+ part_of_speech == "adjective"
42
+ end
43
+
44
+ def adverb?
45
+ part_of_speech == "adverb"
46
+ end
47
+
48
+ def preposition?
49
+ part_of_speech == "preposition"
50
+ end
51
+
52
+ def participle?
53
+ part_of_speech == "participle"
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lutaml/model"
4
+
5
+ module Glossarist
6
+ module Rdf
7
+ class GlossLocality < Lutaml::Model::Serializable
8
+ attribute :locality_type, :string
9
+ attribute :reference_from, :string
10
+ attribute :reference_to, :string
11
+
12
+ rdf do
13
+ namespace Namespaces::GlossaristNamespace
14
+
15
+ subject { |l| "locality/#{l.locality_type}/#{l.reference_from}" }
16
+
17
+ types "gloss:Locality"
18
+
19
+ predicate :localityType, namespace: Namespaces::GlossaristNamespace, to: :locality_type
20
+ predicate :referenceFrom, namespace: Namespaces::GlossaristNamespace, to: :reference_from
21
+ predicate :referenceTo, namespace: Namespaces::GlossaristNamespace, to: :reference_to
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lutaml/model"
4
+
5
+ module Glossarist
6
+ module Rdf
7
+ class GlossLocalizedConcept < Lutaml::Model::Serializable
8
+ attribute :concept_id, :string
9
+ attribute :language_code, :string
10
+ attribute :domain, :string
11
+ attribute :entry_status, :string
12
+ attribute :release, :string
13
+ attribute :lineage_similarity, :integer
14
+ attribute :script, :string
15
+ attribute :system, :string
16
+ attribute :designations, GlossDesignation, collection: true
17
+ attribute :definitions, GlossDetailedDefinition, collection: true
18
+ attribute :notes, GlossDetailedDefinition, collection: true
19
+ attribute :examples, GlossDetailedDefinition, collection: true
20
+ attribute :sources, GlossConceptSource, collection: true
21
+ attribute :non_verb_reps, GlossNonVerbalRep, collection: true
22
+
23
+ rdf do
24
+ namespace Namespaces::GlossaristNamespace,
25
+ Namespaces::SkosNamespace,
26
+ Namespaces::SkosxlNamespace,
27
+ Namespaces::DctermsNamespace,
28
+ Namespaces::IsoThesNamespace,
29
+ Namespaces::RdfNamespace
30
+
31
+ subject { |l| "concept/#{l.concept_id}/#{l.language_code}" }
32
+
33
+ types "gloss:LocalizedConcept", "skos:Concept"
34
+
35
+ predicate :language, namespace: Namespaces::DctermsNamespace, to: :language_code
36
+ predicate :hasEntryStatus, namespace: Namespaces::GlossaristNamespace, to: :entry_status, as: :uri
37
+ predicate :domain, namespace: Namespaces::GlossaristNamespace, to: :domain
38
+ predicate :release, namespace: Namespaces::GlossaristNamespace, to: :release
39
+ predicate :lineageSimilarity, namespace: Namespaces::GlossaristNamespace, to: :lineage_similarity
40
+ predicate :script, namespace: Namespaces::GlossaristNamespace, to: :script
41
+ predicate :conversionSystem, namespace: Namespaces::GlossaristNamespace, to: :system
42
+
43
+ members :designations,
44
+ link: ->(d) { GlossLocalizedConcept.skosxl_label_for(d) }
45
+ members :definitions,
46
+ link: "gloss:hasDefinition"
47
+ members :notes,
48
+ link: "gloss:hasNote"
49
+ members :examples,
50
+ link: "gloss:hasExample"
51
+ members :sources,
52
+ link: "gloss:hasSource"
53
+ members :non_verb_reps,
54
+ link: "gloss:hasNonVerbalRep"
55
+ end
56
+
57
+ def self.skosxl_label_for(designation)
58
+ status = designation.normative_status.to_s.split("/").last
59
+ case status
60
+ when "preferred" then "skosxl:prefLabel"
61
+ when "deprecated" then "skosxl:hiddenLabel"
62
+ else "skosxl:altLabel"
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lutaml/model"
4
+
5
+ module Glossarist
6
+ module Rdf
7
+ class GlossNonVerbalRep < Lutaml::Model::Serializable
8
+ attribute :representation_type, :string
9
+ attribute :representation_ref, :string
10
+ attribute :representation_text, :string
11
+ attribute :sources, GlossConceptSource, collection: true
12
+ attribute :concept_id, :string
13
+ attribute :lang_code, :string
14
+ attribute :index, :string
15
+
16
+ rdf do
17
+ namespace Namespaces::GlossaristNamespace
18
+
19
+ subject { |n| "concept/#{n.concept_id}/#{n.lang_code}/nonverbal/#{n.index}" }
20
+
21
+ types "gloss:NonVerbalRepresentation"
22
+
23
+ predicate :representationType, namespace: Namespaces::GlossaristNamespace, to: :representation_type
24
+ predicate :representationRef, namespace: Namespaces::GlossaristNamespace, to: :representation_ref
25
+ predicate :representationText, namespace: Namespaces::GlossaristNamespace, to: :representation_text
26
+
27
+ members :sources
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lutaml/model"
4
+
5
+ module Glossarist
6
+ module Rdf
7
+ class GlossPronunciation < Lutaml::Model::Serializable
8
+ attribute :content, :string
9
+ attribute :language, :string
10
+ attribute :script, :string
11
+ attribute :country, :string
12
+ attribute :system, :string
13
+ attribute :concept_id, :string
14
+ attribute :lang_code, :string
15
+ attribute :index, :string
16
+
17
+ rdf do
18
+ namespace Namespaces::GlossaristNamespace
19
+
20
+ subject { |p| "concept/#{p.concept_id}/#{p.lang_code}/pronunciation/#{p.index}" }
21
+
22
+ types "gloss:Pronunciation"
23
+
24
+ predicate :pronunciationContent, namespace: Namespaces::GlossaristNamespace, to: :content
25
+ predicate :pronunciationLanguage, namespace: Namespaces::GlossaristNamespace, to: :language
26
+ predicate :pronunciationScript, namespace: Namespaces::GlossaristNamespace, to: :script
27
+ predicate :pronunciationCountry, namespace: Namespaces::GlossaristNamespace, to: :country
28
+ predicate :pronunciationSystem, namespace: Namespaces::GlossaristNamespace, to: :system
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lutaml/model"
4
+ require "digest"
5
+
6
+ module Glossarist
7
+ module Rdf
8
+ # Unified RDF view for bibliographic citations and concept references.
9
+ #
10
+ # Replaces the former GlossCitation and GlossConceptReference classes.
11
+ # Both model "a reference to an item within a collection":
12
+ # - Citation: collection=document series, item=document, position=clause
13
+ # - ConceptReference: collection=termbase, item=concept
14
+ class GlossReference < Lutaml::Model::Serializable
15
+ attribute :text, :string
16
+ attribute :source, :string
17
+ attribute :id, :string
18
+ attribute :version, :string
19
+ attribute :link, :string
20
+ attribute :locality, GlossLocality
21
+ attribute :ref_type, :string
22
+ attribute :urn, :string
23
+ attribute :term, :string
24
+ attribute :parent_id, :string
25
+
26
+ rdf do
27
+ namespace Namespaces::GlossaristNamespace
28
+
29
+ subject { |r| GlossReference.slug(r) }
30
+
31
+ types "gloss:Reference"
32
+
33
+ predicate :citationText, namespace: Namespaces::GlossaristNamespace, to: :text
34
+ predicate :source, namespace: Namespaces::GlossaristNamespace, to: :source
35
+ predicate :refId, namespace: Namespaces::GlossaristNamespace, to: :id
36
+ predicate :version, namespace: Namespaces::GlossaristNamespace, to: :version
37
+ predicate :link, namespace: Namespaces::GlossaristNamespace, to: :link
38
+ predicate :refType, namespace: Namespaces::GlossaristNamespace, to: :ref_type
39
+ predicate :urn, namespace: Namespaces::GlossaristNamespace, to: :urn
40
+ predicate :term, namespace: Namespaces::GlossaristNamespace, to: :term
41
+ members :locality, link: "gloss:hasLocality"
42
+ end
43
+
44
+ def self.slug(ref)
45
+ slug = [ref.source, ref.id].compact.join("/")
46
+ slug = Digest::MD5.hexdigest(ref.text || "")[0..11] if slug.empty?
47
+ slug
48
+ end
49
+ end
50
+
51
+ # Backward-compatible aliases
52
+ GlossCitation = GlossReference
53
+ GlossConceptReference = GlossReference
54
+ end
55
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glossarist
4
+ module Rdf
5
+ module Namespaces
6
+ class GlossaristNamespace < Lutaml::Rdf::Namespace
7
+ uri "https://www.glossarist.org/ontologies/"
8
+ prefix "gloss"
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glossarist
4
+ module Rdf
5
+ module Namespaces
6
+ class IsoThesNamespace < Lutaml::Rdf::Namespace
7
+ uri "http://purl.org/iso25964/skos-thes#"
8
+ prefix "iso-thes"
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glossarist
4
+ module Rdf
5
+ module Namespaces
6
+ class OwlNamespace < Lutaml::Rdf::Namespace
7
+ uri "http://www.w3.org/2002/07/owl#"
8
+ prefix "owl"
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glossarist
4
+ module Rdf
5
+ module Namespaces
6
+ class ProvNamespace < Lutaml::Rdf::Namespace
7
+ uri "http://www.w3.org/ns/prov#"
8
+ prefix "prov"
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glossarist
4
+ module Rdf
5
+ module Namespaces
6
+ class RdfNamespace < Lutaml::Rdf::Namespace
7
+ uri "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8
+ prefix "rdf"
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glossarist
4
+ module Rdf
5
+ module Namespaces
6
+ class SkosxlNamespace < Lutaml::Rdf::Namespace
7
+ uri "http://www.w3.org/2008/05/skos-xl#"
8
+ prefix "skosxl"
9
+ end
10
+ end
11
+ end
12
+ end
@@ -3,8 +3,14 @@
3
3
  module Glossarist
4
4
  module Rdf
5
5
  module Namespaces
6
- autoload :SkosNamespace, "#{__dir__}/namespaces/skos_namespace"
7
- autoload :DctermsNamespace, "#{__dir__}/namespaces/dcterms_namespace"
6
+ autoload :DctermsNamespace, "#{__dir__}/namespaces/dcterms_namespace"
7
+ autoload :GlossaristNamespace, "#{__dir__}/namespaces/glossarist_namespace"
8
+ autoload :IsoThesNamespace, "#{__dir__}/namespaces/iso_thes_namespace"
9
+ autoload :OwlNamespace, "#{__dir__}/namespaces/owl_namespace"
10
+ autoload :RdfNamespace, "#{__dir__}/namespaces/rdf_namespace"
11
+ autoload :ProvNamespace, "#{__dir__}/namespaces/prov_namespace"
12
+ autoload :SkosNamespace, "#{__dir__}/namespaces/skos_namespace"
13
+ autoload :SkosxlNamespace, "#{__dir__}/namespaces/skosxl_namespace"
8
14
  end
9
15
  end
10
16
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glossarist
4
+ module Rdf
5
+ # Included by RDF view classes that carry variable-predicate relationships.
6
+ #
7
+ # Standard SKOS/iso-thes relationships (broader, exactMatch, etc.) and
8
+ # glossarist-specific relationships (deprecates, compares, etc.) are
9
+ # emitted as direct triples with the predicate determined at runtime
10
+ # from REL_PROPERTY_MAP.
11
+ module Relationships
12
+ attr_reader :relationship_triples
13
+
14
+ def relationship_triples=(pairs)
15
+ @relationship_triples = Array(pairs)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../context_configuration"
4
+
5
+ module Glossarist
6
+ module Rdf
7
+ module V3
8
+ module Configuration
9
+ extend Glossarist::ContextConfiguration
10
+
11
+ CONTEXT_ID = :glossarist_rdf_v3
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Load shared infrastructure first
4
+ require_relative "ext"
5
+ require_relative "namespaces"
6
+ require_relative "relationships"
7
+ require_relative "localized_literal"
8
+
9
+ # V3 Configuration must be loaded before view classes are registered
10
+ require_relative "v3/configuration"
11
+
12
+ # Load all view class files (must precede V3 constant assignments)
13
+ require_relative "gloss_locality"
14
+ require_relative "gloss_reference"
15
+ require_relative "gloss_concept_source"
16
+ require_relative "gloss_detailed_definition"
17
+ require_relative "gloss_pronunciation"
18
+ require_relative "gloss_grammar_info"
19
+ require_relative "gloss_non_verbal_rep"
20
+ require_relative "gloss_concept_date"
21
+ require_relative "gloss_designation"
22
+ require_relative "gloss_localized_concept"
23
+ require_relative "gloss_concept"
24
+
25
+ module Glossarist
26
+ module Rdf
27
+ # V3 is the current (and only) RDF schema version.
28
+ #
29
+ # All RDF view classes produce v3 gloss ontology output:
30
+ # namespace URI: https://www.glossarist.org/ontologies/v3/
31
+ #
32
+ # Each version has its own Configuration module with a unique CONTEXT_ID
33
+ # so that V3 and (future) V4 classes are isolated in separate
34
+ # Lutaml::Model::GlobalContext registries.
35
+ #
36
+ # When v4 is added:
37
+ # - Create Rdf::V4::Configuration with CONTEXT_ID = :glossarist_rdf_v4
38
+ # - Create V4 view classes (standalone or inheriting from V3)
39
+ # - Register V4 classes in Rdf::V4::Configuration
40
+ # - Update ConceptToGlossTransform to support v4
41
+ # - V3 and V4 coexist — consumers choose which to use
42
+ module V3
43
+ # Namespace
44
+ GlossaristNamespace = Namespaces::GlossaristNamespace
45
+
46
+ # Single source of truth: add new view classes here once.
47
+ # Each entry is registered in the V3 type registry and
48
+ # re-exported as a V3:: constant.
49
+ VIEW_CLASS_NAMES = %i[
50
+ GlossLocality
51
+ GlossPronunciation
52
+ GlossGrammarInfo
53
+ GlossConceptDate
54
+ GlossReference
55
+ GlossConceptSource
56
+ GlossDetailedDefinition
57
+ GlossNonVerbalRep
58
+ GlossDesignation
59
+ GlossExpression
60
+ GlossAbbreviation
61
+ GlossSymbol
62
+ GlossLetterSymbol
63
+ GlossGraphicalSymbol
64
+ GlossPrefix
65
+ GlossSuffix
66
+ GlossLocalizedConcept
67
+ GlossConcept
68
+ GlossDocument
69
+ ].freeze
70
+
71
+ VIEW_CLASS_NAMES.each do |name|
72
+ klass = ::Glossarist::Rdf.const_get(name)
73
+ registry_id = name.to_s.gsub(/([A-Z])/) { |c| "_#{c.downcase}" }.sub(/^_/, "").to_sym
74
+ Configuration.register_model(klass, id: registry_id)
75
+ const_set(name, klass)
76
+ end
77
+ end
78
+ end
79
+ end
@@ -1,10 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # Load lutaml-model RDF extensions before any RDF view classes
4
+ require_relative "rdf/ext"
5
+
3
6
  module Glossarist
4
7
  module Rdf
5
8
  autoload :Namespaces, "#{__dir__}/rdf/namespaces"
6
9
  autoload :LocalizedLiteral, "#{__dir__}/rdf/localized_literal"
7
- autoload :SkosConcept, "#{__dir__}/rdf/skos_concept"
8
- autoload :SkosVocabulary, "#{__dir__}/rdf/skos_vocabulary"
10
+ autoload :Relationships, "#{__dir__}/rdf/relationships"
11
+ autoload :GlossLocality, "#{__dir__}/rdf/gloss_locality"
12
+ autoload :GlossCitation, "#{__dir__}/rdf/gloss_citation"
13
+ autoload :GlossConceptSource, "#{__dir__}/rdf/gloss_concept_source"
14
+ autoload :GlossDetailedDefinition, "#{__dir__}/rdf/gloss_detailed_definition"
15
+ autoload :GlossPronunciation, "#{__dir__}/rdf/gloss_pronunciation"
16
+ autoload :GlossGrammarInfo, "#{__dir__}/rdf/gloss_grammar_info"
17
+ autoload :GlossNonVerbalRep, "#{__dir__}/rdf/gloss_non_verbal_rep"
18
+ autoload :GlossConceptReference, "#{__dir__}/rdf/gloss_concept_reference"
19
+ autoload :GlossConceptDate, "#{__dir__}/rdf/gloss_concept_date"
20
+ autoload :GlossDesignation, "#{__dir__}/rdf/gloss_designation"
21
+ autoload :GlossExpression, "#{__dir__}/rdf/gloss_designation"
22
+ autoload :GlossAbbreviation, "#{__dir__}/rdf/gloss_designation"
23
+ autoload :GlossSymbol, "#{__dir__}/rdf/gloss_designation"
24
+ autoload :GlossLetterSymbol, "#{__dir__}/rdf/gloss_designation"
25
+ autoload :GlossGraphicalSymbol, "#{__dir__}/rdf/gloss_designation"
26
+ autoload :GlossLocalizedConcept, "#{__dir__}/rdf/gloss_localized_concept"
27
+ autoload :GlossConcept, "#{__dir__}/rdf/gloss_concept"
28
+ autoload :GlossDocument, "#{__dir__}/rdf/gloss_concept"
9
29
  end
10
30
  end
@@ -62,11 +62,7 @@ module Glossarist
62
62
  end
63
63
 
64
64
  def extract_from_localized_concept(l10n)
65
- texts = []
66
- l10n.data.definition&.each { |d| texts << d.content if d.content }
67
- l10n.data.notes&.each { |n| texts << n.content if n.content }
68
- l10n.data.examples&.each { |e| texts << e.content if e.content }
69
- texts.flat_map { |t| extract_from_text(t) }
65
+ l10n.text_content.flat_map { |t| extract_from_text(t) }
70
66
  end
71
67
 
72
68
  # Unified concept mention dispatcher.
@@ -159,6 +155,7 @@ module Glossarist
159
155
  concept.localizations.each do |l10n|
160
156
  Array(l10n.non_verb_rep).each do |nvr|
161
157
  next unless nvr.is_a?(NonVerbRep) && nvr.ref && !nvr.ref.strip.empty?
158
+
162
159
  refs << AssetReference.new(path: nvr.ref.strip)
163
160
  end
164
161
 
@@ -176,19 +173,23 @@ module Glossarist
176
173
  def extract_bib_refs_from_concept(concept)
177
174
  refs = []
178
175
  concept.localizations.each do |l10n|
179
- gather_all_sources(l10n).each do |source|
176
+ l10n.all_sources.each do |source|
180
177
  origin = source.origin
181
178
  next unless origin
182
179
 
183
- if origin.text && !origin.text.strip.empty?
184
- refs << BibliographicReference.new(anchor: origin.text)
180
+ ref = origin.ref
181
+ next unless ref
182
+
183
+ source_text = ref.source
184
+ if source_text && !source_text.strip.empty?
185
+ refs << BibliographicReference.new(anchor: source_text)
185
186
  end
186
187
 
187
- next unless origin.source && origin.id
188
+ next unless ref.source && ref.id
188
189
 
189
- key = "#{origin.source} #{origin.id}"
190
+ key = "#{ref.source} #{ref.id}"
190
191
  refs << BibliographicReference.new(anchor: key)
191
- refs << BibliographicReference.new(anchor: origin.id.to_s)
192
+ refs << BibliographicReference.new(anchor: ref.id.to_s)
192
193
  end
193
194
  end
194
195
  refs
@@ -283,13 +284,5 @@ module Glossarist
283
284
  register_identifier_resolver("urn:") do |ext, identifier, display|
284
285
  ext.resolve_generic_urn(identifier, display)
285
286
  end
286
-
287
- def gather_all_sources(l10n)
288
- sources = Array(l10n.data&.sources)
289
- sources += Array((l10n.data&.definition || []).flat_map(&:sources).compact)
290
- sources += Array((l10n.data&.notes || []).flat_map(&:sources).compact)
291
- sources += Array((l10n.data&.examples || []).flat_map(&:sources).compact)
292
- sources
293
- end
294
287
  end
295
288
  end
@@ -116,7 +116,7 @@ module Glossarist
116
116
 
117
117
  def infer_uri_prefix(package_or_concepts)
118
118
  case package_or_concepts
119
- when GcrPackage then package_or_concepts.metadata&.dig("uri_prefix")
119
+ when GcrPackage then package_or_concepts.metadata&.uri_prefix
120
120
  end
121
121
  end
122
122
 
@@ -128,7 +128,7 @@ module Glossarist
128
128
  next unless File.exist?(gcr_path)
129
129
 
130
130
  gcr = GcrPackage.load(gcr_path)
131
- prefix = pkg["uri_prefix"] || gcr.metadata&.dig("uri_prefix")
131
+ prefix = pkg["uri_prefix"] || gcr.metadata&.uri_prefix
132
132
  register_package(gcr, uri_prefix: prefix)
133
133
  end
134
134
 
@@ -145,7 +145,7 @@ module Glossarist
145
145
  def load_gcr_directory(dir)
146
146
  Dir.glob(File.join(dir, "*.gcr")).each do |gcr_path|
147
147
  pkg = GcrPackage.load(gcr_path)
148
- prefix = pkg.metadata&.dig("uri_prefix")
148
+ prefix = pkg.metadata&.uri_prefix
149
149
  register_package(pkg, uri_prefix: prefix)
150
150
  end
151
151
  end
@@ -5,20 +5,12 @@ module Glossarist
5
5
  attribute :content, :string
6
6
  attribute :type, :string,
7
7
  values: Glossarist::GlossaryDefinition::RELATED_CONCEPT_TYPES
8
- attribute :ref, Citation
8
+ attribute :ref, ConceptRef
9
9
 
10
10
  key_value do
11
11
  map :content, to: :content
12
12
  map :type, to: :type
13
- map :ref, with: { from: :ref_from_yaml, to: :ref_to_yaml }
14
- end
15
-
16
- def ref_to_yaml(model, doc)
17
- doc["ref"] = Citation.as_yaml(model.ref)["ref"] if model.ref
18
- end
19
-
20
- def ref_from_yaml(model, value)
21
- model.ref = Citation.of_yaml(value)
13
+ map :ref, to: :ref
22
14
  end
23
15
  end
24
16
  end