jekyll-diagrams 0.9.2 → 0.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +32 -20
- data/features/blockdiag.feature +1 -2
- data/features/graphviz.feature +58 -6
- data/features/mermaid.feature +1 -2
- data/features/nomnoml.feature +2 -22
- data/features/plantuml.feature +17 -8
- data/features/smcat.feature +10 -15
- data/features/support/env.rb +11 -5
- data/features/syntrax.feature +1 -2
- data/features/vega.feature +24 -12
- data/features/wavedrom.feature +2 -8
- data/lib/jekyll-diagrams.rb +64 -1
- data/lib/jekyll-diagrams/block.rb +33 -8
- data/lib/jekyll-diagrams/blockdiag.rb +8 -6
- data/lib/jekyll-diagrams/erd.rb +7 -1
- data/lib/jekyll-diagrams/errors.rb +25 -0
- data/lib/jekyll-diagrams/graphviz.rb +2 -1
- data/lib/jekyll-diagrams/mermaid.rb +4 -5
- data/lib/jekyll-diagrams/nomnoml.rb +2 -2
- data/lib/jekyll-diagrams/plantuml.rb +3 -4
- data/lib/jekyll-diagrams/rendering.rb +67 -0
- data/lib/jekyll-diagrams/smcat.rb +2 -2
- data/lib/jekyll-diagrams/vega.rb +3 -1
- data/lib/jekyll-diagrams/version.rb +1 -1
- data/test/block_test.rb +6 -0
- data/test/blockdiag_test.rb +28 -0
- data/test/erd_test.rb +5 -2
- data/test/rendering_test.rb +20 -0
- data/test/svgbob_test.rb +22 -0
- data/test/test_helper.rb +12 -3
- metadata +118 -39
- data/.coveralls.yml +0 -1
- data/.github/workflows/test.yml +0 -83
- data/.gitignore +0 -4
- data/.rubocop.yml +0 -22
- data/.simplecov +0 -5
- data/.travis.yml +0 -50
- data/Dockerfile +0 -53
- data/Gemfile +0 -8
- data/Rakefile +0 -28
- data/features/svgbob.feature +0 -22
- data/jekyll-diagrams.gemspec +0 -31
- data/lib/jekyll-diagrams/util.rb +0 -95
- data/test/util_test.rb +0 -20
data/lib/jekyll-diagrams.rb
CHANGED
@@ -1,6 +1,69 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require 'jekyll'
|
4
|
+
|
5
|
+
module Jekyll
|
6
|
+
module Diagrams
|
7
|
+
class << self
|
8
|
+
# Return configuration of Jekyll Diagrams
|
9
|
+
#
|
10
|
+
# @param context [Liquid::Context, :registers] Parsed context
|
11
|
+
# @return Configuration
|
12
|
+
def configuration(context)
|
13
|
+
site_config = context.registers[:site].config
|
14
|
+
page_config = context.registers[:page]
|
15
|
+
|
16
|
+
site_config.merge(page_config)
|
17
|
+
end
|
18
|
+
|
19
|
+
def config_for(context, name)
|
20
|
+
configuration(context).dig(config_name, name) || {}
|
21
|
+
end
|
22
|
+
|
23
|
+
def error_mode(context)
|
24
|
+
liquid_mode = configuration(context).dig('liquid', 'error_mode')
|
25
|
+
custom_mode = configuration(context).dig(config_name, 'error_mode')
|
26
|
+
|
27
|
+
(custom_mode || liquid_mode || :warn).to_sym
|
28
|
+
end
|
29
|
+
|
30
|
+
# Return file path under vendor path
|
31
|
+
#
|
32
|
+
# @param file [String] If not given, return directory path
|
33
|
+
def vendor_path(file = '')
|
34
|
+
File.join(File.expand_path('../vendor', __dir__), file)
|
35
|
+
end
|
36
|
+
|
37
|
+
# @param jar [String] Jar path to run
|
38
|
+
def run_jar(jar)
|
39
|
+
"java -Djava.awt.headless=true -jar #{jar} "
|
40
|
+
end
|
41
|
+
|
42
|
+
def normalized_attrs(attrs, prefix:, sep: '=')
|
43
|
+
attrs =
|
44
|
+
case attrs
|
45
|
+
when String
|
46
|
+
attrs
|
47
|
+
when Array
|
48
|
+
attrs.join(prefix)
|
49
|
+
when Hash
|
50
|
+
attrs.map { |k, v| "#{k}#{sep}#{v}" }.join(prefix)
|
51
|
+
end
|
52
|
+
|
53
|
+
"#{prefix}#{attrs}"
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def config_name
|
59
|
+
'jekyll-diagrams'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
require_relative 'jekyll-diagrams/errors'
|
66
|
+
require_relative 'jekyll-diagrams/rendering'
|
4
67
|
require_relative 'jekyll-diagrams/block'
|
5
68
|
|
6
69
|
require_relative 'jekyll-diagrams/blockdiag'
|
@@ -3,23 +3,48 @@
|
|
3
3
|
module Jekyll
|
4
4
|
module Diagrams
|
5
5
|
class Block < Liquid::Block
|
6
|
-
include
|
6
|
+
include Rendering
|
7
7
|
|
8
8
|
def render(context)
|
9
|
-
|
10
|
-
|
9
|
+
config = Diagrams.config_for(context, block_name)
|
10
|
+
|
11
|
+
output = render_svg(super.to_s, config)
|
12
|
+
wrap_class(output)
|
13
|
+
rescue StandardError => e
|
14
|
+
error_mode = Diagrams.error_mode(context)
|
15
|
+
|
16
|
+
output = handle_error(e, error_mode)
|
17
|
+
wrap_class(output)
|
11
18
|
end
|
12
19
|
|
13
|
-
|
20
|
+
private
|
21
|
+
|
22
|
+
def render_svg(_code, _config)
|
14
23
|
''
|
15
24
|
end
|
16
25
|
|
17
|
-
def
|
18
|
-
|
26
|
+
def wrap_class(content)
|
27
|
+
<<~CONTENT
|
28
|
+
<div class='jekyll-diagrams diagrams #{block_name}'>
|
29
|
+
#{content}
|
30
|
+
</div>"
|
31
|
+
CONTENT
|
19
32
|
end
|
20
33
|
|
21
|
-
def
|
22
|
-
|
34
|
+
def handle_error(error, mode)
|
35
|
+
topic = 'Jekyll Diagrams:'
|
36
|
+
msg = error.message
|
37
|
+
|
38
|
+
case mode
|
39
|
+
when :lax
|
40
|
+
Jekyll.logger.info topic, msg
|
41
|
+
''
|
42
|
+
when :warn
|
43
|
+
Jekyll.logger.warn topic, msg
|
44
|
+
msg
|
45
|
+
when :strict
|
46
|
+
Jekyll.logger.abort_with topic, msg
|
47
|
+
end
|
23
48
|
end
|
24
49
|
end
|
25
50
|
end
|
@@ -4,6 +4,9 @@ module Jekyll
|
|
4
4
|
module Diagrams
|
5
5
|
class BlockdiagBlock < Block
|
6
6
|
CONFIGURATIONS = %w[config font fontmap size].freeze
|
7
|
+
SWITCHES = {
|
8
|
+
'antialias' => false
|
9
|
+
}.freeze
|
7
10
|
|
8
11
|
def render_svg(code, config)
|
9
12
|
command = build_command(config)
|
@@ -13,13 +16,12 @@ module Jekyll
|
|
13
16
|
end
|
14
17
|
end
|
15
18
|
|
16
|
-
def read_config(context)
|
17
|
-
config_for(context, 'blockdiag').merge(config_for(context, block_name))
|
18
|
-
end
|
19
|
-
|
20
19
|
def build_command(config)
|
21
|
-
command = "#{block_name} -T svg --nodoctype"
|
22
|
-
|
20
|
+
command = +"#{block_name} -T svg --nodoctype"
|
21
|
+
|
22
|
+
SWITCHES.merge(config.slice(*SWITCHES.keys)).each do |switch, value|
|
23
|
+
command << " --#{switch}" if value != false
|
24
|
+
end
|
23
25
|
|
24
26
|
CONFIGURATIONS.each do |conf|
|
25
27
|
command << " --#{conf}=#{config[conf]}" if config.key?(conf)
|
data/lib/jekyll-diagrams/erd.rb
CHANGED
@@ -5,6 +5,9 @@ module Jekyll
|
|
5
5
|
class ErdBlock < Block
|
6
6
|
XML_REGEX = /^<\?xml(([^>]|\n)*>\n?){2}/.freeze
|
7
7
|
CONFIGURATIONS = %w[config edge].freeze
|
8
|
+
SWITCHES = {
|
9
|
+
'dot-entity' => false
|
10
|
+
}.freeze
|
8
11
|
|
9
12
|
def render_svg(code, config)
|
10
13
|
command = build_command(config)
|
@@ -15,7 +18,10 @@ module Jekyll
|
|
15
18
|
|
16
19
|
def build_command(config)
|
17
20
|
command = +'erd --fmt=svg'
|
18
|
-
|
21
|
+
|
22
|
+
SWITCHES.merge(config.slice(*SWITCHES.keys)).each do |switch, value|
|
23
|
+
command << " --#{switch}" if value != false
|
24
|
+
end
|
19
25
|
|
20
26
|
CONFIGURATIONS.each do |conf|
|
21
27
|
command << " --#{conf}=#{config[conf]}" if config.key?(conf)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jekyll
|
4
|
+
module Diagrams
|
5
|
+
module Errors
|
6
|
+
BaseError = Class.new(::StandardError) do
|
7
|
+
def initialize(msg)
|
8
|
+
@msg = msg
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
CommandNotFoundError = Class.new(BaseError) do
|
13
|
+
def message
|
14
|
+
"Command Not Found: #{@msg}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
RenderingFailedError = Class.new(BaseError) do
|
19
|
+
def message
|
20
|
+
"Rendering Failed: #{@msg}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -27,7 +27,8 @@ module Jekyll
|
|
27
27
|
CONFIGRATIONS.each do |prefix, conf|
|
28
28
|
next unless config.key?(conf)
|
29
29
|
|
30
|
-
command << normalized_attrs(config[conf],
|
30
|
+
command << Diagrams.normalized_attrs(config[conf],
|
31
|
+
prefix: " -#{prefix}")
|
31
32
|
end
|
32
33
|
|
33
34
|
command
|
@@ -3,7 +3,8 @@
|
|
3
3
|
module Jekyll
|
4
4
|
module Diagrams
|
5
5
|
class MermaidBlock < Block
|
6
|
-
CONFIGURATIONS = %w[
|
6
|
+
CONFIGURATIONS = %w[theme width height backgroundColor
|
7
|
+
configFile cssFile scale].freeze
|
7
8
|
|
8
9
|
def render_svg(code, config)
|
9
10
|
command = build_command(config)
|
@@ -14,10 +15,8 @@ module Jekyll
|
|
14
15
|
end
|
15
16
|
|
16
17
|
def build_command(config)
|
17
|
-
command = +'mmdc'
|
18
|
-
command << '
|
19
|
-
command << vendor_path('mermaid_puppeteer_config.json')
|
20
|
-
command << ' --transparent' if config.fetch('transparent', false) != false
|
18
|
+
command = +'mmdc --puppeteerConfigFile '
|
19
|
+
command << Diagrams.vendor_path('mermaid_puppeteer_config.json')
|
21
20
|
|
22
21
|
CONFIGURATIONS.each do |conf|
|
23
22
|
command << " --#{conf} #{config[conf]}" if config.key?(conf)
|
@@ -13,10 +13,9 @@ module Jekyll
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def build_command(_config)
|
16
|
-
|
17
|
-
|
18
|
-
options
|
19
|
-
options << vendor_path('plantuml.1.2020.1.jar')
|
16
|
+
jar = Diagrams.vendor_path('plantuml.1.2020.1.jar')
|
17
|
+
|
18
|
+
options = +Diagrams.run_jar(jar)
|
20
19
|
options << ' -tsvg -pipe'
|
21
20
|
end
|
22
21
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'open3'
|
4
|
+
require 'tempfile'
|
5
|
+
require 'tmpdir'
|
6
|
+
|
7
|
+
module Jekyll
|
8
|
+
module Diagrams
|
9
|
+
module Rendering
|
10
|
+
module_function
|
11
|
+
|
12
|
+
# Render SVG with stdin and stdout
|
13
|
+
#
|
14
|
+
# @param command Command to run
|
15
|
+
# @param content Content passed to command
|
16
|
+
# @return The SVG output
|
17
|
+
def render_with_stdin_stdout(command, content)
|
18
|
+
render_with_command(command, :stdout, stdin_data: content)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Render SVG with tempfile
|
22
|
+
#
|
23
|
+
# @param command Command to run
|
24
|
+
# @param content Content passed to command
|
25
|
+
# @param block Result of block will append to command
|
26
|
+
# @return The SVG output
|
27
|
+
def render_with_tempfile(command, content)
|
28
|
+
Dir.mktmpdir('jekyll-diagrams-rendering') do |dir|
|
29
|
+
input = Tempfile.new('input', tmpdir: dir)
|
30
|
+
output = Tempfile.new(%w[output .svg], tmpdir: dir)
|
31
|
+
|
32
|
+
File.write(input.path, content)
|
33
|
+
|
34
|
+
extra = yield input.path, output.path
|
35
|
+
command = "#{command} #{extra}"
|
36
|
+
|
37
|
+
render_with_command(command, output.path)
|
38
|
+
ensure
|
39
|
+
input.close!
|
40
|
+
output.close!
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Render SVG with command
|
45
|
+
#
|
46
|
+
# @param command Command to run
|
47
|
+
# @param output Output path, use :stdout for stdout
|
48
|
+
# @param options Extra options passed to Open3.captrue3
|
49
|
+
# @return The SVG output
|
50
|
+
def render_with_command(command, output = :stdout, **options)
|
51
|
+
begin
|
52
|
+
stdout, stderr, status = Open3.capture3(command, **options)
|
53
|
+
rescue Errno::ENOENT
|
54
|
+
raise Errors::CommandNotFoundError, command.split(' ')[0]
|
55
|
+
end
|
56
|
+
|
57
|
+
unless status.success?
|
58
|
+
raise Errors::RenderingFailedError, <<~MSG
|
59
|
+
#{command}: #{stderr.empty? ? stdout : stderr}
|
60
|
+
MSG
|
61
|
+
end
|
62
|
+
|
63
|
+
output == :stdout ? stdout : File.read(output)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -9,8 +9,8 @@ module Jekyll
|
|
9
9
|
def render_svg(code, config)
|
10
10
|
command = build_command(config)
|
11
11
|
|
12
|
-
svg = render_with_tempfile(command, code
|
13
|
-
"#{input} --output-to
|
12
|
+
svg = render_with_tempfile(command, code) do |input, output|
|
13
|
+
"#{input} --output-to #{output}"
|
14
14
|
end
|
15
15
|
|
16
16
|
svg.sub!(XML_REGEX, '')
|
data/lib/jekyll-diagrams/vega.rb
CHANGED
@@ -6,7 +6,9 @@ module Jekyll
|
|
6
6
|
CONFIGURATIONS = %w[scale].freeze
|
7
7
|
|
8
8
|
def render_svg(code, config)
|
9
|
-
|
9
|
+
if block_name == 'vegalite'
|
10
|
+
code = render_with_stdin_stdout('vl2vg', code)
|
11
|
+
end
|
10
12
|
|
11
13
|
command = build_command(config)
|
12
14
|
|
data/test/block_test.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class BlockdiagTest < Minitest::Test
|
6
|
+
def setup
|
7
|
+
@block = Jekyll::Diagrams::BlockdiagBlock.parse(
|
8
|
+
'blockdiag',
|
9
|
+
'',
|
10
|
+
Liquid::Tokenizer.new('{% endblockdiag %}'),
|
11
|
+
Liquid::ParseContext.new
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_build_command_with_default_config
|
16
|
+
config = {}
|
17
|
+
assert_equal 'blockdiag -T svg --nodoctype', @block.build_command(config)
|
18
|
+
|
19
|
+
config = { 'antialias' => true }
|
20
|
+
assert_match '--antialias', @block.build_command(config)
|
21
|
+
|
22
|
+
config = { 'antialias' => false }
|
23
|
+
refute_match '--antialias', @block.build_command(config)
|
24
|
+
|
25
|
+
config = { 'size' => 3 }
|
26
|
+
assert_match '--size=3', @block.build_command(config)
|
27
|
+
end
|
28
|
+
end
|
data/test/erd_test.rb
CHANGED
@@ -4,8 +4,11 @@ require 'test_helper'
|
|
4
4
|
|
5
5
|
class ErdTest < Minitest::Test
|
6
6
|
def setup
|
7
|
-
@block = Jekyll::Diagrams::ErdBlock.
|
8
|
-
|
7
|
+
@block = Jekyll::Diagrams::ErdBlock.parse(
|
8
|
+
'erd',
|
9
|
+
'',
|
10
|
+
Liquid::Tokenizer.new('test {% enderd %}'),
|
11
|
+
Liquid::ParseContext.new
|
9
12
|
)
|
10
13
|
end
|
11
14
|
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class RenderingTest < Minitest::Test
|
6
|
+
include Jekyll::Diagrams::Errors
|
7
|
+
include Jekyll::Diagrams::Rendering
|
8
|
+
|
9
|
+
def test_raise_command_not_found_error
|
10
|
+
assert_raises CommandNotFoundError do
|
11
|
+
render_with_command('not_exist_command')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_raise_rendering_failed_error
|
16
|
+
assert_raises RenderingFailedError do
|
17
|
+
render_with_command('/bin/bash -c "exit 1"')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|