glossarist 2.8.1 → 2.8.4
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/.rubocop_todo.yml +413 -63
- data/CLAUDE.md +1 -1
- data/Gemfile +1 -1
- data/README.adoc +4 -1
- data/glossarist.gemspec +2 -1
- data/lib/glossarist/bibliography_data.rb +41 -0
- data/lib/glossarist/bibliography_entry.rb +13 -0
- data/lib/glossarist/citation.rb +8 -2
- data/lib/glossarist/cli/export_command.rb +10 -5
- data/lib/glossarist/cli/validate_command.rb +21 -5
- data/lib/glossarist/collection.rb +2 -2
- data/lib/glossarist/collections/bibliography_collection.rb +2 -1
- data/lib/glossarist/collections/collection.rb +2 -2
- data/lib/glossarist/collections/localization_collection.rb +4 -4
- data/lib/glossarist/concept_collector.rb +6 -6
- data/lib/glossarist/concept_document.rb +2 -3
- data/lib/glossarist/concept_manager.rb +6 -8
- data/lib/glossarist/concept_set.rb +4 -4
- data/lib/glossarist/concept_store.rb +84 -0
- data/lib/glossarist/dataset_validator.rb +2 -1
- data/lib/glossarist/gcr_package_definition.rb +37 -0
- data/lib/glossarist/gcr_statistics.rb +2 -2
- data/lib/glossarist/glossary_definition.rb +1 -1
- data/lib/glossarist/glossary_store.rb +201 -0
- data/lib/glossarist/managed_concept_collection.rb +2 -2
- data/lib/glossarist/managed_concept_data.rb +2 -0
- data/lib/glossarist/rdf/gloss_citation.rb +8 -4
- data/lib/glossarist/rdf/gloss_concept.rb +13 -4
- data/lib/glossarist/rdf/gloss_concept_date.rb +4 -2
- data/lib/glossarist/rdf/gloss_concept_reference.rb +6 -3
- data/lib/glossarist/rdf/gloss_concept_source.rb +6 -3
- data/lib/glossarist/rdf/gloss_designation.rb +63 -26
- data/lib/glossarist/rdf/gloss_grammar_info.rb +19 -9
- data/lib/glossarist/rdf/gloss_locality.rb +6 -3
- data/lib/glossarist/rdf/gloss_localized_concept.rb +14 -7
- data/lib/glossarist/rdf/gloss_non_verbal_rep.rb +9 -4
- data/lib/glossarist/rdf/gloss_pronunciation.rb +13 -6
- data/lib/glossarist/rdf/gloss_reference.rb +8 -4
- data/lib/glossarist/rdf/namespaces.rb +3 -2
- data/lib/glossarist/rdf/relationship_predicates.rb +79 -0
- data/lib/glossarist/rdf/v3/configuration.rb +0 -2
- data/lib/glossarist/rdf/v3.rb +4 -43
- data/lib/glossarist/rdf.rb +26 -23
- data/lib/glossarist/register_data.rb +68 -18
- data/lib/glossarist/schema_migration.rb +8 -5
- data/lib/glossarist/sts/importer.rb +0 -1
- data/lib/glossarist/transforms/concept_to_gloss_transform.rb +57 -72
- data/lib/glossarist/v2/concept_data.rb +2 -1
- data/lib/glossarist/v2/concept_document.rb +1 -1
- 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/concept_data.rb +2 -1
- data/lib/glossarist/v3/concept_document.rb +1 -1
- 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/asset_index.rb +2 -2
- data/lib/glossarist/validation/bibliography_index.rb +11 -8
- data/lib/glossarist/validation/rules/asciidoc_xref_rule.rb +2 -1
- data/lib/glossarist/validation/rules/authoritative_source_rule.rb +1 -1
- data/lib/glossarist/validation/rules/bibliography_yaml_rule.rb +1 -1
- data/lib/glossarist/validation/rules/citation_completeness_rule.rb +1 -1
- data/lib/glossarist/validation/rules/concept_count_rule.rb +2 -3
- data/lib/glossarist/validation/rules/concept_id_rule.rb +0 -1
- data/lib/glossarist/validation/rules/concept_id_uniqueness_rule.rb +0 -1
- data/lib/glossarist/validation/rules/concept_mention_rule.rb +1 -2
- data/lib/glossarist/validation/rules/concept_status_rule.rb +1 -2
- data/lib/glossarist/validation/rules/concept_uri_rule.rb +1 -1
- data/lib/glossarist/validation/rules/date_type_rule.rb +5 -3
- data/lib/glossarist/validation/rules/date_validity_rule.rb +1 -1
- data/lib/glossarist/validation/rules/definition_content_rule.rb +1 -2
- data/lib/glossarist/validation/rules/domain_target_rule.rb +1 -1
- data/lib/glossarist/validation/rules/duplicate_term_rule.rb +1 -2
- data/lib/glossarist/validation/rules/entry_status_rule.rb +1 -2
- data/lib/glossarist/validation/rules/filename_id_rule.rb +2 -3
- data/lib/glossarist/validation/rules/image_reference_rule.rb +3 -2
- data/lib/glossarist/validation/rules/l10n_uuid_integrity_rule.rb +1 -2
- data/lib/glossarist/validation/rules/language_coverage_rule.rb +1 -2
- data/lib/glossarist/validation/rules/language_list_rule.rb +2 -3
- data/lib/glossarist/validation/rules/locality_completeness_rule.rb +3 -1
- data/lib/glossarist/validation/rules/localization_consistency_rule.rb +1 -1
- data/lib/glossarist/validation/rules/localization_presence_rule.rb +0 -1
- data/lib/glossarist/validation/rules/model_validity_rule.rb +1 -1
- data/lib/glossarist/validation/rules/orphaned_bibliography_rule.rb +2 -1
- data/lib/glossarist/validation/rules/orphaned_images_rule.rb +6 -4
- data/lib/glossarist/validation/rules/orphaned_l10n_files_rule.rb +1 -2
- data/lib/glossarist/validation/rules/preferred_term_rule.rb +1 -2
- data/lib/glossarist/validation/rules/related_concept_cycle_rule.rb +2 -2
- data/lib/glossarist/validation/rules/related_concept_rule.rb +1 -2
- data/lib/glossarist/validation/rules/related_concept_symmetry_rule.rb +1 -1
- data/lib/glossarist/validation/rules/related_concept_target_rule.rb +1 -1
- data/lib/glossarist/validation/rules/source_type_rule.rb +2 -2
- data/lib/glossarist/validation/rules/source_urn_format_rule.rb +2 -2
- data/lib/glossarist/validation/rules/terms_presence_rule.rb +1 -1
- data/lib/glossarist/validation/rules/uuid_format_rule.rb +1 -1
- data/lib/glossarist/validation/rules.rb +18 -49
- data/lib/glossarist/version.rb +1 -1
- data/lib/glossarist.rb +13 -11
- data/scripts/migrate_dataset.rb +14 -8
- data/scripts/migrate_isotc204_to_v3.rb +3 -1
- data/scripts/migrate_isotc211_to_v3.rb +5 -3
- data/scripts/migrate_osgeo_to_v3.rb +4 -2
- data/scripts/upgrade_dataset_to_v3.rb +0 -0
- metadata +24 -11
- 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
|
@@ -26,7 +26,7 @@ module Glossarist
|
|
|
26
26
|
"related concept #{idx + 1} has invalid type '#{rel.type}'",
|
|
27
27
|
code: code, severity: severity,
|
|
28
28
|
location: fname,
|
|
29
|
-
suggestion: "Use one of: #{VALID_TYPES.join(', ')}"
|
|
29
|
+
suggestion: "Use one of: #{VALID_TYPES.join(', ')}"
|
|
30
30
|
)
|
|
31
31
|
end
|
|
32
32
|
end
|
|
@@ -37,4 +37,3 @@ module Glossarist
|
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
|
-
|
|
@@ -40,7 +40,7 @@ module Glossarist
|
|
|
40
40
|
next unless target_id
|
|
41
41
|
|
|
42
42
|
targets = index[target_id]
|
|
43
|
-
next if targets
|
|
43
|
+
next if targets&.any? { |r| r.type == inverse }
|
|
44
44
|
|
|
45
45
|
issues << issue(
|
|
46
46
|
"#{concept_id}: #{rel.type} #{target_id} but #{target_id} has no #{inverse} back-link",
|
|
@@ -6,7 +6,7 @@ module Glossarist
|
|
|
6
6
|
# Verifies that related concept refs point to concepts that exist
|
|
7
7
|
# in the dataset (for local refs) or have valid source/URN (for external).
|
|
8
8
|
class RelatedConceptTargetRule < Base
|
|
9
|
-
URN_RE = %r{\Aurn:[a-z0-9][a-z0-9-]{0,31}:[a-z0-9()+,\-.:=@;$_!*'%/?#]+\z}i
|
|
9
|
+
URN_RE = %r{\Aurn:[a-z0-9][a-z0-9-]{0,31}:[a-z0-9()+,\-.:=@;$_!*'%/?#]+\z}i
|
|
10
10
|
|
|
11
11
|
def code = "GLS-110"
|
|
12
12
|
def category = :references
|
|
@@ -27,7 +27,7 @@ module Glossarist
|
|
|
27
27
|
"source #{idx + 1} has invalid type '#{source.type}'",
|
|
28
28
|
code: "GLS-202", severity: severity,
|
|
29
29
|
location: fname,
|
|
30
|
-
suggestion: "Use one of: #{VALID_TYPES.join(', ')}"
|
|
30
|
+
suggestion: "Use one of: #{VALID_TYPES.join(', ')}"
|
|
31
31
|
)
|
|
32
32
|
end
|
|
33
33
|
|
|
@@ -37,7 +37,7 @@ module Glossarist
|
|
|
37
37
|
"source #{idx + 1} has invalid status '#{source.status}'",
|
|
38
38
|
code: "GLS-203", severity: severity,
|
|
39
39
|
location: fname,
|
|
40
|
-
suggestion: "Use one of: #{VALID_STATUSES.join(', ')}"
|
|
40
|
+
suggestion: "Use one of: #{VALID_STATUSES.join(', ')}"
|
|
41
41
|
)
|
|
42
42
|
end
|
|
43
43
|
|
|
@@ -6,7 +6,7 @@ module Glossarist
|
|
|
6
6
|
# Validates that every URN-format source in citations and references
|
|
7
7
|
# follows a recognized scheme (iso, iec, itu, etc).
|
|
8
8
|
class SourceUrnFormatRule < Base
|
|
9
|
-
URN_RE = %r{\Aurn:([a-z0-9][a-z0-9-]{0,31}):(.+)\z}i
|
|
9
|
+
URN_RE = %r{\Aurn:([a-z0-9][a-z0-9-]{0,31}):(.+)\z}i
|
|
10
10
|
|
|
11
11
|
KNOWN_SCHEMES = %w[
|
|
12
12
|
iso iec itu iso:std:iso iso:std:iec
|
|
@@ -27,7 +27,7 @@ module Glossarist
|
|
|
27
27
|
issues = []
|
|
28
28
|
|
|
29
29
|
all_refs(concept).each_with_index do |ref_str, idx|
|
|
30
|
-
next unless ref_str
|
|
30
|
+
next unless ref_str&.start_with?("urn:")
|
|
31
31
|
|
|
32
32
|
match = URN_RE.match(ref_str)
|
|
33
33
|
unless match
|
|
@@ -27,7 +27,7 @@ module Glossarist
|
|
|
27
27
|
"#{fname}/#{lang}: must have at least 1 term",
|
|
28
28
|
code: code, severity: severity,
|
|
29
29
|
location: "#{fname}/#{lang}",
|
|
30
|
-
suggestion: "Add at least one term/designation to this localization"
|
|
30
|
+
suggestion: "Add at least one term/designation to this localization"
|
|
31
31
|
)
|
|
32
32
|
end
|
|
33
33
|
|
|
@@ -4,7 +4,7 @@ module Glossarist
|
|
|
4
4
|
module Validation
|
|
5
5
|
module Rules
|
|
6
6
|
class UuidFormatRule < Base
|
|
7
|
-
UUID_RE = /\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/i
|
|
7
|
+
UUID_RE = /\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/i
|
|
8
8
|
|
|
9
9
|
def code = "GLS-016"
|
|
10
10
|
def category = :integrity
|
|
@@ -1,52 +1,21 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
module Glossarist
|
|
4
|
+
module Validation
|
|
5
|
+
module Rules
|
|
6
|
+
autoload :Base, "glossarist/validation/rules/base"
|
|
7
|
+
autoload :Registry, "glossarist/validation/rules/registry"
|
|
8
|
+
autoload :DatasetContext, "glossarist/validation/rules/dataset_context"
|
|
9
|
+
autoload :GcrContext, "glossarist/validation/rules/gcr_context"
|
|
10
|
+
autoload :ConceptContext, "glossarist/validation/rules/concept_context"
|
|
8
11
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
require_relative "rules/language_coverage_rule"
|
|
20
|
-
require_relative "rules/filename_id_rule"
|
|
21
|
-
require_relative "rules/l10n_uuid_integrity_rule"
|
|
22
|
-
require_relative "rules/orphaned_l10n_files_rule"
|
|
23
|
-
require_relative "rules/orphaned_bibliography_rule"
|
|
24
|
-
require_relative "rules/orphaned_images_rule"
|
|
25
|
-
require_relative "rules/definition_content_rule"
|
|
26
|
-
require_relative "rules/preferred_term_rule"
|
|
27
|
-
require_relative "rules/duplicate_term_rule"
|
|
28
|
-
require_relative "rules/citation_completeness_rule"
|
|
29
|
-
require_relative "rules/authoritative_source_rule"
|
|
30
|
-
require_relative "rules/related_concept_rule"
|
|
31
|
-
require_relative "rules/concept_status_rule"
|
|
32
|
-
require_relative "rules/source_type_rule"
|
|
33
|
-
require_relative "rules/terms_presence_rule"
|
|
34
|
-
require_relative "rules/bibliography_yaml_rule"
|
|
35
|
-
require_relative "rules/concept_uri_rule"
|
|
36
|
-
require_relative "rules/related_concept_symmetry_rule"
|
|
37
|
-
require_relative "rules/related_concept_cycle_rule"
|
|
38
|
-
require_relative "rules/designation_status_rule"
|
|
39
|
-
require_relative "rules/date_type_rule"
|
|
40
|
-
require_relative "rules/language_code_format_rule"
|
|
41
|
-
require_relative "rules/designation_type_rule"
|
|
42
|
-
require_relative "rules/date_validity_rule"
|
|
43
|
-
require_relative "rules/schema_version_rule"
|
|
44
|
-
require_relative "rules/ref_shape_rule"
|
|
45
|
-
require_relative "rules/locality_completeness_rule"
|
|
46
|
-
require_relative "rules/domain_ref_rule"
|
|
47
|
-
require_relative "rules/uuid_format_rule"
|
|
48
|
-
require_relative "rules/localization_consistency_rule"
|
|
49
|
-
require_relative "rules/related_concept_target_rule"
|
|
50
|
-
require_relative "rules/domain_target_rule"
|
|
51
|
-
require_relative "rules/source_urn_format_rule"
|
|
52
|
-
require_relative "rules/model_validity_rule"
|
|
12
|
+
RULES_DIR = File.join(__dir__, "rules")
|
|
13
|
+
|
|
14
|
+
# Eagerly load all rule files so they self-register via Base.inherited.
|
|
15
|
+
# Adding a new rule file requires zero changes here — just drop it in.
|
|
16
|
+
Dir.glob(File.join(RULES_DIR, "*_rule.rb")).each do |path|
|
|
17
|
+
require path
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
data/lib/glossarist/version.rb
CHANGED
data/lib/glossarist.rb
CHANGED
|
@@ -11,6 +11,8 @@ module Glossarist
|
|
|
11
11
|
autoload :Asset, "glossarist/asset"
|
|
12
12
|
autoload :AssetReference, "glossarist/asset_reference"
|
|
13
13
|
autoload :BibliographicReference, "glossarist/bibliographic_reference"
|
|
14
|
+
autoload :BibliographyData, "glossarist/bibliography_data"
|
|
15
|
+
autoload :BibliographyEntry, "glossarist/bibliography_entry"
|
|
14
16
|
autoload :Citation, "glossarist/citation"
|
|
15
17
|
autoload :CLI, "glossarist/cli"
|
|
16
18
|
autoload :CollectionConfig, "glossarist/collection_config"
|
|
@@ -27,11 +29,13 @@ module Glossarist
|
|
|
27
29
|
autoload :ConceptManager, "glossarist/concept_manager"
|
|
28
30
|
autoload :ConceptSet, "glossarist/concept_set"
|
|
29
31
|
autoload :ConceptSource, "glossarist/concept_source"
|
|
32
|
+
autoload :ConceptStore, "glossarist/concept_store"
|
|
30
33
|
autoload :ConceptValidator, "glossarist/concept_validator"
|
|
31
|
-
autoload :ConceptCollector,
|
|
32
|
-
autoload :ConceptComparator,
|
|
33
|
-
autoload :
|
|
34
|
-
autoload :
|
|
34
|
+
autoload :ConceptCollector, "glossarist/concept_collector"
|
|
35
|
+
autoload :ConceptComparator, "glossarist/concept_comparator"
|
|
36
|
+
autoload :ContextConfiguration, "glossarist/context_configuration"
|
|
37
|
+
autoload :ComparisonResult, "glossarist/comparison_result"
|
|
38
|
+
autoload :ConceptDiff, "glossarist/concept_diff"
|
|
35
39
|
autoload :ConceptDocument, "glossarist/concept_document"
|
|
36
40
|
autoload :ConceptEnricher, "glossarist/concept_enricher"
|
|
37
41
|
autoload :Config, "glossarist/config"
|
|
@@ -41,10 +45,11 @@ module Glossarist
|
|
|
41
45
|
autoload :Designation, "glossarist/designation"
|
|
42
46
|
autoload :Error, "glossarist/error"
|
|
43
47
|
autoload :GcrPackage, "glossarist/gcr_package"
|
|
48
|
+
autoload :GcrPackageDefinition, "glossarist/gcr_package_definition"
|
|
44
49
|
autoload :GcrMetadata, "glossarist/gcr_metadata"
|
|
45
50
|
autoload :GcrStatistics, "glossarist/gcr_statistics"
|
|
46
51
|
autoload :GcrValidator, "glossarist/gcr_validator"
|
|
47
|
-
autoload :InvalidTypeError,
|
|
52
|
+
autoload :InvalidTypeError, "glossarist/error/invalid_type_error"
|
|
48
53
|
autoload :InvalidLanguageCodeError,
|
|
49
54
|
"glossarist/error/invalid_language_code_error"
|
|
50
55
|
autoload :ParseError, "glossarist/error/parse_error"
|
|
@@ -70,13 +75,10 @@ module Glossarist
|
|
|
70
75
|
autoload :V1, "glossarist/v1"
|
|
71
76
|
autoload :V2, "glossarist/v2"
|
|
72
77
|
autoload :V3, "glossarist/v3"
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
require_relative "glossarist/collections"
|
|
77
|
-
require_relative "glossarist/glossary_definition"
|
|
78
|
+
autoload :VERSION, "glossarist/version"
|
|
79
|
+
autoload :GlossaryDefinition, "glossarist/glossary_definition"
|
|
80
|
+
autoload :GlossaryStore, "glossarist/glossary_store"
|
|
78
81
|
|
|
79
|
-
module Glossarist
|
|
80
82
|
LANG_CODES = %w[eng ara deu fra spa ita jpn kor pol por srp swe zho rus fin
|
|
81
83
|
dan nld msa nob nno].freeze
|
|
82
84
|
|
data/scripts/migrate_dataset.rb
CHANGED
|
@@ -45,7 +45,7 @@ def add_subject_area_concepts(collection)
|
|
|
45
45
|
end
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
-
existing_ids = collection.
|
|
48
|
+
existing_ids = collection.to_set { |c| c.data.id }
|
|
49
49
|
|
|
50
50
|
areas.each_key do |area_id|
|
|
51
51
|
next if existing_ids.include?(area_id)
|
|
@@ -83,7 +83,8 @@ def add_subject_area_concepts(collection)
|
|
|
83
83
|
),
|
|
84
84
|
)
|
|
85
85
|
|
|
86
|
-
mc.related = [Glossarist::RelatedConcept.new(type: "broader",
|
|
86
|
+
mc.related = [Glossarist::RelatedConcept.new(type: "broader",
|
|
87
|
+
content: area_id)]
|
|
87
88
|
|
|
88
89
|
section_code = parts.length > 1 ? parts[0..1].join("-") : parts[0]
|
|
89
90
|
l10n = build_domain_localization(section_id, section_code, "eng")
|
|
@@ -94,7 +95,7 @@ def add_subject_area_concepts(collection)
|
|
|
94
95
|
end
|
|
95
96
|
end
|
|
96
97
|
|
|
97
|
-
def build_domain_localization(id,
|
|
98
|
+
def build_domain_localization(id, _label, lang_code)
|
|
98
99
|
cd = Glossarist::ConceptData.new(
|
|
99
100
|
id: id,
|
|
100
101
|
language_code: lang_code,
|
|
@@ -133,6 +134,7 @@ if add_iev_domains
|
|
|
133
134
|
|
|
134
135
|
identifier = concept.data.id.to_s
|
|
135
136
|
next if identifier.empty? || identifier.start_with?("area-", "section-")
|
|
137
|
+
|
|
136
138
|
parts = identifier.split("-")
|
|
137
139
|
next unless parts.length >= 2
|
|
138
140
|
|
|
@@ -166,11 +168,15 @@ end
|
|
|
166
168
|
|
|
167
169
|
# Copy register.yaml if present
|
|
168
170
|
register_src = File.join(File.dirname(source_dir), "register.yaml")
|
|
169
|
-
if File.exist?(register_src) && !File.exist?(File.join(output_dir, "..",
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
171
|
+
if File.exist?(register_src) && !File.exist?(File.join(output_dir, "..",
|
|
172
|
+
"register.yaml"))
|
|
173
|
+
is_managed_format ? File.dirname(output_dir) : output_dir
|
|
174
|
+
register_dst = if File.exist?(File.join(File.dirname(source_dir),
|
|
175
|
+
"register.yaml"))
|
|
176
|
+
File.join(
|
|
177
|
+
is_managed_format ? File.dirname(output_dir) : File.dirname(output_dir), "register.yaml"
|
|
178
|
+
)
|
|
179
|
+
end
|
|
174
180
|
if register_dst
|
|
175
181
|
FileUtils.mkdir_p(File.dirname(register_dst))
|
|
176
182
|
FileUtils.cp(register_src, register_dst) unless register_src == register_dst
|
|
@@ -70,7 +70,9 @@ collection.each do |concept|
|
|
|
70
70
|
|
|
71
71
|
# Add broader relation to section
|
|
72
72
|
concept.related ||= []
|
|
73
|
-
unless concept.related.any?
|
|
73
|
+
unless concept.related.any? do |r|
|
|
74
|
+
r.type == "broader" && r.ref&.id == section_uri
|
|
75
|
+
end
|
|
74
76
|
concept.related << Glossarist::RelatedConcept.new(
|
|
75
77
|
type: "broader",
|
|
76
78
|
content: section_uri,
|
|
@@ -26,13 +26,13 @@ ISO_SOURCE_URN = "urn:iso:std:iso"
|
|
|
26
26
|
def extract_domain_id(ref_text)
|
|
27
27
|
# Match various ISO reference patterns
|
|
28
28
|
patterns = [
|
|
29
|
-
%r{ISO/IEC/IEEE\s+([\d-]+)},
|
|
29
|
+
%r{ISO/IEC/IEEE\s+([\d-]+)}, # ISO/IEC/IEEE 24765:2017
|
|
30
30
|
%r{ISO/IEC\s+([\d-]+)}, # ISO/IEC 19501:2005
|
|
31
31
|
%r{ISO/TS\s+([\d-]+)}, # ISO/TS 19130:2010
|
|
32
32
|
%r{ISO/TR\s+([\d-]+)}, # ISO/TR 19120:2001
|
|
33
33
|
%r{ISO/IEC\s+Guide\s+([\d-]+)}, # ISO/IEC Guide 98-3:2008
|
|
34
34
|
%r{ISO\s+DIS\s+([\d-]+)}, # ISO DIS 19123-1:2022
|
|
35
|
-
%r{ISO\s+(
|
|
35
|
+
%r{ISO\s+(\d+-?\d*)}, # ISO 19136-1:2020
|
|
36
36
|
]
|
|
37
37
|
|
|
38
38
|
patterns.each do |pat|
|
|
@@ -95,7 +95,9 @@ collection.each do |concept|
|
|
|
95
95
|
|
|
96
96
|
# Add broader relation to domain concept
|
|
97
97
|
concept.related ||= []
|
|
98
|
-
unless concept.related.any?
|
|
98
|
+
unless concept.related.any? do |r|
|
|
99
|
+
r.type == "broader" && r.ref&.id == domain_id
|
|
100
|
+
end
|
|
99
101
|
concept.related << Glossarist::RelatedConcept.new(
|
|
100
102
|
type: "broader",
|
|
101
103
|
content: domain_id,
|
|
@@ -32,7 +32,7 @@ def extract_domain_id(ref_text)
|
|
|
32
32
|
%r{ISO/IEC\s+([\d-]+)},
|
|
33
33
|
%r{ISO/TS\s+([\d-]+)},
|
|
34
34
|
%r{ISO/TR\s+([\d-]+)},
|
|
35
|
-
%r{ISO\s+(
|
|
35
|
+
%r{ISO\s+(\d+-?\d*)},
|
|
36
36
|
]
|
|
37
37
|
|
|
38
38
|
patterns.each do |pat|
|
|
@@ -95,7 +95,9 @@ collection.each do |concept|
|
|
|
95
95
|
|
|
96
96
|
# Add broader relation to domain concept
|
|
97
97
|
concept.related ||= []
|
|
98
|
-
unless concept.related.any?
|
|
98
|
+
unless concept.related.any? do |r|
|
|
99
|
+
r.type == "broader" && r.ref&.id == domain_id
|
|
100
|
+
end
|
|
99
101
|
concept.related << Glossarist::RelatedConcept.new(
|
|
100
102
|
type: "broader",
|
|
101
103
|
content: domain_id,
|
|
File without changes
|
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.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-06-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: lutaml-model
|
|
@@ -16,14 +16,28 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: 0.8.
|
|
19
|
+
version: 0.8.15
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: 0.8.
|
|
26
|
+
version: 0.8.15
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: lutaml-store
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: 0.2.0
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: 0.2.0
|
|
27
41
|
- !ruby/object:Gem::Dependency
|
|
28
42
|
name: paint
|
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -162,6 +176,8 @@ files:
|
|
|
162
176
|
- lib/glossarist/asset.rb
|
|
163
177
|
- lib/glossarist/asset_reference.rb
|
|
164
178
|
- lib/glossarist/bibliographic_reference.rb
|
|
179
|
+
- lib/glossarist/bibliography_data.rb
|
|
180
|
+
- lib/glossarist/bibliography_entry.rb
|
|
165
181
|
- lib/glossarist/citation.rb
|
|
166
182
|
- lib/glossarist/cli.rb
|
|
167
183
|
- lib/glossarist/cli/compare_command.rb
|
|
@@ -195,6 +211,7 @@ files:
|
|
|
195
211
|
- lib/glossarist/concept_reference.rb
|
|
196
212
|
- lib/glossarist/concept_set.rb
|
|
197
213
|
- lib/glossarist/concept_source.rb
|
|
214
|
+
- lib/glossarist/concept_store.rb
|
|
198
215
|
- lib/glossarist/concept_validator.rb
|
|
199
216
|
- lib/glossarist/config.rb
|
|
200
217
|
- lib/glossarist/context_configuration.rb
|
|
@@ -218,9 +235,11 @@ files:
|
|
|
218
235
|
- lib/glossarist/error/parse_error.rb
|
|
219
236
|
- lib/glossarist/gcr_metadata.rb
|
|
220
237
|
- lib/glossarist/gcr_package.rb
|
|
238
|
+
- lib/glossarist/gcr_package_definition.rb
|
|
221
239
|
- lib/glossarist/gcr_statistics.rb
|
|
222
240
|
- lib/glossarist/gcr_validator.rb
|
|
223
241
|
- lib/glossarist/glossary_definition.rb
|
|
242
|
+
- lib/glossarist/glossary_store.rb
|
|
224
243
|
- lib/glossarist/locality.rb
|
|
225
244
|
- lib/glossarist/localized_concept.rb
|
|
226
245
|
- lib/glossarist/managed_concept.rb
|
|
@@ -229,12 +248,6 @@ files:
|
|
|
229
248
|
- lib/glossarist/non_verb_rep.rb
|
|
230
249
|
- lib/glossarist/pronunciation.rb
|
|
231
250
|
- 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
251
|
- lib/glossarist/rdf/gloss_citation.rb
|
|
239
252
|
- lib/glossarist/rdf/gloss_concept.rb
|
|
240
253
|
- lib/glossarist/rdf/gloss_concept_date.rb
|
|
@@ -258,7 +271,7 @@ files:
|
|
|
258
271
|
- lib/glossarist/rdf/namespaces/rdf_namespace.rb
|
|
259
272
|
- lib/glossarist/rdf/namespaces/skos_namespace.rb
|
|
260
273
|
- lib/glossarist/rdf/namespaces/skosxl_namespace.rb
|
|
261
|
-
- lib/glossarist/rdf/
|
|
274
|
+
- lib/glossarist/rdf/relationship_predicates.rb
|
|
262
275
|
- lib/glossarist/rdf/v3.rb
|
|
263
276
|
- lib/glossarist/rdf/v3/configuration.rb
|
|
264
277
|
- lib/glossarist/reference_extractor.rb
|
|
@@ -1,208 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "json"
|
|
4
|
-
|
|
5
|
-
# Extends Lutaml::JsonLd::Transform to handle:
|
|
6
|
-
# - Multiple rdf:type values
|
|
7
|
-
# - URI-valued predicates (as: :uri)
|
|
8
|
-
# - Linking predicates for members (link option)
|
|
9
|
-
# - Recursive context/namespace collection
|
|
10
|
-
# - Recursive graph document building
|
|
11
|
-
module Lutaml
|
|
12
|
-
module JsonLd
|
|
13
|
-
class Transform < Lutaml::Rdf::Transform
|
|
14
|
-
def model_to_data(instance, _format, options = {})
|
|
15
|
-
mapping = extract_mapping(options)
|
|
16
|
-
return {} unless mapping
|
|
17
|
-
|
|
18
|
-
if mapping.rdf_members.any?
|
|
19
|
-
build_graph_document(mapping, instance)
|
|
20
|
-
else
|
|
21
|
-
build_resource_object(mapping, instance)
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def data_to_model(data, _format, options = {})
|
|
26
|
-
mapping = extract_mapping(options)
|
|
27
|
-
return model_class.new unless mapping
|
|
28
|
-
|
|
29
|
-
hash = data.is_a?(String) ? JSON.parse(data) : data
|
|
30
|
-
|
|
31
|
-
if hash.key?("@graph") && hash["@graph"].is_a?(Array) && !hash["@graph"].empty?
|
|
32
|
-
graph_data = hash["@graph"]
|
|
33
|
-
first = graph_data.first
|
|
34
|
-
hash = first.is_a?(Hash) ? first : {}
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
hash = strip_jsonld_keywords(hash)
|
|
38
|
-
|
|
39
|
-
attrs = {}
|
|
40
|
-
mapping.rdf_predicates.each do |rule|
|
|
41
|
-
value = hash[rule.predicate_name]
|
|
42
|
-
next if value.nil?
|
|
43
|
-
|
|
44
|
-
attrs[rule.to] = if rule.lang_tagged && value.is_a?(Hash)
|
|
45
|
-
flatten_language_map(value)
|
|
46
|
-
else
|
|
47
|
-
value
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
build_instance(attrs, options)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
private
|
|
55
|
-
|
|
56
|
-
def extract_mapping(options)
|
|
57
|
-
options[:mappings] || mappings_for(:jsonld, lutaml_register)
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def build_graph_document(mapping, instance)
|
|
61
|
-
context = build_merged_context_recursive(mapping, instance)
|
|
62
|
-
graph = collect_resources(mapping, instance)
|
|
63
|
-
|
|
64
|
-
{ "@context" => context, "@graph" => graph }
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def collect_resources(mapping, instance)
|
|
68
|
-
graph = []
|
|
69
|
-
|
|
70
|
-
if mapping.rdf_subject
|
|
71
|
-
resource = build_resource_data(mapping, instance)
|
|
72
|
-
graph << resource unless resource.empty?
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
mapping.rdf_members.each do |member_rule|
|
|
76
|
-
collection = Array(instance.public_send(member_rule.attr_name))
|
|
77
|
-
collection.each do |member|
|
|
78
|
-
member_mapping = member.class.mappings[:jsonld]
|
|
79
|
-
next unless member_mapping
|
|
80
|
-
|
|
81
|
-
resource = build_resource_data(member_mapping, member)
|
|
82
|
-
graph << resource unless resource.empty?
|
|
83
|
-
|
|
84
|
-
# Recurse into child members
|
|
85
|
-
child_resources = collect_resources(member_mapping, member)
|
|
86
|
-
# Skip the first entry (already added above) and any empty resources
|
|
87
|
-
child_resources[1..-1].each { |r| graph << r }
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
graph
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def build_merged_context_recursive(mapping, instance)
|
|
95
|
-
context_hash = build_context_from_mapping(mapping).to_hash
|
|
96
|
-
|
|
97
|
-
mapping.rdf_members.each do |member_rule|
|
|
98
|
-
collection = Array(instance.public_send(member_rule.attr_name))
|
|
99
|
-
next if collection.empty?
|
|
100
|
-
|
|
101
|
-
collection.map(&:class).uniq.each do |klass|
|
|
102
|
-
member_mapping = klass.mappings[:jsonld]
|
|
103
|
-
next unless member_mapping
|
|
104
|
-
|
|
105
|
-
context_hash.merge!(build_context_from_mapping(member_mapping).to_hash)
|
|
106
|
-
|
|
107
|
-
# Recurse into child members
|
|
108
|
-
child_ctx = build_merged_context_recursive(member_mapping, collection.first)
|
|
109
|
-
context_hash.merge!(child_ctx)
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
context_hash
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
def build_context_from_mapping(mapping)
|
|
117
|
-
context = Context.new
|
|
118
|
-
mapping.namespace_set.each { |ns| context.prefix(ns) }
|
|
119
|
-
mapping.rdf_predicates.each do |pred|
|
|
120
|
-
if pred.lang_tagged
|
|
121
|
-
context.term(pred.predicate_name,
|
|
122
|
-
id: pred.uri,
|
|
123
|
-
container: :language)
|
|
124
|
-
else
|
|
125
|
-
context.term(pred.predicate_name, id: pred.uri)
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
context
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
def build_resource_object(mapping, instance)
|
|
132
|
-
context = build_context_from_mapping(mapping).to_hash
|
|
133
|
-
data = build_resource_data(mapping, instance)
|
|
134
|
-
{ "@context" => context }.merge(data)
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
def build_resource_data(mapping, instance)
|
|
138
|
-
result = {}
|
|
139
|
-
|
|
140
|
-
if mapping.rdf_types.any?
|
|
141
|
-
types = mapping.rdf_types.map do |t|
|
|
142
|
-
mapping.namespace_set.resolve_compact_iri(t)
|
|
143
|
-
end
|
|
144
|
-
result["@type"] = types.length == 1 ? types.first : types
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
if mapping.rdf_subject
|
|
148
|
-
result["@id"] = resolve_subject_uri(mapping, instance)
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
mapping.rdf_predicates.each do |rule|
|
|
152
|
-
value = instance.public_send(rule.to)
|
|
153
|
-
next if value.nil?
|
|
154
|
-
next if value.is_a?(String) && value.empty?
|
|
155
|
-
|
|
156
|
-
result[rule.predicate_name] = if rule.lang_tagged
|
|
157
|
-
build_language_map(value)
|
|
158
|
-
else
|
|
159
|
-
serialize_rdf_value(value, rule, mapping)
|
|
160
|
-
end
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
# Emit variable-predicate relationship triples
|
|
164
|
-
if instance.is_a?(Glossarist::Rdf::Relationships)
|
|
165
|
-
Array(instance.relationship_triples).each do |pred_uri, obj_uri|
|
|
166
|
-
key = pred_uri.split("#").last.split("/").last
|
|
167
|
-
result[key] = { "@id" => obj_uri }
|
|
168
|
-
end
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
result
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
def build_language_map(values)
|
|
175
|
-
case values
|
|
176
|
-
when Array
|
|
177
|
-
map = {}
|
|
178
|
-
values.each do |v|
|
|
179
|
-
lang = extract_language(v)
|
|
180
|
-
map[lang] = v.to_s if lang
|
|
181
|
-
end
|
|
182
|
-
map.empty? ? nil : map
|
|
183
|
-
else
|
|
184
|
-
lang = extract_language(values)
|
|
185
|
-
lang ? { lang => values.to_s } : values.to_s
|
|
186
|
-
end
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
def flatten_language_map(lang_map)
|
|
190
|
-
lang_map.values
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
def serialize_rdf_value(value, rule = nil, mapping = nil)
|
|
194
|
-
case value
|
|
195
|
-
when Array then value.map { |v| serialize_rdf_value(v, rule, mapping) }
|
|
196
|
-
when Integer, Float, TrueClass, FalseClass then value
|
|
197
|
-
else value.to_s
|
|
198
|
-
end
|
|
199
|
-
end
|
|
200
|
-
|
|
201
|
-
def strip_jsonld_keywords(data)
|
|
202
|
-
return data unless data.is_a?(Hash)
|
|
203
|
-
|
|
204
|
-
data.reject { |key, _| key.start_with?("@") }
|
|
205
|
-
end
|
|
206
|
-
end
|
|
207
|
-
end
|
|
208
|
-
end
|