rsyntaxtree 0.8.0 → 0.8.3

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: a93fb86aba069b61d5095d8cd565153b36ea9cdc0bd9903b2ffc656bae5986cb
4
- data.tar.gz: a11db6cdb80b0ccdc118761a4f2131915bffd3dc1a13343be4df662e13bb88b3
3
+ metadata.gz: c06870de3a591df5cdde4b1061529a81455614447d7f6279dc056b06b1631924
4
+ data.tar.gz: '095426d0a0b46db22be01e8b57e631eea535eec751488ede9aeaaa9bb72bc7ac'
5
5
  SHA512:
6
- metadata.gz: 8ce0bbb49b1c7207aa5d65958e9185dd2e28c762bf39304077b37d03c8e7a2e32b79f2b490d110a6223d1b1ca7df591f43ec82bbc7532f5f4a6c406107e55d72
7
- data.tar.gz: 66849abf7520966907cece66a1f12fc3eb29384911ddda5f518ad23ecdf7249d589edebfec98c42f35f468c1dea7204e285a38ddb37e510610bec08807d6d154
6
+ metadata.gz: 95ebed8e7a176851b1d7eccc0fdd4a95fd8a8e432efd696e63acc60558fa592e223b2b4e53d0a4f0d7afcd8f5dd858cf40b361eb9b3525176276098772b6d168
7
+ data.tar.gz: b35881b52f62faf9b6d7a34213b1547ff19f99d7338d15bfd26f81cb1576cf3d642e8c11d4fe2aa66c6d1ef1edeb42c287a5c0033af77833d7a3577e045b4162
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # RSyntaxTree: yet another syntax tree generator in Ruby
1
+ # 🌲 RSyntaxTree: yet another syntax tree generator in Ruby
2
2
 
3
3
  **RSyntaxTree** is a graphical syntax tree generator written in the Ruby programming language inspired by [phpSyntaxTree](http://ironcreek.net/phpsyntaxtree/).
4
4
 
data/bin/rsyntaxtree CHANGED
@@ -27,9 +27,9 @@ EOS
27
27
  opt :font, "Path to a ttf font used to generate tree (optional)", :type => String
28
28
  opt :fontsize, "Size: 8-26",
29
29
  :default => 16
30
- opt :margin, "Margin: 0-120",
31
- :default => 0
32
- opt :vheight, "Connector Height: 0.5-2.0",
30
+ opt :margin, "Margin: 1-5",
31
+ :default => 1
32
+ opt :vheight, "Connector Height: 0.5-5.0",
33
33
  :default => 1.0
34
34
  opt :color, "Color text and bars: on or off",
35
35
  :default => "on"
@@ -48,8 +48,8 @@ Optimist::die :fontsize, "must be in the range of 8-26" unless opts[:fontsize] >
48
48
  Optimist::die :color, "must be either on or off" unless /\A(on|off)\z/ =~ opts[:color]
49
49
  Optimist::die :symmetrize, "must be either on or off" unless /\A(on|off)\z/ =~ opts[:symmetrize]
50
50
  Optimist::die :autosub, "must be either on or off" unless /\A(on|off)\z/ =~ opts[:autosub]
51
- Optimist::die :margin, "must be in the range of 0-120" if opts[:margin] < 0 || opts[:margin] > 120
52
- Optimist::die :vheight, "must be in the range of 0.5-2.0" if opts[:vheight] < 0.5 || opts[:vheight] > 2.0
51
+ Optimist::die :margin, "must be in the range of 1-5" if opts[:margin] < 1 || opts[:margin] > 5
52
+ Optimist::die :vheight, "must be in the range of 0.5-5.0" if opts[:vheight] < 0.5 || opts[:vheight] > 5.0
53
53
 
54
54
  string_opts = {}
55
55
  opts.each do |key, value|
File without changes
File without changes
@@ -31,6 +31,7 @@ class Element
31
31
  @content = content.gsub("^"){""} # The actual element content
32
32
  @triangle = false # draw triangle instead of stright bar when in auto mode
33
33
  end
34
+ # workaround to save "[A [B [C] [D] ] [E [F] [G [H] [J] ] ] ]"
34
35
  end
35
36
 
36
37
  # Debug helper function
@@ -58,7 +58,8 @@ class Graph
58
58
 
59
59
  def img_get_txt_metrics(text, font, font_size, multiline)
60
60
 
61
- background = Image.new(500, 250)
61
+ # background = Image.new(500, 250)
62
+ background = Image.new(1, 1)
62
63
 
63
64
  gc = Draw.new
64
65
  gc.annotate(background, 0, 0, 0, 0, text) do |gc|
@@ -73,7 +74,6 @@ class Graph
73
74
  else
74
75
  metrics = gc.get_type_metrics(background, text)
75
76
  end
76
-
77
77
  return metrics
78
78
  end
79
79
 
@@ -150,6 +150,7 @@ class Graph
150
150
  e_arr = @e_list.get_elements
151
151
 
152
152
  h = @e_list.get_level_height
153
+
153
154
  h.times do |i|
154
155
  x = 0
155
156
  e_arr.each do |j|
@@ -189,6 +190,7 @@ class Graph
189
190
  end
190
191
  end
191
192
  return true if !@symmetrize
193
+
192
194
  h.times do |i|
193
195
  curlevel = h - i - 1
194
196
  indent = 0
@@ -238,26 +240,11 @@ class Graph
238
240
  right = k.indent + kw
239
241
  draw_element(left, curlevel, right - left, j.content, j.type)
240
242
  @e_list.set_indent(j.id, left + (right - left) / 2 - tw / 2)
241
- else
242
- parent = @e_list.get_id(j.parent)
243
- pw = img_get_txt_width(parent.content, @font, @font_size)
244
- pleft = parent.indent
245
- pright = pleft + pw
246
- left = j.indent
247
- right = left + tw
248
- if pw > tw
249
- left = pleft
250
- right = pright
251
- end
252
- draw_element(left, curlevel, right - left, j.content, j.type)
253
- @e_list.set_indent(j.id, left + (right - left) / 2 - tw / 2)
254
- end
255
243
 
256
- unless children.empty?
257
244
  k = @e_list.get_id(children[0])
258
245
  words = k.content.split(" ")
259
246
  dw = img_get_txt_width(k.content, @font, @font_size)
260
- unless @leafstyle == "nothing" && ETYPE_LEAF == k.type
247
+ unless (@leafstyle == "nothing" && ETYPE_LEAF == k.type)
261
248
  if (@leafstyle == "triangle" && ETYPE_LEAF == k.type && words.length > 0)
262
249
  txt_width = img_get_txt_width(k.content, @font, @font_size)
263
250
  triangle_to_parent(k.indent, curlevel + 1, dw, txt_width)
@@ -272,7 +259,33 @@ class Graph
272
259
  line_to_parent(k.indent, curlevel + 1, dw, j.indent, tw)
273
260
  end
274
261
  end
262
+
263
+ else
264
+ parent = @e_list.get_id(j.parent)
265
+ pw = img_get_txt_width(parent.content, @font, @font_size)
266
+ pleft = parent.indent
267
+ pright = pleft + pw
268
+ if curlevel == (h - 1) && e_arr.size == idx + 1
269
+ e_arr.select{|l|l.level == curlevel}.each do |l|
270
+ lw = img_get_txt_width(l.content, @font, @font_size)
271
+ left = l.indent
272
+ right = left + lw
273
+ @e_list.set_indent(l.id, left + (right - left) / 2 - tw / 2)
274
+ draw_element(left, curlevel, right - left, l.content, l.type)
275
+ end
276
+ break
277
+ else
278
+ left = j.indent
279
+ right = left + tw
280
+ if pw > tw
281
+ left = pleft
282
+ right = pright
283
+ end
284
+ draw_element(left, curlevel, right - left, j.content, j.type)
285
+ @e_list.set_indent(j.id, left + (right - left) / 2 - tw / 2)
286
+ end
275
287
  end
288
+
276
289
  end
277
290
  end
278
291
  end
@@ -286,7 +299,7 @@ class Graph
286
299
 
287
300
  def get_txt_only(text)
288
301
  text = text.strip
289
- if /\A([\+\-\=\*\~]+).+/ =~ text
302
+ if /\A([\+\-\=\*\#\~]+).+/ =~ text
290
303
  prefix = $1
291
304
  prefix_l = Regexp.escape(prefix)
292
305
  prefix_r = Regexp.escape(prefix.reverse)
@@ -18,18 +18,23 @@ require 'graph'
18
18
 
19
19
  class SVGGraph < Graph
20
20
 
21
- def initialize(e_list, metrics, symmetrize, color, leafstyle, multibyte, fontstyle, font, font_size)
21
+ def initialize(e_list, metrics, symmetrize, color, leafstyle, multibyte, fontstyle, font, font_cjk, font_size)
22
22
 
23
23
  # Store class-specific parameters
24
- @fontstyle = fontstyle
25
24
  @font = multibyte ? font_cjk : font
26
25
  @font_size = font_size
26
+ case fontstyle
27
+ when /(?:sans|cjk)/
28
+ @fontstyle = "sans-serif"
29
+ when /(?:serif|math)/
30
+ @fontstyle = "serif"
31
+ end
27
32
 
28
33
  super(e_list, metrics, symmetrize, color, leafstyle, multibyte, @font, @font_size)
29
34
 
30
- @line_styles = "<line style='stroke:black; stroke-width:1;' x1='X1' y1='Y1' x2='X2' y2='Y2' />\n"
31
- @polygon_styles = "<polygon style='fill: none; stroke: black; stroke-width:1;' points='X1 Y1 X2 Y2 X3 Y3' />\n"
32
- @text_styles = "<text style='fill: COLOR; font-size: FONT_SIZEpx; ST; WA;' x='X_VALUE' y='Y_VALUE' TD font-family='#{@font}'>CONTENT</text>\n"
35
+ @line_styles = "<line style='stroke:black; stroke-width:#{FONT_SCALING};' x1='X1' y1='Y1' x2='X2' y2='Y2' />\n"
36
+ @polygon_styles = "<polygon style='fill: none; stroke: black; stroke-width:#{FONT_SCALING};' points='X1 Y1 X2 Y2 X3 Y3' />\n"
37
+ @text_styles = "<text style='fill: COLOR; font-size: FONT_SIZEpx; ST; WA;' x='X_VALUE' y='Y_VALUE' TD font-family='#{@fontstyle}'>CONTENT</text>\n"
33
38
  @tree_data = String.new
34
39
  end
35
40
 
@@ -115,6 +120,10 @@ EOD
115
120
  main_weight = ""
116
121
  end
117
122
 
123
+ if /\A#(.+)#\z/ =~ main
124
+ main = $1
125
+ end
126
+
118
127
  # Calculate text size for the main and the
119
128
  # subscript part of the element
120
129
  # symbols for underline/overline removed temporarily
@@ -153,6 +162,10 @@ EOD
153
162
  sub_width = 0
154
163
  end
155
164
 
165
+ if /\A#(.+)#\z/ =~ sub
166
+ sub = $1
167
+ end
168
+
156
169
  # Center text in the element
157
170
  txt_width = main_width + sub_width
158
171
  txt_pos = left + (right - left) / 2 - txt_width / 2
@@ -63,10 +63,6 @@ class TreeGraph < Graph
63
63
  def to_blob(fileformat='PNG')
64
64
  draw
65
65
  @im.border!(@margin, @margin, "white")
66
- # return @im.to_blob do
67
- # self.format = fileformat
68
- # self.interlace = PlaneInterlace
69
- # end
70
66
  @im.format = fileformat
71
67
  @im.interlace = PlaneInterlace
72
68
  return @im.to_blob
@@ -104,6 +100,9 @@ class TreeGraph < Graph
104
100
  elsif /\A\-(.+)\-\z/ =~ main
105
101
  main = $1
106
102
  main_decoration = UnderlineDecoration
103
+ elsif /\A\~(.+)\~\z/ =~ main
104
+ main = $1
105
+ main_decoration = LineThroughDecoration
107
106
  else
108
107
  main_decoration = NoDecoration
109
108
  end
@@ -127,7 +126,7 @@ class TreeGraph < Graph
127
126
  end
128
127
  end
129
128
 
130
- if /\A\~(.+)\~\z/ =~ main
129
+ if /\A#(.+)#\z/ =~ main
131
130
  main = $1
132
131
  main_font = @font_math
133
132
  end
@@ -142,8 +141,10 @@ class TreeGraph < Graph
142
141
  sub_decoration = OverlineDecoration
143
142
  elsif /\A\-(.+)\-\z/ =~ sub
144
143
  sub = $1
145
- @gc.decorate(UnderlineDecoration)
146
144
  sub_decoration = UnderlineDecoration
145
+ elsif /\A\~(.+)\~z/ =~ sub
146
+ sub = $1
147
+ sub_decoration = LineThroughDecoration
147
148
  else
148
149
  sub_decoration = NoDecoration
149
150
  end
@@ -166,7 +167,7 @@ class TreeGraph < Graph
166
167
  end
167
168
  end
168
169
 
169
- if /\A~(.+)~\z/ =~ sub
170
+ if /\A#(.+)#\z/ =~ sub
170
171
  sub = $1
171
172
  sub_font = @font_math
172
173
  end
@@ -231,7 +232,7 @@ class TreeGraph < Graph
231
232
 
232
233
  @gc.fill("none")
233
234
  @gc.stroke @col_line
234
- @gc.stroke_width 1
235
+ @gc.stroke_width 1 * FONT_SCALING
235
236
  @gc.line(fromLeft.ceil, fromTop.ceil, toLeft.ceil, toBot.ceil)
236
237
  end
237
238
 
@@ -256,7 +257,7 @@ class TreeGraph < Graph
256
257
 
257
258
  @gc.fill("none")
258
259
  @gc.stroke @col_line
259
- @gc.stroke_width 1
260
+ @gc.stroke_width 1 * 2
260
261
  @gc.line(fromLeft1, fromTop, toLeft, toBot)
261
262
  @gc.line(fromLeft2, fromTop, toLeft, toBot)
262
263
  @gc.line(fromLeft1, fromTop, fromLeft2, fromTop)
@@ -1,4 +1,4 @@
1
1
  module RSyntaxTree
2
- VERSION = "0.8.0"
2
+ VERSION = "0.8.3"
3
3
  end
4
4
 
data/lib/rsyntaxtree.rb CHANGED
@@ -8,9 +8,9 @@
8
8
  # Facade of rsyntaxtree library. When loaded by a driver script, it does all
9
9
  # the necessary 'require' to use the library.
10
10
  #
11
- # This file is part of RSyntaxTree, which is a ruby port of Andre Eisenbach's
11
+ # This file is part of RSyntaxTree, which is originally a ruby port of Andre Eisenbach's
12
12
  # excellent program phpSyntaxTree.
13
- # Copyright (c) 2007-2018 Yoichiro Hasebe <yohasebe@gmail.com>
13
+ # Copyright (c) 2007-2021 Yoichiro Hasebe <yohasebe@gmail.com>
14
14
  # Copyright (c) 2003-2004 Andre Eisenbach <andre@ironcreek.net>
15
15
 
16
16
  $LOAD_PATH << File.join( File.dirname(__FILE__), 'rsyntaxtree')
@@ -31,8 +31,9 @@ ETYPE_UNDEFINED = 0
31
31
  ETYPE_NODE = 1
32
32
  ETYPE_LEAF = 2
33
33
  SUBSCRIPT_CONST = 0.7
34
+ FONT_SCALING = 2
34
35
 
35
- class RSGenerator
36
+ class RSGenerator
36
37
  def initialize(params = {})
37
38
  new_params = {}
38
39
  params.each do |keystr, value|
@@ -51,9 +52,9 @@ class RSGenerator
51
52
  when :symmetrize, :color, :autosub
52
53
  new_params[key] = value && value != "off" ? true : false
53
54
  when :fontsize
54
- new_params[key] = value.to_i
55
+ new_params[key] = value.to_i * FONT_SCALING
55
56
  when :margin
56
- new_params[key] = value.to_i
57
+ new_params[key] = value.to_i * FONT_SCALING * 4
57
58
  when :vheight
58
59
  new_params[key] = value.to_f
59
60
  when :fontstyle
@@ -82,11 +83,11 @@ class RSGenerator
82
83
  new_params[:font_cjk] = FONT_DIR + "/wqy-zenhei.ttf"
83
84
  new_params[:fontstyle] = "sans"
84
85
  elsif value == "modern-math" || value == "math"
85
- new_params[:font] = FONT_DIR + "/latinmodern-math.otf"
86
- new_params[:font_it] = FONT_DIR + "/lmroman10-italic.otf"
87
- new_params[:font_bd] = FONT_DIR + "/lmroman10-bold.otf"
88
- new_params[:font_bdit] = FONT_DIR + "/lmroman10-bolditalic.otf"
89
- new_params[:font_math] = FONT_DIR + "/latinmodern-math.otf"
86
+ new_params[:font] = FONT_DIR + "/latinmodern-math.otf"
87
+ new_params[:font_it] = FONT_DIR + "/lmroman10-italic.otf"
88
+ new_params[:font_bd] = FONT_DIR + "/lmroman10-bold.otf"
89
+ new_params[:font_bdit] = FONT_DIR + "/lmroman10-bolditalic.otf"
90
+ new_params[:font_math] = FONT_DIR + "/latinmodern-math.otf"
90
91
  new_params[:font_cjk] = FONT_DIR + "/NotoSerifCJKjp-Regular.otf"
91
92
  new_params[:fontstyle] = "math"
92
93
  end
@@ -112,7 +113,7 @@ class RSGenerator
112
113
  :font_it => "/NotoSans-Italic.ttf",
113
114
  :font_bd => "/NotoSans-Bold.ttf",
114
115
  :font_bdit => "/NotoSans-BoldItalic.ttf",
115
- :font_math => "/NotoSansMath-Regular.ttf"
116
+ :font_math => "/NotoSansMath-Regular.ttf"
116
117
  }
117
118
  @metrics = {
118
119
  :e_width => 120,
@@ -124,8 +125,8 @@ class RSGenerator
124
125
  }
125
126
 
126
127
  @params.merge! new_params
127
- @params[:fontsize] = @params[:fontsize] * 2
128
- @params[:margin] = @params[:margin] * 2
128
+ @params[:fontsize] = @params[:fontsize] * FONT_SCALING
129
+ @params[:margin] = @params[:margin] * FONT_SCALING
129
130
  @metrics[:v_space] = @metrics[:v_space] * @params[:vheight]
130
131
  end
131
132
 
@@ -161,8 +162,8 @@ class RSGenerator
161
162
  sp.auto_subscript if @params[:autosub]
162
163
  elist = sp.get_elementlist
163
164
  graph = SVGGraph.new(elist, @metrics,
164
- @params[:symmetrize], @params[:color], @params[:leafstyle], @params[:multibyte],
165
- @params[:fontstyle], @params[:font], @params[:fontsize],
165
+ @params[:symmetrize], @params[:color], @params[:leafstyle], @params[:multibyte],
166
+ @params[:fontstyle], @params[:font], @params[:font_cjk], @params[:fontsize],
166
167
  )
167
168
  graph.svg_data
168
169
  end
@@ -175,7 +176,7 @@ class RSGenerator
175
176
  graph = TreeGraph.new(elist, @metrics,
176
177
  @params[:symmetrize], @params[:color], @params[:leafstyle], @params[:multibyte],
177
178
  @params[:fontstyle], @params[:font], @params[:font_it], @params[:font_bd], @params[:font_bdit], @params[:font_math],
178
- @params[:font_cjk], @params[:fontsize], @params[:margin],
179
+ @params[:font_cjk], @params[:fontsize], @params[:margin],
179
180
  )
180
181
  graph.to_blob(@params[:format])
181
182
  end
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.8.0
4
+ version: 0.8.3
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-11-29 00:00:00.000000000 Z
11
+ date: 2021-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rmagick
@@ -110,7 +110,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
110
110
  - !ruby/object:Gem::Version
111
111
  version: '0'
112
112
  requirements: []
113
- rubygems_version: 3.2.11
113
+ rubygems_version: 3.2.32
114
114
  signing_key:
115
115
  specification_version: 4
116
116
  summary: RSyntaxTree is a graphical syntax tree generator written in Ruby