rsyntaxtree 0.9.3 → 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.tags +179 -0
  4. data/Gemfile +2 -0
  5. data/README.md +35 -29
  6. data/Rakefile +7 -0
  7. data/bin/rsyntaxtree +42 -31
  8. data/fonts/OpenMoji-Black.ttf +0 -0
  9. data/fonts/OpenMoji-Color.ttf +0 -0
  10. data/img/elements/circle.png +0 -0
  11. data/img/elements/circle_abc.png +0 -0
  12. data/img/elements/circle_bold.png +0 -0
  13. data/img/elements/circle_hatched.png +0 -0
  14. data/img/elements/circle_one.png +0 -0
  15. data/img/elements/connector.png +0 -0
  16. data/img/elements/connector_bold.png +0 -0
  17. data/img/elements/square.png +0 -0
  18. data/img/elements/square_abc.png +0 -0
  19. data/img/elements/square_bold.png +0 -0
  20. data/img/elements/square_hatched.png +0 -0
  21. data/img/elements/square_one.png +0 -0
  22. data/img/rsyntaxtree.png +0 -0
  23. data/img/sample.png +0 -0
  24. data/img/sample.svg +38 -0
  25. data/lib/rsyntaxtree/base_graph.rb +262 -0
  26. data/lib/rsyntaxtree/element.rb +156 -25
  27. data/lib/rsyntaxtree/elementlist.rb +16 -13
  28. data/lib/rsyntaxtree/markup_parser.rb +208 -0
  29. data/lib/rsyntaxtree/string_parser.rb +187 -204
  30. data/lib/rsyntaxtree/svg_graph.rb +471 -298
  31. data/lib/rsyntaxtree/utils.rb +49 -6
  32. data/lib/rsyntaxtree/version.rb +1 -1
  33. data/lib/rsyntaxtree.rb +144 -161
  34. data/rsyntaxtree.gemspec +2 -0
  35. data/test/markup_parser_test.rb +207 -0
  36. metadata +52 -11
  37. data/fonts/latinmodern-math.otf +0 -0
  38. data/fonts/lmroman10-bold.otf +0 -0
  39. data/fonts/lmroman10-bolditalic.otf +0 -0
  40. data/fonts/lmroman10-italic.otf +0 -0
  41. data/fonts/lmroman10-regular.otf +0 -0
  42. data/lib/rsyntaxtree/error_message.rb +0 -68
  43. data/lib/rsyntaxtree/graph.rb +0 -312
  44. data/lib/rsyntaxtree/tree_graph.rb +0 -327
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rsyntaxtree
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.3
4
+ version: 1.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yoichiro Hasebe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-09 00:00:00.000000000 Z
11
+ date: 2022-02-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rmagick
@@ -50,6 +50,34 @@ dependencies:
50
50
  - - ">="
51
51
  - !ruby/object:Gem::Version
52
52
  version: 3.0.1
53
+ - !ruby/object:Gem::Dependency
54
+ name: parslet
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ type: :runtime
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ - !ruby/object:Gem::Dependency
68
+ name: rsvg2
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ type: :runtime
75
+ prerelease: false
76
+ version_requirements: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
53
81
  description: Yet another syntax tree generator made with Ruby and RMagick
54
82
  email:
55
83
  - yohasebe@gmail.com
@@ -59,6 +87,7 @@ extensions: []
59
87
  extra_rdoc_files: []
60
88
  files:
61
89
  - ".gitignore"
90
+ - ".tags"
62
91
  - Gemfile
63
92
  - README.md
64
93
  - Rakefile
@@ -76,23 +105,35 @@ files:
76
105
  - fonts/NotoSerif-Regular.ttf
77
106
  - fonts/NotoSerifJP-Bold.otf
78
107
  - fonts/NotoSerifJP-Regular.otf
79
- - fonts/latinmodern-math.otf
80
- - fonts/lmroman10-bold.otf
81
- - fonts/lmroman10-bolditalic.otf
82
- - fonts/lmroman10-italic.otf
83
- - fonts/lmroman10-regular.otf
108
+ - fonts/OpenMoji-Black.ttf
109
+ - fonts/OpenMoji-Color.ttf
84
110
  - fonts/wqy-zenhei.ttf
111
+ - img/elements/circle.png
112
+ - img/elements/circle_abc.png
113
+ - img/elements/circle_bold.png
114
+ - img/elements/circle_hatched.png
115
+ - img/elements/circle_one.png
116
+ - img/elements/connector.png
117
+ - img/elements/connector_bold.png
118
+ - img/elements/square.png
119
+ - img/elements/square_abc.png
120
+ - img/elements/square_bold.png
121
+ - img/elements/square_hatched.png
122
+ - img/elements/square_one.png
123
+ - img/rsyntaxtree.png
124
+ - img/sample.png
125
+ - img/sample.svg
85
126
  - lib/rsyntaxtree.rb
127
+ - lib/rsyntaxtree/base_graph.rb
86
128
  - lib/rsyntaxtree/element.rb
87
129
  - lib/rsyntaxtree/elementlist.rb
88
- - lib/rsyntaxtree/error_message.rb
89
- - lib/rsyntaxtree/graph.rb
130
+ - lib/rsyntaxtree/markup_parser.rb
90
131
  - lib/rsyntaxtree/string_parser.rb
91
132
  - lib/rsyntaxtree/svg_graph.rb
92
- - lib/rsyntaxtree/tree_graph.rb
93
133
  - lib/rsyntaxtree/utils.rb
94
134
  - lib/rsyntaxtree/version.rb
95
135
  - rsyntaxtree.gemspec
136
+ - test/markup_parser_test.rb
96
137
  homepage: http://github.com/yohasebe/rsyntaxtree
97
138
  licenses:
98
139
  - MIT
@@ -112,7 +153,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
112
153
  - !ruby/object:Gem::Version
113
154
  version: '0'
114
155
  requirements: []
115
- rubygems_version: 3.2.32
156
+ rubygems_version: 3.3.3
116
157
  signing_key:
117
158
  specification_version: 4
118
159
  summary: RSyntaxTree is a graphical syntax tree generator written in Ruby
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -1,68 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # -*- coding: utf-8 -*-
3
-
4
- #==========================
5
- # error_message.rb
6
- #==========================
7
- #
8
- # Takes an error message and drow an image file of the very message
9
- #
10
- # This file is part of RSyntaxTree, which is a ruby port of Andre Eisenbach's
11
- # excellent program phpSyntaxTree.
12
- #
13
- # Copyright (c) 2007-2021 Yoichiro Hasebe <yohasebe@gmail.com>
14
- # Copyright (c) 2003-2004 Andre Eisenbach <andre@ironcreek.net>
15
-
16
- class ErrorMessage
17
-
18
- def initialize(text, font, font_size, filename, format)
19
-
20
- @text = text
21
- @font = font
22
- @font_size = font_size
23
- @filename = filename
24
- @format = format
25
-
26
- metrics = img_get_txt_metrics(text, font, font_size, NoDecoration, true)
27
-
28
- @im = Image.new(metrics.width, metrics.height)
29
- @gc = Draw.new
30
- @gc.font = font
31
- @gc.pointsize = font_size
32
- @gc.stroke("transparent")
33
- @gc.fill("black")
34
- @gc.gravity(CenterGravity)
35
- @gc.text(0, 0, text)
36
- end
37
-
38
- def img_get_txt_metrics(text, font, font_size, multiline)
39
-
40
- background = Image.new(500, 250)
41
-
42
- gc = Draw.new
43
- gc.annotate(background, 0, 0, 0, 0, text) do |gc|
44
- gc.font = font
45
- gc.pointsize = font_size
46
- gc.gravity = CenterGravity
47
- gc.stroke = 'none'
48
- end
49
-
50
- if multiline
51
- metrics = gc.get_multiline_type_metrics(background, text)
52
- else
53
- metrics = gc.get_type_metrics(background, text)
54
- end
55
-
56
- return metrics
57
- end
58
-
59
- def draw
60
- @gc.draw(@im)
61
- end
62
-
63
- def save
64
- @gc.draw(@im)
65
- @im.write(@filename + "." + @format)
66
- end
67
-
68
- end
@@ -1,312 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # -*- coding: utf-8 -*-
3
-
4
- #==========================
5
- # graph.rb
6
- #==========================
7
- #
8
- # Image utility functions to inspect text font metrics
9
- #
10
- # This file is part of RSyntaxTree, which is a ruby port of Andre Eisenbach's
11
- # excellent program phpSyntaxTree.
12
- #
13
- # Copyright (c) 2007-2021 Yoichiro Hasebe <yohasebe@gmail.com>
14
- # Copyright (c) 2003-2004 Andre Eisenbach <andre@ironcreek.net>
15
-
16
- require 'rmagick'
17
- include Magick
18
-
19
- class Graph
20
-
21
- def initialize(e_list, metrics, symmetrize, color, leafstyle, multibyte, font, font_size)
22
-
23
- # Set class-specific parameters beforehand in subclass
24
-
25
- # Store parameters
26
- @e_list = e_list
27
- @m = metrics
28
- @multibyte = multibyte
29
- @leafstyle = leafstyle
30
- @symmetrize = symmetrize
31
-
32
- # Calculate image dimensions
33
- @e_height = font_size + @m[:e_padd] * 2
34
- h = @e_list.get_level_height
35
- w = calc_level_width(0)
36
- @width = w
37
- @height = h * @e_height + (h-1) * (@m[:v_space] + font_size) + @m[:b_topbot] * 2
38
-
39
- # Initialize the image and colors
40
- @col_bg = "none"
41
- @col_fg = "black"
42
- @col_line = "black"
43
-
44
- if color
45
- @col_node = "blue"
46
- @col_leaf = "green"
47
- @col_trace = "red"
48
- else
49
- @col_node = "black"
50
- @col_leaf = "black"
51
- @col_trace = "black"
52
- end
53
-
54
- @main_height = img_get_txt_height("l", font, font_size)
55
- @sub_size = (font_size * SUBSCRIPT_CONST)
56
- @sub_space_width = img_get_txt_width("l", font, @sub_size)
57
- end
58
-
59
- def img_get_txt_metrics(text, font, font_size, multiline)
60
-
61
- background = Image.new(1, 1)
62
-
63
- gc = Draw.new
64
- gc.annotate(background, 0, 0, 0, 0, text) do |gc|
65
- gc.font = font
66
- gc.pointsize = font_size
67
- gc.gravity = CenterGravity
68
- gc.stroke = 'none'
69
- gc.kerning = 0
70
- gc.interline_spacing = 0
71
- gc.interword_spacing = 0
72
- end
73
-
74
- if multiline
75
- metrics = gc.get_multiline_type_metrics(background, text)
76
- else
77
- metrics = gc.get_type_metrics(background, text)
78
- end
79
- return metrics
80
- end
81
-
82
- # Calculate the width of the element. If the element is
83
- # a node, the calculation will be performed recursively
84
- # for all child elements.
85
- def calc_element_width(e)
86
- w = 0
87
- content = e.content.gsub("<>", " ")
88
-
89
- children = @e_list.get_children(e.id)
90
-
91
- if(children.length == 0)
92
- w = img_get_txt_width(content, @font, @font_size) + @font_size
93
- else
94
- children.each do |child|
95
- child_e = @e_list.get_id(child)
96
- w += calc_element_width(child_e)
97
- end
98
-
99
- tw = img_get_txt_width(content, @font, @font_size) + @font_size
100
- if(tw > w)
101
- fix_child_size(e.id, w, tw)
102
- w = tw
103
- end
104
- end
105
-
106
- @e_list.set_element_width(e.id, w)
107
- return w
108
- end
109
-
110
- # Calculate the width of all elements in a certain level
111
- def calc_level_width(level)
112
- w = 0
113
- e = @e_list.get_first
114
- while e
115
- if(e.level == level)
116
- x = calc_element_width(e)
117
- w += x
118
- end
119
- e = @e_list.get_next
120
- end
121
- return w
122
- end
123
-
124
- def calc_children_width(id)
125
- left = 0
126
- right = 0
127
- c_list = @e_list.get_children(id)
128
- return nil if c_list.empty?
129
-
130
- c_list.each do |c|
131
- left = c.indent if indent == 0 or left > c.indent
132
- end
133
- c_list.each do |c|
134
- right = c.indent + e.width if c.indent + c.width > right
135
- end
136
- return [left, right]
137
- end
138
-
139
- def get_children_indent(id)
140
- calc_children_width(id)[0]
141
- end
142
-
143
- def get_children_width(id)
144
- calc_children_width(id)[1] - get_children_indent(id)
145
- end
146
-
147
- # Parse the elements in the list top to bottom and
148
- # draw the elements into the image.
149
- # As we it iterate through the levels, the element
150
- # indentation is calculated.
151
- def parse_list
152
-
153
- # Calc element list recursively....
154
- e_arr = @e_list.get_elements
155
-
156
- h = @e_list.get_level_height
157
-
158
- h.times do |i|
159
- x = 0
160
- e_arr.each do |j|
161
-
162
- if (j.level == i)
163
- cw = @e_list.get_element_width(j.id)
164
- parent_indent = @e_list.get_indent(j.parent)
165
- if (x < parent_indent)
166
- x = parent_indent
167
- end
168
- @e_list.set_indent(j.id, x)
169
-
170
- if !@symmetrize
171
- draw_element(x, i, cw, j.content, j.type)
172
- if(j.parent != 0 )
173
- words = j.content.split(" ")
174
- unless @leafstyle == "nothing" && ETYPE_LEAF == j.type
175
- if (@leafstyle == "auto" && ETYPE_LEAF == j.type && x == parent_indent)
176
- if words.length > 1 || j.triangle
177
- txt_width = img_get_txt_width(j.content, @font, @font_size)
178
- triangle_to_parent(x, i, cw, txt_width, @symmetrize)
179
- else
180
- line_to_parent(x, i, cw, @e_list.get_indent(j.parent), @e_list.get_element_width(j.parent))
181
- end
182
- else
183
- line_to_parent(x, i, cw, @e_list.get_indent(j.parent), @e_list.get_element_width(j.parent))
184
- end
185
- end
186
- end
187
- end
188
- x += cw
189
- end
190
- end
191
- end
192
- return true if !@symmetrize
193
-
194
- elements_to_draw = {}
195
- triangles_to_draw = []
196
- lines_to_draw = []
197
-
198
- lmost = {:level => nil, :value => nil, :type => nil}
199
- rmost = nil
200
- h.times do |i|
201
- curlevel = h - i - 1
202
- e_arr.each_with_index do |j, idx|
203
- if (j.level == curlevel)
204
- # Draw a line to the parent element
205
- children = @e_list.get_children(j.id)
206
-
207
- tw = img_get_txt_width(j.content, @font, @font_size)
208
- if children.length > 0
209
- left, right = -1, -1
210
- children.each do |child|
211
- k = @e_list.get_id(child)
212
- kw = img_get_txt_width(k.content, @font, @font_size)
213
- left = k.indent + kw / 2 if k.indent + kw / 2 < left or left == -1
214
- right = k.indent + kw / 2 if k.indent + kw / 2 > right
215
- end
216
-
217
- elements_to_draw[j.id] = {:left => left, :curlevel => curlevel, :width => right - left, :content => j.content, :type => j.type}
218
- @e_list.set_indent(j.id, left + (right - left) / 2 - tw / 2)
219
-
220
- children.each do |child|
221
- k = @e_list.get_id(child)
222
- words = k.content.split(" ")
223
- dw = img_get_txt_width(k.content, @font, @font_size)
224
-
225
- children2 = @e_list.get_children(k.id)
226
-
227
- unless @leafstyle == "nothing" && ETYPE_LEAF == k.type
228
- if (@leafstyle == "auto" && ETYPE_LEAF == k.type)
229
- if words.length > 1 || k.triangle
230
- txt_width = img_get_txt_width(k.content, @font, @font_size)
231
- triangles_to_draw << {:indent => k.indent, :curlevel => curlevel + 1, :width1 => dw, :width2 => txt_width}
232
- else
233
- lines_to_draw << {:indent1 => k.indent, :curlevel => curlevel + 1, :width1 => dw, :indent2 => j.indent, :width2 => tw}
234
- end
235
- else
236
- lines_to_draw << {:indent1 => k.indent, :curlevel => curlevel + 1, :width1 => dw, :indent2 => j.indent, :width2 => tw}
237
- end
238
- end
239
- end
240
-
241
- end
242
- elements = e_arr.select do |l|
243
- l.level == curlevel && @e_list.get_children(l.id).empty?
244
- end
245
-
246
- elements.each.with_index do |l, idx|
247
- lw = img_get_txt_width(l.content, @font, @font_size)
248
- left = l.indent
249
- right = left + lw
250
- unless elements_to_draw.include? l.id
251
- elements_to_draw[l.id] = {:left => left, :curlevel => curlevel, :width => right - left, :content => l.content, :type => l.type}
252
- end
253
- end
254
- end
255
- end
256
-
257
- e_arr.each do |e|
258
- lpos = e.indent - img_get_txt_width(e.content, @font, @font_size) / 2
259
- next if lpos > 0
260
- if !lmost[:value] || lmost[:value] > lpos
261
- lmost[:level] = e.level
262
- lmost[:value] = lpos
263
- lmost[:type] = e
264
- end
265
- rpos = e.indent + e.width
266
- rmost = rpos if !rmost || rmost < rpos
267
- end
268
- end
269
-
270
- offset = 0
271
- if lmost[:level] != h - 1
272
- offset = lmost[:value] / -2
273
- new_width = rmost
274
- @width = new_width + offset
275
- end
276
-
277
- elements_to_draw.each do |k, v|
278
- draw_element(v[:left] + offset, v[:curlevel], v[:width], v[:content], v[:type])
279
- end
280
- triangles_to_draw.each do |v|
281
- triangle_to_parent(v[:indent] + offset, v[:curlevel], v[:width1], v[:width2])
282
- end
283
- lines_to_draw.each do |v|
284
- line_to_parent(v[:indent1] + offset, v[:curlevel], v[:width1], v[:indent2] + offset, v[:width2])
285
- end
286
- end
287
-
288
- # Calculate top position from row (level)
289
- def row2px(row)
290
- @m[:b_topbot] + @e_height * row + (@m[:v_space] + @font_size) * row
291
- end
292
-
293
- def get_txt_only(text)
294
- text = text.strip
295
- if /\A([\+\-\=\*\#\~]+).+/ =~ text
296
- prefix = $1
297
- prefix_l = Regexp.escape(prefix)
298
- prefix_r = Regexp.escape(prefix.reverse)
299
- if /\A#{prefix_l}(.+)#{prefix_r}\z/ =~ text
300
- return $1
301
- end
302
- end
303
- return text
304
- end
305
-
306
- def img_get_txt_height(text, font, font_size, multiline = true)
307
- metrics = img_get_txt_metrics(text, font, font_size, multiline)
308
- # y = (metrics.bounds.y2 - metrics.bounds.y1).round
309
- y = metrics.height
310
- return y
311
- end
312
- end