asciidoctor-kroki 0.5.0 → 0.6.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: b10096229def31407946a5f7e77eb57a991895d9407d334b6a4ca3dc7e8ba165
4
- data.tar.gz: 81497c2124169974c072a57c496b37d8cbd5e96b4793a22d59a3152fb1693c45
3
+ metadata.gz: 1d98287cf9a15751a442de9b1a07565c097206aae0912ca204ecaf4bdede4020
4
+ data.tar.gz: b1252225ed15a9f093d8a3c1d577e2bfa23c2abe7962981d638f49ea81d90a7b
5
5
  SHA512:
6
- metadata.gz: 03e1e7d5dc886c9e4ff9d7199f3289aa1a94d8b97a21209ba4ea9c4b505129646297bb62c02cab6390803b157a7a505e3af944ff533c49086af11927647776ce
7
- data.tar.gz: ad4cda7ce19c6ffa1223a224c1528c87e7b8864d554662f26a7534937f4bea49433e500373dad215feb09d71f748c84881ad720ea5c52765977383eb393a9f4c
6
+ metadata.gz: 46688eb160c567e33ba1f220ab229848a66874af0713962c339bc4d3b7d3352a5ef3f2f74e9c257bae6c579e03bf6c32cdf55e16f9b64d7b189aa103bf2d8550
7
+ data.tar.gz: 78a231f8b5921330aab30a2cd5c4f56ab84f917e31dc4cc85d2eb126cec84f04bd52756db2ff1fd8991116086b1100184c0644f35929fadb8ae49f95806e1248
data/.rubocop.yml CHANGED
@@ -1,10 +1,15 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.7
3
+ SuggestExtensions: false
4
+ NewCops: enable
5
+
1
6
  Style/Encoding:
2
7
  Enabled: false
3
8
 
4
9
  Layout/EndOfLine:
5
10
  EnforcedStyle: lf
6
11
 
7
- Metrics/LineLength:
12
+ Layout/LineLength:
8
13
  Max: 180
9
14
 
10
15
  Metrics/ClassLength:
@@ -20,7 +25,10 @@ Metrics/PerceivedComplexity:
20
25
  Max: 10
21
26
 
22
27
  Metrics/AbcSize:
23
- Max: 30
28
+ Max: 31
24
29
 
25
30
  Metrics/ParameterLists:
26
31
  Max: 7
32
+
33
+ Gemspec/RequiredRubyVersion:
34
+ Enabled: false
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.6.5
1
+ 3.1.2
data/Gemfile.lock CHANGED
@@ -1,52 +1,57 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- asciidoctor-kroki (0.5.0)
4
+ asciidoctor-kroki (0.6.0)
5
5
  asciidoctor (~> 2.0)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
10
  asciidoctor (2.0.11)
11
- ast (2.4.1)
12
- diff-lcs (1.3)
13
- jaro_winkler (1.5.4)
14
- parallel (1.19.1)
15
- parser (2.7.1.3)
16
- ast (~> 2.4.0)
17
- rainbow (3.0.0)
18
- rake (12.3.3)
19
- rspec (3.8.0)
20
- rspec-core (~> 3.8.0)
21
- rspec-expectations (~> 3.8.0)
22
- rspec-mocks (~> 3.8.0)
23
- rspec-core (3.8.2)
24
- rspec-support (~> 3.8.0)
25
- rspec-expectations (3.8.6)
11
+ ast (2.4.2)
12
+ diff-lcs (1.4.4)
13
+ parallel (1.22.1)
14
+ parser (3.1.2.0)
15
+ ast (~> 2.4.1)
16
+ rainbow (3.1.1)
17
+ rake (13.0.6)
18
+ regexp_parser (2.5.0)
19
+ rexml (3.2.5)
20
+ rspec (3.10.0)
21
+ rspec-core (~> 3.10.0)
22
+ rspec-expectations (~> 3.10.0)
23
+ rspec-mocks (~> 3.10.0)
24
+ rspec-core (3.10.1)
25
+ rspec-support (~> 3.10.0)
26
+ rspec-expectations (3.10.1)
26
27
  diff-lcs (>= 1.2.0, < 2.0)
27
- rspec-support (~> 3.8.0)
28
- rspec-mocks (3.8.2)
28
+ rspec-support (~> 3.10.0)
29
+ rspec-mocks (3.10.2)
29
30
  diff-lcs (>= 1.2.0, < 2.0)
30
- rspec-support (~> 3.8.0)
31
- rspec-support (3.8.3)
32
- rubocop (0.74.0)
33
- jaro_winkler (~> 1.5.1)
31
+ rspec-support (~> 3.10.0)
32
+ rspec-support (3.10.2)
33
+ rubocop (1.30.0)
34
34
  parallel (~> 1.10)
35
- parser (>= 2.6)
35
+ parser (>= 3.1.0.0)
36
36
  rainbow (>= 2.2.2, < 4.0)
37
+ regexp_parser (>= 1.8, < 3.0)
38
+ rexml (>= 3.2.5, < 4.0)
39
+ rubocop-ast (>= 1.18.0, < 2.0)
37
40
  ruby-progressbar (~> 1.7)
38
- unicode-display_width (>= 1.4.0, < 1.7)
39
- ruby-progressbar (1.10.1)
40
- unicode-display_width (1.6.1)
41
+ unicode-display_width (>= 1.4.0, < 3.0)
42
+ rubocop-ast (1.18.0)
43
+ parser (>= 3.1.1.0)
44
+ ruby-progressbar (1.11.0)
45
+ unicode-display_width (2.1.0)
41
46
 
42
47
  PLATFORMS
43
48
  ruby
44
49
 
45
50
  DEPENDENCIES
46
51
  asciidoctor-kroki!
47
- rake (~> 12.3.2)
48
- rspec (~> 3.8.0)
49
- rubocop (~> 0.74.0)
52
+ rake (~> 13.0.6)
53
+ rspec (~> 3.10.0)
54
+ rubocop (~> 1.30)
50
55
 
51
56
  BUNDLED WITH
52
- 2.2.17
57
+ 2.3.15
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'lib/asciidoctor/extensions/asciidoctor_kroki/version'
4
+
3
5
  Gem::Specification.new do |s|
4
6
  s.name = 'asciidoctor-kroki'
5
- s.version = '0.5.0'
7
+ s.version = Asciidoctor::AsciidoctorKroki::VERSION
6
8
  s.summary = 'Asciidoctor extension to convert diagrams to images using Kroki'
7
9
  s.description = 'An extension for Asciidoctor to convert diagrams to images using https://kroki.io'
8
10
 
@@ -12,15 +14,15 @@ Gem::Specification.new do |s|
12
14
  s.license = 'MIT'
13
15
  s.metadata = {
14
16
  'bug_tracker_uri' => 'https://github.com/Mogztter/asciidoctor-kroki/issues',
15
- 'source_code_uri' => 'https://github.com/Mogztter/asciidoctor-kroki'
17
+ 'source_code_uri' => 'https://github.com/Mogztter/asciidoctor-kroki',
18
+ 'rubygems_mfa_required' => 'true'
16
19
  }
17
20
  s.files = `git ls-files`.split($RS)
18
- s.test_files = s.files.grep(%r{^(test|spec|features|tasks)/})
19
21
  s.require_paths = ['lib']
20
22
 
21
23
  s.add_runtime_dependency 'asciidoctor', '~> 2.0'
22
24
 
23
- s.add_development_dependency 'rake', '~> 12.3.2'
24
- s.add_development_dependency 'rspec', '~> 3.8.0'
25
- s.add_development_dependency 'rubocop', '~> 0.74.0'
25
+ s.add_development_dependency 'rake', '~> 13.0.6'
26
+ s.add_development_dependency 'rspec', '~> 3.10.0'
27
+ s.add_development_dependency 'rubocop', '~> 1.30'
26
28
  end
@@ -38,6 +38,7 @@ module AsciidoctorExtensions
38
38
  # A block macro extension that converts a diagram into an image.
39
39
  #
40
40
  class KrokiBlockMacroProcessor < Asciidoctor::Extensions::BlockMacroProcessor
41
+ include Asciidoctor::Logging
41
42
  use_dsl
42
43
 
43
44
  name_positional_attributes 'format'
@@ -61,14 +62,14 @@ module AsciidoctorExtensions
61
62
  end
62
63
 
63
64
  unless (path = resolve_target_path(target))
64
- logger.error "#{diagram_type} block macro not found: #{target}."
65
- create_block(parent, 'paragraph', unresolved_block_macro_message(diagram_type, target), {})
65
+ logger.error message_with_context "#{diagram_type} block macro not found: #{target}.", source_location: parent.document.reader.cursor_at_mark
66
+ return create_block(parent, 'paragraph', unresolved_block_macro_message(diagram_type, target), {})
66
67
  end
67
68
 
68
69
  begin
69
70
  diagram_text = read(path)
70
- rescue => e # rubocop:disable RescueStandardError
71
- logger.error "Failed to read #{diagram_type} file: #{path}. #{e}."
71
+ rescue => e # rubocop:disable Style/RescueStandardError
72
+ logger.error message_with_context "Failed to read #{diagram_type} file: #{path}. #{e}.", source_location: parent.document.reader.cursor_at_mark
72
73
  return create_block(parent, 'paragraph', unresolved_block_macro_message(diagram_type, path), {})
73
74
  end
74
75
  KrokiProcessor.process(self, parent, attrs, diagram_type, diagram_text, @logger)
@@ -89,9 +90,9 @@ module AsciidoctorExtensions
89
90
  def read(target)
90
91
  if target.start_with?('http://') || target.start_with?('https://')
91
92
  require 'open-uri'
92
- URI.open(target, &:read)
93
+ ::OpenURI.open_uri(target, &:read)
93
94
  else
94
- File.open(target, &:read)
95
+ File.read(target, mode: 'rb:utf-8:utf-8')
95
96
  end
96
97
  end
97
98
 
@@ -126,15 +127,19 @@ module AsciidoctorExtensions
126
127
  vega
127
128
  vegalite
128
129
  wavedrom
130
+ structurizr
129
131
  ].freeze
130
132
  end
131
133
 
132
134
  # Internal processor
133
135
  #
134
136
  class KrokiProcessor
137
+ include Asciidoctor::Logging
138
+
135
139
  TEXT_FORMATS = %w[txt atxt utxt].freeze
136
140
 
137
141
  class << self
142
+ # rubocop:disable Metrics/AbcSize
138
143
  def process(processor, parent, attrs, diagram_type, diagram_text, logger)
139
144
  doc = parent.document
140
145
  diagram_text = prepend_plantuml_config(diagram_text, diagram_type, doc, logger)
@@ -146,12 +151,17 @@ module AsciidoctorExtensions
146
151
  title = attrs.delete('title')
147
152
  caption = attrs.delete('caption')
148
153
  attrs.delete('opts')
149
- role = attrs['role']
150
154
  format = get_format(doc, attrs, diagram_type)
151
- attrs['role'] = get_role(format, role)
155
+ attrs['role'] = get_role(format, attrs['role'])
152
156
  attrs['format'] = format
153
- kroki_diagram = KrokiDiagram.new(diagram_type, format, diagram_text)
154
- kroki_client = KrokiClient.new(server_url(doc), http_method(doc), KrokiHttpClient, logger, max_uri_length(doc))
157
+ kroki_diagram = KrokiDiagram.new(diagram_type, format, diagram_text, attrs['target'])
158
+ kroki_client = KrokiClient.new({
159
+ server_url: server_url(doc),
160
+ http_method: http_method(doc),
161
+ max_uri_length: max_uri_length(doc),
162
+ source_location: doc.reader.cursor_at_mark,
163
+ http_client: KrokiHttpClient
164
+ }, logger)
155
165
  if TEXT_FORMATS.include?(format)
156
166
  text_content = kroki_client.text_content(kroki_diagram)
157
167
  block = processor.create_block(parent, 'literal', text_content, attrs)
@@ -164,6 +174,7 @@ module AsciidoctorExtensions
164
174
  block.assign_caption(caption, 'figure')
165
175
  block
166
176
  end
177
+ # rubocop:enable Metrics/AbcSize
167
178
 
168
179
  private
169
180
 
@@ -174,9 +185,10 @@ module AsciidoctorExtensions
174
185
  plantuml_include_path = doc.normalize_system_path(doc.attr('kroki-plantuml-include'))
175
186
  if ::File.readable? plantuml_include_path
176
187
  config = File.read(plantuml_include_path)
177
- diagram_text = config + "\n" + diagram_text
188
+ diagram_text = "#{config}\n#{diagram_text}"
178
189
  else
179
- logger.warn "Unable to read plantuml-include. File not found or not readable: #{plantuml_include_path}."
190
+ logger.warn message_with_context "Unable to read plantuml-include. File not found or not readable: #{plantuml_include_path}.",
191
+ source_location: doc.reader.cursor_at_mark
180
192
  end
181
193
  end
182
194
  diagram_text
@@ -205,13 +217,13 @@ module AsciidoctorExtensions
205
217
  end
206
218
 
207
219
  def get_format(doc, attrs, diagram_type)
208
- format = attrs['format'] || 'svg'
209
- # The JavaFX preview doesn't support SVG well, therefore we'll use PNG format...
210
- if doc.attr?('env-idea') && format == 'svg'
211
- # ... unless the diagram library does not support PNG as output format!
220
+ format = attrs['format'] || doc.attr('kroki-default-format') || 'svg'
221
+ if format == 'png'
222
+ # redirect PNG format to SVG if the diagram library only supports SVG as output format.
223
+ # this is useful when the default format has been set to PNG
212
224
  # Currently, mermaid, nomnoml, svgbob, wavedrom only support SVG as output format.
213
- svg_only_diagram_types = %w[:mermaid :nomnoml :svgbob :wavedrom]
214
- format = 'png' unless svg_only_diagram_types.include?(diagram_type)
225
+ svg_only_diagram_types = %i[mermaid nomnoml svgbob wavedrom]
226
+ format = 'svg' if svg_only_diagram_types.include?(diagram_type)
215
227
  end
216
228
  format
217
229
  end
@@ -240,10 +252,9 @@ module AsciidoctorExtensions
240
252
  images_dir = doc.attr('imagesdir', '')
241
253
  if (images_output_dir = doc.attr('imagesoutdir'))
242
254
  images_output_dir
243
- elsif (out_dir = doc.attr('outdir'))
255
+ # the nested document logic will become obsolete once https://github.com/asciidoctor/asciidoctor/commit/7edc9da023522be67b17e2a085d72e056703a438 is released
256
+ elsif (out_dir = doc.attr('outdir') || (doc.nested? ? doc.parent_document : doc).options[:to_dir])
244
257
  File.join(out_dir, images_dir)
245
- elsif (to_dir = doc.attr('to_dir'))
246
- File.join(to_dir, images_dir)
247
258
  else
248
259
  File.join(doc.base_dir, images_dir)
249
260
  end
@@ -258,14 +269,13 @@ module AsciidoctorExtensions
258
269
  require 'zlib'
259
270
  require 'digest'
260
271
 
261
- attr_reader :type
262
- attr_reader :text
263
- attr_reader :format
272
+ attr_reader :type, :text, :format, :target
264
273
 
265
- def initialize(type, format, text)
274
+ def initialize(type, format, text, target = nil)
266
275
  @text = text
267
276
  @type = type
268
277
  @format = format
278
+ @target = target
269
279
  end
270
280
 
271
281
  def get_diagram_uri(server_url)
@@ -278,23 +288,21 @@ module AsciidoctorExtensions
278
288
 
279
289
  def save(output_dir_path, kroki_client)
280
290
  diagram_url = get_diagram_uri(kroki_client.server_url)
281
- diagram_name = "diag-#{Digest::SHA256.hexdigest diagram_url}.#{@format}"
291
+ diagram_name = "#{@target || 'diag'}-#{Digest::SHA256.hexdigest diagram_url}.#{@format}"
282
292
  file_path = File.join(output_dir_path, diagram_name)
283
- encoding = if @format == 'txt' || @format == 'atxt' || @format == 'utxt'
293
+ encoding = case @format
294
+ when 'txt', 'atxt', 'utxt', 'svg'
284
295
  'utf8'
285
- elsif @format == 'svg'
286
- 'binary'
287
296
  else
288
297
  'binary'
289
298
  end
290
299
  # file is either (already) on the file system or we should read it from Kroki
291
- contents = File.exist?(file_path) ? File.open(file_path, &:read) : kroki_client.get_image(self, encoding)
292
- FileUtils.mkdir_p(output_dir_path)
293
- if encoding == 'binary'
294
- File.binwrite(file_path, contents)
295
- else
296
- File.write(file_path, contents)
300
+ unless File.exist?(file_path)
301
+ contents = kroki_client.get_image(self, encoding)
302
+ FileUtils.mkdir_p(output_dir_path)
303
+ File.write(file_path, contents, mode: 'wb')
297
304
  end
305
+
298
306
  diagram_name
299
307
  end
300
308
 
@@ -303,12 +311,12 @@ module AsciidoctorExtensions
303
311
  def _join_uri_segments(base, *uris)
304
312
  segments = []
305
313
  # remove trailing slashes
306
- segments.push(base.gsub(%r{[/]+$}, ''))
314
+ segments.push(base.gsub(%r{/+$}, ''))
307
315
  segments.concat(uris.map do |uri|
308
316
  # remove leading and trailing slashes
309
317
  uri.to_s
310
- .gsub(%r{^[/]+}, '')
311
- .gsub(%r{[/]+$}, '')
318
+ .gsub(%r{^/+}, '')
319
+ .gsub(%r{/+$}, '')
312
320
  end)
313
321
  segments.join('/')
314
322
  end
@@ -317,21 +325,23 @@ module AsciidoctorExtensions
317
325
  # Kroki client
318
326
  #
319
327
  class KrokiClient
320
- attr_reader :server_url
321
- attr_reader :method
322
- attr_reader :max_uri_length
328
+ include Asciidoctor::Logging
329
+
330
+ attr_reader :server_url, :method, :max_uri_length
323
331
 
324
332
  SUPPORTED_HTTP_METHODS = %w[get post adaptive].freeze
325
333
 
326
- def initialize(server_url, http_method, http_client, logger = ::Asciidoctor::LoggerManager.logger, max_uri_length = 4000)
327
- @server_url = server_url
328
- @max_uri_length = max_uri_length
329
- @http_client = http_client
330
- method = (http_method || 'adaptive').downcase
334
+ def initialize(opts, logger = ::Asciidoctor::LoggerManager.logger)
335
+ @server_url = opts[:server_url]
336
+ @max_uri_length = opts.fetch(:max_uri_length, 4000)
337
+ @http_client = opts[:http_client]
338
+ method = opts.fetch(:http_method, 'adaptive').downcase
331
339
  if SUPPORTED_HTTP_METHODS.include?(method)
332
340
  @method = method
333
341
  else
334
- logger.warn "Invalid value '#{method}' for kroki-http-method attribute. The value must be either: 'get', 'post' or 'adaptive'. Proceeding using: 'adaptive'."
342
+ logger.warn message_with_context "Invalid value '#{method}' for kroki-http-method attribute. The value must be either: " \
343
+ "'get', 'post' or 'adaptive'. Proceeding using: 'adaptive'.",
344
+ source_location: opts[:source_location]
335
345
  @method = 'adaptive'
336
346
  end
337
347
  end
@@ -372,12 +382,28 @@ module AsciidoctorExtensions
372
382
  require 'json'
373
383
 
374
384
  class << self
385
+ REFERER = "asciidoctor/kroki.rb/#{Asciidoctor::AsciidoctorKroki::VERSION}"
386
+
375
387
  def get(uri, _)
376
- ::OpenURI.open_uri(uri, 'r', &:read)
388
+ uri = URI(uri)
389
+ request = ::Net::HTTP::Get.new(uri)
390
+ request['referer'] = REFERER
391
+ ::Net::HTTP.start(
392
+ uri.hostname,
393
+ uri.port,
394
+ use_ssl: (uri.scheme == 'https')
395
+ ) do |http|
396
+ http.request(request).body
397
+ end
377
398
  end
378
399
 
379
400
  def post(uri, data, _)
380
- res = ::Net::HTTP.request_post(uri, data)
401
+ res = ::Net::HTTP.post(
402
+ URI(uri),
403
+ data,
404
+ 'Content-Type' => 'text/plain',
405
+ 'Referer' => REFERER
406
+ )
381
407
  res.body
382
408
  end
383
409
  end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Asciidoctor
4
+ module AsciidoctorKroki
5
+ VERSION = '0.6.0'
6
+ end
7
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'asciidoctor/extensions' unless RUBY_ENGINE == 'opal'
4
+ require_relative 'asciidoctor_kroki/version'
4
5
  require_relative 'asciidoctor_kroki/extension'
5
6
 
6
7
  Asciidoctor::Extensions.register do
@@ -1,3 +1,4 @@
1
+ # rubocop:disable Lint/ConstantDefinitionInBlock
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require 'rspec_helper'
@@ -88,7 +89,7 @@ describe ::AsciidoctorExtensions::KrokiBlockMacroProcessor do
88
89
  </div>
89
90
  </div>)
90
91
  end
91
- it 'should display unresolved block macro message when the traget cannot be resolved' do
92
+ it 'should display unresolved block macro message when the target cannot be resolved' do
92
93
  # noinspection RubyClassModuleNamingConvention
93
94
  class UnresolvedTargetKrokiBlockMacroProcessor < ::AsciidoctorExtensions::KrokiBlockMacroProcessor
94
95
  def resolve_target_path(_target)
@@ -103,7 +104,7 @@ describe ::AsciidoctorExtensions::KrokiBlockMacroProcessor do
103
104
  ADOC
104
105
  output = Asciidoctor.convert(input, standalone: false, extension_registry: registry)
105
106
  (expect output).to eql %(<div class="paragraph">
106
- <p>Unresolved block macro - plantuml::[]</p>
107
+ <p>Unresolved block macro - plantuml::alice.puml[]</p>
107
108
  </div>)
108
109
  end
109
110
  it 'should override the unresolved block macro message' do
@@ -126,3 +127,4 @@ describe ::AsciidoctorExtensions::KrokiBlockMacroProcessor do
126
127
  end
127
128
  end
128
129
  end
130
+ # rubocop:enable Lint/ConstantDefinitionInBlock
@@ -7,27 +7,27 @@ require_relative '../lib/asciidoctor/extensions/asciidoctor_kroki'
7
7
  describe ::AsciidoctorExtensions::KrokiClient do
8
8
  it 'should use adaptive method when http method is invalid' do
9
9
  kroki_http_client = ::AsciidoctorExtensions::KrokiHttpClient
10
- kroki_client = ::AsciidoctorExtensions::KrokiClient.new('http://localhost:8000', 'patch', kroki_http_client)
10
+ kroki_client = ::AsciidoctorExtensions::KrokiClient.new(server_url: 'http://localhost:8000', http_method: 'patch', http_client: kroki_http_client)
11
11
  expect(kroki_client.method).to eq('adaptive')
12
12
  end
13
13
  it 'should use post method when http method is post' do
14
14
  kroki_http_client = ::AsciidoctorExtensions::KrokiHttpClient
15
- kroki_client = ::AsciidoctorExtensions::KrokiClient.new('http://localhost:8000', 'POST', kroki_http_client)
15
+ kroki_client = ::AsciidoctorExtensions::KrokiClient.new(server_url: 'http://localhost:8000', http_method: 'POST', http_client: kroki_http_client)
16
16
  expect(kroki_client.method).to eq('post')
17
17
  end
18
18
  it 'should use get method when http method is get' do
19
19
  kroki_http_client = ::AsciidoctorExtensions::KrokiHttpClient
20
- kroki_client = ::AsciidoctorExtensions::KrokiClient.new('http://localhost:8000', 'get', kroki_http_client)
20
+ kroki_client = ::AsciidoctorExtensions::KrokiClient.new(server_url: 'http://localhost:8000', http_method: 'get', http_client: kroki_http_client)
21
21
  expect(kroki_client.method).to eq('get')
22
22
  end
23
23
  it 'should use 4000 as the default max URI length' do
24
24
  kroki_http_client = ::AsciidoctorExtensions::KrokiHttpClient
25
- kroki_client = ::AsciidoctorExtensions::KrokiClient.new('http://localhost:8000', 'get', kroki_http_client)
25
+ kroki_client = ::AsciidoctorExtensions::KrokiClient.new(server_url: 'http://localhost:8000', http_method: 'get', http_client: kroki_http_client)
26
26
  expect(kroki_client.max_uri_length).to eq(4000)
27
27
  end
28
28
  it 'should use a custom value as max URI length' do
29
29
  kroki_http_client = ::AsciidoctorExtensions::KrokiHttpClient
30
- kroki_client = ::AsciidoctorExtensions::KrokiClient.new('http://localhost:8000', 'get', kroki_http_client, nil, 8000)
30
+ kroki_client = ::AsciidoctorExtensions::KrokiClient.new(server_url: 'http://localhost:8000', http_method: 'get', http_client: kroki_http_client, max_uri_length: 8000)
31
31
  expect(kroki_client.max_uri_length).to eq(8000)
32
32
  end
33
33
  it 'should get an image with POST request if the URI length is greater than the value configured' do
@@ -55,7 +55,7 @@ describe ::AsciidoctorExtensions::KrokiClient do
55
55
  'diagram-uri'
56
56
  end
57
57
  end.new('type', 'format', 'text')
58
- kroki_client = ::AsciidoctorExtensions::KrokiClient.new('http://localhost:8000', 'adaptive', kroki_http_client, nil, 10)
58
+ kroki_client = ::AsciidoctorExtensions::KrokiClient.new(server_url: 'http://localhost:8000', http_method: 'adaptive', http_client: kroki_http_client, max_uri_length: 10)
59
59
  result = kroki_client.get_image(kroki_diagram, 'utf8')
60
60
  expect(result).to eq('POST http://localhost:8000/type/format - text')
61
61
  end
@@ -84,7 +84,7 @@ describe ::AsciidoctorExtensions::KrokiClient do
84
84
  'diagram-uri'
85
85
  end
86
86
  end.new('type', 'format', 'text')
87
- kroki_client = ::AsciidoctorExtensions::KrokiClient.new('http://localhost:8000', 'adaptive', kroki_http_client, nil, 11)
87
+ kroki_client = ::AsciidoctorExtensions::KrokiClient.new(server_url: 'http://localhost:8000', http_method: 'adaptive', http_client: kroki_http_client, max_uri_length: 11)
88
88
  result = kroki_client.get_image(kroki_diagram, 'utf8')
89
89
  expect(result).to eq('GET diagram-uri')
90
90
  end
@@ -28,11 +28,32 @@ describe ::AsciidoctorExtensions::KrokiDiagram do
28
28
  it 'should fetch a diagram from Kroki and save it to disk' do
29
29
  kroki_diagram = ::AsciidoctorExtensions::KrokiDiagram.new('plantuml', 'txt', ' alice -> bob: hello')
30
30
  kroki_http_client = ::AsciidoctorExtensions::KrokiHttpClient
31
- kroki_client = ::AsciidoctorExtensions::KrokiClient.new('https://kroki.io', 'get', kroki_http_client)
31
+ kroki_client = ::AsciidoctorExtensions::KrokiClient.new(server_url: 'https://kroki.io', http_method: 'get', http_client: kroki_http_client)
32
32
  output_dir_path = "#{__dir__}/../.asciidoctor/kroki"
33
33
  diagram_name = kroki_diagram.save(output_dir_path, kroki_client)
34
34
  diagram_path = File.join(output_dir_path, diagram_name)
35
- expect(File.exist?(diagram_path)).to be_truthy, "expected diagram to be saved at #{diagram_path}"
35
+ expect(File.exist?(diagram_path)).to be_truthy, "diagram should be saved at: #{diagram_path}"
36
+ content = <<-TXT.chomp
37
+ ,-----. ,---.
38
+ |alice| |bob|
39
+ `--+--' `-+-'
40
+ | hello |
41
+ |-------------->|
42
+ ,--+--. ,-+-.
43
+ |alice| |bob|
44
+ `-----' `---'
45
+ TXT
46
+ expect(File.read(diagram_path).split("\n").map(&:rstrip).join("\n")).to eq(content)
47
+ end
48
+ it 'should fetch a diagram from Kroki and save it to disk using the target name' do
49
+ kroki_diagram = ::AsciidoctorExtensions::KrokiDiagram.new('plantuml', 'txt', ' alice -> bob: hello', 'hello-world')
50
+ kroki_http_client = ::AsciidoctorExtensions::KrokiHttpClient
51
+ kroki_client = ::AsciidoctorExtensions::KrokiClient.new(server_url: 'https://kroki.io', http_method: 'get', http_client: kroki_http_client)
52
+ output_dir_path = "#{__dir__}/../.asciidoctor/kroki"
53
+ diagram_name = kroki_diagram.save(output_dir_path, kroki_client)
54
+ diagram_path = File.join(output_dir_path, diagram_name)
55
+ expect(diagram_name).to start_with('hello-world-'), "diagram name should use the target as a prefix, got: #{diagram_name}"
56
+ expect(File.exist?(diagram_path)).to be_truthy, "diagram should be saved at: #{diagram_path}"
36
57
  content = <<-TXT.chomp
37
58
  ,-----. ,---.
38
59
  |alice| |bob|
@@ -48,14 +69,16 @@ describe ::AsciidoctorExtensions::KrokiDiagram do
48
69
  it 'should fetch a diagram from Kroki with the same definition only once' do
49
70
  kroki_diagram = ::AsciidoctorExtensions::KrokiDiagram.new('plantuml', 'png', ' guillaume -> dan: hello')
50
71
  kroki_http_client = ::AsciidoctorExtensions::KrokiHttpClient
51
- kroki_client = ::AsciidoctorExtensions::KrokiClient.new('https://kroki.io', 'get', kroki_http_client)
72
+ kroki_client = ::AsciidoctorExtensions::KrokiClient.new(server_url: 'https://kroki.io', http_method: 'get', http_client: kroki_http_client)
52
73
  output_dir_path = "#{__dir__}/../.asciidoctor/kroki"
53
74
  # make sure that we are doing only one GET request
54
- expect(kroki_http_client).to receive(:get).once
75
+ diagram_contents = File.read("#{__dir__}/fixtures/plantuml-diagram.png", mode: 'rb')
76
+ expect(kroki_http_client).to receive(:get).once.and_return(diagram_contents)
55
77
  diagram_name = kroki_diagram.save(output_dir_path, kroki_client)
56
78
  diagram_path = File.join(output_dir_path, diagram_name)
57
- expect(File.exist?(diagram_path)).to be_truthy, "expected diagram to be saved at #{diagram_path}"
79
+ expect(File.exist?(diagram_path)).to be_truthy, "diagram should be saved at: #{diagram_path}"
58
80
  # calling again... should read the file from disk (and not do a GET request)
59
81
  kroki_diagram.save(output_dir_path, kroki_client)
82
+ expect(File.size(diagram_path)).to be_eql(diagram_contents.length), 'diagram should be fully saved on disk'
60
83
  end
61
84
  end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rspec_helper'
4
+ require 'asciidoctor'
5
+ require_relative '../lib/asciidoctor/extensions/asciidoctor_kroki'
6
+
7
+ describe '::AsciidoctorExtensions::KrokiProcessor' do
8
+ it 'should return the images output directory (imagesoutdir attribute)' do
9
+ doc = Asciidoctor.load('hello', attributes: { 'imagesoutdir' => '.asciidoctor/kroki/images', 'imagesdir' => '../images' })
10
+ output_dir_path = AsciidoctorExtensions::KrokiProcessor.send(:output_dir_path, doc)
11
+ expect(output_dir_path).to eq '.asciidoctor/kroki/images'
12
+ end
13
+ it 'should return a path relative to output directory (to_dir option)' do
14
+ doc = Asciidoctor.load('hello', to_dir: '.asciidoctor/kroki/relative', attributes: { 'imagesdir' => '../images' })
15
+ output_dir_path = AsciidoctorExtensions::KrokiProcessor.send(:output_dir_path, doc)
16
+ expect(output_dir_path).to eq '.asciidoctor/kroki/relative/../images'
17
+ end
18
+ it 'should return a path relative to output directory (outdir attribute)' do
19
+ doc = Asciidoctor.load('hello', attributes: { 'imagesdir' => 'resources/images', 'outdir' => '.asciidoctor/kroki/out' })
20
+ output_dir_path = AsciidoctorExtensions::KrokiProcessor.send(:output_dir_path, doc)
21
+ expect(output_dir_path).to eq '.asciidoctor/kroki/out/resources/images'
22
+ end
23
+ it 'should return a path relative to the base directory (base_dir option)' do
24
+ doc = Asciidoctor.load('hello', base_dir: '.asciidoctor/kroki', attributes: { 'imagesdir' => 'img' })
25
+ output_dir_path = AsciidoctorExtensions::KrokiProcessor.send(:output_dir_path, doc)
26
+ expect(output_dir_path).to eq "#{::Dir.pwd}/.asciidoctor/kroki/img"
27
+ end
28
+ it 'should return a path relative to the base directory (default value is current working directory)' do
29
+ doc = Asciidoctor.load('hello', attributes: { 'imagesdir' => 'img' })
30
+ output_dir_path = AsciidoctorExtensions::KrokiProcessor.send(:output_dir_path, doc)
31
+ expect(output_dir_path).to eq "#{::Dir.pwd}/img"
32
+ end
33
+ end
@@ -20,18 +20,33 @@ describe ::AsciidoctorExtensions::KrokiBlockProcessor do
20
20
  </div>
21
21
  </div>)
22
22
  end
23
- it 'should use png if env-idea is defined' do
23
+ it 'should use png if kroki-default-format is set to png' do
24
24
  input = <<~'ADOC'
25
25
  [plantuml]
26
26
  ....
27
27
  alice -> bob: hello
28
28
  ....
29
29
  ADOC
30
- output = Asciidoctor.convert(input, attributes: { 'env-idea' => '' }, standalone: false)
30
+ output = Asciidoctor.convert(input, attributes: { 'kroki-default-format' => 'png' }, standalone: false)
31
31
  (expect output).to eql %(<div class="imageblock kroki">
32
32
  <div class="content">
33
33
  <img src="https://kroki.io/plantuml/png/eNpLzMlMTlXQtVNIyk-yUshIzcnJBwA9iwZL" alt="Diagram">
34
34
  </div>
35
+ </div>)
36
+ end
37
+ it 'should use svg if kroki-default-format is set to png and the diagram type does not support png' do
38
+ input = <<~'ADOC'
39
+ [mermaid]
40
+ ....
41
+ graph TD;
42
+ A-->B;
43
+ ....
44
+ ADOC
45
+ output = Asciidoctor.convert(input, attributes: { 'kroki-default-format' => 'png' }, standalone: false)
46
+ (expect output).to eql %(<div class="imageblock kroki">
47
+ <div class="content">
48
+ <img src="https://kroki.io/mermaid/svg/eNpLL0osyFAIcbHmUlBw1NW1c7IGADLKBKY=" alt="Diagram">
49
+ </div>
35
50
  </div>)
36
51
  end
37
52
  it 'should include the plantuml-include file when safe mode is safe' do
@@ -41,10 +56,12 @@ describe ::AsciidoctorExtensions::KrokiBlockProcessor do
41
56
  alice -> bob: hello
42
57
  ....
43
58
  ADOC
44
- output = Asciidoctor.convert(input, attributes: { 'env-idea' => '', 'kroki-plantuml-include' => 'spec/fixtures/config.puml' }, standalone: false, safe: :safe)
59
+ output = Asciidoctor.convert(input,
60
+ attributes: { 'kroki-plantuml-include' => 'spec/fixtures/config.puml' },
61
+ standalone: false, safe: :safe)
45
62
  (expect output).to eql %(<div class="imageblock kroki">
46
63
  <div class="content">
47
- <img src="https://kroki.io/plantuml/png/eNorzs7MK0gsSsxVyM3Py0_OKMrPTVUoKSpN5eJKzMlMTlXQtVNIyk-yUshIzcnJBwCT9xBc" alt="Diagram">
64
+ <img src="https://kroki.io/plantuml/svg/eNorzs7MK0gsSsxVyM3Py0_OKMrPTVUoKSpN5eJKzMlMTlXQtVNIyk-yUshIzcnJBwCT9xBc" alt="Diagram">
48
65
  </div>
49
66
  </div>)
50
67
  end
@@ -55,10 +72,10 @@ describe ::AsciidoctorExtensions::KrokiBlockProcessor do
55
72
  alice -> bob: hello
56
73
  ....
57
74
  ADOC
58
- output = Asciidoctor.convert(input, attributes: { 'env-idea' => '', 'kroki-plantuml-include' => '../../../spec/fixtures/config.puml' }, standalone: false, safe: :safe)
75
+ output = Asciidoctor.convert(input, attributes: { 'kroki-plantuml-include' => '../../../spec/fixtures/config.puml' }, standalone: false, safe: :safe)
59
76
  (expect output).to eql %(<div class="imageblock kroki">
60
77
  <div class="content">
61
- <img src="https://kroki.io/plantuml/png/eNorzs7MK0gsSsxVyM3Py0_OKMrPTVUoKSpN5eJKzMlMTlXQtVNIyk-yUshIzcnJBwCT9xBc" alt="Diagram">
78
+ <img src="https://kroki.io/plantuml/svg/eNorzs7MK0gsSsxVyM3Py0_OKMrPTVUoKSpN5eJKzMlMTlXQtVNIyk-yUshIzcnJBwCT9xBc" alt="Diagram">
62
79
  </div>
63
80
  </div>)
64
81
  end
@@ -69,10 +86,10 @@ describe ::AsciidoctorExtensions::KrokiBlockProcessor do
69
86
  alice -> bob: hello
70
87
  ....
71
88
  ADOC
72
- output = Asciidoctor.convert(input, attributes: { 'env-idea' => '', 'kroki-plantuml-include' => '/etc/passwd' }, standalone: false, safe: :safe)
89
+ output = Asciidoctor.convert(input, attributes: { 'kroki-plantuml-include' => '/etc/passwd' }, standalone: false, safe: :safe)
73
90
  (expect output).to eql %(<div class="imageblock kroki">
74
91
  <div class="content">
75
- <img src="https://kroki.io/plantuml/png/eNpLzMlMTlXQtVNIyk-yUshIzcnJBwA9iwZL" alt="Diagram">
92
+ <img src="https://kroki.io/plantuml/svg/eNpLzMlMTlXQtVNIyk-yUshIzcnJBwA9iwZL" alt="Diagram">
76
93
  </div>
77
94
  </div>)
78
95
  end
@@ -83,10 +100,10 @@ describe ::AsciidoctorExtensions::KrokiBlockProcessor do
83
100
  alice -> bob: hello
84
101
  ....
85
102
  ADOC
86
- output = Asciidoctor.convert(input, attributes: { 'env-idea' => '', 'kroki-plantuml-include' => 'spec/fixtures/config.puml' }, standalone: false, safe: :secure)
103
+ output = Asciidoctor.convert(input, attributes: { 'kroki-plantuml-include' => 'spec/fixtures/config.puml' }, standalone: false, safe: :secure)
87
104
  (expect output).to eql %(<div class="imageblock kroki">
88
105
  <div class="content">
89
- <img src="https://kroki.io/plantuml/png/eNpLzMlMTlXQtVNIyk-yUshIzcnJBwA9iwZL" alt="Diagram">
106
+ <img src="https://kroki.io/plantuml/svg/eNpLzMlMTlXQtVNIyk-yUshIzcnJBwA9iwZL" alt="Diagram">
90
107
  </div>
91
108
  </div>)
92
109
  end
@@ -134,7 +151,7 @@ describe ::AsciidoctorExtensions::KrokiBlockProcessor do
134
151
  it 'should instantiate block processor without warning' do
135
152
  original_stderr = $stderr
136
153
  $stderr = StringIO.new
137
- ::AsciidoctorExtensions::KrokiBlockProcessor.new 'plantuml'.to_sym, {}
154
+ ::AsciidoctorExtensions::KrokiBlockProcessor.new :plantuml, {}
138
155
  output = $stderr.string
139
156
  (expect output).to eql ''
140
157
  ensure
@@ -146,7 +163,7 @@ end
146
163
  describe ::AsciidoctorExtensions::Kroki do
147
164
  it 'should return the list of supported diagrams' do
148
165
  diagram_names = ::AsciidoctorExtensions::Kroki::SUPPORTED_DIAGRAM_NAMES
149
- expect(diagram_names).to include('vegalite', 'plantuml', 'bytefield', 'bpmn', 'excalidraw', 'wavedrom', 'pikchr')
166
+ expect(diagram_names).to include('vegalite', 'plantuml', 'bytefield', 'bpmn', 'excalidraw', 'wavedrom', 'pikchr', 'structurizr')
150
167
  end
151
168
  it 'should register the extension for the list of supported diagrams' do
152
169
  doc = Asciidoctor::Document.new
Binary file
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.5.0
4
+ version: 0.6.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: 2021-07-05 00:00:00.000000000 Z
11
+ date: 2022-06-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor
@@ -30,42 +30,42 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 12.3.2
33
+ version: 13.0.6
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 12.3.2
40
+ version: 13.0.6
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 3.8.0
47
+ version: 3.10.0
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 3.8.0
54
+ version: 3.10.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rubocop
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 0.74.0
61
+ version: '1.30'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 0.74.0
68
+ version: '1.30'
69
69
  description: An extension for Asciidoctor to convert diagrams to images using https://kroki.io
70
70
  email:
71
71
  - ggrossetie@yuzutech.fr
@@ -84,13 +84,16 @@ files:
84
84
  - lib/asciidoctor-kroki.rb
85
85
  - lib/asciidoctor/extensions/asciidoctor_kroki.rb
86
86
  - lib/asciidoctor/extensions/asciidoctor_kroki/extension.rb
87
+ - lib/asciidoctor/extensions/asciidoctor_kroki/version.rb
87
88
  - spec/.rubocop.yml
88
89
  - spec/asciidoctor_kroki_block_macro_spec.rb
89
90
  - spec/asciidoctor_kroki_client_spec.rb
90
91
  - spec/asciidoctor_kroki_diagram_spec.rb
92
+ - spec/asciidoctor_kroki_processor_spec.rb
91
93
  - spec/asciidoctor_kroki_spec.rb
92
94
  - spec/fixtures/alice.puml
93
95
  - spec/fixtures/config.puml
96
+ - spec/fixtures/plantuml-diagram.png
94
97
  - spec/require_spec.rb
95
98
  - spec/rspec_helper.rb
96
99
  - tasks/bundler.rake
@@ -102,6 +105,7 @@ licenses:
102
105
  metadata:
103
106
  bug_tracker_uri: https://github.com/Mogztter/asciidoctor-kroki/issues
104
107
  source_code_uri: https://github.com/Mogztter/asciidoctor-kroki
108
+ rubygems_mfa_required: 'true'
105
109
  post_install_message:
106
110
  rdoc_options: []
107
111
  require_paths:
@@ -121,16 +125,4 @@ rubygems_version: 3.1.6
121
125
  signing_key:
122
126
  specification_version: 4
123
127
  summary: Asciidoctor extension to convert diagrams to images using Kroki
124
- test_files:
125
- - spec/.rubocop.yml
126
- - spec/asciidoctor_kroki_block_macro_spec.rb
127
- - spec/asciidoctor_kroki_client_spec.rb
128
- - spec/asciidoctor_kroki_diagram_spec.rb
129
- - spec/asciidoctor_kroki_spec.rb
130
- - spec/fixtures/alice.puml
131
- - spec/fixtures/config.puml
132
- - spec/require_spec.rb
133
- - spec/rspec_helper.rb
134
- - tasks/bundler.rake
135
- - tasks/lint.rake
136
- - tasks/rspec.rake
128
+ test_files: []