victor-cli 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fc2b1c5e3ce6627c982daf91c5ecb7c8427f61064f5df3474619ab4eb1e5f220
4
- data.tar.gz: 04c775439539bb96ddb866354d7c8f3925ade9ddb768cb6b9e23f1cae22a017f
3
+ metadata.gz: 147bb0bcc1f9d770e5470631198215ef12253443c9ffd3d6df79bd6f70f283cf
4
+ data.tar.gz: 3680d1619af8e412b8fc967f1e8792ca725b220703b785dd953299d56d68a2a5
5
5
  SHA512:
6
- metadata.gz: 2453dcea1067196ae6e71ba9ef1c0c509ccc45c2c9ea109632612892a1b115fba64303b43aff65aa590bc75f4ea1a5ba3b8e91d3516a49478750492b2f7b104c
7
- data.tar.gz: d5099606414fe52ff0e27c5da5b411751c38c47c8d98ac5968077b9895158f1de881030a7b00b5e405565618a233aac1a51f728ac201aaa0f4682eeb96be8d2c
6
+ metadata.gz: 1ff97918800fe9c9105bec117a6aa3b661167fc862e6d7a5b9fde740a5d3fbaa35bbefdb2646bcf8168fdb7e27b589f8a54203b3723cd5ed633e2837a08247f5
7
+ data.tar.gz: 66d83bf9127c23bcbb2d7e662e40091f87c25b874c3997005977a446c85fcea3de96a5d826282742b2dad1ff9a9628545f0458ecf5d60baf50c691f2a184ee7b
@@ -1,11 +1,12 @@
1
1
  require 'victor'
2
2
  require 'requires'
3
3
  requires 'cli/refinements'
4
- require_relative 'cli/parser'
5
- require_relative 'cli/svg_source'
6
4
  require_relative 'cli/ruby_source'
5
+ require_relative 'cli/css_data'
7
6
  require_relative 'cli/command_line'
8
- require_relative 'cli/xml_node'
9
- require_relative 'cli/xml_text'
7
+ require_relative 'cli/svg_node'
10
8
 
11
- require 'byebug' if ENV['BYEBUG']
9
+ if ENV['BYEBUG']
10
+ require 'byebug'
11
+ require 'lp'
12
+ end
@@ -18,10 +18,13 @@ module Victor
18
18
  example "victor convert example.svg example.rb"
19
19
 
20
20
  def run
21
- svg_data = File.read(args["SVG_FILE"])
22
- svg_source = SVGSource.new svg_data, template: args['--template']
21
+ svg_file = args["SVG_FILE"]
22
+ template = args['--template']
23
+ svg_node = SVGNode.load_file svg_file, layout: template
23
24
 
24
- code = svg_source.ruby_code
25
+ validate_template template if template
26
+
27
+ code = svg_node.render
25
28
  ruby_file = args["RUBY_FILE"]
26
29
 
27
30
  if ruby_file
@@ -31,6 +34,13 @@ module Victor
31
34
  puts code
32
35
  end
33
36
  end
37
+
38
+ def validate_template(template)
39
+ allowed = %w[cli dsl standalone]
40
+ unless allowed.include? template
41
+ raise "Template not found #{template}\nAvailable templates: #{allowed.join ', '}"
42
+ end
43
+ end
34
44
  end
35
45
  end
36
46
  end
@@ -0,0 +1,27 @@
1
+ require "css_parser"
2
+
3
+ module Victor
4
+ module CLI
5
+ class CSSData
6
+ attr_reader :css_string
7
+
8
+ def initialize(css_string)
9
+ @css_string = css_string
10
+ end
11
+
12
+ def to_h
13
+ parser.load_string! css_string
14
+ parser.to_h['all']
15
+ end
16
+
17
+ private
18
+
19
+ def parser
20
+ @parser ||= CssParser::Parser.new
21
+ end
22
+
23
+ end
24
+ end
25
+ end
26
+
27
+
@@ -0,0 +1,46 @@
1
+ module Victor
2
+ module CLI
3
+ module Rendering
4
+ refine Hash do
5
+ def render
6
+ # TODO: Reduce cognitive complexity
7
+ map do |key, value|
8
+ key = key.to_key if key.is_a? String
9
+
10
+ if key == "style"
11
+ value = "{ #{value.style_to_hash.render} }"
12
+ elsif value.is_a? String
13
+ value = value.to_value
14
+ end
15
+
16
+ "#{key}: #{value}"
17
+ end.join ", "
18
+ end
19
+
20
+ end
21
+
22
+ refine String do
23
+ def to_key
24
+ gsub('-', '_').to_sym.inspect[1..-1]
25
+ end
26
+
27
+ def to_value
28
+ if to_f.to_s == self or to_i.to_s == self
29
+ self
30
+ else
31
+ %Q["#{self}"]
32
+ end
33
+ end
34
+
35
+ # Transforms the valus of a style attribute to a hash
36
+ # Example: "color: black; top: 10" => { color: black, top: 10 }
37
+ def style_to_hash
38
+ parser = CssParser::Parser.new
39
+ parser.load_string! "victor { #{self} }"
40
+ parser.to_h["all"]["victor"]
41
+ end
42
+
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,141 @@
1
+ require 'nokogiri'
2
+ require 'erb'
3
+ require 'rufo'
4
+
5
+ module Victor
6
+ module CLI
7
+ class SVGNode
8
+ using Rendering
9
+ attr_reader :node, :layout
10
+
11
+ # Returns a new instance from an SVG file
12
+ def self.load_file(path, layout: nil)
13
+ load File.read(path), layout: layout
14
+ end
15
+
16
+ # Returns a new instance from raw SVG string
17
+ def self.load(svg_string, layout: nil)
18
+ doc = Nokogiri::XML svg_string
19
+ root = doc.children.last
20
+ new root, layout: layout
21
+ end
22
+
23
+ # Initializes with a Nokogiri XML node
24
+ def initialize(node, layout: nil)
25
+ @node = node
26
+ @layout = layout || :cli
27
+ end
28
+
29
+ # Returns formatted Ruby code
30
+ def render
31
+ Rufo::Formatter.format ruby_code
32
+ rescue Rufo::SyntaxError => e
33
+ raise ruby_code
34
+ end
35
+
36
+ def inspect
37
+ "#<#{self.class} name=#{name}, type=#{type}>"
38
+ end
39
+
40
+ # Returns the tag name
41
+ def name
42
+ node.name
43
+ end
44
+
45
+ # Returns one of our internal types (symbol)
46
+ def type
47
+ @type ||= type!
48
+ end
49
+
50
+ # Returns a hash of attributes
51
+ def attributes
52
+ @attributes ||= attributes!
53
+ end
54
+
55
+ # Returns the content (body) of the lement
56
+ def content
57
+ @content ||= content!
58
+ end
59
+
60
+ # Returns an array of children elements (SVGNode)
61
+ def children
62
+ @children ||= children!
63
+ end
64
+
65
+ # Returns the ruby code, unformatted
66
+ def ruby_code
67
+ erb erb_template
68
+ end
69
+
70
+ private
71
+
72
+ # Returns true if the element should be ignored
73
+ def rejected?
74
+ (node.text? and node.text.strip.empty?) or type == :junk
75
+ end
76
+
77
+ # Renders ERB code
78
+ def erb(code)
79
+ ERB.new(code, nil, "%-").result(binding)
80
+ end
81
+
82
+ # Returns the content of the appropriate ERB tempalte, based on type
83
+ def erb_template
84
+ @erb_template ||= File.read(erb_template_file)
85
+ end
86
+
87
+ # Returns the path to the appropriate ERB template, based on type
88
+ def erb_template_file
89
+ file = type == :root ? "root_#{layout}" : type
90
+ path = File.expand_path "templates/nodes/#{file}.erb", __dir__
91
+ end
92
+
93
+ # Returns the internal element type
94
+ def type!
95
+ if node.text?
96
+ :text
97
+ elsif node.comment?
98
+ :junk
99
+ elsif node.name == 'style'
100
+ :css
101
+ elsif node.name == 'svg'
102
+ :root
103
+ else
104
+ :element
105
+ end
106
+ end
107
+
108
+ # Returns a filtered list of SVGNode children
109
+ def children!
110
+ node.children.map do |child|
111
+ SVGNode.new child
112
+ end.reject(&:rejected?)
113
+ end
114
+
115
+ # Returns a hash of attributes
116
+ def attributes!
117
+ node.attribute_nodes.map do |attr|
118
+ name = attr.name
119
+ value = attr.value
120
+ key = attr.respond_to?(:prefix) ? "#{attr.prefix}:#{name}" : name
121
+
122
+ [key, value]
123
+ end.to_h
124
+ end
125
+
126
+ def content!
127
+ if type == :css
128
+ CSSData.new(node.content).to_h
129
+ elsif node.content.is_a? String
130
+ node.content.strip
131
+ else
132
+ # TODO: do we need this?
133
+ # :nocov:
134
+ node.content
135
+ # :nocov:
136
+ end
137
+ end
138
+
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,7 @@
1
+ <%= "# :css" if ENV['DEBUG'] -%>
2
+ <%- content.each do |selector, declarations| %>
3
+ css[<%= selector.inspect %>] = {
4
+ <%- declarations.each do |key, value| -%>
5
+ <%= key.to_key %>: <%= value.to_value %>,
6
+ <%- end -%>}
7
+ <%- end -%>
@@ -0,0 +1,18 @@
1
+ <%= "# :element" if ENV['DEBUG'] -%>
2
+ <%- if children.any? -%>
3
+ <%- if children.count == 1 and children.first.node.text? -%>
4
+ <%- if attributes.any? -%>
5
+ <%= name %> "<%= content %>", <%= attributes.render %>
6
+ <%- else -%>
7
+ <%= name %> "<%= content %>"
8
+ <%- end -%>
9
+ <%- else -%>
10
+ <%= name %> <%= attributes.render %> do
11
+ <%- children.each do |child| -%>
12
+ <%= child.render %>
13
+ <%- end -%>
14
+ end
15
+ <%- end -%>
16
+ <%- else -%>
17
+ <%= name %> <%= attributes.render %>
18
+ <%- end -%>
@@ -0,0 +1,12 @@
1
+ <%= "# :root" if ENV['DEBUG'] -%>
2
+ # Render this template by running 'victor render FILE'
3
+
4
+ <%- if attributes.any? -%>
5
+ setup <%= attributes.render %>
6
+ <%- end -%>
7
+
8
+ build do
9
+ <%- children.each do |child| -%>
10
+ <%= child.render %>
11
+ <%- end -%>
12
+ end
@@ -0,0 +1,17 @@
1
+ <%= "# :root" if ENV['DEBUG'] -%>
2
+ # Render this template by running 'ruby FILE' or 'victor render FILE'
3
+
4
+ require 'victor/script'
5
+
6
+ <%- if attributes.any? -%>
7
+ setup <%= attributes.render %>
8
+ <%- end -%>
9
+
10
+ build do
11
+ <%- children.each do |child| -%>
12
+ <%= child.render %>
13
+ <%- end -%>
14
+ end
15
+
16
+ puts render
17
+ save 'output'
@@ -0,0 +1,14 @@
1
+ <%= "# :root" if ENV['DEBUG'] -%>
2
+ # Render this template by running 'ruby FILE' or 'victor render FILE'
3
+
4
+ require "victor"
5
+
6
+ svg = Victor::SVG.new <%= attributes.render %>
7
+
8
+ svg.build do
9
+ <%- children.each do |child| -%>
10
+ <%= child.render %>
11
+ <%- end -%>
12
+ end
13
+
14
+ svg.save "result"
@@ -0,0 +1,2 @@
1
+ <%= "# :text" if ENV['DEBUG'] -%>
2
+ _ "<%= content %>"
@@ -1,5 +1,5 @@
1
1
  module Victor
2
2
  module CLI
3
- VERSION = "0.3.0"
3
+ VERSION = "0.3.1"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: victor-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Danny Ben Shitrit
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-05-03 00:00:00.000000000 Z
12
+ date: 2020-05-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: filewatcher
@@ -95,6 +95,20 @@ dependencies:
95
95
  - - "~>"
96
96
  - !ruby/object:Gem::Version
97
97
  version: '0.7'
98
+ - !ruby/object:Gem::Dependency
99
+ name: css_parser
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: '1.7'
105
+ type: :runtime
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: '1.7'
98
112
  - !ruby/object:Gem::Dependency
99
113
  name: mister_bin
100
114
  requirement: !ruby/object:Gem::Requirement
@@ -138,19 +152,20 @@ files:
138
152
  - lib/victor/cli/commands/convert.rb
139
153
  - lib/victor/cli/commands/init.rb
140
154
  - lib/victor/cli/commands/render.rb
141
- - lib/victor/cli/parser.rb
142
- - lib/victor/cli/refinements/stirng_refinements.rb
155
+ - lib/victor/cli/css_data.rb
156
+ - lib/victor/cli/refinements/rendering.rb
143
157
  - lib/victor/cli/ruby_source.rb
144
- - lib/victor/cli/svg_source.rb
145
- - lib/victor/cli/templates/import/cli.rb
146
- - lib/victor/cli/templates/import/dsl.rb
147
- - lib/victor/cli/templates/import/standalone.rb
158
+ - lib/victor/cli/svg_node.rb
148
159
  - lib/victor/cli/templates/init/cli.rb
149
160
  - lib/victor/cli/templates/init/dsl.rb
150
161
  - lib/victor/cli/templates/init/standalone.rb
162
+ - lib/victor/cli/templates/nodes/css.erb
163
+ - lib/victor/cli/templates/nodes/element.erb
164
+ - lib/victor/cli/templates/nodes/root_cli.erb
165
+ - lib/victor/cli/templates/nodes/root_dsl.erb
166
+ - lib/victor/cli/templates/nodes/root_standalone.erb
167
+ - lib/victor/cli/templates/nodes/text.erb
151
168
  - lib/victor/cli/version.rb
152
- - lib/victor/cli/xml_node.rb
153
- - lib/victor/cli/xml_text.rb
154
169
  homepage: https://github.com/dannyben/victor-cli
155
170
  licenses:
156
171
  - MIT
@@ -1,61 +0,0 @@
1
- require "nokogiri"
2
-
3
- module Victor
4
- module CLI
5
- class Parser
6
- attr_reader :raw_svg
7
-
8
- def initialize(raw_svg)
9
- @raw_svg = raw_svg
10
- end
11
-
12
- def parse
13
- parse_node svg_root
14
- end
15
-
16
- private
17
-
18
- def parse_node(node)
19
- case node
20
- when Nokogiri::XML::Comment
21
- nil
22
- when Nokogiri::XML::Text
23
- parse_text node
24
- else
25
- parse_normal_node node
26
- end
27
- end
28
-
29
- def parse_text(node)
30
- text_node = XMLText.new(node.text)
31
- return text_node if text_node.text.length > 0
32
- end
33
-
34
- def parse_normal_node(node)
35
- XMLNode.new(
36
- node.name,
37
- node_attrs(node),
38
- node.children.map(&method(:parse_node)).compact,
39
- )
40
- end
41
-
42
- def node_attrs(node)
43
- node.attributes.values.reduce({}) do |acc, attr|
44
- name = attr.name
45
- value = attr.value
46
- key = attr.respond_to?(:prefix) ? "#{attr.prefix}:#{name}" : name
47
- acc[key] = value
48
- acc
49
- end
50
- end
51
-
52
- def xml_doc
53
- Nokogiri::XML raw_svg
54
- end
55
-
56
- def svg_root
57
- xml_doc.children.last
58
- end
59
- end
60
- end
61
- end
@@ -1,19 +0,0 @@
1
- module Victor
2
- module CLI
3
- module Refinements
4
- refine String do
5
- def format_as_key
6
- gsub('-', '_')
7
- end
8
-
9
- def format_as_value
10
- if to_f.to_s == self or to_i.to_s == self
11
- self
12
- else
13
- %Q["#{self}"]
14
- end
15
- end
16
- end
17
- end
18
- end
19
- end
@@ -1,105 +0,0 @@
1
- require "rufo"
2
-
3
- module Victor
4
- module CLI
5
- class SVGSource
6
- using Refinements
7
- attr_reader :svg_tree, :template
8
-
9
- def initialize(svg_tree, template: nil)
10
- @svg_tree = svg_tree
11
- @svg_tree = Parser.new(@svg_tree).parse if @svg_tree.is_a? String
12
- @template = template || :cli
13
- end
14
-
15
- def ruby_code
16
- @ruby_code ||= Rufo::Formatter.format(code_for_node(svg_tree))
17
- end
18
-
19
- private
20
-
21
- def code_for_node(node)
22
- return text_to_ruby node if node.is_a?(XMLText)
23
-
24
- case node.type
25
- when "svg"
26
- root_to_ruby node
27
- when "text", "tspan"
28
- text_node_to_ruby node
29
- else
30
- node_to_ruby node
31
- end
32
- end
33
-
34
- def text_node_to_ruby(node)
35
- children = node.children
36
- if children.length == 1 && children.first.is_a?(XMLText)
37
- short_text_to_ruby node
38
- else
39
- node_to_ruby node
40
- end
41
- end
42
-
43
- def short_text_to_ruby(node)
44
- attrs = node.attributes.empty? ? "" : ",#{attrs_to_ruby(node.attributes)}"
45
- inner_text = node.children.first.text
46
- "text #{inner_text.inspect} #{attrs}"
47
- end
48
-
49
- def node_to_ruby(node)
50
- code = "#{node.type} #{attrs_to_ruby(node.attributes)} "
51
- unless node.children.empty?
52
- code << " do\n"
53
- code << nodes_to_ruby(node.children)
54
- code << "\nend\n"
55
- end
56
- code
57
- end
58
-
59
- def nodes_to_ruby(nodes)
60
- nodes.map do |node|
61
- code_for_node node
62
- end.join "\n"
63
- end
64
-
65
- def text_to_ruby(node)
66
- "_ #{node.text.inspect}"
67
- end
68
-
69
- def attrs_to_ruby(attrs)
70
- attrs.map do |key, value|
71
- "#{key.format_as_key}: #{value.format_as_value}"
72
- end.join ", "
73
- end
74
-
75
- def root_to_ruby(node)
76
- values = {
77
- attributes: attrs_to_ruby(node.attributes),
78
- nodes: nodes_to_ruby(node.children),
79
- }
80
-
81
- template_content(template) % values
82
- end
83
-
84
- def template_content(name)
85
- filename = File.join templates_path, "#{name}.rb"
86
-
87
- unless File.exist? filename
88
- raise "Template not found #{name}\nAvailable templates: #{available_templates.join ', '}"
89
- end
90
-
91
- File.read filename
92
- end
93
-
94
- def templates_path
95
- @templates_path ||= File.expand_path "templates/import", __dir__
96
- end
97
-
98
- def available_templates
99
- @available_templates ||= Dir["#{templates_path}/*.rb"].map do |path|
100
- File.basename path, '.rb'
101
- end.sort
102
- end
103
- end
104
- end
105
- end
@@ -1,8 +0,0 @@
1
- # Render this template by running 'victor render FILE'
2
-
3
- setup %{attributes}
4
-
5
- build do
6
- %{nodes}
7
- end
8
-
@@ -1,12 +0,0 @@
1
- # Render this template by running 'ruby FILE' or 'victor render FILE'
2
-
3
- require 'victor/script'
4
-
5
- setup %{attributes}
6
-
7
- build do
8
- %{nodes}
9
- end
10
-
11
- puts render
12
- save 'output'
@@ -1,10 +0,0 @@
1
- # Render this template by running 'ruby FILE' or 'victor render FILE'
2
-
3
- require "victor"
4
-
5
- svg = Victor::SVG.new %{attributes}
6
- svg.build do
7
- %{nodes}
8
- end
9
-
10
- svg.save "generated"
@@ -1,14 +0,0 @@
1
- module Victor
2
- module CLI
3
- class XMLNode
4
- attr_reader :type, :attributes, :children
5
-
6
- def initialize(type, attributes, children)
7
- @type = type
8
- @attributes = attributes
9
- @children = children
10
- end
11
-
12
- end
13
- end
14
- end
@@ -1,11 +0,0 @@
1
- module Victor
2
- module CLI
3
- class XMLText
4
- attr_reader :text
5
-
6
- def initialize(text)
7
- @text = text.strip
8
- end
9
- end
10
- end
11
- end