asciidoctor-diagram 1.4.0 → 1.5.0

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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +15 -0
  3. data/README.adoc +252 -95
  4. data/README_zh-CN.adoc +333 -0
  5. data/images/asciidoctor-diagram-classes.png +0 -0
  6. data/images/asciidoctor-diagram-process.png +0 -0
  7. data/lib/{asciidoctor-diagram-java-1.3.8.jar → asciidoctor-diagram-java-1.3.10.jar} +0 -0
  8. data/lib/asciidoctor-diagram.rb +9 -9
  9. data/lib/asciidoctor-diagram/blockdiag.rb +1 -2
  10. data/lib/asciidoctor-diagram/blockdiag/extension.rb +27 -12
  11. data/lib/asciidoctor-diagram/ditaa.rb +1 -2
  12. data/lib/asciidoctor-diagram/ditaa/extension.rb +33 -48
  13. data/lib/asciidoctor-diagram/extensions.rb +85 -18
  14. data/lib/asciidoctor-diagram/graphviz.rb +1 -2
  15. data/lib/asciidoctor-diagram/graphviz/extension.rb +14 -4
  16. data/lib/asciidoctor-diagram/meme.rb +1 -2
  17. data/lib/asciidoctor-diagram/meme/extension.rb +82 -79
  18. data/lib/asciidoctor-diagram/mermaid.rb +1 -2
  19. data/lib/asciidoctor-diagram/mermaid/extension.rb +33 -25
  20. data/lib/asciidoctor-diagram/plantuml.rb +1 -2
  21. data/lib/asciidoctor-diagram/plantuml/extension.rb +33 -22
  22. data/lib/asciidoctor-diagram/salt.rb +1 -2
  23. data/lib/asciidoctor-diagram/shaape.rb +1 -2
  24. data/lib/asciidoctor-diagram/shaape/extension.rb +10 -5
  25. data/lib/asciidoctor-diagram/util/cli_generator.rb +7 -5
  26. data/lib/asciidoctor-diagram/util/java.rb +1 -1
  27. data/lib/asciidoctor-diagram/util/platform.rb +12 -1
  28. data/lib/asciidoctor-diagram/util/which.rb +16 -7
  29. data/lib/asciidoctor-diagram/version.rb +1 -1
  30. data/lib/asciidoctor-diagram/wavedrom.rb +1 -2
  31. data/lib/asciidoctor-diagram/wavedrom/extension.rb +24 -20
  32. data/lib/plantuml.jar +0 -0
  33. data/spec/blockdiag_spec.rb +8 -8
  34. data/spec/ditaa_spec.rb +7 -7
  35. data/spec/graphviz_spec.rb +7 -7
  36. data/spec/meme_spec.rb +2 -2
  37. data/spec/mermaid_spec.rb +11 -11
  38. data/spec/plantuml_spec.rb +156 -34
  39. data/spec/shaape_spec.rb +8 -8
  40. data/spec/test_helper.rb +24 -5
  41. data/spec/wavedrom_spec.rb +11 -11
  42. metadata +6 -3
@@ -1,5 +1,4 @@
1
- require 'asciidoctor/extensions'
2
- require_relative 'version'
1
+ require_relative 'extensions'
3
2
 
4
3
  Asciidoctor::Extensions.register do
5
4
  require_relative 'meme/extension'
@@ -12,87 +12,90 @@ module Asciidoctor
12
12
 
13
13
  def self.included(mod)
14
14
  [:png, :gif].each do |format|
15
- mod.register_format(format, :image) do |c, p|
16
- convert = which(p, 'convert')
17
- identify = which(p, 'identify')
18
-
19
- attrs = c.attributes
20
- bg_img = attrs["background"]
21
- raise "background attribute is required" unless bg_img
22
-
23
- bg_img = p.normalize_system_path(bg_img, p.document.attr('imagesdir'))
24
-
25
- top_label = attrs["top"]
26
- bottom_label = attrs["bottom"]
27
- fill_color = attrs.fetch('fillColor', 'white')
28
- stroke_color = attrs.fetch('strokeColor', 'black')
29
- stroke_width = attrs.fetch('strokeWidth', '2')
30
- font = attrs.fetch('font', 'Impact')
31
- options = attrs.fetch('options', '').split(',')
32
- noupcase = options.include?('noupcase')
33
-
34
- dimensions = CliGenerator.run_cli(identify, '-format', '%w %h', bg_img).match /(?<w>\d+) (?<h>\d+)/
35
- bg_width = dimensions['w'].to_i
36
- bg_height = dimensions['h'].to_i
37
- label_width = bg_width
38
- label_height = bg_height / 5
39
-
40
- if top_label
41
- top_img = Tempfile.new(['meme', '.png'])
42
- CliGenerator.run_cli(
43
- convert,
44
- '-background', 'none',
45
- '-fill', fill_color,
46
- '-stroke', stroke_color,
47
- '-strokewidth', stroke_width,
48
- '-font', font,
49
- '-size', "#{label_width}x#{label_height}",
50
- '-gravity', 'north',
51
- "label:#{prepare_label(top_label, noupcase)}",
52
- top_img.path
53
- )
54
- else
55
- top_img = nil
56
- end
57
-
58
- if bottom_label
59
- bottom_img = Tempfile.new(['meme', '.png'])
60
- CliGenerator.run_cli(
61
- convert,
62
- '-background', 'none',
63
- '-fill', fill_color,
64
- '-stroke', stroke_color,
65
- '-strokewidth', stroke_width,
66
- '-font', font,
67
- '-size', "#{label_width}x#{label_height}",
68
- '-gravity', 'south',
69
- "label:#{prepare_label(bottom_label, noupcase)}",
70
- bottom_img.path
71
- )
72
- else
73
- bottom_img = nil
74
- end
75
-
76
- final_img = Tempfile.new(['meme', ".#{format.to_s}"])
77
-
78
- args = [convert, bg_img]
79
- if top_img
80
- args << top_img.path << '-geometry'<< '+0+0' << '-composite'
81
- end
82
-
83
- if bottom_img
84
- args << bottom_img.path << '-geometry'<< "+0+#{bg_height - label_height}" << '-composite'
85
- end
86
-
87
- args << final_img.path
88
-
89
- CliGenerator.run_cli(*args)
90
-
91
- File.binread(final_img)
15
+ mod.register_format(format, :image) do |parent, source|
16
+ meme(parent, source, format)
92
17
  end
93
18
  end
94
19
  end
95
20
 
21
+ def meme(p, c, format)
22
+ convert = which(p, 'convert')
23
+ identify = which(p, 'identify')
24
+
25
+ bg_img = c.attr('background')
26
+ raise "background attribute is required" unless bg_img
27
+
28
+ bg_img = p.normalize_system_path(bg_img, p.attr('imagesdir'))
29
+
30
+ top_label = c.attr('top')
31
+ bottom_label = c.attr('bottom')
32
+ fill_color = c.attr('fillColor', 'white')
33
+ stroke_color = c.attr('strokeColor', 'black')
34
+ stroke_width = c.attr('strokeWidth', '2')
35
+ font = c.attr('font', 'Impact')
36
+ options = c.attr('options', '').split(',')
37
+ noupcase = options.include?('noupcase')
38
+
39
+ dimensions = CliGenerator.run_cli(identify, '-format', '%w %h', bg_img).match /(?<w>\d+) (?<h>\d+)/
40
+ bg_width = dimensions['w'].to_i
41
+ bg_height = dimensions['h'].to_i
42
+ label_width = bg_width
43
+ label_height = bg_height / 5
44
+
45
+ if top_label
46
+ top_img = Tempfile.new(['meme', '.png'])
47
+ CliGenerator.run_cli(
48
+ convert,
49
+ '-background', 'none',
50
+ '-fill', fill_color,
51
+ '-stroke', stroke_color,
52
+ '-strokewidth', stroke_width,
53
+ '-font', font,
54
+ '-size', "#{label_width}x#{label_height}",
55
+ '-gravity', 'north',
56
+ "label:#{prepare_label(top_label, noupcase)}",
57
+ top_img.path
58
+ )
59
+ else
60
+ top_img = nil
61
+ end
62
+
63
+ if bottom_label
64
+ bottom_img = Tempfile.new(['meme', '.png'])
65
+ CliGenerator.run_cli(
66
+ convert,
67
+ '-background', 'none',
68
+ '-fill', fill_color,
69
+ '-stroke', stroke_color,
70
+ '-strokewidth', stroke_width,
71
+ '-font', font,
72
+ '-size', "#{label_width}x#{label_height}",
73
+ '-gravity', 'south',
74
+ "label:#{prepare_label(bottom_label, noupcase)}",
75
+ bottom_img.path
76
+ )
77
+ else
78
+ bottom_img = nil
79
+ end
80
+
81
+ final_img = Tempfile.new(['meme', ".#{format.to_s}"])
82
+
83
+ args = [convert, bg_img]
84
+ if top_img
85
+ args << top_img.path << '-geometry'<< '+0+0' << '-composite'
86
+ end
87
+
88
+ if bottom_img
89
+ args << bottom_img.path << '-geometry'<< "+0+#{bg_height - label_height}" << '-composite'
90
+ end
91
+
92
+ args << final_img.path
93
+
94
+ CliGenerator.run_cli(*args)
95
+
96
+ File.binread(final_img)
97
+ end
98
+
96
99
  private
97
100
  def prepare_label(label, noupcase)
98
101
  label = label.upcase unless noupcase
@@ -109,8 +112,8 @@ module Asciidoctor
109
112
  def create_source(parent, target, attributes)
110
113
  attributes = attributes.dup
111
114
  attributes['background'] = target
112
- ::Asciidoctor::Diagram::Extensions::FileSource.new(nil, attributes)
115
+ ::Asciidoctor::Diagram::Extensions::FileSource.new(parent, nil, attributes)
113
116
  end
114
117
  end
115
118
  end
116
- end
119
+ end
@@ -1,5 +1,4 @@
1
- require 'asciidoctor/extensions'
2
- require_relative 'version'
1
+ require_relative 'extensions'
3
2
 
4
3
  Asciidoctor::Extensions.register do
5
4
  require_relative 'mermaid/extension'
@@ -1,5 +1,6 @@
1
1
  require_relative '../extensions'
2
2
  require_relative '../util/cli_generator'
3
+ require_relative '../util/platform'
3
4
  require_relative '../util/which'
4
5
 
5
6
  module Asciidoctor
@@ -10,38 +11,45 @@ module Asciidoctor
10
11
 
11
12
  def self.included(mod)
12
13
  [:png, :svg].each do |f|
13
- mod.register_format(f, :image) do |c, p|
14
- mermaid = which(p, 'mermaid')
15
-
16
- seq_config = c.attributes['sequenceConfig'] || p.attr('sequenceConfig')
17
- if seq_config
18
- seq_config = p.normalize_system_path(seq_config, p.document.base_dir)
19
- end
14
+ mod.register_format(f, :image) do |parent, source|
15
+ mermaid(parent, source, f)
16
+ end
17
+ end
18
+ end
20
19
 
21
- width = c.attributes['width']
20
+ def mermaid(parent, source, format)
21
+ mermaid = which(parent, 'mermaid')
22
+ @is_mermaid_v6 ||= `#{mermaid} --version`.split('.')[0].to_i >= 6
23
+ # Mermaid >= 6.0.0 requires PhantomJS 2.1; older version required 1.9
24
+ phantomjs = which(parent, 'phantomjs', :alt_attrs => [@is_mermaid_v6 ? 'phantomjs_2' : 'phantomjs_19'])
22
25
 
23
- CliGenerator.generate_file(mermaid, f.to_s, c.to_s) do |tool_path, input_path, output_path|
24
- output_dir = File.dirname(output_path)
25
- output_file = File.expand_path(File.basename(input_path) + ".#{f.to_s}", output_dir)
26
+ seq_config = source.attr('sequenceConfig', nil, true)
27
+ if seq_config
28
+ seq_config = parent.normalize_system_path(seq_config, source.base_dir)
29
+ end
26
30
 
27
- args = [tool_path, "--#{f.to_s}", '-o', output_dir]
31
+ width = source.attr('width')
28
32
 
29
- if seq_config
30
- args << '--sequenceConfig' << seq_config
31
- end
33
+ CliGenerator.generate_file(mermaid, 'mmd', format.to_s, source.to_s) do |tool_path, input_path, output_path|
34
+ output_dir = File.dirname(output_path)
35
+ output_file = File.expand_path(File.basename(input_path) + ".#{format.to_s}", output_dir)
32
36
 
33
- if width
34
- args << '--width' << width
35
- end
37
+ args = [tool_path, '--phantomPath', Platform.native_path(phantomjs), "--#{format.to_s}", '-o', Platform.native_path(output_dir)]
36
38
 
37
- args << input_path
39
+ if seq_config
40
+ args << '--sequenceConfig' << Platform.native_path(seq_config)
41
+ end
38
42
 
39
- {
40
- :args => args,
41
- :out_file => output_file
42
- }
43
- end
43
+ if width
44
+ args << '--width' << width
44
45
  end
46
+
47
+ args << Platform.native_path(input_path)
48
+
49
+ {
50
+ :args => args,
51
+ :out_file => output_file
52
+ }
45
53
  end
46
54
  end
47
55
  end
@@ -54,4 +62,4 @@ module Asciidoctor
54
62
  include Mermaid
55
63
  end
56
64
  end
57
- end
65
+ end
@@ -1,5 +1,4 @@
1
- require 'asciidoctor/extensions'
2
- require_relative 'version'
1
+ require_relative 'extensions'
3
2
 
4
3
  Asciidoctor::Extensions.register do
5
4
  require_relative 'plantuml/extension'
@@ -14,21 +14,21 @@ module Asciidoctor
14
14
  end
15
15
  Java.classpath.concat JARS
16
16
 
17
- def plantuml(parent, code, tag, mime_type)
17
+ def plantuml(parent, source, tag, mime_type)
18
18
  Java.load
19
19
 
20
- code = preprocess_code(parent, code, tag)
20
+ code = preprocess_code(parent, source, tag)
21
21
 
22
22
  headers = {
23
23
  'Accept' => mime_type
24
24
  }
25
25
 
26
- config_file = parent.document.attributes['plantumlconfig']
26
+ config_file = parent.attr('plantumlconfig', nil, true)
27
27
  if config_file
28
- headers['X-PlantUML-Config'] = File.expand_path(config_file, parent.document.attributes['docdir'])
28
+ headers['X-PlantUML-Config'] = File.expand_path(config_file, parent.attr('docdir', nil, true))
29
29
  end
30
30
 
31
- dot = which(parent, 'dot', :attr_names => ['dot', 'graphvizdot'], :raise_on_error => false)
31
+ dot = which(parent, 'dot', :alt_attrs => ['graphvizdot'], :raise_on_error => false)
32
32
  if dot
33
33
  headers['X-Graphviz'] = dot
34
34
  end
@@ -46,34 +46,45 @@ module Asciidoctor
46
46
  response[:body]
47
47
  end
48
48
 
49
- def preprocess_code(parent, code, tag)
49
+ def preprocess_code(parent, source, tag)
50
+ code = source.to_s
51
+ base_dir = source.base_dir
52
+
50
53
  code = "@start#{tag}\n#{code}\n@end#{tag}" unless code.index "@start#{tag}"
51
54
 
52
55
  code.gsub!(/(?<=<img:)[^>]+(?=>)/) do |match|
53
- if match =~ URI.regexp
54
- uri = URI.parse(match)
55
- if uri.scheme == 'file'
56
- parent.normalize_system_path(uri.path, parent.attr('imagesdir'))
57
- else
58
- parent.normalize_web_path(match)
59
- end
60
- else
61
- parent.normalize_system_path(match, parent.attr('imagesdir'))
62
- end
56
+ resolve_path(match, parent, parent.attr('imagesdir'))
57
+ end
58
+
59
+ code.gsub!(/(?<=!include )[^!\n\r]+/) do |match|
60
+ resolve_path(match, parent, base_dir)
63
61
  end
64
62
 
65
63
  code
66
64
  end
67
65
 
66
+ def resolve_path(path, parent, base_dir)
67
+ if path =~ URI.regexp
68
+ uri = URI.parse(path)
69
+ if uri.scheme == 'file'
70
+ parent.normalize_system_path(uri.path, base_dir)
71
+ else
72
+ parent.normalize_web_path(path)
73
+ end
74
+ else
75
+ parent.normalize_system_path(path, base_dir)
76
+ end
77
+ end
78
+
68
79
  def self.included(mod)
69
- mod.register_format(:png, :image) do |c, p|
70
- plantuml(p, c.to_s, mod.tag, 'image/png')
80
+ mod.register_format(:png, :image) do |parent, source|
81
+ plantuml(parent, source, mod.tag, 'image/png')
71
82
  end
72
- mod.register_format(:svg, :image) do |c, p|
73
- plantuml(p, c.to_s, mod.tag, 'image/svg+xml')
83
+ mod.register_format(:svg, :image) do |parent, source|
84
+ plantuml(parent, source, mod.tag, 'image/svg+xml')
74
85
  end
75
- mod.register_format(:txt, :literal) do |c, p|
76
- plantuml(p, c.to_s, mod.tag, 'text/plain;charset=utf-8')
86
+ mod.register_format(:txt, :literal) do |parent, source|
87
+ plantuml(parent, source, mod.tag, 'text/plain;charset=utf-8')
77
88
  end
78
89
  end
79
90
  end
@@ -1,5 +1,4 @@
1
- require 'asciidoctor/extensions'
2
- require_relative 'version'
1
+ require_relative 'extensions'
3
2
 
4
3
  Asciidoctor::Extensions.register do
5
4
  require_relative 'plantuml/extension'
@@ -1,5 +1,4 @@
1
- require 'asciidoctor/extensions'
2
- require_relative 'version'
1
+ require_relative 'extensions'
3
2
 
4
3
  Asciidoctor::Extensions.register do
5
4
  require_relative 'shaape/extension'
@@ -1,5 +1,6 @@
1
1
  require_relative '../extensions'
2
2
  require_relative '../util/cli_generator'
3
+ require_relative '../util/platform'
3
4
  require_relative '../util/which'
4
5
 
5
6
  module Asciidoctor
@@ -10,13 +11,17 @@ module Asciidoctor
10
11
 
11
12
  def self.included(mod)
12
13
  [:png, :svg].each do |f|
13
- mod.register_format(f, :image) do |c, p|
14
- CliGenerator.generate_stdin(which(p, 'shaape'), f.to_s, c.to_s) do |tool_path, output_path|
15
- [tool_path, '-o', output_path, '-t', f.to_s, '-']
16
- end
14
+ mod.register_format(f, :image) do |parent, source|
15
+ shaape(parent, source, f)
17
16
  end
18
17
  end
19
18
  end
19
+
20
+ def shaape(parent, source, format)
21
+ CliGenerator.generate_stdin(which(parent, 'shaape'), format.to_s, source.to_s) do |tool_path, output_path|
22
+ [tool_path, '-o', Platform.native_path(output_path), '-t', format.to_s, '-']
23
+ end
24
+ end
20
25
  end
21
26
 
22
27
  class ShaapeBlockProcessor < Extensions::DiagramBlockProcessor
@@ -27,4 +32,4 @@ module Asciidoctor
27
32
  include Shaape
28
33
  end
29
34
  end
30
- end
35
+ end
@@ -20,14 +20,14 @@ module Asciidoctor
20
20
  end
21
21
  end
22
22
 
23
- def self.generate_file(tool, format, code)
23
+ def self.generate_file(tool, input_ext, output_ext, code)
24
24
  tool_name = File.basename(tool)
25
25
 
26
- source_file = Tempfile.new([tool_name, ".#{format}"])
26
+ source_file = Tempfile.new([tool_name, ".#{input_ext}"])
27
27
  begin
28
28
  File.write(source_file.path, code)
29
29
 
30
- target_file = Tempfile.new([tool_name, ".#{format}"])
30
+ target_file = Tempfile.new([tool_name, ".#{output_ext}"])
31
31
  begin
32
32
  target_file.close
33
33
 
@@ -54,7 +54,9 @@ module Asciidoctor
54
54
  raise "Block passed to generate_file should return an Array or a Hash"
55
55
  end
56
56
 
57
- run_cli(*args, open3_opts)
57
+ output = run_cli(*args, open3_opts)
58
+
59
+ raise "#{args[0]} failed: #{output}" unless File.exist?(out_file || target_file.path)
58
60
 
59
61
  if out_file
60
62
  File.rename(out_file, target_file.path)
@@ -70,7 +72,7 @@ module Asciidoctor
70
72
  raise "#{File.basename(args[0])} failed: #{stdout.empty? ? stderr : stdout}"
71
73
  end
72
74
 
73
- stdout
75
+ stdout.empty? ? stderr : stdout
74
76
  end
75
77
  end
76
78
  end