railroad_diagrams 0.2.0 → 0.3.0
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/.github/workflows/main.yml +33 -0
- data/.gitignore +9 -0
- data/CHANGELOG.md +8 -0
- data/Gemfile +7 -0
- data/README.md +2 -0
- data/lib/railroad_diagrams/alternating_sequence.rb +5 -5
- data/lib/railroad_diagrams/choice.rb +31 -28
- data/lib/railroad_diagrams/command.rb +3 -3
- data/lib/railroad_diagrams/comment.rb +1 -1
- data/lib/railroad_diagrams/diagram.rb +5 -4
- data/lib/railroad_diagrams/diagram_item.rb +1 -1
- data/lib/railroad_diagrams/group.rb +1 -1
- data/lib/railroad_diagrams/horizontal_choice.rb +14 -15
- data/lib/railroad_diagrams/multiple_choice.rb +1 -1
- data/lib/railroad_diagrams/one_or_more.rb +3 -3
- data/lib/railroad_diagrams/optional_sequence.rb +6 -5
- data/lib/railroad_diagrams/stack.rb +1 -0
- data/lib/railroad_diagrams/text_diagram.rb +96 -59
- data/lib/railroad_diagrams/version.rb +1 -1
- data/railroad_diagrams.gemspec +30 -0
- data/test.rb +2 -0
- metadata +7 -7
- data/sample/sample.html +0 -215
@@ -117,24 +117,43 @@ module RailroadDiagrams
|
|
117
117
|
end
|
118
118
|
end
|
119
119
|
|
120
|
-
def rect(item, dashed
|
120
|
+
def rect(item, dashed: false)
|
121
121
|
rectish('rect', item, dashed)
|
122
122
|
end
|
123
123
|
|
124
|
-
def round_rect(item, dashed
|
124
|
+
def round_rect(item, dashed: false)
|
125
125
|
rectish('roundrect', item, dashed)
|
126
126
|
end
|
127
127
|
|
128
|
+
def max_width(*args)
|
129
|
+
max_width = 0
|
130
|
+
args.each do |arg|
|
131
|
+
width =
|
132
|
+
case arg
|
133
|
+
when TextDiagram
|
134
|
+
arg.width
|
135
|
+
when Array
|
136
|
+
arg.map(&:length).max
|
137
|
+
when Numeric
|
138
|
+
arg.to_s.length
|
139
|
+
else
|
140
|
+
arg.length
|
141
|
+
end
|
142
|
+
max_width = width if width > max_width
|
143
|
+
end
|
144
|
+
max_width
|
145
|
+
end
|
146
|
+
|
128
147
|
def pad_l(string, width, pad)
|
129
148
|
gap = width - string.length
|
130
|
-
raise "Gap #{gap} must be a multiple of pad string '#{pad}'" unless gap % pad.length
|
149
|
+
raise "Gap #{gap} must be a multiple of pad string '#{pad}'" unless (gap % pad.length).zero?
|
131
150
|
|
132
151
|
(pad * (gap / pad.length)) + string
|
133
152
|
end
|
134
153
|
|
135
154
|
def pad_r(string, width, pad)
|
136
155
|
gap = width - string.length
|
137
|
-
raise "Gap #{gap} must be a multiple of pad string '#{pad}'" unless gap % pad.length
|
156
|
+
raise "Gap #{gap} must be a multiple of pad string '#{pad}'" unless (gap % pad.length).zero?
|
138
157
|
|
139
158
|
string + (pad * (gap / pad.length))
|
140
159
|
end
|
@@ -169,54 +188,57 @@ module RailroadDiagrams
|
|
169
188
|
|
170
189
|
def rectish(rect_type, data, dashed)
|
171
190
|
line_type = dashed ? '_dashed' : ''
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
lines
|
189
|
-
|
191
|
+
top_left, ctr_left, bot_left, top_right, ctr_right, bot_right, top_horiz, bot_horiz, line, cross =
|
192
|
+
get_parts([
|
193
|
+
"#{rect_type}_top_left",
|
194
|
+
"#{rect_type}_left#{line_type}",
|
195
|
+
"#{rect_type}_bot_left",
|
196
|
+
"#{rect_type}_top_right",
|
197
|
+
"#{rect_type}_right#{line_type}",
|
198
|
+
"#{rect_type}_bot_right",
|
199
|
+
"#{rect_type}_top#{line_type}",
|
200
|
+
"#{rect_type}_bot#{line_type}",
|
201
|
+
'line',
|
202
|
+
'cross'
|
203
|
+
])
|
204
|
+
|
205
|
+
item_td = data.is_a?(TextDiagram) ? data : new(0, 0, [data])
|
206
|
+
|
207
|
+
lines = [top_horiz * (item_td.width + 2)]
|
208
|
+
if data.is_a?(TextDiagram)
|
209
|
+
lines += item_td.expand(1, 1, 0, 0).lines
|
210
|
+
else
|
211
|
+
(0...item_td.lines.length).each do |i|
|
212
|
+
lines += [" #{item_td.lines[i]} "]
|
213
|
+
end
|
214
|
+
end
|
215
|
+
lines += [(bot_horiz * (item_td.width + 2))]
|
190
216
|
|
191
217
|
entry = item_td.entry + 1
|
192
218
|
exit = item_td.exit + 1
|
193
219
|
|
194
|
-
|
195
|
-
lefts =
|
196
|
-
lefts[0] =
|
197
|
-
lefts[-1] =
|
198
|
-
lefts[entry] =
|
220
|
+
left_max_width = max_width(top_left, ctr_left, bot_left)
|
221
|
+
lefts = [pad_r(ctr_left, left_max_width, ' ')] * lines.length
|
222
|
+
lefts[0] = pad_r(top_left, left_max_width, top_horiz)
|
223
|
+
lefts[-1] = pad_r(bot_left, left_max_width, bot_horiz)
|
224
|
+
lefts[entry] = cross if data.is_a?(TextDiagram)
|
199
225
|
|
200
|
-
|
201
|
-
rights =
|
202
|
-
rights[0] =
|
203
|
-
rights[-1] =
|
204
|
-
rights[exit] =
|
226
|
+
right_max_width = max_width(top_right, ctr_right, bot_right)
|
227
|
+
rights = [pad_l(ctr_right, right_max_width, ' ')] * lines.length
|
228
|
+
rights[0] = pad_l(top_right, right_max_width, top_horiz)
|
229
|
+
rights[-1] = pad_l(bot_right, right_max_width, bot_horiz)
|
230
|
+
rights[exit] = cross if data.is_a?(TextDiagram)
|
205
231
|
|
206
|
-
|
207
|
-
lefts[i] + line + rights[i]
|
208
|
-
end
|
232
|
+
lines = enclose_lines(lines, lefts, rights)
|
209
233
|
|
210
|
-
lefts =
|
211
|
-
lefts[entry] =
|
212
|
-
rights =
|
213
|
-
rights[exit] =
|
234
|
+
lefts = [' '] * lines.length
|
235
|
+
lefts[entry] = line
|
236
|
+
rights = [' '] * lines.length
|
237
|
+
rights[exit] = line
|
214
238
|
|
215
|
-
|
216
|
-
lefts[i] + line + rights[i]
|
217
|
-
end
|
239
|
+
lines = enclose_lines(lines, lefts, rights)
|
218
240
|
|
219
|
-
new(entry, exit,
|
241
|
+
new(entry, exit, lines)
|
220
242
|
end
|
221
243
|
end
|
222
244
|
|
@@ -227,12 +249,17 @@ module RailroadDiagrams
|
|
227
249
|
@exit = exit
|
228
250
|
@lines = lines.dup
|
229
251
|
@height = lines.size
|
230
|
-
@width = lines.
|
252
|
+
@width = lines.any? ? lines[0].length : 0
|
253
|
+
|
254
|
+
raise "Entry is not within diagram vertically:\n#{dump(false)}" unless entry <= lines.length
|
255
|
+
raise "Exit is not within diagram vertically:\n#{dump(false)}" unless exit <= lines.length
|
231
256
|
|
232
|
-
|
257
|
+
lines.each do |line|
|
258
|
+
raise "Diagram data is not rectangular:\n#{dump(false)}" unless lines[0].length == line.length
|
259
|
+
end
|
233
260
|
end
|
234
261
|
|
235
|
-
def alter(new_entry
|
262
|
+
def alter(new_entry: nil, new_exit: nil, new_lines: nil)
|
236
263
|
self.class.new(
|
237
264
|
new_entry || @entry,
|
238
265
|
new_exit || @exit,
|
@@ -310,23 +337,33 @@ module RailroadDiagrams
|
|
310
337
|
)
|
311
338
|
end
|
312
339
|
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
@lines.each do |
|
320
|
-
|
340
|
+
def dump(show = true)
|
341
|
+
result = "height=#{@height}; len(lines)=#{@lines.length}"
|
342
|
+
|
343
|
+
result += "; entry outside diagram: entry=#{@ntry}" if @entry > @lines.length
|
344
|
+
result += "; exit outside diagram: exit=#{@exit}" if @exit > @lines.length
|
345
|
+
|
346
|
+
(0...[@lines.length, @entry + 1, @exit + 1].max).each do |y|
|
347
|
+
result += "\n[#{format('%03d', y)}]"
|
348
|
+
result += " '#{@lines[y]}' len=#{@lines[y].length}" if y < @lines.length
|
349
|
+
if y == @entry && y == @exit
|
350
|
+
result += ' <- entry, exit'
|
351
|
+
elsif y == @entry
|
352
|
+
result += ' <- entry'
|
353
|
+
elsif y == @exit
|
354
|
+
result += ' <- exit'
|
355
|
+
end
|
321
356
|
end
|
322
357
|
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
358
|
+
if show
|
359
|
+
puts result
|
360
|
+
else
|
361
|
+
result
|
362
|
+
end
|
328
363
|
end
|
329
364
|
|
365
|
+
private
|
366
|
+
|
330
367
|
def inspect
|
331
368
|
output = ["TextDiagram(entry=#{@entry}, exit=#{@exit}, height=#{@height})"]
|
332
369
|
@lines.each_with_index do |line, i|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lib/railroad_diagrams/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'railroad_diagrams'
|
7
|
+
spec.version = RailroadDiagrams::VERSION
|
8
|
+
spec.authors = ['Yudai Takada']
|
9
|
+
spec.email = ['t.yudai92@gmail.com']
|
10
|
+
|
11
|
+
spec.summary = '🛤️ A tiny Ruby+SVG library for drawing railroad syntax diagrams like JSON.org.'
|
12
|
+
spec.description = 'Generate SVG railroad syntax diagrams, like on JSON.org.'
|
13
|
+
spec.homepage = 'https://github.com/ydah/railroad_diagrams'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.5.0')
|
16
|
+
|
17
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
18
|
+
spec.metadata['source_code_uri'] = spec.homepage
|
19
|
+
spec.metadata['changelog_uri'] = "#{spec.homepage}/releases"
|
20
|
+
spec.metadata['bug_tracker_uri'] = "#{spec.homepage}/issues"
|
21
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
22
|
+
|
23
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
24
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features|sample)/}) }
|
25
|
+
end
|
26
|
+
|
27
|
+
spec.bindir = 'exe'
|
28
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
29
|
+
spec.require_paths = ['lib']
|
30
|
+
end
|
data/test.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: railroad_diagrams
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yudai Takada
|
8
|
-
autorequire:
|
9
8
|
bindir: exe
|
10
9
|
cert_chain: []
|
11
|
-
date: 2025-02-
|
10
|
+
date: 2025-02-24 00:00:00.000000000 Z
|
12
11
|
dependencies: []
|
13
12
|
description: Generate SVG railroad syntax diagrams, like on JSON.org.
|
14
13
|
email:
|
@@ -18,7 +17,10 @@ executables:
|
|
18
17
|
extensions: []
|
19
18
|
extra_rdoc_files: []
|
20
19
|
files:
|
20
|
+
- ".github/workflows/main.yml"
|
21
|
+
- ".gitignore"
|
21
22
|
- CHANGELOG.md
|
23
|
+
- Gemfile
|
22
24
|
- LICENSE.txt
|
23
25
|
- MIT
|
24
26
|
- README.md
|
@@ -50,7 +52,7 @@ files:
|
|
50
52
|
- lib/railroad_diagrams/text_diagram.rb
|
51
53
|
- lib/railroad_diagrams/version.rb
|
52
54
|
- lib/railroad_diagrams/zero_or_more.rb
|
53
|
-
-
|
55
|
+
- railroad_diagrams.gemspec
|
54
56
|
- test.rb
|
55
57
|
homepage: https://github.com/ydah/railroad_diagrams
|
56
58
|
licenses:
|
@@ -61,7 +63,6 @@ metadata:
|
|
61
63
|
changelog_uri: https://github.com/ydah/railroad_diagrams/releases
|
62
64
|
bug_tracker_uri: https://github.com/ydah/railroad_diagrams/issues
|
63
65
|
rubygems_mfa_required: 'true'
|
64
|
-
post_install_message:
|
65
66
|
rdoc_options: []
|
66
67
|
require_paths:
|
67
68
|
- lib
|
@@ -76,8 +77,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
76
77
|
- !ruby/object:Gem::Version
|
77
78
|
version: '0'
|
78
79
|
requirements: []
|
79
|
-
rubygems_version: 3.
|
80
|
-
signing_key:
|
80
|
+
rubygems_version: 3.7.0.dev
|
81
81
|
specification_version: 4
|
82
82
|
summary: "\U0001F6E4️ A tiny Ruby+SVG library for drawing railroad syntax diagrams
|
83
83
|
like JSON.org."
|