aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/_clean_attrs.sed135
-rw-r--r--tools/_clean_style_attr.sed217
-rwxr-xr-xtools/_scour.sh47
-rw-r--r--tools/_svgo.yml126
-rwxr-xr-xtools/ffsvg.sh78
5 files changed, 603 insertions, 0 deletions
diff --git a/tools/_clean_attrs.sed b/tools/_clean_attrs.sed
new file mode 100644
index 000000000..d6ccedea6
--- /dev/null
+++ b/tools/_clean_attrs.sed
@@ -0,0 +1,135 @@
+#!/bin/sed -rf
+#
+# Written in 2016 by Sergei Eremenko <https://github.com/SmartFinn>
+#
+# To the extent possible under law, the author(s) have dedicated all copyright
+# and related and neighboring rights to this software to the public domain
+# worldwide. This software is distributed without any warranty.
+#
+# You should have received a copy of the CC0 Public Domain Dedication along
+# with this software. If not, see
+# <http://creativecommons.org/publicdomain/zero/1.0/>.
+#
+# Description:
+# This script removes unused attributes and removes attributes with default
+# values from elements.
+# Details https://www.w3.org/TR/SVG/attindex.html
+#
+# Get defaults from Inkscape:
+# sed -e '/^$/d' -e '/NO.DEFAULT/d' -e 's/"//g' \
+# /usr/share/inkscape/attributes/css_defaults \
+# | awk -F" - " '{printf "s/[ ]%s=\"%s\"//gI\n", $1,$2}'
+#
+# Usage:
+# sed -r -i -f _clean_attrs.sed FILE...
+
+# remove unused attributes
+s/[ ]aria-label="[^"]*"//gI
+
+# delete default ids
+s/[ ]id="circle[0-9][^ ]*"//gI
+s/[ ]id="defs[0-9][^ ]*"//gI
+s/[ ]id="g[0-9][^ ]*"//gI
+s/[ ]id="path[0-9][^ ]*"//gI
+s/[ ]id="rect[0-9][^ ]*"//gI
+s/[ ]id="svg[0-9][^ ]*"//gI
+
+# properties in a style attribute has higher priority
+/style=/ {
+ /fill:[^;"]/ s/[ ]fill="[^"]+"//gI
+ /[^-]opacity:[^;"]/ s/[ ]opacity="[^"]+"//gI
+}
+
+# remove attributes with default values
+s/[ ]alignment-baseline="auto"//gI
+s/[ ]backface-visibility="visible"//gI
+s/[ ]baseline-shift="baseline"//gI
+s/[ ]clip="auto"//gI
+s/[ ]clip-path="none"//gI
+s/[ ]clip-rule="nonzero"//gI
+s/[ ]color-interpolation="sRGB"//gI
+s/[ ]color-interpolation-filters="linearRGB"//gI
+s/[ ]color-profile="auto"//gI
+s/[ ]color-rendering="auto"//gI
+s/[ ]cursor="auto"//gI
+s/[ ]direction="ltr"//gI
+s/[ ]display="inline"//gI
+s/[ ]dominant-baseline="auto"//gI
+s/[ ]enable-background="accumulate"//gI
+s/[ ]fill="black"//gI
+s/[ ]fill-opacity="1"//gI
+s/[ ]fill-rule="nonzero"//gI
+s/[ ]filter="none"//gI
+s/[ ]flood-color="black"//gI
+s/[ ]flood-opacity="1"//gI
+s/[ ]font-feature-settings="normal"//gI
+s/[ ]font-size="medium"//gI
+s/[ ]font-size-adjust="none"//gI
+s/[ ]font-stretch="normal"//gI
+s/[ ]font-style="normal"//gI
+s/[ ]font-variant="normal"//gI
+s/[ ]font-variant-alternates="normal"//gI
+s/[ ]font-variant-caps="normal"//gI
+s/[ ]font-variant-east-asian="normal"//gI
+s/[ ]font-variant-ligatures="normal"//gI
+s/[ ]font-variant-numeric="normal"//gI
+s/[ ]font-variant-position="normal"//gI
+s/[ ]font-weight="normal"//gI
+s/[ ]glyph-orientation-horizontal="0deg"//gI
+s/[ ]glyph-orientation-vertical="auto"//gI
+s/[ ]image-rendering="auto"//gI
+s/[ ]isolation="auto"//gI
+s/[ ]kerning="auto"//gI
+s/[ ]letter-spacing="normal"//gI
+s/[ ]lighting-color="white"//gI
+s/[ ]marker="none"//gI
+s/[ ]marker-end="none"//gI
+s/[ ]marker-mid="none"//gI
+s/[ ]marker-start="none"//gI
+s/[ ]mask="none"//gI
+s/[ ]mix-blend-mode="normal"//gI
+s/[ ]opacity="1"//gI
+s/[ ]overflow="hidden"//gI
+s/[ ]paint-order="normal"//gI
+s/[ ]perspective="none"//gI
+s/[ ]pointer-events="visiblePainted"//gI
+s/[ ]shape-inside="auto"//gI
+s/[ ]shape-margin="0"//gI
+s/[ ]shape-outside="auto"//gI
+s/[ ]shape-padding="none"//gI
+s/[ ]shape-rendering="auto"//gI
+s/[ ]solid-color="#000000"//gI
+s/[ ]solid-opacity="1"//gI
+s/[ ]stop-color="black"//gI
+s/[ ]stop-opacity="1"//gI
+s/[ ]stroke="none"//gI
+s/[ ]stroke-dasharray="none"//gI
+s/[ ]stroke-dashoffset="0"//gI
+s/[ ]stroke-linecap="butt"//gI
+s/[ ]stroke-linejoin="miter"//gI
+s/[ ]stroke-miterlimit="4"//gI
+s/[ ]stroke-opacity="1"//gI
+s/[ ]stroke-width="1"//gI
+s/[ ]text-align="start"//gI
+s/[ ]text-anchor="start"//gI
+s/[ ]text-decoration-line="none"//gI
+s/[ ]text-decoration-style="solid"//gI
+s/[ ]text-indent="0"//gI
+s/[ ]text-orientation="mixed"//gI
+s/[ ]text-rendering="auto"//gI
+s/[ ]text-transform="none"//gI
+s/[ ]transform="none"//gI
+s/[ ]transform-style="flat"//gI
+s/[ ]unicode-bidi="normal"//gI
+s/[ ]visibility="visible"//gI
+s/[ ]white-space="normal"//gI
+s/[ ]word-spacing="normal"//gI
+s/[ ]writing-mode="lr-tb"//gI
+
+# delete attributes with nonsense values
+s/[ ]fill-opacity="[1-9][0-9.]*"//gI
+s/[ ]fill="(#000|#000000|black)"//gI
+s/[ ]flood-color="(#000|#000000|black)"//gI
+s/[ ]flood-opacity="[1-9][0-9.]*"//gI
+s/[ ]opacity="[1-9][0-9.]*"//gI
+s/[ ]stroke-opacity="[1-9][0-9.]*"//gI
diff --git a/tools/_clean_style_attr.sed b/tools/_clean_style_attr.sed
new file mode 100644
index 000000000..85483a510
--- /dev/null
+++ b/tools/_clean_style_attr.sed
@@ -0,0 +1,217 @@
+#!/bin/sed -rf
+#
+# Written in 2016 by Sergei Eremenko <https://github.com/SmartFinn>
+#
+# To the extent possible under law, the author(s) have dedicated all copyright
+# and related and neighboring rights to this software to the public domain
+# worldwide. This software is distributed without any warranty.
+#
+# You should have received a copy of the CC0 Public Domain Dedication along
+# with this software. If not, see
+# <http://creativecommons.org/publicdomain/zero/1.0/>.
+#
+# Description:
+# This script removes unused properties and removes properties with default
+# values from style attributes.
+# Details https://www.w3.org/TR/SVG/styling.html
+#
+# Get CSS defaults from Inkscape:
+# sed -e '/^$/d' -e '/NO.DEFAULT/d' -e 's/"//g' \
+# /usr/share/inkscape/attributes/css_defaults \
+# | awk -F" - " '{printf "s/%s:%s;//gI\n", $1,$2}'
+#
+# Usage:
+# sed -r -i -f _clean_style_attr.sed FILE...
+
+/style=/ {
+
+ # add a trailing semicolon for secure matching
+ s/style="([^"]+[^;])"/style="\1;"/gI
+
+ # delete properties with default values
+ s/alignment-baseline:auto;//gI
+ s/backface-visibility:visible;//gI
+ s/baseline-shift:baseline;//gI
+ s/block-progression:tb;//gI
+ s/clip:auto;//gI
+ s/clip-path:none;//gI
+ s/clip-rule:nonzero;//gI
+ s/color-interpolation:sRGB;//gI
+ s/color-interpolation-filters:linearRGB;//gI
+ s/color-profile:auto;//gI
+ s/color-rendering:auto;//gI
+ s/cursor:auto;//gI
+ s/direction:ltr;//gI
+ s/display:inline;//gI
+ s/dominant-baseline:auto;//gI
+ s/enable-background:accumulate;//gI
+ s/fill:black;//gI
+ s/fill-opacity:1;//gI
+ s/fill-rule:nonzero;//gI
+ s/filter:none;//gI
+ s/flood-color:black;//gI
+ s/flood-opacity:1;//gI
+ s/font-feature-settings:normal;//gI
+ s/font-size:medium;//gI
+ s/font-size-adjust:none;//gI
+ s/font-stretch:normal;//gI
+ s/font-style:normal;//gI
+ s/font-variant:normal;//gI
+ s/font-variant-alternates:normal;//gI
+ s/font-variant-caps:normal;//gI
+ s/font-variant-east-asian:normal;//gI
+ s/font-variant-ligatures:normal;//gI
+ s/font-variant-numeric:normal;//gI
+ s/font-variant-position:normal;//gI
+ s/font-weight:normal;//gI
+ s/glyph-orientation-horizontal:0deg;//gI
+ s/glyph-orientation-vertical:auto;//gI
+ s/image-rendering:auto;//gI
+ s/isolation:auto;//gI
+ s/kerning:auto;//gI
+ s/letter-spacing:normal;//gI
+ s/lighting-color:white;//gI
+ s/marker:none;//gI
+ s/marker-end:none;//gI
+ s/marker-mid:none;//gI
+ s/marker-start:none;//gI
+ s/mask:none;//gI
+ s/mix-blend-mode:normal;//gI
+ s/([^-])opacity:1;/\1/gI
+ s/overflow:hidden;//gI
+ s/paint-order:normal;//gI
+ s/perspective:none;//gI
+ s/pointer-events:visiblePainted;//gI
+ s/shape-inside:auto;//gI
+ s/shape-margin:0;//gI
+ s/shape-outside:auto;//gI
+ s/shape-padding:none;//gI
+ s/shape-rendering:auto;//gI
+ s/solid-color:#000000;//gI
+ s/solid-opacity:1;//gI
+ s/stop-color:black;//gI
+ s/stop-opacity:1;//gI
+ s/stroke:none;//gI
+ s/stroke-dasharray:none;//gI
+ s/stroke-dashoffset:0;//gI
+ s/stroke-linecap:butt;//gI
+ s/stroke-linejoin:miter;//gI
+ s/stroke-miterlimit:4;//gI
+ s/stroke-opacity:1;//gI
+ s/stroke-width:1;//gI
+ s/text-align:start;//gI
+ s/text-anchor:start;//gI
+ s/text-decoration-line:none;//gI
+ s/text-decoration-style:solid;//gI
+ s/text-decoration:none;//gI
+ s/text-indent:0;//gI
+ s/text-orientation:mixed;//gI
+ s/text-rendering:auto;//gI
+ s/text-transform:none;//gI
+ s/transform:none;//gI
+ s/transform-style:flat;//gI
+ s/unicode-bidi:normal;//gI
+ s/vector-effect:none;//gI
+ s/visibility:visible;//gI
+ s/white-space:normal;//gI
+ s/word-spacing:normal;//gI
+ s/writing-mode:lr-tb;//gI
+
+ # delete properties with nonsense values
+ s/fill-opacity:[1-9][0-9.]*;//gI
+ s/font-family:(sans|sans-serif);//gI
+ s/line-height:normal;//gI
+ s/([^-])opacity:[1-9][0-9.]*;/\1/gI
+ s/overflow:visible;//gI
+ s/shape-padding:0;//gI
+ s/solid-color:(#000|#000000|black);//gI
+ s/solid-opacity:[1-9][0-9.]*;//gI
+ s/stroke-opacity:[1-9][0-9.]*;//gI
+ s/text-decoration-color:(#000|#000000|black|currentColor);//gI
+
+ # delete Inkscape properties
+ /-inkscape-/ {
+ s/-inkscape-[^;"]+;//gI
+ }
+
+ # delete 'fill- *' properties if fill equal none
+ /fill[:=]"?none/ {
+ s/fill-rule:[^;"]+;//gI
+ s/fill-opacity:[^;"]+;//gI
+ }
+
+ # delete a fill property if it has the default value and fill attribute not exist
+ /fill="[^"]/! {
+ s/fill:(#000|#000000|black);//gI
+ }
+
+ # delete a color property if currentColor not exists and fill has a value
+ /currentColor/! {
+ s/([^-])color:[^;"]+;/\1/gI
+ }
+
+ # delete 'stroke- *' properties if an object doesn't have a stroke
+ /stroke[:=]/! {
+ s/stroke-width:[^;"]+;//gI
+ s/stroke-linecap:[^;"]+;//gI
+ s/stroke-linejoin:[^;"]+;//gI
+ s/stroke-miterlimit:[^;"]+;//gI
+ s/stroke-dasharray:[^;"]+;//gI
+ s/stroke-dashoffset:[^;"]+;//gI
+ s/stroke-opacity:[^;"]+;//gI
+ }
+
+ # delete unused properties from non-container elements
+ /<(a|defs|glyph|g|marker|mask|missing-glyph|pattern|svg|switch|symbol|use)/! {
+ s/enable-background:[^;"]+;//gI
+ }
+
+ # delete unused properties from non-text content elements
+ /<(altGlyph|textPath|text|tref|tspan|flowRoot|flowPara|flowSpan|a|defs|glyph|g|marker|mask|missing-glyph|pattern|svg|switch|symbol|use)/! {
+ s/alignment-baseline:[^;"]+;//gI
+ s/baseline-shift:[^;"]+;//gI
+ s/block-progression:[^;"]+;//gI
+ s/direction:[^;"]+;//gI
+ s/dominant-baseline:[^;"]+;//gI
+ s/font:[^;"]+;//gI
+ s/font-family:[^;"]+;//gI
+ s/font-feature-settings:[^;"]+;//gI
+ s/font-size-adjust:[^;"]+;//gI
+ s/font-size:[^;"]+;//gI
+ s/font-stretch:[^;"]+;//gI
+ s/font-style:[^;"]+;//gI
+ s/font-variant-alternates:[^;"]+;//gI
+ s/font-variant-caps:[^;"]+;//gI
+ s/font-variant-ligatures:[^;"]+;//gI
+ s/font-variant-numeric:[^;"]+;//gI
+ s/font-variant-position:[^;"]+;//gI
+ s/font-variant:[^;"]+;//gI
+ s/font-weight:[^;"]+;//gI
+ s/glyph-orientation-horizontal:[^;"]+;//gI
+ s/glyph-orientation-vertical:[^;"]+;//gI
+ s/kerning:[^;"]+;//gI
+ s/letter-spacing:[^;"]+;//gI
+ s/line-height:[^;"]+;//gI
+ s/text-align:[^;"]+;//gI
+ s/text-anchor:[^;"]+;//gI
+ s/text-decoration-color:[^;"]+;//gI
+ s/text-decoration-line:[^;"]+;//gI
+ s/text-decoration-style:[^;"]+;//gI
+ s/text-decoration:[^;"]+;//gI
+ s/text-indent:[^;"]+;//gI
+ s/text-orientation:[^;"]+;//gI
+ s/text-transform:[^;"]+;//gI
+ s/unicode-bidi:[^;"]+;//gI
+ s/word-spacing:[^;"]+;//gI
+ s/writing-mode:[^;"]+;//gI
+ }
+
+ # replace 2 and more semicolons by one
+ s/;{2,}/;/g
+
+ # delete trailing semicolon
+ s/;+"/"/g
+
+ # delete style attribute if it's empty
+ s/[[:space:]]?style=""//g
+}
diff --git a/tools/_scour.sh b/tools/_scour.sh
new file mode 100755
index 000000000..16d53b720
--- /dev/null
+++ b/tools/_scour.sh
@@ -0,0 +1,47 @@
+#!/bin/sh
+#
+# Written in 2016 by Sergei Eremenko <https://github.com/SmartFinn>
+#
+# To the extent possible under law, the author(s) have dedicated all copyright
+# and related and neighboring rights to this software to the public domain
+# worldwide. This software is distributed without any warranty.
+#
+# You should have received a copy of the CC0 Public Domain Dedication along
+# with this software. If not, see
+# <http://creativecommons.org/publicdomain/zero/1.0/>.
+#
+# Description:
+# This script removes unused attributes and removes attributes with default
+# values from elements.
+# More details https://www.w3.org/TR/SVG/attindex.html
+#
+# Usage:
+# _clean_attrs.sh FILE...
+
+set -e
+
+for i in "$@"; do
+ if [ -f "$i" ] && [ ! -L "$i" ]; then
+ # is a file and is not a symlink
+
+ # continue if an extension is svg
+ [ "${i##*.}" = "svg" ] || continue
+
+ scour \
+ --quiet \
+ --disable-simplify-colors \
+ --disable-style-to-xml \
+ --enable-id-stripping \
+ --remove-metadata \
+ --renderer-workaround \
+ --strip-xml-prolog \
+ --set-precision=8 \
+ --strip-xml-space \
+ -i "$i" -o "$i".tmp
+
+ # rename
+ mv -f "$i".tmp "$i"
+ else
+ continue
+ fi
+done
diff --git a/tools/_svgo.yml b/tools/_svgo.yml
new file mode 100644
index 000000000..635dba262
--- /dev/null
+++ b/tools/_svgo.yml
@@ -0,0 +1,126 @@
+# Default config for SVGO
+#
+# Usage:
+#
+# for d in Papirus/16x16/* Papirus/22x22/* Papirus/24x24/*
+# do
+# svgo --config=_svgo.yml -f "$d"
+# done
+#
+# or
+#
+# svgo --config=_svgo.yml -f Papirus/16x16/actions
+#
+# or
+#
+# svgo --config=_svgo.yml -i FILE
+
+full: true
+multipass: true
+
+plugins:
+
+ # removes doctype declaration
+ - removeDoctype
+
+ # removes XML processing instructions
+ - removeXMLProcInst
+
+ # removes comments
+ - removeComments
+
+ # removes <metadata>
+ - removeMetadata
+
+ # removes editors namespaces, elements and attributes
+ - removeEditorsNSData
+
+ # cleanups attributes from newlines, trailing and repeating spaces
+ - cleanupAttrs
+
+ # removes unused IDs
+ - cleanupIDs:
+ minify: false
+ preserve: [ 'current-color-scheme' ]
+
+ # removes elements in <defs> without id
+ - removeUselessDefs
+
+ # rounds numeric values to the fixed precision
+ # opacity="0.72000004" --> opactity=".72"
+ # removes default ‘px’ units
+ # y="749.936002px" --> y="749.936"
+ - cleanupNumericValues:
+ floatPrecision: 3
+ leadingZero: true
+ defaultPx: true
+ convertToPx: false
+
+ # rounds list of values to the fixed precision
+ # viewBox="0 0 16px 16px" --> viewBox="0 0 16 16"
+ - cleanupListOfValues:
+ floatPrecision: 2
+ leadingZero: true
+ defaultPx: true
+ convertToPx: false
+
+ # converts colors: rgb() to #rrggbb
+ - convertColors:
+ shorthex: false
+ shortname: false
+
+ # removes unknown elements content and attributes
+ # don't touch attrs with default values
+ # - removeUnknownsAndDefaults:
+ # defaultAttrs: false
+
+ # remove or cleanup enable-background attribute when possible
+ - cleanupEnableBackground
+
+ # removes empty <text> elements
+ - removeEmptyText
+
+ # removes empty attributes
+ - removeEmptyAttrs
+
+ # removes empty container elements
+ - removeEmptyContainers
+
+ # removes unused namespaces declaration
+ - removeUnusedNS
+
+ # sorts element attributes (disabled by default)
+ - sortAttrs:
+ order:
+ - 'id'
+ - 'fill'
+ - 'stroke'
+ - 'opacity'
+ - 'style'
+ - 'class'
+ - 'width'
+ - 'height'
+ - 'x'
+ - 'x1'
+ - 'x2'
+ - 'y'
+ - 'y1'
+ - 'y2'
+ - 'cx'
+ - 'cy'
+ - 'r'
+ - 'd'
+
+ # removes <title> (disabled by default)
+ - removeTitle: true
+
+ # removes <desc> (only non-meaningful by default)
+ - removeDesc
+
+# configure the indent (default 4 spaces) used by `--pretty` here:
+#
+# @see https://github.com/svg/svgo/blob/master/lib/svgo/js2svg.js#L6 for more config options
+#
+js2svg:
+ pretty: true
+ indent: ' '
diff --git a/tools/ffsvg.sh b/tools/ffsvg.sh
new file mode 100755
index 000000000..02f6a631b
--- /dev/null
+++ b/tools/ffsvg.sh
@@ -0,0 +1,78 @@
+#!/bin/sh
+#
+# Written in 2016 by Sergei Eremenko <https://github.com/SmartFinn>
+#
+# To the extent possible under law, the author(s) have dedicated all copyright
+# and related and neighboring rights to this software to the public domain
+# worldwide. This software is distributed without any warranty.
+#
+# You should have received a copy of the CC0 Public Domain Dedication along
+# with this software. If not, see
+# <http://creativecommons.org/publicdomain/zero/1.0/>.
+#
+# Description:
+# This script finds, fixes and cleans SVG files.
+#
+# Usage:
+# ffsvg.sh PATH...
+
+set -e
+
+SCRIPT_DIR=$(dirname "$0")
+
+_run_helpers() {
+ echo "=> Working on '$1' ..." >&2
+
+ # optimize a SVG
+ if command -v svgo > /dev/null 2>&1; then
+ # use SVGO
+ svgo --config="$SCRIPT_DIR/_svgo.yml" -i "$1"
+ elif command -v scour > /dev/null 2>&1; then
+ # use scour
+ "$SCRIPT_DIR/_scour.sh" "$1"
+ else
+ cat <<-'EOF'
+
+ You should have installed svgo or scour to use this script.
+
+ sudo apt-get install python-scour
+
+ EOF
+
+ exit 1
+ fi
+
+ # fix a color scheme
+ #"$SCRIPT_DIR/_fix_color_scheme.sh" "$1"
+
+ # clear attributes
+ sed -r -i -f "$SCRIPT_DIR/_clean_attrs.sed" "$1"
+
+ # clear a style attribute
+ sed -r -i -f "$SCRIPT_DIR/_clean_style_attr.sed" "$1"
+}
+
+for i in "$@"; do
+ if [ -d "$i" ]; then
+ # is a directory
+
+ echo "=> Directory '$i' will be processed." >&2
+ echo " Press <CTRL-C> to abort (wait 1 seconds) ..." >&2
+
+ sleep 1
+
+ # process all SVG files w/o symlinks
+ find "$i" -type f -name '*.svg' | while read -r file; do
+ _run_helpers "$file"
+ done
+ elif [ -f "$i" ] && [ ! -L "$i" ]; then
+ # is a file and is not a symlink
+
+ # continue if an extension is svg
+ [ "${i##*.}" = "svg" ] || continue
+
+ _run_helpers "$i"
+ else
+ continue
+ fi
+done