asciidoctor-kroki 0.6.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/Gemfile.lock +2 -2
- data/asciidoctor-kroki.gemspec +3 -3
- data/lib/asciidoctor/extensions/asciidoctor_kroki/extension.rb +38 -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 +36 -5
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b1a9ee37258ade055ecd3df006bc1ef56be944dae7a257a27f092578487f0497
|
4
|
+
data.tar.gz: 8bee22bb9a553eaad890b3c162e29d86cbe5dcfbda90f01dd92fbdd44c3db03a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 93bbb72cf26b1f7c95b41ae7a9dc99d41e9c2207e4919b7e5afb267a221a37f1cfa1a3dcb3ecda76adad8ff3535de90cd25bb5a8acb81b46ff983cdac1e20618
|
7
|
+
data.tar.gz: 83d814b471385da42de1ed2c253f6d57a4a026fd23af8b272928c8ede48ed5a74453e9b394b05cf4b5d1f400f2af9b22f853cac9f90c705fb7e3f70300d81576
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.
|
1
|
+
3.2.0
|
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.8.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.18)
|
11
11
|
ast (2.4.2)
|
12
12
|
diff-lcs (1.4.4)
|
13
13
|
parallel (1.22.1)
|
data/asciidoctor-kroki.gemspec
CHANGED
@@ -10,11 +10,11 @@ Gem::Specification.new do |s|
|
|
10
10
|
|
11
11
|
s.authors = ['Guillaume Grossetie']
|
12
12
|
s.email = ['ggrossetie@yuzutech.fr']
|
13
|
-
s.homepage = 'https://github.com/
|
13
|
+
s.homepage = 'https://github.com/ggrossetie/asciidoctor-kroki'
|
14
14
|
s.license = 'MIT'
|
15
15
|
s.metadata = {
|
16
|
-
'bug_tracker_uri' => 'https://github.com/
|
17
|
-
'source_code_uri' => 'https://github.com/
|
16
|
+
'bug_tracker_uri' => 'https://github.com/ggrossetie/asciidoctor-kroki/issues',
|
17
|
+
'source_code_uri' => 'https://github.com/ggrossetie/asciidoctor-kroki',
|
18
18
|
'rubygems_mfa_required' => 'true'
|
19
19
|
}
|
20
20
|
s.files = `git ls-files`.split($RS)
|
@@ -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
|
@@ -110,6 +111,8 @@ module AsciidoctorExtensions
|
|
110
111
|
bpmn
|
111
112
|
bytefield
|
112
113
|
c4plantuml
|
114
|
+
d2
|
115
|
+
dbml
|
113
116
|
ditaa
|
114
117
|
erd
|
115
118
|
excalidraw
|
@@ -128,6 +131,7 @@ module AsciidoctorExtensions
|
|
128
131
|
vegalite
|
129
132
|
wavedrom
|
130
133
|
structurizr
|
134
|
+
diagramsnet
|
131
135
|
].freeze
|
132
136
|
end
|
133
137
|
|
@@ -137,6 +141,7 @@ module AsciidoctorExtensions
|
|
137
141
|
include Asciidoctor::Logging
|
138
142
|
|
139
143
|
TEXT_FORMATS = %w[txt atxt utxt].freeze
|
144
|
+
BUILTIN_ATTRIBUTES = %w[target width height format fallback link float align role caption title cloaked-context subs].freeze
|
140
145
|
|
141
146
|
class << self
|
142
147
|
# rubocop:disable Metrics/AbcSize
|
@@ -148,13 +153,12 @@ module AsciidoctorExtensions
|
|
148
153
|
if (subs = attrs['subs'])
|
149
154
|
diagram_text = parent.apply_subs(diagram_text, parent.resolve_subs(subs))
|
150
155
|
end
|
151
|
-
title = attrs.delete('title')
|
152
|
-
caption = attrs.delete('caption')
|
153
156
|
attrs.delete('opts')
|
154
157
|
format = get_format(doc, attrs, diagram_type)
|
155
158
|
attrs['role'] = get_role(format, attrs['role'])
|
156
159
|
attrs['format'] = format
|
157
|
-
|
160
|
+
opts = attrs.filter { |key, _| key.is_a?(String) && BUILTIN_ATTRIBUTES.none? { |k| key == k } && !key.end_with?('-option') }
|
161
|
+
kroki_diagram = KrokiDiagram.new(diagram_type, format, diagram_text, attrs['target'], opts)
|
158
162
|
kroki_client = KrokiClient.new({
|
159
163
|
server_url: server_url(doc),
|
160
164
|
http_method: http_method(doc),
|
@@ -162,11 +166,14 @@ module AsciidoctorExtensions
|
|
162
166
|
source_location: doc.reader.cursor_at_mark,
|
163
167
|
http_client: KrokiHttpClient
|
164
168
|
}, logger)
|
169
|
+
alt = get_alt(attrs)
|
170
|
+
title = attrs.delete('title')
|
171
|
+
caption = attrs.delete('caption')
|
165
172
|
if TEXT_FORMATS.include?(format)
|
166
173
|
text_content = kroki_client.text_content(kroki_diagram)
|
167
174
|
block = processor.create_block(parent, 'literal', text_content, attrs)
|
168
175
|
else
|
169
|
-
attrs['alt'] =
|
176
|
+
attrs['alt'] = alt
|
170
177
|
attrs['target'] = create_image_src(doc, kroki_diagram, kroki_client)
|
171
178
|
block = processor.create_image_block(parent, attrs)
|
172
179
|
end
|
@@ -221,8 +228,8 @@ module AsciidoctorExtensions
|
|
221
228
|
if format == 'png'
|
222
229
|
# redirect PNG format to SVG if the diagram library only supports SVG as output format.
|
223
230
|
# this is useful when the default format has been set to PNG
|
224
|
-
# Currently,
|
225
|
-
svg_only_diagram_types = %i[
|
231
|
+
# Currently, nomnoml, svgbob, wavedrom only support SVG as output format.
|
232
|
+
svg_only_diagram_types = %i[nomnoml svgbob wavedrom]
|
226
233
|
format = 'svg' if svg_only_diagram_types.include?(diagram_type)
|
227
234
|
end
|
228
235
|
format
|
@@ -269,17 +276,19 @@ module AsciidoctorExtensions
|
|
269
276
|
require 'zlib'
|
270
277
|
require 'digest'
|
271
278
|
|
272
|
-
attr_reader :type, :text, :format, :target
|
279
|
+
attr_reader :type, :text, :format, :target, :opts
|
273
280
|
|
274
|
-
def initialize(type, format, text, target = nil)
|
281
|
+
def initialize(type, format, text, target = nil, opts = {})
|
275
282
|
@text = text
|
276
283
|
@type = type
|
277
284
|
@format = format
|
278
285
|
@target = target
|
286
|
+
@opts = opts
|
279
287
|
end
|
280
288
|
|
281
289
|
def get_diagram_uri(server_url)
|
282
|
-
|
290
|
+
query_params = opts.map { |k, v| "#{k}=#{_url_encode(v.to_s)}" }.join('&') unless opts.empty?
|
291
|
+
_join_uri_segments(server_url, @type, @format, encode) + (query_params ? "?#{query_params}" : '')
|
283
292
|
end
|
284
293
|
|
285
294
|
def encode
|
@@ -308,6 +317,10 @@ module AsciidoctorExtensions
|
|
308
317
|
|
309
318
|
private
|
310
319
|
|
320
|
+
def _url_encode(text)
|
321
|
+
CGI.escape(text).gsub(/\+/, '%20')
|
322
|
+
end
|
323
|
+
|
311
324
|
def _join_uri_segments(base, *uris)
|
312
325
|
segments = []
|
313
326
|
# remove trailing slashes
|
@@ -354,6 +367,7 @@ module AsciidoctorExtensions
|
|
354
367
|
type = kroki_diagram.type
|
355
368
|
format = kroki_diagram.format
|
356
369
|
text = kroki_diagram.text
|
370
|
+
opts = kroki_diagram.opts
|
357
371
|
if @method == 'adaptive' || @method == 'get'
|
358
372
|
uri = kroki_diagram.get_diagram_uri(server_url)
|
359
373
|
if uri.length > @max_uri_length
|
@@ -361,15 +375,15 @@ module AsciidoctorExtensions
|
|
361
375
|
if @method == 'get'
|
362
376
|
# The request might be rejected by the server with a 414 Request-URI Too Large.
|
363
377
|
# Consider using the attribute kroki-http-method with the value 'adaptive'.
|
364
|
-
@http_client.get(uri, encoding)
|
378
|
+
@http_client.get(uri, opts, encoding)
|
365
379
|
else
|
366
|
-
@http_client.post("#{@server_url}/#{type}/#{format}", text, encoding)
|
380
|
+
@http_client.post("#{@server_url}/#{type}/#{format}", text, opts, encoding)
|
367
381
|
end
|
368
382
|
else
|
369
|
-
@http_client.get(uri, encoding)
|
383
|
+
@http_client.get(uri, opts, encoding)
|
370
384
|
end
|
371
385
|
else
|
372
|
-
@http_client.post("#{@server_url}/#{type}/#{format}", text, encoding)
|
386
|
+
@http_client.post("#{@server_url}/#{type}/#{format}", text, opts, encoding)
|
373
387
|
end
|
374
388
|
end
|
375
389
|
end
|
@@ -384,10 +398,11 @@ module AsciidoctorExtensions
|
|
384
398
|
class << self
|
385
399
|
REFERER = "asciidoctor/kroki.rb/#{Asciidoctor::AsciidoctorKroki::VERSION}"
|
386
400
|
|
387
|
-
def get(uri, _)
|
401
|
+
def get(uri, opts, _)
|
388
402
|
uri = URI(uri)
|
389
|
-
|
390
|
-
|
403
|
+
headers = opts.transform_keys { |key| "Kroki-Diagram-Options-#{key}" }
|
404
|
+
.merge({ 'referer' => REFERER })
|
405
|
+
request = ::Net::HTTP::Get.new(uri, headers)
|
391
406
|
::Net::HTTP.start(
|
392
407
|
uri.hostname,
|
393
408
|
uri.port,
|
@@ -397,12 +412,16 @@ module AsciidoctorExtensions
|
|
397
412
|
end
|
398
413
|
end
|
399
414
|
|
400
|
-
def post(uri, data, _)
|
415
|
+
def post(uri, data, opts, _)
|
416
|
+
headers = opts.transform_keys { |key| "Kroki-Diagram-Options-#{key}" }
|
417
|
+
.merge({
|
418
|
+
'Content-Type' => 'text/plain',
|
419
|
+
'referer' => REFERER
|
420
|
+
})
|
401
421
|
res = ::Net::HTTP.post(
|
402
422
|
URI(uri),
|
403
423
|
data,
|
404
|
-
|
405
|
-
'Referer' => REFERER
|
424
|
+
headers
|
406
425
|
)
|
407
426
|
res.body
|
408
427
|
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
|
@@ -163,7 +194,7 @@ end
|
|
163
194
|
describe ::AsciidoctorExtensions::Kroki do
|
164
195
|
it 'should return the list of supported diagrams' do
|
165
196
|
diagram_names = ::AsciidoctorExtensions::Kroki::SUPPORTED_DIAGRAM_NAMES
|
166
|
-
expect(diagram_names).to include('vegalite', 'plantuml', 'bytefield', 'bpmn', 'excalidraw', 'wavedrom', 'pikchr', 'structurizr')
|
197
|
+
expect(diagram_names).to include('vegalite', 'plantuml', 'bytefield', 'bpmn', 'excalidraw', 'wavedrom', 'pikchr', 'structurizr', 'diagramsnet')
|
167
198
|
end
|
168
199
|
it 'should register the extension for the list of supported diagrams' do
|
169
200
|
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.8.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:
|
11
|
+
date: 2023-02-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: asciidoctor
|
@@ -99,12 +99,12 @@ files:
|
|
99
99
|
- tasks/bundler.rake
|
100
100
|
- tasks/lint.rake
|
101
101
|
- tasks/rspec.rake
|
102
|
-
homepage: https://github.com/
|
102
|
+
homepage: https://github.com/ggrossetie/asciidoctor-kroki
|
103
103
|
licenses:
|
104
104
|
- MIT
|
105
105
|
metadata:
|
106
|
-
bug_tracker_uri: https://github.com/
|
107
|
-
source_code_uri: https://github.com/
|
106
|
+
bug_tracker_uri: https://github.com/ggrossetie/asciidoctor-kroki/issues
|
107
|
+
source_code_uri: https://github.com/ggrossetie/asciidoctor-kroki
|
108
108
|
rubygems_mfa_required: 'true'
|
109
109
|
post_install_message:
|
110
110
|
rdoc_options: []
|