Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

svgo --precision #211

Merged
merged 4 commits into from
Nov 17, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## unreleased

* Added `svgo-allow-lossy` and `svgo-precision` options to use svgo in lossy mode. This sets svgo `precision`, which can result in substantially smaller svgs. Lower values are more lossy. 3 is the default, but many SVGs will work well even with 0 or 1. [#210] [@gurgeous](https://github.com/gurgeous)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is better to use complete option names --svgo-precision, also I assume default is to use global --allow-lossy instead of per worker --xxx-allow-lossy.
And please create complete link to #210, so it works even outside of github and please add a link to this PR too.


## v0.31.3 (2023-02-17)

* Support Psych4/Ruby 3.1 changes to use safe_yaml methods by default [#203](https://github.com/toy/image_optim/issues/203) [#204](https://github.com/toy/image_optim/pull/204) [@oscillot](https://github.com/oscillot) [@toy](https://github.com/toy)
Expand Down
20 changes: 20 additions & 0 deletions lib/image_optim/worker/svgo.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# frozen_string_literal: true

require 'image_optim/option_helpers'
require 'image_optim/worker'

class ImageOptim
Expand All @@ -16,6 +17,24 @@ class Svgo < Worker
Array(v).map(&:to_s)
end

ALLOW_LOSSY_OPTION =
option(:allow_lossy, false, 'Allow precision option'){ |v| !!v }

PRECISION_OPTION =
option(:precision, 3, 'number of digits in the fractional part ' \
'`0`..`10`, ignored in default/lossless mode') \
do |v, opt_def|
if allow_lossy
OptionHelpers.limit_with_range(v.to_i, 0..10)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

svgo allows precision to be from 0 to 20. I'm wondering why are negative numbers forbidden (to round integer part), but that is a question to svgo.

else
if v != opt_def.default
warn "#{self.class.bin_sym} #{opt_def.name} #{v} ignored " \
'in default/lossless mode'
end
opt_def.default
end
end

def optimize(src, dst, options = {})
args = %W[
--input #{src}
Expand All @@ -27,6 +46,7 @@ def optimize(src, dst, options = {})
enable_plugins.each do |plugin_name|
args.unshift "--enable=#{plugin_name}"
end
args.unshift "--precision=#{precision}" if allow_lossy
execute(:svgo, args, options) && optimized?(src, dst)
end
end
Expand Down
53 changes: 53 additions & 0 deletions spec/image_optim/worker/svgo_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# frozen_string_literal: true

require 'spec_helper'
require 'image_optim/worker/svgo'

describe ImageOptim::Worker::Svgo do
describe 'precision option' do
describe 'default' do
subject{ described_class::PRECISION_OPTION.default }

it{ is_expected.to eq(3) }
end

describe 'value' do
let(:subject){ described_class.new(ImageOptim.new, options).precision }

context 'when lossy not allowed' do
context 'by default' do
let(:options){ {} }

it{ is_expected.to eq(3) }
end

context 'when value is passed through options' do
let(:options){ {precision: 5} }

it 'warns and keeps default' do
expect_any_instance_of(described_class).
to receive(:warn).with(%r{ignored in default/lossless mode})
is_expected.to eq(3)
end
end
end

context 'when lossy allowed' do
context 'by default' do
let(:options){ {allow_lossy: true} }

it{ is_expected.to eq(3) }
end

context 'when value is passed through options' do
let(:options){ {allow_lossy: true, precision: 5} }

it 'sets the value without warning' do
expect_any_instance_of(described_class).not_to receive(:warn)
is_expected.to eq(5)
end
end
end
end
end
end