metanorma-standoc 3.1.3 → 3.1.5
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 +4 -4
- data/lib/metanorma/standoc/biblio-standoc.rng +0 -49
- data/lib/metanorma/standoc/biblio.rng +11 -1
- data/lib/metanorma/standoc/blocks_notes.rb +1 -0
- data/lib/metanorma/standoc/cleanup.rb +4 -1
- data/lib/metanorma/standoc/cleanup_bibdata.rb +16 -1
- data/lib/metanorma/standoc/cleanup_boilerplate.rb +62 -16
- data/lib/metanorma/standoc/cleanup_maths.rb +2 -1
- data/lib/metanorma/standoc/cleanup_section_names.rb +8 -8
- data/lib/metanorma/standoc/converter.rb +2 -3
- data/lib/metanorma/standoc/front.rb +0 -8
- data/lib/metanorma/standoc/front_committee.rb +140 -0
- data/lib/metanorma/standoc/front_contributor.rb +14 -3
- data/lib/metanorma/standoc/front_organisation.rb +24 -18
- data/lib/metanorma/standoc/isodoc.rng +24 -1
- data/lib/metanorma/standoc/macros.rb +1 -3
- data/lib/metanorma/standoc/ref_queue.rb +1 -1
- data/lib/metanorma/standoc/ref_utility.rb +27 -2
- data/lib/metanorma/standoc/regex.rb +6 -5
- data/lib/metanorma/standoc/sectiontype.rb +1 -0
- data/lib/metanorma/standoc/utils.rb +11 -1
- data/lib/metanorma/standoc/validate.rb +1 -1
- data/lib/metanorma/standoc/validate_section.rb +12 -2
- data/lib/metanorma/standoc/validate_table.rb +3 -1
- data/lib/metanorma/standoc/version.rb +1 -1
- data/metanorma-standoc.gemspec +1 -0
- metadata +17 -12
- data/lib/asciidoctor/standoc/datamodel/attributes_table_preprocessor.rb +0 -3
- data/lib/asciidoctor/standoc/datamodel/diagram_preprocessor.rb +0 -3
- data/lib/asciidoctor/standoc/datamodel/plantuml_renderer.rb +0 -8
- data/lib/asciidoctor/standoc/macros_plantuml.rb +0 -2
- data/lib/metanorma/standoc/datamodel/attributes_table_preprocessor.rb +0 -57
- data/lib/metanorma/standoc/datamodel/diagram_preprocessor.rb +0 -103
- data/lib/metanorma/standoc/datamodel/plantuml_renderer.rb +0 -409
- data/lib/metanorma/standoc/macros_plantuml.rb +0 -143
- data/lib/metanorma/standoc/views/datamodel/model_representation.adoc.erb +0 -30
- data/lib/metanorma/standoc/views/datamodel/plantuml_representation.adoc.erb +0 -20
@@ -1,409 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "erb"
|
4
|
-
|
5
|
-
module Metanorma
|
6
|
-
module Datamodel
|
7
|
-
class PlantumlRenderer
|
8
|
-
TEMPLATES_PATH = File.expand_path("../views/datamodel", __dir__).freeze
|
9
|
-
|
10
|
-
attr_reader :yml, :plantuml_path
|
11
|
-
|
12
|
-
def initialize(yml, plantuml_path)
|
13
|
-
@yml = yml
|
14
|
-
@plantuml_path = plantuml_path
|
15
|
-
end
|
16
|
-
|
17
|
-
def join_as_plantuml(*ary)
|
18
|
-
ary.compact.join("\n").sub(/(?<!\s)\s+\Z/, "")
|
19
|
-
end
|
20
|
-
|
21
|
-
def render
|
22
|
-
ERB.new(
|
23
|
-
File.read(
|
24
|
-
File.join(TEMPLATES_PATH, "plantuml_representation.adoc.erb"),
|
25
|
-
),
|
26
|
-
).result(binding)
|
27
|
-
end
|
28
|
-
|
29
|
-
def diagram_caption
|
30
|
-
yml["caption"]
|
31
|
-
end
|
32
|
-
|
33
|
-
def imports_yml_to_plantuml
|
34
|
-
return if empty?(yml, "imports")
|
35
|
-
|
36
|
-
<<~TEMPLATE
|
37
|
-
'******* IMPORTS ******************************************************
|
38
|
-
!include #{plantuml_path}/style.uml.inc
|
39
|
-
TEMPLATE
|
40
|
-
end
|
41
|
-
|
42
|
-
def class_defs_yml_to_plantuml
|
43
|
-
return if empty?(yml, "classes") && empty?(yml, "enums")
|
44
|
-
|
45
|
-
<<~TEMPLATE
|
46
|
-
'******* CLASS DEFINITIONS ********************************************
|
47
|
-
#{join_as_plantuml(
|
48
|
-
classes_to_classes_plantuml(yml['classes']),
|
49
|
-
enums_to_enums_plantuml(yml['enums']),
|
50
|
-
)}
|
51
|
-
TEMPLATE
|
52
|
-
end
|
53
|
-
|
54
|
-
def class_groups_yml_to_plantuml
|
55
|
-
return if empty?(yml, "groups")
|
56
|
-
|
57
|
-
<<~TEMPLATE
|
58
|
-
'******* CLASS GROUPS *************************************************
|
59
|
-
#{join_as_plantuml(
|
60
|
-
groups_to_plantuml(yml['groups']),
|
61
|
-
)}
|
62
|
-
TEMPLATE
|
63
|
-
end
|
64
|
-
|
65
|
-
def class_relations_yml_to_plantuml
|
66
|
-
return if empty?(yml, "classes") && empty?(yml, "relations")
|
67
|
-
|
68
|
-
<<~TEMPLATE
|
69
|
-
'******* CLASS RELATIONS **********************************************
|
70
|
-
#{join_as_plantuml(
|
71
|
-
classes_to_relations_plantuml(yml['classes']),
|
72
|
-
relations_to_plantuml(nil, yml['relations']),
|
73
|
-
)}
|
74
|
-
TEMPLATE
|
75
|
-
end
|
76
|
-
|
77
|
-
def diagram_options_yml_to_plantuml
|
78
|
-
return if empty?(yml, "diagram_options")
|
79
|
-
|
80
|
-
<<~TEMPLATE
|
81
|
-
'******* DIAGRAM SPECIFIC CONFIG **************************************
|
82
|
-
#{join_as_plantuml(
|
83
|
-
diagram_options_to_plantuml(yml['diagram_options']),
|
84
|
-
)}
|
85
|
-
TEMPLATE
|
86
|
-
end
|
87
|
-
|
88
|
-
def bottom_yml_to_plantuml
|
89
|
-
return if empty?(yml, "bottom")
|
90
|
-
|
91
|
-
<<~TEMPLATE
|
92
|
-
'******* BOTTOM OVERRIDE CONFIG **************************************
|
93
|
-
#{join_as_plantuml(bottom_to_plantuml(yml['bottom']))}
|
94
|
-
TEMPLATE
|
95
|
-
end
|
96
|
-
|
97
|
-
def fidelity_yml_to_plantuml
|
98
|
-
return if empty?(yml, "fidelity")
|
99
|
-
|
100
|
-
<<~TEMPLATE
|
101
|
-
'******* FIDELITY *****************************************************
|
102
|
-
#{join_as_plantuml(fidelity_to_plantuml(yml['fidelity']))}
|
103
|
-
TEMPLATE
|
104
|
-
end
|
105
|
-
|
106
|
-
def classes_to_classes_plantuml(classes)
|
107
|
-
classes ||= {}
|
108
|
-
|
109
|
-
return if classes.empty?
|
110
|
-
|
111
|
-
classes.map do |(class_name, class_hash)|
|
112
|
-
class_to_plantuml(class_name, class_hash)
|
113
|
-
end.join("\n")
|
114
|
-
end
|
115
|
-
|
116
|
-
def class_to_plantuml(class_name, class_hash)
|
117
|
-
return unless class_name
|
118
|
-
|
119
|
-
class_hash ||= {}
|
120
|
-
|
121
|
-
<<~TEMPLATE
|
122
|
-
class #{class_name}#{model_stereotype_to_plantuml(class_hash['type'])} {
|
123
|
-
#{join_as_plantuml(
|
124
|
-
attributes_to_plantuml(class_hash['attributes']),
|
125
|
-
constraints_to_plantuml(class_hash['constraints']),
|
126
|
-
)}
|
127
|
-
}
|
128
|
-
TEMPLATE
|
129
|
-
end
|
130
|
-
|
131
|
-
def attributes_to_plantuml(attributes)
|
132
|
-
return unless attributes
|
133
|
-
|
134
|
-
attributes.map do |(attr_name, attr_hash)|
|
135
|
-
attribute_to_plantuml(attr_name, attr_hash)
|
136
|
-
end.join("").sub(/\n\Z/, "")
|
137
|
-
end
|
138
|
-
|
139
|
-
def attribute_to_plantuml(attr_name, attr_hash)
|
140
|
-
<<~TEMPLATE
|
141
|
-
+#{attr_name}: #{attr_hash['type']}#{attribute_cardinality_plantuml(attr_hash['cardinality'])}
|
142
|
-
TEMPLATE
|
143
|
-
end
|
144
|
-
|
145
|
-
def attribute_cardinality_plantuml(cardinality, with_bracket = true)
|
146
|
-
return "" if cardinality.nil? ||
|
147
|
-
(cardinality["min"] == cardinality["max"] &&
|
148
|
-
cardinality["min"] == 1)
|
149
|
-
|
150
|
-
card = "#{cardinality['min']}..#{cardinality['max']}"
|
151
|
-
return card unless with_bracket
|
152
|
-
|
153
|
-
"[#{card}]"
|
154
|
-
end
|
155
|
-
|
156
|
-
def constraints_to_plantuml(constraints)
|
157
|
-
constraints ||= []
|
158
|
-
|
159
|
-
return if constraints.empty?
|
160
|
-
|
161
|
-
constraints_output = constraints.map do |constraint|
|
162
|
-
" {#{constraint}}"
|
163
|
-
end
|
164
|
-
|
165
|
-
<<~TEMPLATE
|
166
|
-
__ constraints __
|
167
|
-
#{join_as_plantuml(
|
168
|
-
*constraints_output,
|
169
|
-
)}
|
170
|
-
TEMPLATE
|
171
|
-
end
|
172
|
-
|
173
|
-
def classes_to_relations_plantuml(classes)
|
174
|
-
output_ary = classes.map do |(class_name, class_hash)|
|
175
|
-
class_hash ||= {}
|
176
|
-
relations = class_hash["relations"]
|
177
|
-
relations_to_plantuml(class_name, relations)
|
178
|
-
end
|
179
|
-
|
180
|
-
join_as_plantuml(*output_ary)
|
181
|
-
end
|
182
|
-
|
183
|
-
def relations_to_plantuml(class_name, relations)
|
184
|
-
return unless relations
|
185
|
-
|
186
|
-
output_ary = relations.map do |relation|
|
187
|
-
source = class_name || relation["source"]
|
188
|
-
relation_to_plantuml(source,
|
189
|
-
relation["target"],
|
190
|
-
relation)
|
191
|
-
end
|
192
|
-
|
193
|
-
join_as_plantuml(*output_ary)
|
194
|
-
end
|
195
|
-
|
196
|
-
def relation_arrow(relationship, relation)
|
197
|
-
[
|
198
|
-
relationship_type_to_plantuml("source",
|
199
|
-
relationship["source"]["type"]),
|
200
|
-
(relation["direction"]).to_s,
|
201
|
-
relationship_type_to_plantuml("target",
|
202
|
-
relationship["target"]["type"]),
|
203
|
-
].compact.join("-")
|
204
|
-
end
|
205
|
-
|
206
|
-
def relation_label(action)
|
207
|
-
return "" unless action
|
208
|
-
|
209
|
-
case action["direction"]
|
210
|
-
when "source"
|
211
|
-
" : < #{action['verb']}"
|
212
|
-
when "target"
|
213
|
-
" : #{action['verb']} >"
|
214
|
-
else
|
215
|
-
""
|
216
|
-
end
|
217
|
-
end
|
218
|
-
|
219
|
-
def source_arrow_end(source, relationship)
|
220
|
-
source_attribute = relationship_cardinality_to_plantuml(
|
221
|
-
relationship["source"]["attribute"],
|
222
|
-
)
|
223
|
-
[source, source_attribute].join(" ")
|
224
|
-
end
|
225
|
-
|
226
|
-
def target_arrow_end(target, relationship, action)
|
227
|
-
target_attribute = relationship_cardinality_to_plantuml(
|
228
|
-
relationship["target"]["attribute"],
|
229
|
-
)
|
230
|
-
[
|
231
|
-
[target_attribute, target].join(" "),
|
232
|
-
relation_label(action),
|
233
|
-
].join
|
234
|
-
end
|
235
|
-
|
236
|
-
def relation_association(source, target, association)
|
237
|
-
return unless association
|
238
|
-
|
239
|
-
"\n(#{source}, #{target}) . #{association}"
|
240
|
-
end
|
241
|
-
|
242
|
-
def relation_to_plantuml(source, target, relation)
|
243
|
-
relationship = relation["relationship"] || {}
|
244
|
-
relationship["source"] ||= {}
|
245
|
-
relationship["target"] ||= {}
|
246
|
-
relation_output_lines(source, target, relation, relationship)
|
247
|
-
end
|
248
|
-
|
249
|
-
def relation_output_lines(source, target, relation, relationship)
|
250
|
-
output_lines = [
|
251
|
-
source_arrow_end(source, relationship),
|
252
|
-
relation_arrow(relationship, relation),
|
253
|
-
target_arrow_end(target, relationship, relation["action"]),
|
254
|
-
relation_association(source, target, relationship["association"]),
|
255
|
-
].join(" ")
|
256
|
-
|
257
|
-
join_as_plantuml(*output_lines)
|
258
|
-
end
|
259
|
-
|
260
|
-
def relationship_type_to_plantuml(relation_end, relationship_type)
|
261
|
-
is_source = (relation_end == "source")
|
262
|
-
mappings = {
|
263
|
-
"direct" => is_source ? "<" : ">",
|
264
|
-
"inheritance" => is_source ? "<|" : "|>",
|
265
|
-
"composition" => "*",
|
266
|
-
"aggregation" => "o",
|
267
|
-
}
|
268
|
-
mappings.fetch(relationship_type, "")
|
269
|
-
end
|
270
|
-
|
271
|
-
def relationship_cardinality_to_plantuml(attribute)
|
272
|
-
attribute_name = (attribute || {}).keys.first
|
273
|
-
|
274
|
-
return unless attribute_name
|
275
|
-
|
276
|
-
attribute_hash = attribute[attribute_name] || {}
|
277
|
-
card = attribute_cardinality(attribute_hash["cardinality"])
|
278
|
-
"\"+#{attribute_name}#{card}\""
|
279
|
-
end
|
280
|
-
|
281
|
-
def attribute_cardinality(attribute_cardinality)
|
282
|
-
cardinality = ""
|
283
|
-
if attribute_cardinality
|
284
|
-
cardinality = attribute_cardinality_plantuml(
|
285
|
-
attribute_cardinality,
|
286
|
-
false,
|
287
|
-
)
|
288
|
-
cardinality = " #{cardinality}"
|
289
|
-
end
|
290
|
-
cardinality
|
291
|
-
end
|
292
|
-
|
293
|
-
def enums_to_enums_plantuml(enums)
|
294
|
-
enums ||= {}
|
295
|
-
|
296
|
-
enums.map do |(enum_name, enum_hash)|
|
297
|
-
enum_to_plantuml(enum_name, enum_hash)
|
298
|
-
end.join("\n\n")
|
299
|
-
end
|
300
|
-
|
301
|
-
def enum_to_plantuml(enum_name, enum_hash)
|
302
|
-
enum_hash ||= {}
|
303
|
-
|
304
|
-
<<~TEMPLATE
|
305
|
-
enum #{enum_name}#{model_stereotype_to_plantuml(enum_hash['type'])} {
|
306
|
-
#{join_as_plantuml(enum_values_to_plantuml(enum_hash['values']))}
|
307
|
-
}
|
308
|
-
TEMPLATE
|
309
|
-
end
|
310
|
-
|
311
|
-
def model_stereotype_to_plantuml(model_stereotype)
|
312
|
-
return "" unless model_stereotype
|
313
|
-
|
314
|
-
" <<#{model_stereotype}>>"
|
315
|
-
end
|
316
|
-
|
317
|
-
def enum_values_to_plantuml(enum_values)
|
318
|
-
output_ary = enum_values.map do |(enum_value, _enum_value_hash)|
|
319
|
-
" #{enum_value}"
|
320
|
-
end
|
321
|
-
|
322
|
-
join_as_plantuml(*output_ary)
|
323
|
-
end
|
324
|
-
|
325
|
-
def groups_to_plantuml(groups)
|
326
|
-
groups ||= []
|
327
|
-
return if groups.empty?
|
328
|
-
|
329
|
-
groups.reduce("") do |output, group|
|
330
|
-
output += "\ntogether {\n"
|
331
|
-
group.each do |class_name|
|
332
|
-
output += "\nclass #{class_name}\n"
|
333
|
-
end
|
334
|
-
output += "\n}\n"
|
335
|
-
output
|
336
|
-
end
|
337
|
-
end
|
338
|
-
|
339
|
-
def diagram_options_to_plantuml(diagram_options)
|
340
|
-
diagram_options ||= []
|
341
|
-
return if diagram_options.empty?
|
342
|
-
|
343
|
-
"#{diagram_options.join("\n")}\n"
|
344
|
-
end
|
345
|
-
|
346
|
-
def bottom_to_plantuml(bottom)
|
347
|
-
bottom ||= []
|
348
|
-
return if bottom.empty?
|
349
|
-
|
350
|
-
"#{bottom.join("\n")}\n"
|
351
|
-
end
|
352
|
-
|
353
|
-
def format_hidden_class(accum, fidelity_classes, class_hash)
|
354
|
-
return accum if class_hash["relations"].nil?
|
355
|
-
|
356
|
-
class_hash["relations"].each_with_object(accum) do |relation, acc|
|
357
|
-
format_source_target_relation(relation, fidelity_classes, acc)
|
358
|
-
format_association_relation(relation, fidelity_classes, acc)
|
359
|
-
end
|
360
|
-
end
|
361
|
-
|
362
|
-
def format_source_target_relation(relation, fidelity_classes, acc)
|
363
|
-
%w[source target].each do |type|
|
364
|
-
next unless relation[type] && !fidelity_classes.key?(relation[type])
|
365
|
-
|
366
|
-
acc.merge!(relation[type] => true)
|
367
|
-
end
|
368
|
-
end
|
369
|
-
|
370
|
-
def format_association_relation(relation, fidelity_classes, acc)
|
371
|
-
return unless relation["relationship"] &&
|
372
|
-
relation["relationship"]["association"]
|
373
|
-
|
374
|
-
association = relation["relationship"]["association"]
|
375
|
-
return unless association && !fidelity_classes.key?(association)
|
376
|
-
|
377
|
-
acc.merge!(association => true)
|
378
|
-
end
|
379
|
-
|
380
|
-
def hide_other_classes(fidelity)
|
381
|
-
return "" if fidelity.nil? || fidelity["classes"].nil?
|
382
|
-
|
383
|
-
output = ""
|
384
|
-
hidden_classes = fidelity["classes"]
|
385
|
-
.reduce({}) do |acc, (_class_name, class_hash)|
|
386
|
-
format_hidden_class(acc, fidelity["classes"], class_hash)
|
387
|
-
end
|
388
|
-
|
389
|
-
hidden_classes.each_key do |hidden_class_name|
|
390
|
-
output += "\nhide #{hidden_class_name}\n"
|
391
|
-
end
|
392
|
-
output
|
393
|
-
end
|
394
|
-
|
395
|
-
def fidelity_to_plantuml(fidelity)
|
396
|
-
return "" if fidelity.nil?
|
397
|
-
|
398
|
-
output = ""
|
399
|
-
output += hide_other_classes(fidelity) if fidelity["hideOtherClasses"]
|
400
|
-
output += "\nhide members\n" if fidelity["hideMembers"]
|
401
|
-
output
|
402
|
-
end
|
403
|
-
|
404
|
-
def empty?(yml, prop)
|
405
|
-
yml[prop].nil? || yml[prop].length.zero?
|
406
|
-
end
|
407
|
-
end
|
408
|
-
end
|
409
|
-
end
|
@@ -1,143 +0,0 @@
|
|
1
|
-
module Metanorma
|
2
|
-
module Standoc
|
3
|
-
class PlantUMLBlockMacroBackend
|
4
|
-
def self.plantuml_installed?
|
5
|
-
unless which("plantuml")
|
6
|
-
raise "PlantUML not installed"
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
def self.plantuml_bin
|
11
|
-
if Gem.win_platform? || which("plantumlc")
|
12
|
-
"plantumlc"
|
13
|
-
else
|
14
|
-
"plantuml"
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.run(umlfile, outfile, fmt)
|
19
|
-
valid_formats = %w[png svg eps]
|
20
|
-
unless valid_formats.include?(fmt)
|
21
|
-
raise ArgumentError, "Invalid format: #{fmt}. Allowed formats are: #{valid_formats.join(', ')}"
|
22
|
-
end
|
23
|
-
system(plantuml_bin, umlfile.path, "-t#{fmt}") or
|
24
|
-
(warn $? and return false)
|
25
|
-
i = 0
|
26
|
-
until !Gem.win_platform? || File.exist?(outfile) || i == 15
|
27
|
-
sleep(1)
|
28
|
-
i += 1
|
29
|
-
end
|
30
|
-
File.exist?(outfile)
|
31
|
-
end
|
32
|
-
|
33
|
-
# if no :imagesdir: leave image file in plantuml
|
34
|
-
# sleep need for windows because dot works in separate process and
|
35
|
-
# plantuml process may finish earlier then dot, as result png file
|
36
|
-
# maybe not created yet after plantuml finish
|
37
|
-
#
|
38
|
-
# # Warning: metanorma/metanorma-standoc#187
|
39
|
-
# Windows Ruby 2.4 will crash if a Tempfile is "mv"ed.
|
40
|
-
# This is why we need to copy and then unlink.
|
41
|
-
def self.generate_file(parent, reader)
|
42
|
-
ldir, imagesdir, fmt = generate_file_prep(parent)
|
43
|
-
umlfile, outfile = save_plantuml parent, reader, ldir, fmt
|
44
|
-
run(umlfile, outfile, fmt) or
|
45
|
-
raise "No image output from PlantUML (#{umlfile}, #{outfile})!"
|
46
|
-
umlfile.unlink
|
47
|
-
absolute_path, relative_path = path_prep(ldir, imagesdir)
|
48
|
-
filename = File.basename(outfile.to_s)
|
49
|
-
FileUtils.cp(outfile, absolute_path) and outfile.unlink
|
50
|
-
#imagesdir ? filename : File.join(path, filename)
|
51
|
-
File.join(relative_path, filename)
|
52
|
-
end
|
53
|
-
|
54
|
-
def self.generate_file_prep(parent)
|
55
|
-
ldir = localdir(parent)
|
56
|
-
imagesdir = parent.document.attr("imagesdir")
|
57
|
-
fmt = parent.document.attr("plantuml-image-format")&.strip&.downcase ||
|
58
|
-
"png"
|
59
|
-
[ldir, imagesdir, fmt]
|
60
|
-
end
|
61
|
-
|
62
|
-
def self.localdir(parent)
|
63
|
-
ret = Metanorma::Utils::localdir(parent.document)
|
64
|
-
File.writable?(ret) or
|
65
|
-
raise "Destination directory #{ret} not writable for PlantUML!"
|
66
|
-
ret
|
67
|
-
end
|
68
|
-
|
69
|
-
def self.path_prep(localdir, imagesdir)
|
70
|
-
#path = Pathname.new(localdir) + (imagesdir || "plantuml")
|
71
|
-
path = Pathname.new(File.join(localdir, "_plantuml_images"))
|
72
|
-
sourcepath = imagesdir ? File.join(localdir, imagesdir) : localdir
|
73
|
-
path.mkpath
|
74
|
-
File.writable?(path) or
|
75
|
-
raise "Destination path #{path} not writable for PlantUML!"
|
76
|
-
[path, Pathname.new(path).relative_path_from(Pathname.new(sourcepath)).to_s]
|
77
|
-
end
|
78
|
-
|
79
|
-
def self.save_plantuml(_parent, reader, _localdir, fmt)
|
80
|
-
src = prep_source(reader)
|
81
|
-
/^@startuml (?<fn>[^\n]+)\n/ =~ src
|
82
|
-
Tempfile.open(["plantuml", ".pml"], encoding: "utf-8") do |f|
|
83
|
-
f.write(src)
|
84
|
-
[f, File.join(File.dirname(f.path),
|
85
|
-
"#{fn || File.basename(f.path, '.pml')}.#{fmt}")]
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def self.prep_source(reader)
|
90
|
-
src = reader.source
|
91
|
-
reader.lines.first.sub(/(?<!\s)\s+$/, "").match /^@startuml($| )/ or
|
92
|
-
src = "@startuml\n#{src}\n@enduml\n"
|
93
|
-
%r{@enduml\s*$}m.match?(src) or
|
94
|
-
raise "@startuml without matching @enduml in PlantUML!"
|
95
|
-
src
|
96
|
-
end
|
97
|
-
|
98
|
-
def self.generate_attrs(attrs)
|
99
|
-
%w(id align float title role width height alt)
|
100
|
-
.inject({}) do |memo, key|
|
101
|
-
memo[key] = attrs[key] if attrs.has_key? key
|
102
|
-
memo
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
# https://stackoverflow.com/questions/2108727/which-in-ruby-checking-if-program-exists-in-path-from-ruby
|
107
|
-
def self.which(cmd)
|
108
|
-
exts = ENV["PATHEXT"] ? ENV["PATHEXT"].split(";") : [""]
|
109
|
-
ENV["PATH"].split(File::PATH_SEPARATOR).each do |path|
|
110
|
-
exts.each do |ext|
|
111
|
-
exe = File.join(path, "#{cmd}#{ext}")
|
112
|
-
return exe if File.executable?(exe) && !File.directory?(exe)
|
113
|
-
end
|
114
|
-
end
|
115
|
-
nil
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
class PlantUMLBlockMacro < Asciidoctor::Extensions::BlockProcessor
|
120
|
-
use_dsl
|
121
|
-
named :plantuml
|
122
|
-
on_context :literal
|
123
|
-
parse_content_as :raw
|
124
|
-
|
125
|
-
def abort(parent, reader, attrs, msg)
|
126
|
-
warn msg
|
127
|
-
attrs["language"] = "plantuml"
|
128
|
-
create_listing_block parent, reader.source,
|
129
|
-
(attrs.reject { |k, _v| k == 1 })
|
130
|
-
end
|
131
|
-
|
132
|
-
def process(parent, reader, attrs)
|
133
|
-
PlantUMLBlockMacroBackend.plantuml_installed?
|
134
|
-
filename = PlantUMLBlockMacroBackend.generate_file(parent, reader)
|
135
|
-
through_attrs = PlantUMLBlockMacroBackend.generate_attrs attrs
|
136
|
-
through_attrs["target"] = filename
|
137
|
-
create_image_block parent, through_attrs
|
138
|
-
rescue StandardError => e
|
139
|
-
abort(parent, reader, attrs, e.message)
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
|
2
|
-
[yaml2text,<%= model_path %>,definition]
|
3
|
-
----
|
4
|
-
|
5
|
-
=== {definition.name | default: "<%= file_name %>"}
|
6
|
-
{definition.definition}
|
7
|
-
|
8
|
-
{% if definition.attributes %}
|
9
|
-
.{definition.name | default: "<%= file_name %>"} attributes
|
10
|
-
|===
|
11
|
-
|Name |Definition |Mandatory/ Optional/ Conditional |Max Occur |Data Type
|
12
|
-
|
13
|
-
{definition.attributes.*,key,EOK}
|
14
|
-
|{key} |{% if definition.attributes[key].definition %}{{ definition.attributes[key].definition }}{% else %}TODO: enum {{ key }}'s definition{% endif %} |{% if definition.attributes[key].cardinality.min == 0 %}O{% else %}M{% endif %} |{% if definition.attributes[key].cardinality.max == "*" %}N{% else %}1{% endif %} |{% if definition.attributes[key].origin %}<<{{ definition.attributes[key].origin }}>>{% endif %} `{definition.attributes[key].type}`
|
15
|
-
{EOK}
|
16
|
-
|===
|
17
|
-
{% endif %}
|
18
|
-
|
19
|
-
{% if definition['values'] %}
|
20
|
-
.{definition.name | default: "<%= file_name %>"} values
|
21
|
-
|===
|
22
|
-
|Name |Definition
|
23
|
-
|
24
|
-
{definition['values'].*,key,EOK}
|
25
|
-
|{key} |{definition['values'][key].definition}
|
26
|
-
{EOK}
|
27
|
-
|===
|
28
|
-
{% endif %}
|
29
|
-
|
30
|
-
----
|
@@ -1,20 +0,0 @@
|
|
1
|
-
[plantuml,title=<%= diagram_caption %>]
|
2
|
-
....
|
3
|
-
@startuml
|
4
|
-
|
5
|
-
<%= diagram_options_yml_to_plantuml %>
|
6
|
-
|
7
|
-
<%= class_groups_yml_to_plantuml %>
|
8
|
-
|
9
|
-
<%= imports_yml_to_plantuml %>
|
10
|
-
|
11
|
-
<%= class_defs_yml_to_plantuml %>
|
12
|
-
|
13
|
-
<%= class_relations_yml_to_plantuml %>
|
14
|
-
|
15
|
-
<%= fidelity_yml_to_plantuml %>
|
16
|
-
|
17
|
-
<%= bottom_yml_to_plantuml %>
|
18
|
-
|
19
|
-
@enduml
|
20
|
-
....
|