Add filter to shrink SVG icons using scour.
authorNick Bowler <nbowler@draconx.ca>
Sat, 20 Feb 2021 19:41:45 +0000 (14:41 -0500)
committerNick Bowler <nbowler@draconx.ca>
Sat, 20 Feb 2021 19:46:16 +0000 (14:46 -0500)
This reduces the uncompressed size of these images by about 2/3, and
the compressed size by about half, which seems pretty significant.

Rules
lib/scour.rb [new file with mode: 0644]
nanoc.yaml

diff --git a/Rules b/Rules
index 7a9773bca3925ff817f42e72df2d744e801dcba4..43f27a4e15784bf8c278d23da8bdac4dc0145049 100644 (file)
--- a/Rules
+++ b/Rules
@@ -210,6 +210,11 @@ compile '/**/*.scss' do
     write @item.identifier.without_ext + '.css'
 end
 
+compile '/**/*.svg' do
+    filter :scour, comment_stripping: true
+    write @item.identifier.to_s
+end
+
 compile '/**/*' do
     filter :copybin if @item.binary?
     write @item.identifier.to_s
diff --git a/lib/scour.rb b/lib/scour.rb
new file mode 100644 (file)
index 0000000..c84104e
--- /dev/null
@@ -0,0 +1,57 @@
+# Nick's web site: scour filter.  Run scour to reduce the size of SVG images.
+#
+# Copyright © 2021 Nick Bowler
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+class ScourFilter < Nanoc::Filter
+    identifier :scour
+
+    def run(content, params = {})
+        defaults = { quiet: true, id_stripping: true, shorten_ids: true }
+        args = []
+        defaults.merge(params).each do |key, val|
+            prefix = nil
+
+            # Normalize some argument names for consistency
+            case key
+            when :comment_stripping, :viewboxing, :id_stripping
+                prefix = :enable
+            when :simplify_colors, :style_to_xml, :group_collapsing,
+                 :embed_rasters
+                prefix = :disable
+            when :renderer_workaround, :line_breaks
+                prefix = :no if not val
+            end
+
+            # scour does not generally have inverse options, so drop
+            # some nonsense combinations.
+            next if val and prefix == :disable
+            next if val and key == :line_breaks
+            next if !val
+
+            arg = "--"
+            if prefix then arg << "#{prefix}-" end
+            arg << key.to_s.gsub("_", "-")
+            if val != true then arg << "=#{val}" end
+
+            args << arg
+        end
+
+        content, status = Open3.capture2("scour", *args, stdin_data: content)
+        raise "scour failed" if status != 0
+
+        return content
+    end
+end
index ef514bc045e8ae75cdfe740fddae3286bc9cd4cc..679b8de1472c6e144598e0fd0d1f0874b1fb5fbb 100644 (file)
@@ -14,7 +14,7 @@ text_extensions: [ 'adoc', 'asciidoc', 'atom',
                    'markdown', 'md', 'ms', 'mustache',
                    'php',
                    'rb', 'rdoc',
-                   'sass', 'scss', 'sgml', 'slim',
+                   'sass', 'scss', 'sgml', 'slim', 'svg',
                    'txt',
                    'xhtml', 'xml', 'xsl' ]