diagrammatron 0.5.0 → 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 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