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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1d98287cf9a15751a442de9b1a07565c097206aae0912ca204ecaf4bdede4020
4
- data.tar.gz: b1252225ed15a9f093d8a3c1d577e2bfa23c2abe7962981d638f49ea81d90a7b
3
+ metadata.gz: b1a9ee37258ade055ecd3df006bc1ef56be944dae7a257a27f092578487f0497
4
+ data.tar.gz: 8bee22bb9a553eaad890b3c162e29d86cbe5dcfbda90f01dd92fbdd44c3db03a
5
5
  SHA512:
6
- metadata.gz: 46688eb160c567e33ba1f220ab229848a66874af0713962c339bc4d3b7d3352a5ef3f2f74e9c257bae6c579e03bf6c32cdf55e16f9b64d7b189aa103bf2d8550
7
- data.tar.gz: 78a231f8b5921330aab30a2cd5c4f56ab84f917e31dc4cc85d2eb126cec84f04bd52756db2ff1fd8991116086b1100184c0644f35929fadb8ae49f95806e1248
6
+ metadata.gz: 93bbb72cf26b1f7c95b41ae7a9dc99d41e9c2207e4919b7e5afb267a221a37f1cfa1a3dcb3ecda76adad8ff3535de90cd25bb5a8acb81b46ff983cdac1e20618
7
+ data.tar.gz: 83d814b471385da42de1ed2c253f6d57a4a026fd23af8b272928c8ede48ed5a74453e9b394b05cf4b5d1f400f2af9b22f853cac9f90c705fb7e3f70300d81576
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.1.2
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.6.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.11)
10
+ asciidoctor (2.0.18)
11
11
  ast (2.4.2)
12
12
  diff-lcs (1.4.4)
13
13
  parallel (1.22.1)
@@ -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/Mogztter/asciidoctor-kroki'
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/Mogztter/asciidoctor-kroki/issues',
17
- 'source_code_uri' => 'https://github.com/Mogztter/asciidoctor-kroki',
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
- kroki_diagram = KrokiDiagram.new(diagram_type, format, diagram_text, attrs['target'])
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'] = get_alt(attrs)
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, mermaid, nomnoml, svgbob, wavedrom only support SVG as output format.
225
- svg_only_diagram_types = %i[mermaid nomnoml svgbob wavedrom]
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
- _join_uri_segments(server_url, @type, @format, encode)
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
- request = ::Net::HTTP::Get.new(uri)
390
- request['referer'] = REFERER
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
- 'Content-Type' => 'text/plain',
405
- 'Referer' => REFERER
424
+ headers
406
425
  )
407
426
  res.body
408
427
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Asciidoctor
4
4
  module AsciidoctorKroki
5
- VERSION = '0.6.0'
5
+ VERSION = '0.8.0'
6
6
  end
7
7
  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
- [mermaid]
68
+ [nomnoml]
40
69
  ....
41
- graph TD;
42
- A-->B;
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/mermaid/svg/eNpLL0osyFAIcbHmUlBw1NW1c7IGADLKBKY=" alt="Diagram">
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.6.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: 2022-06-22 00:00:00.000000000 Z
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/Mogztter/asciidoctor-kroki
102
+ homepage: https://github.com/ggrossetie/asciidoctor-kroki
103
103
  licenses:
104
104
  - MIT
105
105
  metadata:
106
- bug_tracker_uri: https://github.com/Mogztter/asciidoctor-kroki/issues
107
- source_code_uri: https://github.com/Mogztter/asciidoctor-kroki
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: []