glossarist 2.8.10 → 2.8.11
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/lib/glossarist/concept_data.rb +2 -2
- data/lib/glossarist/concept_set.rb +5 -1
- data/lib/glossarist/managed_concept.rb +15 -15
- data/lib/glossarist/sts/term_extractor.rb +3 -2
- data/lib/glossarist/transforms/concept_to_gloss_transform.rb +1 -1
- data/lib/glossarist/v2/managed_concept.rb +2 -4
- data/lib/glossarist/v3/managed_concept.rb +2 -4
- data/lib/glossarist/validation/rules/asciidoc_xref_rule.rb +11 -21
- data/lib/glossarist/validation/rules/cite_ref_integrity_rule.rb +5 -6
- data/lib/glossarist/validation/rules/concept_context.rb +24 -0
- data/lib/glossarist/validation/rules/concept_mention_rule.rb +1 -3
- data/lib/glossarist/validation/rules/image_reference_rule.rb +10 -21
- data/lib/glossarist/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9c5365426551b5a43eb67d58bd80ec429cc27c7c2d374f45abb7911da3dde329
|
|
4
|
+
data.tar.gz: 86394c15f0f7c8db4101682aeb99f2c44aa89f79012c931a59365d3426488a39
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7434ab207294cbbf27f257a3368e7a7e588594d87fd6a3c896668625625c587dc135609664991e7ebd91077429a7d3bc6a7f2aee46d015666048be32a4f830ba
|
|
7
|
+
data.tar.gz: 745e77b7e667e43fd05d1b96ab44d44c808092f5c2547e95ffa8d84bca1115d21a0d8756d917eaefc024ba78cf51f2e4818e077b0a74492d2b1383304043a256
|
|
@@ -86,7 +86,7 @@ module Glossarist
|
|
|
86
86
|
def all_sources
|
|
87
87
|
list = sources.to_a
|
|
88
88
|
self.class.detailed_definition_fields.each do |field|
|
|
89
|
-
|
|
89
|
+
public_send(field).each { |d| list.concat(d.sources.to_a) }
|
|
90
90
|
end
|
|
91
91
|
Array(terms).each { |t| list.concat(Array(t.sources)) }
|
|
92
92
|
list
|
|
@@ -95,7 +95,7 @@ module Glossarist
|
|
|
95
95
|
def text_content
|
|
96
96
|
texts = []
|
|
97
97
|
self.class.detailed_definition_fields.each do |field|
|
|
98
|
-
|
|
98
|
+
public_send(field).each { |d| texts << d.content if d.content }
|
|
99
99
|
end
|
|
100
100
|
texts
|
|
101
101
|
end
|
|
@@ -67,7 +67,11 @@ module Glossarist
|
|
|
67
67
|
|
|
68
68
|
def normalize_definition(definition)
|
|
69
69
|
definition.gsub(/{{([^}]*)}}/) do |_match|
|
|
70
|
-
|
|
70
|
+
inner = Regexp.last_match[1]
|
|
71
|
+
# Mention syntax: {{identifier}} or {{identifier, render term}}
|
|
72
|
+
# Use the identifier (first part before comma) as the gloss label.
|
|
73
|
+
label = inner.split(",", 2).first.strip.tr("_", "-")
|
|
74
|
+
"\\textbf{\\gls{#{label}}}"
|
|
71
75
|
end
|
|
72
76
|
end
|
|
73
77
|
|
|
@@ -13,19 +13,28 @@ module Glossarist
|
|
|
13
13
|
attribute :status, :string,
|
|
14
14
|
values: Glossarist::GlossaryDefinition::CONCEPT_STATUSES
|
|
15
15
|
|
|
16
|
-
attribute :identifier, :string
|
|
17
|
-
alias :id :identifier
|
|
18
|
-
alias :id= :identifier=
|
|
19
|
-
|
|
20
16
|
attribute :uuid, :string
|
|
21
17
|
|
|
22
18
|
attribute :version, :string
|
|
23
19
|
attribute :schema_version, :string
|
|
24
20
|
|
|
21
|
+
# identifier and id are aliases for uuid — the concept's canonical
|
|
22
|
+
# identity. There is one source of truth: uuid, serialized to the
|
|
23
|
+
# YAML "id" key. Having separate identifier/uuid attributes that both
|
|
24
|
+
# map to the same key caused dual-mapping fragility.
|
|
25
|
+
def identifier
|
|
26
|
+
uuid
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def identifier=(value)
|
|
30
|
+
self.uuid = value
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
alias :id :identifier
|
|
34
|
+
alias :id= :identifier=
|
|
35
|
+
|
|
25
36
|
key_value do
|
|
26
37
|
map :data, to: :data
|
|
27
|
-
map :identifier,
|
|
28
|
-
with: { to: :identifier_to_yaml, from: :identifier_from_yaml }
|
|
29
38
|
map :related, to: :related
|
|
30
39
|
map :dates, to: :dates
|
|
31
40
|
map :sources, to: :sources
|
|
@@ -74,15 +83,6 @@ module Glossarist
|
|
|
74
83
|
)
|
|
75
84
|
end
|
|
76
85
|
|
|
77
|
-
def identifier_to_yaml(model, doc)
|
|
78
|
-
value = model.identifier || model.id
|
|
79
|
-
doc["id"] = value if value && !doc["id"]
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
def identifier_from_yaml(model, value)
|
|
83
|
-
model.identifier = value || model.identifier
|
|
84
|
-
end
|
|
85
|
-
|
|
86
86
|
def localized_concepts=(localized_concepts_collection) # rubocop:disable Metrics/AbcSize
|
|
87
87
|
return unless localized_concepts_collection
|
|
88
88
|
|
|
@@ -253,9 +253,10 @@ module Glossarist
|
|
|
253
253
|
end
|
|
254
254
|
|
|
255
255
|
def extract_ref_text(ref)
|
|
256
|
-
|
|
256
|
+
case ref
|
|
257
|
+
when ::Sts::IsoSts::StdRef
|
|
257
258
|
normalize_whitespace(ref.content.join.to_s)
|
|
258
|
-
|
|
259
|
+
when ::Sts::NisoSts::StandardRef
|
|
259
260
|
normalize_whitespace(ref.value.to_s)
|
|
260
261
|
else
|
|
261
262
|
""
|
|
@@ -122,7 +122,7 @@ module Glossarist
|
|
|
122
122
|
|
|
123
123
|
dd_attrs = if data
|
|
124
124
|
data.class.detailed_definition_fields.to_h do |field|
|
|
125
|
-
[field, build_gloss_definitions(data.
|
|
125
|
+
[field, build_gloss_definitions(data.public_send(field))]
|
|
126
126
|
end
|
|
127
127
|
else
|
|
128
128
|
{ definition: [], notes: [], examples: [] }
|
|
@@ -9,15 +9,13 @@ module Glossarist
|
|
|
9
9
|
|
|
10
10
|
key_value do
|
|
11
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
12
|
map :related, to: :related
|
|
16
13
|
map :dates, to: :dates
|
|
17
14
|
map %i[date_accepted dateAccepted],
|
|
18
15
|
with: { from: :date_accepted_from_yaml, to: :date_accepted_to_yaml }
|
|
19
16
|
map :status, to: :status
|
|
20
|
-
map
|
|
17
|
+
map %i[id uuid], to: :uuid,
|
|
18
|
+
with: { from: :uuid_from_yaml, to: :uuid_to_yaml }
|
|
21
19
|
map :sources, to: :sources
|
|
22
20
|
end
|
|
23
21
|
end
|
|
@@ -9,15 +9,13 @@ module Glossarist
|
|
|
9
9
|
|
|
10
10
|
key_value do
|
|
11
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
12
|
map :related, to: :related
|
|
16
13
|
map :dates, to: :dates
|
|
17
14
|
map %i[date_accepted dateAccepted],
|
|
18
15
|
with: { from: :date_accepted_from_yaml, to: :date_accepted_to_yaml }
|
|
19
16
|
map :status, to: :status
|
|
20
|
-
map
|
|
17
|
+
map %i[id uuid], to: :uuid,
|
|
18
|
+
with: { from: :uuid_from_yaml, to: :uuid_to_yaml }
|
|
21
19
|
map :schema_version, to: :schema_version
|
|
22
20
|
map :sources, to: :sources
|
|
23
21
|
end
|
|
@@ -14,30 +14,20 @@ module Glossarist
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def check(context)
|
|
17
|
-
concept = context.concept
|
|
18
17
|
fname = context.file_name
|
|
19
|
-
extractor = ReferenceExtractor.new
|
|
20
18
|
issues = []
|
|
21
19
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"unresolved bibliography reference <<#{ref.anchor}>>",
|
|
34
|
-
code: code, severity: severity,
|
|
35
|
-
location: "#{fname}/#{lang}",
|
|
36
|
-
suggestion: "add '#{ref.anchor}' as a source, " \
|
|
37
|
-
"or verify it exists in bibliography.yaml"
|
|
38
|
-
)
|
|
39
|
-
end
|
|
40
|
-
end
|
|
20
|
+
context.references.each do |ref|
|
|
21
|
+
next unless ref.is_a?(BibliographicReference)
|
|
22
|
+
next if context.bibliography_index.resolve?(ref.anchor)
|
|
23
|
+
|
|
24
|
+
issues << issue(
|
|
25
|
+
"unresolved bibliography reference <<#{ref.anchor}>>",
|
|
26
|
+
code: code, severity: severity,
|
|
27
|
+
location: fname,
|
|
28
|
+
suggestion: "add '#{ref.anchor}' as a source, " \
|
|
29
|
+
"or verify it exists in bibliography.yaml"
|
|
30
|
+
)
|
|
41
31
|
end
|
|
42
32
|
|
|
43
33
|
issues
|
|
@@ -19,7 +19,7 @@ module Glossarist
|
|
|
19
19
|
issues = []
|
|
20
20
|
|
|
21
21
|
check_unique_source_ids(concept, fname, issues)
|
|
22
|
-
check_unresolved_mentions(concept, fname, issues)
|
|
22
|
+
check_unresolved_mentions(context, concept, fname, issues)
|
|
23
23
|
|
|
24
24
|
issues
|
|
25
25
|
end
|
|
@@ -46,8 +46,8 @@ module Glossarist
|
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
-
def check_unresolved_mentions(concept, fname, issues)
|
|
50
|
-
keys = cite_mention_keys(
|
|
49
|
+
def check_unresolved_mentions(context, concept, fname, issues)
|
|
50
|
+
keys = cite_mention_keys(context)
|
|
51
51
|
return if keys.empty?
|
|
52
52
|
|
|
53
53
|
known_ids = concept.all_sources.filter_map(&:id).to_set
|
|
@@ -63,9 +63,8 @@ module Glossarist
|
|
|
63
63
|
end
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
-
def cite_mention_keys(
|
|
67
|
-
|
|
68
|
-
extractor.extract_from_managed_concept(concept)
|
|
66
|
+
def cite_mention_keys(context)
|
|
67
|
+
context.references
|
|
69
68
|
.select(&:cite?)
|
|
70
69
|
.filter_map(&:concept_id)
|
|
71
70
|
end
|
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
module Glossarist
|
|
4
4
|
module Validation
|
|
5
5
|
module Rules
|
|
6
|
+
# Shared context for concept-scoped validation rules.
|
|
7
|
+
#
|
|
8
|
+
# Provides lazy-memoized access to extracted references so that multiple
|
|
9
|
+
# rules examining the same concept share one extraction pass (DRY,
|
|
10
|
+
# single source of truth). Rules ask the context for references rather
|
|
11
|
+
# than instantiating their own ReferenceExtractor.
|
|
6
12
|
class ConceptContext
|
|
7
13
|
attr_reader :concept, :file_name, :collection_context
|
|
8
14
|
|
|
@@ -16,6 +22,24 @@ module Glossarist
|
|
|
16
22
|
@concept.data&.id&.to_s
|
|
17
23
|
end
|
|
18
24
|
|
|
25
|
+
# All references extracted from the concept's text fields
|
|
26
|
+
# (definitions, notes, examples) via {{...}} mentions, <<xrefs>>,
|
|
27
|
+
# and image::...[] references. Includes ConceptReference,
|
|
28
|
+
# BibliographicReference, and AssetReference objects.
|
|
29
|
+
# Memoized — extracted once per concept, shared across all rules.
|
|
30
|
+
def references
|
|
31
|
+
@references ||= ReferenceExtractor.new
|
|
32
|
+
.extract_from_managed_concept(@concept)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# All asset references (NonVerbRep, GraphicalSymbol) extracted
|
|
36
|
+
# from the concept's model attributes.
|
|
37
|
+
# Memoized — extracted once per concept, shared across all rules.
|
|
38
|
+
def asset_references
|
|
39
|
+
@asset_references ||= ReferenceExtractor.new
|
|
40
|
+
.extract_asset_refs_from_concept(@concept)
|
|
41
|
+
end
|
|
42
|
+
|
|
19
43
|
def bibliography_index
|
|
20
44
|
@collection_context.bibliography_index
|
|
21
45
|
end
|
|
@@ -14,12 +14,10 @@ module Glossarist
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def check(context)
|
|
17
|
-
concept = context.concept
|
|
18
17
|
fname = context.file_name
|
|
19
|
-
extractor = ReferenceExtractor.new
|
|
20
18
|
issues = []
|
|
21
19
|
|
|
22
|
-
refs =
|
|
20
|
+
refs = context.references
|
|
23
21
|
.select { |r| r.is_a?(ConceptReference) && r.local? }
|
|
24
22
|
|
|
25
23
|
refs.each do |ref|
|
|
@@ -14,33 +14,22 @@ module Glossarist
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def check(context)
|
|
17
|
-
concept = context.concept
|
|
18
17
|
fname = context.file_name
|
|
19
|
-
extractor = ReferenceExtractor.new
|
|
20
18
|
issues = []
|
|
21
19
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
l10n.text_content.each do |text|
|
|
26
|
-
next unless text
|
|
27
|
-
|
|
28
|
-
extractor.extract_from_text(text).each do |ref|
|
|
29
|
-
next unless ref.is_a?(AssetReference)
|
|
30
|
-
next if context.asset_index.resolve?(ref.path)
|
|
20
|
+
context.references.each do |ref|
|
|
21
|
+
next unless ref.is_a?(AssetReference)
|
|
22
|
+
next if context.asset_index.resolve?(ref.path)
|
|
31
23
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
end
|
|
39
|
-
end
|
|
24
|
+
issues << issue(
|
|
25
|
+
"unresolved image reference #{ref.path}",
|
|
26
|
+
code: "GLS-103", severity: severity,
|
|
27
|
+
location: fname,
|
|
28
|
+
suggestion: "add '#{ref.path}' to the dataset's images/ directory"
|
|
29
|
+
)
|
|
40
30
|
end
|
|
41
31
|
|
|
42
|
-
|
|
43
|
-
asset_refs.each do |ref|
|
|
32
|
+
context.asset_references.each do |ref|
|
|
44
33
|
next if context.asset_index.resolve?(ref.path)
|
|
45
34
|
|
|
46
35
|
issues << issue(
|
data/lib/glossarist/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: glossarist
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.8.
|
|
4
|
+
version: 2.8.11
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-06-
|
|
11
|
+
date: 2026-06-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: lutaml-model
|