diagrammatron 0.5.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/diagrammatron-schema +1 -1
- data/lib/subsets.rb +147 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f070bf8480ad655c260869aa9854d7553456491c68379403a16b50572ede42f4
|
4
|
+
data.tar.gz: ee33a1019e9d512c0a6afd7e70528b5bfaad8d53de1b00f3087d0e3945af1d0a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c5fb77d00c5ddf0ac067793357ad3dd961d37d47a0fedf152a1c90fe3b1013c35c88ca6496c5265389ca8f14927b77ce8f88a3def1c384e6938aae5617f78016
|
7
|
+
data.tar.gz: 665945789543418c34fe598e4aca5796bcabb0dfebcd19dced9da2c9fab1850136f8b6c76dbec180800f1478aac3e7f74fa10cc2cb9c1b30c1f1bf98a38d5de8
|
data/bin/diagrammatron-schema
CHANGED
@@ -50,7 +50,7 @@ def main
|
|
50
50
|
output = filename
|
51
51
|
end
|
52
52
|
opts.on('-l', '--list', 'List available schemas and exit.') do
|
53
|
-
$stdout.puts list_schemas.join("\n")
|
53
|
+
$stdout.puts list_schemas.sort.join("\n")
|
54
54
|
exit 0
|
55
55
|
end
|
56
56
|
opts.on('-h', '--help', 'Print this help and exit.') do
|
data/lib/subsets.rb
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright © 2023 Ismo Kärkkäinen
|
4
|
+
# Licensed under Universal Permissive License. See LICENSE.txt.
|
5
|
+
|
6
|
+
require_relative '../lib/common'
|
7
|
+
require 'ostruct'
|
8
|
+
require 'set'
|
9
|
+
|
10
|
+
def split_expression_string(expression_string)
|
11
|
+
out = []
|
12
|
+
remaining = expression_string.lstrip
|
13
|
+
until remaining.empty?
|
14
|
+
item, sep, rest = remaining.partition(/[\s+-]/)
|
15
|
+
out << item unless item.empty?
|
16
|
+
sep.strip!
|
17
|
+
unless sep.empty?
|
18
|
+
out << :plus if sep == '+'
|
19
|
+
out << :minus if sep == '-'
|
20
|
+
end
|
21
|
+
remaining = rest.lstrip
|
22
|
+
end
|
23
|
+
out
|
24
|
+
end
|
25
|
+
|
26
|
+
def identifier?(item)
|
27
|
+
item.is_a?(String)
|
28
|
+
end
|
29
|
+
|
30
|
+
def expression_array_errors(expression_array)
|
31
|
+
errors = []
|
32
|
+
previous_item_type = :symbol
|
33
|
+
unless expression_array.empty?
|
34
|
+
errors << 'Expression must start with an identifier' unless identifier?(expression_array.first)
|
35
|
+
errors << 'Expression must end with an identifier' unless identifier?(expression_array.last)
|
36
|
+
end
|
37
|
+
expression_array.each_with_index do |item, index|
|
38
|
+
current_item_type = identifier?(item) ? :identifier : :symbol
|
39
|
+
if current_item_type == previous_item_type
|
40
|
+
errors << "Invalid item '#{item}' at index #{index}. Expected #{current_item_type == :identifier ? 'operator' : 'identifier'}."
|
41
|
+
end
|
42
|
+
previous_item_type = current_item_type
|
43
|
+
end
|
44
|
+
errors.empty? ? nil : errors
|
45
|
+
end
|
46
|
+
|
47
|
+
def check_rules(r, filename)
|
48
|
+
ok = true
|
49
|
+
c = {}
|
50
|
+
r.fetch('sets', []).each do |setrules|
|
51
|
+
name = setrules.delete('name')
|
52
|
+
if c.key?(name)
|
53
|
+
aargh("#{filename} duplicate set name: #{name}")
|
54
|
+
ok = false
|
55
|
+
next
|
56
|
+
end
|
57
|
+
cats = {}
|
58
|
+
%i[any nodes edges].each do |category|
|
59
|
+
fr = {}
|
60
|
+
setrules.fetch(category.to_s, []).each do |fieldrules|
|
61
|
+
frn = fieldrules['name']
|
62
|
+
res = fr.fetch(frn, [])
|
63
|
+
res.concat(fieldrules['rules'].map { |str| Regexp.new(str) })
|
64
|
+
fr[frn] = res
|
65
|
+
rescue StandardError => e
|
66
|
+
aargh("#{filename} #{name} #{category} #{frn} rule error:\n#{e}")
|
67
|
+
ok = false
|
68
|
+
end
|
69
|
+
cats[category] = fr
|
70
|
+
end
|
71
|
+
c[name] = cats
|
72
|
+
end
|
73
|
+
r['sets'] = c
|
74
|
+
c = {}
|
75
|
+
r.fetch('expressions', []).each do |ne|
|
76
|
+
name = ne.delete('name')
|
77
|
+
if c.key?(name)
|
78
|
+
aargh("#{filename} duplicate expression name: #{name}")
|
79
|
+
ok = false
|
80
|
+
next
|
81
|
+
end
|
82
|
+
ea = split_expression_string(ne['expression'])
|
83
|
+
errs = expression_array_errors(ea)
|
84
|
+
unless errs.nil?
|
85
|
+
aargh("#{filename} expressions #{name}:\n#{errs.join("\n")}")
|
86
|
+
ok = false
|
87
|
+
end
|
88
|
+
c[name] = ea
|
89
|
+
end
|
90
|
+
r['expressions'] = c
|
91
|
+
ok
|
92
|
+
end
|
93
|
+
|
94
|
+
# Values in any are used if there is no existing value.
|
95
|
+
def merge_any(r)
|
96
|
+
r.fetch('sets', {}).each_value do |rules|
|
97
|
+
any = rules.delete(:any)
|
98
|
+
next if any.nil?
|
99
|
+
%i[edges nodes].each do |category|
|
100
|
+
c = rules.fetch(category, {})
|
101
|
+
any.each do |field, patterns|
|
102
|
+
next if c.key?(field)
|
103
|
+
c[field] = patterns
|
104
|
+
end
|
105
|
+
rules[category] = c
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# sets:
|
111
|
+
# name:
|
112
|
+
# nodes/edges: # Merge here.
|
113
|
+
# name: []
|
114
|
+
# expressions: # Merge here.
|
115
|
+
# name: string
|
116
|
+
|
117
|
+
def merge_rules(full, overwriting)
|
118
|
+
full['expressions'] = {} unless full.key? 'expressions'
|
119
|
+
full['expressions'].merge!(overwriting.fetch('expressions', {}))
|
120
|
+
sets = full.fetch('sets', {})
|
121
|
+
ow = overwriting.fetch('sets', {})
|
122
|
+
sets.each do |name, rules|
|
123
|
+
%i[nodes edges].each do |category|
|
124
|
+
m = ow.dig(name, category)
|
125
|
+
next if m.nil?
|
126
|
+
rules[category] = {} unless rules.key? category
|
127
|
+
rules[category].merge!(m)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
sets.merge!(ow) { |_key, merged, _used| merged } # Adds new sets.
|
131
|
+
full['sets'] = sets
|
132
|
+
end
|
133
|
+
|
134
|
+
def match_item(item, rules)
|
135
|
+
rules.each do |field, patterns|
|
136
|
+
vals = item.fetch(field, nil)
|
137
|
+
next if vals.nil?
|
138
|
+
vals = [ vals ] unless vals.is_a?(Array)
|
139
|
+
patterns.each do |p|
|
140
|
+
vals.each do |v|
|
141
|
+
next unless v.is_a?(String)
|
142
|
+
return true if p.match?(v)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
false
|
147
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: diagrammatron
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ismo Kärkkäinen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-12-
|
11
|
+
date: 2023-12-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json_schemer
|
@@ -66,6 +66,7 @@ files:
|
|
66
66
|
- lib/place.yaml
|
67
67
|
- lib/render.yaml
|
68
68
|
- lib/subset.yaml
|
69
|
+
- lib/subsets.rb
|
69
70
|
- template/internal.yaml
|
70
71
|
- template/root.yaml
|
71
72
|
- template/svg_1.1.erb
|