glossarist 2.8.1 → 2.8.2
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/.rubocop.yml +1 -1
- data/CLAUDE.md +1 -1
- data/Gemfile +0 -1
- data/README.adoc +4 -1
- data/glossarist.gemspec +2 -1
- data/lib/glossarist/concept_document.rb +0 -2
- data/lib/glossarist/concept_manager.rb +0 -1
- data/lib/glossarist/concept_store.rb +94 -0
- data/lib/glossarist/managed_concept_data.rb +2 -0
- data/lib/glossarist/rdf/gloss_concept.rb +9 -3
- data/lib/glossarist/rdf/gloss_concept_date.rb +1 -1
- data/lib/glossarist/rdf/gloss_concept_source.rb +2 -2
- data/lib/glossarist/rdf/gloss_designation.rb +10 -4
- data/lib/glossarist/rdf/gloss_grammar_info.rb +2 -2
- data/lib/glossarist/rdf/gloss_localized_concept.rb +1 -1
- data/lib/glossarist/rdf/relationship_predicates.rb +72 -0
- data/lib/glossarist/rdf/v3/configuration.rb +0 -2
- data/lib/glossarist/rdf/v3.rb +4 -43
- data/lib/glossarist/rdf.rb +24 -22
- data/lib/glossarist/sts/importer.rb +0 -1
- data/lib/glossarist/transforms/concept_to_gloss_transform.rb +36 -64
- data/lib/glossarist/v2/configuration.rb +0 -2
- data/lib/glossarist/v2/managed_concept_data.rb +1 -0
- data/lib/glossarist/v2.rb +12 -12
- data/lib/glossarist/v3/configuration.rb +0 -2
- data/lib/glossarist/v3/managed_concept_data.rb +1 -0
- data/lib/glossarist/v3.rb +16 -16
- data/lib/glossarist/validation/bibliography_index.rb +9 -7
- data/lib/glossarist/validation/rules.rb +18 -49
- data/lib/glossarist/version.rb +1 -1
- data/lib/glossarist.rb +9 -11
- metadata +21 -16
- data/lib/glossarist/rdf/ext/jsonld_transform_ext.rb +0 -208
- data/lib/glossarist/rdf/ext/mapping_ext.rb +0 -37
- data/lib/glossarist/rdf/ext/mapping_rule_ext.rb +0 -27
- data/lib/glossarist/rdf/ext/member_rule_ext.rb +0 -34
- data/lib/glossarist/rdf/ext/turtle_transform_ext.rb +0 -222
- data/lib/glossarist/rdf/ext.rb +0 -39
- data/lib/glossarist/rdf/relationships.rb +0 -19
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f602beb2e985225705695343d1309f242117b6b59398f27b9b7d4966e2300c98
|
|
4
|
+
data.tar.gz: e5891cad0fd4efecac7140d007f36efe0a2f83609013a771ac02621199ba0306
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 97a81b187d34665f43c2800b3ac7636de9ae71b83c832bb9fdba0f5d9895089f6c3229ba80d38b3e9b0479ab71f16bf282b924c4ee1f9292059c250ade950cfe
|
|
7
|
+
data.tar.gz: 5d5c43b11134a5f072d80d99c5110471dae8145a4c3212aa9cce49ac1c491fd478f748cd4f57adf97a5c3212a41c7ca679c31a07b6018cda6ecf77cdef3fff64
|
data/.rubocop.yml
CHANGED
data/CLAUDE.md
CHANGED
|
@@ -24,7 +24,7 @@ All model classes use `Lutaml::Model::Serializable` for serialization.
|
|
|
24
24
|
- **`Concept`** (`concept.rb`) — base concept with `ConceptData` (definition, terms/designations, notes, examples, sources, dates, language_code). Parent of `LocalizedConcept`.
|
|
25
25
|
- **`LocalizedConcept`** (`localized_concept.rb`) — extends `Concept` with `classification`, `entry_status`, `review_type`.
|
|
26
26
|
- **`ConceptData`** (`concept_data.rb`) — the data payload inside `Concept`: definition, terms, examples, notes, sources, non_verb_rep (collection of `NonVerbRep` resource references), language_code (ISO 639), script (ISO 15924), system (ISO 24229 conversion system code). Uses `DetailedDefinition` collections for definition/examples/notes.
|
|
27
|
-
- **`ManagedConceptData`** (`managed_concept_data.rb`) — the data payload inside `ManagedConcept`: id, localized_concepts hash (lang_code => uuid), domains (ConceptReference collection —
|
|
27
|
+
- **`ManagedConceptData`** (`managed_concept_data.rb`) — the data payload inside `ManagedConcept`: id, localized_concepts hash (lang_code => uuid), domains (ConceptReference collection — terminological domain references), tags (string collection — organizational tags for grouping/filtering, not rendered as domains), sources.
|
|
28
28
|
|
|
29
29
|
### NonVerbRep (Resource Reference)
|
|
30
30
|
|
data/Gemfile
CHANGED
data/README.adoc
CHANGED
|
@@ -101,7 +101,8 @@ related:: Array of <<related-concept,RelatedConcept>>
|
|
|
101
101
|
status:: Enum for the normative status of the term.
|
|
102
102
|
dates:: Array of <<concept-date,ConceptDate>>
|
|
103
103
|
localized_concepts:: Hash of all localizations where keys are language codes and values are uuid of the localized concept.
|
|
104
|
-
domains:: Array of <<concept-reference,ConceptReference>> —
|
|
104
|
+
domains:: Array of <<concept-reference,ConceptReference>> — terminological domain references (subject areas, concept schemes) that this concept belongs to. Each domain is a typed reference (e.g. `{ concept_id: "103", ref_type: "domain" }`). These are rendered as `<domain>` in output.
|
|
105
|
+
tags:: Array of strings — organizational tags for grouping and filtering concepts (e.g. `["time-scale-units"]`). Tags are not rendered as terminological domains; they serve as metadata for document structure and retrieval.
|
|
105
106
|
localizations:: Hash of all localizations for this concept where keys are language codes and values are instances of <<localized-concept,LocalizedConcept>>.
|
|
106
107
|
|
|
107
108
|
There are two ways to initialize and populate a managed concept
|
|
@@ -121,6 +122,7 @@ concept = Glossarist::ManagedConcept.new({
|
|
|
121
122
|
"domains" => [
|
|
122
123
|
{ "concept_id" => "103", "ref_type" => "domain" },
|
|
123
124
|
],
|
|
125
|
+
"tags" => ["time-scales"],
|
|
124
126
|
},
|
|
125
127
|
})
|
|
126
128
|
----
|
|
@@ -134,6 +136,7 @@ concept.id = "123"
|
|
|
134
136
|
concept.data.domains = [
|
|
135
137
|
Glossarist::ConceptReference.new(concept_id: "103", ref_type: "domain"),
|
|
136
138
|
]
|
|
139
|
+
concept.data.tags = ["time-scales"]
|
|
137
140
|
concept.localizations = <Array of localized concepts or localized concept hashes>
|
|
138
141
|
----
|
|
139
142
|
|
data/glossarist.gemspec
CHANGED
|
@@ -31,7 +31,8 @@ Gem::Specification.new do |spec|
|
|
|
31
31
|
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
32
32
|
spec.require_paths = ["lib"]
|
|
33
33
|
|
|
34
|
-
spec.add_dependency "lutaml-model", "~> 0.8.
|
|
34
|
+
spec.add_dependency "lutaml-model", "~> 0.8.15"
|
|
35
|
+
spec.add_dependency "lutaml-store", "~> 0.1.1"
|
|
35
36
|
spec.add_dependency "paint", "~> 2.3"
|
|
36
37
|
spec.add_dependency "relaton", ">= 2.0.0", "< 3"
|
|
37
38
|
spec.add_dependency "rubyzip", ">= 2.3", "< 3"
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/store"
|
|
4
|
+
|
|
5
|
+
module Glossarist
|
|
6
|
+
class ConceptStore
|
|
7
|
+
# Custom serializer that preserves both uuid and identifier through
|
|
8
|
+
# YAML string storage. ManagedConcept's key_value mapping writes both
|
|
9
|
+
# uuid and identifier to the same "id" key, so a naive to_hash/from_hash
|
|
10
|
+
# round-trip loses one of them. Storing the YAML string preserves the
|
|
11
|
+
# model exactly, and explicit metadata fields let the store index and
|
|
12
|
+
# query by uuid/identifier without deserializing.
|
|
13
|
+
class Serializer
|
|
14
|
+
def serialize(model)
|
|
15
|
+
{
|
|
16
|
+
"_yaml" => model.to_yaml,
|
|
17
|
+
"_uuid" => model.uuid,
|
|
18
|
+
"_identifier" => model.identifier,
|
|
19
|
+
}
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def deserialize(data, model_class)
|
|
23
|
+
model = model_class.from_yaml(data["_yaml"])
|
|
24
|
+
model.assign_uuid(data["_uuid"]) if data["_uuid"]
|
|
25
|
+
model.identifier = data["_identifier"] if data["_identifier"]
|
|
26
|
+
model
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
attr_reader :db
|
|
31
|
+
|
|
32
|
+
def initialize(adapter: :memory)
|
|
33
|
+
@db = Lutaml::Store::DatabaseStore.new(
|
|
34
|
+
adapter: adapter,
|
|
35
|
+
models: [managed_concept_registration],
|
|
36
|
+
)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def save(concept)
|
|
40
|
+
db.save(concept)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def fetch(uuid)
|
|
44
|
+
db.fetch(model: ManagedConcept, uuid: uuid)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def fetch_by_id(identifier)
|
|
48
|
+
db.where(model: ManagedConcept, identifier: identifier).first
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def update(uuid, **attributes)
|
|
52
|
+
db.update(model: ManagedConcept, uuid: uuid, attributes: attributes)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def delete(uuid)
|
|
56
|
+
db.destroy(model: ManagedConcept, uuid: uuid)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def all
|
|
60
|
+
db.all(model: ManagedConcept)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def count
|
|
64
|
+
db.count(model: ManagedConcept)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def exists?(uuid)
|
|
68
|
+
db.exists?(model: ManagedConcept, uuid: uuid)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def clear
|
|
72
|
+
all.each { |concept| delete(concept.uuid) }
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def load_from_directory(path, format: :yaml, layout: :separate)
|
|
76
|
+
db.import_all(ManagedConcept, path: path, format: format, layout: layout)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def save_to_directory(path, format: :yaml, layout: :separate)
|
|
80
|
+
db.save_all(all, path: path, format: format, layout: layout)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
private
|
|
84
|
+
|
|
85
|
+
def managed_concept_registration
|
|
86
|
+
{
|
|
87
|
+
model: ManagedConcept,
|
|
88
|
+
key: :uuid,
|
|
89
|
+
dir: "concept",
|
|
90
|
+
serializer: Serializer.new,
|
|
91
|
+
}
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -6,6 +6,7 @@ module Glossarist
|
|
|
6
6
|
attribute :uri, :string
|
|
7
7
|
attribute :localized_concepts, :hash
|
|
8
8
|
attribute :domains, ConceptReference, collection: true
|
|
9
|
+
attribute :tags, :string, collection: true
|
|
9
10
|
attribute :sources, ConceptSource, collection: true
|
|
10
11
|
attribute :localizations, LocalizedConcept,
|
|
11
12
|
collection: Collections::LocalizationCollection,
|
|
@@ -19,6 +20,7 @@ module Glossarist
|
|
|
19
20
|
map %i[localized_concepts localizedConcepts], to: :localized_concepts
|
|
20
21
|
map %i[domains groups], to: :domains,
|
|
21
22
|
with: { from: :domains_from_yaml, to: :domains_to_yaml }
|
|
23
|
+
map :tags, to: :tags
|
|
22
24
|
map :sources, to: :sources
|
|
23
25
|
map :localizations, to: :localizations,
|
|
24
26
|
with: { from: :localizations_from_yaml, to: :localizations_to_yaml }
|
|
@@ -5,8 +5,6 @@ require "lutaml/model"
|
|
|
5
5
|
module Glossarist
|
|
6
6
|
module Rdf
|
|
7
7
|
class GlossConcept < Lutaml::Model::Serializable
|
|
8
|
-
include Relationships
|
|
9
|
-
|
|
10
8
|
attribute :identifier, :string
|
|
11
9
|
attribute :status, :string
|
|
12
10
|
attribute :localizations, GlossLocalizedConcept, collection: true
|
|
@@ -14,6 +12,10 @@ module Glossarist
|
|
|
14
12
|
attribute :domains, GlossConceptReference, collection: true
|
|
15
13
|
attribute :dates, GlossConceptDate, collection: true
|
|
16
14
|
|
|
15
|
+
RelationshipPredicates::CONCEPT_REL_PREDICATES.each_key do |type|
|
|
16
|
+
attribute :"#{type}_targets", :string, collection: true
|
|
17
|
+
end
|
|
18
|
+
|
|
17
19
|
rdf do
|
|
18
20
|
namespace Namespaces::GlossaristNamespace,
|
|
19
21
|
Namespaces::SkosNamespace,
|
|
@@ -27,7 +29,7 @@ module Glossarist
|
|
|
27
29
|
types "gloss:Concept", "skos:Concept"
|
|
28
30
|
|
|
29
31
|
predicate :identifier, namespace: Namespaces::GlossaristNamespace, to: :identifier
|
|
30
|
-
predicate :hasStatus, namespace: Namespaces::GlossaristNamespace, to: :status,
|
|
32
|
+
predicate :hasStatus, namespace: Namespaces::GlossaristNamespace, to: :status, uri_reference: true
|
|
31
33
|
|
|
32
34
|
members :localizations,
|
|
33
35
|
link: "gloss:hasLocalization"
|
|
@@ -37,6 +39,10 @@ module Glossarist
|
|
|
37
39
|
link: "gloss:hasDomain"
|
|
38
40
|
members :dates,
|
|
39
41
|
link: "gloss:hasDate"
|
|
42
|
+
|
|
43
|
+
RelationshipPredicates::CONCEPT_REL_PREDICATES.each do |type, (ns, name)|
|
|
44
|
+
predicate name, namespace: ns, to: :"#{type}_targets", uri_reference: true
|
|
45
|
+
end
|
|
40
46
|
end
|
|
41
47
|
end
|
|
42
48
|
|
|
@@ -17,7 +17,7 @@ module Glossarist
|
|
|
17
17
|
types "gloss:ConceptDate"
|
|
18
18
|
|
|
19
19
|
predicate :dateValue, namespace: Namespaces::GlossaristNamespace, to: :date_value
|
|
20
|
-
predicate :dateType, namespace: Namespaces::GlossaristNamespace, to: :date_type,
|
|
20
|
+
predicate :dateType, namespace: Namespaces::GlossaristNamespace, to: :date_type, uri_reference: true
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
23
|
end
|
|
@@ -17,8 +17,8 @@ module Glossarist
|
|
|
17
17
|
|
|
18
18
|
types "gloss:ConceptSource"
|
|
19
19
|
|
|
20
|
-
predicate :sourceStatus, namespace: Namespaces::GlossaristNamespace, to: :status,
|
|
21
|
-
predicate :sourceType, namespace: Namespaces::GlossaristNamespace, to: :type,
|
|
20
|
+
predicate :sourceStatus, namespace: Namespaces::GlossaristNamespace, to: :status, uri_reference: true
|
|
21
|
+
predicate :sourceType, namespace: Namespaces::GlossaristNamespace, to: :type, uri_reference: true
|
|
22
22
|
predicate :modification, namespace: Namespaces::GlossaristNamespace, to: :modification
|
|
23
23
|
|
|
24
24
|
members :origin, link: "gloss:sourceOrigin"
|
|
@@ -6,8 +6,8 @@ module Glossarist
|
|
|
6
6
|
module Rdf
|
|
7
7
|
COMMON_DESIGNATION_PREDICATES = lambda { |dsl|
|
|
8
8
|
dsl.predicate :literalForm, namespace: Namespaces::SkosxlNamespace, to: :designation
|
|
9
|
-
dsl.predicate :normativeStatus, namespace: Namespaces::GlossaristNamespace, to: :normative_status,
|
|
10
|
-
dsl.predicate :hasTermType, namespace: Namespaces::GlossaristNamespace, to: :term_type,
|
|
9
|
+
dsl.predicate :normativeStatus, namespace: Namespaces::GlossaristNamespace, to: :normative_status, uri_reference: true
|
|
10
|
+
dsl.predicate :hasTermType, namespace: Namespaces::GlossaristNamespace, to: :term_type, uri_reference: true
|
|
11
11
|
dsl.predicate :isInternational, namespace: Namespaces::GlossaristNamespace, to: :international
|
|
12
12
|
dsl.predicate :isAbsent, namespace: Namespaces::GlossaristNamespace, to: :absent
|
|
13
13
|
dsl.predicate :geographicalArea, namespace: Namespaces::GlossaristNamespace, to: :language
|
|
@@ -16,6 +16,10 @@ module Glossarist
|
|
|
16
16
|
dsl.predicate :conversionSystem, namespace: Namespaces::GlossaristNamespace, to: :system
|
|
17
17
|
dsl.members :pronunciations, link: "gloss:hasPronunciation"
|
|
18
18
|
dsl.members :sources
|
|
19
|
+
|
|
20
|
+
RelationshipPredicates::DESIGNATION_REL_PREDICATES.each do |type, (ns, name)|
|
|
21
|
+
dsl.predicate name, namespace: ns, to: :"#{type}_targets", uri_reference: true
|
|
22
|
+
end
|
|
19
23
|
}.freeze
|
|
20
24
|
|
|
21
25
|
DESIGNATION_NAMESPACES = [
|
|
@@ -27,8 +31,6 @@ module Glossarist
|
|
|
27
31
|
].freeze
|
|
28
32
|
|
|
29
33
|
class GlossDesignation < Lutaml::Model::Serializable
|
|
30
|
-
include Relationships
|
|
31
|
-
|
|
32
34
|
attribute :designation, :string
|
|
33
35
|
attribute :normative_status, :string
|
|
34
36
|
attribute :type, :string
|
|
@@ -44,6 +46,10 @@ module Glossarist
|
|
|
44
46
|
attribute :pronunciations, GlossPronunciation, collection: true
|
|
45
47
|
attribute :sources, GlossConceptSource, collection: true
|
|
46
48
|
|
|
49
|
+
RelationshipPredicates::DESIGNATION_REL_PREDICATES.each_key do |type|
|
|
50
|
+
attribute :"#{type}_targets", :string, collection: true
|
|
51
|
+
end
|
|
52
|
+
|
|
47
53
|
rdf do
|
|
48
54
|
namespace(*DESIGNATION_NAMESPACES)
|
|
49
55
|
|
|
@@ -19,8 +19,8 @@ module Glossarist
|
|
|
19
19
|
|
|
20
20
|
types "gloss:GrammarInfo"
|
|
21
21
|
|
|
22
|
-
predicate :gender, namespace: Namespaces::GlossaristNamespace, to: :gender,
|
|
23
|
-
predicate :number, namespace: Namespaces::GlossaristNamespace, to: :number,
|
|
22
|
+
predicate :gender, namespace: Namespaces::GlossaristNamespace, to: :gender, uri_reference: true
|
|
23
|
+
predicate :number, namespace: Namespaces::GlossaristNamespace, to: :number, uri_reference: true
|
|
24
24
|
predicate :isNoun, namespace: Namespaces::GlossaristNamespace, to: :noun?
|
|
25
25
|
predicate :isVerb, namespace: Namespaces::GlossaristNamespace, to: :verb?
|
|
26
26
|
predicate :isAdjective, namespace: Namespaces::GlossaristNamespace, to: :adjective?
|
|
@@ -33,7 +33,7 @@ module Glossarist
|
|
|
33
33
|
types "gloss:LocalizedConcept", "skos:Concept"
|
|
34
34
|
|
|
35
35
|
predicate :language, namespace: Namespaces::DctermsNamespace, to: :language_code
|
|
36
|
-
predicate :hasEntryStatus, namespace: Namespaces::GlossaristNamespace, to: :entry_status,
|
|
36
|
+
predicate :hasEntryStatus, namespace: Namespaces::GlossaristNamespace, to: :entry_status, uri_reference: true
|
|
37
37
|
predicate :domain, namespace: Namespaces::GlossaristNamespace, to: :domain
|
|
38
38
|
predicate :release, namespace: Namespaces::GlossaristNamespace, to: :release
|
|
39
39
|
predicate :lineageSimilarity, namespace: Namespaces::GlossaristNamespace, to: :lineage_similarity
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Glossarist
|
|
4
|
+
module Rdf
|
|
5
|
+
# Canonical data-driven maps for relationship predicates.
|
|
6
|
+
#
|
|
7
|
+
# Each entry maps a relationship type symbol to [namespace_module, predicate_name].
|
|
8
|
+
# These maps drive:
|
|
9
|
+
# 1. Attribute declarations in RDF view classes (one typed collection per predicate)
|
|
10
|
+
# 2. RDF predicate mappings with uri_reference: true
|
|
11
|
+
# 3. Transform grouping logic in ConceptToGlossTransform
|
|
12
|
+
module RelationshipPredicates
|
|
13
|
+
CONCEPT_REL_PREDICATES = {
|
|
14
|
+
broader: [Namespaces::SkosNamespace, :broader],
|
|
15
|
+
narrower: [Namespaces::SkosNamespace, :narrower],
|
|
16
|
+
broader_generic: [Namespaces::IsoThesNamespace, :broaderGeneric],
|
|
17
|
+
narrower_generic: [Namespaces::IsoThesNamespace, :narrowerGeneric],
|
|
18
|
+
broader_partitive: [Namespaces::IsoThesNamespace, :broaderPartitive],
|
|
19
|
+
narrower_partitive: [Namespaces::IsoThesNamespace, :narrowerPartitive],
|
|
20
|
+
broader_instantial: [Namespaces::IsoThesNamespace, :broaderInstantial],
|
|
21
|
+
narrower_instantial: [Namespaces::IsoThesNamespace, :narrowerInstantial],
|
|
22
|
+
equivalent: [Namespaces::SkosNamespace, :exactMatch],
|
|
23
|
+
close_match: [Namespaces::SkosNamespace, :closeMatch],
|
|
24
|
+
broad_match: [Namespaces::SkosNamespace, :broadMatch],
|
|
25
|
+
narrow_match: [Namespaces::SkosNamespace, :narrowMatch],
|
|
26
|
+
related_match: [Namespaces::SkosNamespace, :relatedMatch],
|
|
27
|
+
see: [Namespaces::SkosNamespace, :related],
|
|
28
|
+
deprecates: [Namespaces::GlossaristNamespace, :deprecates],
|
|
29
|
+
supersedes: [Namespaces::GlossaristNamespace, :supersedes],
|
|
30
|
+
superseded_by: [Namespaces::GlossaristNamespace, :supersededBy],
|
|
31
|
+
compare: [Namespaces::GlossaristNamespace, :compares],
|
|
32
|
+
contrast: [Namespaces::GlossaristNamespace, :contrasts],
|
|
33
|
+
sequentially_related_concept: [Namespaces::GlossaristNamespace, :sequentiallyRelated],
|
|
34
|
+
spatially_related_concept: [Namespaces::GlossaristNamespace, :spatiallyRelated],
|
|
35
|
+
temporally_related_concept: [Namespaces::GlossaristNamespace, :temporallyRelated],
|
|
36
|
+
related_concept_broader: [Namespaces::GlossaristNamespace, :relatedConceptBroader],
|
|
37
|
+
related_concept_narrower: [Namespaces::GlossaristNamespace, :relatedConceptNarrower],
|
|
38
|
+
}.freeze
|
|
39
|
+
|
|
40
|
+
DESIGNATION_REL_PREDICATES = {
|
|
41
|
+
homograph: [Namespaces::GlossaristNamespace, :hasHomograph],
|
|
42
|
+
false_friend: [Namespaces::GlossaristNamespace, :hasFalseFriend],
|
|
43
|
+
abbreviated_form_for: [Namespaces::GlossaristNamespace, :abbreviatedFormFor],
|
|
44
|
+
short_form_for: [Namespaces::GlossaristNamespace, :shortFormFor],
|
|
45
|
+
}.freeze
|
|
46
|
+
|
|
47
|
+
ALL_REL_PREDICATES = CONCEPT_REL_PREDICATES.merge(DESIGNATION_REL_PREDICATES).freeze
|
|
48
|
+
|
|
49
|
+
def self.related_targets_by_type(related_concepts, predicate_map)
|
|
50
|
+
targets = group_targets(related_concepts, predicate_map)
|
|
51
|
+
predicate_map.each_key.to_h do |type|
|
|
52
|
+
[:"#{type}_targets", targets[:"#{type}_targets"] || []]
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def self.group_targets(related_concepts, predicate_map)
|
|
57
|
+
valid = valid_related(related_concepts, predicate_map)
|
|
58
|
+
valid
|
|
59
|
+
.group_by { |rc| rc.type.to_sym }
|
|
60
|
+
.transform_values { |rcs| rcs.map { |rc| "concept/#{rc.ref.id}" } }
|
|
61
|
+
.transform_keys { |type| :"#{type}_targets" }
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def self.valid_related(related_concepts, predicate_map)
|
|
65
|
+
Array(related_concepts).select do |rc|
|
|
66
|
+
rc.ref&.id && predicate_map.key?(rc.type.to_sym)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
private_class_method :group_targets, :valid_related
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
data/lib/glossarist/rdf/v3.rb
CHANGED
|
@@ -1,51 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
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
3
|
module Glossarist
|
|
26
4
|
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
5
|
module V3
|
|
43
|
-
|
|
44
|
-
GlossaristNamespace = Namespaces::GlossaristNamespace
|
|
6
|
+
autoload :Configuration, "glossarist/rdf/v3/configuration"
|
|
45
7
|
|
|
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
8
|
VIEW_CLASS_NAMES = %i[
|
|
50
9
|
GlossLocality
|
|
51
10
|
GlossPronunciation
|
|
@@ -70,7 +29,9 @@ module Glossarist
|
|
|
70
29
|
|
|
71
30
|
VIEW_CLASS_NAMES.each do |name|
|
|
72
31
|
klass = ::Glossarist::Rdf.const_get(name)
|
|
73
|
-
registry_id = name.to_s
|
|
32
|
+
registry_id = name.to_s
|
|
33
|
+
.gsub(/([A-Z])/) { |c| "_#{c.downcase}" }
|
|
34
|
+
.sub(/^_/, "").to_sym
|
|
74
35
|
Configuration.register_model(klass, id: registry_id)
|
|
75
36
|
const_set(name, klass)
|
|
76
37
|
end
|
data/lib/glossarist/rdf.rb
CHANGED
|
@@ -1,30 +1,32 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
require "lutaml/rdf"
|
|
4
|
+
require "lutaml/turtle"
|
|
5
|
+
require "lutaml/jsonld"
|
|
5
6
|
|
|
6
7
|
module Glossarist
|
|
7
8
|
module Rdf
|
|
8
|
-
autoload :Namespaces,
|
|
9
|
-
autoload :LocalizedLiteral,
|
|
10
|
-
autoload :
|
|
11
|
-
autoload :GlossLocality,
|
|
12
|
-
autoload :GlossCitation,
|
|
13
|
-
autoload :GlossConceptSource,
|
|
9
|
+
autoload :Namespaces, "#{__dir__}/rdf/namespaces"
|
|
10
|
+
autoload :LocalizedLiteral, "#{__dir__}/rdf/localized_literal"
|
|
11
|
+
autoload :RelationshipPredicates, "#{__dir__}/rdf/relationship_predicates"
|
|
12
|
+
autoload :GlossLocality, "#{__dir__}/rdf/gloss_locality"
|
|
13
|
+
autoload :GlossCitation, "#{__dir__}/rdf/gloss_citation"
|
|
14
|
+
autoload :GlossConceptSource, "#{__dir__}/rdf/gloss_concept_source"
|
|
14
15
|
autoload :GlossDetailedDefinition, "#{__dir__}/rdf/gloss_detailed_definition"
|
|
15
|
-
autoload :GlossPronunciation,
|
|
16
|
-
autoload :GlossGrammarInfo,
|
|
17
|
-
autoload :GlossNonVerbalRep,
|
|
18
|
-
autoload :GlossConceptReference,
|
|
19
|
-
autoload :GlossConceptDate,
|
|
20
|
-
autoload :GlossDesignation,
|
|
21
|
-
autoload :GlossExpression,
|
|
22
|
-
autoload :GlossAbbreviation,
|
|
23
|
-
autoload :GlossSymbol,
|
|
24
|
-
autoload :GlossLetterSymbol,
|
|
25
|
-
autoload :GlossGraphicalSymbol,
|
|
26
|
-
autoload :GlossLocalizedConcept,
|
|
27
|
-
autoload :GlossConcept,
|
|
28
|
-
autoload :GlossDocument,
|
|
16
|
+
autoload :GlossPronunciation, "#{__dir__}/rdf/gloss_pronunciation"
|
|
17
|
+
autoload :GlossGrammarInfo, "#{__dir__}/rdf/gloss_grammar_info"
|
|
18
|
+
autoload :GlossNonVerbalRep, "#{__dir__}/rdf/gloss_non_verbal_rep"
|
|
19
|
+
autoload :GlossConceptReference, "#{__dir__}/rdf/gloss_concept_reference"
|
|
20
|
+
autoload :GlossConceptDate, "#{__dir__}/rdf/gloss_concept_date"
|
|
21
|
+
autoload :GlossDesignation, "#{__dir__}/rdf/gloss_designation"
|
|
22
|
+
autoload :GlossExpression, "#{__dir__}/rdf/gloss_designation"
|
|
23
|
+
autoload :GlossAbbreviation, "#{__dir__}/rdf/gloss_designation"
|
|
24
|
+
autoload :GlossSymbol, "#{__dir__}/rdf/gloss_designation"
|
|
25
|
+
autoload :GlossLetterSymbol, "#{__dir__}/rdf/gloss_designation"
|
|
26
|
+
autoload :GlossGraphicalSymbol, "#{__dir__}/rdf/gloss_designation"
|
|
27
|
+
autoload :GlossLocalizedConcept, "#{__dir__}/rdf/gloss_localized_concept"
|
|
28
|
+
autoload :GlossConcept, "#{__dir__}/rdf/gloss_concept"
|
|
29
|
+
autoload :GlossDocument, "#{__dir__}/rdf/gloss_concept"
|
|
30
|
+
autoload :V3, "#{__dir__}/rdf/v3"
|
|
29
31
|
end
|
|
30
32
|
end
|