glossarist 2.8.11 → 2.8.13
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/config.yml +28 -4
- data/lib/glossarist/concept_reference.rb +1 -1
- data/lib/glossarist/dataset_register.rb +79 -0
- data/lib/glossarist/rdf/relationship_predicates.rb +7 -6
- data/lib/glossarist/validation/rules/dataset_context.rb +14 -0
- data/lib/glossarist/validation/rules/domain_ref_rule.rb +15 -0
- data/lib/glossarist/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 807c7a2aface582e6a1dfb6c4dd63f09c51d7429274597d8b7ee48d63282b7a9
|
|
4
|
+
data.tar.gz: 5af5e853bb00cec098806db6dbbe03b91dd5177a06388f4e9d79255dbf43cc2e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4020f1eabf8c0915ef3463e646abc71929d71ebe1fedbf0691ef008581b68c8c6913f9a908612fc2863e2c495bdc4ef643a4390ac6a2bf3dde4b7441b172bfdd
|
|
7
|
+
data.tar.gz: 69a9f82209f07c81bb8f7a68fdb1e556b3cc4d7180630f99f88f889ce84e81d37e18b9d643b8b35aaed4f0391f890841c51c468a0da4edc96ace4d22d1859f95
|
data/config.yml
CHANGED
|
@@ -39,10 +39,17 @@ designation:
|
|
|
39
39
|
|
|
40
40
|
related_concept:
|
|
41
41
|
type:
|
|
42
|
-
# Lifecycle (ISO 10241-1)
|
|
42
|
+
# Lifecycle (ISO 10241-1 / ISO 19135)
|
|
43
43
|
- deprecates
|
|
44
|
+
- deprecated_by
|
|
44
45
|
- supersedes
|
|
45
46
|
- superseded_by
|
|
47
|
+
- replaces
|
|
48
|
+
- replaced_by
|
|
49
|
+
- invalidates
|
|
50
|
+
- invalidated_by
|
|
51
|
+
- retires
|
|
52
|
+
- retired_by
|
|
46
53
|
# Hierarchical (ISO 10241-1 / ISO 25964)
|
|
47
54
|
- narrower
|
|
48
55
|
- broader
|
|
@@ -52,9 +59,13 @@ related_concept:
|
|
|
52
59
|
# Hierarchical sub-types — ISO 25964 partitive (BTP/NTP)
|
|
53
60
|
- broader_partitive
|
|
54
61
|
- narrower_partitive
|
|
62
|
+
- has_part
|
|
63
|
+
- is_part_of
|
|
55
64
|
# Hierarchical sub-types — ISO 25964 instantial (BTI/NTI)
|
|
56
65
|
- broader_instantial
|
|
57
66
|
- narrower_instantial
|
|
67
|
+
- instance_of
|
|
68
|
+
- has_instance
|
|
58
69
|
# Equivalence (ISO 10241-1 / ISO 25964 exactMatch / SKOS)
|
|
59
70
|
- equivalent
|
|
60
71
|
- exact_match
|
|
@@ -69,17 +80,30 @@ related_concept:
|
|
|
69
80
|
- contrast
|
|
70
81
|
# Associative (ISO 10241-1 / ISO 25964 RT / TBX crossReference)
|
|
71
82
|
- see
|
|
83
|
+
- references
|
|
72
84
|
# Associative sub-types (ISO 25964 / TBX)
|
|
73
85
|
- related_concept
|
|
74
86
|
- related_concept_broader
|
|
75
87
|
- related_concept_narrower
|
|
76
88
|
# Associative — spatial/temporal (ISO 25964 / TBX)
|
|
77
|
-
-
|
|
78
|
-
-
|
|
79
|
-
-
|
|
89
|
+
- sequentially_related
|
|
90
|
+
- spatially_related
|
|
91
|
+
- temporally_related
|
|
80
92
|
# Lexical (ISO 12620 / TBX)
|
|
81
93
|
- homograph
|
|
82
94
|
- false_friend
|
|
95
|
+
# Register management (ISO 19135)
|
|
96
|
+
- has_concept
|
|
97
|
+
- is_concept_of
|
|
98
|
+
- has_definition
|
|
99
|
+
- definition_of
|
|
100
|
+
- inherits
|
|
101
|
+
- inherited_by
|
|
102
|
+
# Versioning / definitional (ISO 19135)
|
|
103
|
+
- has_version
|
|
104
|
+
- version_of
|
|
105
|
+
- current_version
|
|
106
|
+
- current_version_of
|
|
83
107
|
|
|
84
108
|
iso12620:
|
|
85
109
|
term_type:
|
|
@@ -56,6 +56,37 @@ module Glossarist
|
|
|
56
56
|
nil
|
|
57
57
|
end
|
|
58
58
|
|
|
59
|
+
# Returns all ancestor section IDs for a given section, from immediate
|
|
60
|
+
# parent up to the root. Implements the cascading membership semantics:
|
|
61
|
+
# a concept in section "3.1.1" is also a member of "3.1" and "3".
|
|
62
|
+
# (concept-model: gloss:hasChildSection / gloss:hasParentSection are
|
|
63
|
+
# owl:TransitiveProperty.)
|
|
64
|
+
def section_ancestor_ids(target_id)
|
|
65
|
+
@section_parent_index ||= build_section_parent_index
|
|
66
|
+
@section_parent_index[target_id] || []
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Returns all section IDs that a concept belongs to, including
|
|
70
|
+
# transitive ancestor sections (cascading membership).
|
|
71
|
+
#
|
|
72
|
+
# Resolution order (concept-model convention):
|
|
73
|
+
# 1. Explicit domains[] entries with ref_type: "section"
|
|
74
|
+
# 2. Term-ID-prefix derivation fallback (longest registered prefix)
|
|
75
|
+
#
|
|
76
|
+
# @param concept [ManagedConcept, #data] the concept to resolve
|
|
77
|
+
# @return [Array<String>] section IDs, child-first then ancestors
|
|
78
|
+
def concept_section_ids(concept)
|
|
79
|
+
explicit = explicit_section_ids(concept)
|
|
80
|
+
ids = explicit.empty? ? derive_section_ids_from_id(concept) : explicit
|
|
81
|
+
ids.flat_map { |id| [id] + section_ancestor_ids(id) }.uniq
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Returns true if the given section ID exists anywhere in the section
|
|
85
|
+
# tree (root or descendant).
|
|
86
|
+
def section_exists?(target_id)
|
|
87
|
+
!section_by_id(target_id).nil?
|
|
88
|
+
end
|
|
89
|
+
|
|
59
90
|
def self.from_file(path)
|
|
60
91
|
return nil unless File.exist?(path)
|
|
61
92
|
|
|
@@ -68,5 +99,53 @@ module Glossarist
|
|
|
68
99
|
|
|
69
100
|
from_file(register_path)
|
|
70
101
|
end
|
|
102
|
+
|
|
103
|
+
private
|
|
104
|
+
|
|
105
|
+
# Build a flat child→[ancestor_ids] index by walking the section tree.
|
|
106
|
+
# Ancestors are ordered immediate-parent-first (closest section first).
|
|
107
|
+
# @example for sections [{id:"3", children:[{id:"3.1"}]}]:
|
|
108
|
+
# { "3.1" => ["3"] }
|
|
109
|
+
def build_section_parent_index
|
|
110
|
+
index = {}
|
|
111
|
+
walk_section_tree(sections, []) do |section, ancestors|
|
|
112
|
+
index[section.id] = ancestors.reverse unless ancestors.empty?
|
|
113
|
+
end
|
|
114
|
+
index
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def walk_section_tree(nodes, ancestors, &block)
|
|
118
|
+
Array(nodes).each do |section|
|
|
119
|
+
yield section, ancestors
|
|
120
|
+
child_ancestors = ancestors + [section.id]
|
|
121
|
+
walk_section_tree(section.children, child_ancestors, &block)
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def explicit_section_ids(concept)
|
|
126
|
+
domains = concept.respond_to?(:data) ? concept.data&.domains : nil
|
|
127
|
+
Array(domains).select { |d| d.ref_type == "section" }
|
|
128
|
+
.filter_map(&:concept_id)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Term-ID-prefix derivation: when a concept has no explicit section
|
|
132
|
+
# domains, derive section membership from its identifier using the
|
|
133
|
+
# longest registered section prefix.
|
|
134
|
+
# @example "103-01-01" with section "103" registered → ["103"]
|
|
135
|
+
def derive_section_ids_from_id(concept)
|
|
136
|
+
concept_id = concept.respond_to?(:data) ? concept.data&.id : nil
|
|
137
|
+
return [] unless concept_id
|
|
138
|
+
|
|
139
|
+
all_section_ids = collect_all_section_ids
|
|
140
|
+
all_section_ids.select { |sid| concept_id.start_with?("#{sid}-", "#{sid}.") }
|
|
141
|
+
.max_by(&:length)
|
|
142
|
+
&.then { |sid| [sid] } || []
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def collect_all_section_ids
|
|
146
|
+
ids = []
|
|
147
|
+
walk_section_tree(sections, []) { |section, _| ids << section.id }
|
|
148
|
+
ids
|
|
149
|
+
end
|
|
71
150
|
end
|
|
72
151
|
end
|
|
@@ -27,16 +27,17 @@ module Glossarist
|
|
|
27
27
|
related_match: [Namespaces::SkosNamespace, :relatedMatch],
|
|
28
28
|
see: [Namespaces::SkosNamespace, :related],
|
|
29
29
|
deprecates: [Namespaces::GlossaristNamespace, :deprecates],
|
|
30
|
+
deprecated_by: [Namespaces::GlossaristNamespace, :deprecatedBy],
|
|
30
31
|
supersedes: [Namespaces::GlossaristNamespace, :supersedes],
|
|
31
32
|
superseded_by: [Namespaces::GlossaristNamespace, :supersededBy],
|
|
32
33
|
compare: [Namespaces::GlossaristNamespace, :compares],
|
|
33
34
|
contrast: [Namespaces::GlossaristNamespace, :contrasts],
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
sequentially_related: [Namespaces::GlossaristNamespace,
|
|
36
|
+
:sequentiallyRelated],
|
|
37
|
+
spatially_related: [Namespaces::GlossaristNamespace,
|
|
38
|
+
:spatiallyRelated],
|
|
39
|
+
temporally_related: [Namespaces::GlossaristNamespace,
|
|
40
|
+
:temporallyRelated],
|
|
40
41
|
related_concept_broader: [Namespaces::GlossaristNamespace,
|
|
41
42
|
:relatedConceptBroader],
|
|
42
43
|
related_concept_narrower: [Namespaces::GlossaristNamespace,
|
|
@@ -31,6 +31,13 @@ module Glossarist
|
|
|
31
31
|
nil
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
+
# Loads the dataset's register.yaml as a DatasetRegister (with
|
|
35
|
+
# hierarchical sections, urn, ordering). Returns nil if no
|
|
36
|
+
# register.yaml exists or it uses the legacy format.
|
|
37
|
+
def dataset_register
|
|
38
|
+
@dataset_register ||= load_dataset_register
|
|
39
|
+
end
|
|
40
|
+
|
|
34
41
|
def bibliography_index
|
|
35
42
|
@bibliography_index ||= BibliographyIndex.build_from_concepts(
|
|
36
43
|
concepts, dataset_path: @path
|
|
@@ -98,6 +105,13 @@ module Glossarist
|
|
|
98
105
|
end
|
|
99
106
|
index
|
|
100
107
|
end
|
|
108
|
+
|
|
109
|
+
def load_dataset_register
|
|
110
|
+
reg_path = File.join(@path, "register.yaml")
|
|
111
|
+
return nil unless File.exist?(reg_path)
|
|
112
|
+
|
|
113
|
+
DatasetRegister.from_file(reg_path)
|
|
114
|
+
end
|
|
101
115
|
end
|
|
102
116
|
end
|
|
103
117
|
end
|
|
@@ -27,6 +27,21 @@ module Glossarist
|
|
|
27
27
|
suggestion: "Provide at least concept_id or urn for the domain reference",
|
|
28
28
|
)
|
|
29
29
|
end
|
|
30
|
+
|
|
31
|
+
next unless domain.ref_type == "section" && domain.concept_id
|
|
32
|
+
|
|
33
|
+
register = context.collection_context.dataset_register
|
|
34
|
+
next unless register
|
|
35
|
+
|
|
36
|
+
unless register.section_exists?(domain.concept_id)
|
|
37
|
+
issues << issue(
|
|
38
|
+
"domain #{idx + 1} references section '#{domain.concept_id}' " \
|
|
39
|
+
"that does not exist in register.yaml",
|
|
40
|
+
location: fname,
|
|
41
|
+
suggestion: "Add section '#{domain.concept_id}' to " \
|
|
42
|
+
"register.yaml or fix the reference",
|
|
43
|
+
)
|
|
44
|
+
end
|
|
30
45
|
end
|
|
31
46
|
|
|
32
47
|
issues
|
data/lib/glossarist/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: glossarist
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.8.
|
|
4
|
+
version: 2.8.13
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-06-
|
|
11
|
+
date: 2026-06-16 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: lutaml-model
|