asciidoctor-kroki 0.3.0 → 0.4.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/.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
|