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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1d98287cf9a15751a442de9b1a07565c097206aae0912ca204ecaf4bdede4020
4
- data.tar.gz: b1252225ed15a9f093d8a3c1d577e2bfa23c2abe7962981d638f49ea81d90a7b
3
+ metadata.gz: 46f326afecfa57d4b918121fdf939c2c8dcf46897daeff74236a551628ffbfdf
4
+ data.tar.gz: c43629e9e6d4303fa59d761b61e95e6b63006cea1a27faf1dc3e80ceb9994f8c
5
5
  SHA512:
6
- metadata.gz: 46688eb160c567e33ba1f220ab229848a66874af0713962c339bc4d3b7d3352a5ef3f2f74e9c257bae6c579e03bf6c32cdf55e16f9b64d7b189aa103bf2d8550
7
- data.tar.gz: 78a231f8b5921330aab30a2cd5c4f56ab84f917e31dc4cc85d2eb126cec84f04bd52756db2ff1fd8991116086b1100184c0644f35929fadb8ae49f95806e1248
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.6.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.11)
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
- kroki_diagram = KrokiDiagram.new(diagram_type, format, diagram_text, attrs['target'])
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'] = get_alt(attrs)
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, mermaid, nomnoml, svgbob, wavedrom only support SVG as output format.
225
- svg_only_diagram_types = %i[mermaid nomnoml svgbob wavedrom]
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
- _join_uri_segments(server_url, @type, @format, encode)
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
- request = ::Net::HTTP::Get.new(uri)
390
- request['referer'] = REFERER
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
- 'Content-Type' => 'text/plain',
405
- 'Referer' => REFERER
421
+ headers
406
422
  )
407
423
  res.body
408
424
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Asciidoctor
4
4
  module AsciidoctorKroki
5
- VERSION = '0.6.0'
5
+ VERSION = '0.7.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
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.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-06-22 00:00:00.000000000 Z
11
+ date: 2022-09-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor