glossarist 2.6.5 → 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 (155) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/release.yml +1 -4
  3. data/.rubocop_todo.yml +53 -2
  4. data/CLAUDE.md +27 -2
  5. data/README.adoc +532 -56
  6. data/config.yml +68 -1
  7. data/glossarist.gemspec +2 -0
  8. data/lib/glossarist/citation.rb +26 -123
  9. data/lib/glossarist/cli/compare_command.rb +106 -0
  10. data/lib/glossarist/cli/export_command.rb +11 -14
  11. data/lib/glossarist/cli/validate_command.rb +111 -20
  12. data/lib/glossarist/cli.rb +18 -0
  13. data/lib/glossarist/collections/bibliography_collection.rb +4 -2
  14. data/lib/glossarist/collections/localization_collection.rb +2 -0
  15. data/lib/glossarist/comparison_result.rb +35 -0
  16. data/lib/glossarist/concept.rb +1 -1
  17. data/lib/glossarist/concept_collector.rb +44 -0
  18. data/lib/glossarist/concept_comparator.rb +72 -0
  19. data/lib/glossarist/concept_data.rb +20 -0
  20. data/lib/glossarist/concept_diff.rb +15 -0
  21. data/lib/glossarist/concept_document.rb +11 -0
  22. data/lib/glossarist/concept_manager.rb +19 -5
  23. data/lib/glossarist/concept_ref.rb +13 -0
  24. data/lib/glossarist/concept_reference.rb +12 -19
  25. data/lib/glossarist/concept_validator.rb +6 -1
  26. data/lib/glossarist/context_configuration.rb +90 -0
  27. data/lib/glossarist/dataset_validator.rb +8 -4
  28. data/lib/glossarist/designation/abbreviation.rb +0 -2
  29. data/lib/glossarist/designation/base.rb +21 -1
  30. data/lib/glossarist/designation/expression.rb +3 -0
  31. data/lib/glossarist/designation/letter_symbol.rb +0 -4
  32. data/lib/glossarist/designation/prefix.rb +17 -0
  33. data/lib/glossarist/designation/suffix.rb +17 -0
  34. data/lib/glossarist/designation/symbol.rb +0 -2
  35. data/lib/glossarist/gcr_metadata.rb +7 -14
  36. data/lib/glossarist/gcr_package.rb +35 -23
  37. data/lib/glossarist/gcr_validator.rb +38 -17
  38. data/lib/glossarist/glossary_definition.rb +5 -0
  39. data/lib/glossarist/localized_concept.rb +8 -0
  40. data/lib/glossarist/managed_concept.rb +39 -6
  41. data/lib/glossarist/managed_concept_data.rb +22 -2
  42. data/lib/glossarist/non_verb_rep.rb +21 -6
  43. data/lib/glossarist/pronunciation.rb +32 -0
  44. data/lib/glossarist/rdf/ext/jsonld_transform_ext.rb +208 -0
  45. data/lib/glossarist/rdf/ext/mapping_ext.rb +37 -0
  46. data/lib/glossarist/rdf/ext/mapping_rule_ext.rb +27 -0
  47. data/lib/glossarist/rdf/ext/member_rule_ext.rb +34 -0
  48. data/lib/glossarist/rdf/ext/turtle_transform_ext.rb +222 -0
  49. data/lib/glossarist/rdf/ext.rb +39 -0
  50. data/lib/glossarist/rdf/gloss_citation.rb +36 -0
  51. data/lib/glossarist/rdf/gloss_concept.rb +58 -0
  52. data/lib/glossarist/rdf/gloss_concept_date.rb +24 -0
  53. data/lib/glossarist/rdf/gloss_concept_reference.rb +29 -0
  54. data/lib/glossarist/rdf/gloss_concept_source.rb +37 -0
  55. data/lib/glossarist/rdf/gloss_designation.rb +146 -0
  56. data/lib/glossarist/rdf/gloss_detailed_definition.rb +24 -0
  57. data/lib/glossarist/rdf/gloss_grammar_info.rb +57 -0
  58. data/lib/glossarist/rdf/gloss_locality.rb +25 -0
  59. data/lib/glossarist/rdf/gloss_localized_concept.rb +67 -0
  60. data/lib/glossarist/rdf/gloss_non_verbal_rep.rb +31 -0
  61. data/lib/glossarist/rdf/gloss_pronunciation.rb +32 -0
  62. data/lib/glossarist/rdf/gloss_reference.rb +55 -0
  63. data/lib/glossarist/rdf/namespaces/glossarist_namespace.rb +12 -0
  64. data/lib/glossarist/rdf/namespaces/iso_thes_namespace.rb +12 -0
  65. data/lib/glossarist/rdf/namespaces/owl_namespace.rb +12 -0
  66. data/lib/glossarist/rdf/namespaces/prov_namespace.rb +12 -0
  67. data/lib/glossarist/rdf/namespaces/rdf_namespace.rb +12 -0
  68. data/lib/glossarist/rdf/namespaces/skosxl_namespace.rb +12 -0
  69. data/lib/glossarist/rdf/namespaces.rb +8 -2
  70. data/lib/glossarist/rdf/relationships.rb +19 -0
  71. data/lib/glossarist/rdf/v3/configuration.rb +15 -0
  72. data/lib/glossarist/rdf/v3.rb +79 -0
  73. data/lib/glossarist/rdf.rb +22 -2
  74. data/lib/glossarist/reference_extractor.rb +15 -24
  75. data/lib/glossarist/reference_resolver.rb +3 -3
  76. data/lib/glossarist/related_concept.rb +2 -10
  77. data/lib/glossarist/schema_migration.rb +39 -0
  78. data/lib/glossarist/sts/term_mapper.rb +2 -2
  79. data/lib/glossarist/transforms/concept_to_gloss_transform.rb +355 -0
  80. data/lib/glossarist/transforms.rb +2 -2
  81. data/lib/glossarist/urn_resolver.rb +13 -1
  82. data/lib/glossarist/v1/concept.rb +18 -11
  83. data/lib/glossarist/v2/citation.rb +36 -0
  84. data/lib/glossarist/v2/concept_data.rb +46 -0
  85. data/lib/glossarist/v2/concept_document.rb +18 -0
  86. data/lib/glossarist/v2/concept_ref.rb +8 -0
  87. data/lib/glossarist/v2/concept_source.rb +16 -0
  88. data/lib/glossarist/v2/configuration.rb +13 -0
  89. data/lib/glossarist/v2/detailed_definition.rb +14 -0
  90. data/lib/glossarist/v2/localized_concept.rb +9 -0
  91. data/lib/glossarist/v2/managed_concept.rb +25 -0
  92. data/lib/glossarist/v2/managed_concept_data.rb +49 -0
  93. data/lib/glossarist/v2/related_concept.rb +15 -0
  94. data/lib/glossarist/v2.rb +28 -0
  95. data/lib/glossarist/v3/bibliography_entry.rb +19 -0
  96. data/lib/glossarist/v3/bibliography_file.rb +27 -0
  97. data/lib/glossarist/v3/citation.rb +30 -0
  98. data/lib/glossarist/v3/concept_data.rb +46 -0
  99. data/lib/glossarist/v3/concept_document.rb +18 -0
  100. data/lib/glossarist/v3/concept_ref.rb +8 -0
  101. data/lib/glossarist/v3/concept_source.rb +16 -0
  102. data/lib/glossarist/v3/configuration.rb +13 -0
  103. data/lib/glossarist/v3/detailed_definition.rb +14 -0
  104. data/lib/glossarist/v3/image_entry.rb +21 -0
  105. data/lib/glossarist/v3/image_file.rb +31 -0
  106. data/lib/glossarist/v3/localized_concept.rb +9 -0
  107. data/lib/glossarist/v3/managed_concept.rb +26 -0
  108. data/lib/glossarist/v3/managed_concept_data.rb +34 -0
  109. data/lib/glossarist/v3/related_concept.rb +15 -0
  110. data/lib/glossarist/v3.rb +36 -0
  111. data/lib/glossarist/validation/asset_index.rb +4 -3
  112. data/lib/glossarist/validation/bibliography_index.rb +61 -30
  113. data/lib/glossarist/validation/rules/asciidoc_xref_rule.rb +2 -15
  114. data/lib/glossarist/validation/rules/authoritative_source_rule.rb +2 -15
  115. data/lib/glossarist/validation/rules/base.rb +5 -0
  116. data/lib/glossarist/validation/rules/bibliography_yaml_rule.rb +2 -3
  117. data/lib/glossarist/validation/rules/citation_completeness_rule.rb +5 -27
  118. data/lib/glossarist/validation/rules/dataset_context.rb +8 -3
  119. data/lib/glossarist/validation/rules/date_validity_rule.rb +1 -1
  120. data/lib/glossarist/validation/rules/designation_status_rule.rb +0 -1
  121. data/lib/glossarist/validation/rules/designation_type_rule.rb +1 -5
  122. data/lib/glossarist/validation/rules/domain_ref_rule.rb +37 -0
  123. data/lib/glossarist/validation/rules/domain_target_rule.rb +56 -0
  124. data/lib/glossarist/validation/rules/gcr_context.rb +12 -13
  125. data/lib/glossarist/validation/rules/image_reference_rule.rb +2 -17
  126. data/lib/glossarist/validation/rules/locality_completeness_rule.rb +58 -0
  127. data/lib/glossarist/validation/rules/localization_consistency_rule.rb +72 -0
  128. data/lib/glossarist/validation/rules/localization_presence_rule.rb +1 -1
  129. data/lib/glossarist/validation/rules/model_validity_rule.rb +71 -0
  130. data/lib/glossarist/validation/rules/orphaned_bibliography_rule.rb +1 -13
  131. data/lib/glossarist/validation/rules/orphaned_images_rule.rb +16 -11
  132. data/lib/glossarist/validation/rules/ref_shape_rule.rb +68 -0
  133. data/lib/glossarist/validation/rules/related_concept_cycle_rule.rb +1 -3
  134. data/lib/glossarist/validation/rules/related_concept_symmetry_rule.rb +1 -3
  135. data/lib/glossarist/validation/rules/related_concept_target_rule.rb +64 -0
  136. data/lib/glossarist/validation/rules/schema_version_rule.rb +41 -0
  137. data/lib/glossarist/validation/rules/source_type_rule.rb +1 -15
  138. data/lib/glossarist/validation/rules/source_urn_format_rule.rb +65 -0
  139. data/lib/glossarist/validation/rules/uuid_format_rule.rb +33 -0
  140. data/lib/glossarist/validation/rules.rb +10 -43
  141. data/lib/glossarist/validation/validation_issue.rb +14 -11
  142. data/lib/glossarist/validation_result.rb +12 -22
  143. data/lib/glossarist/version.rb +1 -1
  144. data/lib/glossarist.rb +10 -0
  145. data/memory/project-status.md +43 -0
  146. data/scripts/migrate_dataset.rb +180 -0
  147. data/scripts/migrate_isotc204_to_v3.rb +134 -0
  148. data/scripts/migrate_isotc211_to_v3.rb +153 -0
  149. data/scripts/migrate_osgeo_to_v3.rb +155 -0
  150. data/scripts/upgrade_dataset_to_v3.rb +47 -0
  151. metadata +112 -6
  152. data/TODO.integration/01-gcr-package-cli.md +0 -180
  153. data/lib/glossarist/rdf/skos_concept.rb +0 -43
  154. data/lib/glossarist/rdf/skos_vocabulary.rb +0 -25
  155. data/lib/glossarist/transforms/concept_to_skos_transform.rb +0 -131
@@ -0,0 +1,155 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Migration script for osgeo-glossary: adds v3 fields to existing concepts.
5
+ #
6
+ # Adds:
7
+ # - status: "valid" at managed concept level
8
+ # - date_accepted at managed concept level (set to 2011-01-01 as earliest
9
+ # known publication date for the OSGeo Lexicon)
10
+ # - domains for concepts with identifiable ISO standard sources
11
+ # - related (broader to domain) for those concepts
12
+ # - Creates domain concepts for identified ISO standards
13
+ #
14
+ # Idempotent: safe to run multiple times.
15
+ #
16
+ # Usage:
17
+ # cd /Users/mulgogi/src/glossarist/glossarist-ruby
18
+ # bundle exec ruby scripts/migrate_osgeo_to_v3.rb
19
+
20
+ require "glossarist"
21
+
22
+ DIR = "/Users/mulgogi/src/geolexica/osgeo-glossary/concepts"
23
+
24
+ OSGEO_DATE = "2011-01-01T00:00:00+00:00"
25
+
26
+ # Extract a stable domain ID from an authoritative source reference string.
27
+ def extract_domain_id(ref_text)
28
+ return nil unless ref_text
29
+
30
+ patterns = [
31
+ %r{ISO/IEC/IEEE\s+([\d-]+)},
32
+ %r{ISO/IEC\s+([\d-]+)},
33
+ %r{ISO/TS\s+([\d-]+)},
34
+ %r{ISO/TR\s+([\d-]+)},
35
+ %r{ISO\s+([\d]+-?[\d]*)},
36
+ ]
37
+
38
+ patterns.each do |pat|
39
+ if (m = ref_text.match(pat))
40
+ return "iso-#{m[1]}"
41
+ end
42
+ end
43
+
44
+ nil
45
+ end
46
+
47
+ collection = Glossarist::ManagedConceptCollection.new
48
+ collection.load_from_files(DIR)
49
+
50
+ puts "Loaded #{collection.count} concepts"
51
+
52
+ domain_index = {}
53
+ concepts_with_domain = 0
54
+
55
+ collection.each do |concept|
56
+ # Set status
57
+ concept.status = "valid" unless concept.status
58
+
59
+ # Set date_accepted
60
+ unless concept.date_accepted
61
+ concept.date_accepted = Glossarist::ConceptDate.new(
62
+ type: "accepted",
63
+ date: OSGEO_DATE,
64
+ )
65
+ end
66
+
67
+ # Extract domain from source
68
+ eng = concept.localization("eng")
69
+ next unless eng
70
+
71
+ sources = eng.data&.sources
72
+ next unless sources
73
+
74
+ auth = sources.find { |s| s.type == "authoritative" }
75
+ next unless auth&.origin
76
+
77
+ ref_text = auth.origin.text || auth.origin.ref
78
+ next unless ref_text
79
+
80
+ domain_id = extract_domain_id(ref_text)
81
+ next unless domain_id
82
+
83
+ (domain_index[domain_id] ||= []) << concept.data.id
84
+ concepts_with_domain += 1
85
+
86
+ # Add domain ConceptReference
87
+ concept.data.domains ||= []
88
+ unless concept.data.domains.any? { |d| d.concept_id == domain_id }
89
+ concept.data.domains << Glossarist::ConceptReference.new(
90
+ concept_id: domain_id,
91
+ source: "urn:iso:std:iso",
92
+ ref_type: "domain",
93
+ )
94
+ end
95
+
96
+ # Add broader relation to domain concept
97
+ concept.related ||= []
98
+ unless concept.related.any? { |r| r.type == "broader" && r.ref&.id == domain_id }
99
+ concept.related << Glossarist::RelatedConcept.new(
100
+ type: "broader",
101
+ content: domain_id,
102
+ ref: Glossarist::Citation.new(source: "ISO", id: domain_id),
103
+ )
104
+ end
105
+ end
106
+
107
+ puts "Added status and date_accepted to #{collection.count} concepts"
108
+ puts "Added domains to #{concepts_with_domain} concepts with ISO sources"
109
+
110
+ # Create domain hierarchy concepts
111
+ domain_index.sort.each do |domain_id, child_ids|
112
+ mc = Glossarist::ManagedConcept.new(
113
+ data: Glossarist::ManagedConceptData.new(
114
+ id: domain_id,
115
+ domains: [Glossarist::ConceptReference.new(
116
+ concept_id: domain_id,
117
+ source: "urn:iso:std:iso",
118
+ ref_type: "domain",
119
+ )],
120
+ ),
121
+ )
122
+ mc.status = "valid"
123
+ mc.date_accepted = Glossarist::ConceptDate.new(
124
+ type: "accepted",
125
+ date: OSGEO_DATE,
126
+ )
127
+
128
+ l10n = Glossarist::LocalizedConcept.new
129
+ l10n.data = Glossarist::ConceptData.new(
130
+ id: domain_id,
131
+ language_code: "eng",
132
+ terms: [Glossarist::Designation::Expression.new(
133
+ type: "expression",
134
+ designation: domain_id,
135
+ normative_status: "preferred",
136
+ )],
137
+ )
138
+ l10n.entry_status = "valid"
139
+ mc.add_l10n(l10n)
140
+
141
+ narrower = child_ids.sort.map do |child_id|
142
+ Glossarist::RelatedConcept.new(
143
+ type: "narrower",
144
+ content: child_id.to_s,
145
+ ref: Glossarist::Citation.new(source: "OSGeo", id: child_id.to_s),
146
+ )
147
+ end
148
+ mc.related = narrower
149
+
150
+ collection.store(mc)
151
+ puts "Created domain: #{domain_id} — #{child_ids.size} narrower"
152
+ end
153
+
154
+ collection.save_grouped_concepts_to_files(DIR)
155
+ puts "Saved #{collection.count} concepts to #{DIR}"
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Upgrades a dataset directory to v3 format.
5
+ #
6
+ # Usage: bundle exec ruby scripts/upgrade_dataset_to_v3.rb <concepts_dir> [--grouped|--separate]
7
+ #
8
+ # Formats:
9
+ # --grouped (default): each concept + localizations in a single YAML file
10
+ # --separate: concept/ and localized_concept/ in separate files
11
+ #
12
+ # For each concept:
13
+ # 1. Loads with ConceptManager (auto-detects v2/v3)
14
+ # 2. Promotes data.related -> top-level related (if needed)
15
+ # 3. Sets schema_version = "3"
16
+ # 4. Re-saves in v3 format
17
+
18
+ require "glossarist"
19
+
20
+ dir = ARGV[0]
21
+ mode = ARGV.include?("--separate") ? :separate : :grouped
22
+
23
+ unless dir && Dir.exist?(dir)
24
+ abort "Usage: #{$PROGRAM_NAME} <concepts_dir> [--grouped|--separate]"
25
+ end
26
+
27
+ manager = Glossarist::ConceptManager.new(path: dir)
28
+ collection = Glossarist::ManagedConceptCollection.new
29
+
30
+ puts "Loading concepts from #{dir}..."
31
+ manager.load_from_files(collection: collection)
32
+
33
+ count = 0
34
+ collection.each do |concept|
35
+ Glossarist::SchemaMigration.migrate_concept(concept)
36
+ count += 1
37
+ end
38
+
39
+ puts "Migrated #{count} concepts. Saving..."
40
+
41
+ if mode == :separate
42
+ manager.save_to_files(collection)
43
+ else
44
+ manager.save_grouped_concepts_to_files(collection)
45
+ end
46
+
47
+ puts "Done. All concepts now in v3 format."
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.6.5
4
+ version: 2.6.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-05-12 00:00:00.000000000 Z
11
+ date: 2026-05-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lutaml-model
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.8.5
27
+ - !ruby/object:Gem::Dependency
28
+ name: paint
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.3'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.3'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: relaton
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -78,6 +92,20 @@ dependencies:
78
92
  - - "~>"
79
93
  - !ruby/object:Gem::Version
80
94
  version: 0.5.6
95
+ - !ruby/object:Gem::Dependency
96
+ name: table_tennis
97
+ requirement: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - "~>"
100
+ - !ruby/object:Gem::Version
101
+ version: '0.0'
102
+ type: :runtime
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - "~>"
107
+ - !ruby/object:Gem::Version
108
+ version: '0.0'
81
109
  - !ruby/object:Gem::Dependency
82
110
  name: tbx
83
111
  requirement: !ruby/object:Gem::Requirement
@@ -127,7 +155,6 @@ files:
127
155
  - LICENSE.txt
128
156
  - README.adoc
129
157
  - Rakefile
130
- - TODO.integration/01-gcr-package-cli.md
131
158
  - config.yml
132
159
  - exe/glossarist
133
160
  - glossarist.gemspec
@@ -137,6 +164,7 @@ files:
137
164
  - lib/glossarist/bibliographic_reference.rb
138
165
  - lib/glossarist/citation.rb
139
166
  - lib/glossarist/cli.rb
167
+ - lib/glossarist/cli/compare_command.rb
140
168
  - lib/glossarist/cli/export_command.rb
141
169
  - lib/glossarist/cli/import_command.rb
142
170
  - lib/glossarist/cli/package_command.rb
@@ -153,18 +181,23 @@ files:
153
181
  - lib/glossarist/collections/detailed_definition_collection.rb
154
182
  - lib/glossarist/collections/localization_collection.rb
155
183
  - lib/glossarist/collections/typed_collection.rb
184
+ - lib/glossarist/comparison_result.rb
156
185
  - lib/glossarist/concept.rb
157
186
  - lib/glossarist/concept_collector.rb
187
+ - lib/glossarist/concept_comparator.rb
158
188
  - lib/glossarist/concept_data.rb
159
189
  - lib/glossarist/concept_date.rb
190
+ - lib/glossarist/concept_diff.rb
160
191
  - lib/glossarist/concept_document.rb
161
192
  - lib/glossarist/concept_enricher.rb
162
193
  - lib/glossarist/concept_manager.rb
194
+ - lib/glossarist/concept_ref.rb
163
195
  - lib/glossarist/concept_reference.rb
164
196
  - lib/glossarist/concept_set.rb
165
197
  - lib/glossarist/concept_source.rb
166
198
  - lib/glossarist/concept_validator.rb
167
199
  - lib/glossarist/config.rb
200
+ - lib/glossarist/context_configuration.rb
168
201
  - lib/glossarist/custom_locality.rb
169
202
  - lib/glossarist/dataset_validator.rb
170
203
  - lib/glossarist/designation.rb
@@ -174,6 +207,8 @@ files:
174
207
  - lib/glossarist/designation/grammar_info.rb
175
208
  - lib/glossarist/designation/graphical_symbol.rb
176
209
  - lib/glossarist/designation/letter_symbol.rb
210
+ - lib/glossarist/designation/prefix.rb
211
+ - lib/glossarist/designation/suffix.rb
177
212
  - lib/glossarist/designation/symbol.rb
178
213
  - lib/glossarist/detailed_definition.rb
179
214
  - lib/glossarist/error.rb
@@ -192,13 +227,40 @@ files:
192
227
  - lib/glossarist/managed_concept_collection.rb
193
228
  - lib/glossarist/managed_concept_data.rb
194
229
  - lib/glossarist/non_verb_rep.rb
230
+ - lib/glossarist/pronunciation.rb
195
231
  - lib/glossarist/rdf.rb
232
+ - lib/glossarist/rdf/ext.rb
233
+ - lib/glossarist/rdf/ext/jsonld_transform_ext.rb
234
+ - lib/glossarist/rdf/ext/mapping_ext.rb
235
+ - lib/glossarist/rdf/ext/mapping_rule_ext.rb
236
+ - lib/glossarist/rdf/ext/member_rule_ext.rb
237
+ - lib/glossarist/rdf/ext/turtle_transform_ext.rb
238
+ - lib/glossarist/rdf/gloss_citation.rb
239
+ - lib/glossarist/rdf/gloss_concept.rb
240
+ - lib/glossarist/rdf/gloss_concept_date.rb
241
+ - lib/glossarist/rdf/gloss_concept_reference.rb
242
+ - lib/glossarist/rdf/gloss_concept_source.rb
243
+ - lib/glossarist/rdf/gloss_designation.rb
244
+ - lib/glossarist/rdf/gloss_detailed_definition.rb
245
+ - lib/glossarist/rdf/gloss_grammar_info.rb
246
+ - lib/glossarist/rdf/gloss_locality.rb
247
+ - lib/glossarist/rdf/gloss_localized_concept.rb
248
+ - lib/glossarist/rdf/gloss_non_verbal_rep.rb
249
+ - lib/glossarist/rdf/gloss_pronunciation.rb
250
+ - lib/glossarist/rdf/gloss_reference.rb
196
251
  - lib/glossarist/rdf/localized_literal.rb
197
252
  - lib/glossarist/rdf/namespaces.rb
198
253
  - lib/glossarist/rdf/namespaces/dcterms_namespace.rb
254
+ - lib/glossarist/rdf/namespaces/glossarist_namespace.rb
255
+ - lib/glossarist/rdf/namespaces/iso_thes_namespace.rb
256
+ - lib/glossarist/rdf/namespaces/owl_namespace.rb
257
+ - lib/glossarist/rdf/namespaces/prov_namespace.rb
258
+ - lib/glossarist/rdf/namespaces/rdf_namespace.rb
199
259
  - lib/glossarist/rdf/namespaces/skos_namespace.rb
200
- - lib/glossarist/rdf/skos_concept.rb
201
- - lib/glossarist/rdf/skos_vocabulary.rb
260
+ - lib/glossarist/rdf/namespaces/skosxl_namespace.rb
261
+ - lib/glossarist/rdf/relationships.rb
262
+ - lib/glossarist/rdf/v3.rb
263
+ - lib/glossarist/rdf/v3/configuration.rb
202
264
  - lib/glossarist/reference_extractor.rb
203
265
  - lib/glossarist/reference_resolver.rb
204
266
  - lib/glossarist/register_data.rb
@@ -218,7 +280,7 @@ files:
218
280
  - lib/glossarist/sts/term_extractor.rb
219
281
  - lib/glossarist/sts/term_mapper.rb
220
282
  - lib/glossarist/transforms.rb
221
- - lib/glossarist/transforms/concept_to_skos_transform.rb
283
+ - lib/glossarist/transforms/concept_to_gloss_transform.rb
222
284
  - lib/glossarist/transforms/concept_to_tbx_transform.rb
223
285
  - lib/glossarist/urn_resolver.rb
224
286
  - lib/glossarist/utilities.rb
@@ -228,6 +290,34 @@ files:
228
290
  - lib/glossarist/v1/concept.rb
229
291
  - lib/glossarist/v1/cross_references.rb
230
292
  - lib/glossarist/v1/register.rb
293
+ - lib/glossarist/v2.rb
294
+ - lib/glossarist/v2/citation.rb
295
+ - lib/glossarist/v2/concept_data.rb
296
+ - lib/glossarist/v2/concept_document.rb
297
+ - lib/glossarist/v2/concept_ref.rb
298
+ - lib/glossarist/v2/concept_source.rb
299
+ - lib/glossarist/v2/configuration.rb
300
+ - lib/glossarist/v2/detailed_definition.rb
301
+ - lib/glossarist/v2/localized_concept.rb
302
+ - lib/glossarist/v2/managed_concept.rb
303
+ - lib/glossarist/v2/managed_concept_data.rb
304
+ - lib/glossarist/v2/related_concept.rb
305
+ - lib/glossarist/v3.rb
306
+ - lib/glossarist/v3/bibliography_entry.rb
307
+ - lib/glossarist/v3/bibliography_file.rb
308
+ - lib/glossarist/v3/citation.rb
309
+ - lib/glossarist/v3/concept_data.rb
310
+ - lib/glossarist/v3/concept_document.rb
311
+ - lib/glossarist/v3/concept_ref.rb
312
+ - lib/glossarist/v3/concept_source.rb
313
+ - lib/glossarist/v3/configuration.rb
314
+ - lib/glossarist/v3/detailed_definition.rb
315
+ - lib/glossarist/v3/image_entry.rb
316
+ - lib/glossarist/v3/image_file.rb
317
+ - lib/glossarist/v3/localized_concept.rb
318
+ - lib/glossarist/v3/managed_concept.rb
319
+ - lib/glossarist/v3/managed_concept_data.rb
320
+ - lib/glossarist/v3/related_concept.rb
231
321
  - lib/glossarist/validation.rb
232
322
  - lib/glossarist/validation/asset_index.rb
233
323
  - lib/glossarist/validation/bibliography_index.rb
@@ -250,6 +340,8 @@ files:
250
340
  - lib/glossarist/validation/rules/definition_content_rule.rb
251
341
  - lib/glossarist/validation/rules/designation_status_rule.rb
252
342
  - lib/glossarist/validation/rules/designation_type_rule.rb
343
+ - lib/glossarist/validation/rules/domain_ref_rule.rb
344
+ - lib/glossarist/validation/rules/domain_target_rule.rb
253
345
  - lib/glossarist/validation/rules/duplicate_term_rule.rb
254
346
  - lib/glossarist/validation/rules/entry_status_rule.rb
255
347
  - lib/glossarist/validation/rules/filename_id_rule.rb
@@ -259,26 +351,40 @@ files:
259
351
  - lib/glossarist/validation/rules/language_code_format_rule.rb
260
352
  - lib/glossarist/validation/rules/language_coverage_rule.rb
261
353
  - lib/glossarist/validation/rules/language_list_rule.rb
354
+ - lib/glossarist/validation/rules/locality_completeness_rule.rb
355
+ - lib/glossarist/validation/rules/localization_consistency_rule.rb
262
356
  - lib/glossarist/validation/rules/localization_presence_rule.rb
357
+ - lib/glossarist/validation/rules/model_validity_rule.rb
263
358
  - lib/glossarist/validation/rules/orphaned_bibliography_rule.rb
264
359
  - lib/glossarist/validation/rules/orphaned_images_rule.rb
265
360
  - lib/glossarist/validation/rules/orphaned_l10n_files_rule.rb
266
361
  - lib/glossarist/validation/rules/preferred_term_rule.rb
362
+ - lib/glossarist/validation/rules/ref_shape_rule.rb
267
363
  - lib/glossarist/validation/rules/registry.rb
268
364
  - lib/glossarist/validation/rules/related_concept_cycle_rule.rb
269
365
  - lib/glossarist/validation/rules/related_concept_rule.rb
270
366
  - lib/glossarist/validation/rules/related_concept_symmetry_rule.rb
367
+ - lib/glossarist/validation/rules/related_concept_target_rule.rb
368
+ - lib/glossarist/validation/rules/schema_version_rule.rb
271
369
  - lib/glossarist/validation/rules/source_type_rule.rb
370
+ - lib/glossarist/validation/rules/source_urn_format_rule.rb
272
371
  - lib/glossarist/validation/rules/terms_presence_rule.rb
372
+ - lib/glossarist/validation/rules/uuid_format_rule.rb
273
373
  - lib/glossarist/validation/validation_issue.rb
274
374
  - lib/glossarist/validation_result.rb
275
375
  - lib/glossarist/version.rb
376
+ - memory/project-status.md
276
377
  - relaton-bib-2.0.0.gem
277
378
  - relaton-bib-2.1.0.gem
278
379
  - relaton-cen-2.0.0.gem
279
380
  - relaton-iec-2.0.0.gem
280
381
  - relaton-iso-2.0.0.gem
281
382
  - relaton-itu-2.0.0.gem
383
+ - scripts/migrate_dataset.rb
384
+ - scripts/migrate_isotc204_to_v3.rb
385
+ - scripts/migrate_isotc211_to_v3.rb
386
+ - scripts/migrate_osgeo_to_v3.rb
387
+ - scripts/upgrade_dataset_to_v3.rb
282
388
  homepage: https://github.com/glossarist/glossarist-ruby
283
389
  licenses:
284
390
  - BSD-2-Clause
@@ -1,180 +0,0 @@
1
- # 01 — GCR Packaging CLI with Versioning
2
-
3
- ## Goal
4
-
5
- The `glossarist` Ruby gem provides the canonical way to build versioned GCR packages from concept datasets. Each glossary repo uses `glossarist package` in CI to publish GCR releases.
6
-
7
- ## Current State
8
-
9
- - CLI has `package`, `upgrade`, `validate` commands (via Thor)
10
- - `GcrPackage.create` / `GcrPackage.load` handle ZIP I/O
11
- - `GcrMetadata` generates metadata with statistics
12
- - `SchemaMigration` handles v0→v1 harmonization
13
- - Missing: `shortname` and `version` fields in GcrMetadata
14
- - Missing: v2 format support in `PackageCommand`
15
-
16
- ## Status
17
-
18
- Tasks 1–5 are **implemented** on branch `fix/gemfile-lutaml-model-substring`. Remaining: task 6 (publish gem to RubyGems).
19
-
20
- ## Tasks
21
-
22
- ### 1. Add `shortname` and `version` to `GcrMetadata`
23
-
24
- Edit `lib/glossarist/gcr_metadata.rb`:
25
-
26
- ```ruby
27
- attr_accessor :shortname, :version, :title, :description, :owner, :tags,
28
- :concept_count, :languages,
29
- :created_at, :glossarist_version, :schema_version,
30
- :statistics, :homepage, :repository, :license
31
-
32
- def initialize(attrs = {})
33
- @shortname = attrs[:shortname]
34
- @version = attrs[:version]
35
- # ... existing fields ...
36
- end
37
-
38
- def self.from_concepts(concepts, register_data: nil, options: {})
39
- stats = GcrStatistics.from_concepts(concepts)
40
- new(
41
- shortname: options[:shortname],
42
- version: options[:version],
43
- title: options[:title] || register_data&.dig("name"),
44
- # ... existing fields ...
45
- )
46
- end
47
-
48
- def to_h
49
- h = {
50
- "shortname" => shortname,
51
- "version" => version,
52
- "title" => title,
53
- # ... existing fields ...
54
- }
55
- h.compact
56
- end
57
- ```
58
-
59
- ### 2. Add `--shortname` and `--version` CLI options
60
-
61
- Edit `lib/glossarist/cli.rb`:
62
-
63
- ```ruby
64
- desc "package DIR", "Create a .gcr ZIP archive from a dataset"
65
- option :output, aliases: :o, required: true, desc: "Output .gcr file path"
66
- option :shortname, type: :string, required: true, desc: "Machine-readable dataset ID"
67
- option :version, type: :string, required: true, desc: "Semantic version (e.g. 1.0.0)"
68
- option :title, type: :string, desc: "Dataset title"
69
- option :description, type: :string, desc: "Dataset description"
70
- option :owner, type: :string, desc: "Dataset owner"
71
- option :register_yaml, type: :string, desc: "Path to register.yaml"
72
- option :tags, type: :array, desc: "Tags for the dataset"
73
- def package(dir)
74
- # ...
75
- end
76
- ```
77
-
78
- ### 3. Add v2 format support to `PackageCommand`
79
-
80
- Edit `lib/glossarist/cli/package_command.rb`:
81
-
82
- ```ruby
83
- def collect_concepts
84
- if v1_concepts?
85
- collect_v1_concepts
86
- elsif v2_concepts?
87
- collect_v2_concepts
88
- else
89
- []
90
- end
91
- end
92
-
93
- def v1_concepts?
94
- concepts_dir = File.join(@dir, "concepts")
95
- File.directory?(concepts_dir) && Dir.glob(File.join(concepts_dir, "*.yaml")).any?
96
- end
97
-
98
- def v2_concepts?
99
- File.directory?(File.join(@dir, "geolexica-v2"))
100
- end
101
-
102
- def collect_v2_concepts
103
- collection = Glossarist::ManagedConceptCollection.new
104
- manager = Glossarist::ConceptManager.new(path: File.join(@dir, "geolexica-v2"))
105
- manager.load_from_files(collection: collection)
106
-
107
- collection.map { |concept| concept_to_v1_hash(concept) }
108
- end
109
-
110
- def concept_to_v1_hash(concept)
111
- hash = { "termid" => concept.data.id.to_s }
112
- concept.localizations.each do |lang, l10n|
113
- hash[lang] = localized_to_hash(l10n)
114
- end
115
- hash["term"] = preferred_designation(hash["eng"]&.dig("terms")) || ""
116
- hash
117
- end
118
-
119
- def localized_to_hash(l10n)
120
- h = {}
121
- h["terms"] = l10n.designations.map(&:to_h) if l10n.designations.any?
122
- h["definition"] = l10n.definition.map { |d| { "content" => d.content } } if l10n.definition.any?
123
- h["notes"] = l10n.notes.map { |n| { "content" => n.content } } if l10n.notes.any?
124
- h["examples"] = l10n.examples.map { |e| { "content" => e.content } } if l10n.examples.any?
125
- h["sources"] = l10n.sources.map(&:to_h) if l10n.sources.any?
126
- h["language_code"] = l10n.language_code if l10n.language_code
127
- h["entry_status"] = l10n.entry_status if l10n.entry_status
128
- h["dates"] = l10n.dates.map(&:to_h) if l10n.dates.any?
129
- h
130
- end
131
- ```
132
-
133
- ### 4. Auto-derive shortname from directory name
134
-
135
- If `--shortname` is not provided, derive from:
136
- 1. `register.yaml` → `register["shortname"]` or `register["id"]`
137
- 2. Directory basename
138
- 3. Raise error if none available
139
-
140
- ### 5. Validate filename matches metadata
141
-
142
- In `GcrPackage.validate`, check that the filename pattern `{shortname}-{version}.gcr` matches the `shortname` and `version` in metadata.yaml.
143
-
144
- ### 6. Publish gem
145
-
146
- ```bash
147
- gem build glossarist.gemspec
148
- gem push glossarist-2.6.0.gem
149
- ```
150
-
151
- ## CLI Usage
152
-
153
- ```bash
154
- # Install
155
- gem install glossarist
156
-
157
- # Package (v1 format)
158
- glossarist package ./isotc204-glossary \
159
- --shortname isotc204 --version 1.0.0 \
160
- -o isotc204-1.0.0.gcr \
161
- --title "ISO/TC 204 ITS Vocabulary" --owner "ISO/TC 204"
162
-
163
- # Package (v2 format, auto-detected)
164
- glossarist package ./isotc211-glossary \
165
- --shortname isotc211 --version 2.3.0 \
166
- -o isotc211-2.3.0.gcr \
167
- --title "ISO/TC 211 Multi-Lingual Glossary" --owner "ISO/TC 211"
168
-
169
- # Validate
170
- glossarist validate isotc204-1.0.0.gcr
171
- ```
172
-
173
- ## Acceptance Criteria
174
-
175
- - [x] `GcrMetadata` includes `shortname` and `version` fields
176
- - [x] `glossarist package --shortname X --version Y` produces `{X}-{Y}.gcr`
177
- - [x] `metadata.yaml` contains `shortname` and `version`
178
- - [x] `glossarist validate` checks metadata has required fields
179
- - [x] Works with both v1 (`concepts/*.yaml`) and v2 (`geolexica-v2/*.yaml`) datasets
180
- - [ ] Gem published to RubyGems
@@ -1,43 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "lutaml/turtle"
4
- require "lutaml/jsonld"
5
-
6
- module Glossarist
7
- module Rdf
8
- class SkosConcept < Lutaml::Model::Serializable
9
- attribute :code, :string
10
- attribute :labels, LocalizedLiteral, collection: true
11
- attribute :definitions, LocalizedLiteral, collection: true
12
- attribute :alt_labels, LocalizedLiteral, collection: true
13
- attribute :scope_notes, LocalizedLiteral, collection: true
14
- attribute :sources, :string, collection: true
15
- attribute :domain, :string
16
- attribute :date_accepted, :string
17
-
18
- rdf do
19
- namespace Namespaces::SkosNamespace, Namespaces::DctermsNamespace
20
-
21
- subject { |c| "https://glossarist.org/concept/#{c.code}" }
22
- type "skos:Concept"
23
-
24
- predicate :notation, namespace: Namespaces::SkosNamespace,
25
- to: :code
26
- predicate :prefLabel, namespace: Namespaces::SkosNamespace,
27
- to: :labels, lang_tagged: true
28
- predicate :definition, namespace: Namespaces::SkosNamespace,
29
- to: :definitions, lang_tagged: true
30
- predicate :altLabel, namespace: Namespaces::SkosNamespace,
31
- to: :alt_labels, lang_tagged: true
32
- predicate :scopeNote, namespace: Namespaces::SkosNamespace,
33
- to: :scope_notes, lang_tagged: true
34
- predicate :subject, namespace: Namespaces::DctermsNamespace,
35
- to: :domain
36
- predicate :source, namespace: Namespaces::DctermsNamespace,
37
- to: :sources
38
- predicate :dateAccepted, namespace: Namespaces::DctermsNamespace,
39
- to: :date_accepted
40
- end
41
- end
42
- end
43
- end
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "lutaml/turtle"
4
- require "lutaml/jsonld"
5
-
6
- module Glossarist
7
- module Rdf
8
- class SkosVocabulary < Lutaml::Model::Serializable
9
- attribute :id, :string
10
- attribute :title, :string
11
- attribute :concepts, SkosConcept, collection: true
12
-
13
- rdf do
14
- namespace Namespaces::SkosNamespace, Namespaces::DctermsNamespace
15
-
16
- subject { |v| "https://glossarist.org/vocab/#{v.id}" }
17
- type "skos:ConceptScheme"
18
-
19
- predicate :prefLabel, namespace: Namespaces::SkosNamespace, to: :title
20
-
21
- members :concepts
22
- end
23
- end
24
- end
25
- end