liquid-diagrams 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +124 -0
- data/lib/liquid-diagrams.rb +3 -0
- data/lib/liquid_diagrams/basic_block.rb +49 -0
- data/lib/liquid_diagrams/basic_renderer.rb +20 -0
- data/lib/liquid_diagrams/errors.rb +12 -0
- data/lib/liquid_diagrams/renderers/blockdiag_renderer.rb +50 -0
- data/lib/liquid_diagrams/renderers/erd_renderer.rb +36 -0
- data/lib/liquid_diagrams/renderers/graphviz_renderer.rb +33 -0
- data/lib/liquid_diagrams/renderers/mermaid_renderer.rb +34 -0
- data/lib/liquid_diagrams/renderers/nomnoml_renderer.rb +17 -0
- data/lib/liquid_diagrams/renderers/plantuml_renderer.rb +20 -0
- data/lib/liquid_diagrams/renderers/smcat_renderer.rb +31 -0
- data/lib/liquid_diagrams/renderers/svgbob_renderer.rb +28 -0
- data/lib/liquid_diagrams/renderers/syntrax_renderer.rb +28 -0
- data/lib/liquid_diagrams/renderers/vega_renderer.rb +25 -0
- data/lib/liquid_diagrams/renderers/wavedrom_renderer.rb +17 -0
- data/lib/liquid_diagrams/rendering.rb +47 -0
- data/lib/liquid_diagrams/utils.rb +47 -0
- data/lib/liquid_diagrams/version.rb +5 -0
- data/lib/liquid_diagrams.rb +89 -0
- data/spec/liquid_diagrams/basic_block_spec.rb +49 -0
- data/spec/liquid_diagrams/basic_renderer_spec.rb +28 -0
- data/spec/liquid_diagrams/renderers/blockdiag_renderer_spec.rb +43 -0
- data/spec/liquid_diagrams/renderers/erd_renderer_spec.rb +49 -0
- data/spec/liquid_diagrams/renderers/graphviz_renderer_spec.rb +63 -0
- data/spec/liquid_diagrams/renderers/mermaid_renderer_spec.rb +31 -0
- data/spec/liquid_diagrams/renderers/nomnoml_renderer_spec.rb +15 -0
- data/spec/liquid_diagrams/renderers/plantuml_renderer_spec.rb +41 -0
- data/spec/liquid_diagrams/renderers/smcat_renderer_spec.rb +33 -0
- data/spec/liquid_diagrams/renderers/svgbob_renderer_spec.rb +31 -0
- data/spec/liquid_diagrams/renderers/syntrax_renderer_spec.rb +31 -0
- data/spec/liquid_diagrams/renderers/vega_renderer_spec.rb +33 -0
- data/spec/liquid_diagrams/renderers/wavedrom_renderer_spec.rb +15 -0
- data/spec/liquid_diagrams/rendering_spec.rb +127 -0
- data/spec/liquid_diagrams/utils_spec.rb +66 -0
- data/spec/liquid_diagrams_spec.rb +79 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/support/shared_examples.rb +47 -0
- data/vendor/mermaid_puppeteer_config.json +3 -0
- data/vendor/plantuml.1.2020.1.jar +0 -0
- 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,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
|