asciidoctor-kroki 0.6.0 → 0.7.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/Gemfile.lock +2 -2
- data/lib/asciidoctor/extensions/asciidoctor_kroki/extension.rb +35 -19
- data/lib/asciidoctor/extensions/asciidoctor_kroki/version.rb +1 -1
- data/spec/asciidoctor_kroki_client_spec.rb +9 -7
- data/spec/asciidoctor_kroki_diagram_spec.rb +18 -0
- data/spec/asciidoctor_kroki_spec.rb +35 -4
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 46f326afecfa57d4b918121fdf939c2c8dcf46897daeff74236a551628ffbfdf
|
4
|
+
data.tar.gz: c43629e9e6d4303fa59d761b61e95e6b63006cea1a27faf1dc3e80ceb9994f8c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70eac4468da00da494aa490e3c413189feb13474d25aa778f1d0cb301957c7ce1811bbc82cc7d1e2782a43223452f5b1de75a150b446824c2de7f9380811defc
|
7
|
+
data.tar.gz: e9d6cbbdc63c8f28dd99c1921f1496765ccbb873210756c765d879d1311994243af42f55f3d4dc18e0500be299ef89d5027bbccf5afefee24255d65c71e829d4
|
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.7.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.17)
|
11
11
|
ast (2.4.2)
|
12
12
|
diff-lcs (1.4.4)
|
13
13
|
parallel (1.22.1)
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'cgi'
|
3
4
|
require 'asciidoctor/extensions' unless RUBY_ENGINE == 'opal'
|
4
5
|
|
5
6
|
# Asciidoctor extensions
|
@@ -137,6 +138,7 @@ module AsciidoctorExtensions
|
|
137
138
|
include Asciidoctor::Logging
|
138
139
|
|
139
140
|
TEXT_FORMATS = %w[txt atxt utxt].freeze
|
141
|
+
BUILTIN_ATTRIBUTES = %w[target width height format fallback link float align role caption title cloaked-context subs].freeze
|
140
142
|
|
141
143
|
class << self
|
142
144
|
# rubocop:disable Metrics/AbcSize
|
@@ -148,13 +150,12 @@ module AsciidoctorExtensions
|
|
148
150
|
if (subs = attrs['subs'])
|
149
151
|
diagram_text = parent.apply_subs(diagram_text, parent.resolve_subs(subs))
|
150
152
|
end
|
151
|
-
title = attrs.delete('title')
|
152
|
-
caption = attrs.delete('caption')
|
153
153
|
attrs.delete('opts')
|
154
154
|
format = get_format(doc, attrs, diagram_type)
|
155
155
|
attrs['role'] = get_role(format, attrs['role'])
|
156
156
|
attrs['format'] = format
|
157
|
-
|
157
|
+
opts = attrs.filter { |key, _| key.is_a?(String) && BUILTIN_ATTRIBUTES.none? { |k| key == k } && !key.end_with?('-option') }
|
158
|
+
kroki_diagram = KrokiDiagram.new(diagram_type, format, diagram_text, attrs['target'], opts)
|
158
159
|
kroki_client = KrokiClient.new({
|
159
160
|
server_url: server_url(doc),
|
160
161
|
http_method: http_method(doc),
|
@@ -162,11 +163,14 @@ module AsciidoctorExtensions
|
|
162
163
|
source_location: doc.reader.cursor_at_mark,
|
163
164
|
http_client: KrokiHttpClient
|
164
165
|
}, logger)
|
166
|
+
alt = get_alt(attrs)
|
167
|
+
title = attrs.delete('title')
|
168
|
+
caption = attrs.delete('caption')
|
165
169
|
if TEXT_FORMATS.include?(format)
|
166
170
|
text_content = kroki_client.text_content(kroki_diagram)
|
167
171
|
block = processor.create_block(parent, 'literal', text_content, attrs)
|
168
172
|
else
|
169
|
-
attrs['alt'] =
|
173
|
+
attrs['alt'] = alt
|
170
174
|
attrs['target'] = create_image_src(doc, kroki_diagram, kroki_client)
|
171
175
|
block = processor.create_image_block(parent, attrs)
|
172
176
|
end
|
@@ -221,8 +225,8 @@ module AsciidoctorExtensions
|
|
221
225
|
if format == 'png'
|
222
226
|
# redirect PNG format to SVG if the diagram library only supports SVG as output format.
|
223
227
|
# this is useful when the default format has been set to PNG
|
224
|
-
# Currently,
|
225
|
-
svg_only_diagram_types = %i[
|
228
|
+
# Currently, nomnoml, svgbob, wavedrom only support SVG as output format.
|
229
|
+
svg_only_diagram_types = %i[nomnoml svgbob wavedrom]
|
226
230
|
format = 'svg' if svg_only_diagram_types.include?(diagram_type)
|
227
231
|
end
|
228
232
|
format
|
@@ -269,17 +273,19 @@ module AsciidoctorExtensions
|
|
269
273
|
require 'zlib'
|
270
274
|
require 'digest'
|
271
275
|
|
272
|
-
attr_reader :type, :text, :format, :target
|
276
|
+
attr_reader :type, :text, :format, :target, :opts
|
273
277
|
|
274
|
-
def initialize(type, format, text, target = nil)
|
278
|
+
def initialize(type, format, text, target = nil, opts = {})
|
275
279
|
@text = text
|
276
280
|
@type = type
|
277
281
|
@format = format
|
278
282
|
@target = target
|
283
|
+
@opts = opts
|
279
284
|
end
|
280
285
|
|
281
286
|
def get_diagram_uri(server_url)
|
282
|
-
|
287
|
+
query_params = opts.map { |k, v| "#{k}=#{_url_encode(v.to_s)}" }.join('&') unless opts.empty?
|
288
|
+
_join_uri_segments(server_url, @type, @format, encode) + (query_params ? "?#{query_params}" : '')
|
283
289
|
end
|
284
290
|
|
285
291
|
def encode
|
@@ -308,6 +314,10 @@ module AsciidoctorExtensions
|
|
308
314
|
|
309
315
|
private
|
310
316
|
|
317
|
+
def _url_encode(text)
|
318
|
+
CGI.escape(text).gsub(/\+/, '%20')
|
319
|
+
end
|
320
|
+
|
311
321
|
def _join_uri_segments(base, *uris)
|
312
322
|
segments = []
|
313
323
|
# remove trailing slashes
|
@@ -354,6 +364,7 @@ module AsciidoctorExtensions
|
|
354
364
|
type = kroki_diagram.type
|
355
365
|
format = kroki_diagram.format
|
356
366
|
text = kroki_diagram.text
|
367
|
+
opts = kroki_diagram.opts
|
357
368
|
if @method == 'adaptive' || @method == 'get'
|
358
369
|
uri = kroki_diagram.get_diagram_uri(server_url)
|
359
370
|
if uri.length > @max_uri_length
|
@@ -361,15 +372,15 @@ module AsciidoctorExtensions
|
|
361
372
|
if @method == 'get'
|
362
373
|
# The request might be rejected by the server with a 414 Request-URI Too Large.
|
363
374
|
# Consider using the attribute kroki-http-method with the value 'adaptive'.
|
364
|
-
@http_client.get(uri, encoding)
|
375
|
+
@http_client.get(uri, opts, encoding)
|
365
376
|
else
|
366
|
-
@http_client.post("#{@server_url}/#{type}/#{format}", text, encoding)
|
377
|
+
@http_client.post("#{@server_url}/#{type}/#{format}", text, opts, encoding)
|
367
378
|
end
|
368
379
|
else
|
369
|
-
@http_client.get(uri, encoding)
|
380
|
+
@http_client.get(uri, opts, encoding)
|
370
381
|
end
|
371
382
|
else
|
372
|
-
@http_client.post("#{@server_url}/#{type}/#{format}", text, encoding)
|
383
|
+
@http_client.post("#{@server_url}/#{type}/#{format}", text, opts, encoding)
|
373
384
|
end
|
374
385
|
end
|
375
386
|
end
|
@@ -384,10 +395,11 @@ module AsciidoctorExtensions
|
|
384
395
|
class << self
|
385
396
|
REFERER = "asciidoctor/kroki.rb/#{Asciidoctor::AsciidoctorKroki::VERSION}"
|
386
397
|
|
387
|
-
def get(uri, _)
|
398
|
+
def get(uri, opts, _)
|
388
399
|
uri = URI(uri)
|
389
|
-
|
390
|
-
|
400
|
+
headers = opts.transform_keys { |key| "Kroki-Diagram-Options-#{key}" }
|
401
|
+
.merge({ 'referer' => REFERER })
|
402
|
+
request = ::Net::HTTP::Get.new(uri, headers)
|
391
403
|
::Net::HTTP.start(
|
392
404
|
uri.hostname,
|
393
405
|
uri.port,
|
@@ -397,12 +409,16 @@ module AsciidoctorExtensions
|
|
397
409
|
end
|
398
410
|
end
|
399
411
|
|
400
|
-
def post(uri, data, _)
|
412
|
+
def post(uri, data, opts, _)
|
413
|
+
headers = opts.transform_keys { |key| "Kroki-Diagram-Options-#{key}" }
|
414
|
+
.merge({
|
415
|
+
'Content-Type' => 'text/plain',
|
416
|
+
'referer' => REFERER
|
417
|
+
})
|
401
418
|
res = ::Net::HTTP.post(
|
402
419
|
URI(uri),
|
403
420
|
data,
|
404
|
-
|
405
|
-
'Referer' => REFERER
|
421
|
+
headers
|
406
422
|
)
|
407
423
|
res.body
|
408
424
|
end
|
@@ -37,18 +37,19 @@ describe ::AsciidoctorExtensions::KrokiClient do
|
|
37
37
|
"GET #{uri}"
|
38
38
|
end
|
39
39
|
|
40
|
-
def post(uri, data, _)
|
40
|
+
def post(uri, data, _, _)
|
41
41
|
"POST #{uri} - #{data}"
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
45
45
|
kroki_diagram = Class.new do
|
46
|
-
attr_reader :type, :text, :format
|
46
|
+
attr_reader :type, :text, :format, :opts
|
47
47
|
|
48
|
-
def initialize(type, format, text)
|
48
|
+
def initialize(type, format, text, opts = {})
|
49
49
|
@text = text
|
50
50
|
@type = type
|
51
51
|
@format = format
|
52
|
+
@opts = opts
|
52
53
|
end
|
53
54
|
|
54
55
|
def get_diagram_uri(_)
|
@@ -62,22 +63,23 @@ describe ::AsciidoctorExtensions::KrokiClient do
|
|
62
63
|
it 'should get an image with GET request if the URI length is lower or equals than the value configured' do
|
63
64
|
kroki_http_client = Class.new do
|
64
65
|
class << self
|
65
|
-
def get(uri, _)
|
66
|
+
def get(uri, _, _)
|
66
67
|
"GET #{uri}"
|
67
68
|
end
|
68
69
|
|
69
|
-
def post(uri, data, _)
|
70
|
+
def post(uri, data, _, _)
|
70
71
|
"POST #{uri} - #{data}"
|
71
72
|
end
|
72
73
|
end
|
73
74
|
end
|
74
75
|
kroki_diagram = Class.new do
|
75
|
-
attr_reader :type, :text, :format
|
76
|
+
attr_reader :type, :text, :format, :opts
|
76
77
|
|
77
|
-
def initialize(type, format, text)
|
78
|
+
def initialize(type, format, text, opts = {})
|
78
79
|
@text = text
|
79
80
|
@type = type
|
80
81
|
@format = format
|
82
|
+
@opts = opts
|
81
83
|
end
|
82
84
|
|
83
85
|
def get_diagram_uri(_)
|
@@ -20,6 +20,24 @@ describe ::AsciidoctorExtensions::KrokiDiagram do
|
|
20
20
|
diagram_uri = kroki_diagram.get_diagram_uri('https://my-server/kroki//')
|
21
21
|
expect(diagram_uri).to eq('https://my-server/kroki/vegalite/png/eNqrrgUAAXUA-Q==')
|
22
22
|
end
|
23
|
+
it 'should compute a diagram URI with query parameters' do
|
24
|
+
text = %q{
|
25
|
+
.---.
|
26
|
+
/-o-/--
|
27
|
+
.-/ / /->
|
28
|
+
( * \/
|
29
|
+
'-. \
|
30
|
+
\ /
|
31
|
+
'
|
32
|
+
}
|
33
|
+
opts = {
|
34
|
+
'stroke-width' => 1,
|
35
|
+
'background' => 'black'
|
36
|
+
}
|
37
|
+
kroki_diagram = ::AsciidoctorExtensions::KrokiDiagram.new('svgbob', 'png', text, nil, opts)
|
38
|
+
diagram_uri = kroki_diagram.get_diagram_uri('http://localhost:8000')
|
39
|
+
expect(diagram_uri).to eq('http://localhost:8000/svgbob/png/eNrjUoAAPV1dXT0uCFtfN19XX1eXCyysrwCEunZAjoaCloJCjD5IWF1XD8gEK49R0IdoUwdTAN3kC7U=?stroke-width=1&background=black')
|
40
|
+
end
|
23
41
|
it 'should encode a diagram text definition' do
|
24
42
|
kroki_diagram = ::AsciidoctorExtensions::KrokiDiagram.new('plantuml', 'txt', ' alice -> bob: hello')
|
25
43
|
diagram_definition_encoded = kroki_diagram.encode
|
@@ -18,6 +18,35 @@ describe ::AsciidoctorExtensions::KrokiBlockProcessor do
|
|
18
18
|
<div class="content">
|
19
19
|
<img src="https://kroki.io/plantuml/svg/eNpLzMlMTlXQtVNIyk-yUshIzcnJBwA9iwZL" alt="Diagram">
|
20
20
|
</div>
|
21
|
+
</div>)
|
22
|
+
end
|
23
|
+
it 'should only pass diagram options as query parameters' do
|
24
|
+
input = <<~'ADOC'
|
25
|
+
[plantuml,alice-bob,svg,role=sequence,width=100,format=svg,link=https://asciidoc.org/,align=center,float=right,theme=bluegray]
|
26
|
+
....
|
27
|
+
alice -> bob: hello
|
28
|
+
....
|
29
|
+
ADOC
|
30
|
+
output = Asciidoctor.convert(input, standalone: false)
|
31
|
+
(expect output).to eql %(<div class="imageblock right text-center sequence kroki-format-svg kroki">
|
32
|
+
<div class="content">
|
33
|
+
<a class="image" href="https://asciidoc.org/"><img src="https://kroki.io/plantuml/svg/eNpLzMlMTlXQtVNIyk-yUshIzcnJBwA9iwZL?theme=bluegray" alt="alice-bob" width="100"></a>
|
34
|
+
</div>
|
35
|
+
</div>)
|
36
|
+
end
|
37
|
+
it 'should use the title attribute as the alt value' do
|
38
|
+
input = <<~'ADOC'
|
39
|
+
[plantuml,title="Alice saying hello to Bob"]
|
40
|
+
....
|
41
|
+
alice -> bob: hello
|
42
|
+
....
|
43
|
+
ADOC
|
44
|
+
output = Asciidoctor.convert(input, standalone: false)
|
45
|
+
(expect output).to eql %(<div class="imageblock kroki">
|
46
|
+
<div class="content">
|
47
|
+
<img src="https://kroki.io/plantuml/svg/eNpLzMlMTlXQtVNIyk-yUshIzcnJBwA9iwZL" alt="Alice saying hello to Bob">
|
48
|
+
</div>
|
49
|
+
<div class="title">Figure 1. Alice saying hello to Bob</div>
|
21
50
|
</div>)
|
22
51
|
end
|
23
52
|
it 'should use png if kroki-default-format is set to png' do
|
@@ -36,16 +65,18 @@ describe ::AsciidoctorExtensions::KrokiBlockProcessor do
|
|
36
65
|
end
|
37
66
|
it 'should use svg if kroki-default-format is set to png and the diagram type does not support png' do
|
38
67
|
input = <<~'ADOC'
|
39
|
-
[
|
68
|
+
[nomnoml]
|
40
69
|
....
|
41
|
-
|
42
|
-
|
70
|
+
[Pirate|eyeCount: Int|raid();pillage()|
|
71
|
+
[beard]--[parrot]
|
72
|
+
[beard]-:>[foul mouth]
|
73
|
+
]
|
43
74
|
....
|
44
75
|
ADOC
|
45
76
|
output = Asciidoctor.convert(input, attributes: { 'kroki-default-format' => 'png' }, standalone: false)
|
46
77
|
(expect output).to eql %(<div class="imageblock kroki">
|
47
78
|
<div class="content">
|
48
|
-
<img src="https://kroki.io/
|
79
|
+
<img src="https://kroki.io/nomnoml/svg/eNqLDsgsSixJrUmtTHXOL80rsVLwzCupKUrMTNHQtC7IzMlJTE_V0KzhUlCITkpNLEqJ1dWNLkgsKsoviUUSs7KLTssvzVHIzS8tyYjligUAMhEd0g==" alt="Diagram">
|
49
80
|
</div>
|
50
81
|
</div>)
|
51
82
|
end
|
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.7.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: 2022-
|
11
|
+
date: 2022-09-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: asciidoctor
|