glossarist 2.6.4 → 2.6.5

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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +11 -111
  3. data/Gemfile +0 -2
  4. data/README.adoc +207 -1
  5. data/glossarist.gemspec +1 -1
  6. data/lib/glossarist/asset_reference.rb +16 -0
  7. data/lib/glossarist/bibliographic_reference.rb +16 -0
  8. data/lib/glossarist/concept_enricher.rb +1 -0
  9. data/lib/glossarist/concept_reference.rb +4 -0
  10. data/lib/glossarist/concept_validator.rb +27 -56
  11. data/lib/glossarist/dataset_validator.rb +30 -34
  12. data/lib/glossarist/gcr_validator.rb +26 -101
  13. data/lib/glossarist/reference_extractor.rb +80 -10
  14. data/lib/glossarist/reference_resolver.rb +1 -0
  15. data/lib/glossarist/validation/asset_index.rb +113 -0
  16. data/lib/glossarist/validation/bibliography_index.rb +121 -0
  17. data/lib/glossarist/validation/rules/asciidoc_xref_rule.rb +60 -0
  18. data/lib/glossarist/validation/rules/authoritative_source_rule.rb +47 -0
  19. data/lib/glossarist/validation/rules/base.rb +46 -0
  20. data/lib/glossarist/validation/rules/bibliography_yaml_rule.rb +37 -0
  21. data/lib/glossarist/validation/rules/citation_completeness_rule.rb +63 -0
  22. data/lib/glossarist/validation/rules/concept_context.rb +45 -0
  23. data/lib/glossarist/validation/rules/concept_count_rule.rb +34 -0
  24. data/lib/glossarist/validation/rules/concept_id_rule.rb +29 -0
  25. data/lib/glossarist/validation/rules/concept_id_uniqueness_rule.rb +42 -0
  26. data/lib/glossarist/validation/rules/concept_mention_rule.rb +44 -0
  27. data/lib/glossarist/validation/rules/concept_status_rule.rb +36 -0
  28. data/lib/glossarist/validation/rules/concept_uri_rule.rb +30 -0
  29. data/lib/glossarist/validation/rules/dataset_context.rb +99 -0
  30. data/lib/glossarist/validation/rules/date_type_rule.rb +54 -0
  31. data/lib/glossarist/validation/rules/date_validity_rule.rb +66 -0
  32. data/lib/glossarist/validation/rules/definition_content_rule.rb +41 -0
  33. data/lib/glossarist/validation/rules/designation_status_rule.rb +45 -0
  34. data/lib/glossarist/validation/rules/designation_type_rule.rb +55 -0
  35. data/lib/glossarist/validation/rules/duplicate_term_rule.rb +63 -0
  36. data/lib/glossarist/validation/rules/entry_status_rule.rb +39 -0
  37. data/lib/glossarist/validation/rules/filename_id_rule.rb +35 -0
  38. data/lib/glossarist/validation/rules/gcr_context.rb +92 -0
  39. data/lib/glossarist/validation/rules/image_reference_rule.rb +73 -0
  40. data/lib/glossarist/validation/rules/l10n_uuid_integrity_rule.rb +40 -0
  41. data/lib/glossarist/validation/rules/language_code_format_rule.rb +39 -0
  42. data/lib/glossarist/validation/rules/language_coverage_rule.rb +37 -0
  43. data/lib/glossarist/validation/rules/language_list_rule.rb +46 -0
  44. data/lib/glossarist/validation/rules/localization_presence_rule.rb +25 -0
  45. data/lib/glossarist/validation/rules/orphaned_bibliography_rule.rb +64 -0
  46. data/lib/glossarist/validation/rules/orphaned_images_rule.rb +68 -0
  47. data/lib/glossarist/validation/rules/orphaned_l10n_files_rule.rb +39 -0
  48. data/lib/glossarist/validation/rules/preferred_term_rule.rb +41 -0
  49. data/lib/glossarist/validation/rules/registry.rb +42 -0
  50. data/lib/glossarist/validation/rules/related_concept_cycle_rule.rb +102 -0
  51. data/lib/glossarist/validation/rules/related_concept_rule.rb +40 -0
  52. data/lib/glossarist/validation/rules/related_concept_symmetry_rule.rb +87 -0
  53. data/lib/glossarist/validation/rules/source_type_rule.rb +63 -0
  54. data/lib/glossarist/validation/rules/terms_presence_rule.rb +39 -0
  55. data/lib/glossarist/validation/rules.rb +85 -0
  56. data/lib/glossarist/validation/validation_issue.rb +39 -0
  57. data/lib/glossarist/validation.rb +12 -0
  58. data/lib/glossarist/validation_result.rb +26 -9
  59. data/lib/glossarist/version.rb +1 -1
  60. data/lib/glossarist.rb +3 -0
  61. metadata +60 -15
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glossarist
4
+ module Validation
5
+ module Rules
6
+ class OrphanedBibliographyRule < Base
7
+ def code = "GLS-020"
8
+ def category = :references
9
+ def severity = "warning"
10
+ def scope = :collection
11
+
12
+ def applicable?(context)
13
+ context.bibliography_index.entries.any?
14
+ end
15
+
16
+ def check(context)
17
+ extractor = ReferenceExtractor.new
18
+ bib_index = context.bibliography_index
19
+ referenced_anchors = Set.new
20
+
21
+ context.concepts.each do |concept|
22
+ concept.localizations.each do |l10n|
23
+ texts = extract_texts(l10n)
24
+ texts.each do |text|
25
+ next unless text
26
+ extractor.extract_from_text(text).each do |ref|
27
+ if ref.is_a?(BibliographicReference)
28
+ referenced_anchors.add(ref.anchor)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ issues = []
36
+ bib_index.each_entry do |entry|
37
+ next if referenced_anchors.any? { |a| bib_index.resolve?(a) }
38
+
39
+ anchor = entry[:anchor]
40
+ issues << issue(
41
+ "Orphaned bibliography entry: '#{anchor}'",
42
+ code: code, severity: severity,
43
+ location: "bibliography.yaml",
44
+ suggestion: "Remove the entry or reference it from a concept",
45
+ )
46
+ end
47
+
48
+ issues
49
+ end
50
+
51
+ private
52
+
53
+ def extract_texts(l10n)
54
+ texts = []
55
+ (l10n.data&.definition || []).each { |d| texts << d.content if d.content }
56
+ (l10n.data&.notes || []).each { |n| texts << n.content if n.content }
57
+ (l10n.data&.examples || []).each { |e| texts << e.content if e.content }
58
+ texts
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glossarist
4
+ module Validation
5
+ module Rules
6
+ class OrphanedImagesRule < Base
7
+ def code = "GLS-021"
8
+ def category = :references
9
+ def severity = "warning"
10
+ def scope = :collection
11
+
12
+ def applicable?(context)
13
+ context.asset_index.paths.any?
14
+ end
15
+
16
+ def check(context)
17
+ extractor = ReferenceExtractor.new
18
+ referenced_paths = Set.new
19
+
20
+ context.concepts.each do |concept|
21
+ # Text-embedded image refs
22
+ concept.localizations.each do |l10n|
23
+ texts = extract_texts(l10n)
24
+ texts.each do |text|
25
+ next unless text
26
+ extractor.extract_from_text(text).each do |ref|
27
+ if ref.is_a?(AssetReference)
28
+ referenced_paths.add(ref.path)
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ # Model-level asset refs
35
+ extractor.extract_asset_refs_from_concept(concept).each do |ref|
36
+ referenced_paths.add(ref.path)
37
+ end
38
+ end
39
+
40
+ issues = []
41
+ context.asset_index.each_path do |path|
42
+ next if referenced_paths.include?(path)
43
+
44
+ issues << issue(
45
+ "Orphaned image: #{path} (not referenced by any concept)",
46
+ code: code, severity: severity,
47
+ location: path,
48
+ suggestion: "Remove the image or reference it from a concept",
49
+ )
50
+ end
51
+
52
+ issues
53
+ end
54
+
55
+ private
56
+
57
+ def extract_texts(l10n)
58
+ texts = []
59
+ (l10n.data&.definition || []).each { |d| texts << d.content if d.content }
60
+ (l10n.data&.notes || []).each { |n| texts << n.content if n.content }
61
+ (l10n.data&.examples || []).each { |e| texts << e.content if e.content }
62
+ texts
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glossarist
4
+ module Validation
5
+ module Rules
6
+ class OrphanedL10nFilesRule < Base
7
+ def code = "GLS-019"
8
+ def category = :integrity
9
+ def severity = "warning"
10
+ def scope = :collection
11
+
12
+ def applicable?(context)
13
+ context.localization_index.any?
14
+ end
15
+
16
+ def check(context)
17
+ lc_index = context.localization_index
18
+ referenced = context.referenced_l10n_uuids
19
+ issues = []
20
+
21
+ lc_index.each do |uuid, path|
22
+ next if referenced.include?(uuid)
23
+
24
+ issues << issue(
25
+ "Orphaned localization file: #{File.basename(path)} " \
26
+ "(not referenced by any concept)",
27
+ code: code, severity: severity,
28
+ location: File.basename(path),
29
+ suggestion: "Delete the file or add a reference from a managed concept",
30
+ )
31
+ end
32
+
33
+ issues
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glossarist
4
+ module Validation
5
+ module Rules
6
+ class PreferredTermRule < Base
7
+ def code = "GLS-301"
8
+ def category = :quality
9
+ def severity = "warning"
10
+ def scope = :concept
11
+
12
+ def applicable?(context)
13
+ context.concept.localizations&.any?
14
+ end
15
+
16
+ def check(context)
17
+ concept = context.concept
18
+ fname = context.file_name
19
+ issues = []
20
+
21
+ concept.localizations.each do |l10n|
22
+ lang = l10n.language_code || "unknown"
23
+ terms = l10n.data&.terms || []
24
+ next if terms.empty?
25
+ next if terms.any? { |t| t.normative_status == "preferred" }
26
+
27
+ issues << issue(
28
+ "has #{terms.size} term(s) but none are preferred",
29
+ code: code, severity: severity,
30
+ location: "#{fname}/#{lang}",
31
+ suggestion: "Set normative_status: preferred on the primary term",
32
+ )
33
+ end
34
+
35
+ issues
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glossarist
4
+ module Validation
5
+ module Rules
6
+ module Registry
7
+ @rules = []
8
+ @mutex = Mutex.new
9
+
10
+ def self.register(rule_class)
11
+ @mutex.synchronize do
12
+ @rules << rule_class unless @rules.include?(rule_class)
13
+ end
14
+ end
15
+
16
+ def self.all
17
+ @rules.map(&:new)
18
+ end
19
+
20
+ def self.for_category(category)
21
+ all.select { |r| r.category == category }
22
+ end
23
+
24
+ def self.for_scope(scope)
25
+ all.select { |r| r.scope == scope }
26
+ end
27
+
28
+ def self.find(code)
29
+ all.find { |r| r.code == code }
30
+ end
31
+
32
+ def self.reset!
33
+ @mutex.synchronize { @rules.clear }
34
+ end
35
+
36
+ def self.rule_classes
37
+ @rules.dup
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glossarist
4
+ module Validation
5
+ module Rules
6
+ class RelatedConceptCycleRule < Base
7
+ def code = "GLS-113"
8
+ def category = :references
9
+ def severity = "error"
10
+ def scope = :collection
11
+
12
+ DIRECTIONAL = %w[supersedes deprecates narrower].freeze
13
+
14
+ def applicable?(context)
15
+ context.concepts.any? { |c| c.related&.any? }
16
+ end
17
+
18
+ def check(context)
19
+ graph = build_directed_graph(context.concepts)
20
+ issues = []
21
+
22
+ cycles = detect_cycles(graph)
23
+ cycles.each do |cycle|
24
+ path = cycle.join(" -> ")
25
+ issues << issue(
26
+ "Circular relation chain detected: #{path}",
27
+ location: cycle.first,
28
+ suggestion: "Break the cycle by removing or redirecting one of the relations",
29
+ )
30
+ end
31
+
32
+ issues
33
+ end
34
+
35
+ private
36
+
37
+ def build_directed_graph(concepts)
38
+ graph = {}
39
+ concepts.each do |c|
40
+ next unless c.related&.any?
41
+
42
+ src_id = c.data&.id&.to_s
43
+ next unless src_id
44
+
45
+ c.related.each do |rel|
46
+ next unless DIRECTIONAL.include?(rel.type)
47
+
48
+ target_id = resolve_target_id(rel)
49
+ next unless target_id
50
+
51
+ (graph[src_id] ||= []) << target_id
52
+ end
53
+ end
54
+ graph
55
+ end
56
+
57
+ def resolve_target_id(rel)
58
+ ref = rel.ref
59
+ return nil unless ref
60
+
61
+ if ref.is_a?(Glossarist::Citation)
62
+ ref.id || ref.text
63
+ end
64
+ end
65
+
66
+ def detect_cycles(graph)
67
+ visited = Set.new
68
+ stack = Set.new
69
+ cycles = []
70
+
71
+ graph.keys.each do |node|
72
+ next if visited.include?(node)
73
+
74
+ dfs(node, graph, visited, stack, [], cycles)
75
+ end
76
+
77
+ cycles
78
+ end
79
+
80
+ def dfs(node, graph, visited, stack, path, cycles)
81
+ return if visited.include?(node) && !stack.include?(node)
82
+
83
+ if stack.include?(node)
84
+ cycle_start = path.index(node)
85
+ cycles << path[cycle_start..] + [node] if cycle_start
86
+ return
87
+ end
88
+
89
+ visited.add(node)
90
+ stack.add(node)
91
+ path = path + [node]
92
+
93
+ (graph[node] || []).each do |neighbor|
94
+ dfs(neighbor, graph, visited, stack, path, cycles)
95
+ end
96
+
97
+ stack.delete(node)
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glossarist
4
+ module Validation
5
+ module Rules
6
+ class RelatedConceptRule < Base
7
+ def code = "GLS-200"
8
+ def category = :schema
9
+ def severity = "error"
10
+ def scope = :concept
11
+
12
+ VALID_TYPES = Glossarist::GlossaryDefinition::RELATED_CONCEPT_TYPES
13
+
14
+ def applicable?(context)
15
+ context.concept.related&.any?
16
+ end
17
+
18
+ def check(context)
19
+ concept = context.concept
20
+ fname = context.file_name
21
+ issues = []
22
+
23
+ (concept.related || []).each_with_index do |rel, idx|
24
+ unless VALID_TYPES.include?(rel.type)
25
+ issues << issue(
26
+ "related concept #{idx + 1} has invalid type '#{rel.type}'",
27
+ code: code, severity: severity,
28
+ location: fname,
29
+ suggestion: "Use one of: #{VALID_TYPES.join(', ')}",
30
+ )
31
+ end
32
+ end
33
+
34
+ issues
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glossarist
4
+ module Validation
5
+ module Rules
6
+ class RelatedConceptSymmetryRule < Base
7
+ def code = "GLS-112"
8
+ def category = :references
9
+ def severity = "warning"
10
+ def scope = :collection
11
+
12
+ INVERSE = {
13
+ "supersedes" => "superseded_by",
14
+ "superseded_by" => "supersedes",
15
+ "narrower" => "broader",
16
+ "broader" => "narrower",
17
+ "deprecates" => "deprecated_by",
18
+ "deprecated_by" => "deprecates",
19
+ }.freeze
20
+
21
+ DIRECTIONAL = %w[supersedes deprecates narrower].freeze
22
+
23
+ def applicable?(context)
24
+ context.concepts.any? { |c| c.related&.any? }
25
+ end
26
+
27
+ def check(context)
28
+ index = build_relation_index(context.concepts)
29
+ issues = []
30
+
31
+ context.concepts.each do |concept|
32
+ next unless concept.related&.any?
33
+
34
+ concept_id = concept.data&.id&.to_s || "unknown"
35
+ (concept.related || []).each do |rel|
36
+ inverse = INVERSE[rel.type]
37
+ next unless inverse
38
+
39
+ target_id = resolve_target_id(rel)
40
+ next unless target_id
41
+
42
+ targets = index[target_id]
43
+ next if targets && targets.any? { |r| r.type == inverse }
44
+
45
+ issues << issue(
46
+ "#{concept_id}: #{rel.type} #{target_id} but #{target_id} has no #{inverse} back-link",
47
+ location: concept_id,
48
+ suggestion: "Add a #{inverse} relation on #{target_id} pointing back to #{concept_id}",
49
+ )
50
+ end
51
+ end
52
+
53
+ issues
54
+ end
55
+
56
+ private
57
+
58
+ def build_relation_index(concepts)
59
+ index = {}
60
+ concepts.each do |c|
61
+ next unless c.related&.any?
62
+
63
+ src_id = c.data&.id&.to_s
64
+ next unless src_id
65
+
66
+ c.related.each do |rel|
67
+ target_id = resolve_target_id(rel)
68
+ next unless target_id
69
+
70
+ (index[src_id] ||= []) << rel
71
+ end
72
+ end
73
+ index
74
+ end
75
+
76
+ def resolve_target_id(rel)
77
+ ref = rel.ref
78
+ return nil unless ref
79
+
80
+ if ref.is_a?(Glossarist::Citation)
81
+ ref.id || ref.text
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glossarist
4
+ module Validation
5
+ module Rules
6
+ class SourceEnumRule < Base
7
+ def code = "GLS-202"
8
+ def category = :schema
9
+ def severity = "error"
10
+ def scope = :concept
11
+
12
+ VALID_TYPES = Glossarist::GlossaryDefinition::CONCEPT_SOURCE_TYPES
13
+ VALID_STATUSES = Glossarist::GlossaryDefinition::CONCEPT_SOURCE_STATUSES
14
+
15
+ def applicable?(context)
16
+ context.concept.localizations&.any?
17
+ end
18
+
19
+ def check(context)
20
+ concept = context.concept
21
+ fname = context.file_name
22
+ issues = []
23
+
24
+ gather_all_sources(concept).each_with_index do |source, idx|
25
+ unless VALID_TYPES.include?(source.type)
26
+ issues << issue(
27
+ "source #{idx + 1} has invalid type '#{source.type}'",
28
+ code: "GLS-202", severity: severity,
29
+ location: fname,
30
+ suggestion: "Use one of: #{VALID_TYPES.join(', ')}",
31
+ )
32
+ end
33
+
34
+ next unless source.status && !VALID_STATUSES.include?(source.status)
35
+
36
+ issues << issue(
37
+ "source #{idx + 1} has invalid status '#{source.status}'",
38
+ code: "GLS-203", severity: severity,
39
+ location: fname,
40
+ suggestion: "Use one of: #{VALID_STATUSES.join(', ')}",
41
+ )
42
+ end
43
+
44
+ issues
45
+ end
46
+
47
+ private
48
+
49
+ def gather_all_sources(concept)
50
+ sources = []
51
+ concept.localizations.each do |l10n|
52
+ (l10n.data&.sources || []).each { |s| sources << s }
53
+ (l10n.data&.definition || []).each { |d| (d.sources || []).each { |s| sources << s } }
54
+ (l10n.data&.notes || []).each { |n| (n.sources || []).each { |s| sources << s } }
55
+ (l10n.data&.examples || []).each { |e| (e.sources || []).each { |s| sources << s } }
56
+ end
57
+ sources
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glossarist
4
+ module Validation
5
+ module Rules
6
+ class TermsPresenceRule < Base
7
+ def code = "GLS-005"
8
+ def category = :structure
9
+ def severity = "error"
10
+ def scope = :concept
11
+
12
+ def applicable?(context)
13
+ context.concept.localizations&.any?
14
+ end
15
+
16
+ def check(context)
17
+ concept = context.concept
18
+ fname = context.file_name
19
+ issues = []
20
+
21
+ concept.localizations.each do |l10n|
22
+ lang = l10n.language_code || "unknown"
23
+ terms = l10n.data&.terms || []
24
+ next unless terms.empty?
25
+
26
+ issues << issue(
27
+ "#{fname}/#{lang}: must have at least 1 term",
28
+ code: code, severity: severity,
29
+ location: "#{fname}/#{lang}",
30
+ suggestion: "Add at least one term/designation to this localization",
31
+ )
32
+ end
33
+
34
+ issues
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "rules/base"
4
+ require_relative "rules/registry"
5
+ require_relative "rules/dataset_context"
6
+ require_relative "rules/gcr_context"
7
+ require_relative "rules/concept_context"
8
+
9
+ # Load all rule definitions
10
+ require_relative "rules/concept_id_rule"
11
+ require_relative "rules/concept_id_uniqueness_rule"
12
+ require_relative "rules/localization_presence_rule"
13
+ require_relative "rules/entry_status_rule"
14
+ require_relative "rules/asciidoc_xref_rule"
15
+ require_relative "rules/image_reference_rule"
16
+ require_relative "rules/concept_mention_rule"
17
+ require_relative "rules/concept_count_rule"
18
+ require_relative "rules/language_list_rule"
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
+
44
+ # Register all built-in rules
45
+ module Glossarist
46
+ module Validation
47
+ module Rules
48
+ R = Registry
49
+
50
+ R.register(ConceptIdRule)
51
+ R.register(ConceptIdUniquenessRule)
52
+ R.register(LocalizationPresenceRule)
53
+ R.register(EntryStatusRule)
54
+ R.register(AsciidocXrefRule)
55
+ R.register(ImageReferenceRule)
56
+ R.register(ConceptMentionRule)
57
+ R.register(ConceptCountRule)
58
+ R.register(LanguageListRule)
59
+ R.register(LanguageCoverageRule)
60
+ R.register(FilenameIdRule)
61
+ R.register(L10nUuidIntegrityRule)
62
+ R.register(OrphanedL10nFilesRule)
63
+ R.register(OrphanedBibliographyRule)
64
+ R.register(OrphanedImagesRule)
65
+ R.register(DefinitionContentRule)
66
+ R.register(PreferredTermRule)
67
+ R.register(DuplicateTermRule)
68
+ R.register(CitationCompletenessRule)
69
+ R.register(AuthoritativeSourceRule)
70
+ R.register(RelatedConceptRule)
71
+ R.register(ConceptStatusRule)
72
+ R.register(SourceEnumRule)
73
+ R.register(TermsPresenceRule)
74
+ R.register(BibliographyYamlRule)
75
+ R.register(ConceptUriRule)
76
+ R.register(RelatedConceptSymmetryRule)
77
+ R.register(RelatedConceptCycleRule)
78
+ R.register(DesignationStatusRule)
79
+ R.register(DateTypeRule)
80
+ R.register(LanguageCodeFormatRule)
81
+ R.register(DesignationTypeRule)
82
+ R.register(DateValidityRule)
83
+ end
84
+ end
85
+ end