rsyntaxtree 0.7.6 → 0.8.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -3
- data/bin/rsyntaxtree +12 -12
- data/fonts/NotoSansMath-Regular.ttf +0 -0
- data/fonts/latinmodern-math.otf +0 -0
- data/fonts/lmroman10-bold.otf +0 -0
- data/fonts/lmroman10-bolditalic.otf +0 -0
- data/fonts/lmroman10-italic.otf +0 -0
- data/fonts/lmroman10-regular.otf +0 -0
- data/lib/rsyntaxtree/element.rb +2 -1
- data/lib/rsyntaxtree/elementlist.rb +1 -1
- data/lib/rsyntaxtree/error_message.rb +1 -1
- data/lib/rsyntaxtree/graph.rb +31 -20
- data/lib/rsyntaxtree/string_parser.rb +13 -13
- data/lib/rsyntaxtree/svg_graph.rb +22 -14
- data/lib/rsyntaxtree/tree_graph.rb +32 -27
- data/lib/rsyntaxtree/utils.rb +1 -1
- data/lib/rsyntaxtree/version.rb +1 -1
- data/lib/rsyntaxtree.rb +27 -13
- data/rsyntaxtree.gemspec +2 -5
- metadata +28 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4606912993b73a0aafb6b6be73cbad23109df14ee1509c6c686c61990acff33c
|
4
|
+
data.tar.gz: 073a6ecee37e7ce9aa67c329aee75da916dcac4a2cce101f4389cad85e82ed65
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 569d8c208901a62379792019b9cd528e0a4ffff5c237c30c40244b70502a1852f3921d78f69e6b868ac2fa5096cf6ef1d550795dc74bce160951b3d610d30cc9
|
7
|
+
data.tar.gz: d15c6e7481e277621b32003a93356f146e3e22bda6c23730889aac5f08d1192b28e5d0dd92681326aff3249f6470fe3c17a91507a17c01c40e7960554a2b72af
|
data/README.md
CHANGED
@@ -1,10 +1,10 @@
|
|
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
|
|
5
5
|
### Web Interface
|
6
6
|
|
7
|
-
|
7
|
+
See updates and a working web interface available at <https://yohasebe.com/rsyntaxtree>.
|
8
8
|
|
9
9
|
### Installation
|
10
10
|
|
@@ -25,7 +25,7 @@ where [options] are:
|
|
25
25
|
-o, --outdir=<s> Output directory (default: ./)
|
26
26
|
-f, --format=<s> Output format: png, pdf, or svg (default: png)
|
27
27
|
-l, --leafstyle=<s> visual style of tree leaves: auto, triangle, bar, or nothing (default: auto)
|
28
|
-
-n, --fontstyle=<s> Font style: sans, serif, cjk (default: sans)
|
28
|
+
-n, --fontstyle=<s> Font style: sans, serif, cjk, math (default: sans)
|
29
29
|
-t, --font=<s> Path to a ttf font used to generate tree (optional)
|
30
30
|
-s, --fontsize=<i> Size: 8-26 (default: 16)
|
31
31
|
-c, --color=<s> Color text and bars: on or off (default: on)
|
data/bin/rsyntaxtree
CHANGED
@@ -7,7 +7,7 @@ require 'rsyntaxtree'
|
|
7
7
|
require 'optimist'
|
8
8
|
|
9
9
|
opts = Optimist::options do
|
10
|
-
version "RSyntaxTree #{RSyntaxTree::VERSION} (c)
|
10
|
+
version "RSyntaxTree #{RSyntaxTree::VERSION} (c) 2021 Yoichiro Hasebe"
|
11
11
|
banner <<-EOS
|
12
12
|
RSyntaxTree, (linguistic) syntax tree generator written in Ruby.
|
13
13
|
|
@@ -20,36 +20,36 @@ EOS
|
|
20
20
|
:default => "./"
|
21
21
|
opt :format, "Output format: png, gif, jpg, pdf, or svg",
|
22
22
|
:default => "png"
|
23
|
-
opt :leafstyle, "visual style of tree leaves: auto, triangle, bar, or nothing",
|
23
|
+
opt :leafstyle, "visual style of tree leaves: auto, triangle, bar, or nothing",
|
24
24
|
:default => "auto"
|
25
|
-
opt :fontstyle, "Font style (available when ttf font is specified): sans, serif, cjk",
|
25
|
+
opt :fontstyle, "Font style (available when ttf font is specified): sans, serif, cjk, math",
|
26
26
|
:default => "sans"
|
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
|
-
:default => "on"
|
35
|
+
:default => "on"
|
36
36
|
opt :symmetrize, "Generate symmetrical, balanced tree: on or off",
|
37
|
-
:default => "on"
|
37
|
+
:default => "on"
|
38
38
|
opt :autosub, "Put subscript numbers to nodes: on or off",
|
39
|
-
:default => "off"
|
39
|
+
:default => "off"
|
40
40
|
end
|
41
41
|
|
42
42
|
Optimist::die :outdir, "must be an exsting directory path" unless FileTest::directory?(opts[:outdir])
|
43
43
|
Optimist::die :format, "must be png, jpg, gif, or svg" unless /\A(png|jpg|gif|pdf|svg)\z/ =~ opts[:format]
|
44
44
|
Optimist::die :leafstyle, "must be auto, triangle, bar, or nothing" unless /\A(auto|triangle|bar|nothing)\z/ =~ opts[:leafstyle]
|
45
|
-
Optimist::die :fontstyle, "must be sans, serif, cjk" unless /\A(sans|serif|cjk)\z/ =~ opts[:fontstyle]
|
45
|
+
Optimist::die :fontstyle, "must be sans, serif, cjk, math" unless /\A(sans|serif|cjk|math)\z/ =~ opts[:fontstyle]
|
46
46
|
Optimist::die :font, "must be path to an existing ttf font" if opts[:font] && !File::exists?(opts[:font])
|
47
47
|
Optimist::die :fontsize, "must be in the range of 8-26" unless opts[:fontsize] >= 8 && opts[:fontsize] <= 26
|
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|
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/lib/rsyntaxtree/element.rb
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
# This file is part of RSyntaxTree, which is a ruby port of Andre Eisenbach's
|
11
11
|
# excellent program phpSyntaxTree.
|
12
12
|
#
|
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
|
class Element
|
@@ -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
|
@@ -10,7 +10,7 @@
|
|
10
10
|
# This file is part of RSyntaxTree, which is a ruby port of Andre Eisenbach's
|
11
11
|
# excellent program phpSyntaxTree.
|
12
12
|
#
|
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
|
require 'element'
|
@@ -10,7 +10,7 @@
|
|
10
10
|
# This file is part of RSyntaxTree, which is a ruby port of Andre Eisenbach's
|
11
11
|
# excellent program phpSyntaxTree.
|
12
12
|
#
|
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
|
class ErrorMessage
|
data/lib/rsyntaxtree/graph.rb
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
# This file is part of RSyntaxTree, which is a ruby port of Andre Eisenbach's
|
11
11
|
# excellent program phpSyntaxTree.
|
12
12
|
#
|
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
|
require 'rmagick'
|
@@ -58,11 +58,12 @@ 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|
|
65
|
-
gc.font = font
|
66
|
+
gc.font = font
|
66
67
|
gc.pointsize = font_size
|
67
68
|
gc.gravity = CenterGravity
|
68
69
|
gc.stroke = 'none'
|
@@ -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
|
|
@@ -238,22 +238,7 @@ class Graph
|
|
238
238
|
right = k.indent + kw
|
239
239
|
draw_element(left, curlevel, right - left, j.content, j.type)
|
240
240
|
@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
241
|
|
256
|
-
unless children.empty?
|
257
242
|
k = @e_list.get_id(children[0])
|
258
243
|
words = k.content.split(" ")
|
259
244
|
dw = img_get_txt_width(k.content, @font, @font_size)
|
@@ -272,7 +257,33 @@ class Graph
|
|
272
257
|
line_to_parent(k.indent, curlevel + 1, dw, j.indent, tw)
|
273
258
|
end
|
274
259
|
end
|
260
|
+
|
261
|
+
else
|
262
|
+
parent = @e_list.get_id(j.parent)
|
263
|
+
pw = img_get_txt_width(parent.content, @font, @font_size)
|
264
|
+
pleft = parent.indent
|
265
|
+
pright = pleft + pw
|
266
|
+
if curlevel == (h - 1)
|
267
|
+
e_arr.select{|l|l.level == curlevel}.each do |l|
|
268
|
+
lw = img_get_txt_width(l.content, @font, @font_size)
|
269
|
+
left = l.indent
|
270
|
+
right = left + lw
|
271
|
+
draw_element(left, curlevel, right - left, l.content, l.type)
|
272
|
+
@e_list.set_indent(l.id, left + (right - left) / 2 - tw / 2)
|
273
|
+
end
|
274
|
+
break
|
275
|
+
else
|
276
|
+
left = j.indent
|
277
|
+
right = left + tw
|
278
|
+
if pw > tw
|
279
|
+
left = pleft
|
280
|
+
right = pright
|
281
|
+
end
|
282
|
+
draw_element(left, curlevel, right - left, j.content, j.type)
|
283
|
+
@e_list.set_indent(j.id, left + (right - left) / 2 - tw / 2)
|
284
|
+
end
|
275
285
|
end
|
286
|
+
|
276
287
|
end
|
277
288
|
end
|
278
289
|
end
|
@@ -286,7 +297,7 @@ class Graph
|
|
286
297
|
|
287
298
|
def get_txt_only(text)
|
288
299
|
text = text.strip
|
289
|
-
if /\A([
|
300
|
+
if /\A([\+\-\=\*\#\~]+).+/ =~ text
|
290
301
|
prefix = $1
|
291
302
|
prefix_l = Regexp.escape(prefix)
|
292
303
|
prefix_r = Regexp.escape(prefix.reverse)
|
@@ -11,24 +11,24 @@
|
|
11
11
|
# This file is part of RSyntaxTree, which is a ruby port of Andre Eisenbach's
|
12
12
|
# excellent program phpSyntaxTree.
|
13
13
|
#
|
14
|
-
# Copyright (c) 2007-
|
14
|
+
# Copyright (c) 2007-2021 Yoichiro Hasebe <yohasebe@gmail.com>
|
15
15
|
# Copyright (c) 2003-2004 Andre Eisenbach <andre@ironcreek.net>
|
16
16
|
|
17
17
|
require 'elementlist'
|
18
18
|
require 'element'
|
19
19
|
|
20
|
-
def escape_high_ascii(string)
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
20
|
+
# def escape_high_ascii(string)
|
21
|
+
# html = ""
|
22
|
+
# string.length.times do |i|
|
23
|
+
# ch = string[i]
|
24
|
+
# if(ch < 127)
|
25
|
+
# html += ch.chr
|
26
|
+
# else
|
27
|
+
# html += sprintf("&#%d;", ch)
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
# html
|
31
|
+
# end
|
32
32
|
|
33
33
|
class StringParser
|
34
34
|
|
@@ -10,7 +10,7 @@
|
|
10
10
|
# This file is part of RSyntaxTree, which is a ruby port of Andre Eisenbach's
|
11
11
|
# excellent program phpSyntaxTree.
|
12
12
|
#
|
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
|
require "tempfile"
|
@@ -18,17 +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_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
|
-
@font
|
24
|
+
@font = multibyte ? font_cjk : font
|
25
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
|
26
32
|
|
27
33
|
super(e_list, metrics, symmetrize, color, leafstyle, multibyte, @font, @font_size)
|
28
34
|
|
29
|
-
@line_styles = "<line style='stroke:black; stroke-width
|
30
|
-
@polygon_styles = "<polygon style='fill: none; stroke: black; stroke-width
|
31
|
-
@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"
|
32
38
|
@tree_data = String.new
|
33
39
|
end
|
34
40
|
|
@@ -87,15 +93,12 @@ EOD
|
|
87
93
|
sub = ""
|
88
94
|
end
|
89
95
|
|
90
|
-
if /\A
|
96
|
+
if /\A\=(.+)\=\z/ =~ main
|
91
97
|
main = $1
|
92
98
|
main_decoration= "overline"
|
93
99
|
elsif /\A\-(.+)\-\z/ =~ main
|
94
100
|
main = $1
|
95
101
|
main_decoration= "underline"
|
96
|
-
elsif /\A\=(.+)\=\z/ =~ main
|
97
|
-
main = $1
|
98
|
-
main_decoration= "line-through"
|
99
102
|
else
|
100
103
|
main_decoration= ""
|
101
104
|
end
|
@@ -117,6 +120,10 @@ EOD
|
|
117
120
|
main_weight = ""
|
118
121
|
end
|
119
122
|
|
123
|
+
if /\A#(.+)#\z/ =~ main
|
124
|
+
main = $1
|
125
|
+
end
|
126
|
+
|
120
127
|
# Calculate text size for the main and the
|
121
128
|
# subscript part of the element
|
122
129
|
# symbols for underline/overline removed temporarily
|
@@ -124,15 +131,12 @@ EOD
|
|
124
131
|
main_width = img_get_txt_width(main, @font, @font_size)
|
125
132
|
|
126
133
|
if sub != ""
|
127
|
-
if /\A
|
134
|
+
if /\A\=(.+)\=\z/ =~ sub
|
128
135
|
sub = $1
|
129
136
|
sub_decoration= "overline"
|
130
137
|
elsif /\A\-(.+)\-\z/ =~ sub
|
131
138
|
sub = $1
|
132
139
|
sub_decoration= "underline"
|
133
|
-
elsif /\A\=(.+)\=\z/ =~ sub
|
134
|
-
sub = $1
|
135
|
-
sub_decoration= "line-through"
|
136
140
|
else
|
137
141
|
sub_decoration= ""
|
138
142
|
end
|
@@ -158,6 +162,10 @@ EOD
|
|
158
162
|
sub_width = 0
|
159
163
|
end
|
160
164
|
|
165
|
+
if /\A#(.+)#\z/ =~ sub
|
166
|
+
sub = $1
|
167
|
+
end
|
168
|
+
|
161
169
|
# Center text in the element
|
162
170
|
txt_width = main_width + sub_width
|
163
171
|
txt_pos = left + (right - left) / 2 - txt_width / 2
|
@@ -10,7 +10,7 @@
|
|
10
10
|
# This file is part of RSyntaxTree, which is a ruby port of Andre Eisenbach's
|
11
11
|
# excellent program phpSyntaxTree.
|
12
12
|
#
|
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
|
require 'graph'
|
@@ -20,7 +20,7 @@ include Magick
|
|
20
20
|
class TreeGraph < Graph
|
21
21
|
|
22
22
|
def initialize(e_list, metrics, symmetrize, color, leafstyle, multibyte,
|
23
|
-
fontstyle, font, font_it, font_bd, font_itbd, font_cjk, font_size,
|
23
|
+
fontstyle, font, font_it, font_bd, font_itbd, font_math, font_cjk, font_size,
|
24
24
|
margin)
|
25
25
|
|
26
26
|
# Store class-specific parameters
|
@@ -30,6 +30,7 @@ class TreeGraph < Graph
|
|
30
30
|
@font_it = font_it
|
31
31
|
@font_bd = font_bd
|
32
32
|
@font_itbd = font_itbd
|
33
|
+
@font_math = font_math
|
33
34
|
@font_cjk = font_cjk
|
34
35
|
@margin = margin
|
35
36
|
|
@@ -62,28 +63,27 @@ class TreeGraph < Graph
|
|
62
63
|
def to_blob(fileformat='PNG')
|
63
64
|
draw
|
64
65
|
@im.border!(@margin, @margin, "white")
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
end
|
66
|
+
@im.format = fileformat
|
67
|
+
@im.interlace = PlaneInterlace
|
68
|
+
return @im.to_blob
|
69
|
+
end
|
70
70
|
|
71
71
|
:private
|
72
72
|
|
73
73
|
# Add the element into the tree (draw it)
|
74
74
|
def draw_element(x, y, w, string, type)
|
75
|
-
string = string.sub(/\^\z/){""}
|
75
|
+
string = string.sub(/\^\z/){""}
|
76
76
|
# Calculate element dimensions and position
|
77
77
|
if (type == ETYPE_LEAF) and @leafstyle == "nothing"
|
78
78
|
top = row2px(y - 1) + (@font_size * 1.5)
|
79
|
-
else
|
79
|
+
else
|
80
80
|
top = row2px(y)
|
81
81
|
end
|
82
82
|
left = x + @m[:b_side]
|
83
83
|
bottom = top + @e_height
|
84
84
|
right = left + w
|
85
85
|
|
86
|
-
# Split the string into the main part and the
|
86
|
+
# Split the string into the main part and the
|
87
87
|
# subscript part of the element (if any)
|
88
88
|
parts = string.split("_", 2)
|
89
89
|
if(parts.length > 1 )
|
@@ -94,19 +94,21 @@ class TreeGraph < Graph
|
|
94
94
|
sub = ""
|
95
95
|
end
|
96
96
|
|
97
|
-
if /\A
|
97
|
+
if /\A\=(.+)\=\z/ =~ main
|
98
98
|
main = $1
|
99
99
|
main_decoration = OverlineDecoration
|
100
100
|
elsif /\A\-(.+)\-\z/ =~ main
|
101
101
|
main = $1
|
102
102
|
main_decoration = UnderlineDecoration
|
103
|
-
elsif /\A
|
103
|
+
elsif /\A\~(.+)\~\z/ =~ main
|
104
104
|
main = $1
|
105
105
|
main_decoration = LineThroughDecoration
|
106
106
|
else
|
107
107
|
main_decoration = NoDecoration
|
108
108
|
end
|
109
109
|
|
110
|
+
main_font = @font
|
111
|
+
|
110
112
|
if /\A\*\*\*(.+)\*\*\*\z/ =~ main
|
111
113
|
main = $1
|
112
114
|
if !@multibyte
|
@@ -122,24 +124,25 @@ class TreeGraph < Graph
|
|
122
124
|
if !@multibyte
|
123
125
|
main_font = @font_it
|
124
126
|
end
|
125
|
-
else
|
126
|
-
main_font = @font
|
127
127
|
end
|
128
128
|
|
129
|
-
#
|
129
|
+
if /\A#(.+)#\z/ =~ main
|
130
|
+
main = $1
|
131
|
+
main_font = @font_math
|
132
|
+
end
|
133
|
+
|
134
|
+
# Calculate text size for the main and the
|
130
135
|
# subscript part of the element
|
131
|
-
# symbols for underline/overline removed temporarily
|
132
136
|
|
133
137
|
main_width = img_get_txt_width(main, main_font, @font_size)
|
134
138
|
|
135
|
-
if /\A
|
139
|
+
if /\A\=(.+)\=\z/ =~ sub
|
136
140
|
sub = $1
|
137
141
|
sub_decoration = OverlineDecoration
|
138
142
|
elsif /\A\-(.+)\-\z/ =~ sub
|
139
143
|
sub = $1
|
140
|
-
@gc.decorate(UnderlineDecoration)
|
141
144
|
sub_decoration = UnderlineDecoration
|
142
|
-
elsif /\A
|
145
|
+
elsif /\A\~(.+)\~z/ =~ sub
|
143
146
|
sub = $1
|
144
147
|
sub_decoration = LineThroughDecoration
|
145
148
|
else
|
@@ -147,7 +150,6 @@ class TreeGraph < Graph
|
|
147
150
|
end
|
148
151
|
|
149
152
|
sub_font = @font
|
150
|
-
|
151
153
|
if /\A\*\*\*(.+)\*\*\*\z/ =~ sub
|
152
154
|
sub = $1
|
153
155
|
if !@multibyte
|
@@ -163,8 +165,11 @@ class TreeGraph < Graph
|
|
163
165
|
if !@multibyte
|
164
166
|
sub_font = @font_it
|
165
167
|
end
|
166
|
-
|
167
|
-
|
168
|
+
end
|
169
|
+
|
170
|
+
if /\A#(.+)#\z/ =~ sub
|
171
|
+
sub = $1
|
172
|
+
sub_font = @font_math
|
168
173
|
end
|
169
174
|
|
170
175
|
if sub != ""
|
@@ -182,7 +187,7 @@ class TreeGraph < Graph
|
|
182
187
|
if(type == ETYPE_LEAF)
|
183
188
|
col = @col_leaf
|
184
189
|
else
|
185
|
-
col = @col_node
|
190
|
+
col = @col_node
|
186
191
|
end
|
187
192
|
|
188
193
|
if(main[0].chr == "<" && main[-1].chr == ">")
|
@@ -227,7 +232,7 @@ class TreeGraph < Graph
|
|
227
232
|
|
228
233
|
@gc.fill("none")
|
229
234
|
@gc.stroke @col_line
|
230
|
-
@gc.stroke_width 1
|
235
|
+
@gc.stroke_width 1 * FONT_SCALING
|
231
236
|
@gc.line(fromLeft.ceil, fromTop.ceil, toLeft.ceil, toBot.ceil)
|
232
237
|
end
|
233
238
|
|
@@ -252,7 +257,7 @@ class TreeGraph < Graph
|
|
252
257
|
|
253
258
|
@gc.fill("none")
|
254
259
|
@gc.stroke @col_line
|
255
|
-
@gc.stroke_width 1
|
260
|
+
@gc.stroke_width 1 * 2
|
256
261
|
@gc.line(fromLeft1, fromTop, toLeft, toBot)
|
257
262
|
@gc.line(fromLeft2, fromTop, toLeft, toBot)
|
258
263
|
@gc.line(fromLeft1, fromTop, fromLeft2, fromTop)
|
@@ -267,9 +272,9 @@ class TreeGraph < Graph
|
|
267
272
|
children = @e_list.get_children(id)
|
268
273
|
@e_list.set_element_width(id, target)
|
269
274
|
|
270
|
-
if(children.length > 0 )
|
275
|
+
if(children.length > 0 )
|
271
276
|
delta = target - current
|
272
|
-
target_delta = delta / children.length
|
277
|
+
target_delta = delta / children.length
|
273
278
|
|
274
279
|
children.each do |child|
|
275
280
|
child_width = @e_list.get_element_width(child)
|
data/lib/rsyntaxtree/utils.rb
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
# This file is part of RSyntaxTree, which is a ruby port of Andre Eisenbach's
|
11
11
|
# excellent program phpSyntaxTree.
|
12
12
|
#
|
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
|
class String
|
data/lib/rsyntaxtree/version.rb
CHANGED
data/lib/rsyntaxtree.rb
CHANGED
@@ -8,14 +8,14 @@
|
|
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')
|
17
17
|
|
18
|
-
require '
|
18
|
+
require 'cgi'
|
19
19
|
require 'utils'
|
20
20
|
require 'element'
|
21
21
|
require 'elementlist'
|
@@ -31,15 +31,16 @@ 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|
|
39
40
|
key = keystr.to_sym
|
40
41
|
case key
|
41
42
|
when :data
|
42
|
-
data =
|
43
|
+
data = CGI.unescape(value)
|
43
44
|
data = data.gsub('-AMP-', '&')
|
44
45
|
.gsub('-PERCENT-', "%")
|
45
46
|
.gsub('-PRIME-', "'")
|
@@ -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
|
@@ -62,6 +63,7 @@ class RSGenerator
|
|
62
63
|
new_params[:font_it] = FONT_DIR + "/NotoSans-Italic.ttf"
|
63
64
|
new_params[:font_bd] = FONT_DIR + "/NotoSans-Bold.ttf"
|
64
65
|
new_params[:font_bdit] = FONT_DIR + "/NotoSans-BoldItalic.ttf"
|
66
|
+
new_params[:font_math] = FONT_DIR + "/NotoSansMath-Regular.ttf"
|
65
67
|
new_params[:font_cjk] = FONT_DIR + "/NotoSansCJKjp-Regular.otf"
|
66
68
|
new_params[:fontstyle] = "sans"
|
67
69
|
elsif value == "noto-serif" || value == "serif"
|
@@ -69,6 +71,7 @@ class RSGenerator
|
|
69
71
|
new_params[:font_it] = FONT_DIR + "/NotoSerif-Italic.ttf"
|
70
72
|
new_params[:font_bd] = FONT_DIR + "/NotoSerif-Bold.ttf"
|
71
73
|
new_params[:font_bdit] = FONT_DIR + "/NotoSerif-BoldItalic.ttf"
|
74
|
+
new_params[:font_math] = FONT_DIR + "/NotoSansMath-Regular.ttf"
|
72
75
|
new_params[:font_cjk] = FONT_DIR + "/NotoSerifCJKjp-Regular.otf"
|
73
76
|
new_params[:fontstyle] = "serif"
|
74
77
|
elsif value == "cjk zenhei" || value == "cjk"
|
@@ -76,14 +79,24 @@ class RSGenerator
|
|
76
79
|
new_params[:font_it] = FONT_DIR + "/NotoSans-Italic.ttf"
|
77
80
|
new_params[:font_bd] = FONT_DIR + "/NotoSans-Bold.ttf"
|
78
81
|
new_params[:font_bdit] = FONT_DIR + "/NotoSans-BoldItalic.ttf"
|
82
|
+
new_params[:font_math] = FONT_DIR + "/NotoSansMath-Regular.ttf"
|
79
83
|
new_params[:font_cjk] = FONT_DIR + "/wqy-zenhei.ttf"
|
80
84
|
new_params[:fontstyle] = "sans"
|
85
|
+
elsif value == "modern-math" || value == "math"
|
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"
|
91
|
+
new_params[:font_cjk] = FONT_DIR + "/NotoSerifCJKjp-Regular.otf"
|
92
|
+
new_params[:fontstyle] = "math"
|
81
93
|
end
|
82
94
|
else
|
83
95
|
new_params[key] = value
|
84
96
|
end
|
85
97
|
end
|
86
98
|
|
99
|
+
# defaults to the following
|
87
100
|
@params = {
|
88
101
|
:symmetrize => true,
|
89
102
|
:color => true,
|
@@ -100,6 +113,7 @@ class RSGenerator
|
|
100
113
|
:font_it => "/NotoSans-Italic.ttf",
|
101
114
|
:font_bd => "/NotoSans-Bold.ttf",
|
102
115
|
:font_bdit => "/NotoSans-BoldItalic.ttf",
|
116
|
+
:font_math => "/NotoSansMath-Regular.ttf"
|
103
117
|
}
|
104
118
|
@metrics = {
|
105
119
|
:e_width => 120,
|
@@ -111,8 +125,8 @@ class RSGenerator
|
|
111
125
|
}
|
112
126
|
|
113
127
|
@params.merge! new_params
|
114
|
-
@params[:fontsize] = @params[:fontsize] *
|
115
|
-
@params[:margin] = @params[:margin] *
|
128
|
+
@params[:fontsize] = @params[:fontsize] * FONT_SCALING
|
129
|
+
@params[:margin] = @params[:margin] * FONT_SCALING
|
116
130
|
@metrics[:v_space] = @metrics[:v_space] * @params[:vheight]
|
117
131
|
end
|
118
132
|
|
@@ -148,8 +162,8 @@ class RSGenerator
|
|
148
162
|
sp.auto_subscript if @params[:autosub]
|
149
163
|
elist = sp.get_elementlist
|
150
164
|
graph = SVGGraph.new(elist, @metrics,
|
151
|
-
@params[:symmetrize], @params[:color], @params[:leafstyle], @params[:multibyte],
|
152
|
-
@params[:fontstyle], @params[:fontsize],
|
165
|
+
@params[:symmetrize], @params[:color], @params[:leafstyle], @params[:multibyte],
|
166
|
+
@params[:fontstyle], @params[:font], @params[:font_cjk], @params[:fontsize],
|
153
167
|
)
|
154
168
|
graph.svg_data
|
155
169
|
end
|
@@ -161,8 +175,8 @@ class RSGenerator
|
|
161
175
|
elist = sp.get_elementlist
|
162
176
|
graph = TreeGraph.new(elist, @metrics,
|
163
177
|
@params[:symmetrize], @params[:color], @params[:leafstyle], @params[:multibyte],
|
164
|
-
@params[:fontstyle], @params[:font], @params[:font_it], @params[:font_bd], @params[:font_bdit],
|
165
|
-
@params[:font_cjk], @params[:fontsize], @params[:margin],
|
178
|
+
@params[:fontstyle], @params[:font], @params[:font_it], @params[:font_bd], @params[:font_bdit], @params[:font_math],
|
179
|
+
@params[:font_cjk], @params[:fontsize], @params[:margin],
|
166
180
|
)
|
167
181
|
graph.to_blob(@params[:format])
|
168
182
|
end
|
data/rsyntaxtree.gemspec
CHANGED
@@ -12,14 +12,11 @@ Gem::Specification.new do |s|
|
|
12
12
|
s.summary = %q{RSyntaxTree is a graphical syntax tree generator written in Ruby}
|
13
13
|
s.description = %q{Yet another syntax tree generator made with Ruby and RMagick}
|
14
14
|
s.licenses = ["MIT"]
|
15
|
-
|
16
|
-
s.rubyforge_project = "rsyntaxtree"
|
17
|
-
|
18
15
|
s.files = `git ls-files`.split("\n")
|
19
16
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
17
|
s.require_paths = ["lib"]
|
21
18
|
|
22
19
|
# specify any dependencies here; for example:
|
23
|
-
s.add_runtime_dependency
|
24
|
-
s.add_runtime_dependency
|
20
|
+
s.add_runtime_dependency 'rmagick', '~> 4.2', '>= 4.2.3'
|
21
|
+
s.add_runtime_dependency 'optimist', '~> 3.0', '>= 3.0.1'
|
25
22
|
end
|
metadata
CHANGED
@@ -1,43 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rsyntaxtree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yoichiro Hasebe
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-12-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rmagick
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.2'
|
17
20
|
- - ">="
|
18
21
|
- !ruby/object:Gem::Version
|
19
|
-
version: 2.
|
22
|
+
version: 4.2.3
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '4.2'
|
24
30
|
- - ">="
|
25
31
|
- !ruby/object:Gem::Version
|
26
|
-
version: 2.
|
32
|
+
version: 4.2.3
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: optimist
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
30
36
|
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '3.0'
|
31
40
|
- - ">="
|
32
41
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
42
|
+
version: 3.0.1
|
34
43
|
type: :runtime
|
35
44
|
prerelease: false
|
36
45
|
version_requirements: !ruby/object:Gem::Requirement
|
37
46
|
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '3.0'
|
38
50
|
- - ">="
|
39
51
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
52
|
+
version: 3.0.1
|
41
53
|
description: Yet another syntax tree generator made with Ruby and RMagick
|
42
54
|
email:
|
43
55
|
- yohasebe@gmail.com
|
@@ -56,11 +68,17 @@ files:
|
|
56
68
|
- fonts/NotoSans-Italic.ttf
|
57
69
|
- fonts/NotoSans-Regular.ttf
|
58
70
|
- fonts/NotoSansCJKjp-Regular.otf
|
71
|
+
- fonts/NotoSansMath-Regular.ttf
|
59
72
|
- fonts/NotoSerif-Bold.ttf
|
60
73
|
- fonts/NotoSerif-BoldItalic.ttf
|
61
74
|
- fonts/NotoSerif-Italic.ttf
|
62
75
|
- fonts/NotoSerif-Regular.ttf
|
63
76
|
- fonts/NotoSerifCJKjp-Regular.otf
|
77
|
+
- fonts/latinmodern-math.otf
|
78
|
+
- fonts/lmroman10-bold.otf
|
79
|
+
- fonts/lmroman10-bolditalic.otf
|
80
|
+
- fonts/lmroman10-italic.otf
|
81
|
+
- fonts/lmroman10-regular.otf
|
64
82
|
- fonts/wqy-zenhei.ttf
|
65
83
|
- lib/rsyntaxtree.rb
|
66
84
|
- lib/rsyntaxtree/element.rb
|
@@ -77,7 +95,7 @@ homepage: http://github.com/yohasebe/rsyntaxtree
|
|
77
95
|
licenses:
|
78
96
|
- MIT
|
79
97
|
metadata: {}
|
80
|
-
post_install_message:
|
98
|
+
post_install_message:
|
81
99
|
rdoc_options: []
|
82
100
|
require_paths:
|
83
101
|
- lib
|
@@ -92,8 +110,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
92
110
|
- !ruby/object:Gem::Version
|
93
111
|
version: '0'
|
94
112
|
requirements: []
|
95
|
-
rubygems_version: 3.
|
96
|
-
signing_key:
|
113
|
+
rubygems_version: 3.2.11
|
114
|
+
signing_key:
|
97
115
|
specification_version: 4
|
98
116
|
summary: RSyntaxTree is a graphical syntax tree generator written in Ruby
|
99
117
|
test_files: []
|