asciidoctor-diagram 2.3.2 → 3.0.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: e68570e8ec8e10bd6815b05ef8a6884716fe9bdeb6da30c30d813fe15eef3514
4
- data.tar.gz: 426bebf1b41d3f4f3d262a41d90db635f1dffe711de6bde0ac112ffd03b6e496
3
+ metadata.gz: 993b52833cbee514282ba62841b0dfafc69760770884a42ea24843b6e9b58224
4
+ data.tar.gz: 38d9215b0859313c6610ec6876b65e2fee4437b87bcc1f2a01465c39db8dedc4
5
5
  SHA512:
6
- metadata.gz: f97b8cad30f43d309e2607c8cbcec8e8f64998de86255ea80e717e5886165632b8e5f0ab97674375cf59edb1249807d2a23c475a9b58de64a611a9182b574ccc
7
- data.tar.gz: 5d0ff9dd8bed877c2e5db712320779486735b5cc24ea87c0c3623f94a27be949d84849ed6e504e8428535cdf394ffbccaecebdeb4d7e9d98525a8ddf12f66849
6
+ metadata.gz: 15477c98c7d90da97ce45106f2f6159b26eb60caeeb0e9d36a700959e15aba484449334ba31c4d74e1bb6806f3360d477e1c424242ad2c3657dd2135d4d9b89f
7
+ data.tar.gz: 18b93c67ac75d7916eab56073b92a49c6a22ec52be0bc48bc5431d967d2c2a7968d570146a2c53acbf773452453b67dc76c539b69e5e3c9ce9df2d857d9d9cff
data/CHANGELOG.adoc CHANGED
@@ -1,5 +1,16 @@
1
1
  = Asciidoctor-diagram Changelog
2
2
 
3
+ == 3.0.0
4
+
5
+ Breaking Changes::
6
+
7
+ * Asciidoctor Diagram no longer has a runtime dependency on the https://rubygems.org/gems/asciidoctor-diagram-ditaamini[asciidoctor-diagram-ditaamini] and https://rubygems.org/gems/asciidoctor-diagram-plantuml[asciidoctor-diagram-plantuml] gems.
8
+ These gems will now have to be installed and required explicitly if necessary.
9
+
10
+ Enhancements::
11
+
12
+ * Issue #478: Add support for PlantUML native image builds (@fliiiix)
13
+
3
14
  == 2.3.2
4
15
 
5
16
  Enhancements::
data/README.adoc CHANGED
@@ -23,19 +23,23 @@ The example below shows an embedded Ditaa diagram block.
23
23
  ---------
24
24
  [ditaa]
25
25
  ----
26
- +-------------+
27
- | asciidoctor |---------------+
28
- | diagram | |
29
- +-------------+ | image
30
- ^ |
31
- | diagram source |
32
- | v
33
- +--------+ +------+------+ /--------------\
34
- | adoc |------>+ asciidoctor +------->| HTML + image |
35
- +--------+ +-------------+ html \--------------/
26
+ +-------------+
27
+ | Diagram +----------------+
28
+ | Renderer | |
29
+ +-------------+ |
30
+ | Asciidoctor | |
31
+ | Diagram | |
32
+ +-------------+ | Image
33
+ ^ |
34
+ | Diagram source |
35
+ +---------------+ | v
36
+ | Asciidoc | +------+------+ /-------+------\
37
+ | with embedded +------>+ Asciidoctor +------->| Beautiful |
38
+ | diagram {d}| +-------------+ HTML | Output |
39
+ +---------------+ \--------------/
36
40
  ----
37
41
  ---------
38
42
 
39
43
  After processing by Asciidoctor, the output file will show a rendered version of the diagram instead of the diagram source code.
40
44
 
41
- image::docs/modules/ROOT/images/asciidoctor-diagram-process.png[]
45
+ image::docs/modules/ROOT/images/asciidoctor-diagram-process.png[]
@@ -1,5 +1,7 @@
1
1
  require_relative '../diagram_converter'
2
2
  require_relative '../util/java'
3
+ require_relative '../util/cli'
4
+ require_relative '../util/cli_generator'
3
5
  require 'delegate'
4
6
  require 'uri'
5
7
 
@@ -8,6 +10,7 @@ module Asciidoctor
8
10
  # @private
9
11
  class PlantUmlConverter
10
12
  include DiagramConverter
13
+ include CliGenerator
11
14
 
12
15
  CLASSPATH_ENV = Java.environment_variable('DIAGRAM_PLANTUML_CLASSPATH')
13
16
  LIB_DIR = File.expand_path('../..', File.dirname(__FILE__))
@@ -27,6 +30,15 @@ module Asciidoctor
27
30
  Java.classpath.concat PLANTUML_JARS
28
31
  end
29
32
 
33
+ def self.find_plantuml_native(source)
34
+ source.find_command(
35
+ 'plantuml-full',
36
+ :raise_on_error => false,
37
+ :attrs => ['plantuml-native'],
38
+ :alt_cmds => ['plantuml-headless']
39
+ )
40
+ end
41
+
30
42
  def wrap_source(source)
31
43
  PlantUMLPreprocessedSource.new(source, self)
32
44
  end
@@ -54,6 +66,19 @@ module Asciidoctor
54
66
  source.attr('preprocess', 'true') == 'true'
55
67
  end
56
68
 
69
+ def convert(source, format, options)
70
+ plantuml_native = PlantUmlConverter.find_plantuml_native(source)
71
+ if plantuml_native
72
+ convert_native(plantuml_native, source, format, options)
73
+ elsif PLANTUML_JARS
74
+ convert_http(source, format, options)
75
+ else
76
+ raise "Could not load PlantUML. Either require 'asciidoctor-diagram-plantuml' " \
77
+ "or specify the location of the PlantUML JAR(s) using the 'DIAGRAM_PLANTUML_CLASSPATH' environment variable. " \
78
+ "Alternatively a PlantUML binary can be provided (plantuml-native in $PATH)."
79
+ end
80
+ end
81
+
57
82
  def add_common_headers(headers, source)
58
83
  base_dir = source.base_dir
59
84
 
@@ -78,10 +103,7 @@ module Asciidoctor
78
103
  headers['X-PlantUML-SizeLimit'] = limit if limit
79
104
  end
80
105
 
81
- def convert(source, format, options)
82
- unless PLANTUML_JARS
83
- raise "Could not load PlantUML. Either require 'asciidoctor-diagram-plantuml' or specify the location of the PlantUML JAR(s) using the 'DIAGRAM_PLANTUML_CLASSPATH' environment variable."
84
- end
106
+ def convert_http(source, format, options)
85
107
  Java.load
86
108
 
87
109
  code = source.code
@@ -100,7 +122,7 @@ module Asciidoctor
100
122
  end
101
123
 
102
124
  headers = {
103
- 'Accept' => mime_type
125
+ 'Accept' => mime_type
104
126
  }
105
127
 
106
128
  unless should_preprocess(source)
@@ -122,9 +144,9 @@ module Asciidoctor
122
144
  end
123
145
 
124
146
  response = Java.send_request(
125
- :url => '/plantuml',
126
- :body => code,
127
- :headers => headers
147
+ :url => '/plantuml',
148
+ :body => code,
149
+ :headers => headers
128
150
  )
129
151
 
130
152
  unless response[:code] == 200
@@ -163,6 +185,77 @@ module Asciidoctor
163
185
  response[:body]
164
186
  end
165
187
  end
188
+
189
+ def add_theme_arg(args, theme)
190
+ if theme
191
+ args << '-theme' << theme
192
+ end
193
+ end
194
+
195
+ def add_common_args(args, source)
196
+ base_dir = File.expand_path(source.base_dir)
197
+ args << '-filedir'
198
+ args << base_dir
199
+
200
+ config_file = source.attr('plantumlconfig', nil, true) || source.attr('config')
201
+ if config_file
202
+ args << '-config'
203
+ args << File.expand_path(config_file, base_dir)
204
+ end
205
+
206
+ include_dir = source.attr('includedir')
207
+ if include_dir
208
+ args << "-Dplantuml.include.path=#{Platform.native_path(File.expand_path(include_dir, base_dir))}"
209
+ end
210
+ end
211
+
212
+ def convert_native(plantuml, source, format, options)
213
+ code = source.code
214
+
215
+ args = []
216
+ env = {}
217
+
218
+ args << case format
219
+ when :png
220
+ '-tpng'
221
+ when :svg
222
+ '-tsvg'
223
+ when :txt, :utxt
224
+ '-tutxt'
225
+ when :atxt
226
+ '-ttxt'
227
+ else
228
+ raise "Unsupported format: #{format}"
229
+ end
230
+
231
+ add_common_args(args, source)
232
+ add_theme_arg(args, options[:theme])
233
+
234
+ if options[:size_limit]
235
+ env['PLANTUML_LIMIT_SIZE'] = options[:size_limit]
236
+ end
237
+
238
+ dot = source.find_command('dot', :alt_attrs => ['graphvizdot'], :raise_on_error => false)
239
+ if options[:smetana] || !dot
240
+ args << '-Playout=smetana'
241
+ else
242
+ args << '-graphvizdot'
243
+ args << ::Asciidoctor::Diagram::Platform.host_os_path(dot)
244
+ end
245
+
246
+ generate_stdin_stdout(plantuml, code) do |tool, _|
247
+ cmd = [tool]
248
+ cmd << '-pipe'
249
+ cmd << '-failfast2'
250
+ cmd << '-stdrpt:1'
251
+ cmd.concat args
252
+
253
+ {
254
+ :args => cmd,
255
+ :env => env
256
+ }
257
+ end
258
+ end
166
259
  end
167
260
 
168
261
  class UmlConverter < PlantUmlConverter
@@ -178,6 +271,8 @@ module Asciidoctor
178
271
  end
179
272
 
180
273
  class PlantUMLPreprocessedSource < SimpleDelegator
274
+ include CliGenerator
275
+
181
276
  def initialize(source, converter)
182
277
  super(source)
183
278
  @converter = converter
@@ -188,34 +283,82 @@ module Asciidoctor
188
283
  end
189
284
 
190
285
  def load_code
191
- Java.load
192
-
193
286
  code = __getobj__.code
194
287
 
195
288
  tag = @converter.class.tag
196
289
  code = "@start#{tag}\n#{code}\n@end#{tag}" unless code.index("@start") && code.index("@end")
197
290
 
198
291
  if @converter.should_preprocess(self)
199
- headers = {}
200
- @converter.add_common_headers(headers, self)
201
- @converter.add_theme_header(headers, @converter.collect_options(self)[:theme])
202
-
203
- response = Java.send_request(
204
- :url => '/plantumlpreprocessor',
205
- :body => code,
206
- :headers => headers
207
- )
208
-
209
- unless response[:code] == 200
210
- raise Java.create_error("PlantUML preprocessing failed", response)
292
+ plantuml_native = PlantUmlConverter.find_plantuml_native(self)
293
+ if plantuml_native
294
+ code = preprocess_native(plantuml_native, code)
295
+ else
296
+ code = preprocess_http(code)
211
297
  end
212
-
213
- code = response[:body]
214
- code.force_encoding(Encoding::UTF_8)
215
298
  end
216
299
 
217
300
  code
218
301
  end
302
+
303
+ private
304
+
305
+ def preprocess_http(code)
306
+ Java.load
307
+
308
+ headers = {}
309
+ @converter.add_common_headers(headers, self)
310
+ @converter.add_theme_header(headers, @converter.collect_options(self)[:theme])
311
+
312
+ response = Java.send_request(
313
+ :url => '/plantumlpreprocessor',
314
+ :body => code,
315
+ :headers => headers
316
+ )
317
+
318
+ unless response[:code] == 200
319
+ raise Java.create_error("PlantUML preprocessing failed", response)
320
+ end
321
+
322
+ code = response[:body]
323
+ code.force_encoding(Encoding::UTF_8)
324
+ end
325
+
326
+ def preprocess_native(plantuml, code)
327
+ generate_stdin_stdout(plantuml, code) do |tool, _|
328
+ cmd = [tool]
329
+ cmd << '-pipe'
330
+ cmd << '-preproc'
331
+ cmd << '-failfast2'
332
+ cmd << '-stdrpt:1'
333
+
334
+ @converter.add_common_args(cmd, self)
335
+ @converter.add_theme_arg(cmd, @converter.collect_options(self)[:theme])
336
+
337
+ base_dir = File.expand_path(self.base_dir)
338
+ cmd << '-filedir'
339
+ cmd << base_dir
340
+
341
+ config_file = self.attr('plantumlconfig', nil, true) || self.attr('config')
342
+ if config_file
343
+ cmd << '-config'
344
+ cmd << File.expand_path(config_file, base_dir)
345
+ end
346
+
347
+ include_dir = self.attr('includedir')
348
+ if include_dir
349
+ cmd << "-Dplantuml.include.path=#{Platform.native_path(File.expand_path(include_dir, base_dir))}"
350
+ end
351
+
352
+ theme = @converter.collect_options(self)[:theme]
353
+ if theme
354
+ cmd << '-theme' << theme
355
+ end
356
+
357
+ {
358
+ :args => cmd
359
+ }
360
+ end
361
+ end
219
362
  end
220
363
  end
221
364
  end
@@ -100,7 +100,7 @@ module Asciidoctor
100
100
  exit = status.exitstatus
101
101
 
102
102
  if exit != 0
103
- raise "#{cmd} failed: #{stdout.empty? ? stderr : stdout}"
103
+ raise "#{cmd} failed: #{stderr.empty? ? stdout : stderr}"
104
104
  end
105
105
 
106
106
  {
@@ -18,6 +18,16 @@ module Asciidoctor
18
18
  raise "Classpath item #{j} does not exist" unless File.exist?(j)
19
19
  require j
20
20
  end
21
+
22
+ # Strange issue seen with JRuby where 'java.class.path' has the value ':'.
23
+ # This causes issue in PlantUML which splits the class path string and then
24
+ # raises errors when trying to handle empty strings.
25
+ java_cp = ::Java.java.lang.System.getProperty("java.class.path")
26
+ new_java_cp = java_cp.split(File::PATH_SEPARATOR)
27
+ .reject { |p| p.empty? }
28
+ .join "File::PATH_SEPARATOR"
29
+ ::Java.java.lang.System.setProperty("java.class.path", new_java_cp)
30
+
21
31
  @loaded = true
22
32
  end
23
33
 
@@ -1,5 +1,5 @@
1
1
  module Asciidoctor
2
2
  module Diagram
3
- VERSION = "2.3.2"
3
+ VERSION = "3.0.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: asciidoctor-diagram
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.2
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pepijn Van Eeckhoudt
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2025-03-24 00:00:00.000000000 Z
10
+ date: 2025-04-24 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: bundler
@@ -72,34 +71,6 @@ dependencies:
72
71
  - - "<"
73
72
  - !ruby/object:Gem::Version
74
73
  version: 3.x
75
- - !ruby/object:Gem::Dependency
76
- name: asciidoctor-diagram-ditaamini
77
- requirement: !ruby/object:Gem::Requirement
78
- requirements:
79
- - - "~>"
80
- - !ruby/object:Gem::Version
81
- version: '1.0'
82
- type: :runtime
83
- prerelease: false
84
- version_requirements: !ruby/object:Gem::Requirement
85
- requirements:
86
- - - "~>"
87
- - !ruby/object:Gem::Version
88
- version: '1.0'
89
- - !ruby/object:Gem::Dependency
90
- name: asciidoctor-diagram-plantuml
91
- requirement: !ruby/object:Gem::Requirement
92
- requirements:
93
- - - "~>"
94
- - !ruby/object:Gem::Version
95
- version: '1.2021'
96
- type: :runtime
97
- prerelease: false
98
- version_requirements: !ruby/object:Gem::Requirement
99
- requirements:
100
- - - "~>"
101
- - !ruby/object:Gem::Version
102
- version: '1.2021'
103
74
  - !ruby/object:Gem::Dependency
104
75
  name: rexml
105
76
  requirement: !ruby/object:Gem::Requirement
@@ -261,7 +232,6 @@ metadata:
261
232
  documentation_uri: https://docs.asciidoctor.org/diagram-extension/latest/
262
233
  homepage_uri: https://github.com/asciidoctor/asciidoctor-diagram
263
234
  source_code_uri: https://github.com/asciidoctor/asciidoctor-diagram.git
264
- post_install_message:
265
235
  rdoc_options: []
266
236
  require_paths:
267
237
  - lib
@@ -276,8 +246,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
276
246
  - !ruby/object:Gem::Version
277
247
  version: '0'
278
248
  requirements: []
279
- rubygems_version: 3.2.22
280
- signing_key:
249
+ rubygems_version: 3.6.3
281
250
  specification_version: 4
282
251
  summary: A family of Asciidoctor extensions that generate images from a broad range
283
252
  of embedded plain text diagram descriptions, including PlantUML, ditaa, Kroki, and