rsyntaxtree 0.9.1 → 1.0.4

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.
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.1
4
+ version: 1.0.4
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,22 @@ 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
85
111
  - lib/rsyntaxtree.rb
112
+ - lib/rsyntaxtree/base_graph.rb
86
113
  - lib/rsyntaxtree/element.rb
87
114
  - lib/rsyntaxtree/elementlist.rb
88
- - lib/rsyntaxtree/error_message.rb
89
- - lib/rsyntaxtree/graph.rb
115
+ - lib/rsyntaxtree/markup_parser.rb
90
116
  - lib/rsyntaxtree/string_parser.rb
91
117
  - lib/rsyntaxtree/svg_graph.rb
92
- - lib/rsyntaxtree/tree_graph.rb
93
118
  - lib/rsyntaxtree/utils.rb
94
119
  - lib/rsyntaxtree/version.rb
95
120
  - rsyntaxtree.gemspec
121
+ - syntree.png
122
+ - syntree.svg
123
+ - test/markup_parser_test.rb
96
124
  homepage: http://github.com/yohasebe/rsyntaxtree
97
125
  licenses:
98
126
  - MIT
@@ -112,7 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
112
140
  - !ruby/object:Gem::Version
113
141
  version: '0'
114
142
  requirements: []
115
- rubygems_version: 3.2.32
143
+ rubygems_version: 3.3.3
116
144
  signing_key:
117
145
  specification_version: 4
118
146
  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