metanorma-plugin-lutaml 0.4.5 → 0.4.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: 0a510a5a23684dee91557fb6047267ca6ac87be25cbe11e0bcad8e4c0d0812b9
4
- data.tar.gz: 5d6e5cfc99c66b42ed50b7f6c6b1346fd2887ee9bba4436cacd5fbc56121dde6
3
+ metadata.gz: 7be44107e7c1d3c9a4471ead7d39630d49cdced1e3996b6bea8b3c64be4fd03f
4
+ data.tar.gz: b99ff8fa3069c0fb0f983de14a984c06db12ecc595e0b876ed83e83926c6eeba
5
5
  SHA512:
6
- metadata.gz: ea2e863ee349fb9bc5e60c43802569b0592b3437f2aad58f5bdb5591ecd430388566aff7ad8ff6d6c187e64868df9f1f303917afa94e73396e5c6d6564d0571a
7
- data.tar.gz: dc8d9a72fbea070f7aec02fa576c59859ce34abf6375e307ef18685cdbd70130edcc3958839e7b82e9e7155befc8b51657c685d5f42cef96e900de0fd4a50532
6
+ metadata.gz: 2e6d79ef550cecde85e2e0d49717259f6e9016ef7e3935fdb938d13173361daf404e586a1d1319b05a1ab4a393213086625399d5d3e1090a4afd902c0bfc3f82
7
+ data.tar.gz: 454fe356b82f983a2a4ed9b2a1fa81de19ea8dcb6ac0c10243f1afc8db8e2eed8b8600658c7f0e37040224401dae077a0f93e433227b31c9dd63c7119c59db5f
data/README.adoc CHANGED
@@ -1,21 +1,36 @@
1
- = metanorma-plugin-lutaml
1
+ = Metanorma LutaML plugin (metanorma-plugin-lutaml)
2
2
 
3
3
  image:https://github.com/metanorma/metanorma-plugin-lutaml/workflows/rake/badge.svg["Build Status", link="https://github.com/metanorma/metanorma-plugin-lutaml/actions?workflow=rake"]
4
4
 
5
- == Functionality
5
+ == Purpose
6
6
 
7
- Metanorma plugin that allows you to access lutaml objects from a Metanorma document
7
+ LutaML is a data model accessor that supports various data model formats,
8
+ including:
8
9
 
9
- === Installation
10
+ * EXPRESS (`*.exp` files)
11
+ * OMG UML in XMI format (`*.xmi` files)
12
+
13
+ This plugin allows you to access LutaML models from within a Metanorma document.
14
+
15
+ == Installation
10
16
 
11
17
  [source,console]
12
18
  ----
13
19
  $ gem install metanorma-plugin-lutaml
14
20
  ----
15
21
 
16
- === Usage, `lutaml` macro
17
22
 
18
- Given `example.exp` file with the content:
23
+ == Usage with EXPRESS
24
+
25
+ === General
26
+
27
+ LutaML supports accessing EXPRESS models via the
28
+ https://github.com/lutaml/expressir[Expressir] parser.
29
+
30
+
31
+ === Usage of the `lutaml_express` EXPRESS macro
32
+
33
+ Given an `example.exp` EXPRESS file with the content:
19
34
 
20
35
  [source,exp]
21
36
  ----
@@ -42,11 +57,11 @@ SCHEMA test_schema 'test';
42
57
  END_SCHEMA;
43
58
  ----
44
59
 
45
- And the `lutaml` macro block:
60
+ And the `lutaml_express` macro block:
46
61
 
47
62
  [source,adoc]
48
63
  -----
49
- [lutaml,example.exp,my_context]
64
+ [lutaml_express,example.exp,my_context]
50
65
  ----
51
66
 
52
67
  {% for schema in my_context.schemas %}
@@ -67,13 +82,15 @@ Where:
67
82
  * `{example.exp}` is the location of the EXPRESS schema file (`*.exp`) that
68
83
  contains data to be loaded. Location of the file is computed relative to the
69
84
  source directory that `[lutaml]` is used (e.g., if
70
- `[lutaml,example.exp,my_context]` is invoked in an `.adoc` file located at
85
+ `[lutaml_express,example.exp,my_context]` is invoked in an `.adoc` file located at
71
86
  `/foo/bar/doc.adoc`, the data file is expected to be found at
72
87
  `/foo/bar/example.exp`);
73
88
 
74
- * `{my_context}` is the name where the EXPRESS Repository read from the .exp
75
- file can be accessed with. Context object is a serialized
76
- `Expressir::Model::Repository` object with all variable names available. See
89
+ * `{my_context}` is the name where the EXPRESS Repository read from the `.exp`
90
+ file can be accessed with.
91
+
92
+ ** The `context` object is a serialized `Expressir::Model::Repository` object
93
+ with all variable names available. See
77
94
  https://github.com/lutaml/expressir[Expressir] docs for reference.
78
95
  `{my_context}` has `schemas` method to access Expressir
79
96
  https://github.com/lutaml/expressir/blob/master/lib/expressir/model/schema.rb[schemas]
@@ -121,7 +138,7 @@ Example of usage:
121
138
  = Document title
122
139
  Author
123
140
  :lutaml-express-index: my_custom_name; /path/to/express_files; cache=/path/to/cache_file.yaml
124
- [lutaml,my_custom_name,my_context]
141
+ [lutaml_express,my_custom_name,my_context]
125
142
  ----
126
143
  {% for schema in my_context.schemas %}
127
144
  == {{schema.id}}
@@ -142,7 +159,7 @@ diagram MyView {
142
159
  enum AddressClassProfile {
143
160
  imlicistAttributeProfile: CharacterString [0..1] {
144
161
  definition
145
- this is multiline with `ascidoc`
162
+ this is multiline with `asciidoc`
146
163
  end definition
147
164
  }
148
165
  }
@@ -193,7 +210,7 @@ diagram MyView {
193
210
  ----
194
211
 
195
212
 
196
- === Usage, `lutaml_uml_attributes_table` macro
213
+ === Usage of `lutaml_uml_attributes_table` macro
197
214
 
198
215
  This macro allows to quickly render data model attributes/values tables.
199
216
 
@@ -246,7 +263,7 @@ Will produce this output:
246
263
  |===
247
264
  -----
248
265
 
249
- In case of "enumeration"(AddressClassProfile) entity:
266
+ In case of "enumeration" (AddressClassProfile) entity:
250
267
 
251
268
  [source,adoc]
252
269
  -----
@@ -264,12 +281,12 @@ Will produce this output:
264
281
  |===
265
282
  |Name |Definition
266
283
 
267
- |imlicistAttributeProfile |this is multiline with `ascidoc`
284
+ |imlicistAttributeProfile |this is multiline with `asciidoc`
268
285
 
269
286
  |===
270
287
  -----
271
288
 
272
- === Usage, `lutaml_uml_datamodel_description` macro
289
+ === Usage of `lutaml_uml_datamodel_description` macro
273
290
 
274
291
  This macro allows to quickly render data model packages and its dependent
275
292
  objects for supplied XMI file.
@@ -286,44 +303,44 @@ The `lutaml_uml_datamodel_description` macro can be used:
286
303
  [lutaml_uml_datamodel_description, path/to/example.xmi]
287
304
  --
288
305
  [.before]
289
- ...
306
+ ....
290
307
  my text
291
- ...
308
+ ....
292
309
 
293
- [.diagram_include_block, base_path="requirements/"]
294
- ...
310
+ [.diagram_include_block, base_path="requirements/", format="emf"]
311
+ ....
295
312
  Diagram text
296
- ...
313
+ ....
297
314
 
298
315
  [.include_block, package="Another", base_path="spec/fixtures"]
299
- ...
316
+ ....
300
317
  my text
301
- ...
318
+ ....
302
319
 
303
320
  [.include_block, base_path="spec/fixtures"]
304
- ...
321
+ ....
305
322
  my text
306
- ...
323
+ ....
307
324
 
308
325
  [.before, package="Another"]
309
- ...
326
+ ....
310
327
  text before Another package
311
- ...
328
+ ....
312
329
 
313
330
  [.after, package="Another"]
314
- ...
331
+ ....
315
332
  text after Another package
316
- ...
333
+ ....
317
334
 
318
335
  [.after, package="CityGML"]
319
- ...
336
+ ....
320
337
  text after CityGML package
321
- ...
338
+ ....
322
339
 
323
340
  [.after]
324
- ...
341
+ ....
325
342
  footer text
326
- ...
343
+ ....
327
344
  --
328
345
  --
329
346
  -----
@@ -332,33 +349,46 @@ Where:
332
349
 
333
350
  * `path/to/example.xmi` - required, path to the XMI file to render
334
351
 
335
- * `[.before]` - macro to add additional text before the rendered output, can be used only once, additional occurrences of macro will overwrite text
352
+ * `[.before]` - macro to add additional text before the rendered output, can be used only once, additional occurrences of macro will overwrite text, not that `literal` block style must be used in there(eg `....`)
336
353
 
337
354
  * `[.after]` - macro to add additional text after the rendered output, can be used only once, additional occurrences of macro will overwrite text
338
355
 
339
356
  * `[.after, package="Another"]` - macro with text to be inserted before(after in case of `.before` name) the package
340
357
 
341
- * `[.diagram_include_block]` - macro to automatically include diagram images. Attribute `base_path` is a required attribute to supply path prefix where to look for a digram image. The logic is as follows:
358
+ * `[.diagram_include_block]` - macro to automatically include diagram images. Attribute `base_path` is a required attribute to supply path prefix where to look for a diagram image. `format` is an optional attribute that tells what file extension to use when including diagram file. The logic is as follows:
342
359
  [source,adoc]
343
360
  -----
344
361
  {% for diagram in package.diagrams %}
345
362
  [[figure-{{ diagram.xmi_id }}]]
346
363
  .{{ diagram.name }}
347
- image::{{ image_base_path }}/{{ diagram.xmi_id }}.png[]
364
+ image::{{ image_base_path }}/{{ diagram.xmi_id }}.{{ format | default: 'png' }}[]
348
365
 
349
366
  {% if diagram.definition %}
350
367
  {{ diagram.definition | html2adoc }}
351
368
  {% endif %}
352
369
  {% endfor %}
353
370
  -----
354
- Eg: script will take package diagrams supplied in xmi file and will try to include `image` with the name equal to diagram' xmi_id attribute plus `.png`. Also one can add any text to the macro text, it will be added as paragraph before each image include.
371
+
372
+ For instance, the script will take package diagrams supplied in the XMI file and will try to include `image` with the name equal to diagram' xmi_id attribute plus `.png`. Also one can add any text to the macro text, it will be added as paragraph before each image include.
355
373
 
356
374
  * `[.diagram_include_block, package="Another"]` - same as above, but diagram will be included only for supplied package name
357
375
 
358
- * `[.include_block, base_path="spec/fixtures"]` - macro to inlude files(adoc/liquid) for each package name. Attribute `base_path` is a required attribute to supply path prefix where to look for file to include. Macro will look for a file called `base_path` + `/` `_package_name`(downcase, replace : -> '', ' ' -> '_') + `.adoc`[`.liquid`], eg for package 'My Package name' and `base_path` eq to `my/path`, macro will look for the following file path: `my/path/_my_package_name.adoc`.
376
+ * `[.include_block, base_path="spec/fixtures"]` - macro to include files (`*.adoc` or `*.liquid`) for each package name. Attribute `base_path` is a required attribute to supply path prefix where to look for file to include. Macro will look for a file called `base_path` + `/` `_package_name`(downcase, replace : -> '', ' ' -> '_') + `.adoc`[`.liquid`], eg for package 'My Package name' and `base_path` eq to `my/path`, macro will look for the following file path: `my/path/_my_package_name.adoc`.
359
377
 
360
378
  * `[.include_block, package="Another", base_path="spec/fixtures"]` - same as above, but include block will be included only for supplied package name
361
379
 
380
+ In addition to the macros listed above that can be used only inside `lutaml_uml_datamodel_description` macro there is another macroses called `lutaml_figure` and `lutaml_table`. `lutaml_figure` is used to lookup and reference xmi package diagrams. `lutaml_table` is used to lookup rendered xmi entries. The syntax is as follows:
381
+
382
+ [source,adoc]
383
+ -----
384
+ This is lutaml_figure::[package="Wrapper root package", name="Fig B1 Full model"] figure
385
+ This is lutaml_table::[package="Wrapper root package"] package
386
+ This is lutaml_table::[package="Wrapper root package", class="my name"] class
387
+ This is lutaml_table::[package="Wrapper root package", enum="my name"] enum
388
+ This is lutaml_table::[package="Wrapper root package", data_type="my name"] data_type
389
+ -----
390
+
391
+ This code will be transformed into `<<figure-{diagram.xmi_id}>>` and will point to diagram figure. One can only use this macro when document rendered `lutaml_uml_datamodel_description` macro as it needs diagram lookup table in order to reference package diagram.
362
392
 
363
393
  Will produce this output:
364
394
 
@@ -372,18 +402,17 @@ Diagram text
372
402
 
373
403
  [[figure-EAID_ACBB5EE3_3428_40f5_9C7C_E41923419F29]]
374
404
  .CityGML Package Diagram
375
- image::requirements//EAID_ACBB5EE3_3428_40f5_9C7C_E41923419F29.png[]
405
+ image::requirements/EAID_ACBB5EE3_3428_40f5_9C7C_E41923419F29.png[]
376
406
 
377
407
  BuildingFurnitureFunctionValue is a code list that enumerates the different purposes of a BuildingFurniture.
378
408
 
379
409
  [[figure-EAID_938AE961_1C57_4052_B964_997D1894A58D]]
380
410
  .Use of ISO and OASIS standards in CityGML
381
- image::requirements//EAID_938AE961_1C57_4052_B964_997D1894A58D.png[]
411
+ image::requirements/EAID_938AE961_1C57_4052_B964_997D1894A58D.png[]
382
412
 
383
413
  The CityGML package is organized into
384
414
  2 packages with 1 modules:
385
415
 
386
- [arabic]
387
416
  . Another package
388
417
  . CityTML package
389
418
 
@@ -393,18 +422,17 @@ Content for CityGML package
393
422
 
394
423
  ==== Defining tables
395
424
 
396
- [arabic]
397
- .<<tab-P-another-C-abstractatomictimeseries>> -- Elements of Another::AbstractAtomicTimeseries
425
+ .<<section-EAPK_9C96A88B_E98B_490b_8A9C_24AEDAC64293>> -- Elements of &#8220;Another::AbstractAtomicTimeseries&#8221; (class)
398
426
 
399
- [[tab-P-another-C-abstractatomictimeseries]]
400
- .Elements of Another::AbstractAtomicTimeseries
427
+ [[section-EAPK_9C96A88B_E98B_490b_8A9C_24AEDAC64293]]
428
+ .Elements of &#8220;Another::AbstractAtomicTimeseries&#8221; (class)
401
429
  [width="100%",cols="a,a,a,a,a,a,a,a"]
402
430
  |===
403
431
  h|Name: 7+| AbstractAtomicTimeseries
404
432
  h|Definition: 7+|
405
433
  h|Stereotype: 7+| interface
406
434
  h|Abstract: 7+|
407
- .1+h|Associations: 7+| (none)
435
+ h|Associations: 7+| (none)
408
436
  .4+h|Public attributes:
409
437
  | _Name_
410
438
  2+| _Definition_
@@ -438,7 +466,7 @@ h|Constraints: 7+| (none)
438
466
  text after CityGML package
439
467
  -----
440
468
 
441
- In addition to just supplying XMI file, this macro also supports YAML
469
+ In addition to just supplying an XMI file, this macro also supports a YAML
442
470
  configuration file.
443
471
 
444
472
  The format for using YAML is this:
@@ -453,26 +481,33 @@ packages:
453
481
  - three
454
482
  # skips these packages
455
483
  - skip: four
484
+ render_style: entity_list|data_dictionary|default
485
+ section_depth: 2
456
486
  -----
457
487
 
458
488
  Where:
459
489
 
460
490
  * `packages` - required, root element with the list of strings or objects
461
-
462
491
  * `Package *` - pattern matching, specifies lookup condition for packages to
463
492
  render.
464
493
  +
465
494
  NOTE: In this example, it is equal to the following regular expression: `/^Package.*$/`
466
495
 
467
496
  * `skip: four` - object with package name to skip
497
+ * `render_style` - what template to use to render packages, can be: entity_list, data_dictionary or default
498
+ * `section_depth` - what package to use as root package for render, eg `section_depth` equal to 2 tells processor to use first nested package of the first root packages in xmi file. Example: if xmi file has this package structure: [{ name: 'One', packages: [{ name: 'one-1' }, { name: 'one-2' }] }, { name: 'Two', packages: [{ name: 'two-1' }, { name: 'two-2' }] }] and we have `section_depth` equal to 2, root package will be `one-1`
468
499
 
469
500
  Usage with macro:
470
501
 
471
502
  [source,adoc]
472
- -----
503
+ --
473
504
  [lutaml_uml_datamodel_description, path/to/example.xmi, path/to/config.yml]
474
- ....
475
- -----
505
+ ----
506
+ [.diagram_include_block, base_path="models/Images", format="png"]
507
+ ...
508
+ ...
509
+ ----
510
+ --
476
511
 
477
512
  The macro processor will read supplied YAML file and arrange packages according
478
513
  to the order supplied in the config file, also all packages supplied as `skip`
@@ -3,7 +3,7 @@
3
3
  {% for diagram in package.diagrams %}
4
4
  [[figure-{{ diagram.xmi_id }}]]
5
5
  .{{ diagram.name }}
6
- image::{{ image_base_path }}/{{ diagram.xmi_id }}.png[]
6
+ image::{{ image_base_path }}/{{ diagram.xmi_id }}.{{ format | default: 'png' }}[]
7
7
 
8
8
  {% if diagram.definition %}
9
9
  {{ diagram.definition | html2adoc }}
@@ -1,11 +1,9 @@
1
1
  {% for package in context.packages %}
2
2
  {% assign package_name = package.name | downcase | replace: ":", "" | replace: " ", "_" %}
3
- {% if additional_context.before %}
4
- {{ additional_context.before.text }}
5
- {% endif %}
6
- {% assign before_package_key = 'before;' | append: package.name %}
7
- {% if additional_context[before_package_key] %}
8
- {{ additional_context[before_package_key].text }}
3
+ {% if additional_context.before and additional_context.before.size > 0 %}
4
+ {% for before in additional_context.before %}
5
+ {{ before.text }}
6
+ {% endfor %}
9
7
  {% endif %}
10
8
  {% assign is_package_spare = package.name | slice: 0,5 %}
11
9
  {% if is_package_spare == 'old: ' %}{% continue %}
@@ -13,16 +11,25 @@
13
11
  {% endif %}
14
12
 
15
13
  {% capture equalsigns %}{% for count in (1..depth) %}={% endfor %}{% endcapture %}{{equalsigns}} {{ package.name }} package
14
+ [[section-{{ package.xmi_id }}]]
16
15
  {{equalsigns}}= {{ package.name }} overview
17
16
 
17
+ {% assign before_package_key = 'before;' | append: package.name %}
18
+ {% if additional_context[before_package_key] and additional_context[before_package_key].size > 0 %}
19
+ {% for before in additional_context[before_package_key] %}
20
+ {{ before.text }}
21
+ {% endfor %}
22
+ {% endif %}
18
23
  {% if additional_context.diagram_include_block %}
19
- {% include "diagrams_block", package_name: package_name, image_base_path: additional_context.diagram_include_block.base_path, text: additional_context.diagram_include_block.text %}
24
+ {% for diagram_include_block in additional_context.diagram_include_block %}
25
+ {% include "diagrams_block", package_name: package_name, image_base_path: diagram_include_block.base_path, text: diagram_include_block.text, format: diagram_include_block.format %}
26
+ {% endfor %}
20
27
  {% endif %}
21
28
 
22
29
  {% if package.packages.size > 0 %}The {{ package.name }} package is organized into
23
30
  {{ package.packages.size }} packages{% assign modules_nested_size = 0 %}{% for module in package.packages %}{% assign modules_nested_size = modules_nested_size | plus: module.packages.size %}{% endfor %}{% if modules_nested_size > 0 %} with {{modules_nested_size}} modules{% endif %}:
24
31
  {% endif %}
25
- [arabic]
32
+
26
33
  {% for module in package.packages %}
27
34
  {% if module.packages.length > 0 %}
28
35
  . {{ module.name }} package comprises:
@@ -38,14 +45,13 @@
38
45
 
39
46
  {{equalsigns}}= Defining tables
40
47
 
41
- [arabic]
42
48
  {% for klass in package.classes %}
43
49
  {% assign is_klass_spare = klass.name | slice: 0,5 %}
44
50
  {% if is_klass_spare == 'old: ' %}{% continue %}
45
51
  {% elsif is_klass_spare == 'Spare' %}{% continue %}
46
52
  {% endif %}
47
53
  {% assign klass_name = klass.name | downcase | replace: ':', '' | replace: ' ', '_' %}
48
- .<<tab-P-{{ package_name }}-C-{{ klass_name }}>> -- Elements of {{ package.name }}::{{ klass.name }}
54
+ .<<section-{{ klass.xmi_id }}>> -- &#8220;Elements of {{ package.name }}::{{ klass.name }}&#8221; (class)
49
55
 
50
56
  {% endfor %}
51
57
  {% for enum in package.enums %}
@@ -54,7 +60,7 @@
54
60
  {% elsif is_enum_spare == 'Spare' %}{% continue %}
55
61
  {% endif %}
56
62
  {% assign enum_name = enum.name | downcase | replace: ':', '' | replace: ' ', '_' %}
57
- .<<tab-P-{{ package_name }}-E-{{ enum_name }}>> -- Elements of {{ package.name }}::{{ enum.name }}
63
+ .<<section-{{ enum.xmi_id }}>> -- &#8220;Elements of {{ package.name }}::{{ enum.name }}&#8221; (enum)
58
64
 
59
65
  {% endfor %}
60
66
  {% for data_type in package.data_types %}
@@ -63,7 +69,7 @@
63
69
  {% elsif is_data_type_spare == 'Spare' %}{% continue %}
64
70
  {% endif %}
65
71
  {% assign data_type_name = data_type.name | downcase | replace: ':', '' | replace: ' ', '_' %}
66
- .<<tab-P-{{ package_name }}-DT-{{ data_type_name }}>> -- Elements of {{ package.name }}::{{ data_type.name }}
72
+ .<<section-{{ data_type.xmi_id }}>> -- &#8220;Elements of {{ package.name }}::{{ data_type.name }}&#8221; (data_type)
67
73
 
68
74
  {% endfor %}
69
75
 
@@ -81,9 +87,9 @@
81
87
 
82
88
  {% endif %}
83
89
 
84
- {% if additional_context.include_block %}
85
- {% assign block = additional_context.include_block %}
86
- {% capture block_filename %}{{ block.base_path }}/{{ package_name }}{% endcapture %}
90
+ {% if additional_context.include_block and additional_context.include_block.size > 0 %}
91
+ {% for block in additional_context.include_block %}
92
+ {% capture block_filename %}{{ block.base_path }}{{ package_name }}{% endcapture %}
87
93
  {% capture block_content %}{% include block_filename %}{% endcapture %}
88
94
  {% unless block_content contains "Liquid error" %}
89
95
  {% if block.text %}
@@ -91,12 +97,13 @@
91
97
  {% endif %}
92
98
  {{ block_content }}
93
99
  {% endunless %}
100
+ {% endfor %}
94
101
  {% endif %}
95
102
 
96
103
  {% assign include_block_package_key = 'include_block;' | append: package.name %}
97
- {% assign block = additional_context[include_block_package_key] %}
98
- {% if block %}
99
- {% capture block_filename %}{{ block.base_path }}/{{ package_name }}{% endcapture %}
104
+ {% if additional_context[include_block_package_key] and additional_context[include_block_package_key].size > 0 %}
105
+ {% for block in additional_context[include_block_package_key] %}
106
+ {% capture block_filename %}{{ block.base_path }}{{ package_name }}{% endcapture %}
100
107
  {% capture block_content %}{% include block_filename %}{% endcapture %}
101
108
  {% unless block_content contains "Liquid error" %}
102
109
  {% if block.text %}
@@ -104,16 +111,23 @@
104
111
  {% endif %}
105
112
  {{ block_content }}
106
113
  {% endunless %}
114
+ {% endfor %}
107
115
  {% endif %}
108
116
 
109
117
  {% assign after_package_key = 'after;' | append: package.name %}
110
- {{equalsigns}}= Additional Information
111
118
  {% if additional_context[after_package_key] %}
112
- {{ additional_context[after_package_key].text }}
119
+ {{equalsigns}}= Additional information
120
+ {% for after in additional_context[after_package_key] %}
121
+ {{ after.text }}
122
+ {% endfor %}
123
+ {% endif %}
124
+ {% if package.packages.size > 0 and render_nested_packages %}
125
+ {% assign nested_depth = depth | plus: 1 %}{% include "packages", depth: nested_depth, context: package %}
113
126
  {% endif %}
114
- {% if package.packages.size > 0 and render_nested_packages %}{% assign nested_depth = depth | plus: 1 %}{% include "packages", depth: nested_depth, context: package %}{% endif %}
115
127
  {% endfor %}
116
128
 
117
- {% if additional_context.after %}
118
- {{ additional_context.after.text }}
129
+ {% if additional_context.after and additional_context.after.size > 0 %}
130
+ {% for after in additional_context.after %}
131
+ {{ after.text }}
132
+ {% endfor %}
119
133
  {% endif %}