asciidoctor-kroki 0.6.0 → 0.8.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/.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: []
|