asciidoctor-diagram 1.3.0.preview.1 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +9 -1
- data/README.adoc +12 -0
- data/Rakefile +8 -7
- data/lib/asciidoctor-diagram/ditaa/extension.rb +68 -16
- data/lib/asciidoctor-diagram/extensions.rb +75 -24
- data/lib/asciidoctor-diagram/plantuml/extension.rb +43 -33
- data/lib/asciidoctor-diagram/salt.rb +9 -0
- data/lib/asciidoctor-diagram/util/cli_generator.rb +1 -1
- data/lib/asciidoctor-diagram/util/java.rb +77 -1
- data/lib/asciidoctor-diagram/util/java_jruby.rb +12 -19
- data/lib/asciidoctor-diagram/util/java_socket.rb +107 -0
- data/lib/asciidoctor-diagram/version.rb +1 -1
- data/lib/asciidoctor-diagram-java-1.3.4.jar +0 -0
- data/lib/asciidoctor-diagram.rb +1 -0
- data/lib/ditaamini-0.10.jar +0 -0
- data/lib/plantuml.jar +0 -0
- data/spec/ditaa_spec.rb +68 -0
- data/spec/plantuml_spec.rb +164 -1
- data/spec/test_helper.rb +2 -6
- metadata +18 -30
- data/lib/asciidoctor-diagram/util/java_rjb.rb +0 -91
- data/lib/ditaamini0_9.jar +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a2f204cc0c29acb26136512bd4a8d50b94eb19d
|
4
|
+
data.tar.gz: 0115d195b3546f4ab1a1967a45891769b4d28fb5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8bedbbef25acb0ea9d0617b67521f8b92f57a66a730f58b35090e221936cc3ee3a1ff76af260f78f7ccec6e88467188744b048e9997701c46d667e37f2f142f6
|
7
|
+
data.tar.gz: fc0668cb0299126c80f392efccba75c8eda819a835e69b3c27c99fd57c50d1d4b312271bba3cbae7cbebf34a23dbd56a7adfd470a7a48fe8079fb3b4ae210345
|
data/CHANGELOG.adoc
CHANGED
@@ -8,7 +8,15 @@ Enhancements::
|
|
8
8
|
* Add support for Actdiag diagrams (requires Actdiag to be installed separately)
|
9
9
|
* Add support for Seqdiag diagrams (requires Seqdiag to be installed separately)
|
10
10
|
* Add support for Nwdiag diagrams (requires Nwdiag to be installed separately)
|
11
|
-
* Updated PlantUML to revision
|
11
|
+
* Updated PlantUML to revision 8021 (14/03/2015)
|
12
|
+
* Remove dependency on RJB to simplify installation
|
13
|
+
* Add diagram scaling support using the scale attribute
|
14
|
+
* Add Ditaa command line option support using the options attribute
|
15
|
+
|
16
|
+
Bug Fixes::
|
17
|
+
|
18
|
+
* Issue #49: Resolve issue that made Java 6 installation prompt appear on Mac OS X
|
19
|
+
* Issue #51: Resolved issue where PNG files generated by Graphviz were not processed correctly on Windows
|
12
20
|
|
13
21
|
== 1.2.0
|
14
22
|
|
data/README.adoc
CHANGED
@@ -14,6 +14,12 @@ The extension takes care of running the diagram processor to generate the images
|
|
14
14
|
|
15
15
|
This gem was inspired by the https://code.google.com/p/asciidoc-plantuml/[AsciiDoc PlantUML filter] for AsciiDoc Python.
|
16
16
|
|
17
|
+
== Status
|
18
|
+
|
19
|
+
image:https://travis-ci.org/asciidoctor/asciidoctor-diagram.svg?branch=master["Linux Build Status", link="https://travis-ci.org/asciidoctor/asciidoctor-diagram"]
|
20
|
+
|
21
|
+
image:https://ci.appveyor.com/api/projects/status/4r4gkk5gy3igs6nh/branch/master?svg=true["Windows Build Status", link="https://ci.appveyor.com/project/asciidoctor/asciidoctor-diagram"]
|
22
|
+
|
17
23
|
== Installation
|
18
24
|
|
19
25
|
Add this line to your application's Gemfile:
|
@@ -91,6 +97,12 @@ The diagram blocks support the following attributes:
|
|
91
97
|
. `target` (or 2nd position): the basename of the file to generate. If not specified an auto-generated name will be used.
|
92
98
|
. `format` (or 3rd position): the output format. PlantUML blocks support `png`, `svg` and `txt`. Graphviz, Shaape and BlockDiag support `png` and `svg`. Ditaa only supports `png`.
|
93
99
|
|
100
|
+
Once you have all of this in place and your original AsciiDoc file contains a diagram block, it's time to build it into an HTML file with Asciidoctor Diagram magic!
|
101
|
+
When executing Asciidoctor, you must reference the Adciidoctor Diagram library, otherwise your diagam blocks won't be recognized as such. When executing Asciidoctor from the command line, do it using the -r parameter to reference this external library:
|
102
|
+
|
103
|
+
$ asciidoctor -r asciidoctor-diagram doc.adoc
|
104
|
+
|
105
|
+
|
94
106
|
== Contributing
|
95
107
|
|
96
108
|
. Fork it
|
data/Rakefile
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
require 'rubygems/package_task'
|
2
2
|
require 'rspec/core/rake_task'
|
3
3
|
|
4
|
-
RSpec::Core::RakeTask.new(:test)
|
4
|
+
test = RSpec::Core::RakeTask.new(:test)
|
5
|
+
|
6
|
+
if ENV['APPVEYOR']
|
7
|
+
# Exclude diagram types that require external libraries that are difficult to build on Windows.
|
8
|
+
test.exclude_pattern = 'spec/**/{blockdiag,shaape}_spec.rb'
|
9
|
+
end
|
5
10
|
|
6
11
|
task :default => :test
|
7
12
|
|
8
|
-
|
9
|
-
|
10
|
-
Gem::Specification.reset
|
11
|
-
spec = Gem::Specification.load('asciidoctor-diagram.gemspec')
|
12
|
-
Gem::PackageTask.new(spec) { |task| }
|
13
|
-
end
|
13
|
+
spec = Gem::Specification.load('asciidoctor-diagram.gemspec')
|
14
|
+
Gem::PackageTask.new(spec) { |task| }
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
1
3
|
require_relative '../extensions'
|
2
4
|
require_relative '../util/java'
|
3
5
|
|
@@ -5,31 +7,81 @@ module Asciidoctor
|
|
5
7
|
module Diagram
|
6
8
|
# @private
|
7
9
|
module Ditaa
|
8
|
-
|
9
|
-
|
10
|
+
JARS = ['ditaamini-0.10.jar'].map do |jar|
|
11
|
+
File.expand_path File.join('../..', jar), File.dirname(__FILE__)
|
12
|
+
end
|
13
|
+
Java.classpath.concat JARS
|
10
14
|
|
11
|
-
def ditaa(code)
|
15
|
+
def ditaa(code, source)
|
12
16
|
Java.load
|
13
17
|
|
14
|
-
|
18
|
+
response = Java.send_request(
|
19
|
+
:url => '/ditaa',
|
20
|
+
:body => code,
|
21
|
+
:headers => {
|
22
|
+
'X-Options' => source.options
|
23
|
+
}
|
24
|
+
)
|
25
|
+
|
26
|
+
unless response[:code] == 200
|
27
|
+
raise "Ditaa image generation failed: #{response[:reason]} #{response[:body]}"
|
28
|
+
end
|
29
|
+
|
30
|
+
response[:body]
|
31
|
+
end
|
15
32
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
bos.close
|
33
|
+
def self.included(mod)
|
34
|
+
mod.register_format(:png, :image) do |c, _, source|
|
35
|
+
ditaa(c.to_s, source)
|
36
|
+
end
|
37
|
+
end
|
22
38
|
|
23
|
-
|
39
|
+
def create_source(parent, reader, attributes)
|
40
|
+
source = super(parent, reader, attributes)
|
41
|
+
source.extend DitaaSource
|
24
42
|
|
25
|
-
|
43
|
+
source.init_ditaa_options(parent, attributes)
|
26
44
|
|
27
|
-
|
45
|
+
source
|
28
46
|
end
|
29
47
|
|
30
|
-
|
31
|
-
|
32
|
-
|
48
|
+
module DitaaSource
|
49
|
+
attr_reader :options
|
50
|
+
|
51
|
+
OPTIONS = {
|
52
|
+
'scale' => lambda { |o, v| o << '--scale' << v if v },
|
53
|
+
'tabs' => lambda { |o, v| o << '--tabs' << v if v },
|
54
|
+
'background' => lambda { |o, v| o << '--background' << v if v },
|
55
|
+
'antialias' => lambda { |o, v| o << '--no-antialias' if v == 'false' },
|
56
|
+
'separation' => lambda { |o, v| o << '--no-separation' if v == 'false'},
|
57
|
+
'round-corners' => lambda { |o, v| o << '--round-corners' if v == 'true'},
|
58
|
+
'shadows' => lambda { |o, v| o << '--no-shadows' if v == 'false'},
|
59
|
+
'debug' => lambda { |o, v| o << '--debug' if v == 'true'},
|
60
|
+
'fixed-slope' => lambda { |o, v| o << '--fixed-slope' if v == 'true'},
|
61
|
+
'transparent' => lambda { |o, v| o << '--transparent' if v == 'true'}
|
62
|
+
}
|
63
|
+
|
64
|
+
def init_ditaa_options(parent, attributes)
|
65
|
+
global_attributes = parent.document.attributes
|
66
|
+
|
67
|
+
options = []
|
68
|
+
|
69
|
+
OPTIONS.keys.each do |key|
|
70
|
+
value = attributes.delete(key) || global_attributes["ditaa-option-#{key}"]
|
71
|
+
OPTIONS[key].call(options, value)
|
72
|
+
end
|
73
|
+
|
74
|
+
@options = options.join(' ')
|
75
|
+
end
|
76
|
+
|
77
|
+
def should_process?(image_file, image_metadata)
|
78
|
+
super(image_file, image_metadata) || image_metadata['options'] != @options
|
79
|
+
end
|
80
|
+
|
81
|
+
def create_image_metadata
|
82
|
+
metadata = super
|
83
|
+
metadata['options'] = @options
|
84
|
+
metadata
|
33
85
|
end
|
34
86
|
end
|
35
87
|
end
|
@@ -27,6 +27,8 @@ module Asciidoctor
|
|
27
27
|
# File.read(source.to_s)
|
28
28
|
# end
|
29
29
|
def register_format(format, type, &block)
|
30
|
+
raise "Unsupported output type: #{type}" unless type == :image || type == :literal
|
31
|
+
|
30
32
|
unless @default_format
|
31
33
|
@default_format = format
|
32
34
|
end
|
@@ -35,7 +37,7 @@ module Asciidoctor
|
|
35
37
|
:type => type,
|
36
38
|
:generator => block
|
37
39
|
}
|
38
|
-
|
40
|
+
end
|
39
41
|
|
40
42
|
# Returns the registered formats
|
41
43
|
#
|
@@ -82,9 +84,9 @@ module Asciidoctor
|
|
82
84
|
# @param attributes [Hash] the attributes of the block or block macro
|
83
85
|
# @return [Asciidoctor::AbstractBlock] a new block that replaces the original block or block macro
|
84
86
|
def process(parent, reader_or_target, attributes)
|
85
|
-
source = create_source(parent, reader_or_target, attributes)
|
87
|
+
source = create_source(parent, reader_or_target, attributes.dup)
|
86
88
|
|
87
|
-
format = attributes.delete('format') || self.class.default_format
|
89
|
+
format = source.attributes.delete('format') || self.class.default_format
|
88
90
|
format = format.to_sym if format.respond_to?(:to_sym)
|
89
91
|
|
90
92
|
raise "Format undefined" unless format
|
@@ -93,13 +95,19 @@ module Asciidoctor
|
|
93
95
|
|
94
96
|
raise "#{self.class.name} does not support output format #{format}" unless generator_info
|
95
97
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
98
|
+
begin
|
99
|
+
case generator_info[:type]
|
100
|
+
when :literal
|
101
|
+
create_literal_block(parent, source, generator_info)
|
102
|
+
else
|
103
|
+
create_image_block(parent, source, format, generator_info)
|
104
|
+
end
|
105
|
+
rescue => e
|
106
|
+
text = "Failed to generate image: #{e.message}"
|
107
|
+
warn %(asciidoctor-diagram: ERROR: #{text})
|
108
|
+
text << "\n"
|
109
|
+
text << source.code
|
110
|
+
Asciidoctor::Block.new parent, :listing, :source => text, :attributes => attributes
|
103
111
|
end
|
104
112
|
end
|
105
113
|
|
@@ -121,10 +129,9 @@ module Asciidoctor
|
|
121
129
|
end
|
122
130
|
|
123
131
|
private
|
124
|
-
def create_image_block(parent, source,
|
132
|
+
def create_image_block(parent, source, format, generator_info)
|
125
133
|
image_name = "#{source.image_name}.#{format}"
|
126
|
-
|
127
|
-
image_dir = parent.normalize_system_path parent.document.attr 'imagesdir', outdir
|
134
|
+
image_dir = image_output_dir(parent)
|
128
135
|
image_file = parent.normalize_system_path image_name, image_dir
|
129
136
|
metadata_file = parent.normalize_system_path "#{image_name}.cache", image_dir
|
130
137
|
|
@@ -134,10 +141,12 @@ module Asciidoctor
|
|
134
141
|
metadata = {}
|
135
142
|
end
|
136
143
|
|
144
|
+
image_attributes = source.attributes
|
145
|
+
|
137
146
|
if !File.exists?(image_file) || source.should_process?(image_file, metadata)
|
138
147
|
params = IMAGE_PARAMS[format]
|
139
148
|
|
140
|
-
result = instance_exec(source, parent, &generator_info[:generator])
|
149
|
+
result = instance_exec(source, parent, source, &generator_info[:generator])
|
141
150
|
|
142
151
|
result.force_encoding(params[:encoding])
|
143
152
|
|
@@ -149,16 +158,29 @@ module Asciidoctor
|
|
149
158
|
File.open(metadata_file, 'w') { |f| JSON.dump(metadata, f) }
|
150
159
|
end
|
151
160
|
|
152
|
-
image_attributes = attributes.dup
|
153
161
|
image_attributes['target'] = image_name
|
162
|
+
|
163
|
+
scale = image_attributes['scale']
|
164
|
+
if scalematch = /(\d+(?:\.\d+))/.match(scale)
|
165
|
+
scale_factor = scalematch[1].to_f
|
166
|
+
else
|
167
|
+
scale_factor = 1.0
|
168
|
+
end
|
169
|
+
|
154
170
|
if /html/i =~ parent.document.attributes['backend']
|
155
|
-
image_attributes
|
156
|
-
|
171
|
+
image_attributes.delete('scale')
|
172
|
+
if metadata['width'] && !image_attributes['width']
|
173
|
+
image_attributes['width'] = (metadata['width'] * scale_factor).to_i
|
174
|
+
end
|
175
|
+
if metadata['height'] && !image_attributes['height']
|
176
|
+
image_attributes['height'] = (metadata['height'] * scale_factor).to_i
|
177
|
+
end
|
157
178
|
end
|
158
|
-
|
179
|
+
|
180
|
+
image_attributes['alt'] ||= if title_text = image_attributes['title']
|
159
181
|
title_text
|
160
|
-
elsif target =
|
161
|
-
(File.basename
|
182
|
+
elsif target = image_attributes['target']
|
183
|
+
(File.basename(target, File.extname(target)) || '').tr '_-', ' '
|
162
184
|
else
|
163
185
|
'Diagram'
|
164
186
|
end
|
@@ -166,8 +188,33 @@ module Asciidoctor
|
|
166
188
|
Asciidoctor::Block.new parent, :image, :content_model => :empty, :attributes => image_attributes
|
167
189
|
end
|
168
190
|
|
169
|
-
def
|
170
|
-
|
191
|
+
def scale(size, factor)
|
192
|
+
if match = /(\d+)(.*)/.match(size)
|
193
|
+
value = match[1].to_i
|
194
|
+
unit = match[2]
|
195
|
+
(value * factor).to_i.to_s + unit
|
196
|
+
else
|
197
|
+
size
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def image_output_dir(parent)
|
202
|
+
document = parent.document
|
203
|
+
|
204
|
+
images_dir = document.attr('imagesoutdir')
|
205
|
+
|
206
|
+
if images_dir
|
207
|
+
base_dir = nil
|
208
|
+
else
|
209
|
+
base_dir = document.attr('outdir') || (document.respond_to?(:options) && document.options[:to_dir])
|
210
|
+
images_dir = document.attr('imagesdir')
|
211
|
+
end
|
212
|
+
|
213
|
+
parent.normalize_system_path(images_dir, base_dir)
|
214
|
+
end
|
215
|
+
|
216
|
+
def create_literal_block(parent, source, generator_info)
|
217
|
+
literal_attributes = source.attributes
|
171
218
|
literal_attributes.delete('target')
|
172
219
|
|
173
220
|
result = instance_exec(source, parent, &generator_info[:generator])
|
@@ -207,7 +254,7 @@ module Asciidoctor
|
|
207
254
|
#
|
208
255
|
# @return [FileSource] a FileSource
|
209
256
|
def create_source(parent, target, attributes)
|
210
|
-
FileSource.new(File.expand_path(target, parent.document.
|
257
|
+
FileSource.new(File.expand_path(target, parent.document.base_dir), attributes)
|
211
258
|
end
|
212
259
|
end
|
213
260
|
|
@@ -256,6 +303,8 @@ module Asciidoctor
|
|
256
303
|
class BasicSource
|
257
304
|
include DiagramSource
|
258
305
|
|
306
|
+
attr_reader :attributes
|
307
|
+
|
259
308
|
def initialize(attributes)
|
260
309
|
@attributes = attributes
|
261
310
|
end
|
@@ -317,7 +366,9 @@ module Asciidoctor
|
|
317
366
|
end
|
318
367
|
|
319
368
|
def code
|
320
|
-
|
369
|
+
lines = File.readlines(@file_name)
|
370
|
+
lines = ::Asciidoctor::Helpers.normalize_lines(lines)
|
371
|
+
@code ||= lines.join("\n")
|
321
372
|
end
|
322
373
|
end
|
323
374
|
end
|
@@ -6,70 +6,80 @@ module Asciidoctor
|
|
6
6
|
module PlantUml
|
7
7
|
private
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
unless @graphvizdot
|
14
|
-
@graphvizdot = parent.document.attributes['dot']
|
15
|
-
@graphvizdot = ::Asciidoctor::Diagram.which('dot') unless @graphvizdot && File.executable?(@graphvizdot)
|
16
|
-
raise "Could not find the Graphviz 'dot' executable in PATH; add it to the PATH or specify its location using the 'dot' document attribute" unless @graphvizdot
|
17
|
-
end
|
9
|
+
JARS = ['plantuml.jar'].map do |jar|
|
10
|
+
File.expand_path File.join('../..', jar), File.dirname(__FILE__)
|
11
|
+
end
|
12
|
+
Java.classpath.concat JARS
|
18
13
|
|
14
|
+
def plantuml(parent, code, tag, mime_type)
|
19
15
|
Java.load
|
20
16
|
|
21
17
|
code = "@start#{tag}\n#{code}\n@end#{tag}" unless code.index "@start#{tag}"
|
22
18
|
|
23
|
-
|
19
|
+
headers = {
|
20
|
+
'Accept' => mime_type
|
21
|
+
}
|
24
22
|
|
25
23
|
config_file = parent.document.attributes['plantumlconfig']
|
26
24
|
if config_file
|
27
|
-
|
25
|
+
headers['X-PlantUML-Config'] = File.expand_path(config_file, parent.document.attributes['docdir'])
|
28
26
|
end
|
29
27
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
code,
|
35
|
-
option.getConfig()
|
28
|
+
response = Java.send_request(
|
29
|
+
:url => '/plantuml',
|
30
|
+
:body => code,
|
31
|
+
:headers => headers
|
36
32
|
)
|
37
33
|
|
38
|
-
|
39
|
-
|
40
|
-
source_reader.generateImage(ps, 0, option.getFileFormatOption())
|
41
|
-
ps.close
|
42
|
-
Java.string_from_java_bytes(bos.toByteArray)
|
43
|
-
end
|
44
|
-
|
45
|
-
def config_args(parent)
|
46
|
-
config_args = []
|
47
|
-
config = parent.document.attributes['plantumlconfig']
|
48
|
-
if config
|
49
|
-
config_args += ['-config', File.expand_path(config, parent.document.attributes['docdir'])]
|
34
|
+
unless response[:code] == 200
|
35
|
+
raise "PlantUML image generation failed: #{response[:reason]} #{response[:body]}"
|
50
36
|
end
|
51
37
|
|
52
|
-
|
38
|
+
response[:body]
|
53
39
|
end
|
54
40
|
|
55
41
|
def self.included(mod)
|
56
42
|
mod.register_format(:png, :image) do |c, p|
|
57
|
-
plantuml(p, c.to_s, '
|
43
|
+
plantuml(p, c.to_s, mod.tag, 'image/png')
|
58
44
|
end
|
59
45
|
mod.register_format(:svg, :image) do |c, p|
|
60
|
-
plantuml(p, c.to_s,
|
46
|
+
plantuml(p, c.to_s, mod.tag, 'image/svg+xml')
|
61
47
|
end
|
62
48
|
mod.register_format(:txt, :literal) do |c, p|
|
63
|
-
plantuml(p, c.to_s,
|
49
|
+
plantuml(p, c.to_s, mod.tag, 'text/plain;charset=utf-8')
|
64
50
|
end
|
65
51
|
end
|
66
52
|
end
|
67
53
|
|
68
54
|
class PlantUmlBlockProcessor < Extensions::DiagramBlockProcessor
|
55
|
+
def self.tag
|
56
|
+
'uml'
|
57
|
+
end
|
58
|
+
|
69
59
|
include PlantUml
|
70
60
|
end
|
71
61
|
|
72
62
|
class PlantUmlBlockMacroProcessor < Extensions::DiagramBlockMacroProcessor
|
63
|
+
def self.tag
|
64
|
+
'uml'
|
65
|
+
end
|
66
|
+
|
67
|
+
include PlantUml
|
68
|
+
end
|
69
|
+
|
70
|
+
class SaltBlockProcessor < Extensions::DiagramBlockProcessor
|
71
|
+
def self.tag
|
72
|
+
'salt'
|
73
|
+
end
|
74
|
+
|
75
|
+
include PlantUml
|
76
|
+
end
|
77
|
+
|
78
|
+
class SaltBlockMacroProcessor < Extensions::DiagramBlockMacroProcessor
|
79
|
+
def self.tag
|
80
|
+
'salt'
|
81
|
+
end
|
82
|
+
|
73
83
|
include PlantUml
|
74
84
|
end
|
75
85
|
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'asciidoctor/extensions'
|
2
|
+
require_relative 'version'
|
3
|
+
|
4
|
+
Asciidoctor::Extensions.register do
|
5
|
+
require_relative 'plantuml/extension'
|
6
|
+
|
7
|
+
block Asciidoctor::Diagram::SaltBlockProcessor, :salt
|
8
|
+
block_macro Asciidoctor::Diagram::SaltBlockMacroProcessor, :salt
|
9
|
+
end
|
@@ -1,5 +1,81 @@
|
|
1
|
+
module Asciidoctor
|
2
|
+
module Diagram
|
3
|
+
# @private
|
4
|
+
module Java
|
5
|
+
def self.classpath
|
6
|
+
@classpath ||= [
|
7
|
+
File.expand_path(File.join('../..', 'asciidoctor-diagram-java-1.3.4.jar'), File.dirname(__FILE__))
|
8
|
+
]
|
9
|
+
end
|
10
|
+
|
11
|
+
CRLF = "\r\n".encode(Encoding::US_ASCII)
|
12
|
+
|
13
|
+
def self.format_request(req, io)
|
14
|
+
io.set_encoding Encoding::US_ASCII
|
15
|
+
io.write "POST #{req[:url]} HTTP/1.1"
|
16
|
+
io.write CRLF
|
17
|
+
|
18
|
+
headers = req[:headers]
|
19
|
+
if headers
|
20
|
+
headers.each_pair do |key, value|
|
21
|
+
io.write "#{key}: #{value}"
|
22
|
+
io.write CRLF
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
if req[:body]
|
27
|
+
unless headers && headers['Content-Length']
|
28
|
+
io.write 'Content-Length: '
|
29
|
+
io.write req[:body].bytesize.to_s
|
30
|
+
io.write CRLF
|
31
|
+
end
|
32
|
+
|
33
|
+
unless headers && headers['Content-Type']
|
34
|
+
io.write 'Content-Type: text/plain; charset='
|
35
|
+
io.write req[:body].encoding.name
|
36
|
+
io.write CRLF
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
io.write CRLF
|
41
|
+
|
42
|
+
io.set_encoding Encoding::BINARY
|
43
|
+
io.write req[:body]
|
44
|
+
end
|
45
|
+
|
46
|
+
STATUS_LINE = Regexp.new("HTTP/1.1 (\\d+) (.*)\r\n".encode(Encoding::US_ASCII))
|
47
|
+
|
48
|
+
def self.parse_response(io)
|
49
|
+
resp = {}
|
50
|
+
|
51
|
+
io.set_encoding Encoding::US_ASCII
|
52
|
+
status_line = io.readline(CRLF)
|
53
|
+
status_line_parts = STATUS_LINE.match status_line
|
54
|
+
resp[:code] = status_line_parts[1].to_i
|
55
|
+
resp[:reason] = status_line_parts[2]
|
56
|
+
|
57
|
+
headers = {}
|
58
|
+
until (header = io.readline(CRLF).strip).empty?
|
59
|
+
key, value = header.split ':', 2
|
60
|
+
headers[key] = value.strip
|
61
|
+
end
|
62
|
+
|
63
|
+
resp[:headers] = headers
|
64
|
+
|
65
|
+
content_length = headers['Content-Length']
|
66
|
+
if content_length
|
67
|
+
io.set_encoding Encoding::BINARY
|
68
|
+
resp[:body] = io.read(content_length.to_i)
|
69
|
+
end
|
70
|
+
|
71
|
+
resp
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
1
77
|
if RUBY_PLATFORM == "java"
|
2
78
|
require_relative 'java_jruby'
|
3
79
|
else
|
4
|
-
require_relative '
|
80
|
+
require_relative 'java_socket'
|
5
81
|
end
|
@@ -1,40 +1,33 @@
|
|
1
1
|
require 'java'
|
2
|
+
require 'stringio'
|
2
3
|
|
3
4
|
module Asciidoctor
|
4
5
|
module Diagram
|
5
6
|
# @private
|
6
7
|
module Java
|
7
|
-
def self.classpath
|
8
|
-
@classpath ||= []
|
9
|
-
end
|
10
|
-
|
11
8
|
def self.load
|
12
9
|
if @loaded
|
13
10
|
return
|
14
11
|
end
|
15
12
|
|
16
|
-
classpath.each { |j| require j }
|
13
|
+
classpath.flatten.each { |j| require j }
|
17
14
|
@loaded = true
|
18
15
|
end
|
19
16
|
|
20
|
-
def self.
|
21
|
-
|
22
|
-
end
|
17
|
+
def self.send_request(req)
|
18
|
+
cp = ::Java.org.asciidoctor.diagram.CommandProcessor.new()
|
23
19
|
|
24
|
-
|
25
|
-
|
26
|
-
|
20
|
+
req_io = StringIO.new
|
21
|
+
format_request(req, req_io)
|
22
|
+
req_io.close
|
27
23
|
|
28
|
-
|
29
|
-
raise "No arguments expected" unless args.empty?
|
30
|
-
raise "No block expected" if block
|
24
|
+
response = cp.processRequest(req_io.string.to_java_bytes)
|
31
25
|
|
32
|
-
|
33
|
-
|
34
|
-
|
26
|
+
resp_io = StringIO.new(String.from_java_bytes(response))
|
27
|
+
resp = parse_response(resp_io)
|
28
|
+
resp_io.close
|
35
29
|
|
36
|
-
|
37
|
-
java_class.new(*args)
|
30
|
+
resp
|
38
31
|
end
|
39
32
|
end
|
40
33
|
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
require_relative 'which'
|
4
|
+
|
5
|
+
module Asciidoctor
|
6
|
+
module Diagram
|
7
|
+
# @private
|
8
|
+
module Java
|
9
|
+
class CommandServer
|
10
|
+
attr_reader :port
|
11
|
+
|
12
|
+
def initialize(java, classpath)
|
13
|
+
args = []
|
14
|
+
args << '-Djava.awt.headless=true'
|
15
|
+
args << '-cp'
|
16
|
+
args << classpath.flatten.join(File::PATH_SEPARATOR)
|
17
|
+
args << 'org.asciidoctor.diagram.CommandServer'
|
18
|
+
|
19
|
+
@server = IO.popen([java, *args])
|
20
|
+
@port = @server.readline.strip.to_i
|
21
|
+
@client = TCPSocket.new 'localhost', port
|
22
|
+
end
|
23
|
+
|
24
|
+
def io
|
25
|
+
@client
|
26
|
+
end
|
27
|
+
|
28
|
+
def shutdown
|
29
|
+
# KILL is a bit heavy handed, but TERM does not seem to shut down the JVM on Windows.
|
30
|
+
Process.kill('KILL', @server.pid)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.load
|
35
|
+
if @loaded
|
36
|
+
return
|
37
|
+
end
|
38
|
+
|
39
|
+
instance
|
40
|
+
@loaded = true
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.instance
|
44
|
+
@java_exe ||= find_java
|
45
|
+
raise "Could not find Java executable" unless @java_exe
|
46
|
+
|
47
|
+
unless @command_server
|
48
|
+
server = CommandServer.new(@java_exe, classpath)
|
49
|
+
@command_server = server
|
50
|
+
at_exit do
|
51
|
+
server.shutdown
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
@command_server
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.send_request(req)
|
59
|
+
svr = instance
|
60
|
+
headers = req[:headers] ||= {}
|
61
|
+
headers['Host'] = "localhost:#{svr.port}"
|
62
|
+
format_request(req, svr.io)
|
63
|
+
parse_response(svr.io)
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
def self.find_java
|
68
|
+
if /cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM
|
69
|
+
# Windows
|
70
|
+
path_to(ENV['JAVA_HOME'], 'bin/java.exe') || registry_lookup || ::Asciidoctor::Diagram.which('java')
|
71
|
+
elsif /darwin/ =~ RUBY_PLATFORM
|
72
|
+
# Mac
|
73
|
+
path_to(ENV['JAVA_HOME'], 'bin/java') || path_to(`/usr/libexec/java_home`.strip, 'bin/java') || ::Asciidoctor::Diagram.which('java')
|
74
|
+
else
|
75
|
+
# Other unix-like system
|
76
|
+
path_to(ENV['JAVA_HOME'], 'bin/java') || ::Asciidoctor::Diagram.which('java')
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.path_to(java_home, java_binary)
|
81
|
+
exe_path = File.expand_path(java_binary, java_home)
|
82
|
+
if File.executable?(exe_path)
|
83
|
+
exe_path
|
84
|
+
else
|
85
|
+
nil
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.registry_lookup
|
90
|
+
key_re = /^HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\.*\\([0-9\.]+)/
|
91
|
+
value_re = /\s*JavaHome\s*REG_SZ\s*(.*)/
|
92
|
+
result = `reg query "HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft" /s /v JavaHome`.lines.map { |l| l.strip }
|
93
|
+
vms = result.each_slice(3).map do |_, key, value|
|
94
|
+
key_match = key_re.match(key)
|
95
|
+
value_match = value_re.match(value)
|
96
|
+
if key_match && value_match
|
97
|
+
[key_match[1].split('.').map { |v| v.to_i }, value_match[1]]
|
98
|
+
else
|
99
|
+
nil
|
100
|
+
end
|
101
|
+
end.reject { |v| v.nil? }.sort_by { |v| v[0] }
|
102
|
+
java_exes = vms.map { |version, path| File.expand_path('bin/java.exe', path) }.select { |exe| File.executable?(exe) }
|
103
|
+
java_exes && java_exes[0]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
Binary file
|
data/lib/asciidoctor-diagram.rb
CHANGED
Binary file
|
data/lib/plantuml.jar
CHANGED
Binary file
|
data/spec/ditaa_spec.rb
CHANGED
@@ -118,4 +118,72 @@ Doc Writer <doc@example.com>
|
|
118
118
|
expect(target).to match /\.png$/
|
119
119
|
expect(File.exists?(target)).to be true
|
120
120
|
end
|
121
|
+
|
122
|
+
it "should support ditaa options as attributes" do
|
123
|
+
doc = <<-eos
|
124
|
+
:ditaa-option-antialias: false
|
125
|
+
:ditaa-option-round-corners: true
|
126
|
+
= Hello, PlantUML!
|
127
|
+
Doc Writer <doc@example.com>
|
128
|
+
|
129
|
+
== First Section
|
130
|
+
|
131
|
+
[ditaa, shadows=false, separation=false, round-corners=false, scale=2.3]
|
132
|
+
----
|
133
|
+
+--------+ +-------+ +-------+
|
134
|
+
| | --+ ditaa +--> | |
|
135
|
+
| Text | +-------+ |diagram|
|
136
|
+
|Document| |!magic!| | |
|
137
|
+
| {d}| | | | |
|
138
|
+
+---+----+ +-------+ +-------+
|
139
|
+
: ^
|
140
|
+
| Lots of work |
|
141
|
+
+-------------------------+
|
142
|
+
----
|
143
|
+
eos
|
144
|
+
|
145
|
+
d = Asciidoctor.load StringIO.new(doc)
|
146
|
+
expect(d).to_not be_nil
|
147
|
+
|
148
|
+
b = d.find { |b| b.context == :image }
|
149
|
+
expect(b).to_not be_nil
|
150
|
+
target = b.attributes['target']
|
151
|
+
expect(target).to match /\.png$/
|
152
|
+
expect(File.exists?(target)).to be true
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should regenerate images when options change" do
|
156
|
+
doc = <<-eos
|
157
|
+
= Hello, PlantUML!
|
158
|
+
Doc Writer <doc@example.com>
|
159
|
+
|
160
|
+
== First Section
|
161
|
+
|
162
|
+
[ditaa, {opts}]
|
163
|
+
----
|
164
|
+
+--------+ +-------+ +-------+
|
165
|
+
| | --+ ditaa +--> | |
|
166
|
+
| Text | +-------+ |diagram|
|
167
|
+
|Document| |!magic!| | |
|
168
|
+
| {d}| | | | |
|
169
|
+
+---+----+ +-------+ +-------+
|
170
|
+
: ^
|
171
|
+
| Lots of work |
|
172
|
+
+-------------------------+
|
173
|
+
----
|
174
|
+
eos
|
175
|
+
|
176
|
+
d = Asciidoctor.load StringIO.new(doc.sub('{opts}', 'shadow=false'))
|
177
|
+
b = d.find { |b| b.context == :image }
|
178
|
+
target = b.attributes['target']
|
179
|
+
mtime1 = File.mtime(target)
|
180
|
+
|
181
|
+
sleep 1
|
182
|
+
|
183
|
+
d = Asciidoctor.load StringIO.new(doc.sub('{opts}', 'round-corners=true'))
|
184
|
+
|
185
|
+
mtime2 = File.mtime(target)
|
186
|
+
|
187
|
+
expect(mtime2).to be > mtime1
|
188
|
+
end
|
121
189
|
end
|
data/spec/plantuml_spec.rb
CHANGED
@@ -297,6 +297,31 @@ Foo1 -> Foo2 : To boundary
|
|
297
297
|
expect(File.exists?(File.expand_path(target, 'foo'))).to be true
|
298
298
|
end
|
299
299
|
|
300
|
+
it "should write files to imagesoutdir if set" do
|
301
|
+
doc = <<-eos
|
302
|
+
= Hello, PlantUML!
|
303
|
+
Doc Writer <doc@example.com>
|
304
|
+
|
305
|
+
== First Section
|
306
|
+
|
307
|
+
[plantuml, format="svg"]
|
308
|
+
----
|
309
|
+
actor Foo1
|
310
|
+
boundary Foo2
|
311
|
+
Foo1 -> Foo2 : To boundary
|
312
|
+
----
|
313
|
+
eos
|
314
|
+
|
315
|
+
d = Asciidoctor.load StringIO.new(doc), {:attributes => {'imagesoutdir' => 'bar', 'outdir' => 'foo'}}
|
316
|
+
b = d.find { |b| b.context == :image }
|
317
|
+
|
318
|
+
target = b.attributes['target']
|
319
|
+
expect(target).to_not be_nil
|
320
|
+
expect(File.exists?(target)).to be false
|
321
|
+
expect(File.exists?(File.expand_path(target, 'bar'))).to be true
|
322
|
+
expect(File.exists?(File.expand_path(target, 'foo'))).to be false
|
323
|
+
end
|
324
|
+
|
300
325
|
it "should omit width/height attributes when generating docbook" do
|
301
326
|
doc = <<-eos
|
302
327
|
= Hello, PlantUML!
|
@@ -310,7 +335,7 @@ User -> (Start)
|
|
310
335
|
----
|
311
336
|
eos
|
312
337
|
|
313
|
-
d = Asciidoctor.load StringIO.new(doc), :attributes => {'backend' => 'docbook5'
|
338
|
+
d = Asciidoctor.load StringIO.new(doc), :attributes => {'backend' => 'docbook5'}
|
314
339
|
expect(d).to_not be_nil
|
315
340
|
|
316
341
|
b = d.find { |b| b.context == :image }
|
@@ -322,4 +347,142 @@ User -> (Start)
|
|
322
347
|
expect(b.attributes['width']).to be_nil
|
323
348
|
expect(b.attributes['height']).to be_nil
|
324
349
|
end
|
350
|
+
|
351
|
+
it "should support salt diagrams using salt block type" do
|
352
|
+
doc = <<-eos
|
353
|
+
= Hello, PlantUML!
|
354
|
+
Doc Writer <doc@example.com>
|
355
|
+
|
356
|
+
== First Section
|
357
|
+
|
358
|
+
[salt, format="png"]
|
359
|
+
----
|
360
|
+
{
|
361
|
+
Just plain text
|
362
|
+
[This is my button]
|
363
|
+
() Unchecked radio
|
364
|
+
(X) Checked radio
|
365
|
+
[] Unchecked box
|
366
|
+
[X] Checked box
|
367
|
+
"Enter text here "
|
368
|
+
^This is a droplist^
|
369
|
+
}
|
370
|
+
----
|
371
|
+
eos
|
372
|
+
|
373
|
+
d = Asciidoctor.load StringIO.new(doc), :attributes => {'backend' => 'docbook5'}
|
374
|
+
expect(d).to_not be_nil
|
375
|
+
|
376
|
+
b = d.find { |b| b.context == :image }
|
377
|
+
expect(b).to_not be_nil
|
378
|
+
|
379
|
+
target = b.attributes['target']
|
380
|
+
expect(File.exists?(target)).to be true
|
381
|
+
|
382
|
+
expect(b.attributes['width']).to be_nil
|
383
|
+
expect(b.attributes['height']).to be_nil
|
384
|
+
end
|
385
|
+
|
386
|
+
it "should support salt diagrams using plantuml block type" do
|
387
|
+
doc = <<-eos
|
388
|
+
= Hello, PlantUML!
|
389
|
+
Doc Writer <doc@example.com>
|
390
|
+
|
391
|
+
== First Section
|
392
|
+
|
393
|
+
[plantuml, format="png"]
|
394
|
+
----
|
395
|
+
salt
|
396
|
+
{
|
397
|
+
Just plain text
|
398
|
+
[This is my button]
|
399
|
+
() Unchecked radio
|
400
|
+
(X) Checked radio
|
401
|
+
[] Unchecked box
|
402
|
+
[X] Checked box
|
403
|
+
"Enter text here "
|
404
|
+
^This is a droplist^
|
405
|
+
}
|
406
|
+
----
|
407
|
+
eos
|
408
|
+
|
409
|
+
d = Asciidoctor.load StringIO.new(doc), :attributes => {'backend' => 'docbook5'}
|
410
|
+
expect(d).to_not be_nil
|
411
|
+
|
412
|
+
b = d.find { |b| b.context == :image }
|
413
|
+
expect(b).to_not be_nil
|
414
|
+
|
415
|
+
target = b.attributes['target']
|
416
|
+
expect(File.exists?(target)).to be true
|
417
|
+
|
418
|
+
expect(b.attributes['width']).to be_nil
|
419
|
+
expect(b.attributes['height']).to be_nil
|
420
|
+
end
|
421
|
+
|
422
|
+
it "should support salt diagrams containing tree widgets" do
|
423
|
+
doc = <<-eos
|
424
|
+
= Hello, PlantUML!
|
425
|
+
Doc Writer <doc@example.com>
|
426
|
+
|
427
|
+
== First Section
|
428
|
+
|
429
|
+
[plantuml, format="png"]
|
430
|
+
----
|
431
|
+
salt
|
432
|
+
{
|
433
|
+
{T
|
434
|
+
+A
|
435
|
+
++a
|
436
|
+
}
|
437
|
+
}
|
438
|
+
----
|
439
|
+
eos
|
440
|
+
|
441
|
+
d = Asciidoctor.load StringIO.new(doc), :attributes => {'backend' => 'docbook5'}
|
442
|
+
expect(d).to_not be_nil
|
443
|
+
|
444
|
+
b = d.find { |b| b.context == :image }
|
445
|
+
expect(b).to_not be_nil
|
446
|
+
|
447
|
+
target = b.attributes['target']
|
448
|
+
expect(File.exists?(target)).to be true
|
449
|
+
|
450
|
+
expect(b.attributes['width']).to be_nil
|
451
|
+
expect(b.attributes['height']).to be_nil
|
452
|
+
end
|
453
|
+
|
454
|
+
it "should support scaling diagrams" do
|
455
|
+
doc = <<-eos
|
456
|
+
= Hello, PlantUML!
|
457
|
+
Doc Writer <doc@example.com>
|
458
|
+
|
459
|
+
== First Section
|
460
|
+
|
461
|
+
[plantuml, format="png"]
|
462
|
+
----
|
463
|
+
A -> B
|
464
|
+
----
|
465
|
+
eos
|
466
|
+
|
467
|
+
scaled_doc = <<-eos
|
468
|
+
= Hello, PlantUML!
|
469
|
+
Doc Writer <doc@example.com>
|
470
|
+
|
471
|
+
== First Section
|
472
|
+
|
473
|
+
[plantuml, format="png", scale="1.5"]
|
474
|
+
----
|
475
|
+
A -> B
|
476
|
+
----
|
477
|
+
eos
|
478
|
+
|
479
|
+
d = Asciidoctor.load StringIO.new(doc), :attributes => {'backend' => 'html5'}
|
480
|
+
unscaled_image = d.find { |b| b.context == :image }
|
481
|
+
|
482
|
+
d = Asciidoctor.load StringIO.new(scaled_doc), :attributes => {'backend' => 'html5'}
|
483
|
+
scaled_image = d.find { |b| b.context == :image }
|
484
|
+
|
485
|
+
expect(scaled_image.attributes['width']).to be_within(1).of(unscaled_image.attributes['width'] * 1.5)
|
486
|
+
expect(scaled_image.attributes['height']).to be_within(1).of(unscaled_image.attributes['height'] * 1.5)
|
487
|
+
end
|
325
488
|
end
|
data/spec/test_helper.rb
CHANGED
@@ -30,7 +30,7 @@ module Asciidoctor
|
|
30
30
|
end
|
31
31
|
|
32
32
|
RSpec.configure do |c|
|
33
|
-
TEST_DIR = 'testing'
|
33
|
+
TEST_DIR = File.expand_path('testing')
|
34
34
|
|
35
35
|
c.before(:suite) do
|
36
36
|
FileUtils.rm_r TEST_DIR if Dir.exists? TEST_DIR
|
@@ -45,12 +45,8 @@ RSpec.configure do |c|
|
|
45
45
|
test_dir = File.expand_path(metadata[:description].gsub(/[^\w]+/, '_'), group_dir)
|
46
46
|
Dir.mkdir(test_dir)
|
47
47
|
|
48
|
-
|
49
|
-
Dir.chdir test_dir
|
50
|
-
begin
|
48
|
+
Dir.chdir(test_dir) do
|
51
49
|
example.run
|
52
|
-
ensure
|
53
|
-
Dir.chdir old_wd
|
54
50
|
end
|
55
51
|
end
|
56
52
|
end
|
metadata
CHANGED
@@ -1,85 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: asciidoctor-diagram
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.0
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pepijn Van Eeckhoudt
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-08-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.3'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.3'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: asciidoctor
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - ~>
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: 1.5.0
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - ~>
|
66
|
+
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 1.5.0
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: rjb
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ~>
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: 1.4.8
|
76
|
-
type: :runtime
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ~>
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: 1.4.8
|
83
69
|
description: Asciidoctor diagramming extension
|
84
70
|
email:
|
85
71
|
- pepijn@vaneeckhoudt.net
|
@@ -95,6 +81,7 @@ files:
|
|
95
81
|
- examples/README.adoc
|
96
82
|
- examples/design.adoc
|
97
83
|
- examples/features.adoc
|
84
|
+
- lib/asciidoctor-diagram-java-1.3.4.jar
|
98
85
|
- lib/asciidoctor-diagram.rb
|
99
86
|
- lib/asciidoctor-diagram/blockdiag.rb
|
100
87
|
- lib/asciidoctor-diagram/blockdiag/extension.rb
|
@@ -105,18 +92,19 @@ files:
|
|
105
92
|
- lib/asciidoctor-diagram/graphviz/extension.rb
|
106
93
|
- lib/asciidoctor-diagram/plantuml.rb
|
107
94
|
- lib/asciidoctor-diagram/plantuml/extension.rb
|
95
|
+
- lib/asciidoctor-diagram/salt.rb
|
108
96
|
- lib/asciidoctor-diagram/shaape.rb
|
109
97
|
- lib/asciidoctor-diagram/shaape/extension.rb
|
110
98
|
- lib/asciidoctor-diagram/util/binaryio.rb
|
111
99
|
- lib/asciidoctor-diagram/util/cli_generator.rb
|
112
100
|
- lib/asciidoctor-diagram/util/java.rb
|
113
101
|
- lib/asciidoctor-diagram/util/java_jruby.rb
|
114
|
-
- lib/asciidoctor-diagram/util/
|
102
|
+
- lib/asciidoctor-diagram/util/java_socket.rb
|
115
103
|
- lib/asciidoctor-diagram/util/png.rb
|
116
104
|
- lib/asciidoctor-diagram/util/svg.rb
|
117
105
|
- lib/asciidoctor-diagram/util/which.rb
|
118
106
|
- lib/asciidoctor-diagram/version.rb
|
119
|
-
- lib/
|
107
|
+
- lib/ditaamini-0.10.jar
|
120
108
|
- lib/plantuml.jar
|
121
109
|
- spec/blockdiag_spec.rb
|
122
110
|
- spec/ditaa_spec.rb
|
@@ -134,17 +122,17 @@ require_paths:
|
|
134
122
|
- lib
|
135
123
|
required_ruby_version: !ruby/object:Gem::Requirement
|
136
124
|
requirements:
|
137
|
-
- -
|
125
|
+
- - ">="
|
138
126
|
- !ruby/object:Gem::Version
|
139
127
|
version: '0'
|
140
128
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
141
129
|
requirements:
|
142
|
-
- -
|
130
|
+
- - ">="
|
143
131
|
- !ruby/object:Gem::Version
|
144
|
-
version:
|
132
|
+
version: '0'
|
145
133
|
requirements: []
|
146
134
|
rubyforge_project:
|
147
|
-
rubygems_version: 2.
|
135
|
+
rubygems_version: 2.4.7
|
148
136
|
signing_key:
|
149
137
|
specification_version: 4
|
150
138
|
summary: An extension for asciidoctor that adds support for UML diagram generation
|
@@ -1,91 +0,0 @@
|
|
1
|
-
require 'rjb'
|
2
|
-
|
3
|
-
module Asciidoctor
|
4
|
-
module Diagram
|
5
|
-
# @private
|
6
|
-
module Java
|
7
|
-
INITAWT_JAR_PATH = File.expand_path File.join('..', 'initawt.jar'), File.dirname(__FILE__)
|
8
|
-
|
9
|
-
module Package
|
10
|
-
def method_missing(meth, *args, &block)
|
11
|
-
raise "No arguments expected" unless args.empty?
|
12
|
-
raise "No block expected" if block
|
13
|
-
|
14
|
-
name = meth.to_s
|
15
|
-
@proxies ||= {}
|
16
|
-
@proxies[name] ||= create_java_proxy(name)
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
def create_java_proxy(name)
|
22
|
-
qualified_name = @name ? "#{@name}.#{name}" : name
|
23
|
-
if name =~ /^[[:upper:]]/
|
24
|
-
Package.create_class(qualified_name)
|
25
|
-
else
|
26
|
-
Package.create_package(qualified_name)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.create_class(name)
|
31
|
-
::Rjb.import(name)
|
32
|
-
end
|
33
|
-
|
34
|
-
def self.create_package(name)
|
35
|
-
package = Module.new
|
36
|
-
package.extend Package
|
37
|
-
package.instance_variable_set :@name, name
|
38
|
-
package.instance_variable_set :@parent, name
|
39
|
-
package
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def self.classpath
|
44
|
-
@classpath ||= []
|
45
|
-
end
|
46
|
-
|
47
|
-
def self.load
|
48
|
-
if @loaded
|
49
|
-
return
|
50
|
-
end
|
51
|
-
|
52
|
-
Rjb::load(classpath.join(File::PATH_SEPARATOR))
|
53
|
-
|
54
|
-
# On OS X using AWT from JNI is extremely deadlock prone. Enabling AWT headless mode resolves this issue. We're
|
55
|
-
# never actually going to display an AWT GUI, so this should be fairly safe.
|
56
|
-
Rjb::import('java.lang.System').setProperty 'java.awt.headless', 'true'
|
57
|
-
|
58
|
-
@loaded = true
|
59
|
-
end
|
60
|
-
|
61
|
-
def self.array_to_java_array(array, type)
|
62
|
-
# Rjb does not require an explicit conversion of a Ruby Array containing Ruby Strings to a Ruby Array containing
|
63
|
-
# Java Strings. It handles this implicitly when calling Java methods.
|
64
|
-
array
|
65
|
-
end
|
66
|
-
|
67
|
-
def self.string_from_java_bytes(bytes)
|
68
|
-
# Rjb implictly converts Java byte arrays to Ruby Strings so nothing needs to be done here
|
69
|
-
bytes
|
70
|
-
end
|
71
|
-
|
72
|
-
def self.method_missing(meth, *args, &block)
|
73
|
-
raise "No arguments expected" unless args.empty?
|
74
|
-
raise "No block expected" if block
|
75
|
-
|
76
|
-
load
|
77
|
-
|
78
|
-
@root_package ||= Package.send(:create_package, nil)
|
79
|
-
@root_package.send(meth, *args)
|
80
|
-
end
|
81
|
-
|
82
|
-
def self.new_object(java_class, signature = nil, *args)
|
83
|
-
if signature
|
84
|
-
java_class.new_with_sig(signature, *args)
|
85
|
-
else
|
86
|
-
java_class.new(*args)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
data/lib/ditaamini0_9.jar
DELETED
Binary file
|