metanorma-plugin-lutaml 0.7.8 → 0.7.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '091036d68a92b76cdfb383ae829bd65182a26ddc1146cce1d844a5646c27ca83'
4
- data.tar.gz: 39bfe3ec5d4b57985902f5ab17f6d097db903f3151efee95068cefe4d2861f5e
3
+ metadata.gz: 29510e3dd02119b47d1d179c94d0a954b596dc0255410091d8c0db366e6a4dd3
4
+ data.tar.gz: b2502ffd6bea597bc56c8882712c58d13e72799eca5387c76329a9ef813d62eb
5
5
  SHA512:
6
- metadata.gz: 4276c20cae2b83cc37b562217429e00b951a2e0a73bf384f931b47bd94b71774db3b42d62cfc1c380bf3b64bf9b6d5c6b8d98fbe18b5b2d9426558ba8aa40a1e
7
- data.tar.gz: 4323e58139487b3192af2da916a8142f1bd56b7cf8d2df3dae2882172ea7cf22c10e0cfd4d31278cbd3e731f2a689ab871e6a5baa1d89d462a95df90ab389500
6
+ metadata.gz: b06a2f0d8be8e9073c3f631b260d8e88525353afb8e4e6cdf11bd6db9d78994543eb6a9acda9a2602212943ff972a700efa7c7d3dc870951cd3f2c6e5a219ff2
7
+ data.tar.gz: c80c2d456bec408dccb3c621397bc9313e2cc6a53cf7c5671d504737087ebb597b446d2fc043e3deaaf809a0941f0f3b732837bf4b5aee404685d70cd6ab0d27
data/Gemfile CHANGED
@@ -11,7 +11,3 @@ begin
11
11
  rescue StandardError
12
12
  nil
13
13
  end
14
-
15
- # gem "lutaml", path: "../../lutaml/lutaml"
16
-
17
- gem "ogc-gml", github: "lutaml/ogc-gml"
@@ -1,5 +1,4 @@
1
1
  require "coradoc"
2
- require "coradoc/input/html"
3
2
 
4
3
  module Metanorma
5
4
  module Plugin
@@ -7,6 +6,7 @@ module Metanorma
7
6
  module Liquid
8
7
  module CustomFilters
9
8
  def html2adoc(input)
9
+ # Coradoc::ReverseAdoc.convert(input)
10
10
  Coradoc::Input::HTML.convert(input)
11
11
  end
12
12
 
@@ -0,0 +1,310 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "liquid"
4
+ require "asciidoctor"
5
+ require "asciidoctor/reader"
6
+ require "lutaml"
7
+ # require "lutaml/uml"
8
+ require "xmi"
9
+ require "lutaml/xmi"
10
+ require "metanorma/plugin/lutaml/utils"
11
+ require "metanorma/plugin/lutaml/asciidoctor/preprocessor"
12
+
13
+ module Metanorma
14
+ module Plugin
15
+ module Lutaml
16
+ # Macro for quick rendering of datamodel attributes/values tables
17
+ # from liquid drop object
18
+ class LutamlEaXmiPreprocessor <
19
+ ::Asciidoctor::Extensions::Preprocessor
20
+ MACRO_REGEXP =
21
+ /\[lutaml_ea_xmi,([^,]+),?(.+)?\]/.freeze
22
+ LIQUID_INCLUDE_PATH = File.join(
23
+ Gem.loaded_specs["metanorma-plugin-lutaml"].full_gem_path,
24
+ "lib", "metanorma", "plugin", "lutaml", "liquid_templates"
25
+ )
26
+ DEFAULT_RENDER_INCLUDE = "packages"
27
+ RENDER_STYLES_INCLUDES = {
28
+ "default" => "packages",
29
+ "entity_list" => "packages_entity_list",
30
+ "entity_list_class" => "packages_entity_list_class",
31
+ "data_dictionary" => "packages_data_dictionary",
32
+ }.freeze
33
+ RENDER_STYLE_ATTRIBUTE = "render_style"
34
+ SUPPORTED_NESTED_MACRO = %w[
35
+ before diagram_include_block after include_block package_text
36
+ ].freeze
37
+ # search document for block `lutaml_ea_xmi`
38
+ # read include derectives that goes after that in block and transform
39
+ # into yaml2text blocks
40
+ def process(document, reader)
41
+ r = Asciidoctor::PreprocessorNoIfdefsReader.new document, reader.lines
42
+ input_lines = r.readlines.to_enum
43
+ Asciidoctor::PreprocessorNoIfdefsReader
44
+ .new(document, processed_lines(document, input_lines))
45
+ end
46
+
47
+ private
48
+
49
+ def lutaml_document_from_file_or_cache(document, file_path, yaml_config)
50
+ full_path = Utils.relative_file_path(document, file_path)
51
+ if document.attributes["lutaml_xmi_cache"] &&
52
+ document.attributes["lutaml_xmi_cache"][full_path]
53
+ return document.attributes["lutaml_xmi_cache"][full_path]
54
+ end
55
+
56
+ yaml_config["ea_extension"]&.each do |ea_extension_path|
57
+ ea_extension_full_path = File.expand_path(
58
+ ea_extension_path, File.dirname(file_path)
59
+ )
60
+ Xmi::EaRoot.load_extension(ea_extension_full_path)
61
+ end
62
+
63
+ result_document = ::Lutaml::XMI::Parsers::XML.serialize_xmi_to_liquid(
64
+ File.new(
65
+ full_path, encoding: "UTF-8"
66
+ ),
67
+ )
68
+
69
+ document.attributes["lutaml_xmi_cache"] ||= {}
70
+ document.attributes["lutaml_xmi_cache"][full_path] = result_document
71
+ result_document
72
+ end
73
+
74
+ def parse_yaml_config_file(document, file_path)
75
+ return {} if file_path.nil?
76
+
77
+ relative_file_path = Utils.relative_file_path(document, file_path)
78
+ YAML.safe_load(File.read(relative_file_path, encoding: "UTF-8"))
79
+ end
80
+
81
+ def processed_lines(document, input_lines)
82
+ result = []
83
+ loop do
84
+ result.push(*process_text_blocks(document, input_lines))
85
+ end
86
+ result
87
+ end
88
+
89
+ def process_text_blocks(document, input_lines)
90
+ line = input_lines.next
91
+ block_match = line.match(MACRO_REGEXP)
92
+
93
+ return [line] if block_match.nil?
94
+
95
+ yaml_config = parse_yaml_config_file(document, block_match[2])
96
+ lutaml_document = lutaml_document_from_file_or_cache(document,
97
+ block_match[1],
98
+ yaml_config)
99
+ fill_in_diagrams_attributes(document, lutaml_document)
100
+ model_representation(
101
+ lutaml_document, document,
102
+ collect_additional_context(document, input_lines, input_lines.next),
103
+ yaml_config
104
+ )
105
+ end
106
+
107
+ def fill_in_entities_refs_attributes(document,
108
+ lutaml_document, options)
109
+ # render_style = options.fetch(RENDER_STYLE_ATTRIBUTE, "default")
110
+ all_children_packages = lutaml_document.packages
111
+ .map(&:children_packages).flatten
112
+ package_flat_packages = lambda do |pks|
113
+ pks.each_with_object({}) do |package, res|
114
+ res[package.name] = package.xmi_id
115
+ end
116
+ end
117
+ children_pks = package_flat_packages.call(all_children_packages)
118
+ ref_dictionary = package_flat_packages.call(lutaml_document.packages)
119
+ .merge(children_pks)
120
+ %w[class enum data_type].each do |type|
121
+ package_flat = lambda do |pks|
122
+ pks.each_with_object({}) do |package, res|
123
+ plural = type == "class" ? "classes" : "#{type}s"
124
+ package.send(plural).map do |entity|
125
+ res["#{type}:#{package.name}:#{entity.name}"] = entity.xmi_id
126
+ end
127
+ end
128
+ end
129
+ children_pks_diags = package_flat.call(all_children_packages)
130
+ ref_dictionary = ref_dictionary
131
+ .merge(package_flat.call(lutaml_document.packages)
132
+ .merge(children_pks_diags))
133
+ end
134
+ document.attributes["lutaml_entity_id"] = ref_dictionary
135
+ end
136
+
137
+ def fill_in_diagrams_attributes(document, lutaml_document)
138
+ package_flat_diagrams = lambda do |pks|
139
+ pks.each_with_object({}) do |package, res|
140
+ package.diagrams.map do |diag|
141
+ res["#{package.name}:#{diag.name}"] = diag.xmi_id
142
+ end
143
+ end
144
+ end
145
+ children_pks_diags = package_flat_diagrams.call(
146
+ lutaml_document.packages.map(&:children_packages).flatten,
147
+ )
148
+
149
+ document.attributes["lutaml_figure_id"] = package_flat_diagrams
150
+ .call(lutaml_document.packages)
151
+ .merge(children_pks_diags)
152
+ end
153
+
154
+ def collect_additional_context(document, input_lines, end_mark)
155
+ additional_context = Hash.new { |hash, key| hash[key] = [] }
156
+ additional_context["all_macros"] = []
157
+ block_lines = []
158
+ while (block_line = input_lines.next) != end_mark
159
+ block_lines.push(block_line)
160
+ end
161
+ processed_lines =
162
+ process(document, ::Asciidoctor::PreprocessorReader.new(
163
+ document, block_lines
164
+ ))
165
+ .read_lines
166
+ block_document = ::Asciidoctor::Document
167
+ .new(processed_lines, {}).parse
168
+ block_document.blocks.each do |block|
169
+ next unless SUPPORTED_NESTED_MACRO.include?(block.attributes["role"])
170
+
171
+ attrs = block.attributes
172
+ name = attrs.delete("role")
173
+ package = attrs.delete("package")
174
+ macro_keyword = [name, package].compact.join(";")
175
+ block_text = block.lines.length.positive? ? block.lines.join("\n") : ""
176
+ additional_context[macro_keyword]
177
+ .push({ "text" => block_text }.merge(attrs))
178
+ additional_context["all_macros"]
179
+ .push({ "text" => block_text,
180
+ "type" => name, "package" => package }.merge(attrs))
181
+ end
182
+ additional_context
183
+ end
184
+
185
+ def package_level(lutaml_document, level)
186
+ return lutaml_document if level <= 0
187
+
188
+ package_level(lutaml_document["packages"].first, level - 1)
189
+ end
190
+
191
+ def create_context_object(lutaml_document, additional_context, options)
192
+ root_package = package_level(lutaml_document.to_liquid,
193
+ options["package_root_level"] || 1)
194
+ if options.empty? || options["packages"].nil?
195
+ return {
196
+ "render_nested_packages" => true,
197
+ "packages" => root_package["packages"],
198
+ "root_packages" => [root_package],
199
+ "additional_context" => additional_context
200
+ .merge("external_classes" => options["external_classes"]),
201
+ "name" => root_package["name"],
202
+ }
203
+ end
204
+
205
+ all_packages = [root_package, *root_package["children_packages"]]
206
+ {
207
+ "packages" => sort_and_filter_out_packages(all_packages, options),
208
+ "package_entities" => package_entities(options),
209
+ "package_skip_sections" => package_skip_sections(options),
210
+ "additional_context" => additional_context
211
+ .merge("external_classes" => options["external_classes"]),
212
+ "root_packages" => [root_package],
213
+ "render_nested_packages" => options["render_nested_packages"] ||
214
+ false,
215
+ "name" => root_package["name"],
216
+ }
217
+ end
218
+
219
+ def package_entities(options)
220
+ return {} unless options["packages"]
221
+
222
+ options["packages"]
223
+ .find_all { |entity| entity.is_a?(Hash) && entity.values.first["render_entities"] }
224
+ .map do |entity|
225
+ [entity.keys.first,
226
+ entity.values.first["render_entities"].map { |n| [n, true] }.to_h]
227
+ end.to_h
228
+ end
229
+
230
+ def package_skip_sections(options)
231
+ return {} unless options["packages"]
232
+
233
+ options["packages"]
234
+ .find_all { |entity| entity.is_a?(Hash) && entity.values.first["skip_tables"] }
235
+ .map do |entity|
236
+ [entity.keys.first, entity.values.first["skip_tables"].map do |n|
237
+ [n, true]
238
+ end.to_h]
239
+ end.to_h
240
+ end
241
+
242
+ def sort_and_filter_out_packages(all_packages, options)
243
+ return all_packages if options["packages"].nil?
244
+
245
+ result = []
246
+ # Step one - filter out all skipped packages
247
+ options["packages"]
248
+ .find_all { |entity| entity.is_a?(Hash) && entity["skip"] }
249
+ .each do |entity|
250
+ entity_regexp = config_entity_regexp(entity["skip"])
251
+ all_packages
252
+ .delete_if { |package| package["name"] =~ entity_regexp }
253
+ end
254
+ # Step two - select supplied packages by pattern
255
+ options["packages"]
256
+ .find_all { |entity| entity.is_a?(String) || (entity.is_a?(Hash) && !entity["skip"]) }
257
+ .each do |entity_obj|
258
+ entity = entity_obj.is_a?(String) ? entity_obj : entity_obj.keys.first
259
+ entity_regexp = config_entity_regexp(entity)
260
+ all_packages.each do |package|
261
+ if package["name"]&.match?(entity_regexp)
262
+ result.push(package)
263
+ all_packages
264
+ .delete_if { |nest_package| nest_package["name"] == package["name"] }
265
+ end
266
+ end
267
+ end
268
+ result
269
+ end
270
+
271
+ def config_entity_regexp(entity)
272
+ additional_sym = ".*" if /\*$/.match?(entity)
273
+ %r{^#{Regexp.escape(entity.delete('*'))}#{additional_sym}$}
274
+ end
275
+
276
+ def model_representation(lutaml_document, document, additional_context,
277
+ options)
278
+ fill_in_entities_refs_attributes(document, lutaml_document, options)
279
+ render_result, errors = Utils.render_liquid_string(
280
+ template_string: template(options["section_depth"] || 2,
281
+ options["render_style"],
282
+ options["include_root"]),
283
+ context_items: create_context_object(lutaml_document,
284
+ additional_context,
285
+ options),
286
+ context_name: "context",
287
+ document: document,
288
+ include_path: LIQUID_INCLUDE_PATH,
289
+ )
290
+ Utils.notify_render_errors(document, errors)
291
+ render_result.split("\n")
292
+ end
293
+
294
+ def template(section_depth, render_style, include_root)
295
+ include_name = RENDER_STYLES_INCLUDES.fetch(render_style,
296
+ DEFAULT_RENDER_INCLUDE)
297
+ result = ""
298
+ if include_root
299
+ result += <<~LIQUID
300
+ {% include "#{include_name}", package_skip_sections: context.package_skip_sections, package_entities: context.package_entities, context: context.root_packages, additional_context: context.additional_context, render_nested_packages: false %}
301
+ LIQUID
302
+ end
303
+ result + <<~LIQUID
304
+ {% include "#{include_name}", depth: #{section_depth}, package_skip_sections: context.package_skip_sections, package_entities: context.package_entities, context: context, additional_context: context.additional_context, render_nested_packages: context.render_nested_packages %}
305
+ LIQUID
306
+ end
307
+ end
308
+ end
309
+ end
310
+ end
@@ -1,7 +1,7 @@
1
1
  module Metanorma
2
2
  module Plugin
3
3
  module Lutaml
4
- VERSION = "0.7.8".freeze
4
+ VERSION = "0.7.9".freeze
5
5
  end
6
6
  end
7
7
  end
@@ -3,6 +3,7 @@ require "metanorma/plugin/lutaml/lutaml_preprocessor"
3
3
  require "metanorma/plugin/lutaml/lutaml_uml_class_preprocessor"
4
4
  require "metanorma/plugin/lutaml/lutaml_uml_attributes_table_preprocessor"
5
5
  require "metanorma/plugin/lutaml/lutaml_uml_datamodel_description_preprocessor"
6
+ require "metanorma/plugin/lutaml/lutaml_ea_xmi_preprocessor"
6
7
  require "metanorma/plugin/lutaml/lutaml_diagram_block"
7
8
  require "metanorma/plugin/lutaml/lutaml_diagram_block_macro"
8
9
  require "metanorma/plugin/lutaml/lutaml_figure_inline_macro"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metanorma-plugin-lutaml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.8
4
+ version: 0.7.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
@@ -355,6 +355,7 @@ files:
355
355
  - lib/metanorma/plugin/lutaml/lutaml_diagram_block.rb
356
356
  - lib/metanorma/plugin/lutaml/lutaml_diagram_block_macro.rb
357
357
  - lib/metanorma/plugin/lutaml/lutaml_ea_diagram_block_macro.rb
358
+ - lib/metanorma/plugin/lutaml/lutaml_ea_xmi_preprocessor.rb
358
359
  - lib/metanorma/plugin/lutaml/lutaml_figure_inline_macro.rb
359
360
  - lib/metanorma/plugin/lutaml/lutaml_gml_dictionary_base.rb
360
361
  - lib/metanorma/plugin/lutaml/lutaml_gml_dictionary_block.rb