rsyntaxtree 1.0.8 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,41 +1,41 @@
1
- #!/usr/bin/env ruby
2
- # -*- coding: utf-8 -*-
1
+ # frozen_string_literal: true
3
2
 
4
3
  #==========================
5
4
  # svg_graph.rb
6
5
  #==========================
7
6
  #
8
7
  # Parses an element list into an SVG tree.
9
- # Copyright (c) 2007-2021 Yoichiro Hasebe <yohasebe@gmail.com>
8
+ # Copyright (c) 2007-2023 Yoichiro Hasebe <yohasebe@gmail.com>
10
9
 
11
10
  require "tempfile"
12
- require 'base_graph'
13
- require 'utils'
11
+ require_relative 'base_graph'
12
+ require_relative 'utils'
14
13
 
15
14
  module RSyntaxTree
16
15
  class SVGGraph < BaseGraph
17
16
  attr_accessor :width, :height
18
17
 
19
- def initialize(element_list, params)
18
+ def initialize(element_list, params, global)
20
19
  @height = 0
21
20
  @width = 0
22
21
  @extra_lines = []
23
- @fontset = params[:fontset]
24
- @fontsize = params[:fontsize]
22
+ @fontset = params[:fontset]
23
+ @fontsize = params[:fontsize]
25
24
  @transparent = params[:transparent]
26
25
  @color = params[:color]
27
26
  @fontstyle = params[:fontstyle]
28
27
  @margin = params[:margin].to_i
29
28
  @polyline = params[:polyline]
30
- @line_styles = "<line style='stroke:black; stroke-width:#{FONT_SCALING};' x1='X1' y1='Y1' x2='X2' y2='Y2' />\n"
31
- @polyline_styles = "<polyline style='stroke:black; stroke-width:#{FONT_SCALING}; fill:none;'
29
+ @line_styles = "<line style='stroke:black; stroke-width:#{FONT_SCALING};' x1='X1' y1='Y1' x2='X2' y2='Y2' />\n"
30
+ @polyline_styles = "<polyline style='stroke:black; stroke-width:#{FONT_SCALING}; fill:none;'
32
31
  points='CHIX CHIY MIDX1 MIDY1 MIDX2 MIDY2 PARX PARY' />\n"
33
- @polygon_styles = "<polygon style='fill: none; stroke: black; stroke-width:#{FONT_SCALING};' points='X1 Y1 X2 Y2 X3 Y3' />\n"
34
- @text_styles = "<text white-space='pre' alignment-baseline='text-top' style='fill: COLOR; font-size: fontsize' x='X_VALUE' y='Y_VALUE'>CONTENT</text>\n"
35
- @tree_data = String.new
32
+ @polygon_styles = "<polygon style='fill: none; stroke: black; stroke-width:#{FONT_SCALING};' points='X1 Y1 X2 Y2 X3 Y3' />\n"
33
+ @text_styles = "<text white-space='pre' alignment-baseline='text-top' style='fill: COLOR; font-size: fontsize' x='X_VALUE' y='Y_VALUE'>CONTENT</text>\n"
34
+ @tree_data = String.new
36
35
  @visited_x = {}
37
36
  @visited_y = {}
38
- super(element_list, params)
37
+ @global = global
38
+ super(element_list, params, global)
39
39
  end
40
40
 
41
41
  def svg_data
@@ -49,32 +49,32 @@ module RSyntaxTree
49
49
  y2 = @height + @margin
50
50
  extra_lines = @extra_lines.join("\n")
51
51
 
52
- as2 = $h_gap_between_nodes / 2 * 0.8
52
+ as2 = @global[:h_gap_between_nodes] / 2 * 0.8
53
53
  as = as2 / 2
54
54
 
55
- header =<<EOD
56
- <?xml version="1.0" standalone="no"?>
57
- <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
58
- <svg width="#{@width}" height="#{@height}" viewBox="#{x1}, #{y1}, #{x2}, #{y2}" version="1.1" xmlns="http://www.w3.org/2000/svg">
59
- <defs>
60
- <marker id="arrow" markerUnits="strokeWidth" markerWidth="#{as2}" markerHeight="#{as2}" viewBox="0 0 #{as2} #{as2}" refX="#{as}" refY="0">
61
- <polyline fill="none" stroke="#{@col_path}" stroke-width="1" points="0,#{as2},#{as},0,#{as2},#{as2}" />
62
- </marker>
63
- <pattern id="hatchBlack" x="10" y="10" width="10" height="10" patternUnits="userSpaceOnUse" patternTransform="rotate(45)">
64
- <line x1="0" y="0" x2="0" y2="10" stroke="black" stroke-width="4"></line>
65
- </pattern>
66
- <pattern id="hatchForNode" x="10" y="10" width="10" height="10" patternUnits="userSpaceOnUse" patternTransform="rotate(45)">
67
- <line x1="0" y="0" x2="0" y2="10" stroke="#{@col_node}" stroke-width="4"></line>
68
- </pattern>
69
- <pattern id="hatchForLeaf" x="10" y="10" width="10" height="10" patternUnits="userSpaceOnUse" patternTransform="rotate(45)">
70
- <line x1="0" y="0" x2="0" y2="10" stroke="#{@col_leaf}" stroke-width="4"></line>
71
- </pattern>
72
- </defs>
73
- EOD
74
-
75
- rect =<<EOD
76
- <rect x="#{x1}" y="#{y1}" width="#{x2}" height="#{y2}" stroke="none" fill="white" />"
77
- EOD
55
+ header = <<~HDR
56
+ <?xml version="1.0" standalone="no"?>
57
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
58
+ <svg width="#{@width}" height="#{@height}" viewBox="#{x1}, #{y1}, #{x2}, #{y2}" version="1.1" xmlns="http://www.w3.org/2000/svg">
59
+ <defs>
60
+ <marker id="arrow" markerUnits="strokeWidth" markerWidth="#{as2}" markerHeight="#{as2}" viewBox="0 0 #{as2} #{as2}" refX="#{as}" refY="0">
61
+ <polyline fill="none" stroke="#{@col_path}" stroke-width="1" points="0,#{as2},#{as},0,#{as2},#{as2}" />
62
+ </marker>
63
+ <pattern id="hatchBlack" x="10" y="10" width="10" height="10" patternUnits="userSpaceOnUse" patternTransform="rotate(45)">
64
+ <line x1="0" y="0" x2="0" y2="10" stroke="black" stroke-width="4"></line>
65
+ </pattern>
66
+ <pattern id="hatchForNode" x="10" y="10" width="10" height="10" patternUnits="userSpaceOnUse" patternTransform="rotate(45)">
67
+ <line x1="0" y="0" x2="0" y2="10" stroke="#{@col_node}" stroke-width="4"></line>
68
+ </pattern>
69
+ <pattern id="hatchForLeaf" x="10" y="10" width="10" height="10" patternUnits="userSpaceOnUse" patternTransform="rotate(45)">
70
+ <line x1="0" y="0" x2="0" y2="10" stroke="#{@col_leaf}" stroke-width="4"></line>
71
+ </pattern>
72
+ </defs>
73
+ HDR
74
+
75
+ rect = <<~RCT
76
+ <rect x="#{x1}" y="#{y1}" width="#{x2}" height="#{y2}" stroke="none" fill="white" />"
77
+ RCT
78
78
 
79
79
  footer = "</svg>"
80
80
 
@@ -86,17 +86,15 @@ EOD
86
86
  end
87
87
 
88
88
  def draw_a_path(s_x, s_y, t_x, t_y, target_arrow = :none)
89
-
90
- x_spacing = $h_gap_between_nodes * 1.25
91
- y_spacing = $height_connector * 0.65
89
+ x_spacing = @global[:h_gap_between_nodes] * 1.25
90
+ y_spacing = @global[:height_connector] * 0.65
92
91
 
93
92
  ymax = [s_y, t_y].max
94
- if ymax < @height
95
- new_y = @height + y_spacing
96
- else
97
- new_y = ymax + y_spacing
98
- end
99
-
93
+ new_y = if ymax < @height
94
+ @height + y_spacing
95
+ else
96
+ ymax + y_spacing
97
+ end
100
98
 
101
99
  if @visited_x[s_x]
102
100
  new_s_x = s_x - x_spacing * @visited_x[s_x]
@@ -114,67 +112,64 @@ EOD
114
112
  @visited_x[t_x] = 1
115
113
  end
116
114
 
117
- s_y += $h_gap_between_nodes / 2
118
- t_y += $h_gap_between_nodes / 2
119
- new_y += $h_gap_between_nodes / 2
115
+ s_y += @global[:h_gap_between_nodes] / 2
116
+ t_y += @global[:h_gap_between_nodes] / 2
117
+ new_y += @global[:h_gap_between_nodes] / 2
120
118
 
121
119
  dashed = true if target_arrow == :none
122
120
 
123
- if target_arrow == :single
121
+ case target_arrow
122
+ when :single
124
123
  @extra_lines << generate_line(new_s_x, s_y, new_s_x, new_y, @col_path, dashed)
125
124
  @extra_lines << generate_line(new_s_x, new_y, new_t_x, new_y, @col_path, dashed)
126
- @extra_lines << generate_line(new_t_x, new_y, new_t_x, t_y, @col_path ,dashed, true)
127
- elsif target_arrow == :double
125
+ @extra_lines << generate_line(new_t_x, new_y, new_t_x, t_y, @col_path, dashed, true)
126
+ when :double
128
127
  @extra_lines << generate_line(new_s_x, new_y, new_s_x, s_y, @col_path, dashed, true)
129
128
  @extra_lines << generate_line(new_s_x, new_y, new_t_x, new_y, @col_path, dashed)
130
- @extra_lines << generate_line(new_t_x, new_y, new_t_x, t_y, @col_path ,dashed, true)
129
+ @extra_lines << generate_line(new_t_x, new_y, new_t_x, t_y, @col_path, dashed, true)
131
130
  else
132
131
  @extra_lines << generate_line(new_s_x, s_y, new_s_x, new_y, @col_path, dashed)
133
132
  @extra_lines << generate_line(new_s_x, new_y, new_t_x, new_y, @col_path, dashed)
134
- @extra_lines << generate_line(new_t_x, new_y, new_t_x, t_y, @col_path ,dashed)
133
+ @extra_lines << generate_line(new_t_x, new_y, new_t_x, t_y, @col_path, dashed)
135
134
  end
136
135
 
137
136
  @height = new_y if new_y > @height
138
137
  end
139
138
 
140
139
  def draw_element(element)
141
- top = element.vertical_indent
142
-
143
- left = element.horizontal_indent
144
- bottom = top +$single_line_height
145
- right = left + element.content_width
146
-
140
+ top = element.vertical_indent
141
+ left = element.horizontal_indent
142
+ right = left + element.content_width
147
143
  txt_pos = left + (right - left) / 2
148
144
 
149
- if(element.type == ETYPE_LEAF)
150
- col = @col_leaf
151
- else
152
- col = @col_node
153
- end
145
+ col = if element.type == ETYPE_LEAF
146
+ @col_leaf
147
+ else
148
+ @col_node
149
+ end
154
150
 
155
151
  text_data = @text_styles.sub(/COLOR/, col)
156
152
  text_data = text_data.sub(/fontsize/, @fontsize.to_s + "px;")
157
153
  text_x = txt_pos - element.content_width / 2
158
- text_y = top + $single_line_height - $height_connector_to_text
154
+ text_y = top + @global[:single_line_height] - @global[:height_connector_to_text]
159
155
  text_data = text_data.sub(/X_VALUE/, text_x.to_s)
160
156
  text_data = text_data.sub(/Y_VALUE/, text_y.to_s)
161
- new_text = ""
157
+ new_text = +""
162
158
  this_x = 0
163
159
  this_y = 0
164
- bc = {:x => text_x - $h_gap_between_nodes / 2 , :y => top, :width => element.content_width + $h_gap_between_nodes, :height => nil}
160
+ bc = { x: text_x - @global[:h_gap_between_nodes] / 2, y: top, width: element.content_width + @global[:h_gap_between_nodes], height: nil }
165
161
  element.content.each_with_index do |l, idx|
166
162
  case l[:type]
167
163
  when :border, :bborder
168
164
  x1 = text_x
169
- if idx == 0
165
+ if idx.zero?
170
166
  text_y -= l[:height]
171
- elsif
167
+ else
172
168
  text_y += l[:height]
173
169
  end
174
- y1 = text_y - $single_line_height / 8
170
+ y1 = text_y - @global[:single_line_height] / 8
175
171
  x2 = text_x + element.content_width
176
172
  y2 = y1
177
- this_width = x2 - x1
178
173
  case l[:type]
179
174
  when :border
180
175
  stroke_width = FONT_SCALING
@@ -192,31 +187,23 @@ EOD
192
187
  end
193
188
  this_x = txt_pos - (ewidth / 2)
194
189
  end
195
- text_y += l[:elements].map{|e| e[:height]}.max if idx != 0
190
+ text_y += l[:elements].map { |e| e[:height] }.max if idx != 0
196
191
 
197
- l[:elements].each_with_index do |e, idx|
192
+ l[:elements].each do |e|
198
193
  escaped_text = e[:text].gsub('>', '&gt;').gsub('<', '&lt;');
199
194
  decorations = []
200
- if e[:decoration].include?(:overline)
201
- decorations << "overline"
202
- end
203
-
204
- if e[:decoration].include?(:underline)
205
- decorations << "underline"
206
- end
207
-
208
- if e[:decoration].include?(:linethrough)
209
- decorations << "line-through"
210
- end
211
- decoration ="text-decoration=\"" + decorations.join(" ") + "\""
195
+ decorations << "overline" if e[:decoration].include?(:overline)
196
+ decorations << "underline" if e[:decoration].include?(:underline)
197
+ decorations << "line-through" if e[:decoration].include?(:linethrough)
198
+ decoration = "text-decoration=\"" + decorations.join(" ") + "\""
212
199
 
213
200
  style = "style=\""
214
201
  if e[:decoration].include?(:small)
215
202
  style += "font-size: #{(SUBSCRIPT_CONST.to_f * 100).to_i}%; "
216
- this_y = text_y - (($single_X_metrics.height - $single_X_metrics.height * SUBSCRIPT_CONST) / 4) + 2
203
+ this_y = text_y - ((@global[:single_x_metrics].height - @global[:single_x_metrics].height * SUBSCRIPT_CONST) / 4) + 2
217
204
  elsif e[:decoration].include?(:superscript)
218
205
  style += "font-size: #{(SUBSCRIPT_CONST.to_f * 100).to_i}%; "
219
- this_y = text_y - ($single_X_metrics.height / 4) + 1
206
+ this_y = text_y - (@global[:single_x_metrics].height / 4) + 1
220
207
  elsif e[:decoration].include?(:subscript)
221
208
  style += "font-size: #{(SUBSCRIPT_CONST.to_f * 100).to_i}%; "
222
209
  this_y = text_y + 4
@@ -224,72 +211,59 @@ EOD
224
211
  this_y = text_y
225
212
  end
226
213
 
227
- if e[:decoration].include?(:bold) || e[:decoration].include?(:bolditalic)
228
- style += "font-weight: bold; "
229
- end
230
-
231
- if e[:decoration].include?(:italic) || e[:decoration].include?(:bolditalic)
232
- style += "font-style: italic; "
233
- end
234
-
214
+ style += "font-weight: bold; " if e[:decoration].include?(:bold) || e[:decoration].include?(:bolditalic)
215
+ style += "font-style: italic; " if e[:decoration].include?(:italic) || e[:decoration].include?(:bolditalic)
235
216
  style += "\""
236
217
 
237
218
  case @fontstyle
238
219
  when /(?:cjk)/
239
220
  fontstyle = "'WenQuanYi Zen Hei', 'Noto Sans', OpenMoji, 'OpenMoji Color', 'OpenMoji Black', sans-serif"
240
221
  when /(?:sans)/
241
- if e[:cjk]
242
- fontstyle = "'Noto Sans JP', 'Noto Sans', OpenMoji, 'OpenMoji Color', 'OpenMoji Black', sans-serif"
243
- else
244
- fontstyle = "'Noto Sans', 'Noto Sans JP', OpenMoji, 'OpenMoji Color', 'OpenMoji Black', sans-serif"
245
- end
222
+ fontstyle = if e[:cjk]
223
+ "'Noto Sans JP', 'Noto Sans', OpenMoji, 'OpenMoji Color', 'OpenMoji Black', sans-serif"
224
+ else
225
+ "'Noto Sans', 'Noto Sans JP', OpenMoji, 'OpenMoji Color', 'OpenMoji Black', sans-serif"
226
+ end
246
227
  when /(?:serif)/
247
- if e[:cjk]
248
- fontstyle = "'Noto Serif JP', 'Noto Serif', OpenMoji, 'OpenMoji Color', 'OpenMoji Black', serif"
249
- else
250
- fontstyle = "'Noto Serif', 'Noto Serif JP', OpenMoji, 'OpenMoji Color', 'OpenMoji Black', serif"
251
- end
228
+ fontstyle = if e[:cjk]
229
+ "'Noto Serif JP', 'Noto Serif', OpenMoji, 'OpenMoji Color', 'OpenMoji Black', serif"
230
+ else
231
+ "'Noto Serif', 'Noto Serif JP', OpenMoji, 'OpenMoji Color', 'OpenMoji Black', serif"
232
+ end
252
233
  end
253
234
 
254
235
  if e[:decoration].include?(:box) || e[:decoration].include?(:circle) || e[:decoration].include?(:bar)
255
236
  enc_height = e[:height]
256
237
  enc_y = this_y - e[:height] * 0.8 + FONT_SCALING
257
-
258
- if e[:text].size == 1
259
- enc_width = e[:width]
260
- enc_x = this_x
261
- else
262
- enc_width = e[:width]
263
- enc_x = this_x
264
- end
238
+ enc_width = e[:width]
239
+ enc_x = this_x
265
240
 
266
241
  if e[:decoration].include?(:hatched)
267
242
  case element.type
268
243
  when ETYPE_LEAF
269
- if @color
270
- fill = "url(#hatchForLeaf)"
271
- else
272
- fill = "url(#hatchBlack)"
273
- end
244
+ fill = if @color
245
+ "url(#hatchForLeaf)"
246
+ else
247
+ "url(#hatchBlack)"
248
+ end
274
249
  when ETYPE_NODE
275
- if @color
276
- fill = "url(#hatchForNode)"
277
- else
278
- fill = "url(#hatchBlack)"
279
- end
250
+ fill = if @color
251
+ "url(#hatchForNode)"
252
+ else
253
+ "url(#hatchBlack)"
254
+ end
280
255
  end
281
256
  else
282
257
  fill = "none"
283
258
  end
284
259
 
285
260
  enc = nil
286
- bar = nil
287
261
 
288
- if e[:decoration].include?(:bstroke)
289
- stroke_width = FONT_SCALING * 2.5
290
- else
291
- stroke_width = FONT_SCALING
292
- end
262
+ stroke_width = if e[:decoration].include?(:bstroke)
263
+ FONT_SCALING * 2.5
264
+ else
265
+ FONT_SCALING
266
+ end
293
267
 
294
268
  if e[:decoration].include?(:box)
295
269
  enc = "<rect style='stroke: #{col}; stroke-width:#{stroke_width};'
@@ -319,25 +293,22 @@ EOD
319
293
  r_arrowhead = "<polyline stroke-linejoin='bevel' fill='none' stroke='#{col}' stroke-width='#{stroke_width}' points='#{x2 - ar_hwidth},#{y2 - ar_hwidth / 2} #{x2},#{y2} #{x2 - ar_hwidth},#{y2 + ar_hwidth / 2}' />\n"
320
294
  @extra_lines << r_arrowhead
321
295
  end
322
-
323
-
324
296
  end
325
297
 
326
298
  @extra_lines << enc if enc
327
299
 
328
- if e[:text].size == 1
329
- this_x += (e[:height] - e[:content_width]) / 2
330
- else
331
- this_x += $width_half_X / 2
332
- end
300
+ this_x += if e[:text].size == 1
301
+ (e[:height] - e[:content_width]) / 2
302
+ else
303
+ @global[:width_half_x] / 2
304
+ end
305
+
333
306
  new_text << set_tspan(this_x, this_y, style, decoration, fontstyle, escaped_text)
334
- if e[:text].size == 1
335
- this_x += e[:content_width]
336
- this_x += (e[:height] - e[:content_width]) / 2
337
- else
338
- this_x += e[:content_width]
339
- this_x += $width_half_X / 2
340
- end
307
+ this_x += if e[:text].size == 1
308
+ e[:content_width] + (e[:height] - e[:content_width]) / 2
309
+ else
310
+ e[:content_width] + @global[:width_half_x] / 2
311
+ end
341
312
 
342
313
  elsif e[:decoration].include?(:whitespace)
343
314
  this_x += e[:width]
@@ -346,26 +317,26 @@ EOD
346
317
  new_text << set_tspan(this_x, this_y, style, decoration, fontstyle, escaped_text)
347
318
  this_x += e[:width]
348
319
  end
349
-
350
320
  end
351
321
  end
352
322
  @height = text_y if text_y > @height
353
323
  end
354
- bc[:y] = bc[:y] + $height_connector_to_text * 3 / 4
355
- bc[:height] = text_y - bc[:y] + $height_connector_to_text
356
- if element.enclosure == :brackets
357
- @extra_lines << generate_line(bc[:x], bc[:y], bc[:x] + $h_gap_between_nodes / 2, bc[:y], col)
324
+ bc[:y] = bc[:y] + @global[:height_connector_to_text] * 3 / 4
325
+ bc[:height] = text_y - bc[:y] + @global[:height_connector_to_text]
326
+ case element.enclosure
327
+ when :brackets
328
+ @extra_lines << generate_line(bc[:x], bc[:y], bc[:x] + @global[:h_gap_between_nodes] / 2, bc[:y], col)
358
329
  @extra_lines << generate_line(bc[:x], bc[:y], bc[:x], bc[:y] + bc[:height], col)
359
- @extra_lines << generate_line(bc[:x], bc[:y] + bc[:height], bc[:x] + $h_gap_between_nodes / 2, bc[:y] + bc[:height], col)
360
- @extra_lines << generate_line(bc[:x] + bc[:width], bc[:y], bc[:x] + bc[:width] - $h_gap_between_nodes / 2, bc[:y], col)
330
+ @extra_lines << generate_line(bc[:x], bc[:y] + bc[:height], bc[:x] + @global[:h_gap_between_nodes] / 2, bc[:y] + bc[:height], col)
331
+ @extra_lines << generate_line(bc[:x] + bc[:width], bc[:y], bc[:x] + bc[:width] - @global[:h_gap_between_nodes] / 2, bc[:y], col)
361
332
  @extra_lines << generate_line(bc[:x] + bc[:width], bc[:y], bc[:x] + bc[:width], bc[:y] + bc[:height], col)
362
- @extra_lines << generate_line(bc[:x] + bc[:width], bc[:y] + bc[:height], bc[:x] + bc[:width] - $h_gap_between_nodes / 2, bc[:y] + bc[:height], col)
363
- elsif element.enclosure == :rectangle
333
+ @extra_lines << generate_line(bc[:x] + bc[:width], bc[:y] + bc[:height], bc[:x] + bc[:width] - @global[:h_gap_between_nodes] / 2, bc[:y] + bc[:height], col)
334
+ when :rectangle
364
335
  @extra_lines << generate_line(bc[:x], bc[:y], bc[:x] + bc[:width], bc[:y], col)
365
336
  @extra_lines << generate_line(bc[:x], bc[:y], bc[:x], bc[:y] + bc[:height], col)
366
337
  @extra_lines << generate_line(bc[:x] + bc[:width], bc[:y], bc[:x] + bc[:width], bc[:y] + bc[:height], col)
367
338
  @extra_lines << generate_line(bc[:x], bc[:y] + bc[:height], bc[:x] + bc[:width], bc[:y] + bc[:height], col)
368
- elsif element.enclosure == :brectangle
339
+ when :brectangle
369
340
  @extra_lines << generate_line(bc[:x], bc[:y], bc[:x] + bc[:width], bc[:y], col, false, false, 2)
370
341
  @extra_lines << generate_line(bc[:x], bc[:y], bc[:x], bc[:y] + bc[:height], col, false, false, 2)
371
342
  @extra_lines << generate_line(bc[:x] + bc[:width], bc[:y], bc[:x] + bc[:width], bc[:y] + bc[:height], col, false, false, 2)
@@ -384,9 +355,7 @@ EOD
384
355
  "<tspan x='#{this_x}' y='#{this_y}' #{style} #{decoration} font-family=\"#{fontstyle}\">#{text}</tspan>\n"
385
356
  end
386
357
 
387
-
388
358
  def draw_paths
389
- rockbottom = 0
390
359
  path_pool_target = {}
391
360
  path_pool_other = {}
392
361
  path_pool_source = {}
@@ -397,7 +366,7 @@ EOD
397
366
  elist.each do |element|
398
367
  x1 = element.horizontal_indent + element.content_width / 2
399
368
  y1 = element.vertical_indent + element.content_height
400
- y1 += $height_connector_to_text if element.enclosure != :none
369
+ y1 += @global[:height_connector_to_text] if element.enclosure != :none
401
370
  et = element.path
402
371
  et.each do |tr|
403
372
  if /\A>(\d+)\z/ =~ tr
@@ -417,28 +386,24 @@ EOD
417
386
  path_pool_source[tr] = [x1, y1]
418
387
  end
419
388
  path_flags << tr
420
- if path_flags.tally.any?{|k, v| v > 2}
421
- raise RSTError, "Error: input text contains a path having more than two ends:\n > #{tr}"
422
- end
389
+ raise RSTError, "Error: input text contains a path having more than two ends:\n > #{tr}" if path_flags.tally.any? { |_k, v| v > 2 }
423
390
  end
424
391
  end
425
392
 
426
393
  path_flags.tally.each do |k, v|
427
- if v == 1
428
- raise RSTError, "Error: input text contains a path having only one end:\n > #{k}"
429
- end
394
+ raise RSTError, "Error: input text contains a path having only one end:\n > #{k}" if v == 1
430
395
  end
431
396
 
432
397
  paths = []
433
398
  path_pool_source.each do |k, v|
434
399
  path_flags.delete(k)
435
- if targets = path_pool_target[k]
400
+ if (targets = path_pool_target[k])
436
401
  targets.each do |t|
437
- paths << {x1: v[0], y1: v[1], x2: t[0], y2: t[1], arrow: :single}
402
+ paths << { x1: v[0], y1: v[1], x2: t[0], y2: t[1], arrow: :single }
438
403
  end
439
- elsif others = path_pool_other[k]
404
+ elsif (others = path_pool_other[k])
440
405
  others.each do |t|
441
- paths << {x1: v[0], y1: v[1], x2: t[0], y2: t[1], arrow: :none}
406
+ paths << { x1: v[0], y1: v[1], x2: t[0], y2: t[1], arrow: :none }
442
407
  end
443
408
  end
444
409
  end
@@ -447,13 +412,13 @@ EOD
447
412
  targets = path_pool_target[k]
448
413
  fst = targets.shift
449
414
  targets.each do |t|
450
- paths << {x1: fst[0], y1: fst[1], x2: t[0], y2: t[1], arrow: :double}
415
+ paths << { x1: fst[0], y1: fst[1], x2: t[0], y2: t[1], arrow: :double }
451
416
  end
452
417
  end
453
418
 
454
419
  paths.each do |t|
455
- draw_a_path(t[:x1], t[:y1] + $height_connector_to_text / 2,
456
- t[:x2], t[:y2] + $height_connector_to_text / 2,
420
+ draw_a_path(t[:x1], t[:y1] + @global[:height_connector_to_text] / 2,
421
+ t[:x2], t[:y2] + @global[:height_connector_to_text] / 2,
457
422
  t[:arrow])
458
423
  end
459
424
 
@@ -461,11 +426,11 @@ EOD
461
426
  end
462
427
 
463
428
  def generate_line(x1, y1, x2, y2, col, dashed = false, arrow = false, stroke_width = 1)
464
- if arrow
465
- string = "marker-end='url(#arrow)' "
466
- else
467
- string = ""
468
- end
429
+ string = if arrow
430
+ "marker-end='url(#arrow)' "
431
+ else
432
+ ""
433
+ end
469
434
  dasharray = dashed ? "stroke-dasharray='8 8'" : ""
470
435
  swidth = FONT_SCALING * stroke_width
471
436
 
@@ -474,36 +439,34 @@ EOD
474
439
 
475
440
  # Draw a line between child/parent elements
476
441
  def line_to_parent(parent, child)
477
- if (child.horizontal_indent == 0 )
478
- return
479
- end
442
+ return if child.horizontal_indent.zero?
480
443
 
481
444
  if @polyline
482
445
  chi_x = child.horizontal_indent + child.content_width / 2
483
- chi_y = child.vertical_indent + $height_connector_to_text / 2
446
+ chi_y = child.vertical_indent + @global[:height_connector_to_text] / 2
484
447
 
485
448
  par_x = parent.horizontal_indent + parent.content_width / 2
486
- par_y = parent.vertical_indent + parent.content_height + $height_connector_to_text
449
+ par_y = parent.vertical_indent + parent.content_height + @global[:height_connector_to_text]
487
450
 
488
451
  mid_x1 = chi_x
489
- mid_y1 = par_y + (chi_y - par_y) / 2
452
+ mid_y1 = par_y + (chi_y - par_y) / 2
490
453
 
491
454
  mid_x2 = par_x
492
455
  mid_y2 = mid_y1
493
456
 
494
457
  @tree_data += @polyline_styles.sub(/CHIX/, chi_x.to_s)
495
- .sub(/CHIY/, chi_y.to_s)
496
- .sub(/MIDX1/, mid_x1.to_s)
497
- .sub(/MIDY1/, mid_y1.to_s)
498
- .sub(/MIDX2/, mid_x2.to_s)
499
- .sub(/MIDY2/, mid_y2.to_s)
500
- .sub(/PARX/, par_x.to_s)
501
- .sub(/PARY/, par_y.to_s)
458
+ .sub(/CHIY/, chi_y.to_s)
459
+ .sub(/MIDX1/, mid_x1.to_s)
460
+ .sub(/MIDY1/, mid_y1.to_s)
461
+ .sub(/MIDX2/, mid_x2.to_s)
462
+ .sub(/MIDY2/, mid_y2.to_s)
463
+ .sub(/PARX/, par_x.to_s)
464
+ .sub(/PARY/, par_y.to_s)
502
465
  else
503
466
  x1 = child.horizontal_indent + child.content_width / 2
504
- y1 = child.vertical_indent + $height_connector_to_text / 2
467
+ y1 = child.vertical_indent + @global[:height_connector_to_text] / 2
505
468
  x2 = parent.horizontal_indent + parent.content_width / 2
506
- y2 = parent.vertical_indent + parent.content_height + $height_connector_to_text
469
+ y2 = parent.vertical_indent + parent.content_height + @global[:height_connector_to_text]
507
470
 
508
471
  line_data = @line_styles.sub(/X1/, x1.to_s)
509
472
  line_data = line_data.sub(/Y1/, y1.to_s)
@@ -514,16 +477,14 @@ EOD
514
477
 
515
478
  # Draw a triangle between child/parent elements
516
479
  def triangle_to_parent(parent, child)
517
- if (child.horizontal_indent == 0)
518
- return
519
- end
480
+ return if child.horizontal_indent.zero?
520
481
 
521
482
  x1 = child.horizontal_indent
522
- y1 = child.vertical_indent + $height_connector_to_text / 2
483
+ y1 = child.vertical_indent + @global[:height_connector_to_text] / 2
523
484
  x2 = child.horizontal_indent + child.content_width
524
- y2 = child.vertical_indent + $height_connector_to_text / 2
485
+ y2 = child.vertical_indent + @global[:height_connector_to_text] / 2
525
486
  x3 = parent.horizontal_indent + parent.content_width / 2
526
- y3 = parent.vertical_indent + parent.content_height + $height_connector_to_text
487
+ y3 = parent.vertical_indent + parent.content_height + @global[:height_connector_to_text]
527
488
 
528
489
  polygon_data = @polygon_styles.sub(/X1/, x1.to_s)
529
490
  polygon_data = polygon_data.sub(/Y1/, y1.to_s)