asciidoctor-kroki 0.3.0 → 0.4.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: c68a706bac6918c95daef5ada0de0d6a8471cbd69cc83ced875119ca69b90f58
4
- data.tar.gz: c2683ddf3c70e743faff32a73442ef651fd17145191148e4a5930ac7d16852f9
3
+ metadata.gz: dfa0c461bdb74571b618747d791e059125dc09a5e67dd6886861101fe972237f
4
+ data.tar.gz: d882ff8e33c787b3a1578eb7d11b590411e18f594eaec188d7f06ffc182a3b11
5
5
  SHA512:
6
- metadata.gz: 45ea1d0252ebfab9fc9dfba56b13a3497ddf1e5ca58cb05777c941829ec2316f0f194a87bef490483c800d43cd7cf0e008804cb4f92ad4955cc864203ad26dfb
7
- data.tar.gz: 3fec5d036175f848b0fa26df6c47439ee2f61a776393c097ecb0e79e0f407939e99df233bb1461360feaf4aae4224377aadff7bbc9d93ffa6fad6af62f7fc40e
6
+ metadata.gz: f72b7293f3fb8c6d37b456c39d4e2691c0b65e1cb908d5f3f29d23466f0c51135b9977dd0977a2ccac7adb667b4fc5071a4a5fc59bed6a3304154bddc8efda3d
7
+ data.tar.gz: 1e93fbf9df1cab9282f7743f76331ea6caddfdce150fff36fb7aa7222d561d089c31101ec0f16a939f5aa2c0c7dd5a09206059700974b76ae6fadcfc0150acd3
data/.rubocop.yml CHANGED
@@ -1,8 +1,14 @@
1
1
  Style/Encoding:
2
2
  Enabled: false
3
3
 
4
+ Layout/EndOfLine:
5
+ EnforcedStyle: lf
6
+
4
7
  Metrics/LineLength:
5
- Max: 160
8
+ Max: 180
9
+
10
+ Metrics/ClassLength:
11
+ Max: 150
6
12
 
7
13
  Metrics/MethodLength:
8
14
  Max: 50
@@ -15,3 +21,6 @@ Metrics/PerceivedComplexity:
15
21
 
16
22
  Metrics/AbcSize:
17
23
  Max: 30
24
+
25
+ Metrics/ParameterLists:
26
+ Max: 7
data/Gemfile.lock CHANGED
@@ -1,13 +1,13 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- asciidoctor-kroki (0.3.0)
4
+ asciidoctor-kroki (0.4.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)
10
+ asciidoctor (2.0.11)
11
11
  ast (2.4.1)
12
12
  diff-lcs (1.3)
13
13
  jaro_winkler (1.5.4)
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'asciidoctor-kroki'
5
- s.version = '0.3.0'
5
+ s.version = '0.4.0'
6
6
  s.summary = 'Asciidoctor extension to convert diagrams to images using Kroki'
7
7
  s.description = 'An extension for Asciidoctor to convert diagrams to images using https://kroki.io'
8
8
 
@@ -15,11 +15,24 @@ module AsciidoctorExtensions
15
15
  on_context :listing, :literal
16
16
  name_positional_attributes 'target', 'format'
17
17
 
18
+ # @param name [String] name of the block macro (optional)
19
+ # @param config [Hash] a config hash (optional)
20
+ # @param logger [Logger] a logger used to log warning and errors (optional)
21
+ #
22
+ def initialize(name = nil, config = {}, logger: ::Asciidoctor::LoggerManager.logger)
23
+ super(name, config)
24
+ @logger = logger
25
+ end
26
+
18
27
  def process(parent, reader, attrs)
19
28
  diagram_type = @name
20
29
  diagram_text = reader.string
21
- KrokiProcessor.process(self, parent, attrs, diagram_type, diagram_text)
30
+ KrokiProcessor.process(self, parent, attrs, diagram_type, diagram_text, @logger)
22
31
  end
32
+
33
+ protected
34
+
35
+ attr_reader :logger
23
36
  end
24
37
 
25
38
  # A block macro extension that converts a diagram into an image.
@@ -29,11 +42,48 @@ module AsciidoctorExtensions
29
42
 
30
43
  name_positional_attributes 'format'
31
44
 
45
+ # @param name [String] name of the block macro (optional)
46
+ # @param config [Hash] a config hash (optional)
47
+ # @param logger [Logger] a logger used to log warning and errors (optional)
48
+ #
49
+ def initialize(name = nil, config = {}, logger: ::Asciidoctor::LoggerManager.logger)
50
+ super(name, config)
51
+ @logger = logger
52
+ end
53
+
32
54
  def process(parent, target, attrs)
33
55
  diagram_type = @name
34
56
  target = parent.apply_subs(target, [:attributes])
35
- diagram_text = read(target)
36
- KrokiProcessor.process(self, parent, attrs, diagram_type, diagram_text)
57
+
58
+ unless read_allowed?(target)
59
+ link = create_inline(parent, :anchor, target, type: :link, target: target)
60
+ return create_block(parent, :paragraph, link.convert, {}, content_model: :raw)
61
+ end
62
+
63
+ 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), {})
66
+ end
67
+
68
+ begin
69
+ diagram_text = read(path)
70
+ rescue => e # rubocop:disable RescueStandardError
71
+ logger.error "Failed to read #{diagram_type} file: #{path}. #{e}."
72
+ return create_block(parent, 'paragraph', unresolved_block_macro_message(diagram_type, path), {})
73
+ end
74
+ KrokiProcessor.process(self, parent, attrs, diagram_type, diagram_text, @logger)
75
+ end
76
+
77
+ protected
78
+
79
+ attr_reader :logger
80
+
81
+ def resolve_target_path(target)
82
+ target
83
+ end
84
+
85
+ def read_allowed?(_target)
86
+ true
37
87
  end
38
88
 
39
89
  def read(target)
@@ -44,6 +94,10 @@ module AsciidoctorExtensions
44
94
  File.open(target, &:read)
45
95
  end
46
96
  end
97
+
98
+ def unresolved_block_macro_message(name, target)
99
+ "Unresolved block macro - #{name}::#{target}[]"
100
+ end
47
101
  end
48
102
 
49
103
  # Kroki API
@@ -70,7 +124,7 @@ module AsciidoctorExtensions
70
124
  umlet
71
125
  vega
72
126
  vegalite
73
- wavedrow
127
+ wavedrom
74
128
  ].freeze
75
129
  end
76
130
 
@@ -80,9 +134,9 @@ module AsciidoctorExtensions
80
134
  TEXT_FORMATS = %w[txt atxt utxt].freeze
81
135
 
82
136
  class << self
83
- def process(processor, parent, attrs, diagram_type, diagram_text)
137
+ def process(processor, parent, attrs, diagram_type, diagram_text, logger)
84
138
  doc = parent.document
85
- diagram_text = prepend_plantuml_config(diagram_text, diagram_type, doc)
139
+ diagram_text = prepend_plantuml_config(diagram_text, diagram_type, doc, logger)
86
140
  # If "subs" attribute is specified, substitute accordingly.
87
141
  # Be careful not to specify "specialcharacters" or your diagram code won't be valid anymore!
88
142
  if (subs = attrs['subs'])
@@ -96,7 +150,7 @@ module AsciidoctorExtensions
96
150
  attrs['role'] = get_role(format, role)
97
151
  attrs['format'] = format
98
152
  kroki_diagram = KrokiDiagram.new(diagram_type, format, diagram_text)
99
- kroki_client = KrokiClient.new(server_url(doc), http_method(doc), KrokiHttpClient)
153
+ kroki_client = KrokiClient.new(server_url(doc), http_method(doc), KrokiHttpClient, logger, max_uri_length(doc))
100
154
  if TEXT_FORMATS.include?(format)
101
155
  text_content = kroki_client.text_content(kroki_diagram)
102
156
  block = processor.create_block(parent, 'literal', text_content, attrs)
@@ -112,12 +166,17 @@ module AsciidoctorExtensions
112
166
 
113
167
  private
114
168
 
115
- def prepend_plantuml_config(diagram_text, diagram_type, doc)
116
- if diagram_type == :plantuml && doc.attr?('kroki-plantuml-include')
117
- # TODO: this behaves different than the JS version
118
- # The file should be added by !include #{plantuml_include}" once we have a preprocessor for ruby
119
- config = File.read(doc.attr('kroki-plantuml-include'))
120
- diagram_text = config + '\n' + diagram_text
169
+ def prepend_plantuml_config(diagram_text, diagram_type, doc, logger)
170
+ if diagram_type == :plantuml && doc.safe < ::Asciidoctor::SafeMode::SECURE && doc.attr?('kroki-plantuml-include')
171
+ # REMIND: this behaves different than the JS version
172
+ # Once we have a preprocessor for Ruby, the value should be added in the diagram source as "!include #{plantuml_include}"
173
+ plantuml_include_path = doc.normalize_system_path(doc.attr('kroki-plantuml-include'))
174
+ if ::File.readable? plantuml_include_path
175
+ config = File.read(plantuml_include_path)
176
+ diagram_text = config + "\n" + diagram_text
177
+ else
178
+ logger.warn "Unable to read plantuml-include. File not found or not readable: #{plantuml_include_path}."
179
+ end
121
180
  end
122
181
  diagram_text
123
182
  end
@@ -157,7 +216,7 @@ module AsciidoctorExtensions
157
216
  end
158
217
 
159
218
  def create_image_src(doc, kroki_diagram, kroki_client)
160
- if doc.attr('kroki-fetch-diagram')
219
+ if doc.attr('kroki-fetch-diagram') && doc.safe < ::Asciidoctor::SafeMode::SECURE
161
220
  kroki_diagram.save(output_dir_path(doc), kroki_client)
162
221
  else
163
222
  kroki_diagram.get_diagram_uri(server_url(doc))
@@ -172,20 +231,20 @@ module AsciidoctorExtensions
172
231
  doc.attr('kroki-http-method', 'adaptive').downcase
173
232
  end
174
233
 
234
+ def max_uri_length(doc)
235
+ doc.attr('kroki-max-uri-length', '4000').to_i
236
+ end
237
+
175
238
  def output_dir_path(doc)
176
- images_output_dir = doc.attr('imagesoutdir')
177
- out_dir = doc.attr('outdir')
178
- to_dir = doc.attr('to_dir')
179
- base_dir = doc.base_dir
180
239
  images_dir = doc.attr('imagesdir', '')
181
- if images_output_dir
240
+ if (images_output_dir = doc.attr('imagesoutdir'))
182
241
  images_output_dir
183
- elsif out_dir
242
+ elsif (out_dir = doc.attr('outdir'))
184
243
  File.join(out_dir, images_dir)
185
- elsif to_dir
244
+ elsif (to_dir = doc.attr('to_dir'))
186
245
  File.join(to_dir, images_dir)
187
246
  else
188
- File.join(base_dir, images_dir)
247
+ File.join(doc.base_dir, images_dir)
189
248
  end
190
249
  end
191
250
  end
@@ -259,18 +318,19 @@ module AsciidoctorExtensions
259
318
  class KrokiClient
260
319
  attr_reader :server_url
261
320
  attr_reader :method
321
+ attr_reader :max_uri_length
262
322
 
263
323
  SUPPORTED_HTTP_METHODS = %w[get post adaptive].freeze
264
324
 
265
- def initialize(server_url, http_method, http_client)
325
+ def initialize(server_url, http_method, http_client, logger = ::Asciidoctor::LoggerManager.logger, max_uri_length = 4000)
266
326
  @server_url = server_url
267
- @max_uri_length = 4096
327
+ @max_uri_length = max_uri_length
268
328
  @http_client = http_client
269
329
  method = (http_method || 'adaptive').downcase
270
330
  if SUPPORTED_HTTP_METHODS.include?(method)
271
331
  @method = method
272
332
  else
273
- puts "Invalid value '#{method}' for kroki-http-method attribute. The value must be either: 'get', 'post' or 'adaptive'. Proceeding using: 'adaptive'."
333
+ logger.warn "Invalid value '#{method}' for kroki-http-method attribute. The value must be either: 'get', 'post' or 'adaptive'. Proceeding using: 'adaptive'."
274
334
  @method = 'adaptive'
275
335
  end
276
336
  end
@@ -286,7 +346,7 @@ module AsciidoctorExtensions
286
346
  if @method == 'adaptive' || @method == 'get'
287
347
  uri = kroki_diagram.get_diagram_uri(server_url)
288
348
  if uri.length > @max_uri_length
289
- # The request URI is longer than 4096.
349
+ # The request URI is longer than the max URI length.
290
350
  if @method == 'get'
291
351
  # The request might be rejected by the server with a 414 Request-URI Too Large.
292
352
  # Consider using the attribute kroki-http-method with the value 'adaptive'.
@@ -0,0 +1,128 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rspec_helper'
4
+ require 'asciidoctor'
5
+ require_relative '../lib/asciidoctor/extensions/asciidoctor_kroki'
6
+ require_relative '../lib/asciidoctor/extensions/asciidoctor_kroki/extension'
7
+
8
+ describe ::AsciidoctorExtensions::KrokiBlockMacroProcessor do
9
+ context 'convert to html5' do
10
+ it 'should catch exception if target is not readable' do
11
+ input = <<~'ADOC'
12
+ plantuml::spec/fixtures/missing.puml[svg,role=sequence]
13
+ ADOC
14
+ output = Asciidoctor.convert(input, standalone: false)
15
+ (expect output).to eql %(<div class="paragraph">
16
+ <p>Unresolved block macro - plantuml::spec/fixtures/missing.puml[]</p>
17
+ </div>)
18
+ end
19
+ end
20
+ context 'using a custom block macro' do
21
+ it 'should disallow read' do
22
+ # noinspection RubyClassModuleNamingConvention
23
+ class DisallowReadKrokiBlockMacroProcessor < ::AsciidoctorExtensions::KrokiBlockMacroProcessor
24
+ def read_allowed?(_target)
25
+ false
26
+ end
27
+ end
28
+ registry = Asciidoctor::Extensions.create do
29
+ block_macro DisallowReadKrokiBlockMacroProcessor, 'plantuml'
30
+ end
31
+ input = <<~'ADOC'
32
+ plantuml::spec/fixtures/alice.puml[svg,role=sequence]
33
+ ADOC
34
+ output = Asciidoctor.convert(input, standalone: false, extension_registry: registry)
35
+ (expect output).to eql %(<div class="paragraph">
36
+ <p><a href="spec/fixtures/alice.puml">spec/fixtures/alice.puml</a></p>
37
+ </div>)
38
+ end
39
+ it 'should allow read if target is not a URI' do
40
+ # noinspection RubyClassModuleNamingConvention
41
+ class DisallowUriReadKrokiBlockMacroProcessor < ::AsciidoctorExtensions::KrokiBlockMacroProcessor
42
+ def read_allowed?(target)
43
+ return false if ::Asciidoctor::Helpers.uriish?(target)
44
+
45
+ true
46
+ end
47
+ end
48
+ registry = Asciidoctor::Extensions.create do
49
+ block_macro DisallowUriReadKrokiBlockMacroProcessor, 'plantuml'
50
+ end
51
+ input = <<~'ADOC'
52
+ plantuml::https://domain.org/alice.puml[svg,role=sequence]
53
+
54
+ plantuml::file://path/to/alice.puml[svg,role=sequence]
55
+
56
+ plantuml::spec/fixtures/alice.puml[svg,role=sequence]
57
+ ADOC
58
+ output = Asciidoctor.convert(input, standalone: false, extension_registry: registry)
59
+ (expect output).to eql %(<div class="paragraph">
60
+ <p><a href="https://domain.org/alice.puml">https://domain.org/alice.puml</a></p>
61
+ </div>
62
+ <div class="paragraph">
63
+ <p><a href="file://path/to/alice.puml">file://path/to/alice.puml</a></p>
64
+ </div>
65
+ <div class="imageblock sequence kroki-format-svg kroki">
66
+ <div class="content">
67
+ <img src="https://kroki.io/plantuml/svg/eNpLzMlMTlXQtVNIyk-yUshIzcnJ5wIAQ-AGVQ==" alt="Diagram">
68
+ </div>
69
+ </div>)
70
+ end
71
+ it 'should override the resolve target method' do
72
+ # noinspection RubyClassModuleNamingConvention
73
+ class FixtureResolveTargetKrokiBlockMacroProcessor < ::AsciidoctorExtensions::KrokiBlockMacroProcessor
74
+ def resolve_target_path(target)
75
+ "spec/fixtures/#{target}"
76
+ end
77
+ end
78
+ registry = Asciidoctor::Extensions.create do
79
+ block_macro FixtureResolveTargetKrokiBlockMacroProcessor, 'plantuml'
80
+ end
81
+ input = <<~'ADOC'
82
+ plantuml::alice.puml[svg,role=sequence]
83
+ ADOC
84
+ output = Asciidoctor.convert(input, standalone: false, extension_registry: registry)
85
+ (expect output).to eql %(<div class="imageblock sequence kroki-format-svg kroki">
86
+ <div class="content">
87
+ <img src="https://kroki.io/plantuml/svg/eNpLzMlMTlXQtVNIyk-yUshIzcnJ5wIAQ-AGVQ==" alt="Diagram">
88
+ </div>
89
+ </div>)
90
+ end
91
+ it 'should display unresolved block macro message when the traget cannot be resolved' do
92
+ # noinspection RubyClassModuleNamingConvention
93
+ class UnresolvedTargetKrokiBlockMacroProcessor < ::AsciidoctorExtensions::KrokiBlockMacroProcessor
94
+ def resolve_target_path(_target)
95
+ nil
96
+ end
97
+ end
98
+ registry = Asciidoctor::Extensions.create do
99
+ block_macro UnresolvedTargetKrokiBlockMacroProcessor, 'plantuml'
100
+ end
101
+ input = <<~'ADOC'
102
+ plantuml::alice.puml[svg,role=sequence]
103
+ ADOC
104
+ output = Asciidoctor.convert(input, standalone: false, extension_registry: registry)
105
+ (expect output).to eql %(<div class="paragraph">
106
+ <p>Unresolved block macro - plantuml::[]</p>
107
+ </div>)
108
+ end
109
+ it 'should override the unresolved block macro message' do
110
+ # noinspection RubyClassModuleNamingConvention
111
+ class CustomUnresolvedTargetMessageKrokiBlockMacroProcessor < ::AsciidoctorExtensions::KrokiBlockMacroProcessor
112
+ def unresolved_block_macro_message(name, target)
113
+ "*[ERROR: #{name}::#{target}[] - unresolved block macro]*"
114
+ end
115
+ end
116
+ registry = Asciidoctor::Extensions.create do
117
+ block_macro CustomUnresolvedTargetMessageKrokiBlockMacroProcessor, 'plantuml'
118
+ end
119
+ input = <<~'ADOC'
120
+ plantuml::spec/fixtures/missing.puml[svg,role=sequence]
121
+ ADOC
122
+ output = Asciidoctor.convert(input, standalone: false, extension_registry: registry)
123
+ (expect output).to eql %(<div class="paragraph">
124
+ <p><strong>[ERROR: plantuml::spec/fixtures/missing.puml[] - unresolved block macro]</strong></p>
125
+ </div>)
126
+ end
127
+ end
128
+ end
@@ -20,4 +20,72 @@ describe ::AsciidoctorExtensions::KrokiClient do
20
20
  kroki_client = ::AsciidoctorExtensions::KrokiClient.new('http://localhost:8000', 'get', kroki_http_client)
21
21
  expect(kroki_client.method).to eq('get')
22
22
  end
23
+ it 'should use 4000 as the default max URI length' do
24
+ kroki_http_client = ::AsciidoctorExtensions::KrokiHttpClient
25
+ kroki_client = ::AsciidoctorExtensions::KrokiClient.new('http://localhost:8000', 'get', kroki_http_client)
26
+ expect(kroki_client.max_uri_length).to eq(4000)
27
+ end
28
+ it 'should use a custom value as max URI length' do
29
+ kroki_http_client = ::AsciidoctorExtensions::KrokiHttpClient
30
+ kroki_client = ::AsciidoctorExtensions::KrokiClient.new('http://localhost:8000', 'get', kroki_http_client, nil, 8000)
31
+ expect(kroki_client.max_uri_length).to eq(8000)
32
+ end
33
+ it 'should get an image with POST request if the URI length is greater than the value configured' do
34
+ kroki_http_client = Class.new do
35
+ class << self
36
+ def get(uri, _)
37
+ "GET #{uri}"
38
+ end
39
+
40
+ def post(uri, data, _)
41
+ "POST #{uri} - #{data}"
42
+ end
43
+ end
44
+ end
45
+ kroki_diagram = Class.new do
46
+ attr_reader :type, :text, :format
47
+
48
+ def initialize(type, format, text)
49
+ @text = text
50
+ @type = type
51
+ @format = format
52
+ end
53
+
54
+ def get_diagram_uri(_)
55
+ 'diagram-uri'
56
+ end
57
+ end.new('type', 'format', 'text')
58
+ kroki_client = ::AsciidoctorExtensions::KrokiClient.new('http://localhost:8000', 'adaptive', kroki_http_client, nil, 10)
59
+ result = kroki_client.get_image(kroki_diagram, 'utf8')
60
+ expect(result).to eq('POST http://localhost:8000/type/format - text')
61
+ end
62
+ it 'should get an image with GET request if the URI length is lower or equals than the value configured' do
63
+ kroki_http_client = Class.new do
64
+ class << self
65
+ def get(uri, _)
66
+ "GET #{uri}"
67
+ end
68
+
69
+ def post(uri, data, _)
70
+ "POST #{uri} - #{data}"
71
+ end
72
+ end
73
+ end
74
+ kroki_diagram = Class.new do
75
+ attr_reader :type, :text, :format
76
+
77
+ def initialize(type, format, text)
78
+ @text = text
79
+ @type = type
80
+ @format = format
81
+ end
82
+
83
+ def get_diagram_uri(_)
84
+ 'diagram-uri'
85
+ end
86
+ end.new('type', 'format', 'text')
87
+ kroki_client = ::AsciidoctorExtensions::KrokiClient.new('http://localhost:8000', 'adaptive', kroki_http_client, nil, 11)
88
+ result = kroki_client.get_image(kroki_diagram, 'utf8')
89
+ expect(result).to eq('GET diagram-uri')
90
+ end
23
91
  end
@@ -34,17 +34,59 @@ describe ::AsciidoctorExtensions::KrokiBlockProcessor do
34
34
  </div>
35
35
  </div>)
36
36
  end
37
- it 'should include the plantuml-include file' do
37
+ it 'should include the plantuml-include file when safe mode is safe' do
38
38
  input = <<~'ADOC'
39
39
  [plantuml]
40
40
  ....
41
41
  alice -> bob: hello
42
42
  ....
43
43
  ADOC
44
- output = Asciidoctor.convert(input, attributes: { 'env-idea' => '', 'kroki-plantuml-include' => 'spec/fixtures/config.puml' }, standalone: false)
44
+ output = Asciidoctor.convert(input, attributes: { 'env-idea' => '', 'kroki-plantuml-include' => 'spec/fixtures/config.puml' }, standalone: false, safe: :safe)
45
45
  (expect output).to eql %(<div class="imageblock kroki">
46
46
  <div class="content">
47
- <img src="https://kroki.io/plantuml/png/eNorzs7MK0gsSsxVyM3Py0_OKMrPTVUoKSpN5YrJS8zJTE5V0LVTSMpPslLISM3JyQcArVsRHA==" alt="Diagram">
47
+ <img src="https://kroki.io/plantuml/png/eNorzs7MK0gsSsxVyM3Py0_OKMrPTVUoKSpN5eJKzMlMTlXQtVNIyk-yUshIzcnJBwCT9xBc" alt="Diagram">
48
+ </div>
49
+ </div>)
50
+ end
51
+ it 'should normalize plantuml-include path when safe mode is safe' do
52
+ input = <<~'ADOC'
53
+ [plantuml]
54
+ ....
55
+ alice -> bob: hello
56
+ ....
57
+ ADOC
58
+ output = Asciidoctor.convert(input, attributes: { 'env-idea' => '', 'kroki-plantuml-include' => '../../../spec/fixtures/config.puml' }, standalone: false, safe: :safe)
59
+ (expect output).to eql %(<div class="imageblock kroki">
60
+ <div class="content">
61
+ <img src="https://kroki.io/plantuml/png/eNorzs7MK0gsSsxVyM3Py0_OKMrPTVUoKSpN5eJKzMlMTlXQtVNIyk-yUshIzcnJBwCT9xBc" alt="Diagram">
62
+ </div>
63
+ </div>)
64
+ end
65
+ it 'should not include file which reside outside of the parent directory of the source when safe mode is safe' do
66
+ input = <<~'ADOC'
67
+ [plantuml]
68
+ ....
69
+ alice -> bob: hello
70
+ ....
71
+ ADOC
72
+ output = Asciidoctor.convert(input, attributes: { 'env-idea' => '', 'kroki-plantuml-include' => '/etc/passwd' }, standalone: false, safe: :safe)
73
+ (expect output).to eql %(<div class="imageblock kroki">
74
+ <div class="content">
75
+ <img src="https://kroki.io/plantuml/png/eNpLzMlMTlXQtVNIyk-yUshIzcnJBwA9iwZL" alt="Diagram">
76
+ </div>
77
+ </div>)
78
+ end
79
+ it 'should not include file when safe mode is secure' do
80
+ input = <<~'ADOC'
81
+ [plantuml]
82
+ ....
83
+ alice -> bob: hello
84
+ ....
85
+ ADOC
86
+ output = Asciidoctor.convert(input, attributes: { 'env-idea' => '', 'kroki-plantuml-include' => 'spec/fixtures/config.puml' }, standalone: false, safe: :secure)
87
+ (expect output).to eql %(<div class="imageblock kroki">
88
+ <div class="content">
89
+ <img src="https://kroki.io/plantuml/png/eNpLzMlMTlXQtVNIyk-yUshIzcnJBwA9iwZL" alt="Diagram">
48
90
  </div>
49
91
  </div>)
50
92
  end
@@ -54,11 +96,24 @@ describe ::AsciidoctorExtensions::KrokiBlockProcessor do
54
96
 
55
97
  plantuml::spec/fixtures/alice.puml[svg,role=sequence]
56
98
  ADOC
57
- output = Asciidoctor.convert(input, attributes: { 'kroki-fetch-diagram' => '' }, standalone: false)
99
+ output = Asciidoctor.convert(input, attributes: { 'kroki-fetch-diagram' => '' }, standalone: false, safe: :safe)
58
100
  (expect output).to eql %(<div class="imageblock sequence kroki-format-svg kroki">
59
101
  <div class="content">
60
102
  <img src=".asciidoctor/kroki/diag-f6acdc206506b6ca7badd3fe722f252af992871426e580c8361ff4d47c2c7d9b.svg" alt="Diagram">
61
103
  </div>
104
+ </div>)
105
+ end
106
+ it 'should not fetch diagram when safe mode is secure' do
107
+ input = <<~'ADOC'
108
+ :imagesdir: .asciidoctor/kroki
109
+
110
+ plantuml::spec/fixtures/alice.puml[svg,role=sequence]
111
+ ADOC
112
+ output = Asciidoctor.convert(input, attributes: { 'kroki-fetch-diagram' => '' }, standalone: false)
113
+ (expect output).to eql %(<div class="imageblock sequence kroki-format-svg kroki">
114
+ <div class="content">
115
+ <img src="https://kroki.io/plantuml/svg/eNpLzMlMTlXQtVNIyk-yUshIzcnJ5wIAQ-AGVQ==" alt="Diagram">
116
+ </div>
62
117
  </div>)
63
118
  end
64
119
  it 'should create PNG diagram in imagesdir if kroki-fetch-diagram is set' do
@@ -67,7 +122,7 @@ describe ::AsciidoctorExtensions::KrokiBlockProcessor do
67
122
 
68
123
  plantuml::spec/fixtures/alice.puml[png,role=sequence]
69
124
  ADOC
70
- output = Asciidoctor.convert(input, attributes: { 'kroki-fetch-diagram' => '' }, standalone: false)
125
+ output = Asciidoctor.convert(input, attributes: { 'kroki-fetch-diagram' => '' }, standalone: false, safe: :safe)
71
126
  (expect output).to eql %(<div class="imageblock sequence kroki-format-png kroki">
72
127
  <div class="content">
73
128
  <img src=".asciidoctor/kroki/diag-d4f314b2d4e75cc08aa4f8c2c944f7bf78321895d8ec5f665b42476d4e67e610.png" alt="Diagram">
@@ -80,7 +135,7 @@ end
80
135
  describe ::AsciidoctorExtensions::Kroki do
81
136
  it 'should return the list of supported diagrams' do
82
137
  diagram_names = ::AsciidoctorExtensions::Kroki::SUPPORTED_DIAGRAM_NAMES
83
- expect(diagram_names).to include('vegalite', 'plantuml', 'bytefield', 'bpmn', 'excalidraw')
138
+ expect(diagram_names).to include('vegalite', 'plantuml', 'bytefield', 'bpmn', 'excalidraw', 'wavedrom')
84
139
  end
85
140
  it 'should register the extension for the list of supported diagrams' do
86
141
  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.3.0
4
+ version: 0.4.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-01-12 00:00:00.000000000 Z
11
+ date: 2021-02-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor
@@ -85,6 +85,7 @@ files:
85
85
  - lib/asciidoctor/extensions/asciidoctor_kroki.rb
86
86
  - lib/asciidoctor/extensions/asciidoctor_kroki/extension.rb
87
87
  - spec/.rubocop.yml
88
+ - spec/asciidoctor_kroki_block_macro_spec.rb
88
89
  - spec/asciidoctor_kroki_client_spec.rb
89
90
  - spec/asciidoctor_kroki_diagram_spec.rb
90
91
  - spec/asciidoctor_kroki_spec.rb
@@ -122,6 +123,7 @@ specification_version: 4
122
123
  summary: Asciidoctor extension to convert diagrams to images using Kroki
123
124
  test_files:
124
125
  - spec/.rubocop.yml
126
+ - spec/asciidoctor_kroki_block_macro_spec.rb
125
127
  - spec/asciidoctor_kroki_client_spec.rb
126
128
  - spec/asciidoctor_kroki_diagram_spec.rb
127
129
  - spec/asciidoctor_kroki_spec.rb