diagrammatron 0.4.3 → 0.5.1
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/bin/diagrammatron-edges +28 -42
- data/bin/diagrammatron-get +4 -5
- data/bin/diagrammatron-nodes +18 -40
- data/bin/diagrammatron-place +20 -21
- data/bin/diagrammatron-prune +15 -7
- data/bin/diagrammatron-render +22 -20
- data/bin/diagrammatron-schema +107 -0
- data/bin/diagrammatron-subset +188 -0
- data/bin/dot_json2diagrammatron +14 -25
- data/lib/common.rb +50 -2
- data/lib/edges.yaml +45 -0
- data/lib/nodes.yaml +36 -0
- data/lib/place.yaml +65 -0
- data/lib/render.yaml +111 -0
- data/lib/subset.yaml +55 -0
- data/lib/subsets.rb +147 -0
- metadata +37 -6
@@ -0,0 +1,107 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Copyright © 2023 Ismo Kärkkäinen
|
5
|
+
# Licensed under Universal Permissive License. See LICENSE.txt.
|
6
|
+
|
7
|
+
require_relative '../lib/common'
|
8
|
+
require 'optparse'
|
9
|
+
require 'yaml'
|
10
|
+
require 'json'
|
11
|
+
|
12
|
+
def convert(result, format)
|
13
|
+
case format
|
14
|
+
when :json then JSON.generate(result)
|
15
|
+
when :yaml then YAML.dump(result)
|
16
|
+
when :prettyjson then JSON.pretty_generate(result)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def main
|
21
|
+
output = nil
|
22
|
+
format = :json
|
23
|
+
package = :bare
|
24
|
+
ENV['POSIXLY_CORRECT'] = '1' # Leaves patterns as they are.
|
25
|
+
parser = OptionParser.new do |opts|
|
26
|
+
opts.summary_indent = ' '
|
27
|
+
opts.summary_width = 20
|
28
|
+
opts.banner = 'Usage: diagrammatron-schema [options] schema-name ...'
|
29
|
+
opts.separator ''
|
30
|
+
opts.separator 'Options:'
|
31
|
+
opts.on('-f', '--format FMT', 'Output schema format (json, yaml, pretty).') do |fmt|
|
32
|
+
case fmt.upcase
|
33
|
+
when 'JSON' then format = :json
|
34
|
+
when 'YAML' then format = :yaml
|
35
|
+
when 'PRETTY' then format = :prettyjson
|
36
|
+
else
|
37
|
+
format = fmt
|
38
|
+
end
|
39
|
+
end
|
40
|
+
opts.on('-p', '--package PKG', 'Wrap schema(s) in given way.') do |pkg|
|
41
|
+
case pkg.upcase
|
42
|
+
when 'OBJECT' then package = :object
|
43
|
+
when 'ARRAY' then package = :array
|
44
|
+
when 'BARE' then package = :bare
|
45
|
+
else
|
46
|
+
package = pkg
|
47
|
+
end
|
48
|
+
end
|
49
|
+
opts.on('-o', '--output FILE', 'Output file name. Write to stdout if not given.') do |filename|
|
50
|
+
output = filename
|
51
|
+
end
|
52
|
+
opts.on('-l', '--list', 'List available schemas and exit.') do
|
53
|
+
$stdout.puts list_schemas.sort.join("\n")
|
54
|
+
exit 0
|
55
|
+
end
|
56
|
+
opts.on('-h', '--help', 'Print this help and exit.') do
|
57
|
+
$stdout.puts %(#{opts}
|
58
|
+
Outputs the given schema files.
|
59
|
+
Formats are: JSON, YAML, pretty for prettified JSON.
|
60
|
+
Packages are:
|
61
|
+
object: Output schemas as an object with name to schema mapping.
|
62
|
+
array: Output schemas as an array in the order given on the command-line
|
63
|
+
bare: Output schemas in the specified order as they are. The default.
|
64
|
+
)
|
65
|
+
exit 0
|
66
|
+
end
|
67
|
+
end
|
68
|
+
parser.parse! ARGV
|
69
|
+
|
70
|
+
aargh("Unknown format: #{format}", 1) unless format.is_a? Symbol
|
71
|
+
case package
|
72
|
+
when :bare, :array then out = []
|
73
|
+
when :object then out = {}
|
74
|
+
else
|
75
|
+
return aargh("Unknown package: #{package}", 1) unless package.is_a? Symbol
|
76
|
+
end
|
77
|
+
|
78
|
+
ARGV.each do |name|
|
79
|
+
s = load_schema(name)
|
80
|
+
if out.is_a? Array
|
81
|
+
out.push(s)
|
82
|
+
else
|
83
|
+
out[name] = s
|
84
|
+
end
|
85
|
+
rescue Errno::ENOENT
|
86
|
+
aargh "No such schema: #{name}", 2
|
87
|
+
rescue StandardError => e
|
88
|
+
aargh "#{e}\nInternal error: #{name}", 3
|
89
|
+
end
|
90
|
+
|
91
|
+
if output.nil?
|
92
|
+
fp = $stdout
|
93
|
+
else
|
94
|
+
fp = File.new(output, 'w')
|
95
|
+
end
|
96
|
+
if package == :bare
|
97
|
+
out.each do |item|
|
98
|
+
fp.puts(convert(item, format))
|
99
|
+
end
|
100
|
+
else
|
101
|
+
fp.puts(convert(out, format))
|
102
|
+
end
|
103
|
+
fp.close
|
104
|
+
0
|
105
|
+
end
|
106
|
+
|
107
|
+
exit(main) if (defined? $unit_test).nil?
|
@@ -0,0 +1,188 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Copyright © 2023 Ismo Kärkkäinen
|
5
|
+
# Licensed under Universal Permissive License. See LICENSE.txt.
|
6
|
+
|
7
|
+
require_relative '../lib/common'
|
8
|
+
require_relative '../lib/subsets'
|
9
|
+
require 'optparse'
|
10
|
+
require 'set'
|
11
|
+
|
12
|
+
|
13
|
+
class Item
|
14
|
+
@@counter = 0
|
15
|
+
attr_reader :item, :ids
|
16
|
+
|
17
|
+
def initialize(item, label2id = {})
|
18
|
+
@item = item
|
19
|
+
@ids = [ @@counter ]
|
20
|
+
@@counter += 1
|
21
|
+
# This silently removes edges that have no valid end-point.
|
22
|
+
item.fetch('between', []).each { |x| @ids.push(label2id.fetch(x, -1)) }
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.reset
|
26
|
+
@@counter = 0
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def work_copy(src)
|
31
|
+
nodes = src.fetch('nodes', []).map { |n| Item.new(n) }
|
32
|
+
label2id = {}
|
33
|
+
nodes.each { |x| label2id[x.item['label']] = x.ids.first }
|
34
|
+
edges = src.fetch('edges', []).map { |e| Item.new(e, label2id) }
|
35
|
+
{
|
36
|
+
edges: edges,
|
37
|
+
nodes: nodes
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
def prepare_output(doc, work, chosen)
|
42
|
+
%i[edges nodes].each do |s|
|
43
|
+
work[s].select! do |x|
|
44
|
+
(x.ids.index { |id| !chosen.member?(id) }).nil?
|
45
|
+
end
|
46
|
+
doc[s.to_s] = work[s].map(&:item)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def gather_set(work, rules, current)
|
51
|
+
r = rules['sets'].fetch(current, nil)
|
52
|
+
return aargh("Undefined set: #{current}", 9) if r.nil?
|
53
|
+
result = Set.new
|
54
|
+
%i[nodes edges].each do |category|
|
55
|
+
work[category].each do |item|
|
56
|
+
if match_item(item.item, r.fetch(category, {}))
|
57
|
+
result.add(item.ids.first)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
result
|
62
|
+
end
|
63
|
+
|
64
|
+
def gather(work, rules, current, above, set_cache)
|
65
|
+
e = rules['sets'].fetch(current, nil)
|
66
|
+
unless e.nil?
|
67
|
+
set = set_cache.fetch(current, nil)
|
68
|
+
return set unless set.nil?
|
69
|
+
# Evaluate needed set, store, and return it.
|
70
|
+
set = gather_set(work, rules, current)
|
71
|
+
set_cache[current] = set # Error may end up in cache, not a problem.
|
72
|
+
return set
|
73
|
+
end
|
74
|
+
return aargh("Loop in expressions for #{current}: #{above.reverse.join("\n")}", 8) if above.include?(current)
|
75
|
+
e = rules['expressions'].fetch(current, nil)
|
76
|
+
return aargh("Undefined expression: #{current}", 7) if e.nil?
|
77
|
+
above.push(current)
|
78
|
+
result = gather(work, rules, e.first, above, set_cache)
|
79
|
+
return result unless result.is_a?(Set)
|
80
|
+
(1...e.size).step(2) do |k|
|
81
|
+
op = e[k]
|
82
|
+
id = e[k + 1]
|
83
|
+
s = gather(work, rules, id, above, set_cache)
|
84
|
+
return s unless s.is_a?(Set)
|
85
|
+
case op
|
86
|
+
when :plus then result += s
|
87
|
+
when :minus then result -= s
|
88
|
+
else
|
89
|
+
return aargh("Unsupported operator: #{op}", 100)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
above.pop
|
93
|
+
result
|
94
|
+
end
|
95
|
+
|
96
|
+
def main
|
97
|
+
input_output_schema = 'nodes'
|
98
|
+
input = nil
|
99
|
+
output = nil
|
100
|
+
selected = nil
|
101
|
+
ENV['POSIXLY_CORRECT'] = '1'
|
102
|
+
parser = OptionParser.new do |opts|
|
103
|
+
opts.summary_indent = ' '
|
104
|
+
opts.summary_width = 20
|
105
|
+
opts.banner = 'Usage: diagrammatron-subset [options] rule-file-names...'
|
106
|
+
opts.separator ''
|
107
|
+
opts.separator 'Options:'
|
108
|
+
opts.on('-i', '--input FILE', 'Input file name. Read from stdin if not given.') do |filename|
|
109
|
+
input = filename
|
110
|
+
end
|
111
|
+
opts.on('-o', '--output FILE', 'Output file name. Written to stdout if not given.') do |filename|
|
112
|
+
output = filename
|
113
|
+
end
|
114
|
+
opts.on('-s', '--select NAME', 'Select expression or subset NAME result.') do |name|
|
115
|
+
selected = name
|
116
|
+
end
|
117
|
+
opts.on('-h', '--help', 'Print this help and exit.') do
|
118
|
+
$stdout.puts %(#{opts}
|
119
|
+
Rule files can specify named subset selection rules and named expressions on
|
120
|
+
how to combine the subsets when determining which nodes and edges will form the
|
121
|
+
diagram.
|
122
|
+
|
123
|
+
Subset selection rules can apply to nodes only, edges only, or both. The rules
|
124
|
+
give for a field name an array of strings or patterns. If a node or edge
|
125
|
+
matches any of the rules, it belongs to the subset.
|
126
|
+
|
127
|
+
Expressions can refer to the subset or expression names and use operations to
|
128
|
+
form more complex subsets. In the simplest form, they just are a subset name.
|
129
|
+
Operations are a + b to add elements of b and a - b to drop elements of b. If
|
130
|
+
expression and subset have the same name, identifier refers to subset.
|
131
|
+
|
132
|
+
The select option gives the name of the expression or subset to use.
|
133
|
+
|
134
|
+
Edges to removed nodes are removed. Nodes with all edges removed are retained.
|
135
|
+
Output is the input file with remaining nodes and edges.
|
136
|
+
|
137
|
+
Input and output YAML file schema is returned by:
|
138
|
+
diagrammatron-schema #{input_output_schema}
|
139
|
+
|
140
|
+
Rule YAML file schema is returned by:
|
141
|
+
diagrammatron-schema subset
|
142
|
+
|
143
|
+
Note that input schema is minimal and does not restrict running this program
|
144
|
+
at a later stage in the pipeline after other tools have added their fields.
|
145
|
+
You can refer to fields outside the schema.
|
146
|
+
)
|
147
|
+
exit 0
|
148
|
+
end
|
149
|
+
end
|
150
|
+
parser.parse! ARGV
|
151
|
+
|
152
|
+
if selected.nil?
|
153
|
+
return aargh('Must select an expression or subset to use for output.', 2)
|
154
|
+
end
|
155
|
+
|
156
|
+
rules = {}
|
157
|
+
ARGV.each do |filename|
|
158
|
+
r = load_verified(filename, 'subset')
|
159
|
+
return 5 if r.nil?
|
160
|
+
return 6 unless check_rules(r, filename)
|
161
|
+
merge_any(r) # The 'any' field exists to avoid duplicating rules by hand.
|
162
|
+
merge_rules(rules, r)
|
163
|
+
end
|
164
|
+
|
165
|
+
if rules.fetch('sets', {}).key? selected
|
166
|
+
# Refers directly to subset so other expressions do not matter.
|
167
|
+
rules['expressions'] = { selected => selected }
|
168
|
+
elsif !rules.fetch('expressions', {}).key? selected
|
169
|
+
return aargh("Selected #{selected} is not expression or subset name.", 2)
|
170
|
+
end
|
171
|
+
|
172
|
+
doc = load_verified(input, input_output_schema)
|
173
|
+
return 2 if doc.nil?
|
174
|
+
|
175
|
+
begin
|
176
|
+
work = work_copy(doc)
|
177
|
+
return 3 if work.nil?
|
178
|
+
rescue StandardError
|
179
|
+
return aargh('Error processing input.', 3)
|
180
|
+
end
|
181
|
+
|
182
|
+
chosen = gather(work, rules, selected, [], {})
|
183
|
+
return chosen unless chosen.is_a?(Set)
|
184
|
+
prepare_output(doc, work, chosen)
|
185
|
+
save_verified(output, doc, 4, input_output_schema)
|
186
|
+
end
|
187
|
+
|
188
|
+
exit(main) if (defined? $unit_test).nil?
|
data/bin/dot_json2diagrammatron
CHANGED
@@ -1,14 +1,11 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
# Copyright © 2021
|
4
|
+
# Copyright © 2021-2023 Ismo Kärkkäinen
|
5
5
|
# Licensed under Universal Permissive License. See LICENSE.txt.
|
6
6
|
|
7
7
|
require_relative '../lib/common'
|
8
8
|
require 'optparse'
|
9
|
-
require 'yaml'
|
10
|
-
require 'json'
|
11
|
-
require 'pathname'
|
12
9
|
|
13
10
|
|
14
11
|
def convert(src)
|
@@ -63,10 +60,10 @@ def convert(src)
|
|
63
60
|
{ 'edges' => edges, 'nodes' => nodes }
|
64
61
|
end
|
65
62
|
|
66
|
-
$INPUT = nil
|
67
|
-
$OUTPUT = nil
|
68
|
-
|
69
63
|
def main
|
64
|
+
input = nil
|
65
|
+
output = nil
|
66
|
+
output_schema = 'nodes'
|
70
67
|
parser = OptionParser.new do |opts|
|
71
68
|
opts.summary_indent = ' '
|
72
69
|
opts.summary_width = 20
|
@@ -74,24 +71,28 @@ def main
|
|
74
71
|
opts.separator ''
|
75
72
|
opts.separator 'Options:'
|
76
73
|
opts.on('-i', '--input FILE', 'Input file name. Read from stdin if not given.') do |filename|
|
77
|
-
|
74
|
+
input = filename
|
78
75
|
end
|
79
76
|
opts.on('-o', '--output FILE', 'Output file name. Write to stdout if not given.') do |filename|
|
80
|
-
|
77
|
+
output = filename
|
81
78
|
end
|
82
79
|
opts.on('-h', '--help', 'Print this help and exit.') do
|
83
80
|
$stdout.puts opts
|
84
81
|
$stdout.puts %(
|
85
82
|
Output is a YAML file with "name" used as "label" and "shape" used as is
|
86
|
-
for nodes. For edges "tail" and "head" are used as the first and second
|
87
|
-
of "between" with the "name" as the identifier. Compound objects
|
83
|
+
for nodes. For edges "tail" and "head" are used as the first and second
|
84
|
+
element of "between" with the "name" as the identifier. Compound objects
|
85
|
+
are ignored.
|
86
|
+
|
87
|
+
Output YAML file schema is returned by:
|
88
|
+
diagrammatron-schema #{output_schema}
|
88
89
|
)
|
89
90
|
exit 0
|
90
91
|
end
|
91
92
|
end
|
92
93
|
parser.parse! ARGV
|
93
94
|
|
94
|
-
doc = load_source
|
95
|
+
doc = load_source(input)
|
95
96
|
exit(2) if doc.nil?
|
96
97
|
|
97
98
|
begin
|
@@ -101,19 +102,7 @@ of "between" with the "name" as the identifier. Compound objects are ignored.
|
|
101
102
|
end
|
102
103
|
exit(3) if out.nil?
|
103
104
|
|
104
|
-
|
105
|
-
if $OUTPUT.nil?
|
106
|
-
$stdout.puts YAML.dump(out)
|
107
|
-
else
|
108
|
-
fp = Pathname.new $OUTPUT
|
109
|
-
fp.open('w') do |f|
|
110
|
-
f.puts YAML.dump(out)
|
111
|
-
end
|
112
|
-
end
|
113
|
-
rescue StandardError => e
|
114
|
-
aargh("#{e}\nFailed to write output: #{$OUTPUT}")
|
115
|
-
exit 4
|
116
|
-
end
|
105
|
+
save_verified(output, pout, 4, output_schema)
|
117
106
|
end
|
118
107
|
|
119
108
|
main if (defined? $unit_test).nil?
|
data/lib/common.rb
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Copyright © 2021
|
3
|
+
# Copyright © 2021-2023 Ismo Kärkkäinen
|
4
4
|
# Licensed under Universal Permissive License. See LICENSE.txt.
|
5
5
|
|
6
|
+
require 'json_schemer'
|
7
|
+
require 'yaml'
|
8
|
+
require 'set'
|
9
|
+
|
10
|
+
|
6
11
|
def aargh(message, return_value = nil)
|
7
12
|
message = (message.map &(:to_s)).join("\n") if message.is_a? Array
|
8
13
|
$stderr.puts message
|
@@ -20,9 +25,41 @@ end
|
|
20
25
|
def load_source_hash(input)
|
21
26
|
src = load_source(input)
|
22
27
|
unless src.nil?
|
23
|
-
return aargh(
|
28
|
+
return aargh("#{input} is not a simple mapping.") unless src.is_a? Hash
|
29
|
+
end
|
30
|
+
src
|
31
|
+
end
|
32
|
+
|
33
|
+
def list_schemas
|
34
|
+
(Dir.entries(File.dirname(__FILE__)).select { |name| name.upcase.end_with?('.YAML') }).map { |name| name[0, name.size - 5] }
|
35
|
+
end
|
36
|
+
|
37
|
+
def load_schema(schema_name)
|
38
|
+
YAML.safe_load_file(File.join(File.dirname(__FILE__), "#{schema_name}.yaml"))
|
39
|
+
end
|
40
|
+
|
41
|
+
def make_schemer(schema, reading)
|
42
|
+
JSONSchemer.schema(JSON.generate(schema),
|
43
|
+
meta_schema: 'https://json-schema.org/draft/2020-12/schema',
|
44
|
+
insert_property_defaults: reading)
|
45
|
+
end
|
46
|
+
|
47
|
+
def load_verified(input, schema_name)
|
48
|
+
src = load_source(input)
|
49
|
+
unless src.nil?
|
50
|
+
s = load_schema(schema_name)
|
51
|
+
schemer = make_schemer(s, true)
|
52
|
+
errs = schemer.validate(src).to_a
|
53
|
+
unless errs.empty?
|
54
|
+
aargh (errs.map { |e| e['error'] }).join("\n")
|
55
|
+
src = nil
|
56
|
+
end
|
24
57
|
end
|
25
58
|
src
|
59
|
+
rescue Errno::ENOENT
|
60
|
+
aargh "Could not load #{schema_name}"
|
61
|
+
rescue StandardError => e
|
62
|
+
aargh "Internal error: #{e}\n#{e.backtrace.join("\n")}\nFailed to read #{schema_name}"
|
26
63
|
end
|
27
64
|
|
28
65
|
def dump_result(output, doc, error_return)
|
@@ -38,3 +75,14 @@ def dump_result(output, doc, error_return)
|
|
38
75
|
rescue StandardError => e
|
39
76
|
aargh([ e, "Failed to write output: #{output || 'stdout'}" ], error_return)
|
40
77
|
end
|
78
|
+
|
79
|
+
def save_verified(output, doc, error_return, schema_name)
|
80
|
+
s = load_schema(schema_name)
|
81
|
+
schemer = make_schemer(s, false)
|
82
|
+
errs = schemer.validate(doc).to_a
|
83
|
+
unless errs.empty?
|
84
|
+
aargh (errs.map { |e| e['error'] }).join("\n")
|
85
|
+
return error_return
|
86
|
+
end
|
87
|
+
dump_result(output, YAML.dump(doc, line_width: 1_000_000), error_return)
|
88
|
+
end
|
data/lib/edges.yaml
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
type: object
|
2
|
+
properties:
|
3
|
+
edges:
|
4
|
+
type: array
|
5
|
+
minItems: 0
|
6
|
+
default: []
|
7
|
+
items:
|
8
|
+
$ref: "#/$defs/Edge"
|
9
|
+
nodes:
|
10
|
+
type: array
|
11
|
+
minItems: 0
|
12
|
+
default: []
|
13
|
+
items:
|
14
|
+
$ref: "#/$defs/Node"
|
15
|
+
additionalProperties: true
|
16
|
+
$defs:
|
17
|
+
Node:
|
18
|
+
type: object
|
19
|
+
required:
|
20
|
+
- label
|
21
|
+
- sid
|
22
|
+
- xo
|
23
|
+
- yo
|
24
|
+
properties:
|
25
|
+
label:
|
26
|
+
type: string
|
27
|
+
sid:
|
28
|
+
type: integer
|
29
|
+
xo:
|
30
|
+
type: integer
|
31
|
+
yo:
|
32
|
+
type: integer
|
33
|
+
additionalProperties: true
|
34
|
+
Edge:
|
35
|
+
type: object
|
36
|
+
required:
|
37
|
+
- between
|
38
|
+
properties:
|
39
|
+
between:
|
40
|
+
type: array
|
41
|
+
items:
|
42
|
+
type: string
|
43
|
+
minItems: 2
|
44
|
+
maxItems: 2
|
45
|
+
additionalProperties: true
|
data/lib/nodes.yaml
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
type: object
|
2
|
+
properties:
|
3
|
+
edges:
|
4
|
+
type: array
|
5
|
+
minItems: 0
|
6
|
+
default: []
|
7
|
+
items:
|
8
|
+
$ref: "#/$defs/Edge"
|
9
|
+
nodes:
|
10
|
+
type: array
|
11
|
+
minItems: 0
|
12
|
+
default: []
|
13
|
+
items:
|
14
|
+
$ref: "#/$defs/Node"
|
15
|
+
additionalProperties: true
|
16
|
+
$defs:
|
17
|
+
Node:
|
18
|
+
type: object
|
19
|
+
required:
|
20
|
+
- label
|
21
|
+
properties:
|
22
|
+
label:
|
23
|
+
type: string
|
24
|
+
additionalProperties: true
|
25
|
+
Edge:
|
26
|
+
type: object
|
27
|
+
required:
|
28
|
+
- between
|
29
|
+
properties:
|
30
|
+
between:
|
31
|
+
type: array
|
32
|
+
items:
|
33
|
+
type: string
|
34
|
+
minItems: 2
|
35
|
+
maxItems: 2
|
36
|
+
additionalProperties: true
|
data/lib/place.yaml
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
type: object
|
2
|
+
properties:
|
3
|
+
edges:
|
4
|
+
type: array
|
5
|
+
minItems: 0
|
6
|
+
default: []
|
7
|
+
items:
|
8
|
+
$ref: "#/$defs/Edge"
|
9
|
+
nodes:
|
10
|
+
type: array
|
11
|
+
minItems: 0
|
12
|
+
default: []
|
13
|
+
items:
|
14
|
+
$ref: "#/$defs/Node"
|
15
|
+
additionalProperties: true
|
16
|
+
$defs:
|
17
|
+
Node:
|
18
|
+
type: object
|
19
|
+
required:
|
20
|
+
- label
|
21
|
+
- sid
|
22
|
+
- xo
|
23
|
+
- yo
|
24
|
+
properties:
|
25
|
+
label:
|
26
|
+
type: string
|
27
|
+
sid:
|
28
|
+
type: integer
|
29
|
+
xo:
|
30
|
+
type: integer
|
31
|
+
yo:
|
32
|
+
type: integer
|
33
|
+
additionalProperties: true
|
34
|
+
Edge:
|
35
|
+
type: object
|
36
|
+
required:
|
37
|
+
- between
|
38
|
+
- path
|
39
|
+
- sid
|
40
|
+
properties:
|
41
|
+
between:
|
42
|
+
type: array
|
43
|
+
items:
|
44
|
+
type: string
|
45
|
+
minItems: 2
|
46
|
+
maxItems: 2
|
47
|
+
path:
|
48
|
+
type: array
|
49
|
+
items:
|
50
|
+
$ref: "#/$defs/Position"
|
51
|
+
minItems: 2
|
52
|
+
sid:
|
53
|
+
type: integer
|
54
|
+
additionalProperties: true
|
55
|
+
Position:
|
56
|
+
type: object
|
57
|
+
required:
|
58
|
+
- xo
|
59
|
+
- yo
|
60
|
+
properties:
|
61
|
+
xo:
|
62
|
+
type: number
|
63
|
+
yo:
|
64
|
+
type: number
|
65
|
+
|
data/lib/render.yaml
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
type: object
|
2
|
+
properties:
|
3
|
+
diagram:
|
4
|
+
type: object
|
5
|
+
default: {}
|
6
|
+
properties:
|
7
|
+
style:
|
8
|
+
$ref: "#/$defs/Style"
|
9
|
+
default: 'default'
|
10
|
+
edges:
|
11
|
+
type: array
|
12
|
+
minItems: 0
|
13
|
+
default: []
|
14
|
+
items:
|
15
|
+
$ref: "#/$defs/Edge"
|
16
|
+
nodes:
|
17
|
+
type: array
|
18
|
+
minItems: 0
|
19
|
+
default: []
|
20
|
+
items:
|
21
|
+
$ref: "#/$defs/Node"
|
22
|
+
styles:
|
23
|
+
type: object
|
24
|
+
properties:
|
25
|
+
node:
|
26
|
+
type: object
|
27
|
+
properties:
|
28
|
+
default:
|
29
|
+
type: object
|
30
|
+
default: {}
|
31
|
+
additionalProperties: true
|
32
|
+
edge:
|
33
|
+
type: object
|
34
|
+
default: {}
|
35
|
+
properties:
|
36
|
+
default:
|
37
|
+
type: object
|
38
|
+
default: {}
|
39
|
+
additionalProperties: true
|
40
|
+
diagram:
|
41
|
+
type: object
|
42
|
+
default: {}
|
43
|
+
properties:
|
44
|
+
default:
|
45
|
+
type: object
|
46
|
+
default: {}
|
47
|
+
additionalProperties: true
|
48
|
+
additionalProperties: true
|
49
|
+
additionalProperties: true
|
50
|
+
$defs:
|
51
|
+
Node:
|
52
|
+
type: object
|
53
|
+
required:
|
54
|
+
- label
|
55
|
+
- sid
|
56
|
+
- xo
|
57
|
+
- yo
|
58
|
+
properties:
|
59
|
+
label:
|
60
|
+
type: string
|
61
|
+
sid:
|
62
|
+
type: integer
|
63
|
+
xo:
|
64
|
+
type: integer
|
65
|
+
yo:
|
66
|
+
type: integer
|
67
|
+
style:
|
68
|
+
$ref: "#/$defs/Style"
|
69
|
+
default: 'default'
|
70
|
+
additionalProperties: true
|
71
|
+
Edge:
|
72
|
+
type: object
|
73
|
+
required:
|
74
|
+
- between
|
75
|
+
- path
|
76
|
+
- sid
|
77
|
+
properties:
|
78
|
+
between:
|
79
|
+
type: array
|
80
|
+
items:
|
81
|
+
type: string
|
82
|
+
minItems: 2
|
83
|
+
maxItems: 2
|
84
|
+
path:
|
85
|
+
type: array
|
86
|
+
items:
|
87
|
+
$ref: "#/$defs/Position"
|
88
|
+
minItems: 2
|
89
|
+
sid:
|
90
|
+
type: integer
|
91
|
+
style:
|
92
|
+
$ref: "#/$defs/Style"
|
93
|
+
default: 'default'
|
94
|
+
additionalProperties: true
|
95
|
+
Position:
|
96
|
+
type: object
|
97
|
+
required:
|
98
|
+
- xo
|
99
|
+
- yo
|
100
|
+
properties:
|
101
|
+
xo:
|
102
|
+
type: number
|
103
|
+
yo:
|
104
|
+
type: number
|
105
|
+
Style:
|
106
|
+
oneOf:
|
107
|
+
- type: string
|
108
|
+
- type: array
|
109
|
+
items:
|
110
|
+
type: string
|
111
|
+
|