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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8c51dc3c8502bd1626d2a78bccd7e772e60fb25a26e6327879f42144849db598
4
- data.tar.gz: 78548d0ad0af86031afecb81bf4fedca42da58420d0de3a0d5063f07cb68538e
3
+ metadata.gz: f070bf8480ad655c260869aa9854d7553456491c68379403a16b50572ede42f4
4
+ data.tar.gz: ee33a1019e9d512c0a6afd7e70528b5bfaad8d53de1b00f3087d0e3945af1d0a
5
5
  SHA512:
6
- metadata.gz: 03d48ecd6c7e586007dcb470655fff6814e21d32f1921dcb828b35602bea208e48f58d9ba2ea5cdf5f16fb8f633a242a9d43a599c21fbf61d5ffaa631282c827
7
- data.tar.gz: 5ed263d065a49d69a031fa140ac0159d58301da26f4b51807573e5b8eefbeca6238301f6953cca5c8b44423a83fec18903a7e9d960a5b3fcf1d4702f1b671233
6
+ metadata.gz: c5fb77d00c5ddf0ac067793357ad3dd961d37d47a0fedf152a1c90fe3b1013c35c88ca6496c5265389ca8f14927b77ce8f88a3def1c384e6938aae5617f78016
7
+ data.tar.gz: 665945789543418c34fe598e4aca5796bcabb0dfebcd19dced9da2c9fab1850136f8b6c76dbec180800f1478aac3e7f74fa10cc2cb9c1b30c1f1bf98a38d5de8
@@ -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.0
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-19 00:00:00.000000000 Z
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