metanorma-plugin-glossarist 0.3.2 → 0.3.6

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 (30) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +6 -6
  3. data/.rubocop_todo.yml +55 -246
  4. data/Gemfile +6 -5
  5. data/README.adoc +11 -1
  6. data/lib/metanorma/plugin/glossarist/bibliography_renderer.rb +54 -10
  7. data/lib/metanorma/plugin/glossarist/concept_filter.rb +22 -40
  8. data/lib/metanorma/plugin/glossarist/concept_path_resolver.rb +100 -0
  9. data/lib/metanorma/plugin/glossarist/dataset_preprocessor.rb +55 -84
  10. data/lib/metanorma/plugin/glossarist/dataset_registry.rb +98 -0
  11. data/lib/metanorma/plugin/glossarist/document.rb +8 -20
  12. data/lib/metanorma/plugin/glossarist/liquid/custom_blocks/with_glossarist_context.rb +47 -61
  13. data/lib/metanorma/plugin/glossarist/liquid/custom_filters/filters.rb +10 -4
  14. data/lib/metanorma/plugin/glossarist/liquid/custom_filters.rb +14 -0
  15. data/lib/metanorma/plugin/glossarist/liquid/drop_bracket_access.rb +36 -0
  16. data/lib/metanorma/plugin/glossarist/liquid/drops/localization_collection_drop.rb +47 -0
  17. data/lib/metanorma/plugin/glossarist/liquid/drops/managed_concept_data_drop.rb +29 -0
  18. data/lib/metanorma/plugin/glossarist/liquid/drops/managed_concept_drop.rb +45 -0
  19. data/lib/metanorma/plugin/glossarist/liquid/multiply_local_file_system.rb +1 -1
  20. data/lib/metanorma/plugin/glossarist/liquid.rb +26 -0
  21. data/lib/metanorma/plugin/glossarist/liquid_rendering.rb +26 -0
  22. data/lib/metanorma/plugin/glossarist/liquid_templates/_concept.liquid +51 -0
  23. data/lib/metanorma/plugin/glossarist/sanitize.rb +6 -4
  24. data/lib/metanorma/plugin/glossarist/template_renderer.rb +113 -0
  25. data/lib/metanorma/plugin/glossarist/version.rb +1 -1
  26. data/lib/metanorma-plugin-glossarist.rb +26 -7
  27. data/metanorma-plugin-glossarist.gemspec +1 -1
  28. metadata +21 -6
  29. data/lib/metanorma/plugin/glossarist/concept_renderer.rb +0 -91
  30. data/lib/metanorma/plugin/glossarist/concept_serializer.rb +0 -27
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Metanorma
4
+ module Plugin
5
+ module Glossarist
6
+ class ConceptPathResolver
7
+ DELEGATED_TO_DATA = %w[localizations tags].freeze
8
+ DATA_ALIASES = { "identifier" => :id }.freeze
9
+
10
+ def resolve(concept, path)
11
+ parts = parse_path(path)
12
+ value = navigate(concept, parts)
13
+ value.is_a?(String) ? value : value.to_s
14
+ end
15
+
16
+ private
17
+
18
+ def parse_path(path)
19
+ path.split(".").flat_map do |segment|
20
+ if segment.include?("[")
21
+ parse_indexed_segment(segment)
22
+ else
23
+ [segment]
24
+ end
25
+ end
26
+ end
27
+
28
+ def parse_indexed_segment(segment)
29
+ field, index_part = segment.split("[", 2)
30
+ index = index_part&.delete("]'\"")
31
+ if index.match?(/\A\d+\z/)
32
+ [field, index.to_i]
33
+ else
34
+ [field, index]
35
+ end
36
+ end
37
+
38
+ def navigate(obj, parts)
39
+ parts.reduce(obj) do |current, key|
40
+ return nil if current.nil?
41
+
42
+ access(current, key)
43
+ end
44
+ end
45
+
46
+ def access(obj, key)
47
+ case key
48
+ when String then access_string_key(obj, key)
49
+ when Integer then access_index(obj, key)
50
+ end
51
+ end
52
+
53
+ def access_string_key(obj, key)
54
+ case obj
55
+ when ::Glossarist::ManagedConcept
56
+ resolve_managed_concept(obj, key)
57
+ when ::Glossarist::ManagedConceptData
58
+ resolve_data_attribute(obj, key)
59
+ when ::Glossarist::Collections::LocalizationCollection
60
+ obj.find_by(:language_code, key)
61
+ when Array
62
+ nil
63
+ when ::Lutaml::Model::Serializable
64
+ resolve_attribute(obj, key)
65
+ when Hash
66
+ obj[key] || obj[key.to_s]
67
+ end
68
+ end
69
+
70
+ def resolve_managed_concept(concept, key)
71
+ return concept.data.public_send(key) if DELEGATED_TO_DATA.include?(key)
72
+
73
+ resolve_attribute(concept, key) { concept.public_send(key.to_sym) }
74
+ rescue NoMethodError
75
+ nil
76
+ end
77
+
78
+ def resolve_data_attribute(data, key)
79
+ aliased = DATA_ALIASES[key]
80
+ return data.public_send(aliased) if aliased && data.class.attributes.key?(aliased)
81
+
82
+ resolve_attribute(data, key)
83
+ end
84
+
85
+ def resolve_attribute(obj, key)
86
+ sym = key.to_sym
87
+ return obj.public_send(sym) if obj.class.attributes.key?(sym)
88
+
89
+ yield if block_given?
90
+ end
91
+
92
+ def access_index(obj, index)
93
+ obj[index]
94
+ rescue NoMethodError
95
+ nil
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -4,14 +4,6 @@ require "asciidoctor"
4
4
  require "asciidoctor/reader"
5
5
  require "glossarist"
6
6
 
7
- require_relative "sanitize"
8
- require_relative "concept_renderer"
9
- require_relative "bibliography_renderer"
10
- require_relative "concept_serializer"
11
- require_relative "document"
12
- require_relative "liquid/custom_filters/filters"
13
- require_relative "liquid/custom_blocks/with_glossarist_context"
14
-
15
7
  module Metanorma
16
8
  module Plugin
17
9
  module Glossarist
@@ -23,19 +15,22 @@ module Metanorma
23
15
  BIBLIOGRAPHY_REGEX = /^glossarist::render_bibliography\[(.*?)\]$/m
24
16
  BIBLIOGRAPHY_ENTRY_REGEX = /^glossarist::render_bibliography_entry\[(.*?)\]$/m
25
17
 
18
+ BIB_ANCHOR_REGEX = /^\*\s*\[\[\[([^,]+)/
19
+
26
20
  def initialize(config = {})
27
21
  super
28
22
  @config = config
29
- @datasets = {}
30
- @title_depth = 2
31
- @bibliography_renderer = BibliographyRenderer.new
32
- @seen_glossarist = false
33
- @context_names = []
34
23
  end
35
24
 
36
25
  def process(document, reader)
37
26
  input_lines = reader.lines.to_enum
38
27
  @config[:file_system] = relative_file_path(document, "")
28
+ @registry = DatasetRegistry.new
29
+ @rendered_concepts = []
30
+ @title_depth = 2
31
+ @existing_bib_anchors = []
32
+ @seen_glossarist = false
33
+
39
34
  processed_doc = prepare_document(document, input_lines)
40
35
  log(document, processed_doc.to_s) if @seen_glossarist
41
36
  Asciidoctor::PreprocessorReader.new(document,
@@ -57,6 +52,7 @@ module Metanorma
57
52
  skip_dataset: false)
58
53
  liquid_doc = Document.new
59
54
  liquid_doc.file_system = @config[:file_system]
55
+ liquid_doc.registry = @registry
60
56
 
61
57
  loop do
62
58
  current_line = input_lines.next
@@ -88,14 +84,16 @@ module Metanorma
88
84
  @title_depth = current_line.sub(/ .*$/,
89
85
  "").size
90
86
  end
87
+ if (match = current_line.match(BIB_ANCHOR_REGEX))
88
+ @existing_bib_anchors << match[1]
89
+ end
91
90
  liquid_doc.add_content(current_line)
92
91
  end
93
92
  end
94
93
 
95
94
  def process_dataset_tag(document, input_lines, liquid_doc, match)
96
95
  @seen_glossarist = true
97
- @context_names << prepare_dataset_contexts(document, match[1])
98
- @context_names.flatten!
96
+ @registry.register(document, match[1])
99
97
  liquid_doc.add_content(prepare_document(document, input_lines).to_s,
100
98
  render: false)
101
99
  end
@@ -138,16 +136,7 @@ module Metanorma
138
136
  end
139
137
 
140
138
  def get_context_path(document, key)
141
- if @context_names && !@context_names.empty?
142
- context_names = @context_names.map(&:strip)
143
- found = context_names.find do |context|
144
- context_name, = context.split("=")
145
- context_name == key
146
- end
147
- return found.split("=").last.strip if found
148
- end
149
-
150
- relative_file_path(document, key)
139
+ @registry.context_path(key) || relative_file_path(document, key)
151
140
  end
152
141
 
153
142
  def process_render_tag(liquid_doc, match)
@@ -157,92 +146,74 @@ module Metanorma
157
146
  concept_name = matches[1]
158
147
  options = parse_options(matches[2..])
159
148
 
160
- concept = find_concept(context_name, concept_name)
149
+ concept = @registry.find_concept(context_name, concept_name)
161
150
  return unless concept
162
151
 
163
- renderer = ConceptRenderer.new(concept,
164
- depth: @title_depth,
165
- anchor_prefix: options["anchor-prefix"])
166
- liquid_doc.add_content(renderer.render)
152
+ @rendered_concepts << concept
153
+ renderer = TemplateRenderer.new(file_system: @config[:file_system])
154
+ rendered = renderer.render_concept(concept,
155
+ depth: @title_depth,
156
+ anchor_prefix: options["anchor-prefix"])
157
+ liquid_doc.add_content("\n#{rendered}")
167
158
  end
168
159
 
160
+ RENDER_OPTIONS = %w[anchor-prefix].freeze
161
+
169
162
  def process_import_tag(liquid_doc, match)
170
163
  @seen_glossarist = true
171
164
  matches = match[1].split(",").map(&:strip)
172
165
  context_name = matches[0]
173
166
  options = parse_options(matches[1..])
174
- dataset = @datasets[context_name.strip]
167
+ dataset = @registry.resolve_dataset(nil, context_name)
175
168
  return unless dataset
176
169
 
177
- rendered = dataset.filter_map do |concept|
178
- designation = concept.default_designation
179
- next unless designation
180
-
181
- renderer = ConceptRenderer.new(concept,
182
- depth: @title_depth,
183
- anchor_prefix: options["anchor-prefix"])
184
- renderer.render
185
- end.join("\n\n")
186
-
187
- liquid_doc.add_content(rendered)
170
+ filter_options = options.except(*RENDER_OPTIONS)
171
+ concepts = ConceptFilter.new(filter_options).apply(dataset)
172
+ concepts = concepts.select(&:default_designation)
173
+ @rendered_concepts.concat(concepts)
174
+ renderer = TemplateRenderer.new(file_system: @config[:file_system])
175
+ rendered = renderer.render_concepts(concepts,
176
+ depth: @title_depth,
177
+ anchor_prefix: options["anchor-prefix"])
178
+ liquid_doc.add_content("\n#{rendered}")
188
179
  end
189
180
 
190
181
  def process_bibliography(document, liquid_doc, match)
191
182
  @seen_glossarist = true
192
183
  dataset_name = match[1].strip
193
- dataset = resolve_dataset(document, dataset_name)
194
- return unless dataset
195
-
196
- liquid_doc.add_content(@bibliography_renderer.render_all(dataset))
184
+ concepts = if @rendered_concepts.empty?
185
+ @registry.resolve_dataset(
186
+ document, dataset_name
187
+ )
188
+ else
189
+ @rendered_concepts
190
+ end
191
+ return unless concepts && !concepts.empty?
192
+
193
+ renderer = BibliographyRenderer.new(
194
+ existing_anchors: @existing_bib_anchors,
195
+ bibliography_data: @registry.bibliography_data,
196
+ )
197
+ liquid_doc.add_content(renderer.render_all(concepts))
197
198
  end
198
199
 
199
200
  def process_bibliography_entry(document, liquid_doc, match)
200
201
  @seen_glossarist = true
201
202
  dataset_name, concept_name = match[1].split(",").map(&:strip)
202
- concept = find_concept(dataset_name, concept_name, document)
203
+ concept = @registry.find_concept(dataset_name, concept_name, document)
203
204
  return unless concept
204
205
 
205
- entry = @bibliography_renderer.render_entry(concept)
206
+ renderer = BibliographyRenderer.new(
207
+ existing_anchors: @existing_bib_anchors,
208
+ bibliography_data: @registry.bibliography_data,
209
+ )
210
+ entry = renderer.render_entry(concept)
206
211
  liquid_doc.add_content(entry) if entry
207
212
  end
208
213
 
209
- def prepare_dataset_contexts(document, contexts)
210
- contexts.split(";").map do |context|
211
- context_name, file_path = context.split(":").map(&:strip)
212
- path = relative_file_path(document, file_path)
213
- dataset = load_dataset(path)
214
- @datasets[context_name] = dataset.to_a
215
- "#{context_name}=#{path}"
216
- end
217
- end
218
-
219
- def load_dataset(path)
220
- collection = ::Glossarist::ManagedConceptCollection.new
221
- collection.load_from_files(path)
222
- collection
223
- end
224
-
225
- def find_concept(dataset_name, concept_name, document = nil)
226
- dataset = resolve_dataset(document, dataset_name)
227
- return unless dataset
228
-
229
- dataset.find do |concept|
230
- concept.default_designation == concept_name
231
- end
232
- end
233
-
234
- def resolve_dataset(document, dataset_name)
235
- dataset = @datasets[dataset_name]
236
- return dataset if dataset
237
-
238
- return unless document
239
-
240
- path = relative_file_path(document, dataset_name)
241
- collection = load_dataset(path)
242
- @datasets[dataset_name] = collection.to_a
243
- end
244
-
245
214
  def relative_file_path(document, file_path)
215
+ return file_path if File.absolute_path?(file_path)
216
+
246
217
  docfile_directory = File.dirname(
247
218
  document.attributes["docfile"] || ".",
248
219
  )
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "glossarist"
4
+
5
+ module Metanorma
6
+ module Plugin
7
+ module Glossarist
8
+ class DatasetRegistry
9
+ def initialize
10
+ @datasets = {}
11
+ @path_cache = {}
12
+ @bibliography_data = {}
13
+ @context_names = []
14
+ end
15
+
16
+ def register(document, contexts)
17
+ paths = contexts.split(";").map do |context|
18
+ context_name, file_path = context.split(":", 2).map(&:strip)
19
+ path = relative_file_path(document, file_path)
20
+ @datasets[context_name] = load_dataset(path).to_a
21
+ "#{context_name}=#{path}"
22
+ end
23
+ @context_names.concat(paths)
24
+ end
25
+
26
+ def load_cached(path)
27
+ @path_cache[path] ||= load_dataset(path)
28
+ end
29
+
30
+ def resolve_dataset(document, dataset_name)
31
+ dataset = @datasets[dataset_name]
32
+ return dataset if dataset
33
+
34
+ return unless document
35
+
36
+ path = relative_file_path(document, dataset_name)
37
+ @datasets[dataset_name] = load_dataset(path).to_a
38
+ end
39
+
40
+ def find_concept(dataset_name, concept_name, document = nil)
41
+ dataset = resolve_dataset(document, dataset_name)
42
+ return unless dataset
43
+
44
+ dataset.find do |concept|
45
+ concept.default_designation == concept_name
46
+ end
47
+ end
48
+
49
+ def context_path(key)
50
+ return nil if @context_names.empty?
51
+
52
+ found = @context_names.find do |context|
53
+ context_name, = context.split("=")
54
+ context_name.strip == key
55
+ end
56
+ found&.split("=")&.last&.strip
57
+ end
58
+
59
+ def bibliography_data
60
+ @bibliography_data
61
+ end
62
+
63
+ private
64
+
65
+ def load_dataset(path)
66
+ @path_cache[path] ||= begin
67
+ collection = ::Glossarist::ManagedConceptCollection.new
68
+ collection.load_from_files(path)
69
+ load_bibliography_data(path)
70
+ collection
71
+ end
72
+ end
73
+
74
+ def load_bibliography_data(dataset_path)
75
+ bib_path = File.join(dataset_path, "bibliography.yaml")
76
+ return unless File.exist?(bib_path)
77
+
78
+ entries = YAML.safe_load_file(bib_path,
79
+ permitted_classes: [Symbol, Date])
80
+ return unless entries.is_a?(Array)
81
+
82
+ @bibliography_data = entries.each_with_object({}) do |entry, hash|
83
+ hash[entry["id"]] = entry if entry["id"]
84
+ end
85
+ end
86
+
87
+ def relative_file_path(document, file_path)
88
+ return file_path if File.absolute_path?(file_path)
89
+
90
+ docfile_directory = File.dirname(
91
+ document.attributes["docfile"] || ".",
92
+ )
93
+ document.path_resolver.system_path(file_path, docfile_directory)
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -1,13 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "liquid"
4
- require_relative "liquid/multiply_local_file_system"
5
-
6
3
  module Metanorma
7
4
  module Plugin
8
5
  module Glossarist
9
6
  class Document
10
- attr_accessor :content, :file_system
7
+ attr_accessor :file_system, :registry
11
8
 
12
9
  def initialize
13
10
  @content = []
@@ -15,7 +12,13 @@ module Metanorma
15
12
 
16
13
  def add_content(content, options = {})
17
14
  @content << if options[:render]
18
- render_liquid(content, options)
15
+ LiquidRendering.render(
16
+ content,
17
+ include_paths: [file_system,
18
+ options[:template]].compact,
19
+ patterns: LiquidRendering::DOCUMENT_PATTERNS,
20
+ registry: registry,
21
+ )
19
22
  else
20
23
  content
21
24
  end
@@ -24,21 +27,6 @@ module Metanorma
24
27
  def to_s
25
28
  @content.compact.join("\n")
26
29
  end
27
-
28
- private
29
-
30
- def render_liquid(file_content, options = {})
31
- include_paths = [file_system, options[:template]].compact
32
- template = ::Liquid::Template.parse(file_content)
33
- template.registers[:file_system] = ::Metanorma::Plugin::Glossarist::Liquid::LocalFileSystem.new(
34
- include_paths, ["%s.liquid", "_%s.liquid", "_%s.adoc"]
35
- )
36
- rendered = template.render
37
-
38
- return rendered unless template.errors.any?
39
-
40
- raise template.errors.first.cause
41
- end
42
30
  end
43
31
  end
44
32
  end
@@ -1,76 +1,62 @@
1
1
  # frozen_string_literal: true
2
-
3
- require "liquid"
4
- require_relative "../../concept_filter"
5
- require_relative "../../concept_serializer"
6
-
7
2
  module Metanorma
8
3
  module Plugin
9
4
  module Glossarist
10
5
  module Liquid
11
- module CollectionCache
12
- @cache = {}
13
-
14
- def self.fetch(folder_path)
15
- @cache[folder_path] ||= begin
16
- collection = ::Glossarist::ManagedConceptCollection.new
17
- collection.load_from_files(folder_path)
18
- collection
19
- end
6
+ class WithGlossaristContext < ::Liquid::Block
7
+ def self.register!
8
+ ::Liquid::Environment.default.register_tag(
9
+ "with_glossarist_context", self
10
+ )
20
11
  end
21
- end
22
- end
23
- end
24
- end
25
- end
26
12
 
27
- Liquid::Template.register_tag("with_glossarist_context",
28
- Class.new(Liquid::Block) do
29
- def initialize(tag_name, markup, tokens)
30
- super
31
- @contexts = []
32
- @raw_filters = {}
13
+ def initialize(tag_name, markup, tokens)
14
+ super
15
+ @contexts = []
16
+ @raw_filters = {}
33
17
 
34
- contexts_part, filters_part = markup.strip.split(
35
- ";", 2
36
- )
18
+ contexts_part, filters_part = markup.strip.split(";", 2)
37
19
 
38
- parse_filters(filters_part.strip) if filters_part && !filters_part.strip.empty?
20
+ parse_filters(filters_part.strip) if filters_part && !filters_part.strip.empty?
21
+
22
+ contexts_part.split(",").each do |context|
23
+ context_name, file_path = context.split("=", 2).map(&:strip)
24
+ @contexts << { name: context_name, file_path: file_path }
25
+ end
26
+ end
39
27
 
40
- contexts_part.split(",").each do |context|
41
- context_name, file_path = context.split("=").map(&:strip)
42
- @contexts << { name: context_name,
43
- file_path: file_path }
44
- end
45
- end
28
+ def render(context)
29
+ registry = context.registers[:dataset_registry]
46
30
 
47
- def render(context)
48
- @contexts.each do |local_context|
49
- collection = load_collection(local_context[:file_path].strip)
50
- filtered = Metanorma::Plugin::Glossarist::ConceptFilter.new(@raw_filters).apply(collection)
51
- context[local_context[:name]] = filtered.map do |c|
52
- Metanorma::Plugin::Glossarist::ConceptSerializer.new(c).to_h
53
- end
54
- end
31
+ @contexts.each do |local_context|
32
+ path = local_context[:file_path].strip
33
+ collection = registry ? registry.load_cached(path) : load_collection(path)
34
+ filtered = ConceptFilter.new(@raw_filters).apply(collection)
35
+ context[local_context[:name]] = filtered.map do |c|
36
+ ManagedConceptDrop.new(c)
37
+ end
38
+ end
55
39
 
56
- super
57
- end
40
+ super
41
+ end
58
42
 
59
- private
43
+ private
60
44
 
61
- def parse_filters(filters_str)
62
- stripped = filters_str.gsub(/\A['"]|['"]\z/,
63
- "")
64
- stripped.split(";").each do |filter|
65
- property, value = filter.split("=", 2)
66
- if property
67
- @raw_filters[property.strip] =
68
- value&.strip
69
- end
70
- end
71
- end
45
+ def parse_filters(filters_str)
46
+ stripped = filters_str.gsub(/\A['"]|['"]\z/, "")
47
+ stripped.split(";").each do |filter|
48
+ property, value = filter.split("=", 2)
49
+ @raw_filters[property.strip] = value&.strip if property
50
+ end
51
+ end
72
52
 
73
- def load_collection(folder_path)
74
- Metanorma::Plugin::Glossarist::Liquid::CollectionCache.fetch(folder_path)
75
- end
76
- end)
53
+ def load_collection(folder_path)
54
+ collection = ::Glossarist::ManagedConceptCollection.new
55
+ collection.load_from_files(folder_path)
56
+ collection
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -1,13 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "liquid"
4
-
5
3
  module Metanorma
6
4
  module Plugin
7
5
  module Glossarist
8
6
  module Liquid
9
7
  module CustomFilters
10
8
  module Filters
9
+ def self.register!
10
+ ::Liquid::Environment.default.register_filter(self)
11
+ end
12
+
11
13
  def values(list)
12
14
  list.values
13
15
  end
@@ -15,11 +17,15 @@ module Metanorma
15
17
  def sanitize_references(str)
16
18
  Sanitize.references(str)
17
19
  end
20
+
21
+ def format_ref(label)
22
+ return "" if label.nil? || label.strip.empty?
23
+
24
+ label.gsub(%r{[ /:]}, "_")
25
+ end
18
26
  end
19
27
  end
20
28
  end
21
29
  end
22
30
  end
23
31
  end
24
-
25
- Liquid::Template.register_filter(Metanorma::Plugin::Glossarist::Liquid::CustomFilters::Filters)
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Metanorma
4
+ module Plugin
5
+ module Glossarist
6
+ module Liquid
7
+ module CustomFilters
8
+ autoload :Filters,
9
+ "metanorma/plugin/glossarist/liquid/custom_filters/filters"
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Includes Lutaml::Model::Liquid::IndexedAccess into Glossarist collection
4
+ # classes so that their auto-generated Liquid drops support bracket access
5
+ # (e.g., +localizations['eng']+, +definition[0]+).
6
+ #
7
+ # Glossarist collections support +self[key]+ but do not yet include
8
+ # IndexedAccess in their published gem. Once they do, this file can be
9
+ # removed entirely.
10
+ #
11
+ # @see Lutaml::Model::Liquid::IndexedAccess (lutaml-model >= 0.8.15)
12
+ # @see https://github.com/lutaml/lutaml-model/pull/705
13
+ module Metanorma
14
+ module Plugin
15
+ module Glossarist
16
+ module Liquid
17
+ module PolyfillIndexedAccess
18
+ COLLECTION_CLASSES = %w[
19
+ Glossarist::Collections::LocalizationCollection
20
+ Glossarist::Collections::DetailedDefinitionCollection
21
+ Glossarist::Collections::ConceptSourceCollection
22
+ ].freeze
23
+
24
+ def self.apply!
25
+ COLLECTION_CLASSES.each do |class_name|
26
+ klass = class_name.split("::").reduce(Object) do |mod, name|
27
+ mod.const_get(name)
28
+ end
29
+ klass.include(Lutaml::Model::Liquid::IndexedAccess) unless klass.include?(Lutaml::Model::Liquid::IndexedAccess)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end