metanorma-plugin-datastruct 0.1.1 → 0.1.2

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: f1634612a50be53cbe05f8bfe92c2ba7c6f2b918b99ea37cd9eea3eea40f5242
4
- data.tar.gz: 4d7e13e53ec88af6d0ddf31b30dd4acd7c19a5f6fcc0eafd4504ef75ca7545aa
3
+ metadata.gz: 05ff3965fb8f246cb1c376a7f21d1ba4e1306edab31626becbb8ac7d607e6508
4
+ data.tar.gz: bbc073882463a1f6719ee9d8f52d8814fe7ff9169b39d6b48cbb3ebc91a0f3a3
5
5
  SHA512:
6
- metadata.gz: 1ad617b37efc74c72ff0e039f4efa93aee62758e23caf95cdb004f617461b8760d87b1efdedf8968a4f07f0719c6543a4b4b58cea5e6942fc7a518eb6450b52d
7
- data.tar.gz: 0e0fe73fbf339fdc9e97313f248a5d815cc2249f5713ef296dcc73d55d36778cd229d6be004c71adb378f46f4be1c381506f8a320b56a67f59f29cd70b7e0130
6
+ metadata.gz: 1539c1c2dfbd683702e0bc3962a7c5992b635bd09347a50c7cff6ccc49906149df920f45be4588dd765bb497dc7a5c3d6b625788ae137288e587f1ed516faa98
7
+ data.tar.gz: 8c4c7a9ccaf8608d11b88015cb7cd068d09a6df6d0caaf571f1d139627dda3a18863e728d40bcdc00eced82c0684dc8b204cc6e27f7d68f860b375d1813dc196
@@ -0,0 +1,42 @@
1
+ # Auto-generated by Cimas: Do not edit it manually!
2
+ # See https://github.com/metanorma/cimas
3
+ name: rake
4
+
5
+ on:
6
+ push:
7
+ branches: [ master, main ]
8
+ tags: [ v* ]
9
+ pull_request:
10
+
11
+ jobs:
12
+ rake:
13
+ name: Test on Ruby ${{ matrix.ruby }} ${{ matrix.os }}
14
+ runs-on: ${{ matrix.os }}
15
+ continue-on-error: ${{ matrix.experimental }}
16
+ strategy:
17
+ fail-fast: false
18
+ matrix:
19
+ ruby: [ '2.7', '2.6', '2.5', '2.4' ]
20
+ os: [ ubuntu-latest, windows-latest, macos-latest ]
21
+ experimental: [ false ]
22
+ include:
23
+ - ruby: '3.0'
24
+ os: 'ubuntu-latest'
25
+ experimental: true
26
+ - ruby: '3.0'
27
+ os: 'windows-latest'
28
+ experimental: true
29
+ - ruby: '3.0'
30
+ os: 'macos-latest'
31
+ experimental: true
32
+ steps:
33
+ - uses: actions/checkout@v2
34
+ with:
35
+ submodules: true
36
+
37
+ - uses: ruby/setup-ruby@v1
38
+ with:
39
+ ruby-version: ${{ matrix.ruby }}
40
+ bundler-cache: true
41
+
42
+ - run: bundle exec rake
data/README.adoc CHANGED
@@ -4,13 +4,577 @@
4
4
 
5
5
  Metanorma plugin that allows you to access static data structures like JSON, YAML, XML from a Metanorma document
6
6
 
7
- === Installation
7
+ == Installation
8
8
 
9
9
  [source,console]
10
10
  ----
11
11
  $ gem install metanorma-plugin-datastruct
12
12
  ----
13
13
 
14
- == Documentation
14
+ == Usage
15
15
 
16
- See http://metanorma.com[]
16
+ In order to use the macros in Metanorma, add the gem gem 'metanorma-plugin-datastruct' in your Gemfile. Or have the gem installed, and Metanorma can use them automatically via the extension :plugin: datastruct.
17
+
18
+ === Expressions
19
+
20
+ Currently, there are 2 plugins available: `yaml2text` and `json2text`. As states from the name, `yaml2text` allows to load yaml file and use it in expressions, `json2text` works with json files.
21
+ Macroses supports all https://shopify.github.io/liquid/basics/introduction/[Liquid syntax expressions], including:
22
+
23
+ * variables, variable assignment
24
+ * flow control (if/case)
25
+ * filters
26
+ * loops
27
+
28
+ See https://shopify.github.io/liquid/basics/introduction/[here] for the full description of Liquid tags and expressions.
29
+
30
+
31
+ [[defining_syntax]]
32
+ === Defining the block
33
+
34
+ A `yaml2text`(`json2text`) block is created with the following syntax.
35
+
36
+ Block opening and closing is demarcated by an open block syntax (`--`)
37
+ or the `[source]` block syntax (`----` or more `-`).
38
+
39
+ [source,adoc]
40
+ --
41
+ [yaml2text,{YAML(JSON) file path},{self-defined context name}]
42
+ ----
43
+ this is content within the block!
44
+ ----
45
+ --
46
+
47
+ Where:
48
+
49
+ * content within the block is called the "`template`";
50
+
51
+ * `{YAML(JSON) file path}` is the location of the YAML(JSON) file that contains data to be loaded. Location of the file is computed relative to the source directory that `[yaml2text]`(`[json2text]`) is used (e.g., if `[yaml2text,data.yaml,data]` is invoked in an `.adoc` file located at `/foo/bar/doc.adoc`, the data file is expected to be found at `/foo/bar/data.yaml`);
52
+
53
+ * `{self-defined context name}` is the name where the data read from the data file can be accessed with.
54
+
55
+ === Interpolation
56
+
57
+ `yaml2text`(`json2text`) accepts string interpolation of the following forms:
58
+
59
+ . `{variable}`: as in AsciiDoc syntax;
60
+ . `{{ variable }}`, `{% if/else/for/case %}`: basic Liquid tags and expressions are supported.
61
+
62
+ The value within the curly braces will be interpolated by `yaml2text`(`json2text`).
63
+
64
+ Where:
65
+
66
+ * In `{variable}`(`{{variable}}`), `variable` is the name of the variable or AsciiDoc attribute.
67
+ * The location of `{variable}`(`{{variable}}`) in text will be replaced with the value of `variable`.
68
+ * Evaluation order will be first from the defined context, then of the Metanorma AsciiDoc document.
69
+
70
+
71
+ === Accessing object values
72
+
73
+ Object values are accessed via the `.` (dot) separator.
74
+
75
+ EXAMPLE:
76
+ --
77
+ Given:
78
+
79
+ strings.yaml
80
+ [source,yaml]
81
+ ----
82
+ ---
83
+ foo: bar
84
+ dead: beef
85
+ ----
86
+
87
+ And the block:
88
+ [source,asciidoc]
89
+ ------
90
+ [yaml2text,strings.yaml,data]
91
+ ----
92
+ I'm heading to the {{data.foo}} for {{data.dead}}.
93
+ ----
94
+ ------
95
+
96
+ The file path is `strings.yaml`, and context name is `data`.
97
+ `{{data.foo}}` evaluates to the value of the key `foo` in `data`.
98
+
99
+ Will render as:
100
+ [source,asciidoc]
101
+ ----
102
+ I'm heading to the bar for beef.
103
+ ----
104
+
105
+ --
106
+
107
+
108
+ === Accessing arrays
109
+
110
+ ==== Length
111
+
112
+ The length of an array can be obtained by `{{arrayname.size}}`.
113
+
114
+ EXAMPLE:
115
+ --
116
+ Given:
117
+
118
+ strings.yaml
119
+ [source,yaml]
120
+ ----
121
+ ---
122
+ - lorem
123
+ - ipsum
124
+ - dolor
125
+ ----
126
+
127
+ And the block:
128
+ [source,asciidoc]
129
+ ------
130
+ [yaml2text,strings.yaml,data]
131
+ ----
132
+ The length of the YAML array is {{data.size}}.
133
+ ----
134
+ ------
135
+
136
+ The file path is `strings.yaml`, and context name is `data`.
137
+ `{{data.size}}` evaluates to the length of the array using liquid `size` https://shopify.github.io/liquid/filters/size/[filter].
138
+
139
+ Will render as:
140
+ [source,asciidoc]
141
+ ----
142
+ The length of the YAML array is 3.
143
+ ----
144
+
145
+ --
146
+
147
+ ==== Enumeration and context
148
+
149
+ The following syntax is used to enumerate items within an array:
150
+
151
+ [source,asciidoc]
152
+ --
153
+ {% for item in array_name %}
154
+ ...content...
155
+ {% endfor %}
156
+ --
157
+
158
+ Where:
159
+
160
+ * `array_name` is the name of the existing context that contains array data
161
+ * `item` is the current item within the array
162
+
163
+ Within an array enumerator, the following https://shopify.dev/docs/themes/liquid/reference/objects/for-loops[expressions] can be used:
164
+
165
+ * `{{forloop.index0}}` gives the zero-based position of the item `item_name` within the parent array
166
+
167
+ * `{{forloop.length}}` returns the number of iterations of the loop.
168
+
169
+ * `{{forloop.first}}` returns `true` if it's the first iteration of the for loop. Returns `false` if it is not the first iteration.
170
+
171
+ * `{{forloop.last}}` returns `true` if it's the last iteration of the for loop. Returns `false` if it is not the last iteration.
172
+
173
+ * `{{array_name.size}}` gives the length of the array `array_name`
174
+
175
+ * `{{array_name[i]}}` provides the value at index `i` (zero-based: starts with `0`) in the array `array_name`; `-1` can be used to refer to the last item, `-2` the second last item, and so on.
176
+
177
+
178
+ EXAMPLE:
179
+ --
180
+ Given:
181
+
182
+ strings.yaml
183
+ [source,yaml]
184
+ ----
185
+ ---
186
+ - lorem
187
+ - ipsum
188
+ - dolor
189
+ ----
190
+
191
+ And the block:
192
+ [source,asciidoc]
193
+ ------
194
+ [yaml2text,strings.yaml,arr]
195
+ ----
196
+ {% for item in arr %}
197
+ === {{forloop.index0}} {item}
198
+
199
+ This section is about {item}.
200
+
201
+ {endfor}
202
+ ----
203
+ ------
204
+
205
+ Where:
206
+
207
+ * file path is `strings.yaml`
208
+ * current context within the enumerator is called `item`
209
+ * `{{forloop.index0}}` gives the zero-based position of item `item` in the parent array `arr`.
210
+
211
+ Will render as:
212
+ [source,text]
213
+ ----
214
+ === 0 lorem
215
+
216
+ This section is about lorem.
217
+
218
+ === 1 ipsum
219
+
220
+ This section is about ipsum.
221
+
222
+ === 2 dolor
223
+
224
+ This section is about dolor.
225
+ ----
226
+
227
+ --
228
+
229
+
230
+
231
+ === Accessing objects
232
+
233
+
234
+ ==== Size
235
+
236
+ Similar to arrays, the number of key-value pairs within an object can be
237
+ obtained by `{{objectname.size}}`.
238
+
239
+ EXAMPLE:
240
+ --
241
+ Given:
242
+
243
+ object.yaml
244
+ [source,yaml]
245
+ ----
246
+ ---
247
+ name: Lorem ipsum
248
+ desc: dolor sit amet
249
+ ----
250
+
251
+ And the block:
252
+ [source,asciidoc]
253
+ ------
254
+ [yaml2text,object.yaml,data]
255
+ ----
256
+ === {{data.name}}
257
+
258
+ {{data.desc}}
259
+ ----
260
+ ------
261
+
262
+ The file path is `object.yaml`, and context name is `data`.
263
+ `{{data.size}}` evaluates to the size of the object.
264
+
265
+ Will render as:
266
+ [source,asciidoc]
267
+ ----
268
+ === Lorem ipsum
269
+
270
+ dolor sit amet
271
+ ----
272
+
273
+ --
274
+
275
+ ==== Enumeration and context
276
+
277
+ The following syntax is used to enumerate key-value pairs within an object:
278
+
279
+ [source,asciidoc]
280
+ --
281
+ {% for item in object_name %}
282
+ {{item[0]}}, {{item[1]}}
283
+ {% endfor %}
284
+ --
285
+
286
+ Where:
287
+
288
+ * `object_name` is the name of the existing context that contains the object
289
+ * `{{item[0]}}` contains the key of the current enumrated object
290
+ * `{{item[1]}}` contains the value
291
+ * `{% endfor %}` indicates where the object enumeration block ends
292
+
293
+
294
+ EXAMPLE:
295
+ --
296
+ Given:
297
+
298
+ object.yaml
299
+ [source,yaml]
300
+ ----
301
+ ---
302
+ name: Lorem ipsum
303
+ desc: dolor sit amet
304
+ ----
305
+
306
+ And the block:
307
+ [source,asciidoc]
308
+ ------
309
+ [yaml2text,object.yaml,my_item]
310
+ ----
311
+ {% for item in my_item %}
312
+ === {{item[0]}}
313
+
314
+ {{item[1]}}
315
+
316
+ {% endfor %}
317
+ ----
318
+ ------
319
+
320
+ Where:
321
+
322
+ * file path is `object.yaml`
323
+ * current key within the enumerator is called `item[0]`
324
+ * `{{item[0]}}` gives the key name in the current iteration
325
+ * `{{item[1]}}` gives the value in the current iteration
326
+
327
+ Will render as:
328
+ [source,text]
329
+ ----
330
+ === name
331
+
332
+ Lorem ipsum
333
+
334
+ === desc
335
+
336
+ dolor sit amet
337
+ ----
338
+
339
+ --
340
+
341
+
342
+
343
+ Moreover, the `keys` and `values` attributes can also be used in object enumerators.
344
+
345
+
346
+ EXAMPLE:
347
+ --
348
+ Given:
349
+
350
+ object.yaml
351
+ [source,yaml]
352
+ ----
353
+ ---
354
+ name: Lorem ipsum
355
+ desc: dolor sit amet
356
+ ----
357
+
358
+ And the block:
359
+ [source,asciidoc]
360
+ ------
361
+ [yaml2text,object.yaml,item]
362
+ ----
363
+ .{{item.values[1]}}
364
+ [%noheader,cols="h,1"]
365
+ |===
366
+ {% for elem in item %}
367
+ | {{elem[0]}} | {{elem[1]}}
368
+
369
+ {% endfor %}
370
+ |===
371
+ ----
372
+ ------
373
+
374
+ Where:
375
+
376
+ * file path is `object.yaml`
377
+ * current key within the enumerator is called `key`
378
+ * `{{item[1]}}` gives the value of key in the current iteration the parent array `my_item`.
379
+ * `{{item.values[1]}}` gives the value located at the second key within `item`
380
+
381
+ Will render as:
382
+ [source,text]
383
+ ----
384
+ .dolor sit amet
385
+
386
+ [%noheader,cols="h,1"]
387
+ |===
388
+ | name | Lorem ipsum
389
+ | desc | dolor sit amet
390
+ |===
391
+ ----
392
+
393
+ --
394
+
395
+ There are several optional arguments to the for tag that can influence which items you receive in your loop and what order they appear in:
396
+
397
+ * limit:<INTEGER> lets you restrict how many items you get.
398
+ * offset:<INTEGER> lets you start the collection with the nth item.
399
+ * reversed iterates over the collection from last to first.
400
+
401
+ EXAMPLE:
402
+ --
403
+ Given:
404
+
405
+ strings.yaml
406
+ [source,yaml]
407
+ ----
408
+ ---
409
+ - lorem
410
+ - ipsum
411
+ - dolor
412
+ - sit
413
+ - amet
414
+ ----
415
+
416
+ And the block:
417
+ [source,asciidoc]
418
+ ------
419
+ [yaml2text,strings.yaml,items]
420
+ ----
421
+ {% for elem in items limit:2 offset:2 %}
422
+ {{item}}
423
+ {% endfor %}
424
+ ----
425
+ ------
426
+
427
+ Where:
428
+
429
+ * file path is `strings.yaml`
430
+ * `limit` - how many items we shoudl take from the array
431
+ * `offset` - zero-based offset of item from which start the loop
432
+ * `{{item}}` gives the value of item in the array
433
+
434
+ Will render as:
435
+ [source,text]
436
+ ----
437
+ dolor sit
438
+ ----
439
+
440
+ --
441
+
442
+
443
+ == Advanced examples
444
+
445
+ With the syntax of enumerating arrays and objects we can now try more powerful examples.
446
+
447
+
448
+
449
+ === Array of objects
450
+
451
+
452
+ EXAMPLE:
453
+ --
454
+ Given:
455
+
456
+ array_of_objects.yaml
457
+ [source,yaml]
458
+ ----
459
+ ---
460
+ - name: Lorem
461
+ desc: ipsum
462
+ nums: [2]
463
+ - name: dolor
464
+ desc: sit
465
+ nums: []
466
+ - name: amet
467
+ desc: lorem
468
+ nums: [2, 4, 6]
469
+ ----
470
+
471
+ And the block:
472
+ [source,asciidoc]
473
+ ------
474
+ [yaml2text,array_of_objects.yaml,ar]
475
+ ----
476
+ {% for item in ar %}
477
+
478
+ {{item.name}}:: {{item.desc}}
479
+
480
+ {% for num in item.nums %}
481
+ - {{item.name}}: {{num}}
482
+ {% endfor %}
483
+
484
+ {% endfor %}
485
+ ----
486
+ ------
487
+
488
+ Notice we are now defining multiple contexts:
489
+
490
+ * using different context names: `ar`, `item`, and `num`
491
+
492
+ Will render as:
493
+ [source,asciidoc]
494
+ ----
495
+ Lorem:: ipsum
496
+
497
+ - Lorem: 2
498
+
499
+ dolor:: sit
500
+
501
+ amet:: lorem
502
+
503
+ - amet: 2
504
+ - amet: 4
505
+ - amet: 6
506
+ ----
507
+
508
+ --
509
+
510
+
511
+ === An array with interpolated file names (for AsciiDoc consumption)
512
+
513
+ `yaml2text`(`json2text`) blocks can be used for pre-processing document elements for AsciiDoc consumption.
514
+
515
+ EXAMPLE:
516
+ --
517
+ Given:
518
+
519
+ strings.yaml
520
+ [source,yaml]
521
+ ----
522
+ ---
523
+ prefix: doc-
524
+ items:
525
+ - lorem
526
+ - ipsum
527
+ - dolor
528
+ ----
529
+
530
+ And the block:
531
+ [source,asciidoc]
532
+ --------
533
+ [yaml2text,strings.yaml,yaml]
534
+ ------
535
+ First item is {{yaml.items.first}}.
536
+ Last item is {{yaml.items.last}}.
537
+
538
+ {% for s in yaml.items %}
539
+ === {{forloop.index0}} -> {{forloop.index0 | plus: 1}} {{s}} == {{yaml.items[forloop.index0]}}
540
+
541
+ [source,ruby]
542
+ ----
543
+ \include::{{yaml.prefix}}{{forloop.index0}}.rb[]
544
+ ----
545
+
546
+ {% endfor %}
547
+ ------
548
+ --------
549
+
550
+
551
+ Will render as:
552
+ [source,asciidoc]
553
+ ------
554
+ First item is lorem.
555
+ Last item is dolor.
556
+
557
+ === 0 -> 1 lorem == lorem
558
+
559
+ [source,ruby]
560
+ ----
561
+ \include::doc-0.rb[]
562
+ ----
563
+
564
+ === 1 -> 2 ipsum == ipsum
565
+
566
+ [source,ruby]
567
+ ----
568
+ \include::doc-1.rb[]
569
+ ----
570
+
571
+ === 2 -> 3 dolor == dolor
572
+
573
+ [source,ruby]
574
+ ----
575
+ \include::doc-2.rb[]
576
+ ----
577
+
578
+ ------
579
+
580
+ --
@@ -144,15 +144,18 @@ module Metanorma
144
144
  render_result, errors = render_liquid_string(
145
145
  template_string: context_lines.join("\n"),
146
146
  context_items: context_items,
147
- context_name: context_name
147
+ context_name: context_name,
148
+ document: document
148
149
  )
149
150
  notify_render_errors(document, errors)
150
151
  render_result.split("\n")
151
152
  end
152
153
 
153
154
  def render_liquid_string(template_string:, context_items:,
154
- context_name:)
155
+ context_name:, document:)
155
156
  liquid_template = Liquid::Template.parse(template_string)
157
+ # Allow includes for the template
158
+ liquid_template.registers[:file_system] = ::Liquid::LocalFileSystem.new(relative_file_path(document, ""))
156
159
  rendered_string = liquid_template
157
160
  .render(context_name => context_items,
158
161
  strict_variables: true,
@@ -1,7 +1,7 @@
1
1
  module Metanorma
2
2
  module Plugin
3
3
  module Datastruct
4
- VERSION = "0.1.1".freeze
4
+ VERSION = "0.1.2".freeze
5
5
  end
6
6
  end
7
7
  end
@@ -27,7 +27,7 @@ Gem::Specification.new do |spec|
27
27
  spec.add_dependency "metanorma"
28
28
  spec.add_dependency "relaton-cli"
29
29
  spec.add_dependency "isodoc"
30
- spec.add_dependency "liquid"
30
+ spec.add_dependency "liquid", "~> 4"
31
31
 
32
32
  spec.add_development_dependency "byebug"
33
33
  spec.add_development_dependency "equivalent-xml"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metanorma-plugin-datastruct
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.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: 2020-10-28 00:00:00.000000000 Z
11
+ date: 2021-05-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor
@@ -70,16 +70,16 @@ dependencies:
70
70
  name: liquid
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ">="
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '0'
75
+ version: '4'
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ">="
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '0'
82
+ version: '4'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: byebug
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -227,6 +227,7 @@ executables: []
227
227
  extensions: []
228
228
  extra_rdoc_files: []
229
229
  files:
230
+ - ".github/workflows/rake.yml"
230
231
  - ".gitignore"
231
232
  - ".rspec"
232
233
  - CODE_OF_CONDUCT.md
@@ -265,7 +266,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
265
266
  - !ruby/object:Gem::Version
266
267
  version: '0'
267
268
  requirements: []
268
- rubygems_version: 3.0.6
269
+ rubygems_version: 3.0.3
269
270
  signing_key:
270
271
  specification_version: 4
271
272
  summary: Metanorma plugin for yaml2text and json2text