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
@@ -0,0 +1,7 @@
1
+ require 'asciidoctor/extensions'
2
+ require_relative 'diagrams/extension'
3
+
4
+ Asciidoctor::Extensions.register do
5
+ block Asciidoctor::Diagram::DiagramsBlockProcessor, :diagrams
6
+ block_macro Asciidoctor::Diagram::DiagramsBlockMacroProcessor, :diagrams
7
+ end
@@ -0,0 +1,49 @@
1
+ require_relative '../diagram_converter'
2
+ require_relative '../util/cli_generator'
3
+ require_relative '../util/platform'
4
+
5
+ module Asciidoctor
6
+ module Diagram
7
+ # @private
8
+ class DiagramsConverter
9
+ include DiagramConverter
10
+ include CliGenerator
11
+
12
+
13
+ def supported_formats
14
+ [:png, :svg, :pdf]
15
+ end
16
+
17
+ def convert(source, format, options)
18
+ python_path = source.find_command('python3', :attrs => ['diagrams-python'], :alt_cmds => ['python'])
19
+
20
+ code = source.to_s
21
+
22
+ match_data = /Diagram\((.*?)\)/.match(code)
23
+ raise "Could not find Diagram constructor" unless match_data
24
+
25
+ args = match_data[1].strip
26
+
27
+ target_file = Tempfile.new('diagrams')
28
+
29
+ diagram = 'Diagram('
30
+ diagram << args
31
+ diagram << ',' unless args.empty?
32
+ diagram << "filename=\"#{target_file.path}\""
33
+ diagram << ",outformat=\"#{format}\""
34
+ diagram << ')'
35
+
36
+ code = match_data.pre_match + diagram + match_data.post_match
37
+
38
+ begin
39
+ target_file.close
40
+ generate_stdin_file(python_path, code, target_file.path + ".#{format}") do |tool|
41
+ [tool, '-']
42
+ end
43
+ ensure
44
+ target_file.unlink
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,14 @@
1
+ require_relative 'converter'
2
+ require_relative '../diagram_processor'
3
+
4
+ module Asciidoctor
5
+ module Diagram
6
+ class DiagramsBlockProcessor < DiagramBlockProcessor
7
+ use_converter DiagramsConverter
8
+ end
9
+
10
+ class DiagramsBlockMacroProcessor < DiagramBlockMacroProcessor
11
+ use_converter DiagramsConverter
12
+ end
13
+ end
14
+ end
@@ -23,27 +23,40 @@ module Asciidoctor
23
23
  :transparent => lambda { |o, v| o << '--transparent' if v == 'true'}
24
24
  }
25
25
 
26
- JARS = ['ditaa-1.3.15.jar', 'ditaamini-0.12.jar'].map do |jar|
27
- File.expand_path File.join('../..', jar), File.dirname(__FILE__)
28
- end
29
- Java.classpath.concat JARS
30
-
26
+ CLASSPATH_ENV = 'DIAGRAM_DITAA_CLASSPATH'
27
+ DITAA_JARS = if ENV.has_key?(CLASSPATH_ENV)
28
+ ENV[CLASSPATH_ENV].split(File::PATH_SEPARATOR)
29
+ else
30
+ begin
31
+ require 'asciidoctor-diagram/ditaa/classpath'
32
+ ::Asciidoctor::Diagram::DitaaClasspath::JAR_FILES
33
+ rescue LoadError
34
+ raise "Could not load PlantUML. Eiter require 'asciidoctor-diagram-ditaamini' or specify the location of the PlantUML JAR(s) using the 'DIAGRAM_DITAA_CLASSPATH' environment variable."
35
+ end
36
+ end
37
+
38
+ Java.classpath.concat Dir[File.join(File.dirname(__FILE__), '*.jar')]
39
+ Java.classpath.concat DITAA_JARS
31
40
 
32
41
  def supported_formats
33
42
  [:png, :svg]
34
43
  end
35
44
 
36
- def collect_options(source, name)
45
+ def collect_options(source)
37
46
  options = {}
38
47
 
39
48
  OPTIONS.keys.each do |option|
40
49
  attr_name = option.to_s.tr('_', '-')
41
- options[option] = source.attr(attr_name, nil, name) || source.attr(attr_name, nil, 'ditaa-option')
50
+ options[option] = source.attr(attr_name) || source.attr(attr_name, nil, 'ditaa-option')
42
51
  end
43
52
 
44
53
  options
45
54
  end
46
55
 
56
+ def native_scaling?
57
+ true
58
+ end
59
+
47
60
  def convert(source, format, options)
48
61
  Java.load
49
62
 
@@ -0,0 +1,7 @@
1
+ require 'asciidoctor/extensions'
2
+ require_relative 'dpic/extension'
3
+
4
+ Asciidoctor::Extensions.register do
5
+ block Asciidoctor::Diagram::DpicBlockProcessor, :dpic
6
+ block_macro Asciidoctor::Diagram::DpicBlockMacroProcessor, :dpic
7
+ end
@@ -0,0 +1,30 @@
1
+ require_relative '../diagram_converter'
2
+ require_relative '../util/cli_generator'
3
+ require_relative '../util/platform'
4
+
5
+ module Asciidoctor
6
+ module Diagram
7
+ # @private
8
+ class DpicConverter
9
+ include DiagramConverter
10
+ include CliGenerator
11
+
12
+
13
+ def supported_formats
14
+ [:svg]
15
+ end
16
+
17
+ def convert(source, format, options)
18
+ dpic_path = source.find_command('dpic')
19
+
20
+ code = source.to_s
21
+ code.prepend ".PS\n" unless code.start_with?(".PS\n")
22
+ code << "\n.PE" unless code.start_with?("\n.PE")
23
+
24
+ generate_file_stdout(dpic_path, format.to_s, code) do |tool_path, input_path|
25
+ [tool_path, "-v", "-z", input_path]
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,14 @@
1
+ require_relative 'converter'
2
+ require_relative '../diagram_processor'
3
+
4
+ module Asciidoctor
5
+ module Diagram
6
+ class DpicBlockProcessor < DiagramBlockProcessor
7
+ use_converter DpicConverter
8
+ end
9
+
10
+ class DpicBlockMacroProcessor < DiagramBlockMacroProcessor
11
+ use_converter DpicConverter
12
+ end
13
+ end
14
+ end
@@ -14,15 +14,15 @@ module Asciidoctor
14
14
  [:png, :svg, :gif, :txt, :literal]
15
15
  end
16
16
 
17
- def collect_options(source, name)
17
+ def collect_options(source)
18
18
  {
19
- :width => source.attr('width', nil, name),
20
- :height => source.attr('height', nil, name),
21
- :transparent => source.attr('transparent', nil, name),
22
- :crop => source.attr('crop', nil, name),
23
- :font => source.attr('font', nil, name),
24
- :fontscale => source.attr('fontscale', nil, name),
25
- :background => source.attr('background', nil, name),
19
+ :width => source.attr('width'),
20
+ :height => source.attr('height'),
21
+ :transparent => source.attr('transparent'),
22
+ :crop => source.attr('crop'),
23
+ :font => source.attr('font'),
24
+ :fontscale => source.attr('fontscale'),
25
+ :background => source.attr('background'),
26
26
  }
27
27
  end
28
28
 
@@ -13,8 +13,8 @@ module Asciidoctor
13
13
  [:png, :pdf, :svg]
14
14
  end
15
15
 
16
- def collect_options(source, name)
17
- {:layout => source.attr('layout', nil, name)}
16
+ def collect_options(source)
17
+ {:layout => source.attr('layout')}
18
18
  end
19
19
 
20
20
  def convert(source, format, options)
@@ -11,6 +11,8 @@ module Asciidoctor
11
11
  module Diagram
12
12
  # @private
13
13
  class HttpConverter
14
+ DEFAULT_MAX_GET_SIZE = 1024
15
+
14
16
  include DiagramConverter
15
17
 
16
18
  def initialize(base_uri, type, converter)
@@ -23,10 +25,12 @@ module Asciidoctor
23
25
  @converter.supported_formats
24
26
  end
25
27
 
26
- def collect_options(source, name)
27
- {
28
- :block_name => name
29
- }
28
+ def collect_options(source)
29
+ options = {}
30
+
31
+ options[:max_get_size] = source.global_attr('max-get-size', DEFAULT_MAX_GET_SIZE).to_i
32
+
33
+ options
30
34
  end
31
35
 
32
36
  def convert(source, format, options)
@@ -47,30 +51,64 @@ module Asciidoctor
47
51
  encoded = Base64.urlsafe_encode64(compressed)
48
52
  data = '0A' + encoded
49
53
 
50
- path = uri.path
54
+ path = uri.path.dup
51
55
  path << '/' unless path.end_with? '/'
52
56
  path << format.to_s
53
- path << '/' << data
54
57
  when :kroki_io
55
58
  compressed = Zlib.deflate(code, Zlib::BEST_COMPRESSION)
56
59
  data = Base64.urlsafe_encode64(compressed)
57
60
 
58
- path = uri.path
61
+ path = uri.path.dup
59
62
  path << '/' unless path.end_with? '/'
60
- path << options[:block_name].to_s
63
+ path << source.diagram_type.to_s
61
64
  path << '/' << format.to_s
62
- path << '/' << data
63
65
  else
64
66
  raise "Unsupported server type: " + @type
65
67
  end
66
68
 
69
+ get_path = path.dup << '/' << data
70
+
71
+ if get_path.length > options[:max_get_size]
72
+ uri.path = path
73
+ get_uri(uri, code, 'text/plain; charset=utf-8')
74
+ else
75
+ uri.path = get_path
76
+ get_uri(uri)
77
+ end
78
+ end
79
+
80
+ private
81
+
82
+ def get_uri(uri, post_data = nil, post_content_type = nil, attempt = 1)
83
+ if attempt >= 10
84
+ raise "Too many redirects"
85
+ end
86
+
87
+ if post_data.nil?
88
+ request = Net::HTTP::Get.new(uri.path)
89
+ else
90
+ request = Net::HTTP::Post.new(uri.path)
91
+ request.body = post_data
92
+ request.set_content_type(post_content_type) if post_content_type
93
+ end
94
+
67
95
  Net::HTTP.start(uri.hostname, uri.port, :use_ssl => uri.scheme.downcase == 'https') do |http|
68
- response = http.request_get path
96
+ response = http.request(request)
69
97
  case response
70
- when Net::HTTPSuccess
71
- response.body
72
- else
73
- response.value
98
+ when Net::HTTPSuccess
99
+ response.body
100
+ when Net::HTTPRedirection then
101
+ location = response['Location']
102
+ new_uri = URI.parse(location)
103
+ if new_uri.relative?
104
+ resolved_uri = uri + location
105
+ else
106
+ resolved_uri = new_uri
107
+ end
108
+
109
+ get_uri(resolved_uri, post_data, post_content_type, attempt + 1)
110
+ else
111
+ response.value
74
112
  end
75
113
  end
76
114
  end
@@ -67,15 +67,15 @@ module Asciidoctor
67
67
  end
68
68
  end
69
69
 
70
- def render_diagram(type, accepts, code, attributes)
70
+ def render_diagram(type, accepts, source, attributes)
71
71
  converter = get_converter(type.downcase.to_sym)
72
72
  return [500, "Unsupported diagram type #{type}"] unless converter
73
73
 
74
74
  format = converter.supported_formats.find {|f| accepts.call(f)}
75
75
  return [500, "Could not determine supported output format"] unless format
76
76
 
77
- source = ServerSource.new(code, attributes)
78
- options = converter.collect_options(source, type.downcase)
77
+ source = ServerSource.new(type.downcase, source, attributes)
78
+ options = converter.collect_options(source)
79
79
  diagram = converter.convert(source, format, options)
80
80
 
81
81
  content_type to_mime_type(format)
@@ -86,12 +86,17 @@ module Asciidoctor
86
86
  class ServerSource
87
87
  include Asciidoctor::Diagram::DiagramSource
88
88
 
89
- def initialize(source, attributes)
89
+ def initialize(name, source, attributes)
90
+ @name = name
90
91
  @source = source
91
92
  @attributes = attributes
92
93
  end
93
94
 
94
- def attr(name, default_value = nil, inherit = nil)
95
+ def diagram_type
96
+ @name
97
+ end
98
+
99
+ def attr(name, default_value = nil, inherit = diagram_type)
95
100
  @attributes[name] || default_value
96
101
  end
97
102
 
@@ -99,7 +104,7 @@ module Asciidoctor
99
104
  nil
100
105
  end
101
106
 
102
- def code
107
+ def load_code
103
108
  @source
104
109
  end
105
110
 
@@ -9,14 +9,24 @@ module Asciidoctor
9
9
  include DiagramConverter
10
10
  include CliGenerator
11
11
 
12
+ EXTRA_PATH = []
13
+
14
+ if ::Asciidoctor::Diagram::Platform.os == :macosx
15
+ lilypond_app = ::Asciidoctor::Diagram::Which.which('LilyPond.app', :path => ['/Applications'])
16
+ if lilypond_app
17
+ EXTRA_PATH << File.join(lilypond_app, 'Contents/Resources/bin')
18
+ end
19
+ end
20
+
21
+ EXTRA_PATH.freeze
12
22
 
13
23
  def supported_formats
14
24
  [:png, :pdf]
15
25
  end
16
26
 
17
- def collect_options(source, name)
27
+ def collect_options(source)
18
28
  {
19
- :resolution => source.attr('resolution', nil, name)
29
+ :resolution => source.attr('resolution')
20
30
  }
21
31
  end
22
32
 
@@ -34,7 +44,7 @@ module Asciidoctor
34
44
 
35
45
  resolution = options[:resolution]
36
46
 
37
- generate_stdin(source.find_command('lilypond'), format.to_s, code) do |tool_path, output_path|
47
+ generate_stdin(source.find_command('lilypond', :path => EXTRA_PATH), format.to_s, code) do |tool_path, output_path|
38
48
  args = [tool_path, '-daux-files=#f', '-dbackend=eps', '-dno-gs-load-fonts', '-dinclude-eps-fonts', '-o', Platform.native_path(output_path), '-f', format.to_s]
39
49
 
40
50
  args << '-dsafe'
@@ -15,27 +15,35 @@ module Asciidoctor
15
15
  end
16
16
 
17
17
 
18
- def collect_options(source, name)
19
- bg_img = source.attr('background', nil, name)
18
+ def collect_options(source)
19
+ bg_img = source.attr('background')
20
20
  raise "background attribute is required" unless bg_img
21
21
 
22
- options = source.attr('options', '', name).split(',')
22
+ options = source.attr('options', '').split(',')
23
23
 
24
24
  {
25
25
  :bg_img => bg_img,
26
26
  :top_label => source.attr('top'),
27
27
  :bottom_label => source.attr('bottom'),
28
- :fill_color => source.attr('fillcolor', nil, name) || source.attr('fill-color', nil, name),
29
- :stroke_color => source.attr('strokecolor', nil, name) || source.attr('stroke-color', nil, name),
30
- :stroke_width => source.attr('strokewidth', nil, name) || source.attr('stroke-width', nil, name),
31
- :font => source.attr('font', 'Impact', name),
28
+ :fill_color => source.attr(['fillcolor', 'fill-color']),
29
+ :stroke_color => source.attr(['strokecolor', 'stroke-color']),
30
+ :stroke_width => source.attr(['strokewidth', 'stroke-width']),
31
+ :font => source.attr('font', 'Impact'),
32
32
  :noupcase => options.include?('noupcase'),
33
33
  }
34
34
  end
35
35
 
36
36
  def convert(source, format, options)
37
- convert = source.find_command('convert')
38
- identify = source.find_command('identify')
37
+ magick = source.find_command('magick', :raise_on_error => false)
38
+ if magick
39
+ convert = ->(*args) { Cli.run(magick, 'convert', *args) }
40
+ identify = ->(*args) { Cli.run(magick, 'identify', *args) }
41
+ else
42
+ convert_cmd = source.find_command('convert')
43
+ convert = ->(*args) { Cli.run(convert_cmd, *args) }
44
+ identify_cmd = source.find_command('identify')
45
+ identify = ->(*args) { Cli.run(identify_cmd, *args) }
46
+ end
39
47
 
40
48
  bg_img = options[:bg_img]
41
49
  raise "background attribute is required" unless bg_img
@@ -50,7 +58,7 @@ module Asciidoctor
50
58
  font = options[:font] || 'Impact'
51
59
  noupcase = options[:noupcase]
52
60
 
53
- dimensions = Cli.run(identify, '-format', '%w %h', bg_img)[:out].match(/(?<w>\d+) (?<h>\d+)/)
61
+ dimensions = identify.call('-format', '%w %h', bg_img)[:out].match(/(?<w>\d+) (?<h>\d+)/)
54
62
  bg_width = dimensions['w'].to_i
55
63
  bg_height = dimensions['h'].to_i
56
64
  label_width = bg_width
@@ -58,8 +66,7 @@ module Asciidoctor
58
66
 
59
67
  if top_label
60
68
  top_img = Tempfile.new(['meme', '.png'])
61
- Cli.run(
62
- convert,
69
+ convert.call(
63
70
  '-background', 'none',
64
71
  '-fill', fill_color,
65
72
  '-stroke', stroke_color,
@@ -76,8 +83,7 @@ module Asciidoctor
76
83
 
77
84
  if bottom_label
78
85
  bottom_img = Tempfile.new(['meme', '.png'])
79
- Cli.run(
80
- convert,
86
+ convert.call(
81
87
  '-background', 'none',
82
88
  '-fill', fill_color,
83
89
  '-stroke', stroke_color,
@@ -94,7 +100,7 @@ module Asciidoctor
94
100
 
95
101
  final_img = Tempfile.new(['meme', ".#{format.to_s}"])
96
102
 
97
- args = [convert, bg_img]
103
+ args = [bg_img]
98
104
  if top_img
99
105
  args << top_img.path << '-geometry' << '+0+0' << '-composite'
100
106
  end
@@ -105,7 +111,7 @@ module Asciidoctor
105
111
 
106
112
  args << final_img.path
107
113
 
108
- Cli.run(*args)
114
+ convert.call(*args)
109
115
 
110
116
  File.binread(final_img)
111
117
  end