asciidoctor-diagram 1.2.0.preview.3 → 1.2.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 +43 -0
- data/lib/asciidoctor-diagram/blockdiag/extension.rb +18 -0
- data/lib/asciidoctor-diagram/blockdiag.rb +8 -0
- data/lib/asciidoctor-diagram/ditaa/extension.rb +21 -23
- data/lib/asciidoctor-diagram/graphviz/extension.rb +7 -32
- data/lib/asciidoctor-diagram/plantuml/extension.rb +15 -31
- data/lib/asciidoctor-diagram/plantuml/generator.rb +12 -21
- data/lib/asciidoctor-diagram/shaape/extension.rb +16 -0
- data/lib/asciidoctor-diagram/shaape.rb +9 -0
- data/lib/asciidoctor-diagram/util/cli_generator.rb +40 -0
- data/lib/asciidoctor-diagram/util/diagram.rb +75 -54
- data/lib/asciidoctor-diagram/util/java_jruby.rb +4 -0
- data/lib/asciidoctor-diagram/util/java_rjb.rb +8 -0
- data/lib/asciidoctor-diagram/util/svg.rb +19 -23
- data/lib/asciidoctor-diagram/util/which.rb +14 -0
- data/lib/asciidoctor-diagram/version.rb +1 -1
- data/lib/asciidoctor-diagram.rb +3 -1
- data/lib/plantuml.jar +0 -0
- data/spec/blockdiag_spec.rb +183 -0
- data/spec/ditaa_spec.rb +3 -3
- data/spec/graphviz_spec.rb +28 -3
- data/spec/plantuml_spec.rb +60 -9
- data/spec/shaape_spec.rb +227 -0
- data/spec/test_helper.rb +2 -0
- metadata +17 -8
- data/lib/asciidoctor-diagram/ditaa/generator.rb +0 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 74838c060f09bcfe7603faef3aeee8c075cecaec
|
4
|
+
data.tar.gz: cb315faf5b140f071a6f7a0fdb748e366d5eefae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 131fb3f8a3cecb232601c72424240c284996bfeef9a66c64bc3d88c6e0a1aab48299c2baa5935d1d3ed54ceca85b912716ae10dea48c21950ce6d5ff3b76f960
|
7
|
+
data.tar.gz: 4d096215c18e27b7fdfbb4bccd131c6e94699c9fb572c1f5f00e9df196a2c0d81390dd84c70dfbef3153a9cfe8d7c3598fd15f6f14d53979b93fe44130f82589
|
data/CHANGELOG.adoc
CHANGED
@@ -6,6 +6,49 @@ Enhancements::
|
|
6
6
|
|
7
7
|
* Updated to Asciidoctor 1.5.0
|
8
8
|
|
9
|
+
== 1.1.6
|
10
|
+
|
11
|
+
Enhancements::
|
12
|
+
|
13
|
+
* Updated PlantUML to revision 8002 (23/07U/2014)
|
14
|
+
* Add support for Shaape diagrams (requires Shaape to be installed separately)
|
15
|
+
* Add support for Blockdiag diagrams (requires Blockdiag to be installed separately)
|
16
|
+
* Add support for Actdiag diagrams (requires Actdiag to be installed separately)
|
17
|
+
* Add support for Seqdiag diagrams (requires Seqdiag to be installed separately)
|
18
|
+
* Add support for Nwdiag diagrams (requires Nwdiag to be installed separately)
|
19
|
+
|
20
|
+
Bug Fixes::
|
21
|
+
* Issue #38: Resolved Graphviz syntax errors with certain diagrams
|
22
|
+
|
23
|
+
== 1.1.5
|
24
|
+
|
25
|
+
Enhancements::
|
26
|
+
|
27
|
+
* Use the output directory (outdir attribute) as base directory if it's specified.
|
28
|
+
* Do not auto-generate width/height attributes when outputting to a non-HTML backend. This resolves issues with
|
29
|
+
oversized images in docbook output.
|
30
|
+
|
31
|
+
== 1.1.4
|
32
|
+
|
33
|
+
Bug Fixes::
|
34
|
+
|
35
|
+
* Under CRuby in combination with certain Java versions a FileNotFoundException could be triggered due to incorrect
|
36
|
+
method selection by RJB
|
37
|
+
|
38
|
+
== 1.1.3
|
39
|
+
|
40
|
+
Bug Fixes::
|
41
|
+
|
42
|
+
* Image regeneration logic did not always correctly detect cases where images did not need to be updated
|
43
|
+
|
44
|
+
== 1.1.2
|
45
|
+
|
46
|
+
Bug Fixes::
|
47
|
+
|
48
|
+
* Fix corrupt PNG images on Windows
|
49
|
+
* Fix NoSuchMethodError in block macro processing when target image file already existed
|
50
|
+
* Respect target attribute in block macros
|
51
|
+
|
9
52
|
== 1.1.1
|
10
53
|
|
11
54
|
Bug Fixes::
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative '../util/cli_generator'
|
2
|
+
require_relative '../util/diagram'
|
3
|
+
|
4
|
+
module Asciidoctor
|
5
|
+
module Diagram
|
6
|
+
['BlockDiag', 'SeqDiag', 'ActDiag', 'NwDiag', 'RackDiag', 'PacketDiag'].each do |tool|
|
7
|
+
define_processors(tool) do
|
8
|
+
[:png, :svg].each do |f|
|
9
|
+
register_format(f, :image) do |c, p|
|
10
|
+
CliGenerator.generate(tool.downcase, p, c) do |tool_path, output_path|
|
11
|
+
[tool_path, '-o', output_path, "-T#{f.to_s}", '-']
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
require 'asciidoctor/extensions'
|
2
|
+
require_relative 'version'
|
3
|
+
|
4
|
+
Asciidoctor::Extensions.register do
|
5
|
+
require_relative 'blockdiag/extension'
|
6
|
+
block Asciidoctor::Diagram::BlockDiagBlock, :blockdiag
|
7
|
+
block_macro Asciidoctor::Diagram::BlockDiagBlockMacro, :blockdiag
|
8
|
+
end
|
@@ -1,37 +1,35 @@
|
|
1
1
|
require_relative '../util/diagram'
|
2
|
-
require_relative '
|
2
|
+
require_relative '../util/java'
|
3
3
|
|
4
4
|
module Asciidoctor
|
5
5
|
module Diagram
|
6
|
-
module
|
7
|
-
|
6
|
+
module DitaaGenerator
|
7
|
+
DITAA_JAR_PATH = File.expand_path File.join('../..', 'ditaamini0_9.jar'), File.dirname(__FILE__)
|
8
|
+
Java.classpath << DITAA_JAR_PATH
|
8
9
|
|
9
|
-
|
10
|
+
def self.ditaa(code)
|
11
|
+
Java.load
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
args = ['-e', 'UTF-8']
|
14
|
+
|
15
|
+
bytes = code.encode(Encoding::UTF_8).bytes.to_a
|
16
|
+
bis = Java.new_object(Java.java.io.ByteArrayInputStream, '[B', Java.array_to_java_array(bytes, :byte))
|
17
|
+
bos = Java.new_object(Java.java.io.ByteArrayOutputStream)
|
18
|
+
result_code = Java.org.stathissideris.ascii2image.core.CommandLineConverter.convert(Java.array_to_java_array(args, :string), bis, bos)
|
19
|
+
bis.close
|
20
|
+
bos.close
|
17
21
|
|
18
|
-
|
19
|
-
include DiagramProcessorBase
|
20
|
-
include DitaaBase
|
22
|
+
result = Java.string_from_java_bytes(bos.toByteArray)
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
-
|
24
|
+
raise "Ditaa image generation failed: #{result}" unless result_code == 0
|
25
|
+
|
26
|
+
result
|
25
27
|
end
|
26
28
|
end
|
27
29
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
def initialize name = nil, config = {}
|
33
|
-
super
|
34
|
-
register_formats()
|
30
|
+
define_processors('Ditaa') do
|
31
|
+
register_format(:png, :image) do |c|
|
32
|
+
DitaaGenerator.ditaa(c)
|
35
33
|
end
|
36
34
|
end
|
37
35
|
end
|
@@ -1,41 +1,16 @@
|
|
1
|
+
require_relative '../util/cli_generator'
|
1
2
|
require_relative '../util/diagram'
|
2
|
-
require_relative '../plantuml/generator'
|
3
3
|
|
4
4
|
module Asciidoctor
|
5
5
|
module Diagram
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
register_format(:png, :image) do |c, p|
|
13
|
-
plantuml(p, c, 'dot')
|
14
|
-
end
|
15
|
-
register_format(:svg, :image) do |c, p|
|
16
|
-
plantuml(p, c, 'dot', '-tsvg')
|
6
|
+
define_processors('Graphviz') do
|
7
|
+
[:png, :svg].each do |f|
|
8
|
+
register_format(f, :image) do |c, p|
|
9
|
+
CliGenerator.generate('dot', p, c) do |tool_path, output_path|
|
10
|
+
[tool_path, "-o#{output_path}", "-T#{f.to_s}"]
|
11
|
+
end
|
17
12
|
end
|
18
13
|
end
|
19
14
|
end
|
20
|
-
|
21
|
-
class GraphvizBlock < Asciidoctor::Extensions::BlockProcessor
|
22
|
-
include DiagramProcessorBase
|
23
|
-
include GraphvizBase
|
24
|
-
|
25
|
-
def initialize name = nil, config = {}
|
26
|
-
super
|
27
|
-
register_formats()
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
class GraphvizBlockMacro < Asciidoctor::Extensions::BlockMacroProcessor
|
32
|
-
include DiagramProcessorBase
|
33
|
-
include GraphvizBase
|
34
|
-
|
35
|
-
def initialize name = nil, config = {}
|
36
|
-
super
|
37
|
-
register_formats()
|
38
|
-
end
|
39
|
-
end
|
40
15
|
end
|
41
16
|
end
|
@@ -3,41 +3,25 @@ require_relative 'generator'
|
|
3
3
|
|
4
4
|
module Asciidoctor
|
5
5
|
module Diagram
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
register_format(:png, :image) do |c, p|
|
13
|
-
plantuml(p, c, 'uml')
|
14
|
-
end
|
15
|
-
register_format(:svg, :image) do |c, p|
|
16
|
-
plantuml(p, c, 'uml', '-tsvg')
|
6
|
+
define_processors('PlantUml') do
|
7
|
+
def config_args(parent)
|
8
|
+
config_args = []
|
9
|
+
config = parent.document.attributes['plantumlconfig']
|
10
|
+
if config
|
11
|
+
config_args += ['-config', File.expand_path(config, parent.document.attributes['docdir'])]
|
17
12
|
end
|
18
|
-
register_format(:txt, :literal) do |c, p|
|
19
|
-
plantuml(p, c, 'uml', '-tutxt')
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
13
|
|
24
|
-
|
25
|
-
include DiagramProcessorBase
|
26
|
-
include PlantUmlBase
|
27
|
-
|
28
|
-
def initialize name = nil, config = {}
|
29
|
-
super
|
30
|
-
register_formats()
|
14
|
+
config_args
|
31
15
|
end
|
32
|
-
end
|
33
|
-
|
34
|
-
class PlantUmlBlockMacro < Asciidoctor::Extensions::BlockMacroProcessor
|
35
|
-
include DiagramProcessorBase
|
36
|
-
include PlantUmlBase
|
37
16
|
|
38
|
-
|
39
|
-
|
40
|
-
|
17
|
+
register_format(:png, :image) do |c, p|
|
18
|
+
PlantUmlGenerator.plantuml(p, c, 'uml', *config_args(p))
|
19
|
+
end
|
20
|
+
register_format(:svg, :image) do |c, p|
|
21
|
+
PlantUmlGenerator.plantuml(p, c, 'uml', '-tsvg', *config_args(p))
|
22
|
+
end
|
23
|
+
register_format(:txt, :literal) do |c, p|
|
24
|
+
PlantUmlGenerator.plantuml(p, c, 'uml', '-tutxt', *config_args(p))
|
41
25
|
end
|
42
26
|
end
|
43
27
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative '../util/java'
|
2
|
+
require_relative '../util/which'
|
2
3
|
|
3
4
|
module Asciidoctor
|
4
5
|
module Diagram
|
@@ -8,10 +9,10 @@ module Asciidoctor
|
|
8
9
|
PLANTUML_JAR_PATH = File.expand_path File.join('../..', 'plantuml.jar'), File.dirname(__FILE__)
|
9
10
|
Java.classpath << PLANTUML_JAR_PATH
|
10
11
|
|
11
|
-
def plantuml(parent, code, tag, *flags)
|
12
|
+
def self.plantuml(parent, code, tag, *flags)
|
12
13
|
unless @graphvizdot
|
13
14
|
@graphvizdot = parent.document.attributes['graphvizdot']
|
14
|
-
@graphvizdot = which('dot') unless @graphvizdot && File.executable?(@graphvizdot)
|
15
|
+
@graphvizdot = ::Asciidoctor::Diagram.which('dot') unless @graphvizdot && File.executable?(@graphvizdot)
|
15
16
|
raise "Could not find the Graphviz 'dot' executable in PATH; add it to the PATH or specify its location using the 'graphvizdot' document attribute" unless @graphvizdot
|
16
17
|
end
|
17
18
|
|
@@ -25,31 +26,21 @@ module Asciidoctor
|
|
25
26
|
if config_file
|
26
27
|
flags += ['-config', File.expand_path(config_file, parent.document.attributes['docdir'])]
|
27
28
|
end
|
28
|
-
|
29
|
-
option = Java.net.sourceforge.plantuml.Option.
|
30
|
-
source_reader = Java.net.sourceforge.plantuml.SourceStringReader
|
31
|
-
|
32
|
-
|
33
|
-
|
29
|
+
|
30
|
+
option = Java.new_object( Java.net.sourceforge.plantuml.Option, '[Ljava.lang.String;', Java.array_to_java_array(flags, :string) )
|
31
|
+
source_reader = Java.new_object( Java.net.sourceforge.plantuml.SourceStringReader,
|
32
|
+
'Lnet.sourceforge.plantuml.preproc.Defines;Ljava.lang.String;Ljava.util.List;',
|
33
|
+
Java.new_object( Java.net.sourceforge.plantuml.preproc.Defines ),
|
34
|
+
code,
|
35
|
+
option.getConfig()
|
34
36
|
)
|
35
37
|
|
36
|
-
bos = Java.java.io.ByteArrayOutputStream
|
37
|
-
ps = Java.java.io.PrintStream.
|
38
|
+
bos = Java.new_object( Java.java.io.ByteArrayOutputStream )
|
39
|
+
ps = Java.new_object( Java.java.io.PrintStream, 'Ljava.io.OutputStream;', bos )
|
38
40
|
source_reader.generateImage(ps, 0, option.getFileFormatOption())
|
39
41
|
ps.close
|
40
42
|
Java.string_from_java_bytes(bos.toByteArray)
|
41
43
|
end
|
42
|
-
|
43
|
-
def which(cmd)
|
44
|
-
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
45
|
-
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
46
|
-
exts.each { |ext|
|
47
|
-
exe = File.join(path, "#{cmd}#{ext}")
|
48
|
-
return exe if File.executable? exe
|
49
|
-
}
|
50
|
-
end
|
51
|
-
nil
|
52
|
-
end
|
53
44
|
end
|
54
45
|
end
|
55
46
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require_relative '../util/cli_generator'
|
2
|
+
require_relative '../util/diagram'
|
3
|
+
|
4
|
+
module Asciidoctor
|
5
|
+
module Diagram
|
6
|
+
define_processors('Shaape') do
|
7
|
+
[:png, :svg].each do |f|
|
8
|
+
register_format(f, :image) do |c, p|
|
9
|
+
CliGenerator.generate('shaape', p, c) do |tool_path, output_path|
|
10
|
+
[tool_path, '-o', output_path, '-t', f.to_s, '-']
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
|
3
|
+
require_relative '../util/java'
|
4
|
+
require_relative '../util/which'
|
5
|
+
|
6
|
+
module Asciidoctor
|
7
|
+
module Diagram
|
8
|
+
module CliGenerator
|
9
|
+
def self.generate(tool, parent, code)
|
10
|
+
tool_var = '@' + tool
|
11
|
+
|
12
|
+
tool_path = instance_variable_get(tool_var)
|
13
|
+
unless tool_path
|
14
|
+
tool_path = parent.document.attributes[tool]
|
15
|
+
tool_path = ::Asciidoctor::Diagram.which(tool) unless tool_path && File.executable?(tool_path)
|
16
|
+
raise "Could not find the '#{tool}' executable in PATH; add it to the PATH or specify its location using the 'shaape' document attribute" unless tool_path
|
17
|
+
instance_variable_set(tool_var, tool_path)
|
18
|
+
end
|
19
|
+
|
20
|
+
target_file = Tempfile.new(tool)
|
21
|
+
begin
|
22
|
+
target_file.close
|
23
|
+
|
24
|
+
args = yield tool_path, target_file.path
|
25
|
+
|
26
|
+
IO.popen(args, "w") do |io|
|
27
|
+
io.write code
|
28
|
+
end
|
29
|
+
result_code = $?
|
30
|
+
|
31
|
+
raise "#{tool} image generation failed" unless result_code == 0
|
32
|
+
|
33
|
+
File.read(target_file.path)
|
34
|
+
ensure
|
35
|
+
target_file.unlink
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -1,75 +1,54 @@
|
|
1
1
|
require 'asciidoctor/extensions'
|
2
2
|
require 'digest'
|
3
3
|
require 'json'
|
4
|
+
require 'fileutils'
|
4
5
|
require_relative 'java'
|
5
6
|
require_relative 'png'
|
6
7
|
require_relative 'svg'
|
7
8
|
|
8
9
|
module Asciidoctor
|
9
10
|
module Diagram
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
:decoder => SVG
|
15
|
-
},
|
16
|
-
:png => {
|
17
|
-
:encoding => Encoding::ASCII_8BIT,
|
18
|
-
:decoder => PNG
|
19
|
-
}
|
20
|
-
}
|
21
|
-
|
22
|
-
def self.included(base)
|
23
|
-
base.option :pos_attrs, ['target', 'format']
|
24
|
-
|
25
|
-
if base.ancestors.include?(Asciidoctor::Extensions::BlockProcessor)
|
26
|
-
base.option :contexts, [:listing, :literal, :open]
|
27
|
-
base.option :content_model, :simple
|
28
|
-
|
29
|
-
base.instance_eval do
|
30
|
-
alias_method :process, :process_block
|
31
|
-
end
|
32
|
-
else
|
33
|
-
base.instance_eval do
|
34
|
-
alias_method :process, :process_macro
|
35
|
-
end
|
11
|
+
def self.define_processors(name, &init)
|
12
|
+
block = Class.new(Asciidoctor::Extensions::BlockProcessor) do
|
13
|
+
class << self
|
14
|
+
include FormatRegistry
|
36
15
|
end
|
16
|
+
include DiagramProcessor
|
37
17
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
source = FileSource.new(File.expand_path(target, parent.document.attributes['docdir']))
|
42
|
-
attributes['target'] ||= File.basename(target, File.extname(target))
|
18
|
+
option :pos_attrs, ['target', 'format']
|
19
|
+
option :contexts, [:listing, :literal, :open]
|
20
|
+
option :content_model, :simple
|
43
21
|
|
44
|
-
|
45
|
-
|
22
|
+
def process(parent, reader, attributes)
|
23
|
+
generate_block(parent, ReaderSource.new(reader), attributes)
|
24
|
+
end
|
46
25
|
|
47
|
-
|
48
|
-
generate_block(parent, ReaderSource.new(reader), attributes)
|
26
|
+
self.instance_eval &init
|
49
27
|
end
|
50
28
|
|
51
|
-
|
52
|
-
|
53
|
-
|
29
|
+
block_macro = Class.new(Asciidoctor::Extensions::BlockMacroProcessor) do
|
30
|
+
class << self
|
31
|
+
include FormatRegistry
|
32
|
+
end
|
33
|
+
include DiagramProcessor
|
54
34
|
|
55
|
-
|
35
|
+
option :pos_attrs, ['target', 'format']
|
56
36
|
|
57
|
-
|
37
|
+
def process(parent, target, attributes)
|
38
|
+
source = FileSource.new(File.expand_path(target, parent.document.attributes['docdir']))
|
39
|
+
attributes['target'] ||= File.basename(target, File.extname(target))
|
58
40
|
|
59
|
-
|
60
|
-
|
61
|
-
case generator_info[:type]
|
62
|
-
when :image
|
63
|
-
create_image_block(parent, source, attributes, format, generator_info)
|
64
|
-
when :literal
|
65
|
-
create_literal_block(parent, source, attributes, generator_info)
|
66
|
-
else
|
67
|
-
raise "Unsupported output format: #{format}"
|
41
|
+
generate_block(parent, source, attributes)
|
68
42
|
end
|
43
|
+
|
44
|
+
self.instance_eval &init
|
69
45
|
end
|
70
46
|
|
71
|
-
|
47
|
+
Asciidoctor::Diagram.const_set("#{name}Block", block)
|
48
|
+
Asciidoctor::Diagram.const_set("#{name}BlockMacro", block_macro)
|
49
|
+
end
|
72
50
|
|
51
|
+
module FormatRegistry
|
73
52
|
#
|
74
53
|
# Registers a supported format. The first registered format becomes the default format for the block processor.
|
75
54
|
#
|
@@ -92,11 +71,50 @@ module Asciidoctor
|
|
92
71
|
@formats ||= {}
|
93
72
|
end
|
94
73
|
|
74
|
+
def default_format
|
75
|
+
@default_format
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
module DiagramProcessor
|
80
|
+
IMAGE_PARAMS = {
|
81
|
+
:svg => {
|
82
|
+
:encoding => Encoding::UTF_8,
|
83
|
+
:decoder => SVG
|
84
|
+
},
|
85
|
+
:png => {
|
86
|
+
:encoding => Encoding::ASCII_8BIT,
|
87
|
+
:decoder => PNG
|
88
|
+
}
|
89
|
+
}
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def generate_block(parent, source, attributes)
|
94
|
+
format = attributes.delete('format') || self.class.default_format
|
95
|
+
format = format.to_sym if format.respond_to?(:to_sym)
|
96
|
+
|
97
|
+
raise "Format undefined" unless format
|
98
|
+
|
99
|
+
generator_info = self.class.formats[format]
|
100
|
+
|
101
|
+
raise "#{self.class.name} does not support output format #{format}" unless generator_info
|
102
|
+
|
103
|
+
case generator_info[:type]
|
104
|
+
when :image
|
105
|
+
create_image_block(parent, source, attributes, format, generator_info)
|
106
|
+
when :literal
|
107
|
+
create_literal_block(parent, source, attributes, generator_info)
|
108
|
+
else
|
109
|
+
raise "Unsupported output format: #{format}"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
95
113
|
def create_image_block(parent, source, attributes, format, generator_info)
|
96
114
|
target = attributes.delete('target')
|
97
115
|
|
98
116
|
image_name = "#{target || ('diag-' + source.checksum)}.#{format}"
|
99
|
-
image_dir = File.expand_path(parent.document.attributes['imagesdir'] || '', parent.document.attributes['docdir'])
|
117
|
+
image_dir = File.expand_path(parent.document.attributes['imagesdir'] || '', parent.document.attributes['outdir'] || parent.document.attributes['docdir'])
|
100
118
|
image_file = File.expand_path(image_name, image_dir)
|
101
119
|
metadata_file = File.expand_path("#{image_name}.cache", image_dir)
|
102
120
|
|
@@ -116,14 +134,17 @@ module Asciidoctor
|
|
116
134
|
metadata = {'checksum' => source.checksum}
|
117
135
|
metadata['width'], metadata['height'] = params[:decoder].get_image_size(result)
|
118
136
|
|
137
|
+
FileUtils.mkdir_p(image_dir) unless Dir.exists?(image_dir)
|
119
138
|
File.open(image_file, 'wb') { |f| f.write result }
|
120
139
|
File.open(metadata_file, 'w') { |f| JSON.dump(metadata, f) }
|
121
140
|
end
|
122
141
|
|
123
142
|
attributes['target'] = image_name
|
124
|
-
|
125
|
-
|
126
|
-
|
143
|
+
if /html/i =~ parent.document.attributes['backend']
|
144
|
+
attributes['width'] ||= metadata['width'] if metadata['width']
|
145
|
+
attributes['height'] ||= metadata['height'] if metadata['height']
|
146
|
+
end
|
147
|
+
attributes['alt'] ||= if title_text = attributes['title']
|
127
148
|
title_text
|
128
149
|
elsif target
|
129
150
|
(File.basename target, (File.extname target) || '').tr '_-', ' '
|
@@ -77,6 +77,14 @@ module Asciidoctor
|
|
77
77
|
@root_package ||= Package.send(:create_package, nil)
|
78
78
|
@root_package.send(meth, *args)
|
79
79
|
end
|
80
|
+
|
81
|
+
def self.new_object(java_class, signature = nil, *args)
|
82
|
+
if signature
|
83
|
+
java_class.new_with_sig(signature, *args)
|
84
|
+
else
|
85
|
+
java_class.new(*args)
|
86
|
+
end
|
87
|
+
end
|
80
88
|
end
|
81
89
|
end
|
82
90
|
end
|
@@ -4,34 +4,30 @@ module Asciidoctor
|
|
4
4
|
module Diagram
|
5
5
|
module SVG
|
6
6
|
def self.get_image_size(data)
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
if m = START_TAG_REGEX.match(data)
|
8
|
+
start_tag = m[0]
|
9
|
+
if (w = WIDTH_REGEX.match(start_tag)) && (h = HEIGHT_REGEX.match(start_tag))
|
10
|
+
width = w[:value].to_i * to_px_factor(w[:unit])
|
11
|
+
height = h[:value].to_i * to_px_factor(h[:unit])
|
12
|
+
return [width.to_i, height.to_i]
|
13
|
+
end
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
nil
|
15
|
+
if v = VIEWBOX_REGEX.match(start_tag)
|
16
|
+
width = v[:width]
|
17
|
+
height = v[:height]
|
18
|
+
return [width.to_i, height.to_i]
|
19
|
+
end
|
20
20
|
end
|
21
|
+
|
22
|
+
nil
|
21
23
|
end
|
22
24
|
|
23
|
-
|
25
|
+
private
|
24
26
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
height = match_data[:height].to_i * to_px_factor(match_data[:height_unit])
|
30
|
-
[width.to_i, height.to_i]
|
31
|
-
else
|
32
|
-
nil
|
33
|
-
end
|
34
|
-
end
|
27
|
+
START_TAG_REGEX = /<svg[^>]*>/
|
28
|
+
WIDTH_REGEX = /width="(?<value>\d+)(?<unit>[a-zA-Z]+)"/
|
29
|
+
HEIGHT_REGEX = /height="(?<value>\d+)(?<unit>[a-zA-Z]+)"/
|
30
|
+
VIEWBOX_REGEX = /viewBox="\d+ \d+ (?<width>\d+) (?<height>\d+)"/
|
35
31
|
|
36
32
|
def self.to_px_factor(unit)
|
37
33
|
case unit
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Asciidoctor
|
2
|
+
module Diagram
|
3
|
+
def self.which(cmd)
|
4
|
+
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
5
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
6
|
+
exts.each { |ext|
|
7
|
+
exe = File.join(path, "#{cmd}#{ext}")
|
8
|
+
return exe if File.executable? exe
|
9
|
+
}
|
10
|
+
end
|
11
|
+
nil
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|