metanorma-plugin-lutaml 0.6.0 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7e9b3ce23d274ff457c34d3c5a9e2bf73d12d8cd4de898a061f6a3522bb45439
4
- data.tar.gz: 79a063b985b79fa7b835bbc73acd0ada7761c496f058bcfc8d455882cb6d95ea
3
+ metadata.gz: 56a196838fa30ab8585b1834d115bf6ff99b4b81d33176975b75dc7f5c5cd5bd
4
+ data.tar.gz: 458ce39ccac1e11b1dee74289e9e85a06a4ec5fa2faceaa78869ca18cc8dae77
5
5
  SHA512:
6
- metadata.gz: 20896ef23b4b4a2258e3803a9d07bca26778f495aa57dfdd5bcd878ac6db1c09d139a066b7e6dde086e25b1c4a77b74266ae7f51f251613c783a4be7d38771da
7
- data.tar.gz: b10b0ce496d8ac08e4cd83d85065c94292f4846dcaf27544fdc122fba228c9303395076d42e2fd5eecc12090f16faeb564b0300c7bc40ea37f3648dae433ec25
6
+ metadata.gz: 780fa1199a23d199cb8f04d1a1b9b79d416f8aed0a2b442f02baccd370830d76d80fee12c2061e9424c9dd294059f5709b50a0eac7ac9b24fd4b492f54caa839
7
+ data.tar.gz: 1582258a02474a3ee351b935afc686a78ed8c82f1cc72efefde7c003110bfaa8fd4189d979b2070e61509d5d4997208b7644daf529c6e221c9e187e4e3def057
data/Gemfile CHANGED
@@ -6,4 +6,8 @@ git_source(:github) { |repo| "https://github.com/#{repo}" }
6
6
 
7
7
  gemspec
8
8
 
9
- eval_gemfile("Gemfile.devel") rescue nil
9
+ begin
10
+ eval_gemfile("Gemfile.devel")
11
+ rescue StandardError
12
+ nil
13
+ end
data/README.adoc CHANGED
@@ -28,9 +28,9 @@ LutaML supports accessing EXPRESS models via the
28
28
  https://github.com/lutaml/expressir[Expressir] parser.
29
29
 
30
30
 
31
- === Usage of the `lutaml` macro
31
+ === Usage of the `lutaml` command
32
32
 
33
- Given an `example.exp` EXPRESS file with the content:
33
+ Given an `example.exp` EXPRESS file with content:
34
34
 
35
35
  [source,exp]
36
36
  ----
@@ -57,7 +57,7 @@ SCHEMA test_schema 'test';
57
57
  END_SCHEMA;
58
58
  ----
59
59
 
60
- And the `lutaml` macro block:
60
+ And the `lutaml` block:
61
61
 
62
62
  [source,adoc]
63
63
  -----
@@ -137,6 +137,7 @@ Example of usage:
137
137
  = Document title
138
138
  Author
139
139
  :lutaml-express-index: index_name; /path/to/express_files; cache=/path/to/cache_file.yaml
140
+
140
141
  [lutaml,index_name,context]
141
142
  ----
142
143
  {% for schema in context.schemas %}
@@ -145,6 +146,64 @@ Author
145
146
  ----
146
147
  -----
147
148
 
149
+ === Using `config.yaml`
150
+
151
+ This functionality allows `[lutaml_express]` blocks to load a full set of
152
+ EXPRESS schemas in one index, and then provide a select ("filter") option
153
+ per-block via a separate YAML file.
154
+
155
+ [source,adoc]
156
+ ----
157
+ :lutaml-express-index: schemas_1; schemas_all.yaml;
158
+
159
+ [lutaml_express,schemas_1,repo,leveloffset=+1,config_yaml=select.yaml]
160
+ ---
161
+ {% assign selected = repo.schemas | where: "selected" %}
162
+ {% render "templates/resources/schema" for selected as schema %}
163
+ ---
164
+ ----
165
+
166
+ Where `schemas_all.yml` provides all schemas:
167
+
168
+ [source,yaml]
169
+ ----
170
+ ---
171
+ schemas:
172
+ action_schema:
173
+ path: "../../schemas/resources/action_schema/action_schema.exp"
174
+ application_context_schema:
175
+ path: "../../schemas/resources/application_context_schema/application_context_schema.exp"
176
+ approval_schema:
177
+ path: "../../schemas/resources/approval_schema/approval_schema.exp"
178
+ ...
179
+ ----
180
+
181
+ And `select.yaml` only selects 2 schemas:
182
+
183
+ [source,yaml]
184
+ ----
185
+ ---
186
+ schemas:
187
+ - action_schema
188
+ - application_context_schema
189
+ ----
190
+
191
+ The resulting block adds the `select` attribute to every schema of the the
192
+ "context" object, which allows you to filter those out for complex operations
193
+ via Liquid:
194
+
195
+ [source,liquid]
196
+ ----
197
+ [lutaml_express,schemas_1,repo,leveloffset=+1,config_yaml=select.yaml]
198
+ ---
199
+ {% assign selected = repo.schemas | where: "selected" %}
200
+ ... do things with `selected` ...
201
+ ----
202
+
203
+ NOTE: This functionality is used in the ISO 10303 SRL to load the full schema
204
+ set at once but only render the selected schemas in individual documents.
205
+
206
+
148
207
  == Usage with UML
149
208
 
150
209
  === Rendering a LutaML view: `lutaml_diagram`
@@ -48,7 +48,7 @@ module Metanorma
48
48
  # When we are dealing with a relative path of a template:
49
49
  # ../path/to/file we need to transform it into
50
50
  # the absolute one because `image::` macro wont understand it other way
51
- prefixed_path = File.absolute_path(prefixed_path) if prefixed_path.start_with?('../')
51
+ prefixed_path = File.absolute_path(prefixed_path) if prefixed_path.start_with?("../")
52
52
  full_path = File.expand_path(prefixed_path)
53
53
  "#{$1}#{$2}#{full_path}#{$4}"
54
54
  end
@@ -15,7 +15,7 @@ module Metanorma
15
15
  end
16
16
 
17
17
  def identify(input)
18
- input.split(/(?=[A-Z])/).map(&:downcase).join('-')
18
+ input.split(/(?=[A-Z])/).map(&:downcase).join("-")
19
19
  end
20
20
  end
21
21
  end
@@ -12,36 +12,51 @@ module Metanorma
12
12
 
13
13
  def read_template_file(template_path)
14
14
  full_path = full_path(template_path)
15
- raise FileSystemError, "No such template '#{template_path}'" unless File.exist?(full_path)
15
+
16
+ unless File.exist?(full_path)
17
+ raise FileSystemError, "No such template '#{template_path}'"
18
+ end
16
19
 
17
20
  File.read(full_path)
18
21
  end
19
22
 
20
23
  def full_path(template_path)
21
- raise ::Liquid::FileSystemError, "Illegal template name '#{template_path}'" unless %r{\A[^./][a-zA-Z0-9_/]+\z}.match?(template_path)
22
-
23
- result_path = if template_path.include?('/')
24
- roots
25
- .map do |root|
26
- patterns.map do |pattern|
27
- File.join(root, File.dirname(template_path), pattern % File.basename(template_path))
28
- end
29
- end
30
- .flatten
31
- .find { |path| File.file?(path) }
32
- else
33
- roots
34
- .map do |root|
35
- patterns.map do |pattern|
36
- File.join(root, pattern % template_path)
37
- end
38
- end
39
- .flatten
40
- .find { |path| File.file?(path) }
24
+ unless %r{\A[^./][a-zA-Z0-9_/]+\z}.match?(template_path)
25
+ raise ::Liquid::FileSystemError,
26
+ "Illegal template name '#{template_path}'"
27
+ end
28
+
29
+ result_path = if template_path.include?("/")
30
+ roots
31
+ .map do |root|
32
+ patterns.map do |pattern|
33
+ File.join(root, File.dirname(template_path),
34
+ pattern % File.basename(template_path))
35
+ end
36
+ end
37
+ .flatten
38
+ .find { |path| File.file?(path) }
39
+ else
40
+ roots
41
+ .map do |root|
42
+ patterns.map do |pattern|
43
+ File.join(root, pattern % template_path)
44
+ end
45
+ end
46
+ .flatten
47
+ .find { |path| File.file?(path) }
48
+ end
49
+
50
+ if result_path.nil?
51
+ raise ::Liquid::FileSystemError,
52
+ "No documents in template path '#{File.expand_path(template_path)}'"
41
53
  end
42
54
 
43
- unless roots.any? { |root| File.expand_path(result_path).start_with?(File.expand_path(root)) }
44
- raise ::Liquid::FileSystemError, "Illegal template path '#{File.expand_path(result_path)}'"
55
+ unless roots.any? do |root|
56
+ File.expand_path(result_path).start_with?(File.expand_path(root))
57
+ end
58
+ raise ::Liquid::FileSystemError,
59
+ "Illegal template path '#{File.expand_path(result_path)}'"
45
60
  end
46
61
 
47
62
  result_path
@@ -16,164 +16,244 @@ module Metanorma
16
16
  REMARKS_ATTRIBUTE = "remarks"
17
17
 
18
18
  def process(document, reader)
19
- r = Asciidoctor::PreprocessorNoIfdefsReader.new document, reader.lines
19
+ r = Asciidoctor::PreprocessorNoIfdefsReader.new(document,
20
+ reader.lines)
20
21
  input_lines = r.readlines.to_enum
21
- has_lutaml = !input_lines.select { |x| lutaml?(x) }.empty?
22
+
23
+ has_lutaml = input_lines.any? { |line| lutaml?(line) }
22
24
  express_indexes = Utils.parse_document_express_indexes(
23
- document, input_lines
25
+ document,
26
+ input_lines,
27
+ )
28
+
29
+ result_content = process_input_lines(
30
+ document: document,
31
+ input_lines: input_lines,
32
+ express_indexes: express_indexes,
24
33
  )
25
- result_content = processed_lines(document, input_lines,
26
- express_indexes)
27
- has_lutaml and log(document, result_content)
34
+
35
+ log(document, result_content) if has_lutaml
36
+
28
37
  Asciidoctor::PreprocessorNoIfdefsReader.new(document, result_content)
29
38
  end
30
39
 
31
40
  protected
32
41
 
33
- def log(document, result)
34
- File.open("#{document.attr('docfile')}.lutaml.log.txt",
35
- "w:UTF-8") do |f|
36
- f.write(result.join("\n"))
42
+ def log(doc, text)
43
+ File.open("#{doc.attr('docfile')}.lutaml.log.txt", "w:UTF-8") do |f|
44
+ f.write(text.join("\n"))
37
45
  end
38
46
  end
39
47
 
40
48
  def lutaml?(line)
41
- line.match(/^\[(?:\blutaml\b|\blutaml_express\b),([^,]+)?,?([^,]+)?,?([^,]+)?\]/)
49
+ line.match(/^\[(?:\blutaml\b|\blutaml_express\b),(?<index_names>[^,]+)?,?(?<context_name>[^,]+)?(?<options>,.*)?\]/)
42
50
  end
43
51
 
44
- def content_from_files(document, file_paths)
45
- file_list = file_paths.map do |file_path|
46
- File.new(Utils.relative_file_path(document, file_path),
47
- encoding: "UTF-8")
48
- end
49
- ::Lutaml::Parser.parse(file_list)
52
+ def load_lutaml_file(document, file_path)
53
+ ::Lutaml::Parser.parse(
54
+ File.new(
55
+ Utils.relative_file_path(document, file_path),
56
+ encoding: "UTF-8",
57
+ ),
58
+ )
50
59
  end
51
60
 
52
61
  private
53
62
 
54
- def processed_lines(document, input_lines, express_indexes)
63
+ def process_input_lines(
64
+ document:,
65
+ input_lines:,
66
+ express_indexes:
67
+ )
68
+
55
69
  result = []
56
70
  loop do
57
- result
58
- .push(*process_text_blocks(
71
+ result.push(
72
+ *process_text_blocks(
59
73
  document,
60
74
  input_lines,
61
75
  express_indexes,
62
- ))
76
+ ),
77
+ )
63
78
  end
64
79
  result
65
80
  end
66
81
 
67
82
  def process_text_blocks(document, input_lines, express_indexes)
68
83
  line = input_lines.next
69
- block_match = lutaml?(line)
70
- return [line] if block_match.nil?
84
+ block_header_match = lutaml?(line)
85
+
86
+ return [line] if block_header_match.nil?
87
+
88
+ index_names = block_header_match[:index_names].split(";").map(&:strip)
89
+ context_name = block_header_match[:context_name].strip
90
+
91
+ options = block_header_match[:options] &&
92
+ parse_options(block_header_match[:options].to_s.strip) || {}
71
93
 
72
94
  end_mark = input_lines.next
73
- parse_template(document,
74
- collect_internal_block_lines(document,
75
- input_lines,
76
- end_mark),
77
- block_match,
78
- express_indexes)
95
+
96
+ render_template(
97
+ document: document,
98
+ lines: extract_block_lines(input_lines, end_mark),
99
+ index_names: index_names,
100
+ context_name: context_name,
101
+ options: options,
102
+ indexes: express_indexes,
103
+ )
79
104
  end
80
105
 
81
- def collect_internal_block_lines(_document, input_lines, end_mark)
82
- current_block = []
106
+ def extract_block_lines(input_lines, end_mark)
107
+ block = []
83
108
  while (block_line = input_lines.next) != end_mark
84
- current_block.push(block_line)
109
+ block.push(block_line)
85
110
  end
86
- current_block
111
+ block
87
112
  end
88
113
 
89
- def contexts_items(block_match, document, express_indexes)
90
- contexts_names = block_match[1].split(";").map(&:strip)
91
- file_paths = []
92
- result = contexts_names.each_with_object([]) do |path, res|
93
- if express_indexes[path]
94
- res.push(express_indexes[path])
114
+ def gather_context_items(index_names:, document:, indexes:)
115
+ index_names.map do |path|
116
+ # TODO: Rephrase of the below TODO message.
117
+ # ::Lutaml::Parser.parse(file_list) can return an Array or just one.
118
+ # TODO: decide how to handle expressir multiply file parse as one
119
+ # object and lutaml
120
+
121
+ # Does this condition ever happen? That is only if the `lutaml-express-index` condition is not set
122
+ if indexes[path]
123
+ indexes[path][:serialized_hash] ||= indexes[path][:wrapper].to_liquid
95
124
  else
96
- file_paths.push(path)
125
+ wrapper = load_lutaml_file(document, path)
126
+ indexes[path] = {
127
+ wrapper: wrapper,
128
+ serialized_hash: wrapper.to_liquid,
129
+ }
97
130
  end
131
+
132
+ indexes[path]
98
133
  end
99
- if !file_paths.empty?
100
- from_files = content_from_files(document, file_paths)
101
- # TODO: decide how to handle expressir multiply file parse as one object and lutaml
102
- if from_files.is_a?(Array)
103
- result.push(*from_files.map(&:to_liquid))
104
- else
105
- from_files = from_files.to_liquid
106
- from_files["schemas"] = from_files["schemas"].map do |n|
107
- n.merge("relative_path_prefix" => Utils.relative_file_path(document, File.dirname(n["file"])))
108
- end
109
- result.push(from_files)
110
- end
134
+ end
135
+
136
+ def parse_yaml_config_file(document, file_path)
137
+ return nil if file_path.nil?
138
+
139
+ relative_file_path = Utils.relative_file_path(document, file_path)
140
+ YAML.safe_load(File.read(relative_file_path, encoding: "UTF-8"))
141
+ end
142
+
143
+ def decorate_schema_object(schema:, document:, indexes:, index_names:,
144
+ selected:, options:)
145
+ # Mark a schema as "selected" with `.selected`
146
+ schema["selected"] = true if selected
147
+
148
+ # Provide pretty-formatted code under `.formatted`
149
+ _, index_found_value = indexes.detect do |_k, _v|
150
+ _
111
151
  end
112
- result
152
+
153
+ schema["formatted"] = index_found_value[:wrapper].original_document.schemas.detect do |s|
154
+ s.id == schema["id"]
155
+ end.to_s(no_remarks: true)
156
+
157
+ # Decorate the remaining things
158
+ decorate_context_items(
159
+ schema,
160
+ options.merge(
161
+ "relative_path_prefix" =>
162
+ Utils.relative_file_path(document,
163
+ File.dirname(schema["file"])),
164
+ ),
165
+ ) || {}
113
166
  end
114
167
 
115
- def parse_template(document, current_block, block_match,
116
- express_indexes)
117
- options = parse_options(block_match[3])
118
- contexts_items(block_match, document, express_indexes)
119
- .map do |items|
120
- if items["schemas"]
121
- items["schemas"] = items["schemas"].map do |j|
122
- opts = options.merge("relative_path_prefix" => j["relative_path_prefix"])
123
- decorate_context_items(j, opts)
124
- end
125
- end
126
- parse_context_block(document: document,
127
- context_lines: current_block,
128
- context_items: items,
129
- context_name: block_match[2].strip)
130
- end.flatten
168
+ def render_template(document:, lines:, context_name:, index_names:,
169
+ options:, indexes:)
170
+ config_yaml_path = options.delete("config_yaml")
171
+ config_yaml = if config_yaml_path
172
+ parse_yaml_config_file(document, config_yaml_path)
173
+ else
174
+ {}
175
+ end
176
+
177
+ selected_schemas = config_yaml["schemas"]
178
+
179
+ gather_context_items(
180
+ index_names: index_names,
181
+ document: document,
182
+ indexes: indexes,
183
+ ).map do |items|
184
+ serialized_hash = items[:serialized_hash]
185
+
186
+ serialized_hash["schemas"]&.map! do |schema|
187
+ decorate_schema_object(
188
+ schema: schema,
189
+ document: document,
190
+ index_names: index_names,
191
+ indexes: indexes,
192
+ selected: selected_schemas && selected_schemas.include?(schema["id"]),
193
+ options: options,
194
+ )
195
+ end
196
+
197
+ render_block(
198
+ document: document,
199
+ block_lines: lines,
200
+ context_items: serialized_hash,
201
+ context_name: context_name,
202
+ )
203
+ end.flatten
131
204
  rescue StandardError => e
132
- document.logger.warn("Failed to parse lutaml block: #{e.message}")
205
+ raise e
206
+ document.logger.warn("Failed to parse LutaML block: #{e.message}")
133
207
  []
134
208
  end
135
209
 
136
210
  def parse_options(options_string)
137
211
  options_string
138
212
  .to_s
139
- .scan(/(.+?)=(\s?[^\s]+)/)
213
+ .scan(/,\s*([^=]+?)=(\s*[^,]+)/)
140
214
  .map { |elem| elem.map(&:strip) }
141
215
  .to_h
142
216
  end
143
217
 
144
- def decorate_context_items(context_items, options)
145
- return context_items if !context_items.is_a?(Hash)
146
-
147
- context_items
148
- .map do |(key, val)|
149
- if val.is_a?(Hash)
150
- [key, decorate_context_items(val, options)]
151
- elsif key == REMARKS_ATTRIBUTE
152
- [key,
153
- val&.map do |remark|
154
- Metanorma::Plugin::Lutaml::ExpressRemarksDecorator
155
- .call(remark, options)
156
- end]
157
- elsif val.is_a?(Array)
158
- [key, val.map { |n| decorate_context_items(n, options) }]
159
- else
160
- [key, val]
161
- end
162
- end
163
- .to_h
218
+ def decorate_context_item(key, val, options)
219
+ if key == REMARKS_ATTRIBUTE
220
+ return [
221
+ key,
222
+ val&.map do |remark|
223
+ Metanorma::Plugin::Lutaml::ExpressRemarksDecorator
224
+ .call(remark, options)
225
+ end,
226
+ ]
227
+ end
228
+
229
+ case val
230
+ when Hash
231
+ [key, decorate_context_items(val, options)]
232
+ when Array
233
+ [key, val.map { |n| decorate_context_items(n, options) }]
234
+ else
235
+ [key, val]
236
+ end
164
237
  end
165
238
 
166
- def parse_context_block(context_lines:,
167
- context_items:,
168
- context_name:,
169
- document:)
239
+ def decorate_context_items(item, options)
240
+ return item unless item.is_a?(Hash)
241
+
242
+ item.map do |(key, val)|
243
+ decorate_context_item(key, val, options)
244
+ end.to_h
245
+ end
246
+
247
+ def render_block(block_lines:, context_items:, context_name:, document:)
170
248
  render_result, errors = Utils.render_liquid_string(
171
- template_string: context_lines.join("\n"),
249
+ template_string: block_lines.join("\n"),
172
250
  context_items: context_items,
173
251
  context_name: context_name,
174
252
  document: document,
175
253
  )
254
+
176
255
  Utils.notify_render_errors(document, errors)
256
+
177
257
  render_result.split("\n")
178
258
  end
179
259
  end
@@ -9,7 +9,7 @@ module Metanorma
9
9
  # @example [lutaml_uml_attributes_table,path/to/lutaml,EntityName]
10
10
  class LutamlUmlAttributesTablePreprocessor < LutamlUmlClassPreprocessor
11
11
  MACRO_REGEXP =
12
- /\[lutaml_uml_attributes_table,([^,]+),?([^,]+),?(.+?)?\]/
12
+ /\[lutaml_uml_attributes_table,([^,]+),?([^,]+),?(.+?)?\]/.freeze
13
13
 
14
14
  # rubocop:disable Layout/IndentHeredoc
15
15
  def template(options)
@@ -15,7 +15,7 @@ module Metanorma
15
15
  # @example [lutaml_uml_class,path/to/lutaml,EntityName]
16
16
  class LutamlUmlClassPreprocessor < ::Asciidoctor::Extensions::Preprocessor
17
17
  MACRO_REGEXP =
18
- /\[lutaml_uml_class,([^,]+),?([^,]+),?(.+?)?\]/
18
+ /\[lutaml_uml_class,([^,]+),?([^,]+),?(.+?)?\]/.freeze
19
19
 
20
20
  def get_macro_regexp
21
21
  self.class.const_get(:MACRO_REGEXP)
@@ -109,9 +109,9 @@ module Metanorma
109
109
 
110
110
  <<~TEMPLATE
111
111
  {% if definition.keyword == 'enumeration' %}
112
- #{equalsigns(depth) + ' Enumeration: {{ definition.name }}' unless skip_headers}
112
+ #{"#{equalsigns(depth)} Enumeration: {{ definition.name }}" unless skip_headers}
113
113
  {% else %}
114
- #{equalsigns(depth) + ' Class: {{ definition.name }}' unless skip_headers}
114
+ #{"#{equalsigns(depth)} Class: {{ definition.name }}" unless skip_headers}
115
115
  {% endif %}
116
116
 
117
117
  #{equalsigns(depth + 1)} Description
@@ -16,7 +16,7 @@ module Metanorma
16
16
  class LutamlUmlDatamodelDescriptionPreprocessor <
17
17
  ::Asciidoctor::Extensions::Preprocessor
18
18
  MACRO_REGEXP =
19
- /\[lutaml_uml_datamodel_description,([^,]+),?(.+)?\]/
19
+ /\[lutaml_uml_datamodel_description,([^,]+),?(.+)?\]/.freeze
20
20
  LIQUID_INCLUDE_PATH = File.join(
21
21
  Gem.loaded_specs["metanorma-plugin-lutaml"].full_gem_path,
22
22
  "lib", "metanorma", "plugin", "lutaml", "liquid_templates"
@@ -92,7 +92,7 @@ module Metanorma
92
92
  def fill_in_entities_refs_attributes(document, lutaml_document_wrapper,
93
93
  options)
94
94
  lutaml_document = lutaml_document_wrapper.original_document
95
- render_style = options.fetch(RENDER_STYLE_ATTRIBUTE, "default")
95
+ options.fetch(RENDER_STYLE_ATTRIBUTE, "default")
96
96
  all_children_packages = lutaml_document.packages
97
97
  .map(&:children_packages).flatten
98
98
  package_flat_packages = lambda do |pks|
@@ -201,7 +201,8 @@ options)
201
201
  end
202
202
 
203
203
  def package_entities(options)
204
- options["packages"] or return {}
204
+ return {} unless options["packages"]
205
+
205
206
  options["packages"]
206
207
  .find_all { |entity| entity.is_a?(Hash) && entity.values.first["render_entities"] }
207
208
  .map do |entity|
@@ -27,16 +27,22 @@ module Metanorma
27
27
  def render_liquid_string(template_string:, context_items:,
28
28
  context_name:, document:, include_path: nil)
29
29
  liquid_template = ::Liquid::Template.parse(template_string)
30
+
30
31
  # Allow includes for the template
31
- include_paths = [Utils.relative_file_path(document, ""),
32
- include_path].compact
32
+ include_paths = [
33
+ Utils.relative_file_path(document, ""),
34
+ include_path,
35
+ ].compact
36
+
33
37
  liquid_template.registers[:file_system] =
34
38
  ::Metanorma::Plugin::Lutaml::Liquid::LocalFileSystem
35
39
  .new(include_paths, ["_%s.liquid", "_%s.adoc"])
40
+
36
41
  rendered_string = liquid_template
37
42
  .render(context_name => context_items,
38
43
  strict_variables: true,
39
44
  error_mode: :warn)
45
+
40
46
  [rendered_string, liquid_template.errors]
41
47
  end
42
48
 
@@ -48,37 +54,50 @@ module Metanorma
48
54
  end
49
55
  end
50
56
 
51
- def process_express_index(path, cache_path, document,
52
- force_read = false)
53
- if cache_path
54
- cache_full_path = Utils.relative_file_path(document,
55
- cache_path)
56
- end
57
+ def load_express_repositories(path:, cache_path:, document:,
58
+ force_read: false)
59
+ cache_full_path = cache_path &&
60
+ Utils.relative_file_path(document, cache_path)
61
+
62
+ # If there is cache and "force read" not set.
57
63
  if !force_read && cache_full_path && File.file?(cache_full_path)
58
- return express_from_cache(cache_full_path)
64
+ return load_express_repo_from_cache(cache_full_path)
59
65
  end
60
66
 
67
+ # If there is no cache or "force read" is set.
61
68
  full_path = Utils.relative_file_path(document, path)
62
- wrapper = express_from_path(document, full_path)
69
+ lutaml_wrapper = load_express_repo_from_path(document, full_path)
70
+
63
71
  if cache_full_path && !File.file?(cache_full_path)
64
- express_write_cache(cache_full_path, wrapper.original_document,
65
- document)
72
+ save_express_repo_to_cache(
73
+ cache_full_path,
74
+ lutaml_wrapper.original_document,
75
+ document,
76
+ )
66
77
  end
67
- wrapper
78
+
79
+ lutaml_wrapper
68
80
  rescue Expressir::Error
69
81
  FileUtils.rm_rf(cache_full_path)
70
- process_express_index(path, cache_path, document, true)
82
+
83
+ load_express_repositories(
84
+ path: path,
85
+ cache_path: cache_path,
86
+ document: document,
87
+ force_read: true,
88
+ )
71
89
  rescue StandardError => e
72
90
  document.logger.warn("Failed to load #{full_path}: #{e.message}")
73
- nil
91
+ raise e
92
+ # nil
74
93
  end
75
94
 
76
- def express_from_cache(path)
95
+ def load_express_repo_from_cache(path)
77
96
  ::Lutaml::Parser
78
97
  .parse(File.new(path), ::Lutaml::Parser::EXPRESS_CACHE_PARSE_TYPE)
79
98
  end
80
99
 
81
- def express_write_cache(path, repository, document)
100
+ def save_express_repo_to_cache(path, repository, document)
82
101
  root_path = Pathname.new(relative_file_path(document, ""))
83
102
  Expressir::Express::Cache
84
103
  .to_file(path,
@@ -86,43 +105,28 @@ force_read = false)
86
105
  root_path: root_path)
87
106
  end
88
107
 
89
- def express_from_path(document, path)
90
- if File.directory?(path)
91
- return express_from_folder(path)
92
- end
108
+ def load_express_repo_from_path(document, path)
109
+ return load_express_from_folder(path) if File.directory?(path)
93
110
 
94
- express_from_index(document, path)
111
+ load_express_from_index(document, path)
95
112
  end
96
113
 
97
- def express_from_folder(folder)
114
+ def load_express_from_folder(folder)
98
115
  files = Dir["#{folder}/*.exp"].map do |nested_path|
99
116
  File.new(nested_path, encoding: "UTF-8")
100
117
  end
101
118
  ::Lutaml::Parser.parse(files)
102
119
  end
103
120
 
104
- def express_decorate_wrapper(wrapper, document)
105
- serialized = wrapper.to_liquid
106
- serialized["schemas"].map! do |j|
107
- j.merge(
108
- "relative_path_prefix" => Utils
109
- .relative_file_path(document, File.dirname(j["file"])),
110
- "formatted" => wrapper.original_document
111
- .schemas.detect {|s| s.id == j["id"] }.to_s(no_remarks: true)
112
- )
113
- end
114
- serialized
115
- end
116
-
117
- def express_from_index(document, path)
121
+ def load_express_from_index(document, path)
118
122
  yaml_content = YAML.safe_load(File.read(path))
119
123
  root_path = yaml_content["path"]
120
- schemas_paths = yaml_content
121
- .fetch("schemas")
124
+ schemas_paths = yaml_content["schemas"]
122
125
  .map do |(schema_name, schema_values)|
123
126
  schema_values["path"] || File.join(root_path.to_s,
124
127
  "#{schema_name}.exp")
125
128
  end
129
+
126
130
  files_to_load = schemas_paths.map do |path|
127
131
  File.new(Utils.relative_file_path(document, path),
128
132
  encoding: "UTF-8")
@@ -134,20 +138,35 @@ force_read = false)
134
138
  express_indexes = {}
135
139
  loop do
136
140
  line = input_lines.next
141
+
142
+ # Finished parsing document attributes
137
143
  break if line.empty?
138
144
 
139
145
  match = line.match(LUTAML_EXP_IDX_TAG)
140
- if match
141
- name = match[:index_name]
142
- path = match[:index_path]
143
- cache = match[:cache_path]
144
- repositories = process_express_index(path.strip, cache, document)
145
- if repositories
146
- express_indexes[name.strip] =
147
- express_decorate_wrapper(repositories, document)
148
- end
146
+ next unless match
147
+
148
+ name = match[:index_name]&.strip
149
+ path = match[:index_path]&.strip
150
+ cache = match[:cache_path]&.strip
151
+
152
+ unless name && path
153
+ raise StandardError.new("No name and path set in `:lutaml-express-index:` attribute.")
154
+ end
155
+
156
+ lutaml_expressir_wrapper = load_express_repositories(
157
+ path: path,
158
+ cache_path: cache,
159
+ document: document,
160
+ )
161
+
162
+ if lutaml_expressir_wrapper
163
+ express_indexes[name] = {
164
+ wrapper: lutaml_expressir_wrapper,
165
+ serialized_hash: nil,
166
+ }
149
167
  end
150
168
  end
169
+
151
170
  express_indexes
152
171
  rescue StopIteration
153
172
  express_indexes
@@ -1,7 +1,7 @@
1
1
  module Metanorma
2
2
  module Plugin
3
3
  module Lutaml
4
- VERSION = "0.6.0".freeze
4
+ VERSION = "0.6.2".freeze
5
5
  end
6
6
  end
7
7
  end
@@ -30,7 +30,7 @@ Gem::Specification.new do |spec|
30
30
  spec.add_dependency "liquid"
31
31
  spec.add_dependency "lutaml"
32
32
  spec.add_dependency "relaton-cli"
33
- spec.add_dependency "reverse_adoc"
33
+ spec.add_dependency "reverse_adoc", "~> 0.3.7"
34
34
 
35
35
  spec.add_development_dependency "debug"
36
36
  spec.add_development_dependency "equivalent-xml"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metanorma-plugin-lutaml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-04-23 00:00:00.000000000 Z
11
+ date: 2024-05-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor
@@ -84,16 +84,16 @@ dependencies:
84
84
  name: reverse_adoc
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ">="
87
+ - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '0'
89
+ version: 0.3.7
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ">="
94
+ - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '0'
96
+ version: 0.3.7
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: debug
99
99
  requirement: !ruby/object:Gem::Requirement