liquid-diagrams 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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