metanorma-plugin-datastruct 0.1.1 → 0.1.2

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