asciidoctor-kroki 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|