metanorma-plugin-lutaml 0.4.7 → 0.4.11

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 (22) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +153 -72
  3. data/lib/metanorma/plugin/lutaml/liquid/custom_filters.rb +9 -0
  4. data/lib/metanorma/plugin/lutaml/liquid_templates/_packages.liquid +112 -6
  5. data/lib/metanorma/plugin/lutaml/liquid_templates/_packages_class.liquid +12 -12
  6. data/lib/metanorma/plugin/lutaml/liquid_templates/_packages_data_dictionary.liquid +237 -63
  7. data/lib/metanorma/plugin/lutaml/liquid_templates/_packages_data_dictionary_class.liquid +75 -0
  8. data/lib/metanorma/plugin/lutaml/liquid_templates/_packages_data_dictionary_classes.liquid +1 -41
  9. data/lib/metanorma/plugin/lutaml/liquid_templates/_packages_data_type.liquid +9 -10
  10. data/lib/metanorma/plugin/lutaml/liquid_templates/_packages_entity_list.liquid +118 -49
  11. data/lib/metanorma/plugin/lutaml/liquid_templates/_packages_entity_list_class.liquid +19 -0
  12. data/lib/metanorma/plugin/lutaml/liquid_templates/_packages_entity_list_classes.liquid +11 -0
  13. data/lib/metanorma/plugin/lutaml/liquid_templates/_packages_enum.liquid +11 -11
  14. data/lib/metanorma/plugin/lutaml/liquid_templates/test.rb +1 -0
  15. data/lib/metanorma/plugin/lutaml/lutaml_preprocessor.rb +1 -1
  16. data/lib/metanorma/plugin/lutaml/lutaml_table_inline_macro.rb +25 -0
  17. data/lib/metanorma/plugin/lutaml/lutaml_uml_attributes_table_preprocessor.rb +1 -1
  18. data/lib/metanorma/plugin/lutaml/lutaml_uml_datamodel_description_preprocessor.rb +93 -19
  19. data/lib/metanorma/plugin/lutaml/utils.rb +1 -1
  20. data/lib/metanorma/plugin/lutaml/version.rb +1 -1
  21. data/lib/metanorma-plugin-lutaml.rb +1 -0
  22. metadata +7 -2
@@ -2,112 +2,181 @@
2
2
  {% assign package_name = package.name | downcase | replace: ":", "" | replace: " ", "_" %}
3
3
  {% if additional_context.before and additional_context.before.size > 0 %}
4
4
  {% for before in additional_context.before %}
5
+ {% if before.liquid %}
6
+ {{ before.text | interpolate }}
7
+ {% else %}
5
8
  {{ before.text }}
9
+ {% endif %}
6
10
  {% endfor %}
7
11
  {% endif %}
8
- {% capture equalsigns %}{% for count in (1..depth) %}={% endfor %}{% endcapture %}{{equalsigns}} {{ package.name }}
9
- [[rc_{{ package_name }}-model_section]]
10
- {{equalsigns}}= {{ package.name }}
11
-
12
12
  {% assign before_package_key = 'before;' | append: package.name %}
13
- {% if additional_context[before_package_key] and additional_context[before_package_key].size > 0 %}
13
+ {% if additional_context[before_package_key] %}
14
14
  {% for before in additional_context[before_package_key] %}
15
+ {% if before.liquid %}
16
+ {{ before.text | interpolate }}
17
+ {% else %}
15
18
  {{ before.text }}
16
- {% endfor %}
17
19
  {% endif %}
18
- {% if additional_context.diagram_include_block %}
19
- {% for diagram_include_block in additional_context.diagram_include_block %}
20
- {% include "diagrams_block", package_name: package_name, image_base_path: diagram_include_block.base_path, text: diagram_include_block.text %}
21
20
  {% endfor %}
22
21
  {% endif %}
22
+ {% if depth %}
23
+ {% assign nested_depth = depth | plus: 1 %}
24
+ {% capture equalsigns %}{% for count in (1..depth) %}={% endfor %}{% endcapture %}
25
+ [[rc_{{ package_name }}-model_section]]
26
+ {{equalsigns}} {{ package.name }}
27
+ {% endif %}
23
28
 
24
- {% if additional_context.include_block and additional_context.include_block.size > 0 %}
25
- {% for block in additional_context.include_block %}
29
+ {% if additional_context.all_macros.size > 0 %}
30
+ {% assign sorted_all_macros = additional_context.all_macros | where: "position", "before" | sort: 'index' %}
31
+ {% for block in sorted_all_macros %}
32
+ {% case block.type %}
33
+ {% when 'include_block' %}
34
+ {% unless block.package and block.package != package.name %}
26
35
  {% capture block_filename %}{{ block.base_path }}{{ package_name }}{% endcapture %}
27
36
  {% capture block_content %}{% include block_filename %}{% endcapture %}
28
37
  {% unless block_content contains "Liquid error" %}
29
38
  {% if block.text %}
39
+
40
+ {% if block.liquid %}
41
+ {{ block.text | interpolate }}
42
+ {% else %}
30
43
  {{ block.text }}
31
44
  {% endif %}
45
+ {% endif %}
46
+
32
47
  {{ block_content }}
33
48
  {% endunless %}
34
- {% endfor %}
35
- {% endif %}
49
+ {% endunless %}
50
+ {% when 'package_text' %}
51
+ {% unless block.package and block.package != package.name %}
36
52
 
37
- {% assign include_block_package_key = 'include_block;' | append: package.name %}
38
- {% if additional_context[include_block_package_key] and additional_context[include_block_package_key].size > 0 %}
39
- {% for block in additional_context[include_block_package_key] %}
40
- {% capture block_filename %}{{ block.base_path }}{{ package_name }}{% endcapture %}
41
- {% capture block_content %}{% include block_filename %}{% endcapture %}
42
- {% unless block_content contains "Liquid error" %}
43
- {% if block.text %}
53
+ {% if block.liquid %}
54
+ {{ block.text | interpolate }}
55
+ {% else %}
44
56
  {{ block.text }}
45
57
  {% endif %}
46
- {{ block_content }}
47
58
  {% endunless %}
59
+ {% else %}
60
+ {% endcase %}
61
+ {% endfor %}
62
+ {% endif %}
63
+
64
+ {% comment %} // TODO: move to all_macros block {% endcomment %}
65
+ {% if additional_context.diagram_include_block %}
66
+ {% for diagram_include_block in additional_context.diagram_include_block %}
67
+ {% include "diagrams_block", package_name: package_name, image_base_path: diagram_include_block.base_path, text: diagram_include_block.text %}
48
68
  {% endfor %}
49
69
  {% endif %}
50
70
 
51
- {{equalsigns}}= Class Definitions
52
71
  {% if package.classes.size > 0 %}
53
- .Classes used in {{ package.name }}
72
+ {% unless package_skip_sections[package.name]['classes'] %}
73
+ {{equalsigns}}= Class definitions
74
+
75
+ {% endunless %}
76
+ {% comment %} {% assign data_types = package.classes | where: "stereotype", "DataType" %} {% endcomment %}
77
+ {% assign basic_types = package.classes | where: "stereotype", "BasicType" %}
78
+ {% comment %} {% assign enumerations = package.classes | where: "stereotype", "Enumeration" %} {% endcomment %}
79
+ {% assign code_lists = package.classes | where: "stereotype", "CodeList" %}
80
+ {% assign unions = package.data_types | where: "stereotype", "Union" %}
81
+
82
+ {% assign not_classes_length = plus: basic_types.size | plus: code_lists.size %}
83
+ {% assign not_classes_stereotypes = 'DataType,BasicType,Enumeration,CodeList' | split: ','%}
84
+ {% unless not_classes_length == package.classes.size or package_skip_sections[package.name]['classes'] %}
85
+ .Classes defined in {{ package.name }} ({{ package.stereotype }})
54
86
  [cols="2a,6a",options="header"]
55
87
  |===
56
- |Class |Description
88
+ |Name |Description
57
89
 
58
90
  {% for klass in package.classes %}
59
- |<<{{ klass.name }}-section,{{ klass.name }}>>
60
- «{{ klass.stereotype }}»
61
- |{{ klass.definition }}
91
+ {% unless not_classes_stereotypes contains klass.stereotype %}
92
+ {% capture ref_id %}{% if additional_context.external_classes[klass.name] %}{{ additional_context.external_classes[klass.name] }}{% else %}{{ klass.name }}-section{% endif %}{% endcapture %}
93
+ | <<{{ ref_id }},{{ klass.name }}>> «{{ klass.stereotype }}»
94
+ | {{ klass.definition | replace: '|', '\|' }}
62
95
 
96
+ {% endunless %}
63
97
  {% endfor %}
64
98
  |===
99
+ {% endunless %}
100
+
101
+ {% assign non_unions = package.data_types | where: "stereotype", "DataType" %}
102
+ {% if non_unions.size > 0 %}
103
+ {% include "packages_entity_list_classes", classes: non_unions, type: "Data types", depth: nested_depth %}
65
104
  {% endif %}
66
105
 
67
- {% if package.data_types.size > 0 %}
68
- .Data Types used in {{ package.name }}
69
- [cols="2,6",options="header"]
70
- |===
71
- |Name |Description
106
+ {% if basic_types.size > 0 %}
107
+ {% include "packages_entity_list_classes", classes: basic_types, type: "Primitive data types", depth: nested_depth %}
108
+ {% endif %}
72
109
 
73
- {% for klass in package.data_types %}
74
- |<<{{ klass.name }}-section,{{ klass.name }}>>
75
- |{{ klass.definition }}
110
+ {% if package.enums.size > 0 %}
111
+ {% include "packages_entity_list_classes", classes: package.enums, type: "Enumerated classes", depth: nested_depth %}
112
+ {% endif %}
76
113
 
77
- {% endfor %}
114
+ {% if unions.size > 0 %}
115
+ {% include "packages_entity_list_classes", classes: unions, type: "Union types", depth: nested_depth %}
116
+ {% endif %}
78
117
 
79
- |===
118
+ {% if code_lists.size > 0 %}
119
+ {% include "packages_entity_list_classes", classes: code_lists, type: "Code list classes", depth: nested_depth %}
80
120
  {% endif %}
81
121
 
82
- {% if package.enums.size > 0 %}
83
- .Enumerated Classes used in {{ package.name }}
84
- [cols="2a,6a",options="header"]
85
- |===
86
- |Name |Description
122
+ {% endif %}
123
+
124
+ {% if additional_context.all_macros.size > 0 %}
125
+ {% assign sorted_all_macros = additional_context.all_macros | where: "position", "after" | sort: 'index' %}
126
+ {% for block in sorted_all_macros %}
127
+ {% case block.type %}
128
+ {% when 'include_block' %}
129
+ {% unless block.package and block.package != package.name %}
130
+ {% capture block_filename %}{{ block.base_path }}{{ package_name }}{% endcapture %}
131
+ {% capture block_content %}{% include block_filename %}{% endcapture %}
132
+ {% unless block_content contains "Liquid error" %}
133
+ {% if block.text %}
87
134
 
88
- {% for klass in package.enums %}
89
- |<<{{ klass.name }}-section,{{ klass.name }}>>
90
- |{{ klass.definition }}
135
+ {% if block.liquid %}
136
+ {{ block.text | interpolate }}
137
+ {% else %}
138
+ {{ block.text }}
139
+ {% endif %}
140
+ {% endif %}
91
141
 
92
- {% endfor %}
142
+ {{ block_content }}
143
+ {% endunless %}
144
+ {% endunless %}
145
+ {% when 'package_text' %}
146
+ {% unless block.package and block.package != package.name %}
93
147
 
94
- |===
148
+ {% if block.liquid %}
149
+ {{ block.text | interpolate }}
150
+ {% else %}
151
+ {{ block.text }}
152
+ {% endif %}
153
+ {% endunless %}
154
+ {% else %}
155
+ {% endcase %}
156
+ {% endfor %}
95
157
  {% endif %}
96
158
 
97
159
  {% assign after_package_key = 'after;' | append: package.name %}
98
160
  {% if additional_context[after_package_key] %}
99
- {{equalsigns}}= Additional Information
100
161
  {% for after in additional_context[after_package_key] %}
162
+ {% if after.liquid %}
163
+ {{ after.text | interpolate }}
164
+ {% else %}
101
165
  {{ after.text }}
166
+ {% endif %}
102
167
  {% endfor %}
103
168
  {% endif %}
104
169
  {% if package.packages.size > 0 and render_nested_packages %}
105
- {% assign nested_depth = depth | plus: 1 %}{% include "packages_entity_list", depth: nested_depth, context: package %}
170
+ {% include "packages_entity_list", depth: nested_depth, context: package %}
106
171
  {% endif %}
107
172
  {% endfor %}
108
173
 
109
174
  {% if additional_context.after and additional_context.after.size > 0 %}
110
175
  {% for after in additional_context.after %}
176
+ {% if after.liquid %}
177
+ {{ after.text | interpolate }}
178
+ {% else %}
111
179
  {{ after.text }}
180
+ {% endif %}
112
181
  {% endfor %}
113
182
  {% endif %}
@@ -0,0 +1,19 @@
1
+ {% for package in context.packages %}
2
+ {% assign not_classes_stereotypes = 'DataType,BasicType,Enumeration,CodeList' | split: ','%}
3
+ [cols="2a,6a",options="header"]
4
+ |===
5
+ |Class |Description
6
+
7
+ {% for klass in package.classes %}
8
+ {% assign klass_name = klass.name %}
9
+ {% assign package_name = package.name %}
10
+ {% unless package_entities and package_entities[package_name][klass_name] != true %}
11
+ {% unless not_classes_stereotypes contains klass.stereotype %}
12
+ | <<{{ klass.name }}-section,{{ klass.name }}>> «{{ klass.stereotype }}»
13
+ | {{ klass.definition | replace: '|', '\|' }}
14
+
15
+ {% endunless %}
16
+ {% endunless %}
17
+ {% endfor %}
18
+ |===
19
+ {% endfor %}
@@ -0,0 +1,11 @@
1
+ .{{ type }} defined in {{ package.name }} ({{ package.stereotype }})
2
+ [cols="2a,6a",options="header"]
3
+ |===
4
+ |Name |Description
5
+
6
+ {% for klass in classes %}
7
+ | <<{{ klass.name }}-section,{{ klass.name }}>> «{{ klass.stereotype | default: "Enumeration" }}»
8
+ | {{ klass.definition | replace: '|', '\|' }}
9
+
10
+ {% endfor %}
11
+ |===
@@ -3,8 +3,9 @@
3
3
  {% elsif is_klass_spare == 'Spare' %}{% continue %}
4
4
  {% endif %}
5
5
  {% assign klass_name = klass.name | downcase | replace: ':', '' | replace: ' ', '_' %}
6
- [[tab-P-{{ package_name }}-E-{{ klass_name }}]]
7
- .Elements of {{ package.name }}::{{ klass.name }}
6
+
7
+ [[section-{{ klass.xmi_id }}]]
8
+ .Definition table of &#8220;{{ package.name }}::{{ klass.name }}&#8221; ({{ klass.stereotype }})
8
9
  [width="100%",cols="a,a,a,a,a,a,a,a"]
9
10
  |===
10
11
 
@@ -24,14 +25,14 @@ h|Inheritance from: 7+| {{ inherited | map: 'member_end' | join: ", " }}
24
25
  h|Generalization of: 7+| {{ generalizations | map: 'member_end' | join: ", " }}
25
26
  {% endif %}
26
27
 
27
- h|Abstract: 7+| {{ klass.is_abstract }}
28
+ h|Abstract: 7+| {% if klass.is_abstract %}True{% else %}False{% endif %}
28
29
  {% assign aggregations = klass.associations | where: "member_end_type", "aggregation" %}
29
30
  {% if aggregations.size > 0 %}
30
31
  .{{aggregations.size | plus: 1}}+h|Associations:
31
- 4+|_Association with:_
32
- |_Obligation_
32
+ 4+| _Association with_
33
+ | _Obligation_
33
34
  | _Maximum occurrence_
34
- |_Provides:_
35
+ | _Provides_
35
36
 
36
37
  {% for assoc in aggregations %}
37
38
  4+| {{assoc.member_end}}
@@ -41,11 +42,11 @@ h|Abstract: 7+| {{ klass.is_abstract }}
41
42
 
42
43
  {% endfor %}
43
44
  {% else %}
44
-
45
- .1+h|Associations: 7+| (none)
45
+ h| Associations: 7+| (none)
46
46
  {% endif %}
47
+
47
48
  {% if klass.values.size > 0 %}
48
- .{{klass.values.size | plus: 1}}+h|Values:
49
+ .{{klass.values.size | plus: 1}}+h| Values:
49
50
  | _Name_
50
51
  6+| _Definition_
51
52
 
@@ -55,9 +56,8 @@ h|Abstract: 7+| {{ klass.is_abstract }}
55
56
 
56
57
  {% endfor %}
57
58
  {% else %}
58
- .1+h|Values:
59
+ h| Values:
59
60
  7+| (none)
60
61
  {% endif %}
61
62
 
62
-
63
63
  |===
@@ -0,0 +1 @@
1
+ k = {"visibility"=>"public", "name"=>nil, "xmi_id"=>"EAID_0BD8DEDF_F024_453d_AA7D_6EBC873FDBB6", "member_end"=>"AbstractFeatureWithLifespan", "member_end_type"=>"inheritance", "member_end_cardinality"=>{"min"=>nil, "max"=>""},"}, "member_end_attribute_name"=>nil, "owner_end"=>"AbstractCityObject", "definition"=>""}{"visibility"=>"public", "name"=>nil, "xmi_id"=>"EAID_1C91D9CF_14CB_400c_A818_7C74428AE5B7", "member_end"=>"AbstractAppearance", "member_end_type"=>"aggregation", "member_end_cardinality"=>{"min"=>"M", "max"=>" "member_end_attribute_name"=>"appearance", "owner_end"=>"AbstractCityObject", "definition"=>"Relates appearances to the city object."}{"visibility"=>"public", "name"=>nil, "xmi_id"=>"EAID_BDD0FCAB_72F7_499b_AC4D_2391D4DE7CAC", "member_end"=>"AbstractGenericAttribute", "member_end_type"=>"aggregation", "member_end_cardinality"=>{"min"=>"M", "max"=>""},"}, "member_end_attribute_name"=>"genericAttribute", "owner_end"=>"AbstractCityObject", "definition"=>"Relates generic attributes to the city object."}{"visibility"=>"public", "name"=>nil, "xmi_id"=>"EAID_C22B8769_C2E7_4e9b_9C0D_138631E90002", "member_end"=>"AbstractCityObject", "member_end_type"=>"aggregation", "member_end_cardinality"=>{"min"=>"M", "max"=>" "member_end_attribute_name"=>"generalizesTo", "owner_end"=>"AbstractCityObject", "definition"=>"Relates generalized representations of the same real-world object in different Levels of Detail to the city object. The direction of this relation is from the city object to the corresponding generalized city objects."}{"visibility"=>"public", "name"=>nil, "xmi_id"=>"EAID_CF0045E1_6BF1_40a7_B08D_9B7B30ECA025", "member_end"=>"ExternalReference", "member_end_type"=>"aggregation", "member_end_cardinality"=>{"min"=>"M", "max"=>""},"}, "member_end_attribute_name"=>"externalReference", "owner_end"=>"AbstractCityObject", "definition"=>"References external objects in other information systems that have a relation to the city object."}{"visibility"=>"public", "name"=>nil, "xmi_id"=>"EAID_D45045CA_AAD6_418a_AF10_F4BC95DE923A", "member_end"=>"AbstractCityObject", "member_end_type"=>"aggregation", "member_end_cardinality"=>{"min"=>"M", "max"=>" "member_end_attribute_name"=>"relatedTo", "owner_end"=>"AbstractCityObject", "definition"=>"Relates other city objects to the city object. It also describes how the city objects are related to each other."}{"visibility"=>"public", "name"=>nil, "xmi_id"=>"EAID_E3BB8700_143D_4dbd_A7EC_49D33C66D430", "member_end"=>"AbstractDynamizer", "member_end_type"=>"aggregation", "member_end_cardinality"=>{"min"=>"M", "max"=>""},"}, "member_end_attribute_name"=>"dynamizer", "owner_end"=>"AbstractCityObject", "definition"=>"Relates Dynamizer objects to the city object. These allow timeseries data to override static attribute values of the city object."}{"visibility"=>"public", "name"=>nil, "owner_end"=>"AbstractCityObject"}{"visibility"=>"public", "name"=>nil, "xmi_id"=>"EAID_BE026036_E811_494c_9776_D1A309393D6D", "member_end"=>"AbstractSpace", "member_end_type"=>"generalization", "member_end_cardinality"=>nil, "member_end_attribute_name"=>nil, "owner_end"=>"AbstractCityObject", "definition"=>""}{"visibility"=>"public", "name"=>nil, "xmi_id"=>"EAID_C2189DFF_0F24_475b_AB55_070CD09A3186", "member_end"=>"AbstractSpaceBoundary", "member_end_type"=>"generalization", "member_end_cardinality"=>{"min"=>nil, "max"=>" "member_end_attribute_name"=>nil, "owner_end"=>"AbstractCityObject", "definition"=>""}{"visibility"=>"public", "name"=>nil, "xmi_id"=>"EAID_C22B8769_C2E7_4e9b_9C0D_138631E90002", "member_end"=>"AbstractCityObject", "member_end_type"=>"aggregation", "member_end_cardinality"=>{"min"=>"M", "max"=>""},"}, "member_end_attribute_name"=>"generalizesTo", "owner_end"=>"AbstractCityObject", "definition"=>"Relates generalized representations of the same real-world object in different Levels of Detail to the city object. The direction of this relation is from the city object to the corresponding generalized city objects."}{"visibility"=>"public", "name"=>nil, "xmi_id"=>"EAID_D45045CA_AAD6_418a_AF10_F4BC95DE923A", "member_end"=>"AbstractCityObject", "member_end_type"=>"aggregation", "member_end_cardinality"=>{"min"=>"M", "max"=>" "member_end_attribute_name"=>"relatedTo", "owner_end"=>"AbstractCityObject", "definition"=>"Relates other city objects to the city object. It also describes how the city objects are related to each other."}{"visibility"=>"public", "name"=>nil, "owner_end"=>"AbstractCityObject"}{"visibility"=>"public", "name"=>nil, "owner_end"=>"AbstractCityObject"}
@@ -52,7 +52,7 @@ module Metanorma
52
52
 
53
53
  def process_text_blocks(document, input_lines, express_indexes)
54
54
  line = input_lines.next
55
- block_match = line.match(/^\[lutaml,([^,]+)?,?([^,]+)?,?([^,]+)?\]/)
55
+ block_match = line.match(/^\[(?:\blutaml\b|\blutaml_express\b),([^,]+)?,?([^,]+)?,?([^,]+)?\]/)
56
56
  return [line] if block_match.nil?
57
57
 
58
58
  end_mark = input_lines.next
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Metanorma
4
+ module Plugin
5
+ module Lutaml
6
+ class LutamlTableInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
7
+ include LutamlDiagramBase
8
+ SUPPORTED_OPTIONS = %w[class enum data_type]
9
+
10
+ use_dsl
11
+ named :lutaml_table_class
12
+
13
+ def process(parent, _target, attrs)
14
+ keyword = SUPPORTED_OPTIONS.find { |n| attrs[n] }
15
+ entity_key = [keyword, attrs["package"], attrs[keyword]].compact.join(":")
16
+ return if parent.document.attributes['lutaml_entity_id'].nil?
17
+ xmi_id = parent.document.attributes['lutaml_entity_id'][entity_key]
18
+ return unless xmi_id
19
+
20
+ %Q(<xref target="section-#{xmi_id}"></xref>)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -87,7 +87,7 @@ module Metanorma
87
87
  {% else %}
88
88
  .{{ definition.name }} attributes
89
89
  |===
90
- |Name |Definition |Mandatory/ Optional/ Conditional |Max Occur |Data Type
90
+ |Name |Definition |Mandatory / Optional / Conditional |Max Occur |Data Type
91
91
 
92
92
  {% for item in definition.attributes %}
93
93
  |{{ item.name }} |{% if item.definition %}{{ item.definition }}{% endif %} |{% if item.cardinality.min == "0" %}O{% else %}M{% endif %} |{% if item.cardinality.max == "*" %}N{% else %}1{% endif %} |{% if item.origin %}<<{{ item.origin }}>>{% endif %} `{{ item.type }}`
@@ -24,10 +24,12 @@ module Metanorma
24
24
  RENDER_STYLES_INCLUDES = {
25
25
  'default' => 'packages',
26
26
  'entity_list' => 'packages_entity_list',
27
+ 'entity_list_class' => 'packages_entity_list_class',
27
28
  'data_dictionary' => 'packages_data_dictionary'
28
29
  }.freeze
30
+ RENDER_STYLE_ATTRIBUTE = 'render_style'.freeze
29
31
  SUPPORTED_NESTED_MACRO = %w[
30
- before diagram_include_block after include_block].freeze
32
+ before diagram_include_block after include_block package_text].freeze
31
33
  # search document for block `lutaml_uml_datamodel_description`
32
34
  # read include derectives that goes after that in block and transform
33
35
  # into yaml2text blocks
@@ -38,11 +40,19 @@ module Metanorma
38
40
 
39
41
  private
40
42
 
41
- def lutaml_document_from_file(document, file_path)
42
- ::Lutaml::Parser
43
- .parse(File.new(Utils.relative_file_path(document, file_path),
44
- encoding: "UTF-8"))
45
- .first
43
+ def lutaml_document_from_file_or_cache(document, file_path)
44
+ full_path = Utils.relative_file_path(document, file_path)
45
+ if document.attributes['lutaml_xmi_cache'] &&
46
+ document.attributes['lutaml_xmi_cache'][full_path]
47
+ return document.attributes['lutaml_xmi_cache'][full_path]
48
+ end
49
+ result_document = ::Lutaml::Parser.parse(File.new(full_path,
50
+ encoding: "UTF-8"))
51
+ .first
52
+ result_document
53
+ document.attributes['lutaml_xmi_cache'] ||= {}
54
+ document.attributes['lutaml_xmi_cache'][full_path] = result_document
55
+ result_document
46
56
  end
47
57
 
48
58
  def parse_yaml_config_file(document, file_path)
@@ -65,15 +75,44 @@ module Metanorma
65
75
  block_match = line.match(MARCO_REGEXP)
66
76
  return [line] if block_match.nil?
67
77
 
68
- lutaml_document = lutaml_document_from_file(document, block_match[1])
78
+ lutaml_document = lutaml_document_from_file_or_cache(document, block_match[1])
69
79
  fill_in_diagrams_attributes(document, lutaml_document)
70
80
  model_representation(
71
81
  lutaml_document,
72
82
  document,
73
- collect_additional_context(input_lines, input_lines.next),
83
+ collect_additional_context(document, input_lines, input_lines.next),
74
84
  parse_yaml_config_file(document, block_match[2]))
75
85
  end
76
86
 
87
+ def fill_in_entities_refs_attributes(document, lutaml_document_wrapper, options)
88
+ lutaml_document = lutaml_document_wrapper.original_document
89
+ render_style = options.fetch(RENDER_STYLE_ATTRIBUTE, 'default')
90
+ all_children_packages = lutaml_document.packages.map(&:children_packages).flatten
91
+ package_flat_packages = lambda do |pks|
92
+ pks.each_with_object({}) do |package, res|
93
+ res[package.name] = package.xmi_id
94
+ end
95
+ end
96
+ children_pks = package_flat_packages.call(all_children_packages)
97
+ ref_dictionary = package_flat_packages.call(lutaml_document.packages)
98
+ .merge(children_pks)
99
+ %w[class enum data_type].each do |type|
100
+ package_flat = lambda do |pks|
101
+ pks.each_with_object({}) do |package, res|
102
+ plural = type == "class" ? "classes" : "#{type}s"
103
+ package.send(plural).map do |entity|
104
+ res["#{type}:#{package.name}:#{entity.name}"] = entity.xmi_id
105
+ end
106
+ end
107
+ end
108
+ children_pks_daigs = package_flat.call(all_children_packages)
109
+ ref_dictionary = ref_dictionary
110
+ .merge(package_flat.call(lutaml_document.packages)
111
+ .merge(children_pks_daigs))
112
+ end
113
+ document.attributes['lutaml_entity_id'] = ref_dictionary
114
+ end
115
+
77
116
  def fill_in_diagrams_attributes(document, lutaml_document_wrapper)
78
117
  lutaml_document = lutaml_document_wrapper.original_document
79
118
  package_flat_diagrams = lambda do |pks|
@@ -86,13 +125,17 @@ module Metanorma
86
125
  .merge(children_pks_daigs)
87
126
  end
88
127
 
89
- def collect_additional_context(input_lines, end_mark)
128
+ def collect_additional_context(document, input_lines, end_mark)
90
129
  additional_context = Hash.new { |hash, key| hash[key] = [] }
130
+ additional_context['all_macros'] = []
91
131
  block_lines = []
92
132
  while (block_line = input_lines.next) != end_mark
93
133
  block_lines.push(block_line)
94
134
  end
95
- block_document = (Asciidoctor::Document.new(block_lines, {})).parse
135
+ processed_lines = self
136
+ .process(document, Asciidoctor::Reader.new(block_lines))
137
+ .read_lines
138
+ block_document = (Asciidoctor::Document.new(processed_lines, {})).parse
96
139
  block_document.blocks.each do |block|
97
140
  next unless SUPPORTED_NESTED_MACRO.include?(block.attributes['role'])
98
141
 
@@ -100,8 +143,9 @@ module Metanorma
100
143
  name = attrs.delete('role')
101
144
  package = attrs.delete('package')
102
145
  macro_keyword = [name, package].compact.join(";")
103
- block_text = block.lines.length > 0 ? block.lines[1..-2].join("\n") : ''
146
+ block_text = block.lines.length > 0 ? block.lines.join("\n") : ''
104
147
  additional_context[macro_keyword].push({ 'text' => block_text }.merge(attrs))
148
+ additional_context['all_macros'].push({ 'text' => block_text, 'type' => name, 'package' => package }.merge(attrs))
105
149
  end
106
150
  additional_context
107
151
  end
@@ -118,17 +162,39 @@ module Metanorma
118
162
  return {
119
163
  'render_nested_packages' => true,
120
164
  "packages" => root_package['packages'],
121
- "additional_context" => additional_context
165
+ "root_packages" => [root_package],
166
+ "additional_context" => additional_context.merge("external_classes" => options["external_classes"]),
167
+ "name" => root_package['name']
122
168
  }
123
169
  end
124
170
 
125
171
  all_packages = [root_package, *root_package['children_packages']]
126
172
  {
127
173
  "packages" => sort_and_filter_out_packages(all_packages, options),
128
- "additional_context" => additional_context
174
+ "package_entities" => package_entities(options),
175
+ "package_skip_sections" => package_skip_sections(options),
176
+ "additional_context" => additional_context.merge("external_classes" => options["external_classes"]),
177
+ "root_packages" => [root_package],
178
+ "name" => root_package['name']
129
179
  }
130
180
  end
131
181
 
182
+ def package_entities(options)
183
+ return {} unless options['packages']
184
+
185
+ options['packages']
186
+ .find_all { |entity| entity.is_a?(Hash) && entity.values.first['render_entities'] }
187
+ .map { |entity| [entity.keys.first, entity.values.first['render_entities'].map { |n| [n, true] }.to_h] }.to_h
188
+ end
189
+
190
+ def package_skip_sections(options)
191
+ return {} unless options['packages']
192
+
193
+ options['packages']
194
+ .find_all { |entity| entity.is_a?(Hash) && entity.values.first['skip_tables'] }
195
+ .map { |entity| [entity.keys.first, entity.values.first['skip_tables'].map { |n| [n, true] }.to_h] }.to_h
196
+ end
197
+
132
198
  def sort_and_filter_out_packages(all_packages, options)
133
199
  return all_packages if options['packages'].nil?
134
200
 
@@ -143,8 +209,9 @@ module Metanorma
143
209
  end
144
210
  # Step two - select supplied packages by pattern
145
211
  options['packages']
146
- .find_all { |entity| entity.is_a?(String) }
147
- .each do |entity|
212
+ .find_all { |entity| entity.is_a?(String) || (entity.is_a?(Hash) && !entity['skip']) }
213
+ .each do |entity_obj|
214
+ entity = entity_obj.is_a?(String) ? entity_obj : entity_obj.keys.first
148
215
  entity_regexp = config_entity_regexp(entity)
149
216
  all_packages.each.with_index do |package|
150
217
  if package['name'] =~ entity_regexp
@@ -163,8 +230,9 @@ module Metanorma
163
230
  end
164
231
 
165
232
  def model_representation(lutaml_document, document, additional_context, options)
233
+ fill_in_entities_refs_attributes(document, lutaml_document, options)
166
234
  render_result, errors = Utils.render_liquid_string(
167
- template_string: table_template(options['section_depth'] || 2, options['render_style']),
235
+ template_string: table_template(options['section_depth'] || 2, options['render_style'], options['include_root']),
168
236
  context_items: create_context_object(lutaml_document,
169
237
  additional_context,
170
238
  options),
@@ -176,10 +244,16 @@ module Metanorma
176
244
  render_result.split("\n")
177
245
  end
178
246
 
179
- def table_template(section_depth, render_style)
247
+ def table_template(section_depth, render_style, include_root)
180
248
  include_name = RENDER_STYLES_INCLUDES.fetch(render_style, DEFAULT_RENDER_INCLUDE)
181
- <<~LIQUID
182
- {% include "#{include_name}", depth: #{section_depth}, context: context, additional_context: context.additional_context, render_nested_packages: context.render_nested_packages %}
249
+ result = ""
250
+ if include_root
251
+ result += <<~LIQUID
252
+ {% 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 %}
253
+ LIQUID
254
+ end
255
+ result += <<~LIQUID
256
+ {% 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 %}
183
257
  LIQUID
184
258
  end
185
259
  end
@@ -7,7 +7,7 @@ require "metanorma/plugin/lutaml/liquid/multiply_local_file_system"
7
7
  module Metanorma
8
8
  module Plugin
9
9
  module Lutaml
10
- # Helpers for lutaml macroses
10
+ # Helpers for lutaml macros
11
11
  module Utils
12
12
  LUTAML_EXP_IDX_TAG = /^:lutaml-express-index:(?<index_name>.+?);(?<index_path>.+?);?(\s*cache=(?<cache_path>.+))?$/.freeze
13
13
 
@@ -1,7 +1,7 @@
1
1
  module Metanorma
2
2
  module Plugin
3
3
  module Lutaml
4
- VERSION = "0.4.7".freeze
4
+ VERSION = "0.4.11".freeze
5
5
  end
6
6
  end
7
7
  end
@@ -5,6 +5,7 @@ require "metanorma/plugin/lutaml/lutaml_uml_datamodel_description_preprocessor"
5
5
  require "metanorma/plugin/lutaml/lutaml_diagram_block"
6
6
  require "metanorma/plugin/lutaml/lutaml_diagram_block_macro"
7
7
  require "metanorma/plugin/lutaml/lutaml_figure_inline_macro"
8
+ require "metanorma/plugin/lutaml/lutaml_table_inline_macro"
8
9
 
9
10
  module Metanorma
10
11
  module Plugin
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.4.7
4
+ version: 0.4.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-08-20 00:00:00.000000000 Z
11
+ date: 2021-09-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: liquid
@@ -262,15 +262,20 @@ files:
262
262
  - lib/metanorma/plugin/lutaml/liquid_templates/_packages.liquid
263
263
  - lib/metanorma/plugin/lutaml/liquid_templates/_packages_class.liquid
264
264
  - lib/metanorma/plugin/lutaml/liquid_templates/_packages_data_dictionary.liquid
265
+ - lib/metanorma/plugin/lutaml/liquid_templates/_packages_data_dictionary_class.liquid
265
266
  - lib/metanorma/plugin/lutaml/liquid_templates/_packages_data_dictionary_classes.liquid
266
267
  - lib/metanorma/plugin/lutaml/liquid_templates/_packages_data_type.liquid
267
268
  - lib/metanorma/plugin/lutaml/liquid_templates/_packages_entity_list.liquid
269
+ - lib/metanorma/plugin/lutaml/liquid_templates/_packages_entity_list_class.liquid
270
+ - lib/metanorma/plugin/lutaml/liquid_templates/_packages_entity_list_classes.liquid
268
271
  - lib/metanorma/plugin/lutaml/liquid_templates/_packages_enum.liquid
272
+ - lib/metanorma/plugin/lutaml/liquid_templates/test.rb
269
273
  - lib/metanorma/plugin/lutaml/lutaml_diagram_base.rb
270
274
  - lib/metanorma/plugin/lutaml/lutaml_diagram_block.rb
271
275
  - lib/metanorma/plugin/lutaml/lutaml_diagram_block_macro.rb
272
276
  - lib/metanorma/plugin/lutaml/lutaml_figure_inline_macro.rb
273
277
  - lib/metanorma/plugin/lutaml/lutaml_preprocessor.rb
278
+ - lib/metanorma/plugin/lutaml/lutaml_table_inline_macro.rb
274
279
  - lib/metanorma/plugin/lutaml/lutaml_uml_attributes_table_preprocessor.rb
275
280
  - lib/metanorma/plugin/lutaml/lutaml_uml_datamodel_description_preprocessor.rb
276
281
  - lib/metanorma/plugin/lutaml/utils.rb