asciidoctor-diagram 2.0.2 → 2.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +78 -1
  3. data/README.adoc +25 -507
  4. data/Rakefile +1 -1
  5. data/docs/antora.yml +3 -0
  6. data/{images → docs/modules/ROOT/images}/asciidoctor-diagram-classes.png +0 -0
  7. data/docs/modules/ROOT/images/asciidoctor-diagram-process.png +0 -0
  8. data/docs/modules/ROOT/pages/index.adoc +21 -0
  9. data/docs/modules/ROOT/partials/advanced.adoc +319 -0
  10. data/docs/modules/ROOT/partials/create_diagram.adoc +132 -0
  11. data/docs/modules/ROOT/partials/generate.adoc +15 -0
  12. data/docs/modules/ROOT/partials/installation.adoc +19 -0
  13. data/docs/modules/ROOT/partials/uris.adoc +40 -0
  14. data/examples/features.adoc +1 -1
  15. data/lib/asciidoctor-diagram.rb +4 -0
  16. data/lib/asciidoctor-diagram/a2s/converter.rb +10 -6
  17. data/lib/asciidoctor-diagram/blockdiag/converter.rb +1 -1
  18. data/lib/asciidoctor-diagram/bpmn/converter.rb +3 -3
  19. data/lib/asciidoctor-diagram/diagram_converter.rb +9 -1
  20. data/lib/asciidoctor-diagram/diagram_processor.rb +92 -48
  21. data/lib/asciidoctor-diagram/diagram_source.rb +71 -24
  22. data/lib/asciidoctor-diagram/diagrams.rb +7 -0
  23. data/lib/asciidoctor-diagram/diagrams/converter.rb +49 -0
  24. data/lib/asciidoctor-diagram/diagrams/extension.rb +14 -0
  25. data/lib/asciidoctor-diagram/ditaa/converter.rb +20 -7
  26. data/lib/asciidoctor-diagram/ditaa/ditaa-1.3.20.jar +0 -0
  27. data/lib/asciidoctor-diagram/dpic.rb +7 -0
  28. data/lib/asciidoctor-diagram/dpic/converter.rb +30 -0
  29. data/lib/asciidoctor-diagram/dpic/extension.rb +14 -0
  30. data/lib/asciidoctor-diagram/gnuplot/converter.rb +8 -8
  31. data/lib/asciidoctor-diagram/graphviz/converter.rb +2 -2
  32. data/lib/asciidoctor-diagram/http/converter.rb +52 -14
  33. data/lib/asciidoctor-diagram/http/server.rb +11 -6
  34. data/lib/asciidoctor-diagram/lilypond/converter.rb +13 -3
  35. data/lib/asciidoctor-diagram/meme/converter.rb +22 -16
  36. data/lib/asciidoctor-diagram/mermaid/converter.rb +45 -14
  37. data/lib/asciidoctor-diagram/msc/converter.rb +2 -2
  38. data/lib/asciidoctor-diagram/pikchr.rb +7 -0
  39. data/lib/asciidoctor-diagram/pikchr/converter.rb +33 -0
  40. data/lib/asciidoctor-diagram/pikchr/extension.rb +14 -0
  41. data/lib/asciidoctor-diagram/plantuml/converter.rb +68 -43
  42. data/lib/asciidoctor-diagram/plantuml/plantuml-1.3.20.jar +0 -0
  43. data/lib/asciidoctor-diagram/smcat/converter.rb +3 -3
  44. data/lib/asciidoctor-diagram/svgbob/converter.rb +6 -2
  45. data/lib/asciidoctor-diagram/symbolator.rb +7 -0
  46. data/lib/asciidoctor-diagram/symbolator/converter.rb +23 -0
  47. data/lib/asciidoctor-diagram/symbolator/extension.rb +14 -0
  48. data/lib/asciidoctor-diagram/syntrax/converter.rb +9 -6
  49. data/lib/asciidoctor-diagram/tikz/converter.rb +20 -1
  50. data/lib/asciidoctor-diagram/umlet/converter.rb +11 -2
  51. data/lib/asciidoctor-diagram/util/cli.rb +16 -1
  52. data/lib/asciidoctor-diagram/util/cli_generator.rb +30 -8
  53. data/lib/asciidoctor-diagram/util/gif.rb +2 -2
  54. data/lib/asciidoctor-diagram/util/java.rb +118 -3
  55. data/lib/asciidoctor-diagram/util/java_jruby.rb +4 -1
  56. data/lib/asciidoctor-diagram/util/java_socket.rb +8 -109
  57. data/lib/asciidoctor-diagram/util/pdf.rb +2 -2
  58. data/lib/asciidoctor-diagram/util/png.rb +2 -2
  59. data/lib/{server-1.3.15.jar → asciidoctor-diagram/util/server-1.3.20.jar} +0 -0
  60. data/lib/asciidoctor-diagram/util/svg.rb +66 -18
  61. data/lib/asciidoctor-diagram/vega/converter.rb +2 -2
  62. data/lib/asciidoctor-diagram/version.rb +1 -1
  63. data/spec/a2s_spec.rb +6 -144
  64. data/spec/blockdiag_spec.rb +6 -204
  65. data/spec/bpmn_spec.rb +52 -92
  66. data/spec/bytefield_spec.rb +6 -144
  67. data/spec/diagrams_spec.rb +23 -0
  68. data/spec/ditaa_spec.rb +6 -144
  69. data/spec/dpic_spec.rb +19 -0
  70. data/spec/erd_spec.rb +6 -203
  71. data/spec/gnuplot_spec.rb +10 -263
  72. data/spec/graphviz_spec.rb +6 -145
  73. data/spec/lilypond_spec.rb +6 -144
  74. data/spec/mermaid_spec.rb +69 -211
  75. data/spec/msc_spec.rb +6 -203
  76. data/spec/nomnoml_spec.rb +7 -145
  77. data/spec/pikchr_spec.rb +69 -0
  78. data/spec/plantuml_spec.rb +63 -553
  79. data/spec/shaape_spec.rb +12 -224
  80. data/spec/shared_examples.rb +603 -0
  81. data/spec/smcat_spec.rb +6 -144
  82. data/spec/svgbob_spec.rb +6 -144
  83. data/spec/symbolator_spec.rb +23 -0
  84. data/spec/syntrax_spec.rb +7 -217
  85. data/spec/test_helper.rb +4 -29
  86. data/spec/tikz_spec.rb +68 -18
  87. data/spec/umlet_spec.rb +3 -59
  88. data/spec/vega_spec.rb +6 -119
  89. data/spec/wavedrom_spec.rb +3 -200
  90. metadata +82 -18
  91. data/README_zh-CN.adoc +0 -336
  92. data/images/asciidoctor-diagram-process.png +0 -0
  93. data/lib/batik-all-1.10.jar +0 -0
  94. data/lib/ditaa-1.3.15.jar +0 -0
  95. data/lib/ditaamini-0.12.jar +0 -0
  96. data/lib/jlatexmath-minimal-1.0.5.jar +0 -0
  97. data/lib/plantuml-1.3.15.jar +0 -0
  98. data/lib/plantuml.jar +0 -0
  99. data/spec/bpmn-example.xml +0 -44
@@ -2,8 +2,8 @@ module Asciidoctor
2
2
  module Diagram
3
3
  # @private
4
4
  module PDF
5
- def self.get_image_size(_)
6
- nil
5
+ def self.post_process_image(data, optimise)
6
+ [data, nil, nil]
7
7
  end
8
8
  end
9
9
  end
@@ -6,7 +6,7 @@ module Asciidoctor
6
6
  module PNG
7
7
  PNG_SIGNATURE = [137, 80, 78, 71, 13, 10, 26, 10].pack('CCCCCCCC')
8
8
 
9
- def self.get_image_size(data)
9
+ def self.post_process_image(data, optimise)
10
10
  bio = BinaryIO.new(data)
11
11
  png_signature = bio.read_string(8)
12
12
  raise "Invalid PNG signature" unless png_signature == PNG_SIGNATURE
@@ -18,7 +18,7 @@ module Asciidoctor
18
18
 
19
19
  width = bio.read_uint32_be
20
20
  height = bio.read_uint32_be
21
- [width, height]
21
+ [data, width, height]
22
22
  end
23
23
  end
24
24
  end
@@ -1,34 +1,82 @@
1
1
  require_relative 'binaryio'
2
+ require 'rexml/document'
2
3
 
3
4
  module Asciidoctor
4
5
  module Diagram
5
6
  # @private
6
7
  module SVG
7
- def self.get_image_size(data)
8
- if m = START_TAG_REGEX.match(data)
9
- start_tag = m[0]
10
- if (w = WIDTH_REGEX.match(start_tag)) && (h = HEIGHT_REGEX.match(start_tag))
11
- width = w[:value].to_i * to_px_factor(w[:unit])
12
- height = h[:value].to_i * to_px_factor(h[:unit])
13
- return [width.to_i, height.to_i]
14
- end
8
+ def self.post_process_image(data, optimise)
9
+ svg = REXML::Document.new(data)
15
10
 
16
- if v = VIEWBOX_REGEX.match(start_tag)
17
- width = v[:width]
18
- height = v[:height]
19
- return [width.to_i, height.to_i]
20
- end
11
+ root = svg.root
12
+
13
+ unless root.attributes['xmlns']
14
+ root.add_attribute('xmlns', 'http://www.w3.org/2000/svg')
21
15
  end
22
16
 
23
- nil
17
+ unless root.attributes['preserveAspectRatio']
18
+ root.add_attribute('preserveAspectRatio', 'xMidYMid meet')
19
+ end
20
+
21
+ width = nil
22
+ height = nil
23
+
24
+ if (w = WIDTH_HEIGHT_REGEX.match(root.attributes['width'])) && (h = WIDTH_HEIGHT_REGEX.match(root.attributes['height']))
25
+ width = to_numeric(w[:value]) * to_px_factor(w[:unit])
26
+ height = to_numeric(h[:value]) * to_px_factor(h[:unit])
27
+ end
28
+
29
+ viewbox = root.attributes['viewBox']
30
+ if (v = VIEWBOX_REGEX.match(viewbox)) && width.nil? && height.nil?
31
+ width = to_numeric(v[:width])
32
+ height = to_numeric(v[:height])
33
+ end
34
+
35
+ if viewbox.nil? && width && height
36
+ root.add_attribute('viewBox', "0 0 #{width.to_s} #{height.to_s}")
37
+ end
38
+
39
+ indent = 2
40
+ if optimise
41
+ remove_comments(svg)
42
+ indent = -1
43
+ end
44
+
45
+ patched_svg = ""
46
+ svg.write(:output => patched_svg, :indent => indent, :transitive => true)
47
+
48
+ [patched_svg, width, height]
24
49
  end
25
50
 
26
51
  private
27
52
 
28
- START_TAG_REGEX = /<svg[^>]*>/
29
- WIDTH_REGEX = /width="(?<value>\d+(?:\.\d+)?)(?<unit>[a-zA-Z]+)?"/
30
- HEIGHT_REGEX = /height="(?<value>\d+(?:\.\d+)?)(?<unit>[a-zA-Z]+)?"/
31
- VIEWBOX_REGEX = /viewBox="\d+(?:\.\d+)? \d+(?:\.\d+)? (?<width>\d+(?:\.\d+)?) (?<height>\d+(?:\.\d+)?)"/
53
+ def self.remove_comments(parent)
54
+ comments = []
55
+
56
+ parent.each do |child|
57
+ case child
58
+ when REXML::Comment
59
+ comments << child
60
+ when REXML::Parent
61
+ remove_comments(child)
62
+ end
63
+ end
64
+
65
+ comments.each do |c|
66
+ c.remove
67
+ end
68
+ end
69
+
70
+ def self.to_numeric(text)
71
+ if text.include? '.'
72
+ text.to_f
73
+ else
74
+ text.to_i
75
+ end
76
+ end
77
+
78
+ WIDTH_HEIGHT_REGEX = /^\s*(?<value>\d+(?:\.\d+)?)\s*(?<unit>[a-zA-Z]+)?\s*$/
79
+ VIEWBOX_REGEX = /^\s*\d+(?:\.\d+)?\s*\d+(?:\.\d+)?\s*(?<width>\d+(?:\.\d+)?)\s*(?<height>\d+(?:\.\d+)?)\s*$/
32
80
 
33
81
  def self.to_px_factor(unit)
34
82
  case unit
@@ -15,9 +15,9 @@ module Asciidoctor
15
15
  end
16
16
 
17
17
 
18
- def collect_options(source, name)
18
+ def collect_options(source)
19
19
  {
20
- :vegalite => name.to_s.include?('lite') || source.attr('vegalite')
20
+ :vegalite => source.diagram_type.to_s.include?('lite') || source.attr('vegalite')
21
21
  }
22
22
  end
23
23
 
@@ -1,5 +1,5 @@
1
1
  module Asciidoctor
2
2
  module Diagram
3
- VERSION = "2.0.2"
3
+ VERSION = "2.1.2"
4
4
  end
5
5
  end
data/spec/a2s_spec.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  require_relative 'test_helper'
2
2
 
3
- code = <<-eos
3
+ A2S_CODE = <<-eos
4
4
  .--. .---. .---. .---. .---. .---. .---.
5
5
  | | OS API '---' '---' '---' '---' '---' '---'
6
6
  v | | | | | | |
@@ -20,148 +20,10 @@ code = <<-eos
20
20
  '---------------------------------------'
21
21
  eos
22
22
 
23
- describe Asciidoctor::Diagram::AsciiToSvgBlockMacroProcessor, :broken_on_travis, :broken_on_windows do
24
- it "should generate SVG images when format is set to 'svg'" do
25
- File.write('a2s.txt', code)
26
-
27
- doc = <<-eos
28
- = Hello, a2s!
29
- Doc Writer <doc@example.com>
30
-
31
- == First Section
32
-
33
- a2s::a2s.txt[format="svg"]
34
- eos
35
-
36
- d = load_asciidoc doc
37
- expect(d).to_not be_nil
38
-
39
- b = d.find { |bl| bl.context == :image }
40
- expect(b).to_not be_nil
41
-
42
- expect(b.content_model).to eq :empty
43
-
44
- target = b.attributes['target']
45
- expect(target).to_not be_nil
46
- expect(target).to match(/\.svg/)
47
- expect(File.exist?(target)).to be true
48
-
49
- expect(b.attributes['width']).to_not be_nil
50
- expect(b.attributes['height']).to_not be_nil
51
- end
23
+ describe Asciidoctor::Diagram::AsciiToSvgBlockMacroProcessor do
24
+ include_examples "block_macro", :a2s, A2S_CODE, [:svg]
52
25
  end
53
26
 
54
- describe Asciidoctor::Diagram::AsciiToSvgBlockProcessor, :broken_on_travis, :broken_on_windows do
55
- it "should generate SVG images when format is set to 'svg'" do
56
- doc = <<-eos
57
- = Hello, a2s!
58
- Doc Writer <doc@example.com>
59
-
60
- == First Section
61
-
62
- [a2s, format="svg"]
63
- ----
64
- #{code}
65
- ----
66
- eos
67
-
68
- d = load_asciidoc doc
69
- expect(d).to_not be_nil
70
-
71
- b = d.find { |bl| bl.context == :image }
72
- expect(b).to_not be_nil
73
-
74
- expect(b.content_model).to eq :empty
75
-
76
- target = b.attributes['target']
77
- expect(target).to_not be_nil
78
- expect(target).to match(/\.svg/)
79
- expect(File.exist?(target)).to be true
80
-
81
- expect(b.attributes['width']).to_not be_nil
82
- expect(b.attributes['height']).to_not be_nil
83
- end
84
-
85
- it "should raise an error when when format is set to an invalid value" do
86
- doc = <<-eos
87
- = Hello, a2s!
88
- Doc Writer <doc@example.com>
89
-
90
- == First Section
91
-
92
- [a2s, format="foobar"]
93
- ----
94
- ----
95
- eos
96
-
97
- expect { load_asciidoc doc }.to raise_error(/support.*format/i)
98
- end
99
-
100
- it "should not regenerate images when source has not changed" do
101
- File.write('a2s.txt', code)
102
-
103
- doc = <<-eos
104
- = Hello, a2s!
105
- Doc Writer <doc@example.com>
106
-
107
- == First Section
108
-
109
- a2s::a2s.txt
110
-
111
- [a2s]
112
- ----
113
- #{code}
114
- ----
115
- eos
116
-
117
- d = load_asciidoc doc
118
- b = d.find { |bl| bl.context == :image }
119
- expect(b).to_not be_nil
120
- target = b.attributes['target']
121
- mtime1 = File.mtime(target)
122
-
123
- sleep 1
124
-
125
- d = load_asciidoc doc
126
-
127
- mtime2 = File.mtime(target)
128
-
129
- expect(mtime2).to eq mtime1
130
- end
131
-
132
- it "should handle two block macros with the same source" do
133
- File.write('a2s.txt', code)
134
-
135
- doc = <<-eos
136
- = Hello, a2s!
137
- Doc Writer <doc@example.com>
138
-
139
- == First Section
140
-
141
- a2s::a2s.txt[]
142
- a2s::a2s.txt[]
143
- eos
144
-
145
- load_asciidoc doc
146
- expect(File.exist?('a2s.svg')).to be true
147
- end
148
-
149
- it "should respect target attribute in block macros" do
150
- File.write('a2s.txt', code)
151
-
152
- doc = <<-eos
153
- = Hello, a2s!
154
- Doc Writer <doc@example.com>
155
-
156
- == First Section
157
-
158
- a2s::a2s.txt["foobar"]
159
- a2s::a2s.txt["foobaz"]
160
- eos
161
-
162
- load_asciidoc doc
163
- expect(File.exist?('foobar.svg')).to be true
164
- expect(File.exist?('foobaz.svg')).to be true
165
- expect(File.exist?('a2s.svg')).to be false
166
- end
167
- end
27
+ describe Asciidoctor::Diagram::AsciiToSvgBlockProcessor do
28
+ include_examples "block", :svgbob, A2S_CODE, [:svg]
29
+ end
@@ -1,214 +1,16 @@
1
1
  require_relative 'test_helper'
2
2
 
3
- code = <<-eos
3
+ BLOCKDIAG_CODE = <<-eos
4
4
  blockdiag {
5
5
  A -> B -> C -> D;
6
6
  A -> E -> F -> G;
7
7
  }
8
8
  eos
9
9
 
10
- describe Asciidoctor::Diagram::BlockDiagBlockMacroProcessor, :broken_on_appveyor do
11
- it "should generate PNG images when format is set to 'png'" do
12
- File.write('blockdiag.txt', code)
13
-
14
- doc = <<-eos
15
- = Hello, BlockDiag!
16
- Doc Writer <doc@example.com>
17
-
18
- == First Section
19
-
20
- blockdiag::blockdiag.txt[format="png"]
21
- eos
22
-
23
- d = load_asciidoc doc
24
- expect(d).to_not be_nil
25
-
26
- b = d.find { |bl| bl.context == :image }
27
- expect(b).to_not be_nil
28
-
29
- expect(b.content_model).to eq :empty
30
-
31
- target = b.attributes['target']
32
- expect(target).to_not be_nil
33
- expect(target).to match(/\.png$/)
34
- expect(File.exist?(target)).to be true
35
-
36
- expect(b.attributes['width']).to_not be_nil
37
- expect(b.attributes['height']).to_not be_nil
38
- end
10
+ describe Asciidoctor::Diagram::BlockDiagBlockMacroProcessor do
11
+ include_examples "block_macro", :blockdiag, BLOCKDIAG_CODE, [:png, :svg, :pdf]
39
12
  end
40
13
 
41
- describe Asciidoctor::Diagram::BlockDiagBlockProcessor, :broken_on_appveyor do
42
- it "should generate PNG images when format is set to 'png'" do
43
- doc = <<-eos
44
- = Hello, BlockDiag!
45
- Doc Writer <doc@example.com>
46
-
47
- == First Section
48
-
49
- [blockdiag, format="png"]
50
- ----
51
- #{code}
52
- ----
53
- eos
54
-
55
- d = load_asciidoc doc
56
- expect(d).to_not be_nil
57
-
58
- b = d.find { |bl| bl.context == :image }
59
- expect(b).to_not be_nil
60
-
61
- expect(b.content_model).to eq :empty
62
-
63
- target = b.attributes['target']
64
- expect(target).to_not be_nil
65
- expect(target).to match(/\.png$/)
66
- expect(File.exist?(target)).to be true
67
-
68
- expect(b.attributes['width']).to_not be_nil
69
- expect(b.attributes['height']).to_not be_nil
70
- end
71
-
72
- it "should generate SVG images when format is set to 'svg'" do
73
- doc = <<-eos
74
- = Hello, BlockDiag!
75
- Doc Writer <doc@example.com>
76
-
77
- == First Section
78
-
79
- [blockdiag, format="svg"]
80
- ----
81
- #{code}
82
- ----
83
- eos
84
-
85
- d = load_asciidoc doc
86
- expect(d).to_not be_nil
87
-
88
- b = d.find { |bl| bl.context == :image }
89
- expect(b).to_not be_nil
90
-
91
- expect(b.content_model).to eq :empty
92
-
93
- target = b.attributes['target']
94
- expect(target).to_not be_nil
95
- expect(target).to match(/\.svg/)
96
- expect(File.exist?(target)).to be true
97
-
98
- expect(b.attributes['width']).to_not be_nil
99
- expect(b.attributes['height']).to_not be_nil
100
- end
101
-
102
- it "should generate PDF files when format is set to 'pdf'" do
103
- doc = <<-eos
104
- = Hello, BlockDiag!
105
- Doc Writer <doc@example.com>
106
-
107
- == First Section
108
-
109
- [blockdiag, format="pdf"]
110
- ----
111
- #{code}
112
- ----
113
- eos
114
-
115
- d = load_asciidoc doc
116
- expect(d).to_not be_nil
117
-
118
- b = d.find { |bl| bl.context == :image }
119
- expect(b).to_not be_nil
120
-
121
- expect(b.content_model).to eq :empty
122
-
123
- target = b.attributes['target']
124
- expect(target).to_not be_nil
125
- expect(target).to match(/\.pdf/)
126
- expect(File.exist?(target)).to be true
127
-
128
- expect(b.attributes['width']).to be_nil
129
- expect(b.attributes['height']).to be_nil
130
- end
131
-
132
- it "should raise an error when when format is set to an invalid value" do
133
- doc = <<-eos
134
- = Hello, BlockDiag!
135
- Doc Writer <doc@example.com>
136
-
137
- == First Section
138
-
139
- [blockdiag, format="foobar"]
140
- ----
141
- ----
142
- eos
143
-
144
- expect { load_asciidoc doc }.to raise_error(/support.*format/i)
145
- end
146
-
147
- it "should not regenerate images when source has not changed" do
148
- File.write('blockdiag.txt', code)
149
-
150
- doc = <<-eos
151
- = Hello, BlockDiag!
152
- Doc Writer <doc@example.com>
153
-
154
- == First Section
155
-
156
- blockdiag::blockdiag.txt
157
-
158
- [blockdiag, format="png"]
159
- ----
160
- #{code}
161
- ----
162
- eos
163
-
164
- d = load_asciidoc doc
165
- b = d.find { |bl| bl.context == :image }
166
- expect(b).to_not be_nil
167
- target = b.attributes['target']
168
- mtime1 = File.mtime(target)
169
-
170
- sleep 1
171
-
172
- d = load_asciidoc doc
173
-
174
- mtime2 = File.mtime(target)
175
-
176
- expect(mtime2).to eq mtime1
177
- end
178
-
179
- it "should handle two block macros with the same source" do
180
- File.write('blockdiag.txt', code)
181
-
182
- doc = <<-eos
183
- = Hello, BlockDiag!
184
- Doc Writer <doc@example.com>
185
-
186
- == First Section
187
-
188
- blockdiag::blockdiag.txt[]
189
- blockdiag::blockdiag.txt[]
190
- eos
191
-
192
- load_asciidoc doc
193
- expect(File.exist?('blockdiag.png')).to be true
194
- end
195
-
196
- it "should respect target attribute in block macros" do
197
- File.write('blockdiag.txt', code)
198
-
199
- doc = <<-eos
200
- = Hello, BlockDiag!
201
- Doc Writer <doc@example.com>
202
-
203
- == First Section
204
-
205
- blockdiag::blockdiag.txt["foobar"]
206
- blockdiag::blockdiag.txt["foobaz"]
207
- eos
208
-
209
- load_asciidoc doc
210
- expect(File.exist?('foobar.png')).to be true
211
- expect(File.exist?('foobaz.png')).to be true
212
- expect(File.exist?('blockdiag.png')).to be false
213
- end
214
- end
14
+ describe Asciidoctor::Diagram::BlockDiagBlockProcessor do
15
+ include_examples "block", :blockdiag, BLOCKDIAG_CODE, [:png, :svg, :pdf]
16
+ end