asciidoctor-kroki 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +10 -1
- data/Gemfile.lock +2 -2
- data/asciidoctor-kroki.gemspec +1 -1
- data/lib/asciidoctor/extensions/asciidoctor_kroki/extension.rb +86 -26
- data/spec/asciidoctor_kroki_block_macro_spec.rb +128 -0
- data/spec/asciidoctor_kroki_client_spec.rb +68 -0
- data/spec/asciidoctor_kroki_spec.rb +61 -6
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dfa0c461bdb74571b618747d791e059125dc09a5e67dd6886861101fe972237f
|
4
|
+
data.tar.gz: d882ff8e33c787b3a1578eb7d11b590411e18f594eaec188d7f06ffc182a3b11
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f72b7293f3fb8c6d37b456c39d4e2691c0b65e1cb908d5f3f29d23466f0c51135b9977dd0977a2ccac7adb667b4fc5071a4a5fc59bed6a3304154bddc8efda3d
|
7
|
+
data.tar.gz: 1e93fbf9df1cab9282f7743f76331ea6caddfdce150fff36fb7aa7222d561d089c31101ec0f16a939f5aa2c0c7dd5a09206059700974b76ae6fadcfc0150acd3
|
data/.rubocop.yml
CHANGED
@@ -1,8 +1,14 @@
|
|
1
1
|
Style/Encoding:
|
2
2
|
Enabled: false
|
3
3
|
|
4
|
+
Layout/EndOfLine:
|
5
|
+
EnforcedStyle: lf
|
6
|
+
|
4
7
|
Metrics/LineLength:
|
5
|
-
Max:
|
8
|
+
Max: 180
|
9
|
+
|
10
|
+
Metrics/ClassLength:
|
11
|
+
Max: 150
|
6
12
|
|
7
13
|
Metrics/MethodLength:
|
8
14
|
Max: 50
|
@@ -15,3 +21,6 @@ Metrics/PerceivedComplexity:
|
|
15
21
|
|
16
22
|
Metrics/AbcSize:
|
17
23
|
Max: 30
|
24
|
+
|
25
|
+
Metrics/ParameterLists:
|
26
|
+
Max: 7
|
data/Gemfile.lock
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
asciidoctor-kroki (0.
|
4
|
+
asciidoctor-kroki (0.4.0)
|
5
5
|
asciidoctor (~> 2.0)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
asciidoctor (2.0.
|
10
|
+
asciidoctor (2.0.11)
|
11
11
|
ast (2.4.1)
|
12
12
|
diff-lcs (1.3)
|
13
13
|
jaro_winkler (1.5.4)
|
data/asciidoctor-kroki.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = 'asciidoctor-kroki'
|
5
|
-
s.version = '0.
|
5
|
+
s.version = '0.4.0'
|
6
6
|
s.summary = 'Asciidoctor extension to convert diagrams to images using Kroki'
|
7
7
|
s.description = 'An extension for Asciidoctor to convert diagrams to images using https://kroki.io'
|
8
8
|
|
@@ -15,11 +15,24 @@ module AsciidoctorExtensions
|
|
15
15
|
on_context :listing, :literal
|
16
16
|
name_positional_attributes 'target', 'format'
|
17
17
|
|
18
|
+
# @param name [String] name of the block macro (optional)
|
19
|
+
# @param config [Hash] a config hash (optional)
|
20
|
+
# @param logger [Logger] a logger used to log warning and errors (optional)
|
21
|
+
#
|
22
|
+
def initialize(name = nil, config = {}, logger: ::Asciidoctor::LoggerManager.logger)
|
23
|
+
super(name, config)
|
24
|
+
@logger = logger
|
25
|
+
end
|
26
|
+
|
18
27
|
def process(parent, reader, attrs)
|
19
28
|
diagram_type = @name
|
20
29
|
diagram_text = reader.string
|
21
|
-
KrokiProcessor.process(self, parent, attrs, diagram_type, diagram_text)
|
30
|
+
KrokiProcessor.process(self, parent, attrs, diagram_type, diagram_text, @logger)
|
22
31
|
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
|
35
|
+
attr_reader :logger
|
23
36
|
end
|
24
37
|
|
25
38
|
# A block macro extension that converts a diagram into an image.
|
@@ -29,11 +42,48 @@ module AsciidoctorExtensions
|
|
29
42
|
|
30
43
|
name_positional_attributes 'format'
|
31
44
|
|
45
|
+
# @param name [String] name of the block macro (optional)
|
46
|
+
# @param config [Hash] a config hash (optional)
|
47
|
+
# @param logger [Logger] a logger used to log warning and errors (optional)
|
48
|
+
#
|
49
|
+
def initialize(name = nil, config = {}, logger: ::Asciidoctor::LoggerManager.logger)
|
50
|
+
super(name, config)
|
51
|
+
@logger = logger
|
52
|
+
end
|
53
|
+
|
32
54
|
def process(parent, target, attrs)
|
33
55
|
diagram_type = @name
|
34
56
|
target = parent.apply_subs(target, [:attributes])
|
35
|
-
|
36
|
-
|
57
|
+
|
58
|
+
unless read_allowed?(target)
|
59
|
+
link = create_inline(parent, :anchor, target, type: :link, target: target)
|
60
|
+
return create_block(parent, :paragraph, link.convert, {}, content_model: :raw)
|
61
|
+
end
|
62
|
+
|
63
|
+
unless (path = resolve_target_path(target))
|
64
|
+
logger.error "#{diagram_type} block macro not found: #{target}."
|
65
|
+
create_block(parent, 'paragraph', unresolved_block_macro_message(diagram_type, target), {})
|
66
|
+
end
|
67
|
+
|
68
|
+
begin
|
69
|
+
diagram_text = read(path)
|
70
|
+
rescue => e # rubocop:disable RescueStandardError
|
71
|
+
logger.error "Failed to read #{diagram_type} file: #{path}. #{e}."
|
72
|
+
return create_block(parent, 'paragraph', unresolved_block_macro_message(diagram_type, path), {})
|
73
|
+
end
|
74
|
+
KrokiProcessor.process(self, parent, attrs, diagram_type, diagram_text, @logger)
|
75
|
+
end
|
76
|
+
|
77
|
+
protected
|
78
|
+
|
79
|
+
attr_reader :logger
|
80
|
+
|
81
|
+
def resolve_target_path(target)
|
82
|
+
target
|
83
|
+
end
|
84
|
+
|
85
|
+
def read_allowed?(_target)
|
86
|
+
true
|
37
87
|
end
|
38
88
|
|
39
89
|
def read(target)
|
@@ -44,6 +94,10 @@ module AsciidoctorExtensions
|
|
44
94
|
File.open(target, &:read)
|
45
95
|
end
|
46
96
|
end
|
97
|
+
|
98
|
+
def unresolved_block_macro_message(name, target)
|
99
|
+
"Unresolved block macro - #{name}::#{target}[]"
|
100
|
+
end
|
47
101
|
end
|
48
102
|
|
49
103
|
# Kroki API
|
@@ -70,7 +124,7 @@ module AsciidoctorExtensions
|
|
70
124
|
umlet
|
71
125
|
vega
|
72
126
|
vegalite
|
73
|
-
|
127
|
+
wavedrom
|
74
128
|
].freeze
|
75
129
|
end
|
76
130
|
|
@@ -80,9 +134,9 @@ module AsciidoctorExtensions
|
|
80
134
|
TEXT_FORMATS = %w[txt atxt utxt].freeze
|
81
135
|
|
82
136
|
class << self
|
83
|
-
def process(processor, parent, attrs, diagram_type, diagram_text)
|
137
|
+
def process(processor, parent, attrs, diagram_type, diagram_text, logger)
|
84
138
|
doc = parent.document
|
85
|
-
diagram_text = prepend_plantuml_config(diagram_text, diagram_type, doc)
|
139
|
+
diagram_text = prepend_plantuml_config(diagram_text, diagram_type, doc, logger)
|
86
140
|
# If "subs" attribute is specified, substitute accordingly.
|
87
141
|
# Be careful not to specify "specialcharacters" or your diagram code won't be valid anymore!
|
88
142
|
if (subs = attrs['subs'])
|
@@ -96,7 +150,7 @@ module AsciidoctorExtensions
|
|
96
150
|
attrs['role'] = get_role(format, role)
|
97
151
|
attrs['format'] = format
|
98
152
|
kroki_diagram = KrokiDiagram.new(diagram_type, format, diagram_text)
|
99
|
-
kroki_client = KrokiClient.new(server_url(doc), http_method(doc), KrokiHttpClient)
|
153
|
+
kroki_client = KrokiClient.new(server_url(doc), http_method(doc), KrokiHttpClient, logger, max_uri_length(doc))
|
100
154
|
if TEXT_FORMATS.include?(format)
|
101
155
|
text_content = kroki_client.text_content(kroki_diagram)
|
102
156
|
block = processor.create_block(parent, 'literal', text_content, attrs)
|
@@ -112,12 +166,17 @@ module AsciidoctorExtensions
|
|
112
166
|
|
113
167
|
private
|
114
168
|
|
115
|
-
def prepend_plantuml_config(diagram_text, diagram_type, doc)
|
116
|
-
if diagram_type == :plantuml && doc.attr?('kroki-plantuml-include')
|
117
|
-
#
|
118
|
-
#
|
119
|
-
|
120
|
-
|
169
|
+
def prepend_plantuml_config(diagram_text, diagram_type, doc, logger)
|
170
|
+
if diagram_type == :plantuml && doc.safe < ::Asciidoctor::SafeMode::SECURE && doc.attr?('kroki-plantuml-include')
|
171
|
+
# REMIND: this behaves different than the JS version
|
172
|
+
# Once we have a preprocessor for Ruby, the value should be added in the diagram source as "!include #{plantuml_include}"
|
173
|
+
plantuml_include_path = doc.normalize_system_path(doc.attr('kroki-plantuml-include'))
|
174
|
+
if ::File.readable? plantuml_include_path
|
175
|
+
config = File.read(plantuml_include_path)
|
176
|
+
diagram_text = config + "\n" + diagram_text
|
177
|
+
else
|
178
|
+
logger.warn "Unable to read plantuml-include. File not found or not readable: #{plantuml_include_path}."
|
179
|
+
end
|
121
180
|
end
|
122
181
|
diagram_text
|
123
182
|
end
|
@@ -157,7 +216,7 @@ module AsciidoctorExtensions
|
|
157
216
|
end
|
158
217
|
|
159
218
|
def create_image_src(doc, kroki_diagram, kroki_client)
|
160
|
-
if doc.attr('kroki-fetch-diagram')
|
219
|
+
if doc.attr('kroki-fetch-diagram') && doc.safe < ::Asciidoctor::SafeMode::SECURE
|
161
220
|
kroki_diagram.save(output_dir_path(doc), kroki_client)
|
162
221
|
else
|
163
222
|
kroki_diagram.get_diagram_uri(server_url(doc))
|
@@ -172,20 +231,20 @@ module AsciidoctorExtensions
|
|
172
231
|
doc.attr('kroki-http-method', 'adaptive').downcase
|
173
232
|
end
|
174
233
|
|
234
|
+
def max_uri_length(doc)
|
235
|
+
doc.attr('kroki-max-uri-length', '4000').to_i
|
236
|
+
end
|
237
|
+
|
175
238
|
def output_dir_path(doc)
|
176
|
-
images_output_dir = doc.attr('imagesoutdir')
|
177
|
-
out_dir = doc.attr('outdir')
|
178
|
-
to_dir = doc.attr('to_dir')
|
179
|
-
base_dir = doc.base_dir
|
180
239
|
images_dir = doc.attr('imagesdir', '')
|
181
|
-
if images_output_dir
|
240
|
+
if (images_output_dir = doc.attr('imagesoutdir'))
|
182
241
|
images_output_dir
|
183
|
-
elsif out_dir
|
242
|
+
elsif (out_dir = doc.attr('outdir'))
|
184
243
|
File.join(out_dir, images_dir)
|
185
|
-
elsif to_dir
|
244
|
+
elsif (to_dir = doc.attr('to_dir'))
|
186
245
|
File.join(to_dir, images_dir)
|
187
246
|
else
|
188
|
-
File.join(base_dir, images_dir)
|
247
|
+
File.join(doc.base_dir, images_dir)
|
189
248
|
end
|
190
249
|
end
|
191
250
|
end
|
@@ -259,18 +318,19 @@ module AsciidoctorExtensions
|
|
259
318
|
class KrokiClient
|
260
319
|
attr_reader :server_url
|
261
320
|
attr_reader :method
|
321
|
+
attr_reader :max_uri_length
|
262
322
|
|
263
323
|
SUPPORTED_HTTP_METHODS = %w[get post adaptive].freeze
|
264
324
|
|
265
|
-
def initialize(server_url, http_method, http_client)
|
325
|
+
def initialize(server_url, http_method, http_client, logger = ::Asciidoctor::LoggerManager.logger, max_uri_length = 4000)
|
266
326
|
@server_url = server_url
|
267
|
-
@max_uri_length =
|
327
|
+
@max_uri_length = max_uri_length
|
268
328
|
@http_client = http_client
|
269
329
|
method = (http_method || 'adaptive').downcase
|
270
330
|
if SUPPORTED_HTTP_METHODS.include?(method)
|
271
331
|
@method = method
|
272
332
|
else
|
273
|
-
|
333
|
+
logger.warn "Invalid value '#{method}' for kroki-http-method attribute. The value must be either: 'get', 'post' or 'adaptive'. Proceeding using: 'adaptive'."
|
274
334
|
@method = 'adaptive'
|
275
335
|
end
|
276
336
|
end
|
@@ -286,7 +346,7 @@ module AsciidoctorExtensions
|
|
286
346
|
if @method == 'adaptive' || @method == 'get'
|
287
347
|
uri = kroki_diagram.get_diagram_uri(server_url)
|
288
348
|
if uri.length > @max_uri_length
|
289
|
-
# The request URI is longer than
|
349
|
+
# The request URI is longer than the max URI length.
|
290
350
|
if @method == 'get'
|
291
351
|
# The request might be rejected by the server with a 414 Request-URI Too Large.
|
292
352
|
# Consider using the attribute kroki-http-method with the value 'adaptive'.
|
@@ -0,0 +1,128 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rspec_helper'
|
4
|
+
require 'asciidoctor'
|
5
|
+
require_relative '../lib/asciidoctor/extensions/asciidoctor_kroki'
|
6
|
+
require_relative '../lib/asciidoctor/extensions/asciidoctor_kroki/extension'
|
7
|
+
|
8
|
+
describe ::AsciidoctorExtensions::KrokiBlockMacroProcessor do
|
9
|
+
context 'convert to html5' do
|
10
|
+
it 'should catch exception if target is not readable' do
|
11
|
+
input = <<~'ADOC'
|
12
|
+
plantuml::spec/fixtures/missing.puml[svg,role=sequence]
|
13
|
+
ADOC
|
14
|
+
output = Asciidoctor.convert(input, standalone: false)
|
15
|
+
(expect output).to eql %(<div class="paragraph">
|
16
|
+
<p>Unresolved block macro - plantuml::spec/fixtures/missing.puml[]</p>
|
17
|
+
</div>)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
context 'using a custom block macro' do
|
21
|
+
it 'should disallow read' do
|
22
|
+
# noinspection RubyClassModuleNamingConvention
|
23
|
+
class DisallowReadKrokiBlockMacroProcessor < ::AsciidoctorExtensions::KrokiBlockMacroProcessor
|
24
|
+
def read_allowed?(_target)
|
25
|
+
false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
registry = Asciidoctor::Extensions.create do
|
29
|
+
block_macro DisallowReadKrokiBlockMacroProcessor, 'plantuml'
|
30
|
+
end
|
31
|
+
input = <<~'ADOC'
|
32
|
+
plantuml::spec/fixtures/alice.puml[svg,role=sequence]
|
33
|
+
ADOC
|
34
|
+
output = Asciidoctor.convert(input, standalone: false, extension_registry: registry)
|
35
|
+
(expect output).to eql %(<div class="paragraph">
|
36
|
+
<p><a href="spec/fixtures/alice.puml">spec/fixtures/alice.puml</a></p>
|
37
|
+
</div>)
|
38
|
+
end
|
39
|
+
it 'should allow read if target is not a URI' do
|
40
|
+
# noinspection RubyClassModuleNamingConvention
|
41
|
+
class DisallowUriReadKrokiBlockMacroProcessor < ::AsciidoctorExtensions::KrokiBlockMacroProcessor
|
42
|
+
def read_allowed?(target)
|
43
|
+
return false if ::Asciidoctor::Helpers.uriish?(target)
|
44
|
+
|
45
|
+
true
|
46
|
+
end
|
47
|
+
end
|
48
|
+
registry = Asciidoctor::Extensions.create do
|
49
|
+
block_macro DisallowUriReadKrokiBlockMacroProcessor, 'plantuml'
|
50
|
+
end
|
51
|
+
input = <<~'ADOC'
|
52
|
+
plantuml::https://domain.org/alice.puml[svg,role=sequence]
|
53
|
+
|
54
|
+
plantuml::file://path/to/alice.puml[svg,role=sequence]
|
55
|
+
|
56
|
+
plantuml::spec/fixtures/alice.puml[svg,role=sequence]
|
57
|
+
ADOC
|
58
|
+
output = Asciidoctor.convert(input, standalone: false, extension_registry: registry)
|
59
|
+
(expect output).to eql %(<div class="paragraph">
|
60
|
+
<p><a href="https://domain.org/alice.puml">https://domain.org/alice.puml</a></p>
|
61
|
+
</div>
|
62
|
+
<div class="paragraph">
|
63
|
+
<p><a href="file://path/to/alice.puml">file://path/to/alice.puml</a></p>
|
64
|
+
</div>
|
65
|
+
<div class="imageblock sequence kroki-format-svg kroki">
|
66
|
+
<div class="content">
|
67
|
+
<img src="https://kroki.io/plantuml/svg/eNpLzMlMTlXQtVNIyk-yUshIzcnJ5wIAQ-AGVQ==" alt="Diagram">
|
68
|
+
</div>
|
69
|
+
</div>)
|
70
|
+
end
|
71
|
+
it 'should override the resolve target method' do
|
72
|
+
# noinspection RubyClassModuleNamingConvention
|
73
|
+
class FixtureResolveTargetKrokiBlockMacroProcessor < ::AsciidoctorExtensions::KrokiBlockMacroProcessor
|
74
|
+
def resolve_target_path(target)
|
75
|
+
"spec/fixtures/#{target}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
registry = Asciidoctor::Extensions.create do
|
79
|
+
block_macro FixtureResolveTargetKrokiBlockMacroProcessor, 'plantuml'
|
80
|
+
end
|
81
|
+
input = <<~'ADOC'
|
82
|
+
plantuml::alice.puml[svg,role=sequence]
|
83
|
+
ADOC
|
84
|
+
output = Asciidoctor.convert(input, standalone: false, extension_registry: registry)
|
85
|
+
(expect output).to eql %(<div class="imageblock sequence kroki-format-svg kroki">
|
86
|
+
<div class="content">
|
87
|
+
<img src="https://kroki.io/plantuml/svg/eNpLzMlMTlXQtVNIyk-yUshIzcnJ5wIAQ-AGVQ==" alt="Diagram">
|
88
|
+
</div>
|
89
|
+
</div>)
|
90
|
+
end
|
91
|
+
it 'should display unresolved block macro message when the traget cannot be resolved' do
|
92
|
+
# noinspection RubyClassModuleNamingConvention
|
93
|
+
class UnresolvedTargetKrokiBlockMacroProcessor < ::AsciidoctorExtensions::KrokiBlockMacroProcessor
|
94
|
+
def resolve_target_path(_target)
|
95
|
+
nil
|
96
|
+
end
|
97
|
+
end
|
98
|
+
registry = Asciidoctor::Extensions.create do
|
99
|
+
block_macro UnresolvedTargetKrokiBlockMacroProcessor, 'plantuml'
|
100
|
+
end
|
101
|
+
input = <<~'ADOC'
|
102
|
+
plantuml::alice.puml[svg,role=sequence]
|
103
|
+
ADOC
|
104
|
+
output = Asciidoctor.convert(input, standalone: false, extension_registry: registry)
|
105
|
+
(expect output).to eql %(<div class="paragraph">
|
106
|
+
<p>Unresolved block macro - plantuml::[]</p>
|
107
|
+
</div>)
|
108
|
+
end
|
109
|
+
it 'should override the unresolved block macro message' do
|
110
|
+
# noinspection RubyClassModuleNamingConvention
|
111
|
+
class CustomUnresolvedTargetMessageKrokiBlockMacroProcessor < ::AsciidoctorExtensions::KrokiBlockMacroProcessor
|
112
|
+
def unresolved_block_macro_message(name, target)
|
113
|
+
"*[ERROR: #{name}::#{target}[] - unresolved block macro]*"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
registry = Asciidoctor::Extensions.create do
|
117
|
+
block_macro CustomUnresolvedTargetMessageKrokiBlockMacroProcessor, 'plantuml'
|
118
|
+
end
|
119
|
+
input = <<~'ADOC'
|
120
|
+
plantuml::spec/fixtures/missing.puml[svg,role=sequence]
|
121
|
+
ADOC
|
122
|
+
output = Asciidoctor.convert(input, standalone: false, extension_registry: registry)
|
123
|
+
(expect output).to eql %(<div class="paragraph">
|
124
|
+
<p><strong>[ERROR: plantuml::spec/fixtures/missing.puml[] - unresolved block macro]</strong></p>
|
125
|
+
</div>)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -20,4 +20,72 @@ describe ::AsciidoctorExtensions::KrokiClient do
|
|
20
20
|
kroki_client = ::AsciidoctorExtensions::KrokiClient.new('http://localhost:8000', 'get', kroki_http_client)
|
21
21
|
expect(kroki_client.method).to eq('get')
|
22
22
|
end
|
23
|
+
it 'should use 4000 as the default max URI length' do
|
24
|
+
kroki_http_client = ::AsciidoctorExtensions::KrokiHttpClient
|
25
|
+
kroki_client = ::AsciidoctorExtensions::KrokiClient.new('http://localhost:8000', 'get', kroki_http_client)
|
26
|
+
expect(kroki_client.max_uri_length).to eq(4000)
|
27
|
+
end
|
28
|
+
it 'should use a custom value as max URI length' do
|
29
|
+
kroki_http_client = ::AsciidoctorExtensions::KrokiHttpClient
|
30
|
+
kroki_client = ::AsciidoctorExtensions::KrokiClient.new('http://localhost:8000', 'get', kroki_http_client, nil, 8000)
|
31
|
+
expect(kroki_client.max_uri_length).to eq(8000)
|
32
|
+
end
|
33
|
+
it 'should get an image with POST request if the URI length is greater than the value configured' do
|
34
|
+
kroki_http_client = Class.new do
|
35
|
+
class << self
|
36
|
+
def get(uri, _)
|
37
|
+
"GET #{uri}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def post(uri, data, _)
|
41
|
+
"POST #{uri} - #{data}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
kroki_diagram = Class.new do
|
46
|
+
attr_reader :type, :text, :format
|
47
|
+
|
48
|
+
def initialize(type, format, text)
|
49
|
+
@text = text
|
50
|
+
@type = type
|
51
|
+
@format = format
|
52
|
+
end
|
53
|
+
|
54
|
+
def get_diagram_uri(_)
|
55
|
+
'diagram-uri'
|
56
|
+
end
|
57
|
+
end.new('type', 'format', 'text')
|
58
|
+
kroki_client = ::AsciidoctorExtensions::KrokiClient.new('http://localhost:8000', 'adaptive', kroki_http_client, nil, 10)
|
59
|
+
result = kroki_client.get_image(kroki_diagram, 'utf8')
|
60
|
+
expect(result).to eq('POST http://localhost:8000/type/format - text')
|
61
|
+
end
|
62
|
+
it 'should get an image with GET request if the URI length is lower or equals than the value configured' do
|
63
|
+
kroki_http_client = Class.new do
|
64
|
+
class << self
|
65
|
+
def get(uri, _)
|
66
|
+
"GET #{uri}"
|
67
|
+
end
|
68
|
+
|
69
|
+
def post(uri, data, _)
|
70
|
+
"POST #{uri} - #{data}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
kroki_diagram = Class.new do
|
75
|
+
attr_reader :type, :text, :format
|
76
|
+
|
77
|
+
def initialize(type, format, text)
|
78
|
+
@text = text
|
79
|
+
@type = type
|
80
|
+
@format = format
|
81
|
+
end
|
82
|
+
|
83
|
+
def get_diagram_uri(_)
|
84
|
+
'diagram-uri'
|
85
|
+
end
|
86
|
+
end.new('type', 'format', 'text')
|
87
|
+
kroki_client = ::AsciidoctorExtensions::KrokiClient.new('http://localhost:8000', 'adaptive', kroki_http_client, nil, 11)
|
88
|
+
result = kroki_client.get_image(kroki_diagram, 'utf8')
|
89
|
+
expect(result).to eq('GET diagram-uri')
|
90
|
+
end
|
23
91
|
end
|
@@ -34,17 +34,59 @@ describe ::AsciidoctorExtensions::KrokiBlockProcessor do
|
|
34
34
|
</div>
|
35
35
|
</div>)
|
36
36
|
end
|
37
|
-
it 'should include the plantuml-include file' do
|
37
|
+
it 'should include the plantuml-include file when safe mode is safe' do
|
38
38
|
input = <<~'ADOC'
|
39
39
|
[plantuml]
|
40
40
|
....
|
41
41
|
alice -> bob: hello
|
42
42
|
....
|
43
43
|
ADOC
|
44
|
-
output = Asciidoctor.convert(input, attributes: { 'env-idea' => '', 'kroki-plantuml-include' => 'spec/fixtures/config.puml' }, standalone: false)
|
44
|
+
output = Asciidoctor.convert(input, attributes: { 'env-idea' => '', 'kroki-plantuml-include' => 'spec/fixtures/config.puml' }, standalone: false, safe: :safe)
|
45
45
|
(expect output).to eql %(<div class="imageblock kroki">
|
46
46
|
<div class="content">
|
47
|
-
<img src="https://kroki.io/plantuml/png/
|
47
|
+
<img src="https://kroki.io/plantuml/png/eNorzs7MK0gsSsxVyM3Py0_OKMrPTVUoKSpN5eJKzMlMTlXQtVNIyk-yUshIzcnJBwCT9xBc" alt="Diagram">
|
48
|
+
</div>
|
49
|
+
</div>)
|
50
|
+
end
|
51
|
+
it 'should normalize plantuml-include path when safe mode is safe' do
|
52
|
+
input = <<~'ADOC'
|
53
|
+
[plantuml]
|
54
|
+
....
|
55
|
+
alice -> bob: hello
|
56
|
+
....
|
57
|
+
ADOC
|
58
|
+
output = Asciidoctor.convert(input, attributes: { 'env-idea' => '', 'kroki-plantuml-include' => '../../../spec/fixtures/config.puml' }, standalone: false, safe: :safe)
|
59
|
+
(expect output).to eql %(<div class="imageblock kroki">
|
60
|
+
<div class="content">
|
61
|
+
<img src="https://kroki.io/plantuml/png/eNorzs7MK0gsSsxVyM3Py0_OKMrPTVUoKSpN5eJKzMlMTlXQtVNIyk-yUshIzcnJBwCT9xBc" alt="Diagram">
|
62
|
+
</div>
|
63
|
+
</div>)
|
64
|
+
end
|
65
|
+
it 'should not include file which reside outside of the parent directory of the source when safe mode is safe' do
|
66
|
+
input = <<~'ADOC'
|
67
|
+
[plantuml]
|
68
|
+
....
|
69
|
+
alice -> bob: hello
|
70
|
+
....
|
71
|
+
ADOC
|
72
|
+
output = Asciidoctor.convert(input, attributes: { 'env-idea' => '', 'kroki-plantuml-include' => '/etc/passwd' }, standalone: false, safe: :safe)
|
73
|
+
(expect output).to eql %(<div class="imageblock kroki">
|
74
|
+
<div class="content">
|
75
|
+
<img src="https://kroki.io/plantuml/png/eNpLzMlMTlXQtVNIyk-yUshIzcnJBwA9iwZL" alt="Diagram">
|
76
|
+
</div>
|
77
|
+
</div>)
|
78
|
+
end
|
79
|
+
it 'should not include file when safe mode is secure' do
|
80
|
+
input = <<~'ADOC'
|
81
|
+
[plantuml]
|
82
|
+
....
|
83
|
+
alice -> bob: hello
|
84
|
+
....
|
85
|
+
ADOC
|
86
|
+
output = Asciidoctor.convert(input, attributes: { 'env-idea' => '', 'kroki-plantuml-include' => 'spec/fixtures/config.puml' }, standalone: false, safe: :secure)
|
87
|
+
(expect output).to eql %(<div class="imageblock kroki">
|
88
|
+
<div class="content">
|
89
|
+
<img src="https://kroki.io/plantuml/png/eNpLzMlMTlXQtVNIyk-yUshIzcnJBwA9iwZL" alt="Diagram">
|
48
90
|
</div>
|
49
91
|
</div>)
|
50
92
|
end
|
@@ -54,11 +96,24 @@ describe ::AsciidoctorExtensions::KrokiBlockProcessor do
|
|
54
96
|
|
55
97
|
plantuml::spec/fixtures/alice.puml[svg,role=sequence]
|
56
98
|
ADOC
|
57
|
-
output = Asciidoctor.convert(input, attributes: { 'kroki-fetch-diagram' => '' }, standalone: false)
|
99
|
+
output = Asciidoctor.convert(input, attributes: { 'kroki-fetch-diagram' => '' }, standalone: false, safe: :safe)
|
58
100
|
(expect output).to eql %(<div class="imageblock sequence kroki-format-svg kroki">
|
59
101
|
<div class="content">
|
60
102
|
<img src=".asciidoctor/kroki/diag-f6acdc206506b6ca7badd3fe722f252af992871426e580c8361ff4d47c2c7d9b.svg" alt="Diagram">
|
61
103
|
</div>
|
104
|
+
</div>)
|
105
|
+
end
|
106
|
+
it 'should not fetch diagram when safe mode is secure' do
|
107
|
+
input = <<~'ADOC'
|
108
|
+
:imagesdir: .asciidoctor/kroki
|
109
|
+
|
110
|
+
plantuml::spec/fixtures/alice.puml[svg,role=sequence]
|
111
|
+
ADOC
|
112
|
+
output = Asciidoctor.convert(input, attributes: { 'kroki-fetch-diagram' => '' }, standalone: false)
|
113
|
+
(expect output).to eql %(<div class="imageblock sequence kroki-format-svg kroki">
|
114
|
+
<div class="content">
|
115
|
+
<img src="https://kroki.io/plantuml/svg/eNpLzMlMTlXQtVNIyk-yUshIzcnJ5wIAQ-AGVQ==" alt="Diagram">
|
116
|
+
</div>
|
62
117
|
</div>)
|
63
118
|
end
|
64
119
|
it 'should create PNG diagram in imagesdir if kroki-fetch-diagram is set' do
|
@@ -67,7 +122,7 @@ describe ::AsciidoctorExtensions::KrokiBlockProcessor do
|
|
67
122
|
|
68
123
|
plantuml::spec/fixtures/alice.puml[png,role=sequence]
|
69
124
|
ADOC
|
70
|
-
output = Asciidoctor.convert(input, attributes: { 'kroki-fetch-diagram' => '' }, standalone: false)
|
125
|
+
output = Asciidoctor.convert(input, attributes: { 'kroki-fetch-diagram' => '' }, standalone: false, safe: :safe)
|
71
126
|
(expect output).to eql %(<div class="imageblock sequence kroki-format-png kroki">
|
72
127
|
<div class="content">
|
73
128
|
<img src=".asciidoctor/kroki/diag-d4f314b2d4e75cc08aa4f8c2c944f7bf78321895d8ec5f665b42476d4e67e610.png" alt="Diagram">
|
@@ -80,7 +135,7 @@ end
|
|
80
135
|
describe ::AsciidoctorExtensions::Kroki do
|
81
136
|
it 'should return the list of supported diagrams' do
|
82
137
|
diagram_names = ::AsciidoctorExtensions::Kroki::SUPPORTED_DIAGRAM_NAMES
|
83
|
-
expect(diagram_names).to include('vegalite', 'plantuml', 'bytefield', 'bpmn', 'excalidraw')
|
138
|
+
expect(diagram_names).to include('vegalite', 'plantuml', 'bytefield', 'bpmn', 'excalidraw', 'wavedrom')
|
84
139
|
end
|
85
140
|
it 'should register the extension for the list of supported diagrams' do
|
86
141
|
doc = Asciidoctor::Document.new
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: asciidoctor-kroki
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Guillaume Grossetie
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-02-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: asciidoctor
|
@@ -85,6 +85,7 @@ files:
|
|
85
85
|
- lib/asciidoctor/extensions/asciidoctor_kroki.rb
|
86
86
|
- lib/asciidoctor/extensions/asciidoctor_kroki/extension.rb
|
87
87
|
- spec/.rubocop.yml
|
88
|
+
- spec/asciidoctor_kroki_block_macro_spec.rb
|
88
89
|
- spec/asciidoctor_kroki_client_spec.rb
|
89
90
|
- spec/asciidoctor_kroki_diagram_spec.rb
|
90
91
|
- spec/asciidoctor_kroki_spec.rb
|
@@ -122,6 +123,7 @@ specification_version: 4
|
|
122
123
|
summary: Asciidoctor extension to convert diagrams to images using Kroki
|
123
124
|
test_files:
|
124
125
|
- spec/.rubocop.yml
|
126
|
+
- spec/asciidoctor_kroki_block_macro_spec.rb
|
125
127
|
- spec/asciidoctor_kroki_client_spec.rb
|
126
128
|
- spec/asciidoctor_kroki_diagram_spec.rb
|
127
129
|
- spec/asciidoctor_kroki_spec.rb
|