svg_optimizer 0.2.2 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of svg_optimizer might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 8b58103eace64dcab3740e83ce4a1c328dd6ae06
4
- data.tar.gz: 68ee27f69693afcd6eab21e0b1ffa57905d1c90b
2
+ SHA256:
3
+ metadata.gz: 385024a89793a95b04290dbea791b71007a8d27387a02939865f4ed6f2528c72
4
+ data.tar.gz: 8e1e9581f7516362b09bc2221a889043e3ae1b1ad442e73a7b178be26e3e1d8b
5
5
  SHA512:
6
- metadata.gz: '08e57257160f937494ee265a804e887033e59246d1e5a74b903ba99d8a5b4bc47687fd0e0ad9f1affa4afee2c6aa4bbd0d37c1ef5be1fe2d0036473f83c983b5'
7
- data.tar.gz: f6b6caf4b7ff9f4ae069d23a1c22267e55cde26d134fc2368ff5f26efabd767e03687a1e1c21060a9313124e12c14809498e9128f2dd72201fb71e1830fc7a57
6
+ metadata.gz: 699299880bf18dab73133899f59dcfa541a46ab45f3f0d2aeb48eb478caec60bdc2ce07c5093b5ab99e6c09118a966fa1009ba656ac7db0ef768a22a54774222
7
+ data.tar.gz: 1862ba8ad388c1523d7e69ff2e139efef59e4d3ede808d6ac9cabfd112c94b35a706563b1efaf10302386acce25812b02ba2b33ba3a2ab3bb45dc459963748d8
File without changes
data/README.md CHANGED
@@ -1,8 +1,7 @@
1
1
  # SvgOptimizer
2
2
 
3
- [![Travis-CI](https://travis-ci.org/fnando/svg_optimizer.svg)](https://travis-ci.org/fnando/svg_optimizer)
3
+ [![Tests](https://github.com/fnando/svg_optimizer/workflows/ruby-tests/badge.svg)](https://github.com/fnando/svg_optimizer)
4
4
  [![Code Climate](https://codeclimate.com/github/fnando/svg_optimizer/badges/gpa.svg)](https://codeclimate.com/github/fnando/svg_optimizer)
5
- [![Test Coverage](https://codeclimate.com/github/fnando/svg_optimizer/badges/coverage.svg)](https://codeclimate.com/github/fnando/svg_optimizer/coverage)
6
5
  [![Gem](https://img.shields.io/gem/v/svg_optimizer.svg)](https://rubygems.org/gems/svg_optimizer)
7
6
  [![Gem](https://img.shields.io/gem/dt/svg_optimizer.svg)](https://rubygems.org/gems/svg_optimizer)
8
7
 
@@ -10,17 +9,15 @@ Some small optimizations for SVG files.
10
9
 
11
10
  ## Installation
12
11
 
13
- Add this line to your application's Gemfile:
14
-
15
- gem 'svg_optimizer'
16
-
17
- And then execute:
18
-
19
- $ bundle
12
+ ```bash
13
+ gem install svg_optimizer
14
+ ```
20
15
 
21
- Or install it yourself as:
16
+ Or add the following line to your project's Gemfile:
22
17
 
23
- $ gem install svg_optimizer
18
+ ```ruby
19
+ gem "svg_optimizer"
20
+ ```
24
21
 
25
22
  ## Usage
26
23
 
@@ -53,16 +50,34 @@ class MyPlugin < SvgOptimizer::Plugins::Base
53
50
  end
54
51
  ```
55
52
 
56
- The default list of plugins is stored at `SvgOptimizer::DEFAULT_PLUGINS`. To use your new plugin, just do something like this:
53
+ The default list of plugins is stored at `SvgOptimizer::DEFAULT_PLUGINS`. To use
54
+ your new plugin, just do something like this:
57
55
 
58
56
  ```ruby
59
57
  SvgOptimizer.optimize(xml, SvgOptimizer::DEFAULT_PLUGINS + [MyPlugin])
60
58
  ```
61
59
 
60
+ ## Maintainer
61
+
62
+ - [Nando Vieira](https://github.com/fnando)
63
+
64
+ ## Contributors
65
+
66
+ - https://github.com/fnando/svg_optimizer/contributors
67
+
62
68
  ## Contributing
63
69
 
64
- 1. Fork it
65
- 2. Create your feature branch (`git checkout -b my-new-feature`)
66
- 3. Commit your changes (`git commit -am 'Add some feature'`)
67
- 4. Push to the branch (`git push origin my-new-feature`)
68
- 5. Create new Pull Request
70
+ For more details about how to contribute, please read
71
+ https://github.com/fnando/svg_optimizer/blob/main/CONTRIBUTING.md.
72
+
73
+ ## License
74
+
75
+ The gem is available as open source under the terms of the
76
+ [MIT License](https://opensource.org/licenses/MIT). A copy of the license can be
77
+ found at https://github.com/fnando/svg_optimizer/blob/main/LICENSE.md.
78
+
79
+ ## Code of Conduct
80
+
81
+ Everyone interacting in the svg_optimizer project's codebases, issue trackers,
82
+ chat rooms and mailing lists is expected to follow the
83
+ [code of conduct](https://github.com/fnando/svg_optimizer/blob/main/CODE_OF_CONDUCT.md).
@@ -9,7 +9,7 @@ module SvgOptimizer
9
9
  ].freeze
10
10
 
11
11
  IDS = LETTERS.dup.concat(LETTERS.combination(2).to_a).freeze
12
- XLINK_NAMESPACE = "http://www.w3.org/1999/xlink".freeze
12
+ XLINK_NAMESPACE = "http://www.w3.org/1999/xlink"
13
13
 
14
14
  def ids
15
15
  @ids ||= IDS.dup
@@ -19,6 +19,10 @@ module SvgOptimizer
19
19
  # If there's a <script> or <style>, don't mess with ids.
20
20
  return if xml.css("script, style").any?
21
21
 
22
+ # SVG can have ids as arrays.
23
+ # Skip id optimization if that's the case.
24
+ return if xml.css("[id^='[']").size.nonzero?
25
+
22
26
  # Replace the ids otherwise.
23
27
  xml.css("[id]").each(&method(:cleanup_id))
24
28
  end
@@ -3,50 +3,55 @@
3
3
  module SvgOptimizer
4
4
  module Plugins
5
5
  class RemoveEditorNamespace < Base
6
- NAMESPACES = %w[
7
- http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd
8
- http://www.inkscape.org/namespaces/inkscape
9
- http://ns.adobe.com/AdobeIllustrator/10.0/
10
- http://ns.adobe.com/Graphs/1.0/
11
- http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/
12
- http://ns.adobe.com/Variables/1.0/
13
- http://ns.adobe.com/SaveForWeb/1.0/
14
- http://ns.adobe.com/Extensibility/1.0/
15
- http://ns.adobe.com/Flows/1.0/
16
- http://ns.adobe.com/ImageReplacement/1.0/
17
- http://ns.adobe.com/GenericCustomNamespace/1.0/
18
- http://ns.adobe.com/XPath/1.0
19
- http://www.bohemiancoding.com/sketch/ns
6
+ NAMESPACES = [
7
+ "http://ns.adobe.com/AdobeIllustrator/10.0/",
8
+ "http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/",
9
+ "http://ns.adobe.com/Extensibility/1.0/",
10
+ "http://ns.adobe.com/Flows/1.0/",
11
+ "http://ns.adobe.com/GenericCustomNamespace/1.0/",
12
+ "http://ns.adobe.com/Graphs/1.0/",
13
+ "http://ns.adobe.com/ImageReplacement/1.0/",
14
+ "http://ns.adobe.com/SaveForWeb/1.0/",
15
+ "http://ns.adobe.com/Variables/1.0/",
16
+ "http://ns.adobe.com/XPath/1.0",
17
+ "http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd",
18
+ "http://www.bohemiancoding.com/sketch/ns",
19
+ "http://www.inkscape.org/namespaces/inkscape"
20
20
  ].freeze
21
21
 
22
22
  def process
23
- namespaces = xml.namespaces
24
- remove_namespaced_attributes
25
- xml.remove_namespaces!
23
+ xml.namespaces.each do |full_name, href|
24
+ _, name = full_name.split(":")
25
+ next unless NAMESPACES.include?(href)
26
26
 
27
- namespaces.each do |name, value|
28
- next if NAMESPACES.include?(value)
27
+ remove_namespaced_attributes(name, href)
28
+ end
29
29
 
30
- _, name = name.split(":")
31
- xml.root.add_namespace name, value
30
+ xml.root.namespace_definitions.each do |namespace|
31
+ remove_namespace(namespace) if NAMESPACES.include?(namespace.href)
32
32
  end
33
33
  end
34
34
 
35
- def namespaces_to_be_removed
36
- xml.namespaces.map do |name, value|
37
- _, name = name.split(":")
38
- name if NAMESPACES.include?(value)
39
- end.compact
35
+ def remove_namespaced_attributes(name, href)
36
+ xml.xpath("//@*[namespace-uri()='#{href}']").each do |node|
37
+ remove_matching_attribute(node, name)
38
+ end
39
+
40
+ xml.xpath("//*[@#{name}:*]").each do |node|
41
+ remove_matching_attribute(node, name)
42
+ end
40
43
  end
41
44
 
42
- def remove_namespaced_attributes
43
- namespaces_to_be_removed.each do |ns|
44
- xml.xpath("//*[@#{ns}:*]").each do |node|
45
- node.attributes.each do |_, attr|
46
- next unless attr.namespace
47
- attr.remove if attr.namespace.prefix == ns
48
- end
49
- end
45
+ def remove_namespace(namespace)
46
+ source = xml.root.to_s.gsub(/ *xmlns:#{namespace.prefix}=".*?"/, "")
47
+ xml.root = Nokogiri::XML(source).root
48
+ end
49
+
50
+ def remove_matching_attribute(node, name)
51
+ node.attributes.each do |_, attr|
52
+ next unless attr.namespace
53
+
54
+ attr.remove if attr.namespace.prefix == name
50
55
  end
51
56
  end
52
57
  end
@@ -11,9 +11,7 @@ module SvgOptimizer
11
11
  end
12
12
  end
13
13
 
14
- private
15
-
16
- def remove_if_empty(node, attr)
14
+ private def remove_if_empty(node, attr)
17
15
  node.remove_attribute(attr) if node[attr].empty?
18
16
  end
19
17
  end
@@ -3,7 +3,17 @@
3
3
  module SvgOptimizer
4
4
  module Plugins
5
5
  class RemoveEmptyContainer < Base
6
- ELEMENTS = %w[a defs g marker mask missing-glyph pattern switch symbol].freeze
6
+ ELEMENTS = %w[
7
+ a
8
+ defs
9
+ g
10
+ marker
11
+ mask
12
+ missing-glyph
13
+ pattern
14
+ switch
15
+ symbol
16
+ ].freeze
7
17
  SELECTOR = ELEMENTS.map {|element| %[#{element}:empty] }.join(", ")
8
18
 
9
19
  def process
@@ -12,9 +22,7 @@ module SvgOptimizer
12
22
  end
13
23
  end
14
24
 
15
- private
16
-
17
- def remove_node(node)
25
+ private def remove_node(node)
18
26
  node.children.empty? && node.remove
19
27
  remove_node(node.parent) if node.parent
20
28
  end
@@ -7,9 +7,7 @@ module SvgOptimizer
7
7
  xml.xpath("//text()").each(&method(:remove_if_empty))
8
8
  end
9
9
 
10
- private
11
-
12
- def remove_if_empty(node)
10
+ private def remove_if_empty(node)
13
11
  node.remove if node.text.gsub(/\s/, "").empty?
14
12
  end
15
13
  end
@@ -4,7 +4,7 @@ module SvgOptimizer
4
4
  module Plugins
5
5
  class RemoveTitle < Base
6
6
  def process
7
- xml.xpath("//title").remove
7
+ xml.css("title").remove
8
8
  end
9
9
  end
10
10
  end
@@ -13,6 +13,7 @@ module SvgOptimizer
13
13
 
14
14
  def remove_unused_ns(ns)
15
15
  return if xml.xpath("//#{ns.prefix}:*").any?
16
+ return if xml.xpath("//@*[namespace-uri()='#{ns.href}']").any?
16
17
 
17
18
  source = xml.root.to_s.gsub(/ *xmlns:#{ns.prefix}=".*?"/, "")
18
19
  xml.root = Nokogiri::XML(source).root
@@ -4,7 +4,12 @@ module SvgOptimizer
4
4
  module Plugins
5
5
  class RemoveUselessStrokeAndFill < Base
6
6
  SELECTOR = %w[circle ellipse line path polygon polyline rect].join(",")
7
- STROKE_ATTRS = %w[stroke stroke-opacity stroke-width stroke-dashoffset].freeze
7
+ STROKE_ATTRS = %w[
8
+ stroke
9
+ stroke-opacity
10
+ stroke-width
11
+ stroke-dashoffset
12
+ ].freeze
8
13
  FILL_ATTRS = %w[fill-opacity fill-rule].freeze
9
14
 
10
15
  def process
@@ -15,40 +20,39 @@ module SvgOptimizer
15
20
  end
16
21
  end
17
22
 
18
- private
19
-
20
- def remove_useless_attributes(node)
23
+ private def remove_useless_attributes(node)
21
24
  return if inherited_attribute(node, "id")
25
+
22
26
  remove_stroke(node) if remove_stroke?(node)
23
27
  remove_fill(node) if remove_fill?(node)
24
28
  end
25
29
 
26
- def remove_stroke(node)
30
+ private def remove_stroke(node)
27
31
  STROKE_ATTRS.each {|attr| node.delete(attr) }
28
32
  node["stroke"] = "none" if decline_inherited_stroke?(node)
29
33
  end
30
34
 
31
- def remove_fill(node)
35
+ private def remove_fill(node)
32
36
  FILL_ATTRS.each {|attr| node.delete(attr) }
33
37
  node["fill"] = "none" if decline_inherited_fill?(node)
34
38
  end
35
39
 
36
- def decline_inherited_stroke?(node)
40
+ private def decline_inherited_stroke?(node)
37
41
  (inherited_attribute(node.parent, "stroke") || "none") != "none"
38
42
  end
39
43
 
40
- def decline_inherited_fill?(node)
44
+ private def decline_inherited_fill?(node)
41
45
  !inherited_attribute(node, "fill") || node.has_attribute?("fill")
42
46
  end
43
47
 
44
- def remove_stroke?(node)
48
+ private def remove_stroke?(node)
45
49
  return true if (inherited_attribute(node, "stroke") || "none") == "none"
46
50
  return true if inherited_attribute(node, "stroke-opacity") == "0"
47
51
 
48
52
  inherited_attribute(node, "stroke-width") == "0"
49
53
  end
50
54
 
51
- def remove_fill?(node)
55
+ private def remove_fill?(node)
52
56
  fill = inherited_attribute(node, "fill")
53
57
 
54
58
  return true if fill == "none"
@@ -57,7 +61,7 @@ module SvgOptimizer
57
61
  !fill
58
62
  end
59
63
 
60
- def inherited_attribute(node, attr)
64
+ private def inherited_attribute(node, attr)
61
65
  return if node.nil? || node.document?
62
66
  return node[attr] if node.has_attribute?(attr)
63
67
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SvgOptimizer
4
- VERSION = "0.2.2".freeze
4
+ VERSION = "0.2.6"
5
5
  end
data/lib/svg_optimizer.rb CHANGED
@@ -6,7 +6,6 @@ require "svg_optimizer/version"
6
6
  require "svg_optimizer/plugins/base"
7
7
  require "svg_optimizer/plugins/cleanup_attribute"
8
8
  require "svg_optimizer/plugins/cleanup_id"
9
- require "svg_optimizer/plugins/collapse_groups"
10
9
  require "svg_optimizer/plugins/remove_comment"
11
10
  require "svg_optimizer/plugins/remove_metadata"
12
11
  require "svg_optimizer/plugins/remove_empty_text_node"
@@ -22,26 +21,29 @@ require "svg_optimizer/plugins/remove_description"
22
21
 
23
22
  module SvgOptimizer
24
23
  DEFAULT_PLUGINS = %w[
24
+ RemoveTitle
25
+ RemoveDescription
26
+ RemoveUnusedNamespace
25
27
  CleanupAttribute
26
28
  CleanupId
27
29
  RemoveComment
28
30
  RemoveMetadata
29
31
  RemoveEditorNamespace
30
32
  RemoveHiddenElement
31
- RemoveUnusedNamespace
32
33
  RemoveRasterImage
33
34
  RemoveEmptyAttribute
34
- CollapseGroups
35
35
  RemoveUselessStrokeAndFill
36
36
  RemoveEmptyTextNode
37
37
  RemoveEmptyContainer
38
- RemoveTitle
39
- RemoveDescription
40
38
  ].map {|name| Plugins.const_get(name) }
41
39
 
42
40
  def self.optimize(contents, plugins = DEFAULT_PLUGINS)
43
- xml = Nokogiri::XML(contents)
41
+ xml = Nokogiri::XML(contents) do |config|
42
+ config.recover.noent
43
+ end
44
+
44
45
  plugins.each {|plugin| plugin.new(xml).process }
46
+
45
47
  xml.root.to_xml
46
48
  end
47
49
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: svg_optimizer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nando Vieira
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-01 00:00:00.000000000 Z
11
+ date: 2022-01-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: rake
42
+ name: minitest-utils
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -67,7 +67,35 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: minitest-utils
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop-fnando
71
99
  requirement: !ruby/object:Gem::Requirement
72
100
  requirements:
73
101
  - - ">="
@@ -101,13 +129,12 @@ executables: []
101
129
  extensions: []
102
130
  extra_rdoc_files: []
103
131
  files:
104
- - LICENSE.txt
132
+ - LICENSE.md
105
133
  - README.md
106
134
  - lib/svg_optimizer.rb
107
135
  - lib/svg_optimizer/plugins/base.rb
108
136
  - lib/svg_optimizer/plugins/cleanup_attribute.rb
109
137
  - lib/svg_optimizer/plugins/cleanup_id.rb
110
- - lib/svg_optimizer/plugins/collapse_groups.rb
111
138
  - lib/svg_optimizer/plugins/remove_comment.rb
112
139
  - lib/svg_optimizer/plugins/remove_description.rb
113
140
  - lib/svg_optimizer/plugins/remove_editor_namespace.rb
@@ -124,8 +151,9 @@ files:
124
151
  homepage: https://github.com/fnando/svg_optimizer
125
152
  licenses:
126
153
  - MIT
127
- metadata: {}
128
- post_install_message:
154
+ metadata:
155
+ rubygems_mfa_required: 'true'
156
+ post_install_message:
129
157
  rdoc_options: []
130
158
  require_paths:
131
159
  - lib
@@ -133,16 +161,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
133
161
  requirements:
134
162
  - - ">="
135
163
  - !ruby/object:Gem::Version
136
- version: '0'
164
+ version: '2.7'
137
165
  required_rubygems_version: !ruby/object:Gem::Requirement
138
166
  requirements:
139
167
  - - ">="
140
168
  - !ruby/object:Gem::Version
141
169
  version: '0'
142
170
  requirements: []
143
- rubyforge_project:
144
- rubygems_version: 2.6.13
145
- signing_key:
171
+ rubygems_version: 3.3.3
172
+ signing_key:
146
173
  specification_version: 4
147
174
  summary: SVG optimization based on Node's SVGO
148
175
  test_files: []
@@ -1,53 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SvgOptimizer
4
- module Plugins
5
- class CollapseGroups < Base
6
- COLLAPSABLE_ATTRS = %w[transform class].freeze
7
-
8
- def process
9
- xml.css("g:not(:empty)").each do |group|
10
- collapse(group)
11
- end
12
- end
13
-
14
- private
15
-
16
- def collapse(group)
17
- collapse_attributes(group)
18
- group.swap(group.children) if collapse?(group)
19
- end
20
-
21
- def collapse_attributes(group)
22
- child = group.first_element_child
23
- return unless collapse_attributes?(group, child)
24
-
25
- group.attributes.each do |attr, val|
26
- if COLLAPSABLE_ATTRS.include?(attr)
27
- child[attr] = [val, child[attr]].compact.join(" ")
28
- else
29
- child[attr] ||= val
30
- end
31
-
32
- group.delete(attr)
33
- end
34
- end
35
-
36
- def collapse?(group)
37
- group.attributes.empty? &&
38
- !group.element_children.map(&:name).include?("animate")
39
- end
40
-
41
- def collapse_attributes?(group, child)
42
- return unless group.attributes.any?
43
- return unless group.element_children.length == 1
44
- return if child.has_attribute?("id")
45
- return unless !group.has_attribute?("clip-path") ||
46
- child.name == "g" &&
47
- !group.has_attribute?("transform") &&
48
- !child.has_attribute?("transform")
49
- true
50
- end
51
- end
52
- end
53
- end