metanorma-plugin-glossarist 0.3.3 → 0.3.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 (32) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +6 -6
  3. data/.rubocop_todo.yml +90 -196
  4. data/Gemfile +6 -5
  5. data/README.adoc +11 -1
  6. data/lib/metanorma/plugin/glossarist/bibliography_renderer.rb +54 -12
  7. data/lib/metanorma/plugin/glossarist/concept_filter.rb +22 -40
  8. data/lib/metanorma/plugin/glossarist/concept_path_resolver.rb +117 -0
  9. data/lib/metanorma/plugin/glossarist/dataset_preprocessor.rb +98 -82
  10. data/lib/metanorma/plugin/glossarist/dataset_registry.rb +108 -0
  11. data/lib/metanorma/plugin/glossarist/document.rb +9 -20
  12. data/lib/metanorma/plugin/glossarist/liquid/custom_blocks/with_glossarist_context.rb +47 -60
  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 +52 -0
  23. data/lib/metanorma/plugin/glossarist/sanitize.rb +6 -4
  24. data/lib/metanorma/plugin/glossarist/section_filter.rb +50 -0
  25. data/lib/metanorma/plugin/glossarist/template_renderer.rb +112 -0
  26. data/lib/metanorma/plugin/glossarist/version.rb +1 -1
  27. data/lib/metanorma-plugin-glossarist.rb +30 -8
  28. data/metanorma-plugin-glossarist.gemspec +1 -1
  29. metadata +18 -9
  30. data/lib/metanorma/plugin/glossarist/citation_helper.rb +0 -13
  31. data/lib/metanorma/plugin/glossarist/concept_renderer.rb +0 -93
  32. data/lib/metanorma/plugin/glossarist/concept_serializer.rb +0 -27
@@ -4,11 +4,12 @@ module Metanorma
4
4
  module Plugin
5
5
  module Glossarist
6
6
  class ConceptFilter
7
- COLLECTION_FILTERS = %w[lang domain group sort_by].freeze
7
+ COLLECTION_FILTERS = %w[lang domain group section tag sort_by].freeze
8
8
  SORT_LAST = ["￿"].freeze
9
9
 
10
10
  def initialize(filters)
11
11
  @filters = filters || {}
12
+ @resolver = ConceptPathResolver.new
12
13
  end
13
14
 
14
15
  def apply(collection)
@@ -17,6 +18,8 @@ module Metanorma
17
18
  if @filters.key?("domain") || @filters.key?("group")
18
19
  result = filter_by_domain(result)
19
20
  end
21
+ result = filter_by_section(result) if @filters.key?("section")
22
+ result = filter_by_tag(result) if @filters.key?("tag")
20
23
  result = filter_by_field(result) if field_filter?
21
24
  result = sort(result) if @filters.key?("sort_by")
22
25
  result
@@ -44,6 +47,20 @@ module Metanorma
44
47
  end
45
48
  end
46
49
 
50
+ def filter_by_tag(collection)
51
+ tag = @filters["tag"]
52
+ collection.select do |c|
53
+ c.data.tags&.include?(tag)
54
+ end
55
+ end
56
+
57
+ def filter_by_section(collection)
58
+ section_id = @filters["section"]
59
+ collection.select do |c|
60
+ c.data.domains&.any? { |d| d.concept_id == "section-#{section_id}" }
61
+ end
62
+ end
63
+
47
64
  def sort(collection)
48
65
  field = @filters["sort_by"]
49
66
  return collection unless field
@@ -52,14 +69,12 @@ module Metanorma
52
69
  when "term", "default_designation"
53
70
  collection.sort_by { |c| c.default_designation.to_s.downcase }
54
71
  else
55
- parts = parse_path(field)
56
- collection.sort_by { |c| sort_key(c, parts) }
72
+ collection.sort_by { |c| sort_key(c, field) }
57
73
  end
58
74
  end
59
75
 
60
- def sort_key(concept, parts)
61
- hash = ConceptSerializer.new(concept).to_h
62
- value = dig_path(hash, parts)
76
+ def sort_key(concept, field)
77
+ value = @resolver.resolve(concept, field)
63
78
  value.nil? ? SORT_LAST : natural_sort_key(value.to_s)
64
79
  end
65
80
 
@@ -75,10 +90,8 @@ module Metanorma
75
90
  start_with = path.include?(".start_with(")
76
91
  path, match_value = extract_start_with(path, value, start_with)
77
92
 
78
- parts = parse_path(path)
79
93
  collection.select do |concept|
80
- hash = ConceptSerializer.new(concept).to_h
81
- actual = dig_path(hash, parts)
94
+ actual = @resolver.resolve(concept, path)
82
95
  if start_with
83
96
  actual&.start_with?(match_value)
84
97
  else
@@ -95,37 +108,6 @@ module Metanorma
95
108
 
96
109
  [match[1], match[2]]
97
110
  end
98
-
99
- def parse_path(path)
100
- path.split(".").flat_map do |segment|
101
- if segment.include?("[")
102
- parse_indexed_segment(segment)
103
- else
104
- [segment]
105
- end
106
- end
107
- end
108
-
109
- def parse_indexed_segment(segment)
110
- field, index_part = segment.split("[", 2)
111
- index = index_part&.delete("]'\"")
112
- if index.match?(/\A\d+\z/)
113
- [field, index.to_i]
114
- else
115
- [field, index]
116
- end
117
- end
118
-
119
- def dig_path(hash, parts)
120
- parts.reduce(hash) do |current, key|
121
- case current
122
- when Hash
123
- current[key] || current[key.to_s]
124
- when Array
125
- key.is_a?(Integer) ? current[key] : nil
126
- end
127
- end
128
- end
129
111
  end
130
112
  end
131
113
  end
@@ -0,0 +1,117 @@
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
+ read_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
+ if DELEGATED_TO_DATA.include?(key)
72
+ return read_attribute(concept.data,
73
+ key)
74
+ end
75
+
76
+ read_attribute(concept, key) { read_method(concept, key) }
77
+ rescue NoMethodError
78
+ nil
79
+ end
80
+
81
+ def resolve_data_attribute(data, key)
82
+ aliased = DATA_ALIASES[key]
83
+ if aliased && data.class.attributes.key?(aliased)
84
+ return read_attribute(data, aliased)
85
+ end
86
+
87
+ read_attribute(data, key)
88
+ end
89
+
90
+ # Reads a validated public attribute from a Lutaml::Model::Serializable
91
+ # object. Uses public_send because the attribute name is determined at
92
+ # runtime from path strings. Falls back to the block for non-attribute
93
+ # public methods (e.g., ManagedConcept#default_designation).
94
+ def read_attribute(obj, key)
95
+ sym = key.to_sym
96
+ if obj.class.respond_to?(:attributes) && obj.class.attributes.key?(sym)
97
+ obj.public_send(sym)
98
+ elsif block_given?
99
+ yield
100
+ end
101
+ end
102
+
103
+ # Calls a public method by name on the object. Used as a fallback for
104
+ # methods that aren't lutaml-model attributes (e.g., computed accessors).
105
+ def read_method(obj, key)
106
+ obj.public_send(key.to_sym)
107
+ end
108
+
109
+ def access_index(obj, index)
110
+ obj[index]
111
+ rescue NoMethodError
112
+ nil
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
@@ -4,38 +4,35 @@ 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
18
10
  class DatasetPreprocessor < Asciidoctor::Extensions::Preprocessor
19
11
  DATASET_ATTR_REGEX = /^:glossarist-dataset:\s*(.*?)$/m
20
12
  IMPORT_REGEX = /^glossarist::import\[(.*?)\]$/m
13
+ IMPORT_SECTIONS_REGEX = /^glossarist::import_sections\[(.*?)\]$/m
21
14
  RENDER_REGEX = /^glossarist::render\[(.*?)\]$/m
22
15
  BLOCK_REGEX = /^\[glossarist,(.+?),(.+?)\]$/m
23
16
  BIBLIOGRAPHY_REGEX = /^glossarist::render_bibliography\[(.*?)\]$/m
24
17
  BIBLIOGRAPHY_ENTRY_REGEX = /^glossarist::render_bibliography_entry\[(.*?)\]$/m
25
18
 
19
+ BIB_ANCHOR_REGEX = /^\*\s*\[\[\[([^,]+)/
20
+
26
21
  def initialize(config = {})
27
22
  super
28
23
  @config = config
29
- @datasets = {}
30
- @title_depth = 2
31
- @bibliography_renderer = BibliographyRenderer.new
32
- @seen_glossarist = false
33
- @context_names = []
34
24
  end
35
25
 
36
26
  def process(document, reader)
37
27
  input_lines = reader.lines.to_enum
38
28
  @config[:file_system] = relative_file_path(document, "")
29
+ @registry = DatasetRegistry.new
30
+ @renderer = TemplateRenderer.new(file_system: @config[:file_system])
31
+ @rendered_concepts = []
32
+ @title_depth = 2
33
+ @existing_bib_anchors = []
34
+ @seen_glossarist = false
35
+
39
36
  processed_doc = prepare_document(document, input_lines)
40
37
  log(document, processed_doc.to_s) if @seen_glossarist
41
38
  Asciidoctor::PreprocessorReader.new(document,
@@ -57,6 +54,7 @@ module Metanorma
57
54
  skip_dataset: false)
58
55
  liquid_doc = Document.new
59
56
  liquid_doc.file_system = @config[:file_system]
57
+ liquid_doc.registry = @registry
60
58
 
61
59
  loop do
62
60
  current_line = input_lines.next
@@ -75,6 +73,8 @@ module Metanorma
75
73
  process_dataset_tag(document, input_lines, liquid_doc, match)
76
74
  elsif (match = current_line.match(RENDER_REGEX))
77
75
  process_render_tag(liquid_doc, match)
76
+ elsif (match = current_line.match(IMPORT_SECTIONS_REGEX))
77
+ process_import_sections_tag(document, liquid_doc, match)
78
78
  elsif (match = current_line.match(IMPORT_REGEX))
79
79
  process_import_tag(liquid_doc, match)
80
80
  elsif (match = current_line.match(BIBLIOGRAPHY_REGEX))
@@ -88,14 +88,16 @@ module Metanorma
88
88
  @title_depth = current_line.sub(/ .*$/,
89
89
  "").size
90
90
  end
91
+ if (match = current_line.match(BIB_ANCHOR_REGEX))
92
+ @existing_bib_anchors << match[1]
93
+ end
91
94
  liquid_doc.add_content(current_line)
92
95
  end
93
96
  end
94
97
 
95
98
  def process_dataset_tag(document, input_lines, liquid_doc, match)
96
99
  @seen_glossarist = true
97
- @context_names << prepare_dataset_contexts(document, match[1])
98
- @context_names.flatten!
100
+ @registry.register(document, match[1])
99
101
  liquid_doc.add_content(prepare_document(document, input_lines).to_s,
100
102
  render: false)
101
103
  end
@@ -138,16 +140,7 @@ module Metanorma
138
140
  end
139
141
 
140
142
  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)
143
+ @registry.context_path(key) || relative_file_path(document, key)
151
144
  end
152
145
 
153
146
  def process_render_tag(liquid_doc, match)
@@ -157,92 +150,115 @@ module Metanorma
157
150
  concept_name = matches[1]
158
151
  options = parse_options(matches[2..])
159
152
 
160
- concept = find_concept(context_name, concept_name)
153
+ concept = @registry.find_concept(context_name, concept_name)
161
154
  return unless concept
162
155
 
163
- renderer = ConceptRenderer.new(concept,
164
- depth: @title_depth,
165
- anchor_prefix: options["anchor-prefix"])
166
- liquid_doc.add_content(renderer.render)
156
+ @rendered_concepts << concept
157
+ renderer = @renderer
158
+ rendered = renderer.render_concept(concept,
159
+ depth: @title_depth,
160
+ anchor_prefix: options["anchor-prefix"])
161
+ liquid_doc.add_content("\n#{rendered}")
167
162
  end
168
163
 
164
+ RENDER_OPTIONS = %w[anchor-prefix].freeze
165
+
169
166
  def process_import_tag(liquid_doc, match)
170
167
  @seen_glossarist = true
171
168
  matches = match[1].split(",").map(&:strip)
172
169
  context_name = matches[0]
173
170
  options = parse_options(matches[1..])
174
- dataset = @datasets[context_name.strip]
171
+ dataset = @registry.resolve_dataset(nil, context_name)
175
172
  return unless dataset
176
173
 
177
- rendered = dataset.filter_map do |concept|
178
- designation = concept.default_designation
179
- next unless designation
174
+ filter_options = options.except(*RENDER_OPTIONS)
175
+ concepts = ConceptFilter.new(filter_options).apply(dataset)
176
+ concepts = concepts.select(&:default_designation)
177
+ @rendered_concepts.concat(concepts)
178
+ renderer = @renderer
179
+ rendered = renderer.render_concepts(concepts,
180
+ depth: @title_depth,
181
+ anchor_prefix: options["anchor-prefix"])
182
+ liquid_doc.add_content("\n#{rendered}")
183
+ end
180
184
 
181
- renderer = ConceptRenderer.new(concept,
182
- depth: @title_depth,
183
- anchor_prefix: options["anchor-prefix"])
184
- renderer.render
185
- end.join("\n\n")
185
+ def process_import_sections_tag(_document, liquid_doc, match)
186
+ @seen_glossarist = true
187
+ matches = match[1].split(",").map(&:strip)
188
+ context_name = matches[0]
189
+ options = parse_options(matches[1..])
186
190
 
187
- liquid_doc.add_content(rendered)
191
+ sections = @registry.register_sections(context_name)
192
+ return unless sections && !sections.empty?
193
+
194
+ dataset = @registry.resolve_dataset(nil, context_name)
195
+ return unless dataset
196
+
197
+ renderer = @renderer
198
+ sort_by = options["sort_by"] || "term"
199
+ section_filter = SectionFilter.new(
200
+ exclude: (options["section_exclude"] || "").split("|"),
201
+ include: (options["section_include"] || "").split("|"),
202
+ )
203
+ filtered = section_filter.apply(sections)
204
+ parts = render_section_concepts(filtered, dataset, renderer,
205
+ sort_by, options)
206
+ liquid_doc.add_content("\n#{parts.join("\n\n")}")
207
+ end
208
+
209
+ def render_section_concepts(sections, dataset, renderer, sort_by,
210
+ options)
211
+ sections.filter_map do |section|
212
+ filter_options = { "section" => section.id, "sort_by" => sort_by }
213
+ concepts = ConceptFilter.new(filter_options).apply(dataset)
214
+ concepts = concepts.select(&:default_designation)
215
+ next if concepts.empty?
216
+
217
+ @rendered_concepts.concat(concepts)
218
+ heading = "#{'=' * (@title_depth + 1)} #{section.name || section.id}"
219
+ rendered = renderer.render_concepts(concepts,
220
+ depth: @title_depth + 1,
221
+ anchor_prefix: options["anchor-prefix"])
222
+ "#{heading}\n\n#{rendered}"
223
+ end
188
224
  end
189
225
 
190
226
  def process_bibliography(document, liquid_doc, match)
191
227
  @seen_glossarist = true
192
228
  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))
229
+ concepts = if @rendered_concepts.empty?
230
+ @registry.resolve_dataset(
231
+ document, dataset_name
232
+ )
233
+ else
234
+ @rendered_concepts
235
+ end
236
+ return unless concepts && !concepts.empty?
237
+
238
+ renderer = BibliographyRenderer.new(
239
+ existing_anchors: @existing_bib_anchors,
240
+ bibliography_data: @registry.bibliography_data,
241
+ )
242
+ liquid_doc.add_content(renderer.render_all(concepts))
197
243
  end
198
244
 
199
245
  def process_bibliography_entry(document, liquid_doc, match)
200
246
  @seen_glossarist = true
201
247
  dataset_name, concept_name = match[1].split(",").map(&:strip)
202
- concept = find_concept(dataset_name, concept_name, document)
248
+ concept = @registry.find_concept(dataset_name, concept_name, document)
203
249
  return unless concept
204
250
 
205
- entry = @bibliography_renderer.render_entry(concept)
251
+ renderer = BibliographyRenderer.new(
252
+ existing_anchors: @existing_bib_anchors,
253
+ bibliography_data: @registry.bibliography_data,
254
+ )
255
+ entry = renderer.render_entry(concept)
206
256
  liquid_doc.add_content(entry) if entry
207
257
  end
208
258
 
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
259
  def relative_file_path(document, file_path)
260
+ return file_path if File.absolute_path?(file_path)
261
+
246
262
  docfile_directory = File.dirname(
247
263
  document.attributes["docfile"] || ".",
248
264
  )
@@ -0,0 +1,108 @@
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 register_sections(context_name)
60
+ dataset_path = context_path(context_name)
61
+ return nil unless dataset_path
62
+
63
+ @register_cache ||= {}
64
+ @register_cache[dataset_path] ||=
65
+ ::Glossarist::DatasetRegister.from_directory(dataset_path)
66
+ @register_cache[dataset_path]&.sections
67
+ end
68
+
69
+ def bibliography_data
70
+ @bibliography_data
71
+ end
72
+
73
+ private
74
+
75
+ def load_dataset(path)
76
+ @path_cache[path] ||= begin
77
+ collection = ::Glossarist::ManagedConceptCollection.new
78
+ collection.load_from_files(path)
79
+ load_bibliography_data(path)
80
+ collection
81
+ end
82
+ end
83
+
84
+ def load_bibliography_data(dataset_path)
85
+ bib_path = File.join(dataset_path, "bibliography.yaml")
86
+ return unless File.exist?(bib_path)
87
+
88
+ entries = YAML.safe_load_file(bib_path,
89
+ permitted_classes: [Symbol, Date])
90
+ return unless entries.is_a?(Array)
91
+
92
+ @bibliography_data = entries.each_with_object({}) do |entry, hash|
93
+ hash[entry["id"]] = entry if entry["id"]
94
+ end
95
+ end
96
+
97
+ def relative_file_path(document, file_path)
98
+ return file_path if File.absolute_path?(file_path)
99
+
100
+ docfile_directory = File.dirname(
101
+ document.attributes["docfile"] || ".",
102
+ )
103
+ document.path_resolver.system_path(file_path, docfile_directory)
104
+ end
105
+ end
106
+ end
107
+ end
108
+ 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,14 @@ 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
+ TEMPLATES_DIR,
19
+ options[:template]].compact,
20
+ patterns: LiquidRendering::DOCUMENT_PATTERNS,
21
+ registry: registry,
22
+ )
19
23
  else
20
24
  content
21
25
  end
@@ -24,21 +28,6 @@ module Metanorma
24
28
  def to_s
25
29
  @content.compact.join("\n")
26
30
  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
31
  end
43
32
  end
44
33
  end