asciidoctor-diagram 2.2.3 → 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.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +159 -0
  3. data/README.adoc +17 -13
  4. data/lib/asciidoctor-diagram/a2s/converter.rb +7 -2
  5. data/lib/asciidoctor-diagram/barcode/converter.rb +83 -78
  6. data/lib/asciidoctor-diagram/blockdiag/converter.rb +12 -2
  7. data/lib/asciidoctor-diagram/bpmn/converter.rb +4 -1
  8. data/lib/asciidoctor-diagram/bytefield/converter.rb +4 -1
  9. data/lib/asciidoctor-diagram/d2/converter.rb +57 -0
  10. data/lib/asciidoctor-diagram/d2/extension.rb +18 -0
  11. data/lib/asciidoctor-diagram/d2.rb +8 -0
  12. data/lib/asciidoctor-diagram/dbml/converter.rb +27 -0
  13. data/lib/asciidoctor-diagram/dbml/extension.rb +18 -0
  14. data/lib/asciidoctor-diagram/dbml.rb +8 -0
  15. data/lib/asciidoctor-diagram/diagram_processor.rb +49 -9
  16. data/lib/asciidoctor-diagram/diagram_source.rb +35 -33
  17. data/lib/asciidoctor-diagram/diagrams/converter.rb +4 -1
  18. data/lib/asciidoctor-diagram/ditaa/converter.rb +15 -7
  19. data/lib/asciidoctor-diagram/ditaa/ditaa-2.2.0.jar +0 -0
  20. data/lib/asciidoctor-diagram/dpic/converter.rb +4 -1
  21. data/lib/asciidoctor-diagram/erd/converter.rb +5 -2
  22. data/lib/asciidoctor-diagram/gnuplot/converter.rb +7 -1
  23. data/lib/asciidoctor-diagram/graphviz/converter.rb +4 -1
  24. data/lib/asciidoctor-diagram/graphviz_py/converter.rb +4 -1
  25. data/lib/asciidoctor-diagram/http/converter.rb +16 -7
  26. data/lib/asciidoctor-diagram/http/server.rb +2 -2
  27. data/lib/asciidoctor-diagram/lilypond/converter.rb +3 -2
  28. data/lib/asciidoctor-diagram/meme/converter.rb +29 -3
  29. data/lib/asciidoctor-diagram/mermaid/converter.rb +4 -2
  30. data/lib/asciidoctor-diagram/msc/converter.rb +6 -2
  31. data/lib/asciidoctor-diagram/nomnoml/converter.rb +4 -1
  32. data/lib/asciidoctor-diagram/penrose/converter.rb +53 -0
  33. data/lib/asciidoctor-diagram/penrose/extension.rb +18 -0
  34. data/lib/asciidoctor-diagram/penrose.rb +8 -0
  35. data/lib/asciidoctor-diagram/pikchr/converter.rb +4 -1
  36. data/lib/asciidoctor-diagram/pintora/converter.rb +60 -0
  37. data/lib/asciidoctor-diagram/pintora/extension.rb +18 -0
  38. data/lib/asciidoctor-diagram/pintora.rb +8 -0
  39. data/lib/asciidoctor-diagram/plantuml/converter.rb +256 -43
  40. data/lib/asciidoctor-diagram/plantuml/plantuml-2.2.4.jar +0 -0
  41. data/lib/asciidoctor-diagram/shaape/converter.rb +4 -1
  42. data/lib/asciidoctor-diagram/smcat/converter.rb +5 -1
  43. data/lib/asciidoctor-diagram/structurizr/converter.rb +69 -0
  44. data/lib/asciidoctor-diagram/structurizr/extension.rb +52 -0
  45. data/lib/asciidoctor-diagram/structurizr/renderers.rb +63 -0
  46. data/lib/asciidoctor-diagram/structurizr/structurizr-2.2.2.jar +0 -0
  47. data/lib/asciidoctor-diagram/structurizr.rb +7 -0
  48. data/lib/asciidoctor-diagram/svgbob/converter.rb +6 -2
  49. data/lib/asciidoctor-diagram/symbolator/converter.rb +4 -1
  50. data/lib/asciidoctor-diagram/syntrax/converter.rb +72 -17
  51. data/lib/asciidoctor-diagram/syntrax/syntrax-2.2.0.jar +0 -0
  52. data/lib/asciidoctor-diagram/tikz/converter.rb +5 -2
  53. data/lib/asciidoctor-diagram/umlet/converter.rb +4 -1
  54. data/lib/asciidoctor-diagram/util/base64.rb +25 -0
  55. data/lib/asciidoctor-diagram/util/cli.rb +11 -3
  56. data/lib/asciidoctor-diagram/util/cli_generator.rb +1 -0
  57. data/lib/asciidoctor-diagram/util/java.rb +15 -7
  58. data/lib/asciidoctor-diagram/util/java_jruby.rb +14 -0
  59. data/lib/asciidoctor-diagram/util/java_socket.rb +4 -0
  60. data/lib/asciidoctor-diagram/util/server-2.2.3.jar +0 -0
  61. data/lib/asciidoctor-diagram/util/svg.rb +5 -3
  62. data/lib/asciidoctor-diagram/vega/converter.rb +5 -3
  63. data/lib/asciidoctor-diagram/version.rb +1 -1
  64. data/lib/asciidoctor-diagram/wavedrom/converter.rb +38 -24
  65. data/lib/asciidoctor-diagram.rb +5 -0
  66. metadata +32 -115
  67. data/Rakefile +0 -9
  68. data/docs/antora.yml +0 -3
  69. data/docs/modules/ROOT/images/asciidoctor-diagram-classes.png +0 -0
  70. data/docs/modules/ROOT/images/asciidoctor-diagram-process.png +0 -0
  71. data/docs/modules/ROOT/pages/index.adoc +0 -21
  72. data/docs/modules/ROOT/partials/advanced.adoc +0 -365
  73. data/docs/modules/ROOT/partials/create_diagram.adoc +0 -134
  74. data/docs/modules/ROOT/partials/generate.adoc +0 -15
  75. data/docs/modules/ROOT/partials/installation.adoc +0 -19
  76. data/docs/modules/ROOT/partials/uris.adoc +0 -41
  77. data/examples/Gemfile +0 -3
  78. data/examples/README.adoc +0 -18
  79. data/examples/design.adoc +0 -78
  80. data/examples/features.adoc +0 -189
  81. data/lib/asciidoctor-diagram/ditaa/ditaa-1.3.21.jar +0 -0
  82. data/lib/asciidoctor-diagram/plantuml/plantuml-1.3.21.jar +0 -0
  83. data/lib/asciidoctor-diagram/util/server-1.3.21.jar +0 -0
  84. data/spec/a2s_spec.rb +0 -33
  85. data/spec/barcode_spec.rb +0 -176
  86. data/spec/blockdiag_spec.rb +0 -20
  87. data/spec/bpmn_spec.rb +0 -60
  88. data/spec/bytefield_spec.rb +0 -96
  89. data/spec/diagrams_spec.rb +0 -27
  90. data/spec/ditaa_spec.rb +0 -191
  91. data/spec/dpic_spec.rb +0 -23
  92. data/spec/erd_spec.rb +0 -96
  93. data/spec/gnuplot_spec.rb +0 -229
  94. data/spec/graphviz_py_spec.rb +0 -33
  95. data/spec/graphviz_spec.rb +0 -24
  96. data/spec/lilypond_spec.rb +0 -17
  97. data/spec/man.jpg +0 -0
  98. data/spec/meme_spec.rb +0 -67
  99. data/spec/mermaid_spec.rb +0 -198
  100. data/spec/msc_spec.rb +0 -37
  101. data/spec/nomnoml_spec.rb +0 -36
  102. data/spec/pikchr_spec.rb +0 -73
  103. data/spec/plantuml_spec.rb +0 -772
  104. data/spec/shaape_spec.rb +0 -20
  105. data/spec/shared_examples.rb +0 -764
  106. data/spec/smcat_spec.rb +0 -30
  107. data/spec/svgbob_spec.rb +0 -33
  108. data/spec/symbolator_spec.rb +0 -27
  109. data/spec/syntrax_spec.rb +0 -22
  110. data/spec/test_helper.rb +0 -113
  111. data/spec/tikz_spec.rb +0 -181
  112. data/spec/umlet_spec.rb +0 -32
  113. data/spec/vega_spec.rb +0 -133
  114. data/spec/wavedrom_spec.rb +0 -21
@@ -64,6 +64,12 @@ module Asciidoctor
64
64
  location = parent.document.reader.cursor_at_mark
65
65
 
66
66
  normalised_attributes = attributes.inject({}) { |h, (k, v)| h[normalise_attribute_name(k)] = v; h }
67
+ pos_attr_index = config.fetch(:positional_attrs, []).length + 1
68
+ until attributes[pos_attr_index].nil?
69
+ normalised_attributes[attributes[pos_attr_index]] = 'true'
70
+ pos_attr_index = pos_attr_index + 1
71
+ end
72
+
67
73
  converter = config[:converter].new
68
74
 
69
75
  supported_formats = supported_formats(converter)
@@ -75,6 +81,13 @@ module Asciidoctor
75
81
  begin
76
82
  source = converter.wrap_source(source)
77
83
 
84
+ if /html/i =~ parent.document.attributes['backend']
85
+ # Move PDF to the back of the list for the HTML backend
86
+ if supported_formats.delete(:pdf)
87
+ supported_formats << :pdf
88
+ end
89
+ end
90
+
78
91
  format = source.attributes.delete('format') || source.global_attr('format', supported_formats[0])
79
92
  format = format.to_sym if format.respond_to?(:to_sym)
80
93
 
@@ -159,7 +172,9 @@ module Asciidoctor
159
172
  image_file = parent.normalize_system_path(image_name, image_output_dir(parent))
160
173
  metadata_file = parent.normalize_system_path("#{image_name}.cache", cache_dir(source, parent))
161
174
 
162
- if File.exist? metadata_file
175
+ use_cache = !source.global_opt('nocache')
176
+
177
+ if use_cache && File.exist?(metadata_file)
163
178
  metadata = File.open(metadata_file, 'r') {|f| JSON.load(f, nil, :symbolize_names => true, :create_additions => false) }
164
179
  else
165
180
  metadata = {}
@@ -179,20 +194,34 @@ module Asciidoctor
179
194
 
180
195
  options = converter.collect_options(source)
181
196
  result = converter.convert(source, format, options)
182
-
183
- result.force_encoding(params[:encoding])
197
+ if result.is_a? Hash
198
+ image = result[:result]
199
+ extra = result[:extra]
200
+ else
201
+ image = result
202
+ extra = {}
203
+ end
204
+ image.force_encoding(params[:encoding])
184
205
 
185
206
  metadata = source.create_image_metadata
186
207
  metadata[:options] = options
187
208
 
188
- allow_image_optimisation = source.attr('optimise', 'true') == 'true'
189
- result, metadata[:width], metadata[:height] = params[:decoder].post_process_image(result, allow_image_optimisation)
209
+ allow_image_optimisation = !source.global_opt('nooptimise')
210
+ image, metadata[:width], metadata[:height] = params[:decoder].post_process_image(image, allow_image_optimisation)
190
211
 
191
212
  FileUtils.mkdir_p(File.dirname(image_file)) unless Dir.exist?(File.dirname(image_file))
192
- File.open(image_file, 'wb') {|f| f.write result}
213
+ File.open(image_file, 'wb') {|f| f.write image}
193
214
 
194
- FileUtils.mkdir_p(File.dirname(metadata_file)) unless Dir.exist?(File.dirname(metadata_file))
195
- File.open(metadata_file, 'w') {|f| JSON.dump(metadata, f)}
215
+ extra.each do |name, data|
216
+ File.open(image_file + ".#{name}", 'wb') {|f| f.write data}
217
+ end
218
+
219
+ if use_cache
220
+ FileUtils.mkdir_p(File.dirname(metadata_file)) unless Dir.exist?(File.dirname(metadata_file))
221
+ File.open(metadata_file, 'w') { |f| JSON.dump(metadata, f) }
222
+ else
223
+ File.delete(metadata_file) if File.exist?(metadata_file)
224
+ end
196
225
  end
197
226
 
198
227
  scale = image_attributes['scale']
@@ -356,6 +385,7 @@ module Asciidoctor
356
385
  include DiagramProcessor
357
386
 
358
387
  def self.inherited(subclass)
388
+ subclass.use_dsl
359
389
  subclass.name_positional_attributes ['target', 'format']
360
390
  subclass.contexts [:listing, :literal, :open]
361
391
  subclass.content_model :simple
@@ -374,6 +404,7 @@ module Asciidoctor
374
404
  include DiagramProcessor
375
405
 
376
406
  def self.inherited(subclass)
407
+ subclass.use_dsl
377
408
  subclass.name_positional_attributes ['format']
378
409
  end
379
410
 
@@ -415,7 +446,16 @@ module Asciidoctor
415
446
  block = generate_block(parent, reader_or_target, attributes)
416
447
  attrs = block.attributes.dup
417
448
  target = attrs.delete('target')
418
- create_inline(parent, :image, nil, :type => 'image', :target => target, :attributes => attrs).convert
449
+
450
+ # Don't let the asciidoctor try to apply substitutions.
451
+ # The text of inline macros is nil which will cause an error
452
+ attrs.delete('subs')
453
+
454
+ if block.context == :image
455
+ create_inline(parent, :image, nil, :type => 'image', :target => target, :attributes => attrs)
456
+ else
457
+ create_inline(parent, :quoted, block.source, :type => :monospaced, :attributes => attrs)
458
+ end
419
459
  end
420
460
 
421
461
  def supported_formats(converter)
@@ -26,10 +26,18 @@ module Asciidoctor
26
26
  raise NotImplementedError.new
27
27
  end
28
28
 
29
+ def global_opt(opt)
30
+ global_attr("#{opt}-option")
31
+ end
32
+
29
33
  def global_attr(name, default_value = nil)
30
34
  attr(name) || attr(name, default_value, 'diagram')
31
35
  end
32
36
 
37
+ def opt(opt)
38
+ attr("#{opt}-option")
39
+ end
40
+
33
41
  # Get the value for the specified attribute. First look in the attributes on
34
42
  # this document and return the value of the attribute if found. Otherwise, if
35
43
  # this document is a child of the Document document, look in the attributes of the
@@ -50,7 +58,7 @@ module Asciidoctor
50
58
  # @return [String] the base directory against which relative paths in this diagram should be resolved
51
59
  # @abstract
52
60
  def base_dir
53
- attr('docdir', nil, true) || Dir.pwd
61
+ File.expand_path(attr('docdir', "", true))
54
62
  end
55
63
 
56
64
  # Alias for code
@@ -130,9 +138,10 @@ module Asciidoctor
130
138
 
131
139
  config[cmd_var] = cmd_path
132
140
 
133
- if cmd_path.nil? && options.fetch(:raise_on_error, true)
134
- raise "Could not find the #{cmd_names.map { |c| "'#{c}'" }.join(', ')} executable in PATH; add it to the PATH or specify its location using the '#{attr_names[0]}' document attribute"
135
- end
141
+ end
142
+
143
+ if cmd_path.nil? && options.fetch(:raise_on_error, true)
144
+ raise "Could not find the #{cmd_names.map { |c| "'#{c}'" }.join(', ')} executable in PATH; add it to the PATH or specify its location using the '#{attr_names[0]}' document attribute"
136
145
  end
137
146
 
138
147
  cmd_path
@@ -218,7 +227,7 @@ module Asciidoctor
218
227
  end
219
228
 
220
229
  def checksum
221
- @checksum ||= compute_checksum(code)
230
+ @checksum ||= "#{diagram_type.to_s}-#{compute_checksum(code)}"
222
231
  end
223
232
 
224
233
  protected
@@ -240,7 +249,7 @@ module Asciidoctor
240
249
  md5 << k.to_s if k
241
250
  md5 << v.to_s if v
242
251
  end
243
- md5.hexdigest
252
+ "md5-#{md5.hexdigest}"
244
253
  end
245
254
  end
246
255
 
@@ -262,7 +271,7 @@ module Asciidoctor
262
271
  class FileSource < BasicSource
263
272
  def initialize(block_processor, parent_block, file_name, attributes)
264
273
  super(block_processor, parent_block, attributes)
265
- @file_name = file_name
274
+ @file_name = File.expand_path(file_name)
266
275
  end
267
276
 
268
277
  def base_dir
@@ -289,8 +298,7 @@ module Asciidoctor
289
298
 
290
299
  def load_code
291
300
  if @file_name
292
- lines = File.readlines(@file_name)
293
- lines = prepare_source_array(lines)
301
+ lines = prepare_source_array(File.read(@file_name, :mode => 'rb'))
294
302
  @parent_block.apply_subs(lines, resolve_diagram_subs).join("\n")
295
303
  else
296
304
  ''
@@ -299,40 +307,34 @@ module Asciidoctor
299
307
 
300
308
  private
301
309
 
302
- # Byte arrays for UTF-* Byte Order Marks
303
- BOM_BYTES_UTF_8 = [0xef, 0xbb, 0xbf]
304
- BOM_BYTES_UTF_16LE = [0xff, 0xfe]
305
- BOM_BYTES_UTF_16BE = [0xfe, 0xff]
310
+ # Raw binary strings for UTF-* Byte Order Marks
311
+ BOM_BYTES_UTF_8 = String.new("\xef\xbb\xbf", :encoding => Encoding::ASCII_8BIT)
312
+ BOM_BYTES_UTF_16LE = String.new("\xff\xfe", :encoding => Encoding::ASCII_8BIT)
313
+ BOM_BYTES_UTF_16BE = String.new("\xfe\xff", :encoding => Encoding::ASCII_8BIT)
306
314
 
307
- # Prepare the source data Array for parsing.
315
+ # Prepare the source data for parsing.
308
316
  #
309
- # Encodes the data to UTF-8, if necessary, and removes any trailing
317
+ # Encodes the data to UTF-8 and removes any trailing
310
318
  # whitespace from every line.
311
319
  #
312
- # If a BOM is found at the beginning of the data, a best attempt is made to
313
- # encode it to UTF-8 from the specified source encoding.
314
- #
315
- # data - the source data Array to prepare (no nil entries allowed)
320
+ # data - the source data to prepare
316
321
  #
317
322
  # returns a String Array of prepared lines
318
323
  def prepare_source_array data
319
324
  return [] if data.empty?
320
- if (leading_2_bytes = (leading_bytes = (first = data[0]).unpack 'C3').slice 0, 2) == BOM_BYTES_UTF_16LE
321
- data[0] = first.byteslice 2, first.bytesize
322
- # NOTE you can't split a UTF-16LE string using .lines when encoding is UTF-8; doing so will cause this line to fail
323
- return data.map {|line| (line.encode ::Encoding::UTF_8, ::Encoding::UTF_16LE).rstrip}
324
- elsif leading_2_bytes == BOM_BYTES_UTF_16BE
325
- data[0] = first.byteslice 2, first.bytesize
326
- return data.map {|line| (line.encode ::Encoding::UTF_8, ::Encoding::UTF_16BE).rstrip}
327
- elsif leading_bytes == BOM_BYTES_UTF_8
328
- data[0] = first.byteslice 3, first.bytesize
329
- end
330
- if first.encoding == ::Encoding::UTF_8
331
- data.map {|line| line.rstrip}
325
+
326
+ if data.start_with?(BOM_BYTES_UTF_16LE)
327
+ utf8_data = data.byteslice(2, data.bytesize).encode(::Encoding::UTF_8, ::Encoding::UTF_16LE)
328
+ elsif data.start_with?(BOM_BYTES_UTF_16BE)
329
+ utf8_data = data.byteslice(2, data.bytesize).encode(::Encoding::UTF_8, ::Encoding::UTF_16BE)
330
+ elsif data.start_with?(BOM_BYTES_UTF_8)
331
+ utf8_data = data.byteslice(3, data.bytesize).force_encoding(::Encoding::UTF_8)
332
332
  else
333
- data.map {|line| (line.encode ::Encoding::UTF_8).rstrip}
333
+ utf8_data = data.force_encoding(::Encoding::UTF_8)
334
334
  end
335
+
336
+ utf8_data.lines.map {|line| line.rstrip}
335
337
  end
336
338
  end
337
339
  end
338
- end
340
+ end
@@ -38,7 +38,10 @@ module Asciidoctor
38
38
  begin
39
39
  target_file.close
40
40
  generate_stdin_file(python_path, code, target_file.path + ".#{format}") do |tool|
41
- [tool, '-']
41
+ {
42
+ :args => [tool, '-'],
43
+ :chdir => source.base_dir
44
+ }
42
45
  end
43
46
  ensure
44
47
  target_file.unlink
@@ -24,23 +24,25 @@ module Asciidoctor
24
24
  :bullet_characters => lambda { |o, v| o << '--bullet-characters' << v if v }
25
25
  }
26
26
 
27
- CLASSPATH_ENV = 'DIAGRAM_DITAA_CLASSPATH'
28
- DITAA_JARS = if ENV.has_key?(CLASSPATH_ENV)
29
- ENV[CLASSPATH_ENV].split(File::PATH_SEPARATOR)
27
+ CLASSPATH_ENV = Java.environment_variable('DIAGRAM_DITAA_CLASSPATH')
28
+ DITAA_JARS = if CLASSPATH_ENV
29
+ CLASSPATH_ENV.split(File::PATH_SEPARATOR)
30
30
  else
31
31
  begin
32
32
  require 'asciidoctor-diagram/ditaa/classpath'
33
33
  ::Asciidoctor::Diagram::DitaaClasspath::JAR_FILES
34
34
  rescue LoadError
35
- raise "Could not load Ditaa. Eiter require 'asciidoctor-diagram-ditaamini' or specify the location of the Ditaa JAR(s) using the 'DIAGRAM_DITAA_CLASSPATH' environment variable."
35
+ nil
36
36
  end
37
37
  end
38
38
 
39
- Java.classpath.concat Dir[File.join(File.dirname(__FILE__), '*.jar')]
40
- Java.classpath.concat DITAA_JARS
39
+ if DITAA_JARS
40
+ Java.classpath.concat Dir[File.join(File.dirname(__FILE__), '*.jar')]
41
+ Java.classpath.concat DITAA_JARS
42
+ end
41
43
 
42
44
  def supported_formats
43
- [:png, :svg]
45
+ [:png, :svg, :txt]
44
46
  end
45
47
 
46
48
  def collect_options(source)
@@ -59,6 +61,12 @@ module Asciidoctor
59
61
  end
60
62
 
61
63
  def convert(source, format, options)
64
+ return source.to_s if format == :txt
65
+
66
+ unless DITAA_JARS
67
+ raise "Could not load Ditaa. Either require 'asciidoctor-diagram-ditaamini' or specify the location of the Ditaa JAR(s) using the 'DIAGRAM_DITAA_CLASSPATH' environment variable."
68
+ end
69
+
62
70
  Java.load
63
71
 
64
72
  flags = []
@@ -22,7 +22,10 @@ module Asciidoctor
22
22
  code << "\n.PE" unless code.start_with?("\n.PE")
23
23
 
24
24
  generate_file_stdout(dpic_path, format.to_s, code) do |tool_path, input_path|
25
- [tool_path, "-v", "-z", input_path]
25
+ {
26
+ :args => [tool_path, "-v", "-z", input_path],
27
+ :chdir => source.base_dir
28
+ }
26
29
  end
27
30
  end
28
31
  end
@@ -15,7 +15,7 @@ module Asciidoctor
15
15
  end
16
16
 
17
17
  def convert(source, format, options)
18
- erd_path = source.find_command('erd')
18
+ erd_path = source.find_command('erd', :alt_cmds => ['erd-go'])
19
19
  dot_path = source.find_command('dot', :alt_attrs => ['graphvizdot'])
20
20
 
21
21
  dot_code = generate_stdin(erd_path, format.to_s, source.to_s) do |tool_path, output_path|
@@ -23,7 +23,10 @@ module Asciidoctor
23
23
  end
24
24
 
25
25
  generate_stdin(dot_path, format.to_s, dot_code) do |tool_path, output_path|
26
- [tool_path, "-o#{Platform.native_path(output_path)}", "-T#{format.to_s}"]
26
+ {
27
+ :args => [tool_path, "-o#{Platform.native_path(output_path)}", "-T#{format.to_s}"],
28
+ :chdir => source.base_dir
29
+ }
27
30
  end
28
31
  end
29
32
  end
@@ -55,8 +55,14 @@ module Asciidoctor
55
55
 
56
56
  code << "\n"
57
57
  code << source.to_s
58
+ code << "\n"
58
59
 
59
- generate_stdin_stdout(source.find_command('gnuplot'), code)
60
+ generate_stdin_stdout(source.find_command('gnuplot'), code) do |tool|
61
+ {
62
+ :args => [tool],
63
+ :chdir => source.base_dir
64
+ }
65
+ end
60
66
  end
61
67
  end
62
68
  end
@@ -24,7 +24,10 @@ module Asciidoctor
24
24
  layout = options[:layout]
25
25
  args << "-K#{layout}" if layout
26
26
 
27
- args
27
+ {
28
+ :args => args,
29
+ :chdir => source.base_dir
30
+ }
28
31
  end
29
32
  end
30
33
  end
@@ -34,7 +34,10 @@ module Asciidoctor
34
34
  args << argument
35
35
  end
36
36
 
37
- args
37
+ {
38
+ :args => args,
39
+ :chdir => source.base_dir
40
+ }
38
41
  end
39
42
  end
40
43
  end
@@ -1,8 +1,7 @@
1
1
  require_relative '../diagram_converter'
2
- require_relative '../util/cli_generator'
2
+ require_relative '../util/base64'
3
3
  require_relative '../util/platform'
4
4
 
5
- require 'base64'
6
5
  require 'net/http'
7
6
  require 'uri'
8
7
  require 'zlib'
@@ -48,15 +47,20 @@ module Asciidoctor
48
47
  compressed = deflate.deflate(code, Zlib::FINISH)
49
48
  deflate.close
50
49
 
51
- encoded = Base64.urlsafe_encode64(compressed)
52
- data = '0A' + encoded
50
+ data = Base64.urlsafe_encode(compressed)
51
+ # See https://plantuml.com/text-encoding
52
+ # PlantUML uses a different alphabet than the one from RFC 4648
53
+ data.tr!(
54
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
55
+ '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
56
+ )
53
57
 
54
58
  path = uri.path.dup
55
59
  path << '/' unless path.end_with? '/'
56
60
  path << format.to_s
57
61
  when :kroki_io
58
62
  compressed = Zlib.deflate(code, Zlib::BEST_COMPRESSION)
59
- data = Base64.urlsafe_encode64(compressed)
63
+ data = Base64.urlsafe_encode(compressed)
60
64
 
61
65
  path = uri.path.dup
62
66
  path << '/' unless path.end_with? '/'
@@ -68,7 +72,8 @@ module Asciidoctor
68
72
 
69
73
  get_path = path.dup << '/' << data
70
74
 
71
- if get_path.length > options[:max_get_size]
75
+ host = uri.host
76
+ if (host.nil? || !host.downcase.end_with?('plantuml.com')) && get_path.length > options[:max_get_size]
72
77
  uri.path = path
73
78
  get_uri(uri, code, 'text/plain; charset=utf-8')
74
79
  else
@@ -106,7 +111,11 @@ module Asciidoctor
106
111
  resolved_uri = new_uri
107
112
  end
108
113
 
109
- get_uri(resolved_uri, post_data, post_content_type, attempt + 1)
114
+ if response.code == '307'
115
+ get_uri(resolved_uri, post_data, post_content_type, attempt + 1)
116
+ else
117
+ get_uri(resolved_uri, nil, nil, attempt + 1)
118
+ end
110
119
  else
111
120
  response.value
112
121
  end
@@ -1,10 +1,10 @@
1
- require 'base64'
2
1
  require 'json'
3
2
  require 'sinatra/base'
4
3
  require 'zlib'
5
4
 
6
5
  require_relative '../diagram_source'
7
6
  require_relative '../graphviz/converter'
7
+ require_relative '../util/base64'
8
8
  require_relative '../util/which'
9
9
 
10
10
  module Asciidoctor
@@ -14,7 +14,7 @@ module Asciidoctor
14
14
  type = params['type']
15
15
  accepts = lambda { |t| params['format'].downcase.to_sym == t }
16
16
  raw_source = params['source']
17
- decoded_source = Base64.urlsafe_decode64(raw_source)
17
+ decoded_source = Base64.urlsafe_decode(raw_source)
18
18
  decompressed_source = Zlib::Inflate.inflate(decoded_source)
19
19
  source = decompressed_source
20
20
  render_diagram(type, accepts, source, {})
@@ -47,7 +47,7 @@ module Asciidoctor
47
47
  generate_stdin(source.find_command('lilypond', :path => EXTRA_PATH), format.to_s, code) do |tool_path, output_path|
48
48
  args = [tool_path, '-daux-files=#f', '-dbackend=eps', '-dno-gs-load-fonts', '-dinclude-eps-fonts', '-o', Platform.native_path(output_path), '-f', format.to_s]
49
49
 
50
- args << '-dsafe'
50
+ args << "-dcrop=#t"
51
51
  args << "-dresolution=#{resolution}" if resolution
52
52
  args << "-dpixmap-format=pngalpha" if format == :png
53
53
 
@@ -55,7 +55,8 @@ module Asciidoctor
55
55
 
56
56
  {
57
57
  :args => args,
58
- :out_file => "#{output_path}.#{format.to_s}"
58
+ :out_file => "#{output_path}.cropped.#{format.to_s}",
59
+ :chdir => source.base_dir
59
60
  }
60
61
  end
61
62
  end
@@ -19,7 +19,26 @@ module Asciidoctor
19
19
  bg_img = source.attr('background')
20
20
  raise "background attribute is required" unless bg_img
21
21
 
22
- options = source.attr('options', '').split(',')
22
+ margin = source.attr('margin', '')
23
+ margin_parts = margin.split(' ')
24
+ case margin_parts.length
25
+ when 0
26
+ ml = mr = mt = mb = nil
27
+ when 1
28
+ ml = mr = mt = mb = margin_parts[0]
29
+ when 2
30
+ mt = mb = margin_parts[0]
31
+ ml = mr = margin_parts[1]
32
+ when 3
33
+ mt = margin_parts[0]
34
+ ml = mr = margin_parts[1]
35
+ mb = margin_parts[2]
36
+ else
37
+ mt = margin_parts[0]
38
+ mr = margin_parts[1]
39
+ mb = margin_parts[2]
40
+ ml = margin_parts[3]
41
+ end
23
42
 
24
43
  {
25
44
  :bg_img => bg_img,
@@ -29,7 +48,14 @@ module Asciidoctor
29
48
  :stroke_color => source.attr(['strokecolor', 'stroke-color']),
30
49
  :stroke_width => source.attr(['strokewidth', 'stroke-width']),
31
50
  :font => source.attr('font', 'Impact'),
32
- :noupcase => options.include?('noupcase'),
51
+ :font_size => source.attr('font_size', nil),
52
+ :alignment => source.attr('alignment', nil),
53
+ :margin_left => ml,
54
+ :margin_right => mr,
55
+ :margin_top => mt,
56
+ :margin_bottom => mb,
57
+ :noupcase => source.opt('noupcase'),
58
+ :imagesdir => source.attr('imagesdir')
33
59
  }
34
60
  end
35
61
 
@@ -48,7 +74,7 @@ module Asciidoctor
48
74
  bg_img = options[:bg_img]
49
75
  raise "background attribute is required" unless bg_img
50
76
 
51
- bg_img = source.resolve_path(bg_img, source.attr('imagesdir'))
77
+ bg_img = source.resolve_path(bg_img, options[:imagesdir])
52
78
 
53
79
  top_label = options[:top_label]
54
80
  bottom_label = options[:bottom_label]
@@ -164,7 +164,8 @@ module Asciidoctor
164
164
 
165
165
  {
166
166
  :args => args,
167
- :env => {'NODE_OPTIONS' => '--unhandled-rejections=strict'}
167
+ :env => {'NODE_OPTIONS' => '--unhandled-rejections=strict'},
168
+ :chdir => source.base_dir
168
169
  }
169
170
  end
170
171
  end
@@ -200,7 +201,8 @@ module Asciidoctor
200
201
 
201
202
  {
202
203
  :args => args,
203
- :out_file => output_file
204
+ :out_file => output_file,
205
+ :chdir => source.base_dir
204
206
  }
205
207
  end
206
208
  end
@@ -21,13 +21,17 @@ module Asciidoctor
21
21
  def convert(source, format, options)
22
22
  font = options[:font]
23
23
 
24
- generate_stdin(source.find_command('mscgen'), format.to_s, source.to_s) do |tool_path, output_path|
24
+ generate_stdin(source.find_command('mscgen', :alt_cmds => ['mscgen_js']), format.to_s, source.to_s) do |tool_path, output_path|
25
25
  args = [tool_path, '-o', Platform.native_path(output_path), '-T', format.to_s]
26
26
  if font
27
27
  args << '-F' << font
28
28
  end
29
29
  args << '-'
30
- args
30
+
31
+ {
32
+ :args => args,
33
+ :chdir => source.base_dir
34
+ }
31
35
  end
32
36
  end
33
37
  end
@@ -17,7 +17,10 @@ module Asciidoctor
17
17
 
18
18
  def convert(source, format, options)
19
19
  generate_file(source.find_command('nomnoml'), 'nomnoml', format.to_s, source.to_s) do |tool_path, input_path, output_path|
20
- [tool_path, Platform.native_path(input_path), Platform.native_path(output_path)]
20
+ {
21
+ :args => [tool_path, Platform.native_path(input_path), Platform.native_path(output_path)],
22
+ :chdir => source.base_dir
23
+ }
21
24
  end
22
25
  end
23
26
  end
@@ -0,0 +1,53 @@
1
+ require_relative '../diagram_converter'
2
+ require_relative '../util/cli_generator'
3
+ require_relative '../util/platform'
4
+
5
+ module Asciidoctor
6
+ module Diagram
7
+ # @private
8
+ class PenroseConverter
9
+ include DiagramConverter
10
+ include CliGenerator
11
+
12
+ def supported_formats
13
+ [:svg]
14
+ end
15
+
16
+ def collect_options(source)
17
+ {
18
+ :domain => source.attr('domain_file'),
19
+ :style => source.attr('style_file'),
20
+ :variation => source.attr('variation')
21
+ }
22
+ end
23
+
24
+ def convert(source, format, options)
25
+ domain_path = options[:domain]
26
+ raise "Domain file is required" unless domain_path
27
+ style_path = options[:style]
28
+ raise "Style file is required" unless style_path
29
+ variation = options[:variation]
30
+
31
+ generate_file(source.find_command('roger'), 'substance', format.to_s, source.to_s) do |tool_path, source_path, output_path|
32
+ args = [tool_path, 'trio', '-o', Platform.native_path(output_path)]
33
+
34
+ args << "-v" << variation if variation
35
+
36
+ args << "--path"
37
+ args << "/"
38
+
39
+ args << "--trio"
40
+ args << Platform.native_path(source_path)
41
+ args << Platform.native_path(source.resolve_path(domain_path))
42
+ args << Platform.native_path(source.resolve_path(style_path))
43
+ args << "--"
44
+
45
+ {
46
+ :args => args,
47
+ :chdir => source.base_dir
48
+ }
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,18 @@
1
+ require_relative 'converter'
2
+ require_relative '../diagram_processor'
3
+
4
+ module Asciidoctor
5
+ module Diagram
6
+ class PenroseBlockProcessor < DiagramBlockProcessor
7
+ use_converter PenroseConverter
8
+ end
9
+
10
+ class PenroseBlockMacroProcessor < DiagramBlockMacroProcessor
11
+ use_converter PenroseConverter
12
+ end
13
+
14
+ class PenroseInlineMacroProcessor < DiagramInlineMacroProcessor
15
+ use_converter PenroseConverter
16
+ end
17
+ end
18
+ end