liquid-diagrams 0.3.0 → 0.4.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 (63) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +15 -16
  3. data/features/diagrams/bitfield.feature +48 -0
  4. data/features/diagrams/blockdiag.feature +19 -0
  5. data/features/diagrams/erd.feature +19 -0
  6. data/features/diagrams/graphviz.feature +19 -0
  7. data/features/diagrams/mermaid.feature +20 -0
  8. data/features/diagrams/netlistsvg.feature +27 -0
  9. data/features/diagrams/nomnoml.feature +19 -0
  10. data/features/diagrams/plantuml.feature +17 -0
  11. data/features/diagrams/smcat.feature +23 -0
  12. data/features/diagrams/svgbob.feature +19 -0
  13. data/features/diagrams/syntrax.feature +20 -0
  14. data/features/diagrams/vega.feature +23 -0
  15. data/features/diagrams/vegalite.feature +23 -0
  16. data/features/diagrams/wavedrom.feature +24 -0
  17. data/features/step_definitions/diagrams.rb +21 -0
  18. data/features/support/env.rb +15 -0
  19. data/lib/liquid_diagrams.rb +9 -17
  20. data/lib/liquid_diagrams/basic_block.rb +12 -42
  21. data/lib/liquid_diagrams/basic_renderer.rb +43 -1
  22. data/lib/liquid_diagrams/blocks.rb +14 -0
  23. data/lib/liquid_diagrams/renderers.rb +10 -0
  24. data/lib/liquid_diagrams/renderers/bitfield_renderer.rb +9 -13
  25. data/lib/liquid_diagrams/renderers/blockdiag_renderer.rb +7 -15
  26. data/lib/liquid_diagrams/renderers/erd_renderer.rb +7 -15
  27. data/lib/liquid_diagrams/renderers/graphviz_renderer.rb +10 -10
  28. data/lib/liquid_diagrams/renderers/mermaid_renderer.rb +2 -9
  29. data/lib/liquid_diagrams/renderers/netlistsvg_renderer.rb +13 -0
  30. data/lib/liquid_diagrams/renderers/nomnoml_renderer.rb +0 -4
  31. data/lib/liquid_diagrams/renderers/plantuml_renderer.rb +5 -5
  32. data/lib/liquid_diagrams/renderers/smcat_renderer.rb +0 -10
  33. data/lib/liquid_diagrams/renderers/svgbob_renderer.rb +0 -10
  34. data/lib/liquid_diagrams/renderers/syntrax_renderer.rb +0 -10
  35. data/lib/liquid_diagrams/renderers/vega_renderer.rb +9 -23
  36. data/lib/liquid_diagrams/renderers/vegalite_renderer.rb +19 -0
  37. data/lib/liquid_diagrams/renderers/wavedrom_renderer.rb +1 -1
  38. data/lib/liquid_diagrams/rendering.rb +8 -6
  39. data/lib/liquid_diagrams/utils.rb +21 -14
  40. data/lib/liquid_diagrams/version.rb +1 -1
  41. data/spec/liquid_diagrams/basic_block_spec.rb +25 -62
  42. data/spec/liquid_diagrams/basic_renderer_spec.rb +27 -5
  43. data/spec/liquid_diagrams/blocks_spec.rb +0 -0
  44. data/spec/liquid_diagrams/renderers/bitfield_renderer_spec.rb +1 -19
  45. data/spec/liquid_diagrams/renderers/blockdiag_renderer_spec.rb +3 -31
  46. data/spec/liquid_diagrams/renderers/erd_renderer_spec.rb +3 -37
  47. data/spec/liquid_diagrams/renderers/graphviz_renderer_spec.rb +11 -21
  48. data/spec/liquid_diagrams/renderers/mermaid_renderer_spec.rb +3 -19
  49. data/spec/liquid_diagrams/renderers/netlistsvg_renderer_spec.rb +9 -0
  50. data/spec/liquid_diagrams/renderers/nomnoml_renderer_spec.rb +1 -7
  51. data/spec/liquid_diagrams/renderers/plantuml_renderer_spec.rb +4 -14
  52. data/spec/liquid_diagrams/renderers/smcat_renderer_spec.rb +1 -25
  53. data/spec/liquid_diagrams/renderers/svgbob_renderer_spec.rb +1 -23
  54. data/spec/liquid_diagrams/renderers/syntrax_renderer_spec.rb +1 -23
  55. data/spec/liquid_diagrams/renderers/vega_renderer_spec.rb +3 -21
  56. data/spec/liquid_diagrams/renderers/vegalite_renderer_spec.rb +15 -0
  57. data/spec/liquid_diagrams/renderers/wavedrom_renderer_spec.rb +3 -3
  58. data/spec/liquid_diagrams/utils_spec.rb +20 -8
  59. data/spec/liquid_diagrams_spec.rb +52 -0
  60. data/spec/spec_helper.rb +5 -0
  61. data/spec/support/shared_examples.rb +8 -19
  62. data/vendor/{mermaid_puppeteer_config.json → puppeteer.json} +0 -0
  63. metadata +70 -19
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+
5
+ require 'pry-byebug'
6
+
7
+ require 'liquid_diagrams'
8
+
9
+ LiquidDiagrams.register_diagrams(LiquidDiagrams.diagrams)
10
+
11
+ def render_liquid(content, options = {})
12
+ template = Liquid::Template.parse(content, liquid_diagrams: options)
13
+
14
+ template.render
15
+ end
@@ -11,28 +11,20 @@ require_relative 'liquid_diagrams/rendering'
11
11
  require_relative 'liquid_diagrams/basic_renderer'
12
12
  require_relative 'liquid_diagrams/basic_block'
13
13
 
14
- module LiquidDiagrams
15
- # @note All renderers should be defined under this module
16
- module Renderers
17
- pattern = File.join(__dir__, 'liquid_diagrams/renderers/*_renderer.rb')
18
-
19
- Dir[pattern].sort.each { |renderer| require renderer }
20
- end
14
+ require_relative 'liquid_diagrams/renderers'
15
+ require_relative 'liquid_diagrams/blocks'
21
16
 
22
- # @note All blocks are automaticly define under this module if not exist
23
- module Blocks
24
- Renderers.constants.grep(/Renderer$/).each do |renderer|
25
- block_name = "#{renderer.to_s.chomp('Renderer')}Block"
17
+ module LiquidDiagrams
18
+ OPTIONS_KEY = :liquid_diagrams
26
19
 
27
- next if Blocks.const_defined?(block_name)
20
+ class << self
21
+ # Return configuration of diagram
22
+ def configuration(options, key: nil, default: {})
23
+ config = options[OPTIONS_KEY.to_sym] || options[OPTIONS_KEY.to_s] || {}
28
24
 
29
- Blocks.const_set(block_name, Class.new(BasicBlock))
25
+ key ? (config.dig(key.to_sym) || config.dig(key.to_s) || default) : config
30
26
  end
31
- end
32
27
 
33
- OPTIONS_KEY = :liquid_diagrams
34
-
35
- class << self
36
28
  # Return all diagrams defined in {Renderers}
37
29
  #
38
30
  # @return [Array<Symbol>]
@@ -1,70 +1,40 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LiquidDiagrams
4
- # @abstract Subclass and override {#render_with_rescue} or
5
- # {#render_without_rescue} to implement
4
+ # @abstract Subclass and override {#render_content} to implement
6
5
  class BasicBlock < ::Liquid::Block
7
6
  # Return the renderer class matching the block
8
- #
9
- # @return [BasicRenderer]
10
- #
11
- # @raise [NameError] if renderer class not found
12
7
  def self.renderer
13
8
  @renderer ||= Renderers.const_get(
14
9
  name.split('::').last.gsub(/Block$/, 'Renderer')
15
10
  )
16
11
  end
17
12
 
18
- # @note Do not overwite this method, overwrite {#render_with_rescue} or
19
- # {#render_without_recue} instead
13
+ # @note Do not override this method, override {#render_content} instead
20
14
  def render(context)
21
- @content = super.to_s
22
15
  @context = context
16
+ @content = super.to_s
17
+ @config = read_config
23
18
 
24
- render_with_rescue
19
+ render_content
25
20
  end
26
21
 
27
- # Render diagram with error rescued
28
- #
29
- # @return [String]
30
- def render_with_rescue
31
- render_without_rescue
22
+ def render_content
23
+ self.class.renderer.render(@content, @config)
32
24
  rescue Errors::BasicError => error
33
25
  handle_error(error)
34
26
  end
35
27
 
36
- # Render diagram without error rescued
37
- #
38
- # @return [String]
39
- #
40
- # @raise [NameError] @see {.renderer}
41
- # @raise [Errors::BasicError] if rendering failed
42
- def render_without_rescue
43
- self.class.renderer.render(@content, config)
44
- end
45
-
46
- # Default error handler
47
28
  def handle_error(error)
48
29
  error
49
30
  end
50
31
 
51
- # Read configurations
52
- #
53
- # @return [Hash]
54
- def config
55
- template_options.merge(inline_options)
56
- end
57
-
58
- # Read block options from parse context
59
- def template_options
60
- opts = parse_context[OPTIONS_KEY] || parse_context[OPTIONS_KEY.to_s] || {}
61
-
62
- opts.fetch(block_name.to_sym) { opts.fetch(block_name, {}) }
63
- end
32
+ # @api private
33
+ def read_config
34
+ options = LiquidDiagrams.configuration(parse_context, key: block_name)
35
+ inline_options = Utils.parse_inline_options(@markup.strip)
64
36
 
65
- # Read inline options from markup
66
- def inline_options
67
- Utils.parse_inline_options(@markup.strip)
37
+ options.merge(inline_options)
68
38
  end
69
39
  end
70
40
  end
@@ -1,8 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LiquidDiagrams
4
- # @abstract Subclass and override {#render} to implement
4
+ # @abstract Subclass and override {#render} to implement.
5
5
  class BasicRenderer
6
+ include Rendering
7
+
8
+ # Configuration key for argument with boolean value.
9
+ FLAGS = [].freeze
10
+
11
+ # Prefix for {FLAGS}
12
+ FLAGS_PREFIX = '--'
13
+
14
+ # Configuration key for argument with key-value pairs.
15
+ OPTIONS = [].freeze
16
+
17
+ # Separator for key and value of {OPTIONS}.
18
+ OPTIONS_SEPARATOR = ' '
19
+
20
+ # Prefix for {OPTIONS}
21
+ OPTIONS_PREFIX = '--'
22
+
6
23
  def self.render(content, options = {})
7
24
  new(content, options).render
8
25
  end
@@ -12,8 +29,33 @@ module LiquidDiagrams
12
29
  @config = options
13
30
  end
14
31
 
32
+ # Default render method with {Errors::NotImplementedError} raised
33
+ #
34
+ # @important You should overrite this method in your own renderer class
15
35
  def render
16
36
  raise Errors::NotImplementedError
17
37
  end
38
+
39
+ def build_command
40
+ "#{executable} #{arguments}".strip
41
+ end
42
+
43
+ def executable
44
+ self.class.name.split('::').last.sub(/Renderer$/, '').downcase
45
+ end
46
+
47
+ def arguments
48
+ flags = Utils.build_flags(
49
+ @config, self.class.const_get(:FLAGS),
50
+ prefix: self.class.const_get(:FLAGS_PREFIX)
51
+ )
52
+ options = Utils.build_options(
53
+ @config, self.class.const_get(:OPTIONS),
54
+ prefix: self.class.const_get(:OPTIONS_PREFIX),
55
+ sep: self.class.const_get(:OPTIONS_SEPARATOR)
56
+ )
57
+
58
+ "#{flags} #{options}".strip
59
+ end
18
60
  end
19
61
  end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LiquidDiagrams
4
+ # @note All blocks are automaticly define under this module if not defined
5
+ module Blocks
6
+ Renderers.constants.grep(/Renderer$/).each do |renderer|
7
+ block_name = "#{renderer.to_s.chomp('Renderer')}Block"
8
+
9
+ next if Blocks.const_defined?(block_name)
10
+
11
+ Blocks.const_set(block_name, Class.new(BasicBlock))
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LiquidDiagrams
4
+ # @note All renderers should be defined under this module
5
+ module Renderers
6
+ pattern = File.join(__dir__, 'renderers/*_renderer.rb')
7
+
8
+ Dir[pattern].sort.each { |renderer| require renderer }
9
+ end
10
+ end
@@ -3,11 +3,17 @@
3
3
  module LiquidDiagrams
4
4
  module Renderers
5
5
  class BitfieldRenderer < BasicRenderer
6
+ FLAGS = %w[
7
+ compact
8
+ hflip
9
+ vflip
10
+ ].freeze
11
+
6
12
  OPTIONS = %w[
7
- vspace
8
- hspace
9
- lanes
10
13
  bits
14
+ lanes
15
+ hspace
16
+ vspace
11
17
  fontsize
12
18
  fontfamily
13
19
  fontweight
@@ -18,16 +24,6 @@ module LiquidDiagrams
18
24
  "--input #{input} > #{output}"
19
25
  end
20
26
  end
21
-
22
- def build_command
23
- command = +'bitfield'
24
-
25
- @config.slice(*OPTIONS).each do |opt, value|
26
- command << " --#{opt} #{value}"
27
- end
28
-
29
- command
30
- end
31
27
  end
32
28
  end
33
29
  end
@@ -4,6 +4,10 @@ module LiquidDiagrams
4
4
  module Renderers
5
5
  %i[Blockdiag Seqdiag Actdiag Nwdiag Rackdiag Packetdiag].each do |diagram|
6
6
  renderer = Class.new(BasicRenderer) do
7
+ const_set :FLAGS, %w[
8
+ antialias
9
+ ].freeze
10
+
7
11
  const_set :OPTIONS, %w[
8
12
  config
9
13
  font
@@ -11,9 +15,7 @@ module LiquidDiagrams
11
15
  size
12
16
  ].freeze
13
17
 
14
- const_set :SWITCHES, {
15
- 'antialias' => false
16
- }.freeze
18
+ const_set :OPTIONS_SEPARATOR, '='
17
19
 
18
20
  def render
19
21
  Rendering.render_with_tempfile(build_command, @content) do |input, output|
@@ -21,18 +23,8 @@ module LiquidDiagrams
21
23
  end
22
24
  end
23
25
 
24
- define_method :build_command do
25
- command = +"#{diagram.downcase} -T svg --nodoctype"
26
-
27
- @config.slice(*self.class.const_get(:OPTIONS)).each do |opt, value|
28
- command << " --#{opt}=#{value}"
29
- end
30
-
31
- Utils.merge(self.class.const_get(:SWITCHES), @config).each do |swc, value|
32
- command << " --#{swc}" if value
33
- end
34
-
35
- command
26
+ define_method :executable do
27
+ "#{diagram.downcase} -Tsvg --nodoctype"
36
28
  end
37
29
  end
38
30
 
@@ -3,14 +3,16 @@
3
3
  module LiquidDiagrams
4
4
  module Renderers
5
5
  class ErdRenderer < BasicRenderer
6
+ FLAGS = %w[
7
+ dot-entity
8
+ ].freeze
9
+
6
10
  OPTIONS = %w[
7
11
  config
8
12
  edge
9
13
  ].freeze
10
14
 
11
- SWITCHES = {
12
- 'dot-entity' => false
13
- }.freeze
15
+ OPTIONS_SEPARATOR = '='
14
16
 
15
17
  XML_REGEX = /^<\?xml(([^>]|\n)*>\n?){2}/.freeze
16
18
 
@@ -18,18 +20,8 @@ module LiquidDiagrams
18
20
  Rendering.render_with_stdin_stdout(build_command, @content).sub(XML_REGEX, '')
19
21
  end
20
22
 
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
23
+ def executable
24
+ 'erd --fmt=svg'
33
25
  end
34
26
  end
35
27
  end
@@ -3,7 +3,7 @@
3
3
  module LiquidDiagrams
4
4
  module Renderers
5
5
  class GraphvizRenderer < BasicRenderer
6
- MAPPERS = {
6
+ CONFIG_MAPPERS = {
7
7
  'layout' => 'K',
8
8
  'graph_attributes' => 'G',
9
9
  'node_attributes' => 'N',
@@ -13,20 +13,20 @@ module LiquidDiagrams
13
13
  XML_REGEX = /^<\?xml(([^>]|\n)*>\n?){2}/.freeze
14
14
 
15
15
  def render
16
- output = Rendering.render_with_stdin_stdout(build_command, @content)
17
- output.dup.force_encoding('utf-8').sub(XML_REGEX, '')
16
+ Rendering.render_with_stdin_stdout(build_command, @content)
17
+ .encode('utf-8').sub(XML_REGEX, '')
18
18
  end
19
19
 
20
- def build_command
21
- command = +'dot -Tsvg'
20
+ def executable
21
+ 'dot -Tsvg'
22
+ end
22
23
 
23
- @config.slice(*MAPPERS.keys).each do |opt, attrs|
24
- command << Utils.join(attrs, with: " -#{MAPPERS[opt]}") do |attr|
24
+ def arguments
25
+ @config.slice(*CONFIG_MAPPERS.keys).map do |opt, attrs|
26
+ Utils.join(attrs, with: " -#{CONFIG_MAPPERS[opt]}") do |attr|
25
27
  Array(attr).join('=')
26
28
  end
27
- end
28
-
29
- command
29
+ end.join(' ')
30
30
  end
31
31
  end
32
32
  end
@@ -19,15 +19,8 @@ module LiquidDiagrams
19
19
  end
20
20
  end
21
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
22
+ def executable
23
+ "mmdc --puppeteerConfigFile #{Utils.vendor_path('puppeteer.json')}"
31
24
  end
32
25
  end
33
26
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LiquidDiagrams
4
+ module Renderers
5
+ class NetlistsvgRenderer < BasicRenderer
6
+ def render
7
+ Rendering.render_with_tempfile(build_command, @content) do |input, output|
8
+ "#{input} -o #{output}"
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -8,10 +8,6 @@ module LiquidDiagrams
8
8
  "#{input} #{output}"
9
9
  end
10
10
  end
11
-
12
- def build_command
13
- 'nomnoml'
14
- end
15
11
  end
16
12
  end
17
13
  end
@@ -6,14 +6,14 @@ module LiquidDiagrams
6
6
  XML_REGEX = /^<\?xml([^>]|\n)*>\n?/.freeze
7
7
 
8
8
  def render
9
- Rendering.render_with_stdin_stdout(build_command, @content).sub(XML_REGEX, '')
9
+ Rendering.render_with_stdin_stdout(build_command, @content)
10
+ .sub(XML_REGEX, '')
10
11
  end
11
12
 
12
- def build_command
13
- jar = Utils.vendor_path('plantuml.1.2020.1.jar')
13
+ def executable
14
+ jar_path = Utils.vendor_path('plantuml.1.2020.1.jar')
14
15
 
15
- options = +Utils.run_jar(jar)
16
- options << ' -tsvg -pipe'
16
+ "#{Utils.run_jar(jar_path)} -tsvg -pipe"
17
17
  end
18
18
  end
19
19
  end