liquid-diagrams 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +124 -0
  4. data/lib/liquid-diagrams.rb +3 -0
  5. data/lib/liquid_diagrams/basic_block.rb +49 -0
  6. data/lib/liquid_diagrams/basic_renderer.rb +20 -0
  7. data/lib/liquid_diagrams/errors.rb +12 -0
  8. data/lib/liquid_diagrams/renderers/blockdiag_renderer.rb +50 -0
  9. data/lib/liquid_diagrams/renderers/erd_renderer.rb +36 -0
  10. data/lib/liquid_diagrams/renderers/graphviz_renderer.rb +33 -0
  11. data/lib/liquid_diagrams/renderers/mermaid_renderer.rb +34 -0
  12. data/lib/liquid_diagrams/renderers/nomnoml_renderer.rb +17 -0
  13. data/lib/liquid_diagrams/renderers/plantuml_renderer.rb +20 -0
  14. data/lib/liquid_diagrams/renderers/smcat_renderer.rb +31 -0
  15. data/lib/liquid_diagrams/renderers/svgbob_renderer.rb +28 -0
  16. data/lib/liquid_diagrams/renderers/syntrax_renderer.rb +28 -0
  17. data/lib/liquid_diagrams/renderers/vega_renderer.rb +25 -0
  18. data/lib/liquid_diagrams/renderers/wavedrom_renderer.rb +17 -0
  19. data/lib/liquid_diagrams/rendering.rb +47 -0
  20. data/lib/liquid_diagrams/utils.rb +47 -0
  21. data/lib/liquid_diagrams/version.rb +5 -0
  22. data/lib/liquid_diagrams.rb +89 -0
  23. data/spec/liquid_diagrams/basic_block_spec.rb +49 -0
  24. data/spec/liquid_diagrams/basic_renderer_spec.rb +28 -0
  25. data/spec/liquid_diagrams/renderers/blockdiag_renderer_spec.rb +43 -0
  26. data/spec/liquid_diagrams/renderers/erd_renderer_spec.rb +49 -0
  27. data/spec/liquid_diagrams/renderers/graphviz_renderer_spec.rb +63 -0
  28. data/spec/liquid_diagrams/renderers/mermaid_renderer_spec.rb +31 -0
  29. data/spec/liquid_diagrams/renderers/nomnoml_renderer_spec.rb +15 -0
  30. data/spec/liquid_diagrams/renderers/plantuml_renderer_spec.rb +41 -0
  31. data/spec/liquid_diagrams/renderers/smcat_renderer_spec.rb +33 -0
  32. data/spec/liquid_diagrams/renderers/svgbob_renderer_spec.rb +31 -0
  33. data/spec/liquid_diagrams/renderers/syntrax_renderer_spec.rb +31 -0
  34. data/spec/liquid_diagrams/renderers/vega_renderer_spec.rb +33 -0
  35. data/spec/liquid_diagrams/renderers/wavedrom_renderer_spec.rb +15 -0
  36. data/spec/liquid_diagrams/rendering_spec.rb +127 -0
  37. data/spec/liquid_diagrams/utils_spec.rb +66 -0
  38. data/spec/liquid_diagrams_spec.rb +79 -0
  39. data/spec/spec_helper.rb +22 -0
  40. data/spec/support/shared_examples.rb +47 -0
  41. data/vendor/mermaid_puppeteer_config.json +3 -0
  42. data/vendor/plantuml.1.2020.1.jar +0 -0
  43. metadata +232 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: bf13af189666b210d371da56b940db2a64d320f154867ef334d196ed4d4213dd
4
+ data.tar.gz: 5e9c1f89224785821de3de8c7d0365b00dbec7a864e08b0de1aa9dea7ac03e8c
5
+ SHA512:
6
+ metadata.gz: 5c50fbdc3ab16e9f6fd411d2819ca5492d03e239fc185273d4d2382d32c198c7c53884d0ffcef61eeda154eff0f3984c130b90e542424ebc32fae462b8b6be82
7
+ data.tar.gz: 203812b4bb6ecbf2d812dcb8748124f8a13050afed77986d59d22d38b0837f730ffd1ea4c3405d4ae2fdba4aa7bab1d81711456552651291bd02842f82a2d067
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 zhustec
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,124 @@
1
+ # Liquid Diagrams
2
+
3
+ [![Gem](https://img.shields.io/gem/v/liquid-diagrams.svg?label=Gem&style=flat-square)](https://rubygems.org/gems/liquid-diagrams)
4
+ [![Test](https://img.shields.io/github/workflow/status/zhustec/liquid-diagrams/Test?label=Test&style=flat-square)](https://github.com/zhustec/liquid-diagrams/actions?query=workflow%3ATest)
5
+ [![Linter](https://img.shields.io/github/workflow/status/zhustec/liquid-diagrams/Lint?label=Style&style=flat-square)](https://github.com/zhustec/liquid-diagrams/actions?query=workflow%3ALint)
6
+ [![Coverage](https://img.shields.io/coveralls/github/zhustec/liquid-diagrams?label=Coverage&style=flat-square)](https://coveralls.io/github/zhustec/liquid-diagrams)
7
+ [![License](https://img.shields.io/github/license/zhustec/liquid-diagrams.svg?label=License&style=flat-square)](https://github.com/zhustec/liquid-diagrams/blob/master/LICENSE)
8
+
9
+ Liquid Diagrams is a liquid plugins for creating diagrams, it is inspired by [asciidoctor-diagram](https://github.com/asciidoctor/asciidoctor-diagram). Currently support:
10
+
11
+ - [**Blockdiag**](http://blockdiag.com/en/)
12
+ - [**Erd**](https://github.com/BurntSushi/erd)
13
+ - [**GraphViz**](http://graphviz.org/)
14
+ - [**Mermaid**](https://mermaid-js.github.io/mermaid/)
15
+ - [**Nomnoml**](http://nomnoml.com/)
16
+ - [**PlantUML**](https://plantuml.com/)
17
+ - [**Svgbob**](https://ivanceras.github.io/svgbob-editor/)
18
+ - [**Syntrax**](https://kevinpt.github.io/syntrax/)
19
+ - [**Vega**](https://vega.github.io/vega/)
20
+ - [**Vega-Lite**](https://vega.github.io/vega-lite/)
21
+ - [**WaveDrom**](https://wavedrom.com/).
22
+
23
+ **NOTE:** This project is under development currently.
24
+
25
+ - [Installation](#installation)
26
+ - [Usage](#usage)
27
+ - [List of diagrams](#list-of-diagrams)
28
+ - [Register diagrams](#register-diagrams)
29
+ - [Now you can use the diagrams in liquid](#now-you-can-use-the-diagrams-in-liquid)
30
+ - [Configurations](#configurations)
31
+ - [Contributing](#contributing)
32
+ - [License](#license)
33
+ - [Code of Conduct](#code-of-conduct)
34
+
35
+ ## Installation
36
+
37
+ Add this line to your application's Gemfile:
38
+
39
+ ```ruby
40
+ gem 'liquid-diagrams'
41
+ ```
42
+
43
+ And then execute:
44
+
45
+ ```bash
46
+ bundle install
47
+ ```
48
+
49
+ Or install it yourself as:
50
+
51
+ ```bash
52
+ gem install liquid-diagrams
53
+ ```
54
+
55
+ ## Usage
56
+
57
+ ```ruby
58
+ # Require `liquid_diagrams` or `liquid-diagrams`
59
+
60
+ require 'liquid_diagrams'
61
+ ```
62
+
63
+ ### List of diagrams
64
+
65
+ ```ruby
66
+ LiquidDiagrams.diagrams
67
+ #=> [:actdiag, :blockdiag, :graphviz, :mermaid, ...]
68
+
69
+ # Registered diagrams, no diagrams is registered by default
70
+ LiquidDiagrams.registered_diagrams
71
+ # => {}
72
+ ```
73
+
74
+ ### Register diagrams
75
+
76
+ ```ruby
77
+ # Register one by one
78
+ LiquidDiagrams.register_diagram :graphviz
79
+ # => LiquidDiagrams::Blocks::GraphvizBlock
80
+
81
+ # Register in batch
82
+ LiquidDiagrams.register_diagrams :blockdiag, :mermaid
83
+ # => [Blocks::BlockdiagBlock, Blocks::MermaidBlock]
84
+
85
+ # Registered diagrams
86
+ LiquidDiagrams.registered_diagrams
87
+ # => {:graphviz => LiquidDiagrams::Blocks::GraphvizBlock, ...}
88
+
89
+ # Register all available diagrams
90
+ LiquidDiagrams.register_diagrams(LiquidDiagrams.diagrams)
91
+ ```
92
+
93
+ ### Now you can use the diagrams in liquid
94
+
95
+ ```ruby
96
+ content = <<~CONTENT
97
+ {% blockdiag %}
98
+ blockdiag {
99
+ A -> B -> C -> D;
100
+ A -> E -> F -> G;
101
+ }
102
+ {% endblockdiag %}
103
+ CONTENT
104
+
105
+ template = Liquid::Template.parse(content)
106
+ template.render
107
+ # => "<svg ...>...</svg>"
108
+ ```
109
+
110
+ ## Configurations
111
+
112
+ See [Configrurations](CONFIGURATIONS.md)
113
+
114
+ ## Contributing
115
+
116
+ Bug reports and pull requests are welcome on GitHub at <https://github.com/zhustec/liquid-diagrams.> This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/zhustec/liquid-diagrams/blob/master/CODE_OF_CONDUCT.md).
117
+
118
+ ## License
119
+
120
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
121
+
122
+ ## Code of Conduct
123
+
124
+ Everyone interacting in the `liquid-diagrams` project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](CODE_OF_CONDUCT.md).
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'liquid_diagrams'
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LiquidDiagrams
4
+ # @abstract Subclass and override {#render} or {#render!} to implement
5
+ class BasicBlock < ::Liquid::Block
6
+ # Return the renderer class matching the block
7
+ #
8
+ # @return [BasicRenderer]
9
+ #
10
+ # @raise [NameError] if renderer class not found
11
+ def self.renderer
12
+ @renderer ||= Renderers.const_get(
13
+ name.split('::').last.gsub(/Block$/, 'Renderer')
14
+ )
15
+ end
16
+
17
+ # Render with error rescued
18
+ #
19
+ # @param context [Liquid::Context]
20
+ #
21
+ # @return String
22
+ def render(context)
23
+ @content = super.to_s
24
+
25
+ render!(context)
26
+ rescue Errors::BasicError => error
27
+ error
28
+ end
29
+
30
+ # Render without error rescued
31
+ #
32
+ # @param context [Liquid::Context]
33
+ #
34
+ # @return String
35
+ #
36
+ # @raise [Errors::BasicError]
37
+ #
38
+ # rubocop:disable Lint/UnusedMethodArgument
39
+ def render!(context)
40
+ self.class.renderer.render(@content, config)
41
+ end
42
+ # rubocop:enable Lint/UnusedMethodArgument
43
+
44
+ def config
45
+ config = (parse_context[:config] || {})
46
+ config.fetch(name.split('::').last.chomp('Block').downcase, {})
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LiquidDiagrams
4
+ # @abstract Subclass and override {#render} to implement
5
+ class BasicRenderer
6
+ def self.render(content, options = {})
7
+ new(content, options).render
8
+ end
9
+
10
+ def initialize(content, options = {})
11
+ @content = content
12
+ @options = options
13
+ @config = @options.delete(:config) || {}
14
+ end
15
+
16
+ def render
17
+ raise Errors::NotImplementedError
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LiquidDiagrams
4
+ module Errors
5
+ BasicError = Class.new(::StandardError)
6
+
7
+ CommandNotFoundError = Class.new(BasicError)
8
+ DiagramNotFoundError = Class.new(BasicError)
9
+ RenderingFailedError = Class.new(BasicError)
10
+ NotImplementedError = Class.new(BasicError)
11
+ end
12
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LiquidDiagrams
4
+ module Renderers
5
+ %i[ Blockdiag
6
+ Seqdiag
7
+ Actdiag
8
+ Nwdiag
9
+ Rackdiag
10
+ Packetdiag ].each do |diagram|
11
+ renderer = Class.new(BasicRenderer) do
12
+ const_set :OPTIONS, %w[
13
+ config
14
+ font
15
+ fontmap
16
+ size
17
+ ].freeze
18
+
19
+ const_set :SWITCHES, {
20
+ 'antialias' => false
21
+ }.freeze
22
+
23
+ def render
24
+ Rendering.render_with_tempfile(build_command, @content) do |input, output|
25
+ "#{input} -o #{output}"
26
+ end
27
+ end
28
+
29
+ define_method :build_command do
30
+ command = +"#{diagram.downcase} -T svg --nodoctype"
31
+
32
+ options = self.class.const_get(:OPTIONS)
33
+ switches = self.class.const_get(:SWITCHES)
34
+
35
+ @config.slice(*options).each do |opt, value|
36
+ command << " --#{opt}=#{value}"
37
+ end
38
+
39
+ Utils.merge(switches, @config).each do |swc, value|
40
+ command << " --#{swc}" if value
41
+ end
42
+
43
+ command
44
+ end
45
+ end
46
+
47
+ const_set "#{diagram}Renderer", renderer
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LiquidDiagrams
4
+ module Renderers
5
+ class ErdRenderer < BasicRenderer
6
+ OPTIONS = %w[
7
+ config
8
+ edge
9
+ ].freeze
10
+
11
+ SWITCHES = {
12
+ 'dot-entity' => false
13
+ }.freeze
14
+
15
+ XML_REGEX = /^<\?xml(([^>]|\n)*>\n?){2}/.freeze
16
+
17
+ def render
18
+ Rendering.render_with_stdin_stdout(build_command, @content).sub(XML_REGEX, '')
19
+ end
20
+
21
+ def build_command
22
+ command = +'erd --fmt=svg'
23
+
24
+ @config.slice(*OPTIONS).each do |opt, value|
25
+ command << " --#{opt}=#{value}"
26
+ end
27
+
28
+ Utils.merge(SWITCHES, @config).each do |switch, value|
29
+ command << " --#{switch}" if value
30
+ end
31
+
32
+ command
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LiquidDiagrams
4
+ module Renderers
5
+ class GraphvizRenderer < BasicRenderer
6
+ MAPPERS = {
7
+ 'layout' => 'K',
8
+ 'graph_attributes' => 'G',
9
+ 'node_attributes' => 'N',
10
+ 'edge_attributes' => 'E'
11
+ }.freeze
12
+
13
+ XML_REGEX = /^<\?xml(([^>]|\n)*>\n?){2}/.freeze
14
+
15
+ def render
16
+ output = Rendering.render_with_stdin_stdout(build_command, @content)
17
+ output.dup.force_encoding('utf-8').sub(XML_REGEX, '')
18
+ end
19
+
20
+ def build_command
21
+ command = +'dot -Tsvg'
22
+
23
+ @config.slice(*MAPPERS.keys).each do |opt, attrs|
24
+ command << Utils.join(attrs, with: " -#{MAPPERS[opt]}") do |attr|
25
+ Array(attr).join('=')
26
+ end
27
+ end
28
+
29
+ command
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LiquidDiagrams
4
+ module Renderers
5
+ class MermaidRenderer < BasicRenderer
6
+ OPTIONS = %w[
7
+ theme
8
+ width
9
+ height
10
+ backgroundColor
11
+ configFile
12
+ cssFile
13
+ scale
14
+ ].freeze
15
+
16
+ def render
17
+ Rendering.render_with_tempfile(build_command, @content) do |input, output|
18
+ "--input #{input} --output #{output}"
19
+ end
20
+ end
21
+
22
+ def build_command
23
+ command = +'mmdc --puppeteerConfigFile '
24
+ command << Utils.vendor_path('mermaid_puppeteer_config.json')
25
+
26
+ @config.slice(*OPTIONS).each do |opt, value|
27
+ command << " --#{opt} #{value}"
28
+ end
29
+
30
+ command
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LiquidDiagrams
4
+ module Renderers
5
+ class NomnomlRenderer < BasicRenderer
6
+ def render
7
+ Rendering.render_with_tempfile(build_command, @content) do |input, output|
8
+ "#{input} #{output}"
9
+ end
10
+ end
11
+
12
+ def build_command
13
+ 'nomnoml'
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LiquidDiagrams
4
+ module Renderers
5
+ class PlantumlRenderer < BasicRenderer
6
+ XML_REGEX = /^<\?xml([^>]|\n)*>\n?/.freeze
7
+
8
+ def render
9
+ Rendering.render_with_stdin_stdout(build_command, @content).sub(XML_REGEX, '')
10
+ end
11
+
12
+ def build_command
13
+ jar = Utils.vendor_path('Plantuml.1.2020.1.jar')
14
+
15
+ options = +Utils.run_jar(jar)
16
+ options << ' -tsvg -pipe'
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LiquidDiagrams
4
+ module Renderers
5
+ class SmcatRenderer < BasicRenderer
6
+ OPTIONS = %w[
7
+ direction
8
+ engine
9
+ input-type
10
+ ].freeze
11
+
12
+ XML_REGEX = /^<\?xml(([^>]|\n)*>\n?){2}/.freeze
13
+
14
+ def render
15
+ Rendering.render_with_tempfile(build_command, @content) do |input, output|
16
+ "#{input} --output-to #{output}"
17
+ end.sub(XML_REGEX, '')
18
+ end
19
+
20
+ def build_command
21
+ command = +'Smcat'
22
+
23
+ @config.slice(*OPTIONS).each do |opt, value|
24
+ command << " --#{opt} #{value}"
25
+ end
26
+
27
+ command
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LiquidDiagrams
4
+ module Renderers
5
+ class SvgbobRenderer < BasicRenderer
6
+ OPTIONS = %w[
7
+ font-family
8
+ font-size
9
+ scale
10
+ stroke-width
11
+ ].freeze
12
+
13
+ def render
14
+ Rendering.render_with_stdin_stdout(build_command, @content)
15
+ end
16
+
17
+ def build_command
18
+ command = +'svgbob'
19
+
20
+ @config.slice(*OPTIONS).each do |opt, value|
21
+ command << " --#{opt} #{value}"
22
+ end
23
+
24
+ command
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LiquidDiagrams
4
+ module Renderers
5
+ class SyntraxRenderer < BasicRenderer
6
+ OPTIONS = %w[
7
+ scale
8
+ style
9
+ ].freeze
10
+
11
+ def render
12
+ Rendering.render_with_tempfile(build_command, @content) do |input, output|
13
+ "--input #{input} --output #{output}"
14
+ end
15
+ end
16
+
17
+ def build_command
18
+ command = +'syntrax'
19
+
20
+ @config.slice(*OPTIONS).each do |opt, value|
21
+ command << " --#{opt} #{value}"
22
+ end
23
+
24
+ command
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LiquidDiagrams
4
+ module Renderers
5
+ class VegaRenderer < BasicRenderer
6
+ OPTIONS = %w[
7
+ scale
8
+ ].freeze
9
+
10
+ def render
11
+ Rendering.render_with_stdin_stdout(build_command, @content)
12
+ end
13
+
14
+ def build_command
15
+ command = +'vg2svg'
16
+
17
+ @config.slice(*OPTIONS).each do |opt, value|
18
+ command << " --#{opt} #{value}"
19
+ end
20
+
21
+ command
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LiquidDiagrams
4
+ module Renderers
5
+ class WavedromRenderer < BasicRenderer
6
+ def render
7
+ Rendering.render_with_tempfile(build_command, @content) do |input, output|
8
+ "--input #{input} --svg #{output}"
9
+ end
10
+ end
11
+
12
+ def build_command
13
+ 'wavedrom-cli'
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'open3'
4
+ require 'tempfile'
5
+ require 'tmpdir'
6
+
7
+ module LiquidDiagrams
8
+ module Rendering
9
+ module_function
10
+
11
+ def render_with_stdin_stdout(command, content)
12
+ render_with_command(command, :stdout, stdin_data: content)
13
+ end
14
+
15
+ def render_with_tempfile(command, content)
16
+ input = Tempfile.new('input')
17
+ output = Tempfile.new(%w[output .svg])
18
+
19
+ File.write(input.path, content)
20
+
21
+ extra = yield input.path, output.path
22
+ command = "#{command} #{extra}"
23
+
24
+ render_with_command(command, output.path)
25
+ # TODO: recue Tempfile.new and File.write error
26
+ ensure
27
+ input.close!
28
+ output.close!
29
+ end
30
+
31
+ def render_with_command(command, output = :stdout, **options)
32
+ begin
33
+ stdout, stderr, status = Open3.capture3(command, **options)
34
+ rescue Errno::ENOENT
35
+ raise Errors::CommandNotFoundError, command.split(' ')[0]
36
+ end
37
+
38
+ unless status.success?
39
+ raise Errors::RenderingFailedError, <<~MSG
40
+ #{command}: #{stderr.empty? ? stdout : stderr}
41
+ MSG
42
+ end
43
+
44
+ output == :stdout ? stdout : File.read(output)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LiquidDiagrams
4
+ module Utils
5
+ module_function
6
+
7
+ # Join the args with prefix
8
+ #
9
+ # @param args
10
+ # @param with [String]
11
+ #
12
+ # @return [String]
13
+ #
14
+ # @example join on string
15
+ # join('path', with: ' -I') # => ' -Ipath'
16
+ #
17
+ # @example join on array
18
+ # join(['path1', 'path2'], with: ' -I') # => ' -Ipath1 -Ipath2'
19
+ #
20
+ # @example join on hash
21
+ # join({ color: 'red', size: '10' }, with: ' --') do |k, v|
22
+ # "#{k} #{v}"
23
+ # end # => ' --color red --size 10'
24
+ def join(args, with:)
25
+ args = Array(args)
26
+ args = args.map { |arg| yield arg } if block_given?
27
+
28
+ "#{with}#{args.join(with)}"
29
+ end
30
+
31
+ # Merge from the hash with only those keys exists
32
+ #
33
+ # @example
34
+ # merge({ k1: 1, k2: 2}, { k1: 11, k3: 13}) # => { k1: 11, k2: 2 }
35
+ def merge(first, second)
36
+ first.merge(second.slice(*first.keys))
37
+ end
38
+
39
+ def run_jar(jar)
40
+ +"java -Djava.awt.headless=true -jar #{jar}"
41
+ end
42
+
43
+ def vendor_path(file = '')
44
+ File.join(__dir__, '../../vendor', file)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LiquidDiagrams
4
+ VERSION = '0.1.0'
5
+ end