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 +4 -4
- data/README.md +1 -1
- data/bin/rsyntaxtree +5 -5
- data/fonts/NotoSansMath-Regular.ttf +0 -0
- data/fonts/latinmodern-math.otf +0 -0
- data/lib/rsyntaxtree/element.rb +1 -0
- data/lib/rsyntaxtree/graph.rb +32 -19
- data/lib/rsyntaxtree/svg_graph.rb +18 -5
- data/lib/rsyntaxtree/tree_graph.rb +10 -9
- data/lib/rsyntaxtree/version.rb +1 -1
- data/lib/rsyntaxtree.rb +17 -16
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c06870de3a591df5cdde4b1061529a81455614447d7f6279dc056b06b1631924
|
4
|
+
data.tar.gz: '095426d0a0b46db22be01e8b57e631eea535eec751488ede9aeaaa9bb72bc7ac'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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:
|
31
|
-
:default =>
|
32
|
-
opt :vheight, "Connector Height: 0.5-
|
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
|
52
|
-
Optimist::die :vheight, "must be in the range of 0.5-
|
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
|
data/fonts/latinmodern-math.otf
CHANGED
File without changes
|
data/lib/rsyntaxtree/element.rb
CHANGED
@@ -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
|
data/lib/rsyntaxtree/graph.rb
CHANGED
@@ -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([
|
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
|
31
|
-
@polygon_styles = "<polygon style='fill: none; stroke: black; stroke-width
|
32
|
-
@text_styles = "<text style='fill: COLOR; font-size: FONT_SIZEpx; ST; WA;' x='X_VALUE' y='Y_VALUE' TD font-family='#{@
|
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
|
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
|
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)
|
data/lib/rsyntaxtree/version.rb
CHANGED
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-
|
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] *
|
128
|
-
@params[:margin] = @params[:margin] *
|
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.
|
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
|
+
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.
|
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
|