metanorma-plugin-lutaml 0.6.0 → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +5 -1
- data/README.adoc +62 -3
- data/lib/metanorma/plugin/lutaml/express_remarks_decorator.rb +1 -1
- data/lib/metanorma/plugin/lutaml/liquid/custom_filters.rb +1 -1
- data/lib/metanorma/plugin/lutaml/liquid/multiply_local_file_system.rb +38 -23
- data/lib/metanorma/plugin/lutaml/lutaml_preprocessor.rb +176 -96
- data/lib/metanorma/plugin/lutaml/lutaml_uml_attributes_table_preprocessor.rb +1 -1
- data/lib/metanorma/plugin/lutaml/lutaml_uml_class_preprocessor.rb +3 -3
- data/lib/metanorma/plugin/lutaml/lutaml_uml_datamodel_description_preprocessor.rb +4 -3
- data/lib/metanorma/plugin/lutaml/utils.rb +67 -48
- data/lib/metanorma/plugin/lutaml/version.rb +1 -1
- data/metanorma-plugin-lutaml.gemspec +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 56a196838fa30ab8585b1834d115bf6ff99b4b81d33176975b75dc7f5c5cd5bd
|
4
|
+
data.tar.gz: 458ce39ccac1e11b1dee74289e9e85a06a4ec5fa2faceaa78869ca18cc8dae77
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 780fa1199a23d199cb8f04d1a1b9b79d416f8aed0a2b442f02baccd370830d76d80fee12c2061e9424c9dd294059f5709b50a0eac7ac9b24fd4b492f54caa839
|
7
|
+
data.tar.gz: 1582258a02474a3ee351b935afc686a78ed8c82f1cc72efefde7c003110bfaa8fd4189d979b2070e61509d5d4997208b7644daf529c6e221c9e187e4e3def057
|
data/Gemfile
CHANGED
data/README.adoc
CHANGED
@@ -28,9 +28,9 @@ LutaML supports accessing EXPRESS models via the
|
|
28
28
|
https://github.com/lutaml/expressir[Expressir] parser.
|
29
29
|
|
30
30
|
|
31
|
-
=== Usage of the `lutaml`
|
31
|
+
=== Usage of the `lutaml` command
|
32
32
|
|
33
|
-
Given an `example.exp` EXPRESS file with
|
33
|
+
Given an `example.exp` EXPRESS file with content:
|
34
34
|
|
35
35
|
[source,exp]
|
36
36
|
----
|
@@ -57,7 +57,7 @@ SCHEMA test_schema 'test';
|
|
57
57
|
END_SCHEMA;
|
58
58
|
----
|
59
59
|
|
60
|
-
And the `lutaml`
|
60
|
+
And the `lutaml` block:
|
61
61
|
|
62
62
|
[source,adoc]
|
63
63
|
-----
|
@@ -137,6 +137,7 @@ Example of usage:
|
|
137
137
|
= Document title
|
138
138
|
Author
|
139
139
|
:lutaml-express-index: index_name; /path/to/express_files; cache=/path/to/cache_file.yaml
|
140
|
+
|
140
141
|
[lutaml,index_name,context]
|
141
142
|
----
|
142
143
|
{% for schema in context.schemas %}
|
@@ -145,6 +146,64 @@ Author
|
|
145
146
|
----
|
146
147
|
-----
|
147
148
|
|
149
|
+
=== Using `config.yaml`
|
150
|
+
|
151
|
+
This functionality allows `[lutaml_express]` blocks to load a full set of
|
152
|
+
EXPRESS schemas in one index, and then provide a select ("filter") option
|
153
|
+
per-block via a separate YAML file.
|
154
|
+
|
155
|
+
[source,adoc]
|
156
|
+
----
|
157
|
+
:lutaml-express-index: schemas_1; schemas_all.yaml;
|
158
|
+
|
159
|
+
[lutaml_express,schemas_1,repo,leveloffset=+1,config_yaml=select.yaml]
|
160
|
+
---
|
161
|
+
{% assign selected = repo.schemas | where: "selected" %}
|
162
|
+
{% render "templates/resources/schema" for selected as schema %}
|
163
|
+
---
|
164
|
+
----
|
165
|
+
|
166
|
+
Where `schemas_all.yml` provides all schemas:
|
167
|
+
|
168
|
+
[source,yaml]
|
169
|
+
----
|
170
|
+
---
|
171
|
+
schemas:
|
172
|
+
action_schema:
|
173
|
+
path: "../../schemas/resources/action_schema/action_schema.exp"
|
174
|
+
application_context_schema:
|
175
|
+
path: "../../schemas/resources/application_context_schema/application_context_schema.exp"
|
176
|
+
approval_schema:
|
177
|
+
path: "../../schemas/resources/approval_schema/approval_schema.exp"
|
178
|
+
...
|
179
|
+
----
|
180
|
+
|
181
|
+
And `select.yaml` only selects 2 schemas:
|
182
|
+
|
183
|
+
[source,yaml]
|
184
|
+
----
|
185
|
+
---
|
186
|
+
schemas:
|
187
|
+
- action_schema
|
188
|
+
- application_context_schema
|
189
|
+
----
|
190
|
+
|
191
|
+
The resulting block adds the `select` attribute to every schema of the the
|
192
|
+
"context" object, which allows you to filter those out for complex operations
|
193
|
+
via Liquid:
|
194
|
+
|
195
|
+
[source,liquid]
|
196
|
+
----
|
197
|
+
[lutaml_express,schemas_1,repo,leveloffset=+1,config_yaml=select.yaml]
|
198
|
+
---
|
199
|
+
{% assign selected = repo.schemas | where: "selected" %}
|
200
|
+
... do things with `selected` ...
|
201
|
+
----
|
202
|
+
|
203
|
+
NOTE: This functionality is used in the ISO 10303 SRL to load the full schema
|
204
|
+
set at once but only render the selected schemas in individual documents.
|
205
|
+
|
206
|
+
|
148
207
|
== Usage with UML
|
149
208
|
|
150
209
|
=== Rendering a LutaML view: `lutaml_diagram`
|
@@ -48,7 +48,7 @@ module Metanorma
|
|
48
48
|
# When we are dealing with a relative path of a template:
|
49
49
|
# ../path/to/file we need to transform it into
|
50
50
|
# the absolute one because `image::` macro wont understand it other way
|
51
|
-
prefixed_path = File.absolute_path(prefixed_path) if prefixed_path.start_with?(
|
51
|
+
prefixed_path = File.absolute_path(prefixed_path) if prefixed_path.start_with?("../")
|
52
52
|
full_path = File.expand_path(prefixed_path)
|
53
53
|
"#{$1}#{$2}#{full_path}#{$4}"
|
54
54
|
end
|
@@ -12,36 +12,51 @@ module Metanorma
|
|
12
12
|
|
13
13
|
def read_template_file(template_path)
|
14
14
|
full_path = full_path(template_path)
|
15
|
-
|
15
|
+
|
16
|
+
unless File.exist?(full_path)
|
17
|
+
raise FileSystemError, "No such template '#{template_path}'"
|
18
|
+
end
|
16
19
|
|
17
20
|
File.read(full_path)
|
18
21
|
end
|
19
22
|
|
20
23
|
def full_path(template_path)
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
24
|
+
unless %r{\A[^./][a-zA-Z0-9_/]+\z}.match?(template_path)
|
25
|
+
raise ::Liquid::FileSystemError,
|
26
|
+
"Illegal template name '#{template_path}'"
|
27
|
+
end
|
28
|
+
|
29
|
+
result_path = if template_path.include?("/")
|
30
|
+
roots
|
31
|
+
.map do |root|
|
32
|
+
patterns.map do |pattern|
|
33
|
+
File.join(root, File.dirname(template_path),
|
34
|
+
pattern % File.basename(template_path))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
.flatten
|
38
|
+
.find { |path| File.file?(path) }
|
39
|
+
else
|
40
|
+
roots
|
41
|
+
.map do |root|
|
42
|
+
patterns.map do |pattern|
|
43
|
+
File.join(root, pattern % template_path)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
.flatten
|
47
|
+
.find { |path| File.file?(path) }
|
48
|
+
end
|
49
|
+
|
50
|
+
if result_path.nil?
|
51
|
+
raise ::Liquid::FileSystemError,
|
52
|
+
"No documents in template path '#{File.expand_path(template_path)}'"
|
41
53
|
end
|
42
54
|
|
43
|
-
unless roots.any?
|
44
|
-
|
55
|
+
unless roots.any? do |root|
|
56
|
+
File.expand_path(result_path).start_with?(File.expand_path(root))
|
57
|
+
end
|
58
|
+
raise ::Liquid::FileSystemError,
|
59
|
+
"Illegal template path '#{File.expand_path(result_path)}'"
|
45
60
|
end
|
46
61
|
|
47
62
|
result_path
|
@@ -16,164 +16,244 @@ module Metanorma
|
|
16
16
|
REMARKS_ATTRIBUTE = "remarks"
|
17
17
|
|
18
18
|
def process(document, reader)
|
19
|
-
r = Asciidoctor::PreprocessorNoIfdefsReader.new
|
19
|
+
r = Asciidoctor::PreprocessorNoIfdefsReader.new(document,
|
20
|
+
reader.lines)
|
20
21
|
input_lines = r.readlines.to_enum
|
21
|
-
|
22
|
+
|
23
|
+
has_lutaml = input_lines.any? { |line| lutaml?(line) }
|
22
24
|
express_indexes = Utils.parse_document_express_indexes(
|
23
|
-
document,
|
25
|
+
document,
|
26
|
+
input_lines,
|
27
|
+
)
|
28
|
+
|
29
|
+
result_content = process_input_lines(
|
30
|
+
document: document,
|
31
|
+
input_lines: input_lines,
|
32
|
+
express_indexes: express_indexes,
|
24
33
|
)
|
25
|
-
|
26
|
-
|
27
|
-
|
34
|
+
|
35
|
+
log(document, result_content) if has_lutaml
|
36
|
+
|
28
37
|
Asciidoctor::PreprocessorNoIfdefsReader.new(document, result_content)
|
29
38
|
end
|
30
39
|
|
31
40
|
protected
|
32
41
|
|
33
|
-
def log(
|
34
|
-
File.open("#{
|
35
|
-
|
36
|
-
f.write(result.join("\n"))
|
42
|
+
def log(doc, text)
|
43
|
+
File.open("#{doc.attr('docfile')}.lutaml.log.txt", "w:UTF-8") do |f|
|
44
|
+
f.write(text.join("\n"))
|
37
45
|
end
|
38
46
|
end
|
39
47
|
|
40
48
|
def lutaml?(line)
|
41
|
-
line.match(/^\[(?:\blutaml\b|\blutaml_express\b),([^,]+)?,?([^,]+)
|
49
|
+
line.match(/^\[(?:\blutaml\b|\blutaml_express\b),(?<index_names>[^,]+)?,?(?<context_name>[^,]+)?(?<options>,.*)?\]/)
|
42
50
|
end
|
43
51
|
|
44
|
-
def
|
45
|
-
|
46
|
-
File.new(
|
47
|
-
|
48
|
-
|
49
|
-
|
52
|
+
def load_lutaml_file(document, file_path)
|
53
|
+
::Lutaml::Parser.parse(
|
54
|
+
File.new(
|
55
|
+
Utils.relative_file_path(document, file_path),
|
56
|
+
encoding: "UTF-8",
|
57
|
+
),
|
58
|
+
)
|
50
59
|
end
|
51
60
|
|
52
61
|
private
|
53
62
|
|
54
|
-
def
|
63
|
+
def process_input_lines(
|
64
|
+
document:,
|
65
|
+
input_lines:,
|
66
|
+
express_indexes:
|
67
|
+
)
|
68
|
+
|
55
69
|
result = []
|
56
70
|
loop do
|
57
|
-
result
|
58
|
-
|
71
|
+
result.push(
|
72
|
+
*process_text_blocks(
|
59
73
|
document,
|
60
74
|
input_lines,
|
61
75
|
express_indexes,
|
62
|
-
)
|
76
|
+
),
|
77
|
+
)
|
63
78
|
end
|
64
79
|
result
|
65
80
|
end
|
66
81
|
|
67
82
|
def process_text_blocks(document, input_lines, express_indexes)
|
68
83
|
line = input_lines.next
|
69
|
-
|
70
|
-
|
84
|
+
block_header_match = lutaml?(line)
|
85
|
+
|
86
|
+
return [line] if block_header_match.nil?
|
87
|
+
|
88
|
+
index_names = block_header_match[:index_names].split(";").map(&:strip)
|
89
|
+
context_name = block_header_match[:context_name].strip
|
90
|
+
|
91
|
+
options = block_header_match[:options] &&
|
92
|
+
parse_options(block_header_match[:options].to_s.strip) || {}
|
71
93
|
|
72
94
|
end_mark = input_lines.next
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
95
|
+
|
96
|
+
render_template(
|
97
|
+
document: document,
|
98
|
+
lines: extract_block_lines(input_lines, end_mark),
|
99
|
+
index_names: index_names,
|
100
|
+
context_name: context_name,
|
101
|
+
options: options,
|
102
|
+
indexes: express_indexes,
|
103
|
+
)
|
79
104
|
end
|
80
105
|
|
81
|
-
def
|
82
|
-
|
106
|
+
def extract_block_lines(input_lines, end_mark)
|
107
|
+
block = []
|
83
108
|
while (block_line = input_lines.next) != end_mark
|
84
|
-
|
109
|
+
block.push(block_line)
|
85
110
|
end
|
86
|
-
|
111
|
+
block
|
87
112
|
end
|
88
113
|
|
89
|
-
def
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
114
|
+
def gather_context_items(index_names:, document:, indexes:)
|
115
|
+
index_names.map do |path|
|
116
|
+
# TODO: Rephrase of the below TODO message.
|
117
|
+
# ::Lutaml::Parser.parse(file_list) can return an Array or just one.
|
118
|
+
# TODO: decide how to handle expressir multiply file parse as one
|
119
|
+
# object and lutaml
|
120
|
+
|
121
|
+
# Does this condition ever happen? That is only if the `lutaml-express-index` condition is not set
|
122
|
+
if indexes[path]
|
123
|
+
indexes[path][:serialized_hash] ||= indexes[path][:wrapper].to_liquid
|
95
124
|
else
|
96
|
-
|
125
|
+
wrapper = load_lutaml_file(document, path)
|
126
|
+
indexes[path] = {
|
127
|
+
wrapper: wrapper,
|
128
|
+
serialized_hash: wrapper.to_liquid,
|
129
|
+
}
|
97
130
|
end
|
131
|
+
|
132
|
+
indexes[path]
|
98
133
|
end
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
134
|
+
end
|
135
|
+
|
136
|
+
def parse_yaml_config_file(document, file_path)
|
137
|
+
return nil if file_path.nil?
|
138
|
+
|
139
|
+
relative_file_path = Utils.relative_file_path(document, file_path)
|
140
|
+
YAML.safe_load(File.read(relative_file_path, encoding: "UTF-8"))
|
141
|
+
end
|
142
|
+
|
143
|
+
def decorate_schema_object(schema:, document:, indexes:, index_names:,
|
144
|
+
selected:, options:)
|
145
|
+
# Mark a schema as "selected" with `.selected`
|
146
|
+
schema["selected"] = true if selected
|
147
|
+
|
148
|
+
# Provide pretty-formatted code under `.formatted`
|
149
|
+
_, index_found_value = indexes.detect do |_k, _v|
|
150
|
+
_
|
111
151
|
end
|
112
|
-
|
152
|
+
|
153
|
+
schema["formatted"] = index_found_value[:wrapper].original_document.schemas.detect do |s|
|
154
|
+
s.id == schema["id"]
|
155
|
+
end.to_s(no_remarks: true)
|
156
|
+
|
157
|
+
# Decorate the remaining things
|
158
|
+
decorate_context_items(
|
159
|
+
schema,
|
160
|
+
options.merge(
|
161
|
+
"relative_path_prefix" =>
|
162
|
+
Utils.relative_file_path(document,
|
163
|
+
File.dirname(schema["file"])),
|
164
|
+
),
|
165
|
+
) || {}
|
113
166
|
end
|
114
167
|
|
115
|
-
def
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
168
|
+
def render_template(document:, lines:, context_name:, index_names:,
|
169
|
+
options:, indexes:)
|
170
|
+
config_yaml_path = options.delete("config_yaml")
|
171
|
+
config_yaml = if config_yaml_path
|
172
|
+
parse_yaml_config_file(document, config_yaml_path)
|
173
|
+
else
|
174
|
+
{}
|
175
|
+
end
|
176
|
+
|
177
|
+
selected_schemas = config_yaml["schemas"]
|
178
|
+
|
179
|
+
gather_context_items(
|
180
|
+
index_names: index_names,
|
181
|
+
document: document,
|
182
|
+
indexes: indexes,
|
183
|
+
).map do |items|
|
184
|
+
serialized_hash = items[:serialized_hash]
|
185
|
+
|
186
|
+
serialized_hash["schemas"]&.map! do |schema|
|
187
|
+
decorate_schema_object(
|
188
|
+
schema: schema,
|
189
|
+
document: document,
|
190
|
+
index_names: index_names,
|
191
|
+
indexes: indexes,
|
192
|
+
selected: selected_schemas && selected_schemas.include?(schema["id"]),
|
193
|
+
options: options,
|
194
|
+
)
|
195
|
+
end
|
196
|
+
|
197
|
+
render_block(
|
198
|
+
document: document,
|
199
|
+
block_lines: lines,
|
200
|
+
context_items: serialized_hash,
|
201
|
+
context_name: context_name,
|
202
|
+
)
|
203
|
+
end.flatten
|
131
204
|
rescue StandardError => e
|
132
|
-
|
205
|
+
raise e
|
206
|
+
document.logger.warn("Failed to parse LutaML block: #{e.message}")
|
133
207
|
[]
|
134
208
|
end
|
135
209
|
|
136
210
|
def parse_options(options_string)
|
137
211
|
options_string
|
138
212
|
.to_s
|
139
|
-
.scan(
|
213
|
+
.scan(/,\s*([^=]+?)=(\s*[^,]+)/)
|
140
214
|
.map { |elem| elem.map(&:strip) }
|
141
215
|
.to_h
|
142
216
|
end
|
143
217
|
|
144
|
-
def
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
.to_h
|
218
|
+
def decorate_context_item(key, val, options)
|
219
|
+
if key == REMARKS_ATTRIBUTE
|
220
|
+
return [
|
221
|
+
key,
|
222
|
+
val&.map do |remark|
|
223
|
+
Metanorma::Plugin::Lutaml::ExpressRemarksDecorator
|
224
|
+
.call(remark, options)
|
225
|
+
end,
|
226
|
+
]
|
227
|
+
end
|
228
|
+
|
229
|
+
case val
|
230
|
+
when Hash
|
231
|
+
[key, decorate_context_items(val, options)]
|
232
|
+
when Array
|
233
|
+
[key, val.map { |n| decorate_context_items(n, options) }]
|
234
|
+
else
|
235
|
+
[key, val]
|
236
|
+
end
|
164
237
|
end
|
165
238
|
|
166
|
-
def
|
167
|
-
|
168
|
-
|
169
|
-
|
239
|
+
def decorate_context_items(item, options)
|
240
|
+
return item unless item.is_a?(Hash)
|
241
|
+
|
242
|
+
item.map do |(key, val)|
|
243
|
+
decorate_context_item(key, val, options)
|
244
|
+
end.to_h
|
245
|
+
end
|
246
|
+
|
247
|
+
def render_block(block_lines:, context_items:, context_name:, document:)
|
170
248
|
render_result, errors = Utils.render_liquid_string(
|
171
|
-
template_string:
|
249
|
+
template_string: block_lines.join("\n"),
|
172
250
|
context_items: context_items,
|
173
251
|
context_name: context_name,
|
174
252
|
document: document,
|
175
253
|
)
|
254
|
+
|
176
255
|
Utils.notify_render_errors(document, errors)
|
256
|
+
|
177
257
|
render_result.split("\n")
|
178
258
|
end
|
179
259
|
end
|
@@ -9,7 +9,7 @@ module Metanorma
|
|
9
9
|
# @example [lutaml_uml_attributes_table,path/to/lutaml,EntityName]
|
10
10
|
class LutamlUmlAttributesTablePreprocessor < LutamlUmlClassPreprocessor
|
11
11
|
MACRO_REGEXP =
|
12
|
-
/\[lutaml_uml_attributes_table,([^,]+),?([^,]+),?(.+?)?\]
|
12
|
+
/\[lutaml_uml_attributes_table,([^,]+),?([^,]+),?(.+?)?\]/.freeze
|
13
13
|
|
14
14
|
# rubocop:disable Layout/IndentHeredoc
|
15
15
|
def template(options)
|
@@ -15,7 +15,7 @@ module Metanorma
|
|
15
15
|
# @example [lutaml_uml_class,path/to/lutaml,EntityName]
|
16
16
|
class LutamlUmlClassPreprocessor < ::Asciidoctor::Extensions::Preprocessor
|
17
17
|
MACRO_REGEXP =
|
18
|
-
/\[lutaml_uml_class,([^,]+),?([^,]+),?(.+?)?\]
|
18
|
+
/\[lutaml_uml_class,([^,]+),?([^,]+),?(.+?)?\]/.freeze
|
19
19
|
|
20
20
|
def get_macro_regexp
|
21
21
|
self.class.const_get(:MACRO_REGEXP)
|
@@ -109,9 +109,9 @@ module Metanorma
|
|
109
109
|
|
110
110
|
<<~TEMPLATE
|
111
111
|
{% if definition.keyword == 'enumeration' %}
|
112
|
-
#{equalsigns(depth)
|
112
|
+
#{"#{equalsigns(depth)} Enumeration: {{ definition.name }}" unless skip_headers}
|
113
113
|
{% else %}
|
114
|
-
#{equalsigns(depth)
|
114
|
+
#{"#{equalsigns(depth)} Class: {{ definition.name }}" unless skip_headers}
|
115
115
|
{% endif %}
|
116
116
|
|
117
117
|
#{equalsigns(depth + 1)} Description
|
@@ -16,7 +16,7 @@ module Metanorma
|
|
16
16
|
class LutamlUmlDatamodelDescriptionPreprocessor <
|
17
17
|
::Asciidoctor::Extensions::Preprocessor
|
18
18
|
MACRO_REGEXP =
|
19
|
-
/\[lutaml_uml_datamodel_description,([^,]+),?(.+)?\]
|
19
|
+
/\[lutaml_uml_datamodel_description,([^,]+),?(.+)?\]/.freeze
|
20
20
|
LIQUID_INCLUDE_PATH = File.join(
|
21
21
|
Gem.loaded_specs["metanorma-plugin-lutaml"].full_gem_path,
|
22
22
|
"lib", "metanorma", "plugin", "lutaml", "liquid_templates"
|
@@ -92,7 +92,7 @@ module Metanorma
|
|
92
92
|
def fill_in_entities_refs_attributes(document, lutaml_document_wrapper,
|
93
93
|
options)
|
94
94
|
lutaml_document = lutaml_document_wrapper.original_document
|
95
|
-
|
95
|
+
options.fetch(RENDER_STYLE_ATTRIBUTE, "default")
|
96
96
|
all_children_packages = lutaml_document.packages
|
97
97
|
.map(&:children_packages).flatten
|
98
98
|
package_flat_packages = lambda do |pks|
|
@@ -201,7 +201,8 @@ options)
|
|
201
201
|
end
|
202
202
|
|
203
203
|
def package_entities(options)
|
204
|
-
options["packages"]
|
204
|
+
return {} unless options["packages"]
|
205
|
+
|
205
206
|
options["packages"]
|
206
207
|
.find_all { |entity| entity.is_a?(Hash) && entity.values.first["render_entities"] }
|
207
208
|
.map do |entity|
|
@@ -27,16 +27,22 @@ module Metanorma
|
|
27
27
|
def render_liquid_string(template_string:, context_items:,
|
28
28
|
context_name:, document:, include_path: nil)
|
29
29
|
liquid_template = ::Liquid::Template.parse(template_string)
|
30
|
+
|
30
31
|
# Allow includes for the template
|
31
|
-
include_paths = [
|
32
|
-
|
32
|
+
include_paths = [
|
33
|
+
Utils.relative_file_path(document, ""),
|
34
|
+
include_path,
|
35
|
+
].compact
|
36
|
+
|
33
37
|
liquid_template.registers[:file_system] =
|
34
38
|
::Metanorma::Plugin::Lutaml::Liquid::LocalFileSystem
|
35
39
|
.new(include_paths, ["_%s.liquid", "_%s.adoc"])
|
40
|
+
|
36
41
|
rendered_string = liquid_template
|
37
42
|
.render(context_name => context_items,
|
38
43
|
strict_variables: true,
|
39
44
|
error_mode: :warn)
|
45
|
+
|
40
46
|
[rendered_string, liquid_template.errors]
|
41
47
|
end
|
42
48
|
|
@@ -48,37 +54,50 @@ module Metanorma
|
|
48
54
|
end
|
49
55
|
end
|
50
56
|
|
51
|
-
def
|
52
|
-
force_read
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
+
def load_express_repositories(path:, cache_path:, document:,
|
58
|
+
force_read: false)
|
59
|
+
cache_full_path = cache_path &&
|
60
|
+
Utils.relative_file_path(document, cache_path)
|
61
|
+
|
62
|
+
# If there is cache and "force read" not set.
|
57
63
|
if !force_read && cache_full_path && File.file?(cache_full_path)
|
58
|
-
return
|
64
|
+
return load_express_repo_from_cache(cache_full_path)
|
59
65
|
end
|
60
66
|
|
67
|
+
# If there is no cache or "force read" is set.
|
61
68
|
full_path = Utils.relative_file_path(document, path)
|
62
|
-
|
69
|
+
lutaml_wrapper = load_express_repo_from_path(document, full_path)
|
70
|
+
|
63
71
|
if cache_full_path && !File.file?(cache_full_path)
|
64
|
-
|
65
|
-
|
72
|
+
save_express_repo_to_cache(
|
73
|
+
cache_full_path,
|
74
|
+
lutaml_wrapper.original_document,
|
75
|
+
document,
|
76
|
+
)
|
66
77
|
end
|
67
|
-
|
78
|
+
|
79
|
+
lutaml_wrapper
|
68
80
|
rescue Expressir::Error
|
69
81
|
FileUtils.rm_rf(cache_full_path)
|
70
|
-
|
82
|
+
|
83
|
+
load_express_repositories(
|
84
|
+
path: path,
|
85
|
+
cache_path: cache_path,
|
86
|
+
document: document,
|
87
|
+
force_read: true,
|
88
|
+
)
|
71
89
|
rescue StandardError => e
|
72
90
|
document.logger.warn("Failed to load #{full_path}: #{e.message}")
|
73
|
-
|
91
|
+
raise e
|
92
|
+
# nil
|
74
93
|
end
|
75
94
|
|
76
|
-
def
|
95
|
+
def load_express_repo_from_cache(path)
|
77
96
|
::Lutaml::Parser
|
78
97
|
.parse(File.new(path), ::Lutaml::Parser::EXPRESS_CACHE_PARSE_TYPE)
|
79
98
|
end
|
80
99
|
|
81
|
-
def
|
100
|
+
def save_express_repo_to_cache(path, repository, document)
|
82
101
|
root_path = Pathname.new(relative_file_path(document, ""))
|
83
102
|
Expressir::Express::Cache
|
84
103
|
.to_file(path,
|
@@ -86,43 +105,28 @@ force_read = false)
|
|
86
105
|
root_path: root_path)
|
87
106
|
end
|
88
107
|
|
89
|
-
def
|
90
|
-
if File.directory?(path)
|
91
|
-
return express_from_folder(path)
|
92
|
-
end
|
108
|
+
def load_express_repo_from_path(document, path)
|
109
|
+
return load_express_from_folder(path) if File.directory?(path)
|
93
110
|
|
94
|
-
|
111
|
+
load_express_from_index(document, path)
|
95
112
|
end
|
96
113
|
|
97
|
-
def
|
114
|
+
def load_express_from_folder(folder)
|
98
115
|
files = Dir["#{folder}/*.exp"].map do |nested_path|
|
99
116
|
File.new(nested_path, encoding: "UTF-8")
|
100
117
|
end
|
101
118
|
::Lutaml::Parser.parse(files)
|
102
119
|
end
|
103
120
|
|
104
|
-
def
|
105
|
-
serialized = wrapper.to_liquid
|
106
|
-
serialized["schemas"].map! do |j|
|
107
|
-
j.merge(
|
108
|
-
"relative_path_prefix" => Utils
|
109
|
-
.relative_file_path(document, File.dirname(j["file"])),
|
110
|
-
"formatted" => wrapper.original_document
|
111
|
-
.schemas.detect {|s| s.id == j["id"] }.to_s(no_remarks: true)
|
112
|
-
)
|
113
|
-
end
|
114
|
-
serialized
|
115
|
-
end
|
116
|
-
|
117
|
-
def express_from_index(document, path)
|
121
|
+
def load_express_from_index(document, path)
|
118
122
|
yaml_content = YAML.safe_load(File.read(path))
|
119
123
|
root_path = yaml_content["path"]
|
120
|
-
schemas_paths = yaml_content
|
121
|
-
.fetch("schemas")
|
124
|
+
schemas_paths = yaml_content["schemas"]
|
122
125
|
.map do |(schema_name, schema_values)|
|
123
126
|
schema_values["path"] || File.join(root_path.to_s,
|
124
127
|
"#{schema_name}.exp")
|
125
128
|
end
|
129
|
+
|
126
130
|
files_to_load = schemas_paths.map do |path|
|
127
131
|
File.new(Utils.relative_file_path(document, path),
|
128
132
|
encoding: "UTF-8")
|
@@ -134,20 +138,35 @@ force_read = false)
|
|
134
138
|
express_indexes = {}
|
135
139
|
loop do
|
136
140
|
line = input_lines.next
|
141
|
+
|
142
|
+
# Finished parsing document attributes
|
137
143
|
break if line.empty?
|
138
144
|
|
139
145
|
match = line.match(LUTAML_EXP_IDX_TAG)
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
146
|
+
next unless match
|
147
|
+
|
148
|
+
name = match[:index_name]&.strip
|
149
|
+
path = match[:index_path]&.strip
|
150
|
+
cache = match[:cache_path]&.strip
|
151
|
+
|
152
|
+
unless name && path
|
153
|
+
raise StandardError.new("No name and path set in `:lutaml-express-index:` attribute.")
|
154
|
+
end
|
155
|
+
|
156
|
+
lutaml_expressir_wrapper = load_express_repositories(
|
157
|
+
path: path,
|
158
|
+
cache_path: cache,
|
159
|
+
document: document,
|
160
|
+
)
|
161
|
+
|
162
|
+
if lutaml_expressir_wrapper
|
163
|
+
express_indexes[name] = {
|
164
|
+
wrapper: lutaml_expressir_wrapper,
|
165
|
+
serialized_hash: nil,
|
166
|
+
}
|
149
167
|
end
|
150
168
|
end
|
169
|
+
|
151
170
|
express_indexes
|
152
171
|
rescue StopIteration
|
153
172
|
express_indexes
|
@@ -30,7 +30,7 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.add_dependency "liquid"
|
31
31
|
spec.add_dependency "lutaml"
|
32
32
|
spec.add_dependency "relaton-cli"
|
33
|
-
spec.add_dependency "reverse_adoc"
|
33
|
+
spec.add_dependency "reverse_adoc", "~> 0.3.7"
|
34
34
|
|
35
35
|
spec.add_development_dependency "debug"
|
36
36
|
spec.add_development_dependency "equivalent-xml"
|
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.6.
|
4
|
+
version: 0.6.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: 2024-
|
11
|
+
date: 2024-05-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: asciidoctor
|
@@ -84,16 +84,16 @@ dependencies:
|
|
84
84
|
name: reverse_adoc
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - "
|
87
|
+
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
89
|
+
version: 0.3.7
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - "
|
94
|
+
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
96
|
+
version: 0.3.7
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: debug
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|