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
@@ -6,6 +6,45 @@ module Glossarist
6
6
  class SchemaMigration
7
7
  CURRENT_SCHEMA_VERSION = "1"
8
8
 
9
+ def self.migrate_concept(concept, target_version: Glossarist::SCHEMA_VERSION)
10
+ current = concept_version(concept)
11
+ target = target_version.to_s
12
+
13
+ return concept if current == target
14
+
15
+ max_steps = 5
16
+ max_steps.times do
17
+ break if current == target
18
+
19
+ case current
20
+ when "2" then current = step_v2_to_v3(concept)
21
+ else
22
+ raise Error, "No concept migration step from version #{current}"
23
+ end
24
+ end
25
+
26
+ raise Error, "Migration chain too long or unresolvable" unless current == target
27
+
28
+ concept.schema_version = target
29
+ concept
30
+ end
31
+
32
+ def self.concept_version(concept)
33
+ version = concept.schema_version
34
+ return version.to_s if version && !version.to_s.empty?
35
+
36
+ ManagedConcept.detect_schema_version(concept)
37
+ end
38
+
39
+ def self.step_v2_to_v3(concept)
40
+ if concept.data&.related&.any?
41
+ concept.related ||= []
42
+ concept.related = (concept.related + concept.data.related).uniq
43
+ concept.data.related = []
44
+ end
45
+ "3"
46
+ end
47
+
9
48
  ENTRY_STATUS_MAP = {
10
49
  "Standard" => "valid",
11
50
  "Confirmed" => "valid",
@@ -98,7 +98,7 @@ module Glossarist
98
98
  sources << {
99
99
  "status" => "identical",
100
100
  "type" => "authoritative",
101
- "origin" => { "text" => source_ref },
101
+ "origin" => { "ref" => { "source" => source_ref } },
102
102
  }
103
103
  end
104
104
 
@@ -107,7 +107,7 @@ module Glossarist
107
107
 
108
108
  sources << {
109
109
  "type" => "authoritative",
110
- "origin" => { "text" => text },
110
+ "origin" => { "ref" => { "source" => text } },
111
111
  }
112
112
  end
113
113
 
@@ -0,0 +1,355 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glossarist
4
+ module Transforms
5
+ # Transforms Glossarist domain model objects into ontology-faithful RDF
6
+ # using lutaml-model serializable view classes.
7
+ #
8
+ # Creates GlossConcept/GlossLocalizedConcept/GlossDesignation instances
9
+ # and delegates Turtle/JSON-LD serialization to lutaml-model.
10
+ class ConceptToGlossTransform
11
+ GLOSS = Rdf::Namespaces::GlossaristNamespace.uri
12
+ SKOS = Rdf::Namespaces::SkosNamespace.uri
13
+ XL = Rdf::Namespaces::SkosxlNamespace.uri
14
+ ISO = Rdf::Namespaces::IsoThesNamespace.uri
15
+ DCT = Rdf::Namespaces::DctermsNamespace.uri
16
+ RDF_NS = Rdf::Namespaces::RdfNamespace.uri
17
+
18
+ REL_PROPERTY_MAP = {
19
+ "broader" => "#{SKOS}broader",
20
+ "narrower" => "#{SKOS}narrower",
21
+ "broader_generic" => "#{ISO}broaderGeneric",
22
+ "narrower_generic" => "#{ISO}narrowerGeneric",
23
+ "broader_partitive" => "#{ISO}broaderPartitive",
24
+ "narrower_partitive" => "#{ISO}narrowerPartitive",
25
+ "broader_instantial" => "#{ISO}broaderInstantial",
26
+ "narrower_instantial" => "#{ISO}narrowerInstantial",
27
+ "equivalent" => "#{SKOS}exactMatch",
28
+ "close_match" => "#{SKOS}closeMatch",
29
+ "broad_match" => "#{SKOS}broadMatch",
30
+ "narrow_match" => "#{SKOS}narrowMatch",
31
+ "related_match" => "#{SKOS}relatedMatch",
32
+ "see" => "#{SKOS}related",
33
+ "deprecates" => "#{GLOSS}deprecates",
34
+ "supersedes" => "#{GLOSS}supersedes",
35
+ "superseded_by" => "#{GLOSS}supersededBy",
36
+ "compare" => "#{GLOSS}compares",
37
+ "contrast" => "#{GLOSS}contrasts",
38
+ "sequentially_related_concept" => "#{GLOSS}sequentiallyRelated",
39
+ "spatially_related_concept" => "#{GLOSS}spatiallyRelated",
40
+ "temporally_related_concept" => "#{GLOSS}temporallyRelated",
41
+ "homograph" => "#{GLOSS}hasHomograph",
42
+ "false_friend" => "#{GLOSS}hasFalseFriend",
43
+ "related_concept_broader" => "#{GLOSS}relatedConceptBroader",
44
+ "related_concept_narrower" => "#{GLOSS}relatedConceptNarrower",
45
+ "abbreviated_form_for" => "#{GLOSS}abbreviatedFormFor",
46
+ "short_form_for" => "#{GLOSS}shortFormFor",
47
+ }.freeze
48
+
49
+ DATE_TYPE_MAP = {
50
+ "accepted" => "#{GLOSS}status/accepted",
51
+ "amended" => "#{GLOSS}status/amended",
52
+ "retired" => "#{GLOSS}status/retired",
53
+ }.freeze
54
+
55
+ def self.transform(managed_concept, options = {})
56
+ new(managed_concept, options).build
57
+ end
58
+
59
+ def self.transform_document(concepts, options = {})
60
+ new(nil, options).build_document(concepts)
61
+ end
62
+
63
+ def initialize(managed_concept, options = {})
64
+ @concept = managed_concept
65
+ @options = options
66
+ end
67
+
68
+ def build
69
+ build_gloss_concept(concept)
70
+ end
71
+
72
+ def build_document(concepts)
73
+ gloss_concepts = concepts.map { |c| build_gloss_concept(c) }
74
+ doc = Rdf::GlossDocument.new(concepts: gloss_concepts)
75
+ Rdf::GlossDocument.to_turtle(doc)
76
+ end
77
+
78
+ def to_turtle(concepts_or_concept = nil)
79
+ if concepts_or_concept.is_a?(Array)
80
+ build_document(concepts_or_concept)
81
+ else
82
+ target = concepts_or_concept || @concept
83
+ return "" unless target
84
+
85
+ gc = build_gloss_concept(target)
86
+ Rdf::GlossConcept.to_turtle(gc)
87
+ end
88
+ end
89
+
90
+ def to_jsonld(concepts_or_concept = nil)
91
+ if concepts_or_concept.is_a?(Array)
92
+ gloss_concepts = concepts_or_concept.map { |c| build_gloss_concept(c) }
93
+ doc = Rdf::GlossDocument.new(concepts: gloss_concepts)
94
+ Rdf::GlossDocument.to_jsonld(doc)
95
+ else
96
+ target = concepts_or_concept || @concept
97
+ return "" unless target
98
+
99
+ gc = build_gloss_concept(target)
100
+ Rdf::GlossConcept.to_jsonld(gc)
101
+ end
102
+ end
103
+
104
+ def to_jsonl_line
105
+ return "" unless @concept
106
+
107
+ gc = build_gloss_concept(@concept)
108
+ Rdf::GlossConcept.to_jsonld(gc)
109
+ end
110
+
111
+ private
112
+
113
+ attr_reader :concept, :options
114
+
115
+ # ── Build RDF view instances from domain model ─────────────────────
116
+
117
+ def build_gloss_concept(managed_concept)
118
+ identifier = managed_concept.data&.id || managed_concept.identifier
119
+
120
+ localizations = managed_concept.localizations.each_value.map do |l10n|
121
+ build_gloss_localized_concept(l10n, identifier)
122
+ end
123
+
124
+ gc = Rdf::GlossConcept.new(
125
+ identifier: identifier.to_s,
126
+ status: status_uri(managed_concept.status),
127
+ localizations: localizations,
128
+ sources: build_gloss_sources(managed_concept.data&.sources),
129
+ domains: build_gloss_domains(managed_concept.data&.domains, identifier),
130
+ dates: build_gloss_dates(managed_concept.dates, identifier),
131
+ )
132
+
133
+ gc.relationship_triples = build_relationship_triples(managed_concept.related)
134
+ gc
135
+ end
136
+
137
+ def build_gloss_localized_concept(l10n, concept_id)
138
+ lang = l10n.language_code
139
+ data = l10n.data
140
+
141
+ designations = Array(l10n.designations).each_with_index.map do |desig, idx|
142
+ build_gloss_designation(desig, concept_id, lang, idx)
143
+ end
144
+
145
+ definitions = build_gloss_definitions(data&.definition)
146
+ notes = build_gloss_definitions(data&.notes)
147
+ examples = build_gloss_definitions(data&.examples)
148
+ sources = build_gloss_sources(data&.sources)
149
+ non_verb_reps = build_gloss_non_verbal_reps(l10n.non_verb_rep, concept_id, lang)
150
+
151
+ Rdf::GlossLocalizedConcept.new(
152
+ concept_id: concept_id.to_s,
153
+ language_code: lang,
154
+ domain: data&.domain,
155
+ entry_status: data&.entry_status ? "gloss:entstatus/#{data.entry_status}" : nil,
156
+ release: data&.release,
157
+ lineage_similarity: data&.lineage_source_similarity,
158
+ script: data&.script,
159
+ system: data&.system,
160
+ designations: designations,
161
+ definitions: definitions,
162
+ notes: notes,
163
+ examples: examples,
164
+ sources: sources,
165
+ non_verb_reps: non_verb_reps,
166
+ )
167
+ end
168
+
169
+ def build_gloss_designation(desig, concept_id, lang, index)
170
+ common_attrs = designation_common_attrs(desig, concept_id, lang, index)
171
+
172
+ instance = case desig
173
+ when Designation::Abbreviation
174
+ build_gloss_abbreviation(desig, common_attrs, concept_id, lang, index)
175
+ when Designation::Expression
176
+ build_gloss_expression(desig, common_attrs, concept_id, lang, index)
177
+ when Designation::GraphicalSymbol
178
+ Rdf::GlossGraphicalSymbol.new(common_attrs.merge(text: desig.text, image: desig.image))
179
+ when Designation::LetterSymbol
180
+ Rdf::GlossLetterSymbol.new(common_attrs.merge(text: desig.text))
181
+ when Designation::Symbol
182
+ Rdf::GlossSymbol.new(common_attrs)
183
+ else
184
+ Rdf::GlossExpression.new(common_attrs)
185
+ end
186
+
187
+ instance.relationship_triples = build_relationship_triples(desig.related)
188
+ instance
189
+ end
190
+
191
+ def designation_common_attrs(desig, concept_id, lang, index)
192
+ norm_status = desig.normative_status
193
+ {
194
+ designation: desig.designation,
195
+ normative_status: norm_status ? "gloss:norm/#{norm_status}" : nil,
196
+ type: desig.type,
197
+ language: desig.language || lang,
198
+ script: desig.script,
199
+ system: desig.system,
200
+ international: desig.international,
201
+ absent: desig.absent,
202
+ term_type: desig.term_type ? "gloss:termtype/#{desig.term_type}" : nil,
203
+ concept_id: concept_id.to_s,
204
+ lang_code: (desig.language || lang).to_s,
205
+ index: index.to_s,
206
+ pronunciations: build_gloss_pronunciations(desig.pronunciation, concept_id, lang, index),
207
+ sources: build_gloss_sources(desig.sources),
208
+ }
209
+ end
210
+
211
+ def build_gloss_abbreviation(desig, common_attrs, concept_id, lang, index)
212
+ Rdf::GlossAbbreviation.new(common_attrs.merge(
213
+ prefix: desig.prefix,
214
+ usage_info: desig.usage_info,
215
+ field_of_application: desig.field_of_application,
216
+ acronym: desig.acronym,
217
+ initialism: desig.initialism,
218
+ truncation: desig.truncation,
219
+ grammar_info: build_gloss_grammar_infos(desig.grammar_info, concept_id, lang, index),
220
+ ))
221
+ end
222
+
223
+ def build_gloss_expression(desig, common_attrs, concept_id, lang, index)
224
+ Rdf::GlossExpression.new(common_attrs.merge(
225
+ prefix: desig.prefix,
226
+ usage_info: desig.usage_info,
227
+ field_of_application: desig.field_of_application,
228
+ grammar_info: build_gloss_grammar_infos(desig.grammar_info, concept_id, lang, index),
229
+ ))
230
+ end
231
+
232
+ def build_gloss_definitions(definitions)
233
+ Array(definitions).map do |dd|
234
+ Rdf::GlossDetailedDefinition.new(
235
+ content: dd.content,
236
+ sources: build_gloss_sources(dd.sources),
237
+ )
238
+ end
239
+ end
240
+
241
+ def build_gloss_sources(sources)
242
+ Array(sources).map do |src|
243
+ origin = src.origin ? build_gloss_citation(src.origin) : nil
244
+ Rdf::GlossConceptSource.new(
245
+ status: src.status ? "gloss:srcstatus/#{src.status}" : nil,
246
+ type: src.type ? "gloss:srctype/#{src.type}" : nil,
247
+ modification: src.modification,
248
+ origin: origin,
249
+ )
250
+ end
251
+ end
252
+
253
+ def build_gloss_citation(citation)
254
+ locality = citation.locality ? build_gloss_locality(citation.locality) : nil
255
+ ref = citation.ref
256
+
257
+ Rdf::GlossCitation.new(
258
+ source: ref&.source,
259
+ id: ref&.id,
260
+ version: ref&.version,
261
+ link: citation.link,
262
+ locality: locality,
263
+ )
264
+ end
265
+
266
+ def build_gloss_locality(loc)
267
+ Rdf::GlossLocality.new(
268
+ locality_type: loc.type,
269
+ reference_from: loc.reference_from,
270
+ reference_to: loc.reference_to,
271
+ )
272
+ end
273
+
274
+ def build_gloss_pronunciations(pronunciations, concept_id, lang, _desig_index)
275
+ Array(pronunciations).each_with_index.map do |pron, idx|
276
+ Rdf::GlossPronunciation.new(
277
+ content: pron.content,
278
+ language: pron.language,
279
+ script: pron.script,
280
+ country: pron.country,
281
+ system: pron.system,
282
+ concept_id: concept_id.to_s,
283
+ lang_code: lang.to_s,
284
+ index: idx.to_s,
285
+ )
286
+ end
287
+ end
288
+
289
+ def build_gloss_grammar_infos(grammar_infos, concept_id, lang, desig_index)
290
+ Array(grammar_infos).map do |gi|
291
+ Rdf::GlossGrammarInfo.new(
292
+ gender: Array(gi.gender).map { |g| "gloss:gender/#{g}" },
293
+ number: Array(gi.number).map { |n| "gloss:number/#{n}" },
294
+ part_of_speech: gi.part_of_speech,
295
+ concept_id: concept_id.to_s,
296
+ lang_code: lang.to_s,
297
+ index: desig_index.to_s,
298
+ )
299
+ end
300
+ end
301
+
302
+ def build_gloss_non_verbal_reps(non_verb_reps, concept_id, lang)
303
+ Array(non_verb_reps).each_with_index.map do |nvr, idx|
304
+ Rdf::GlossNonVerbalRep.new(
305
+ representation_type: nvr.type,
306
+ representation_ref: nvr.ref,
307
+ representation_text: nvr.text,
308
+ sources: build_gloss_sources(nvr.sources),
309
+ concept_id: concept_id.to_s,
310
+ lang_code: lang.to_s,
311
+ index: idx.to_s,
312
+ )
313
+ end
314
+ end
315
+
316
+ def build_gloss_domains(domains, concept_id)
317
+ Array(domains).map do |ref|
318
+ Rdf::GlossConceptReference.new(
319
+ concept_id: ref.concept_id,
320
+ source: ref.source,
321
+ ref_type: ref.ref_type,
322
+ urn: ref.urn,
323
+ parent_id: concept_id.to_s,
324
+ )
325
+ end
326
+ end
327
+
328
+ def build_gloss_dates(dates, concept_id)
329
+ Array(dates).map do |date|
330
+ Rdf::GlossConceptDate.new(
331
+ date_value: date.date&.to_s,
332
+ date_type: DATE_TYPE_MAP[date.type] || "gloss:status/#{date.type}",
333
+ concept_id: concept_id.to_s,
334
+ )
335
+ end
336
+ end
337
+
338
+ def build_relationship_triples(related_concepts)
339
+ Array(related_concepts).filter_map do |rc|
340
+ predicate_uri = REL_PROPERTY_MAP[rc.type]
341
+ next unless predicate_uri
342
+
343
+ target_id = rc.ref&.id
344
+ next unless target_id
345
+
346
+ [predicate_uri, "concept/#{target_id}"]
347
+ end
348
+ end
349
+
350
+ def status_uri(status)
351
+ status ? "gloss:status/#{status}" : nil
352
+ end
353
+ end
354
+ end
355
+ end
@@ -2,8 +2,8 @@
2
2
 
3
3
  module Glossarist
4
4
  module Transforms
5
- autoload :ConceptToSkosTransform,
6
- "glossarist/transforms/concept_to_skos_transform"
5
+ autoload :ConceptToGlossTransform,
6
+ "glossarist/transforms/concept_to_gloss_transform"
7
7
  autoload :ConceptToTbxTransform,
8
8
  "glossarist/transforms/concept_to_tbx_transform"
9
9
  end
@@ -48,23 +48,6 @@ module Glossarist
48
48
  mc
49
49
  end
50
50
 
51
- private
52
-
53
- def assign_domains(concept)
54
- concept.data.domains = groups.map do |g|
55
- ConceptReference.new(concept_id: g.to_s, ref_type: "domain")
56
- end
57
- end
58
-
59
- def assign_references(concept)
60
- l10n = concept.localization("eng") || concept.localizations.values.first
61
- return unless l10n
62
-
63
- l10n.data.references = references.map do |r|
64
- ConceptReference.new(r.transform_keys(&:to_sym))
65
- end
66
- end
67
-
68
51
  def lang_blocks_from(model, value)
69
52
  blocks = {}
70
53
  value.each do |key, v|
@@ -83,6 +66,23 @@ module Glossarist
83
66
  doc[lang] = data
84
67
  end
85
68
  end
69
+
70
+ private
71
+
72
+ def assign_domains(concept)
73
+ concept.data.domains = groups.map do |g|
74
+ ConceptReference.new(concept_id: g.to_s, ref_type: "domain")
75
+ end
76
+ end
77
+
78
+ def assign_references(concept)
79
+ l10n = concept.localization("eng") || concept.localizations.values.first
80
+ return unless l10n
81
+
82
+ l10n.data.references = references.map do |r|
83
+ ConceptReference.new(r.transform_keys(&:to_sym))
84
+ end
85
+ end
86
86
  end
87
87
  end
88
88
  end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glossarist
4
+ module V2
5
+ class Citation < Glossarist::Citation
6
+ attribute :text, :string
7
+
8
+ key_value do
9
+ map :ref, to: :text, with: { from: :ref_from_yaml, to: :ref_to_yaml }
10
+ map %i[clause locality],
11
+ to: :locality,
12
+ with: { from: :locality_from_yaml, to: :locality_to_yaml }
13
+ map :link, to: :link
14
+ map :original, to: :original
15
+ map %i[custom_locality customLocality], to: :custom_locality
16
+ end
17
+
18
+ def label
19
+ text
20
+ end
21
+
22
+ def ref_from_yaml(model, value)
23
+ model.text = case value
24
+ when Hash
25
+ value["source"] || value[:source]
26
+ when String
27
+ value
28
+ end
29
+ end
30
+
31
+ def ref_to_yaml(model, doc)
32
+ doc["ref"] = model.text if model.text
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glossarist
4
+ module V2
5
+ class ConceptData < Glossarist::ConceptData
6
+ attribute :sources, V2::ConceptSource,
7
+ collection: Collections::ConceptSourceCollection,
8
+ initialize_empty: true
9
+ attribute :definition, V2::DetailedDefinition,
10
+ collection: Collections::DetailedDefinitionCollection,
11
+ initialize_empty: true
12
+ attribute :examples, V2::DetailedDefinition,
13
+ collection: Collections::DetailedDefinitionCollection,
14
+ initialize_empty: true
15
+ attribute :notes, V2::DetailedDefinition,
16
+ collection: Collections::DetailedDefinitionCollection,
17
+ initialize_empty: true
18
+ attribute :related, V2::RelatedConcept, collection: true
19
+
20
+ key_value do
21
+ map :dates, to: :dates
22
+ map :definition, to: :definition, value_map: { to: { empty: :empty } }
23
+ map :examples, to: :examples, value_map: { to: { empty: :empty } }
24
+ map :id, to: :id
25
+ map %i[lineage_source_similarity lineageSourceSimilarity],
26
+ to: :lineage_source_similarity
27
+ map :notes, to: :notes, value_map: { to: { empty: :empty } }
28
+ map :release, to: :release
29
+ map :sources, to: :sources
30
+ map :terms, to: :terms,
31
+ with: { from: :terms_from_yaml, to: :terms_to_yaml }
32
+ map :related, to: :related
33
+ map :references, to: :references
34
+ map :domain, to: :domain
35
+ map %i[language_code languageCode], to: :language_code
36
+ map :script, to: :script
37
+ map :system, to: :system
38
+ map %i[entry_status entryStatus], to: :entry_status
39
+ map %i[review_date reviewDate], to: :review_date
40
+ map %i[review_decision_date reviewDecisionDate], to: :review_decision_date
41
+ map %i[review_decision_event reviewDecisionEvent],
42
+ to: :review_decision_event
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glossarist
4
+ module V2
5
+ class ConceptDocument < Glossarist::ConceptDocument
6
+ attribute :concept, V2::ManagedConcept
7
+ attribute :localizations, V2::LocalizedConcept, collection: true
8
+
9
+ yamls do
10
+ sequence do
11
+ map_document 0, to: :concept, type: V2::ManagedConcept
12
+ map_document 1.., to: :localizations, type: V2::LocalizedConcept,
13
+ collection: true
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glossarist
4
+ module V2
5
+ class ConceptRef < Glossarist::ConceptRef
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glossarist
4
+ module V2
5
+ class ConceptSource < Glossarist::ConceptSource
6
+ attribute :origin, V2::Citation
7
+
8
+ key_value do
9
+ map :origin, to: :origin
10
+ map :status, to: :status
11
+ map :type, to: :type
12
+ map :modification, to: :modification
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../context_configuration"
4
+
5
+ module Glossarist
6
+ module V2
7
+ module Configuration
8
+ extend Glossarist::ContextConfiguration
9
+
10
+ CONTEXT_ID = :glossarist_v2
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glossarist
4
+ module V2
5
+ class DetailedDefinition < Glossarist::DetailedDefinition
6
+ attribute :sources, V2::ConceptSource, collection: true
7
+
8
+ key_value do
9
+ map :content, to: :content
10
+ map :sources, to: :sources
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glossarist
4
+ module V2
5
+ class LocalizedConcept < Glossarist::LocalizedConcept
6
+ attribute :data, V2::ConceptData, default: -> { V2::ConceptData.new }
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glossarist
4
+ module V2
5
+ class ManagedConcept < Glossarist::ManagedConcept
6
+ attribute :data, V2::ManagedConceptData, default: -> { V2::ManagedConceptData.new }
7
+ attribute :related, V2::RelatedConcept, collection: true
8
+ attribute :sources, V2::ConceptSource, collection: true
9
+
10
+ key_value do
11
+ map :data, to: :data
12
+ map :id, with: { to: :identifier_to_yaml, from: :identifier_from_yaml }
13
+ map :identifier,
14
+ with: { to: :identifier_to_yaml, from: :identifier_from_yaml }
15
+ map :related, to: :related
16
+ map :dates, to: :dates
17
+ map %i[date_accepted dateAccepted],
18
+ with: { from: :date_accepted_from_yaml, to: :date_accepted_to_yaml }
19
+ map :status, to: :status
20
+ map :uuid, to: :uuid, with: { from: :uuid_from_yaml, to: :uuid_to_yaml }
21
+ map :sources, to: :sources
22
+ end
23
+ end
24
+ end
25
+ end