asciidoctor-diagram 1.3.0.preview.1 → 1.3.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.
- 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
|