rsyntaxtree 1.0.8 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +77 -0
  3. data/.solargraph.yml +22 -0
  4. data/.tags +238 -10
  5. data/Gemfile +10 -5
  6. data/README.md +3 -2
  7. data/Rakefile +5 -2
  8. data/bin/rsyntaxtree +42 -50
  9. data/docs/Gemfile +3 -1
  10. data/docs/_layouts/default.html +1 -1
  11. data/docs/assets/svg/001.svg +39 -0
  12. data/docs/assets/svg/002.svg +65 -0
  13. data/docs/assets/svg/003.svg +54 -0
  14. data/docs/assets/svg/004.svg +68 -0
  15. data/docs/assets/svg/005.svg +41 -0
  16. data/docs/assets/svg/006.svg +47 -0
  17. data/docs/assets/svg/007.svg +55 -0
  18. data/docs/assets/svg/008.svg +63 -0
  19. data/docs/assets/svg/009.svg +61 -0
  20. data/docs/assets/svg/010.svg +85 -0
  21. data/docs/assets/svg/011.svg +49 -0
  22. data/docs/assets/svg/012.svg +55 -0
  23. data/docs/assets/svg/013.svg +203 -0
  24. data/docs/assets/svg/014.svg +188 -0
  25. data/docs/assets/svg/015.svg +60 -0
  26. data/docs/assets/svg/016.svg +801 -0
  27. data/docs/assets/svg/017.svg +77 -0
  28. data/docs/assets/svg/018.svg +66 -0
  29. data/docs/assets/svg/019.svg +256 -0
  30. data/docs/assets/svg/020.svg +99 -0
  31. data/lib/rsyntaxtree/base_graph.rb +260 -264
  32. data/lib/rsyntaxtree/element.rb +167 -179
  33. data/lib/rsyntaxtree/elementlist.rb +105 -124
  34. data/lib/rsyntaxtree/markup_parser.rb +82 -93
  35. data/lib/rsyntaxtree/string_parser.rb +221 -237
  36. data/lib/rsyntaxtree/svg_graph.rb +158 -197
  37. data/lib/rsyntaxtree/utils.rb +59 -63
  38. data/lib/rsyntaxtree/version.rb +3 -2
  39. data/lib/rsyntaxtree.rb +173 -177
  40. data/rsyntaxtree.gemspec +12 -10
  41. data/test/example_verify_test.rb +96 -0
  42. data/test/markup_parser_test.rb +3 -2
  43. metadata +54 -17
@@ -1,63 +1,59 @@
1
- #!/usr/bin/env ruby
2
- # -*- coding: utf-8 -*-
3
-
4
- #==========================
5
- # utils.rb
6
- #==========================
7
- #
8
- # Image utility functions to inspect text font metrics
9
- # Copyright (c) 2007-2021 Yoichiro Hasebe <yohasebe@gmail.com>
10
-
11
- require 'rmagick'
12
- include Magick
13
-
14
- class String
15
- def contains_cjk?
16
- !!(self.gsub(WHITESPACE_BLOCK, "") =~ /\p{Han}|\p{Katakana}|\p{Hiragana}|\p{Hangul}|[^\x01-\x7E]/)
17
- end
18
-
19
- def contains_emoji?
20
- !!(self.gsub(WHITESPACE_BLOCK, "").gsub(/\d/, "") =~ /\p{Emoji}/)
21
- end
22
-
23
- def all_emoji?
24
- !!(self.gsub(WHITESPACE_BLOCK, "").gsub(/\d/, "") =~ /\A\p{Emoji}[\p{Emoji}\s]*\z/)
25
- end
26
-
27
- def split_by_emoji
28
- results = []
29
- self.split(//).each do |ch|
30
- case ch
31
- when /\d/, WHITESPACE_BLOCK
32
- results << {:type => :normal, :char => ch}
33
- when /\p{Emoji}/
34
- results << {:type => :emoji, :char => ch}
35
- else
36
- results << {:type => :normal, :char => ch}
37
- end
38
- end
39
- results.reject{|string| string == ""}
40
- end
41
- end
42
-
43
- module FontMetrics
44
- def get_metrics(text, font, fontsize, font_style, font_weight)
45
- background = Image.new(1, 1)
46
- gc = Draw.new
47
- gc.annotate(background, 0, 0, 0, 0, text) do |gc|
48
- gc.font = font
49
- gc.font_style = font_style == :italic ? ItalicStyle : NormalStyle
50
- gc.font_weight = font_weight == :bold ? BoldWeight : NormalWeight
51
- gc.pointsize = fontsize
52
- gc.gravity = CenterGravity
53
- gc.stroke = 'none'
54
- gc.kerning = 0
55
- gc.interline_spacing = 0
56
- gc.interword_spacing = 0
57
- end
58
- metrics = gc.get_multiline_type_metrics(background, text)
59
- return metrics
60
- end
61
- module_function :get_metrics
62
- end
63
-
1
+ # frozen_string_literal: true
2
+
3
+ #==========================
4
+ # utils.rb
5
+ #==========================
6
+ #
7
+ # Image utility functions to inspect text font metrics
8
+ # Copyright (c) 2007-2023 Yoichiro Hasebe <yohasebe@gmail.com>
9
+
10
+ require 'rmagick'
11
+
12
+ class String
13
+ def contains_cjk?
14
+ !!(gsub(WHITESPACE_BLOCK, "") =~ /\p{Han}|\p{Katakana}|\p{Hiragana}|\p{Hangul}|[^\x01-\x7E]/)
15
+ end
16
+
17
+ def contains_emoji?
18
+ !!(gsub(WHITESPACE_BLOCK, "").gsub(/\d/, "") =~ /\p{Emoji}/)
19
+ end
20
+
21
+ def all_emoji?
22
+ !!(gsub(WHITESPACE_BLOCK, "").gsub(/\d/, "") =~ /\A\p{Emoji}[\p{Emoji}\s]*\z/)
23
+ end
24
+
25
+ def split_by_emoji
26
+ results = []
27
+ split(//).each do |ch|
28
+ results << case ch
29
+ when /\d/, WHITESPACE_BLOCK
30
+ { type: :normal, char: ch }
31
+ when /\p{Emoji}/
32
+ { type: :emoji, char: ch }
33
+ else
34
+ { type: :normal, char: ch }
35
+ end
36
+ end
37
+ results.reject { |string| string == "" }
38
+ end
39
+ end
40
+
41
+ module FontMetrics
42
+ def get_metrics(text, font, fontsize, font_style, font_weight)
43
+ background = Magick::Image.new(1, 1)
44
+ gc = Magick::Draw.new
45
+ gc.annotate(background, 0, 0, 0, 0, text) do |gca|
46
+ gca.font = font
47
+ gca.font_style = font_style == :italic ? Magick::ItalicStyle : Magick::NormalStyle
48
+ gca.font_weight = font_weight == :bold ? Magick::BoldWeight : Magick::NormalWeight
49
+ gca.pointsize = fontsize
50
+ gca.gravity = Magick::CenterGravity
51
+ gca.stroke = 'none'
52
+ gca.kerning = 0
53
+ gca.interline_spacing = 0
54
+ gca.interword_spacing = 0
55
+ end
56
+ gc.get_multiline_type_metrics(background, text)
57
+ end
58
+ module_function :get_metrics
59
+ end
@@ -1,4 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RSyntaxTree
2
- VERSION = "1.0.8"
4
+ VERSION = "1.1.1"
3
5
  end
4
-
data/lib/rsyntaxtree.rb CHANGED
@@ -1,177 +1,173 @@
1
- #!/usr/bin/env ruby
2
- # -*- coding: utf-8 -*-
3
-
4
- #==========================
5
- # rsyntaxtree.rb
6
- #==========================
7
- #
8
- # Facade of rsyntaxtree library. When loaded by a driver script, it does all
9
- # the necessary 'require' to use the library.
10
- # Copyright (c) 2007-2021 Yoichiro Hasebe <yohasebe@gmail.com>
11
-
12
- $LOAD_PATH << File.join( File.dirname(__FILE__), 'rsyntaxtree')
13
-
14
- FONT_DIR = File.expand_path(File.dirname(__FILE__) + "/../fonts")
15
- ETYPE_NODE = 1
16
- ETYPE_LEAF = 2
17
- SUBSCRIPT_CONST = 0.7
18
- FONT_SCALING = 2
19
- WHITESPACE_BLOCK = ""
20
-
21
- class RSTError < StandardError
22
- def initialize(msg="Error: something unexpected occurred")
23
- msg.gsub!(WHITESPACE_BLOCK, "<>")
24
- super msg
25
- end
26
- end
27
-
28
- require 'cgi'
29
- require 'rsvg2'
30
- require 'utils'
31
- require 'element'
32
- require 'elementlist'
33
- require 'string_parser'
34
- require 'svg_graph'
35
- require 'version'
36
- require 'rmagick'
37
-
38
- module RSyntaxTree
39
-
40
- class RSGenerator
41
-
42
- def initialize(params = {})
43
- new_params = {}
44
- fontset = {}
45
- params.each do |keystr, value|
46
- key = keystr.to_sym
47
- case key
48
- when :data
49
- data = value
50
- data = data.gsub('-AMP-', '&')
51
- .gsub('-PERCENT-', "%")
52
- .gsub('-PRIME-', "'")
53
- .gsub('-SCOLON-', ';')
54
- .gsub('-OABRACKET-', '<')
55
- .gsub('-CABRACKET-', '>')
56
- .gsub('¥¥', '\¥')
57
- .gsub(/(?<!\\)¥/, "\\")
58
- new_params[key] = data
59
-
60
- when :symmetrize, :color, :transparent, :polyline
61
- new_params[key] = value && (value != "off" && value != "false") ? true : false
62
- when :fontsize
63
- new_params[key] = value.to_i * FONT_SCALING
64
- when :margin
65
- new_params[key] = value.to_i * FONT_SCALING * 5
66
- when :vheight
67
- new_params[key] = value.to_f
68
- when :fontstyle
69
- if value == "noto-sans" || value == "sans"
70
- fontset[:normal] = FONT_DIR + "/NotoSans-Regular.ttf"
71
- fontset[:italic] = FONT_DIR + "/NotoSans-Italic.ttf"
72
- fontset[:bold] = FONT_DIR + "/NotoSans-Bold.ttf"
73
- fontset[:bolditalic] = FONT_DIR + "/NotoSans-BoldItalic.ttf"
74
- fontset[:math] = FONT_DIR + "/NotoSansMath-Regular.ttf"
75
- fontset[:cjk] = FONT_DIR + "/NotoSansJP-Regular.otf"
76
- fontset[:emoji] = FONT_DIR + "/OpenMoji-Black.ttf"
77
- new_params[:fontstyle] = "sans"
78
- elsif value == "noto-serif" || value == "serif"
79
- fontset[:normal] = FONT_DIR + "/NotoSerif-Regular.ttf"
80
- fontset[:italic] = FONT_DIR + "/NotoSerif-Italic.ttf"
81
- fontset[:bold] = FONT_DIR + "/NotoSerif-Bold.ttf"
82
- fontset[:bolditalic] = FONT_DIR + "/NotoSerif-BoldItalic.ttf"
83
- fontset[:math] = FONT_DIR + "/latinmodern-math.otf"
84
- fontset[:cjk] = FONT_DIR + "/NotoSerifJP-Regular.otf"
85
- fontset[:emoji] = FONT_DIR + "/OpenMoji-Black.ttf"
86
- new_params[:fontstyle] = "serif"
87
- elsif value == "cjk zenhei" || value == "cjk"
88
- fontset[:normal] = FONT_DIR + "/wqy-zenhei.ttf"
89
- fontset[:italic] = FONT_DIR + "/NotoSans-Italic.ttf"
90
- fontset[:bold] = FONT_DIR + "/NotoSans-Bold.ttf"
91
- fontset[:bolditalic] = FONT_DIR + "/NotoSans-BoldItalic.ttf"
92
- fontset[:math] = FONT_DIR + "/NotoSansMath-Regular.ttf"
93
- fontset[:cjk] = FONT_DIR + "/wqy-zenhei.ttf"
94
- fontset[:emoji] = FONT_DIR + "/OpenMoji-Black.ttf"
95
- new_params[:fontstyle] = "cjk"
96
- end
97
- else
98
- new_params[key] = value
99
- end
100
- end
101
-
102
- # defaults to the following
103
- @params = {
104
- :symmetrize => true,
105
- :color => true,
106
- :transparent => false,
107
- :fontsize => 16,
108
- :format => "png",
109
- :leafstyle => "auto",
110
- :filename => "syntree",
111
- :data => "",
112
- :margin => 0,
113
- :vheight => 1.0,
114
- :polyline => false,
115
- }
116
-
117
- @params.merge! new_params
118
- @params[:fontsize] = @params[:fontsize] * FONT_SCALING
119
- @params[:margin] = @params[:margin] * FONT_SCALING
120
- @params[:fontset] = fontset
121
-
122
- $single_X_metrics = FontMetrics.get_metrics("X", fontset[:normal], @params[:fontsize], :normal, :normal)
123
- $height_connector_to_text = $single_X_metrics.height / 2.0
124
- $single_line_height = $single_X_metrics.height * 2.0
125
- $width_half_X = $single_X_metrics.width / 2.0
126
- $height_connector = $single_X_metrics.height * 1.0 * @params[:vheight]
127
- $h_gap_between_nodes = $single_X_metrics.width * 0.8
128
- $box_vertical_margin = $single_X_metrics.height * 0.8
129
- end
130
-
131
- def self.check_data(text)
132
- if text.to_s == ""
133
- raise RSTError, "Error: input text is empty"
134
- end
135
- StringParser.valid?(text)
136
- end
137
-
138
- def draw_png(binary = false)
139
- svg = draw_svg
140
- rsvg = RSVG::Handle.new_from_data(svg)
141
- dim = rsvg.dimensions
142
- surface = Cairo::ImageSurface.new(Cairo::FORMAT_ARGB32, dim.width, dim.height)
143
- context = Cairo::Context.new(surface)
144
- context.render_rsvg_handle(rsvg)
145
- b = StringIO.new
146
- surface.write_to_png(b)
147
- if binary
148
- return b
149
- else
150
- return b.string
151
- end
152
- end
153
-
154
- def draw_svg
155
- sp = StringParser.new(@params[:data].gsub('&', '&amp;'), @params[:fontset], @params[:fontsize])
156
- sp.parse
157
- graph = SVGGraph.new(sp.get_elementlist, @params)
158
- graph.svg_data
159
- end
160
-
161
- def draw_tree
162
- svg = draw_svg
163
- image, data = Magick::Image.from_blob(svg) do |im|
164
- im.format = 'svg'
165
- end
166
- if @params[:format] == "png"
167
- image = draw_png(false)
168
- else
169
- image.to_blob do |im|
170
- im.format = @params[:format].upcase
171
- end
172
- end
173
- image
174
- end
175
- end
176
- end
177
-
1
+ # frozen_string_literal: true
2
+
3
+ #==========================
4
+ # rsyntaxtree.rb
5
+ #==========================
6
+ #
7
+ # Facade of rsyntaxtree library. When loaded by a driver script, it does all
8
+ # the necessary 'require' to use the library.
9
+ # Copyright (c) 2007-2023 Yoichiro Hasebe <yohasebe@gmail.com>
10
+
11
+ FONT_DIR = File.expand_path(File.join(__dir__, "/../fonts"))
12
+ ETYPE_NODE = 1
13
+ ETYPE_LEAF = 2
14
+ SUBSCRIPT_CONST = 0.7
15
+ FONT_SCALING = 2
16
+ WHITESPACE_BLOCK = "■"
17
+
18
+ class RSTError < StandardError
19
+ def initialize(msg = "Error: something unexpected occurred")
20
+ msg.gsub!(WHITESPACE_BLOCK, "<>")
21
+ super msg
22
+ end
23
+ end
24
+
25
+ require_relative 'rsyntaxtree/utils'
26
+ require_relative 'rsyntaxtree/element'
27
+ require_relative 'rsyntaxtree/elementlist'
28
+ require_relative 'rsyntaxtree/svg_graph'
29
+ require_relative 'rsyntaxtree/version'
30
+ require_relative 'rsyntaxtree/string_parser'
31
+
32
+ require 'cgi'
33
+ require 'rsvg2'
34
+ require 'rmagick'
35
+
36
+ module RSyntaxTree
37
+ class RSGenerator
38
+ def initialize(params = {})
39
+ new_params = {}
40
+ fontset = {}
41
+ params.each do |keystr, value|
42
+ key = keystr.to_sym
43
+ case key
44
+ when :data
45
+ data = value
46
+ data = data.gsub('-AMP-', '&')
47
+ .gsub('-PERCENT-', "%")
48
+ .gsub('-PRIME-', "'")
49
+ .gsub('-SCOLON-', ';')
50
+ .gsub('-OABRACKET-', '<')
51
+ .gsub('-CABRACKET-', '>')
52
+ .gsub('¥¥', '\¥')
53
+ .gsub(/(?<!\\)¥/, "\\")
54
+ new_params[key] = data
55
+
56
+ when :symmetrize, :color, :transparent, :polyline
57
+ new_params[key] = value && (value != "off" && value != "false") ? true : false
58
+ when :fontsize
59
+ new_params[key] = value.to_i * FONT_SCALING
60
+ when :margin
61
+ new_params[key] = value.to_i * FONT_SCALING * 5
62
+ when :vheight
63
+ new_params[key] = value.to_f
64
+ when :fontstyle
65
+ case value
66
+ when "noto-sans", "sans"
67
+ fontset[:normal] = FONT_DIR + "/NotoSans-Regular.ttf"
68
+ fontset[:italic] = FONT_DIR + "/NotoSans-Italic.ttf"
69
+ fontset[:bold] = FONT_DIR + "/NotoSans-Bold.ttf"
70
+ fontset[:bolditalic] = FONT_DIR + "/NotoSans-BoldItalic.ttf"
71
+ fontset[:math] = FONT_DIR + "/NotoSansMath-Regular.ttf"
72
+ fontset[:cjk] = FONT_DIR + "/NotoSansJP-Regular.otf"
73
+ fontset[:emoji] = FONT_DIR + "/OpenMoji-Black.ttf"
74
+ new_params[:fontstyle] = "sans"
75
+ when "noto-serif", "serif"
76
+ fontset[:normal] = FONT_DIR + "/NotoSerif-Regular.ttf"
77
+ fontset[:italic] = FONT_DIR + "/NotoSerif-Italic.ttf"
78
+ fontset[:bold] = FONT_DIR + "/NotoSerif-Bold.ttf"
79
+ fontset[:bolditalic] = FONT_DIR + "/NotoSerif-BoldItalic.ttf"
80
+ fontset[:math] = FONT_DIR + "/latinmodern-math.otf"
81
+ fontset[:cjk] = FONT_DIR + "/NotoSerifJP-Regular.otf"
82
+ fontset[:emoji] = FONT_DIR + "/OpenMoji-Black.ttf"
83
+ new_params[:fontstyle] = "serif"
84
+ when "cjk zenhei", "cjk"
85
+ fontset[:normal] = FONT_DIR + "/wqy-zenhei.ttf"
86
+ fontset[:italic] = FONT_DIR + "/NotoSans-Italic.ttf"
87
+ fontset[:bold] = FONT_DIR + "/NotoSans-Bold.ttf"
88
+ fontset[:bolditalic] = FONT_DIR + "/NotoSans-BoldItalic.ttf"
89
+ fontset[:math] = FONT_DIR + "/NotoSansMath-Regular.ttf"
90
+ fontset[:cjk] = FONT_DIR + "/wqy-zenhei.ttf"
91
+ fontset[:emoji] = FONT_DIR + "/OpenMoji-Black.ttf"
92
+ new_params[:fontstyle] = "cjk"
93
+ end
94
+ else
95
+ new_params[key] = value
96
+ end
97
+ end
98
+
99
+ # defaults to the following
100
+ @params = {
101
+ symmetrize: true,
102
+ color: true,
103
+ transparent: false,
104
+ fontsize: 16,
105
+ format: "png",
106
+ leafstyle: "auto",
107
+ filename: "syntree",
108
+ data: "",
109
+ margin: 0,
110
+ vheight: 1.0,
111
+ polyline: false
112
+ }
113
+
114
+ @params.merge! new_params
115
+ @params[:fontsize] = @params[:fontsize] * FONT_SCALING
116
+ @params[:margin] = @params[:margin] * FONT_SCALING
117
+ @params[:fontset] = fontset
118
+ single_x_metrics = FontMetrics.get_metrics("X", fontset[:normal], @params[:fontsize], :normal, :normal)
119
+ @global = {}
120
+ @global[:single_x_metrics] = single_x_metrics
121
+ @global[:height_connector_to_text] = single_x_metrics.height / 2.0
122
+ @global[:single_line_height] = single_x_metrics.height * 2.0
123
+ @global[:width_half_x] = single_x_metrics.width / 2.0
124
+ @global[:height_connector] = single_x_metrics.height * 1.0 * @params[:vheight]
125
+ @global[:h_gap_between_nodes] = single_x_metrics.width * 0.8
126
+ @global[:box_vertical_margin] = single_x_metrics.height * 0.8
127
+ end
128
+
129
+ def self.check_data(text)
130
+ raise RSTError, "Error: input text is empty" if text.to_s == ""
131
+
132
+ StringParser.valid?(text)
133
+ end
134
+
135
+ def draw_png(binary = false)
136
+ svg = draw_svg
137
+ rsvg = RSVG::Handle.new_from_data(svg)
138
+ dim = rsvg.dimensions
139
+ surface = Cairo::ImageSurface.new(Cairo::FORMAT_ARGB32, dim.width, dim.height)
140
+ context = Cairo::Context.new(surface)
141
+ context.render_rsvg_handle(rsvg)
142
+ b = StringIO.new
143
+ surface.write_to_png(b)
144
+ if binary
145
+ b
146
+ else
147
+ b.string
148
+ end
149
+ end
150
+
151
+ def draw_svg
152
+ sp = StringParser.new(@params[:data].gsub('&', '&amp;'), @params[:fontset], @params[:fontsize], @global)
153
+ sp.parse
154
+ graph = SVGGraph.new(sp.get_elementlist, @params, @global)
155
+ graph.svg_data
156
+ end
157
+
158
+ def draw_tree
159
+ svg = draw_svg
160
+ image, _data = Magick::Image.from_blob(svg) do |im|
161
+ im.format = 'svg'
162
+ end
163
+ if @params[:format] == "png"
164
+ image = draw_png(false)
165
+ else
166
+ image.to_blob do |im|
167
+ im.format = @params[:format].upcase
168
+ end
169
+ end
170
+ image
171
+ end
172
+ end
173
+ end
data/rsyntaxtree.gemspec CHANGED
@@ -1,7 +1,6 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
1
+ # frozen_string_literal: true
3
2
 
4
- require "rsyntaxtree/version"
3
+ require_relative "lib/rsyntaxtree/version"
5
4
 
6
5
  Gem::Specification.new do |s|
7
6
  s.name = "rsyntaxtree"
@@ -9,16 +8,19 @@ Gem::Specification.new do |s|
9
8
  s.authors = ["Yoichiro Hasebe"]
10
9
  s.email = ["yohasebe@gmail.com"]
11
10
  s.homepage = "http://github.com/yohasebe/rsyntaxtree"
12
- s.summary = %q{RSyntaxTree is a graphical syntax tree generator written in Ruby}
13
- s.description = %q{Syntax tree generator made with Ruby}
11
+ s.summary = "RSyntaxTree is a graphical syntax tree generator written in Ruby"
12
+ s.description = "Syntax tree generator made with Ruby"
14
13
  s.licenses = ["MIT"]
14
+ s.required_ruby_version = Gem::Requirement.new(">= 2.6")
15
15
  s.files = `git ls-files`.split("\n")
16
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
17
17
  s.require_paths = ["lib"]
18
18
 
19
19
  # specify any dependencies here; for example:
20
- s.add_runtime_dependency 'rmagick', '~> 4.2', '>= 4.2.3'
21
- s.add_runtime_dependency 'optimist', '~> 3.0', '>= 3.0.1'
22
- s.add_runtime_dependency 'parslet'
23
- s.add_runtime_dependency 'rsvg2'
20
+ s.add_runtime_dependency "optimist", "~> 3.0", ">= 3.0.1"
21
+ s.add_runtime_dependency "parslet"
22
+ s.add_runtime_dependency "rmagick", "~> 4.2", ">= 4.2.3"
23
+ s.add_runtime_dependency "rsvg2"
24
+
25
+ s.add_development_dependency "yaml"
24
26
  end
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "minitest/autorun"
4
+ require "minitest/pride"
5
+ require "yaml"
6
+ require_relative '../lib/rsyntaxtree'
7
+ require_relative '../lib/rsyntaxtree/utils'
8
+
9
+ class ExampleParserTest < Minitest::Test
10
+ examples_dir = File.expand_path(File.join(__dir__, "..", "docs", "_examples"))
11
+ svg_dir = File.expand_path(File.join(__dir__, "..", "docs", "assets", "svg"))
12
+
13
+ Dir.glob("*.md", base: examples_dir).map do |md|
14
+ md = File.join(examples_dir, md)
15
+ config = YAML.load_file(md)
16
+ rst = File.read(md).scan(/```([^`]+)```/m).last.first
17
+
18
+ opts = {
19
+ format: "png",
20
+ leafstyle: "auto",
21
+ fontstyle: "sans",
22
+ fontsize: 16,
23
+ margin: 1,
24
+ vheight: 2.0,
25
+ color: "on",
26
+ symmetrize: "on",
27
+ transparent: "off",
28
+ polyline: "off"
29
+ }
30
+ name = nil
31
+ config.each do |key, value|
32
+ next if value.to_s == ""
33
+
34
+ case key
35
+ when "name"
36
+ name = value
37
+ when "colorization"
38
+ opts[:color] = value
39
+ when "polyline"
40
+ opts[:polyline] = value
41
+ when "symmetrization"
42
+ opts[:symmetrize] = value
43
+ when "connector"
44
+ opts[:leafstyle] = value
45
+ when "font"
46
+ opts[:fontstyle] = case value
47
+ when /sans/i
48
+ "sans"
49
+ when /serif/i
50
+ "serif"
51
+ when /wqy/i
52
+ "cjk"
53
+ else
54
+ "sans"
55
+ end
56
+ end
57
+ end
58
+
59
+ opts[:data] = rst
60
+ rsg = RSyntaxTree::RSGenerator.new(opts)
61
+
62
+ #################################
63
+ # To test SVG, run the code below
64
+ #################################
65
+ svg = rsg.draw_svg
66
+ opts[:svg] = svg
67
+ svg_path = File.join(svg_dir, "#{name}.svg")
68
+ svg_code = File.read(svg_path)
69
+ puts "Creating example SVG test case: #{name}"
70
+
71
+ define_method "test_#{name}" do
72
+ assert_equal svg_code, opts[:svg]
73
+ end
74
+
75
+ ##########################################
76
+ # To create SVG for the tests, comment-out
77
+ # above block and run the code below
78
+ ##########################################
79
+ # File.open(File.join(svg_dir, "#{name}.svg"), "w") do |f|
80
+ # puts "Creating svg file: #{name}.svg"
81
+ # svg = rsg.draw_svg
82
+ # f.write(svg)
83
+ # end
84
+
85
+ ##########################################
86
+ # To create SVG for the documentation,
87
+ # comment-out above and run the code below
88
+ ##########################################
89
+ # png_dir = File.expand_path(File.join(__dir__, "..", "docs", "assets", "img"))
90
+ # File.open(File.join(png_dir, "#{name}.png"), "w") do |f|
91
+ # puts "Creating png file: #{name}.png"
92
+ # png = rsg.draw_png
93
+ # f.write(png)
94
+ # end
95
+ end
96
+ end
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "minitest/autorun"
2
4
  require "minitest/pride"
3
- require "./lib/rsyntaxtree/markup_parser.rb"
5
+ require_relative "../lib/rsyntaxtree/markup_parser"
4
6
 
5
7
  class MarkupParserTest < Minitest::Test
6
8
  def setup
@@ -203,5 +205,4 @@ class MarkupParserTest < Minitest::Test
203
205
  Markup.parse text2
204
206
  # {:status=>:error, :text=>"!^#----\\n\\nX_Y_Z+1+>2"}
205
207
  end
206
-
207
208
  end