liquid-diagrams 0.1.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 (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