metanorma-plugin-lutaml 0.7.8 → 0.7.9

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: '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