svgo 0.1.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.
- checksums.yaml +7 -0
- data/.dockerignore +25 -0
- data/.eslintrc.yml +106 -0
- data/Dockerfile +6 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +27 -0
- data/LICENSE.txt +13 -0
- data/README.MD +102 -0
- data/Rakefile +14 -0
- data/bin/svgo-ruby +224 -0
- data/lib/svgo.rb +130 -0
- data/lib/version.rb +3 -0
- data/svgo-js/svgo-built.js +45392 -0
- data/svgo-js/svgo-wrapper.js +133 -0
- data/svgo.gemspec +29 -0
- data/test/fixtures/ruby.svg +948 -0
- data/yarn.lock +2762 -0
- metadata +117 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c216063430e455819ad08549b9b6bff0a7b2c34b
|
4
|
+
data.tar.gz: 9183a0a0c245e92cbcde98f6f41f947aa82599c7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c163a831dbb98c72c2534bf3082c0337d0b515bafe63c061a4e6d99731919d9961b92b20e64ae3127da184e853124fdadf7a34b84a1b80a0ef2da5bee42a1eb3
|
7
|
+
data.tar.gz: cbfb979e20b28027197b96be6e25c47af9509c9e1d92577cfc070820f7cb7198d4d64421161ac7e8644f71a5d8c64432db41bc7f28d0dceb460739dd08885d0f
|
data/.dockerignore
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# Ignore bundler config
|
2
|
+
/.bundle
|
3
|
+
vendor
|
4
|
+
# Ignore the build directory
|
5
|
+
/build
|
6
|
+
# Ignore cache
|
7
|
+
/.sass-cache
|
8
|
+
/.cache
|
9
|
+
# Ignore .DS_store file
|
10
|
+
.DS_Store
|
11
|
+
# Temporary files
|
12
|
+
*.swp
|
13
|
+
.nfs*
|
14
|
+
tmp
|
15
|
+
|
16
|
+
# other
|
17
|
+
.gitlab/
|
18
|
+
.gitlab-ci.yml
|
19
|
+
.eslintrc.yml
|
20
|
+
yarn.lock
|
21
|
+
package.json
|
22
|
+
.editorconfig
|
23
|
+
Gemfile.lock
|
24
|
+
.ruby-version
|
25
|
+
node_modules/
|
data/.eslintrc.yml
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
env:
|
2
|
+
node: true
|
3
|
+
extends: 'eslint:recommended'
|
4
|
+
parserOptions:
|
5
|
+
ecmaVersion: 5
|
6
|
+
globals:
|
7
|
+
$: false
|
8
|
+
jQuery: false
|
9
|
+
I18n: false
|
10
|
+
locale: true
|
11
|
+
rules:
|
12
|
+
indent:
|
13
|
+
- warn
|
14
|
+
- 2
|
15
|
+
-
|
16
|
+
SwitchCase: 1
|
17
|
+
MemberExpression: 1
|
18
|
+
FunctionDeclaration:
|
19
|
+
body: 1
|
20
|
+
parameters: 2
|
21
|
+
CallExpression:
|
22
|
+
arguments: 1
|
23
|
+
ArrayExpression: 1
|
24
|
+
ObjectExpression: 1
|
25
|
+
|
26
|
+
linebreak-style:
|
27
|
+
- warn
|
28
|
+
- unix
|
29
|
+
quotes:
|
30
|
+
- warn
|
31
|
+
- double
|
32
|
+
-
|
33
|
+
avoidEscape: true
|
34
|
+
semi:
|
35
|
+
- error
|
36
|
+
- always
|
37
|
+
camelcase:
|
38
|
+
- warn
|
39
|
+
-
|
40
|
+
properties: never
|
41
|
+
ignoreDestructuring: false
|
42
|
+
brace-style:
|
43
|
+
- warn
|
44
|
+
- 1tbs
|
45
|
+
-
|
46
|
+
allowSingleLine: true
|
47
|
+
comma-spacing:
|
48
|
+
- warn
|
49
|
+
multiline-comment-style:
|
50
|
+
- warn
|
51
|
+
- separate-lines
|
52
|
+
spaced-comment:
|
53
|
+
- warn
|
54
|
+
- always
|
55
|
+
-
|
56
|
+
line:
|
57
|
+
markers:
|
58
|
+
- "="
|
59
|
+
block:
|
60
|
+
exceptions:
|
61
|
+
- "*"
|
62
|
+
balanced: true
|
63
|
+
no-multiple-empty-lines:
|
64
|
+
- error
|
65
|
+
-
|
66
|
+
max: 2
|
67
|
+
maxBOF: 0
|
68
|
+
maxEOF: 1
|
69
|
+
unicode-bom:
|
70
|
+
- error
|
71
|
+
- never
|
72
|
+
dot-location:
|
73
|
+
- error
|
74
|
+
- property
|
75
|
+
dot-notation:
|
76
|
+
- warn
|
77
|
+
no-alert:
|
78
|
+
warn
|
79
|
+
no-console:
|
80
|
+
warn
|
81
|
+
no-eval:
|
82
|
+
error
|
83
|
+
valid-jsdoc:
|
84
|
+
- error
|
85
|
+
-
|
86
|
+
prefer:
|
87
|
+
arg: param
|
88
|
+
argument: param
|
89
|
+
return: returns
|
90
|
+
preferType:
|
91
|
+
object: Object
|
92
|
+
array: Array
|
93
|
+
list: Array
|
94
|
+
hash: Object
|
95
|
+
dict: Object
|
96
|
+
requireReturn: false
|
97
|
+
requireReturnType: true
|
98
|
+
requireParamType: true
|
99
|
+
requireParamDescription: true
|
100
|
+
matchDescription: ".+"
|
101
|
+
requireReturnDescription: true
|
102
|
+
no-unused-vars:
|
103
|
+
- error
|
104
|
+
-
|
105
|
+
vars: all
|
106
|
+
argsIgnorePattern: "window|document|event|el|element|_"
|
data/Dockerfile
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
svgo (0.1.0)
|
5
|
+
execjs (>= 2.7.0)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
coderay (1.1.2)
|
11
|
+
execjs (2.7.0)
|
12
|
+
method_source (0.9.0)
|
13
|
+
pry (0.11.3)
|
14
|
+
coderay (~> 1.1.0)
|
15
|
+
method_source (~> 0.9.0)
|
16
|
+
rake (12.3.1)
|
17
|
+
|
18
|
+
PLATFORMS
|
19
|
+
ruby
|
20
|
+
|
21
|
+
DEPENDENCIES
|
22
|
+
pry
|
23
|
+
rake (>= 0.11.3)
|
24
|
+
svgo!
|
25
|
+
|
26
|
+
BUNDLED WITH
|
27
|
+
1.16.5
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Copyright 2018 Greenhost BV
|
2
|
+
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License.
|
5
|
+
You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
See the License for the specific language governing permissions and
|
13
|
+
limitations under the License.
|
data/README.MD
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
# A Ruby wrapper for Node SVGO
|
2
|
+
|
3
|
+
Removes metadata and editor data elements and attributes that are redundant
|
4
|
+
from SVG files. Can strip files so they are optimised for web use. Go to [SVGO]
|
5
|
+
(https://github.com/svg/svgo) for more documentation on features.
|
6
|
+
|
7
|
+
## How to use?
|
8
|
+
|
9
|
+
### As a library
|
10
|
+
|
11
|
+
As intended: a Ruby library. Add it to your Gemfile or *.gemspec file and
|
12
|
+
install it.
|
13
|
+
|
14
|
+
#### Method 1 (Recommended)
|
15
|
+
|
16
|
+
By supplying a block that modifies the default options in `SvgoOptions`.
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
require('svgo')
|
20
|
+
svg_file = "path/to/a.svg"
|
21
|
+
svgo = SvgOptimizer.new() do | options |
|
22
|
+
options.plugins << :removeRasterImages # (disabled by default)
|
23
|
+
options.plugins.delete(:cleanupIDs) # (enabled by default)
|
24
|
+
options.js2svg.pretty = true
|
25
|
+
end
|
26
|
+
svgo.optimize(File.read(svg_file))
|
27
|
+
# => <svg xmlns="http://www.w3.org/2000/svg" ...
|
28
|
+
```
|
29
|
+
|
30
|
+
#### Method 2
|
31
|
+
|
32
|
+
You can manually pass options to the class that correspond to [SVGO]
|
33
|
+
(https://github.com/svg/svgo)'s documentation.
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
require('svgo')
|
37
|
+
svg_file = "path/to/a.svg"
|
38
|
+
options = {
|
39
|
+
floatPrecision: 7,
|
40
|
+
js2svg: {
|
41
|
+
pretty: true
|
42
|
+
},
|
43
|
+
multipass: false
|
44
|
+
}
|
45
|
+
svgo = SvgOptimizer.new(options)
|
46
|
+
svgo.optimize(File.read(svg_file))
|
47
|
+
# => <svg xmlns="http://www.w3.org/2000/svg" ...
|
48
|
+
|
49
|
+
# OR..
|
50
|
+
|
51
|
+
svgo.optimize_file(svg_file)
|
52
|
+
# => <svg xmlns="http://www.w3.org/2000/svg" ...
|
53
|
+
```
|
54
|
+
|
55
|
+
You can also choose the plugins to use, you can either pass the exact plugins you want with their configuration, or you can modify the default plugin list.
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
require('svgo')
|
59
|
+
svg_file = "path/to/a.svg"
|
60
|
+
options = {
|
61
|
+
plugins: {
|
62
|
+
:addAttributesToSVGElement=>true,
|
63
|
+
:addClassesToSVGElement=>true,
|
64
|
+
:cleanupAttrs=>false,
|
65
|
+
:cleanupEnableBackground=>true,
|
66
|
+
:cleanupIDs=>false,
|
67
|
+
:cleanupListOfValues=>true,
|
68
|
+
:cleanupNumericValues=>true,
|
69
|
+
:collapseGroups=>true,
|
70
|
+
#etc..
|
71
|
+
}
|
72
|
+
}
|
73
|
+
svgo = SvgOptimizer.new(options)
|
74
|
+
```
|
75
|
+
|
76
|
+
### As a CLI tool
|
77
|
+
|
78
|
+
Strictly speaking this mode is for testing only. But if you can't install NodeJS, and you do have a Ruby environment and you really need a CLI tool, you might be able to squeeze out some optimised files from this utility.
|
79
|
+
|
80
|
+
``` bash
|
81
|
+
gem install svgo-ruby
|
82
|
+
svgo-ruby --pretty < test/fixtures/ruby.svg > test/fixtures/ruby.optim.svg
|
83
|
+
ls -hl test/fixtures
|
84
|
+
total 72
|
85
|
+
-rw-r--r-- 1 user staff 9.5K Nov 5 22:16 ruby.optim.svg
|
86
|
+
-rw-r--r-- 1 user staff 23K Nov 5 22:12 ruby.svg
|
87
|
+
```
|
88
|
+
|
89
|
+
### As a CLI tool from docker
|
90
|
+
|
91
|
+
Because this uses a Node utility from a monolithic JavaScript environment which
|
92
|
+
is highly dependent on whatever version is available on your system, etc.
|
93
|
+
There is a Dockerfile which should always build correctly and run the CLI tool.
|
94
|
+
|
95
|
+
This is also only intended for testing purposes.
|
96
|
+
|
97
|
+
``` bash
|
98
|
+
docker build -t svgo ./
|
99
|
+
docker run -i svgo < test/fixtures/ruby.svg > test/fixtures/ruby.optim.svg
|
100
|
+
-rw-r--r-- 1 user staff 9.5K Nov 5 22:16 ruby.optim.svg
|
101
|
+
-rw-r--r-- 1 user staff 23K Nov 5 22:12 ruby.svg
|
102
|
+
```
|
data/Rakefile
ADDED
data/bin/svgo-ruby
ADDED
@@ -0,0 +1,224 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
##
|
4
|
+
# This is a command line tool primarily to test wrapping Node SVGO, it is NOT
|
5
|
+
# a drop-in replacement of the node SVGO command line tool. Feel free to add
|
6
|
+
# that functionality through a Pull Request if you require it.
|
7
|
+
##
|
8
|
+
|
9
|
+
$:.push File.expand_path("../../lib", __FILE__)
|
10
|
+
require 'svgo'
|
11
|
+
require 'version'
|
12
|
+
require 'optparse'
|
13
|
+
require 'pp'
|
14
|
+
require 'ostruct'
|
15
|
+
|
16
|
+
options = SvgoOptions.new
|
17
|
+
output_file = nil
|
18
|
+
plugins = {
|
19
|
+
addAttributesToSVGElement:
|
20
|
+
"adds attributes to an outer <svg> element",
|
21
|
+
addClassesToSVGElement:
|
22
|
+
"adds classnames to an outer <svg> element",
|
23
|
+
cleanupAttrs:
|
24
|
+
"cleanups attributes from newlines, trailing and repeating spaces",
|
25
|
+
cleanupEnableBackground:
|
26
|
+
"remove or cleanup enable-background attribute when possible",
|
27
|
+
cleanupIDs:
|
28
|
+
"removes unused IDs and minifies used",
|
29
|
+
cleanupListOfValues:
|
30
|
+
"rounds list of values to the fixed precision",
|
31
|
+
cleanupNumericValues:
|
32
|
+
"rounds numeric values to the fixed precision, removes default ‘px’ units",
|
33
|
+
collapseGroups:
|
34
|
+
"collapses useless groups",
|
35
|
+
convertColors:
|
36
|
+
"converts colors: rgb() to #rrggbb and #rrggbb to #rgb",
|
37
|
+
convertPathData:
|
38
|
+
"optimizes path data: writes in shorter form, applies transformations",
|
39
|
+
convertShapeToPath:
|
40
|
+
"converts basic shapes to more compact path form",
|
41
|
+
convertStyleToAttrs:
|
42
|
+
"converts style to attributes",
|
43
|
+
convertTransform:
|
44
|
+
"collapses multiple transformations and optimizes it",
|
45
|
+
inlineStyles:
|
46
|
+
"inline styles (additional options)",
|
47
|
+
mergePaths:
|
48
|
+
"merges multiple paths in one if possible",
|
49
|
+
minifyStyles:
|
50
|
+
"minifies styles and removes unused styles based on usage data",
|
51
|
+
moveElemsAttrsToGroup:
|
52
|
+
"moves elements attributes to the existing group wrapper",
|
53
|
+
moveGroupAttrsToElems:
|
54
|
+
"moves some group attributes to the content elements",
|
55
|
+
prefixIds:
|
56
|
+
"prefix IDs",
|
57
|
+
removeComments:
|
58
|
+
"removes comments",
|
59
|
+
removeDesc:
|
60
|
+
"removes <desc>",
|
61
|
+
removeDimensions:
|
62
|
+
"removes width and height in presence of viewBox (opposite to removeViewBox, disable it first)",
|
63
|
+
removeDoctype:
|
64
|
+
"removes doctype declaration",
|
65
|
+
removeEditorsNSData:
|
66
|
+
"removes editors namespaces, elements and attributes",
|
67
|
+
removeElementsByAttr:
|
68
|
+
"removes arbitrary elements by ID or className (disabled by default)",
|
69
|
+
removeEmptyAttrs:
|
70
|
+
"removes empty attributes",
|
71
|
+
removeEmptyContainers:
|
72
|
+
"removes empty container elements",
|
73
|
+
removeEmptyText:
|
74
|
+
"removes empty <text> elements",
|
75
|
+
removeHiddenElems:
|
76
|
+
"removes hidden elements (zero sized, with absent attributes)",
|
77
|
+
removeMetadata:
|
78
|
+
"removes <metadata>",
|
79
|
+
removeNonInheritableGroupAttrs:
|
80
|
+
"removes non-inheritable group’s presentational attributes",
|
81
|
+
removeRasterImages:
|
82
|
+
"removes raster images (disabled by default)",
|
83
|
+
removeScriptElement:
|
84
|
+
"removes <script> elements (disabled by default)",
|
85
|
+
removeStyleElement:
|
86
|
+
"removes <style> element (disabled by default)",
|
87
|
+
removeTitle:
|
88
|
+
"removes <title>",
|
89
|
+
removeUnknownsAndDefaults:
|
90
|
+
"removes unknown elements content and attributes, removes attrs with default values",
|
91
|
+
removeUnusedNS:
|
92
|
+
"removes unused namespaces declaration",
|
93
|
+
removeUselessDefs:
|
94
|
+
"removes elements in <defs> without id",
|
95
|
+
removeUselessStrokeAndFill:
|
96
|
+
"removes useless stroke and fill attributes",
|
97
|
+
removeViewBox:
|
98
|
+
"removes viewBox attribute when possible",
|
99
|
+
removeXMLNS:
|
100
|
+
"removes xmlns attribute (for inline svg, disabled by default)",
|
101
|
+
removeXMLProcInst:
|
102
|
+
"removes XML processing instructions",
|
103
|
+
sortAttrs:
|
104
|
+
"sorts element attributes (disabled by default)"
|
105
|
+
}
|
106
|
+
|
107
|
+
options.plugins = Hash[
|
108
|
+
plugins.map { |k, str| [k, !str.include?("disabled by default")]}
|
109
|
+
]
|
110
|
+
parser = OptionParser.new do |opts|
|
111
|
+
opts.banner = "Usage: svgo-ruby [options] [input file]"
|
112
|
+
opts.separator ""
|
113
|
+
opts.separator "Specific options:"
|
114
|
+
#opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
|
115
|
+
# options.verbose = v
|
116
|
+
#end
|
117
|
+
opts.on("-o", "--out [file]", String, "Output file.") do |file|
|
118
|
+
output_file = file
|
119
|
+
end
|
120
|
+
opts.on("-p", "--precision [1..9]", Integer,
|
121
|
+
"Number between 1 and 9, the amount of decimals in path coordinates." \
|
122
|
+
"Set this to the highest number that makes no visual difference for " \
|
123
|
+
"your SVGs. (default=7)"
|
124
|
+
) do |precision|
|
125
|
+
unless precision.between? 1, 9
|
126
|
+
puts "Invalid precision, should be in range 1 - 9."
|
127
|
+
exit 2
|
128
|
+
end
|
129
|
+
options.floatPrecision = precision
|
130
|
+
end
|
131
|
+
opts.on_tail("--version", "Show version") do
|
132
|
+
puts SvgoVersion::VERSION
|
133
|
+
exit
|
134
|
+
end
|
135
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
136
|
+
puts opts
|
137
|
+
exit
|
138
|
+
end
|
139
|
+
opts.on("--[no-]pretty", "Pretty print SVG.") do |state|
|
140
|
+
options.js2svg.pretty = state
|
141
|
+
end
|
142
|
+
opts.on(
|
143
|
+
"--[no-]multi-pass",
|
144
|
+
"Try to optimize multiple times, maximum of 10 times, or until there " \
|
145
|
+
"is no size difference.") do |state|
|
146
|
+
options.multipass = state
|
147
|
+
end
|
148
|
+
opts.separator ""
|
149
|
+
opts.separator "Enabling/disabling plugins:"
|
150
|
+
plugins.each do |p, desc|
|
151
|
+
opts.on("--[no-]#{p}", desc) do |state|
|
152
|
+
options.plugins[p.to_sym] = state
|
153
|
+
end
|
154
|
+
end
|
155
|
+
opts.on("--removeAttrs", String, %q(
|
156
|
+
A comma separated list of Javascript compatible regular expressions.
|
157
|
+
The format described in the plugin:
|
158
|
+
|
159
|
+
[element]:([attribute]|[attribute])
|
160
|
+
|
161
|
+
Elements and attributes should be separated by a colon.
|
162
|
+
|
163
|
+
examples:
|
164
|
+
|
165
|
+
.*:id
|
166
|
+
|
167
|
+
path:(id|stroke)
|
168
|
+
|
169
|
+
fill
|
170
|
+
|
171
|
+
path:(id|stroke), fill
|
172
|
+
|
173
|
+
To get an idea of what should happen imagine your expressions wrapped in:
|
174
|
+
|
175
|
+
^<expression>$
|
176
|
+
|
177
|
+
Eg:
|
178
|
+
|
179
|
+
^.*$:^(stroke|path)$
|
180
|
+
|
181
|
+
For more information on the format see:
|
182
|
+
https://github.com/svg/svgo/blob/master/plugins/removeAttrs.js
|
183
|
+
).sub(/^\n\s+/,'').gsub(/ {4}/, " " * 12)) do |plugin_args|
|
184
|
+
patterns = plugin_args.sub(/\s*,\s*/, ",").split(",")
|
185
|
+
options.plugins.removeAttrs = patterns
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
parser.parse!
|
190
|
+
|
191
|
+
svgo = SvgOptimizer.new(options)
|
192
|
+
|
193
|
+
# Read from stdin..
|
194
|
+
unless STDIN.tty? and not STDIN.closed?
|
195
|
+
input_data = ARGF.read
|
196
|
+
result = svgo.optimize(input_data)
|
197
|
+
else
|
198
|
+
# See if there is an input file name
|
199
|
+
input_file = ARGV.pop
|
200
|
+
unless input_file
|
201
|
+
puts "No input file specified."
|
202
|
+
puts parser.banner
|
203
|
+
exit 2
|
204
|
+
else
|
205
|
+
result = svgo.optimize_file(input_file)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
if result['errors'].length > 0
|
210
|
+
if result['errors'].length > 1
|
211
|
+
puts %Q(Errors occurred: \n - #{result['errors'].join("\n - s")})
|
212
|
+
else
|
213
|
+
puts "An error occurred: #{result['errors'][0]}"
|
214
|
+
end
|
215
|
+
exit(1)
|
216
|
+
end
|
217
|
+
|
218
|
+
unless output_file
|
219
|
+
puts result['data']
|
220
|
+
else
|
221
|
+
File.new(output_file, 'w').write(result['data'])
|
222
|
+
end
|
223
|
+
|
224
|
+
|