rsyntaxtree 1.0.8 → 1.1.1

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.
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