Added inkscape extension files
This commit is contained in:
parent
96d9edad78
commit
94a1e28a57
7 changed files with 199 additions and 4 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
SCOURVER="0.17"
|
SCOURVER="0.18"
|
||||||
cd ..
|
cd ..
|
||||||
tar cvf scour/tarballs/scour-$SCOURVER.tar scour/scour.py scour/svg_regex.py scour/LICENSE scour/NOTICE scour/README.txt scour/release-notes.html
|
tar cvf scour/tarballs/scour-$SCOURVER.tar scour/scour.py scour/svg_regex.py scour/LICENSE scour/NOTICE scour/README.txt scour/release-notes.html
|
||||||
gzip scour/tarballs/scour-$SCOURVER.tar
|
gzip scour/tarballs/scour-$SCOURVER.tar
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,16 @@
|
||||||
|
|
||||||
<p>Copyright 2009, Jeff Schiller</p>
|
<p>Copyright 2009, Jeff Schiller</p>
|
||||||
|
|
||||||
|
<section id="0.18">
|
||||||
|
<header>
|
||||||
|
<h2><a href="#0.18">Version 0.18</a></h2>
|
||||||
|
</header>
|
||||||
|
<p>Aug 3rd, 2009</p>
|
||||||
|
<ul>
|
||||||
|
<li>Remove attributes of gradients if they contain default values</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
<section id="0.17">
|
<section id="0.17">
|
||||||
<header>
|
<header>
|
||||||
<h2><a href="#0.17">Version 0.17</a></h2>
|
<h2><a href="#0.17">Version 0.17</a></h2>
|
||||||
|
|
|
||||||
8
scour.inkscape.py
Executable file
8
scour.inkscape.py
Executable file
|
|
@ -0,0 +1,8 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import sys
|
||||||
|
from scour import scourString
|
||||||
|
input = file(sys.argv[1], "r")
|
||||||
|
sys.stdout.write(scourString(input.read()).encode("UTF-8"))
|
||||||
|
input.close()
|
||||||
|
sys.stdout.close()
|
||||||
16
scour.inx
Normal file
16
scour.inx
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
||||||
|
<_name>Scoured SVG Output</_name>
|
||||||
|
<id>org.inkscape.output.scour</id>
|
||||||
|
<dependency type="executable" location="extensions">scour.py</dependency>
|
||||||
|
<dependency type="executable" location="extensions">svg_regex.py</dependency>
|
||||||
|
<output>
|
||||||
|
<extension>.svg</extension>
|
||||||
|
<mimetype>image/svg+xml</mimetype>
|
||||||
|
<_filetypename>Scoured SVG (*.svg)</_filetypename>
|
||||||
|
<_filetypetooltip>Scalable Vector Graphics</_filetypetooltip>
|
||||||
|
</output>
|
||||||
|
<script>
|
||||||
|
<command reldir="extensions" interpreter="python">scour.inkscape.py</command>
|
||||||
|
</script>
|
||||||
|
</inkscape-extension>
|
||||||
86
scour.py
86
scour.py
|
|
@ -59,6 +59,7 @@
|
||||||
# This would require my own serialization of the DOM objects (not impossible)
|
# This would require my own serialization of the DOM objects (not impossible)
|
||||||
|
|
||||||
# Next Up:
|
# Next Up:
|
||||||
|
# - add an option for svgweb compatible markup (no self-closing tags)?
|
||||||
# - if a <g> has only one element in it, collapse the <g> (ensure transform, etc are carried down)
|
# - if a <g> has only one element in it, collapse the <g> (ensure transform, etc are carried down)
|
||||||
# - remove id if it matches the Inkscape-style of IDs (also provide a switch to disable this)
|
# - remove id if it matches the Inkscape-style of IDs (also provide a switch to disable this)
|
||||||
# - prevent elements from being stripped if they are referenced in a <style> element
|
# - prevent elements from being stripped if they are referenced in a <style> element
|
||||||
|
|
@ -978,6 +979,87 @@ def repairStyle(node, options):
|
||||||
|
|
||||||
return num
|
return num
|
||||||
|
|
||||||
|
def removeDefaultAttributeValues(node, options):
|
||||||
|
num = 0
|
||||||
|
if node.nodeType != 1: return 0
|
||||||
|
|
||||||
|
# gradientUnits: objectBoundingBox
|
||||||
|
if node.getAttribute('gradientUnits') == 'objectBoundingBox':
|
||||||
|
node.removeAttribute('gradientUnits')
|
||||||
|
num += 1
|
||||||
|
|
||||||
|
# spreadMethod: pad
|
||||||
|
if node.getAttribute('spreadMethod') == 'pad':
|
||||||
|
node.removeAttribute('spreadMethod')
|
||||||
|
num += 1
|
||||||
|
|
||||||
|
# x1: 0%
|
||||||
|
if node.getAttribute('x1') != '':
|
||||||
|
x1 = SVGLength(node.getAttribute('x1'))
|
||||||
|
if x1.value == 0:
|
||||||
|
node.removeAttribute('x1')
|
||||||
|
num += 1
|
||||||
|
|
||||||
|
# y1: 0%
|
||||||
|
if node.getAttribute('y1') != '':
|
||||||
|
y1 = SVGLength(node.getAttribute('y1'))
|
||||||
|
if y1.value == 0:
|
||||||
|
node.removeAttribute('y1')
|
||||||
|
num += 1
|
||||||
|
|
||||||
|
# x2: 100%
|
||||||
|
if node.getAttribute('x2') != '':
|
||||||
|
x2 = SVGLength(node.getAttribute('x2'))
|
||||||
|
if (x2.value == 100 and x2.units == Unit.PCT) or (x2.value == 1 and x2.units == Unit.NONE):
|
||||||
|
node.removeAttribute('x2')
|
||||||
|
num += 1
|
||||||
|
|
||||||
|
# y2: 0%
|
||||||
|
if node.getAttribute('y2') != '':
|
||||||
|
y2 = SVGLength(node.getAttribute('y2'))
|
||||||
|
if y2.value == 0:
|
||||||
|
node.removeAttribute('y2')
|
||||||
|
num += 1
|
||||||
|
|
||||||
|
# fx: equal to rx
|
||||||
|
if node.getAttribute('fx') != '':
|
||||||
|
if node.getAttribute('fx') == node.getAttribute('cx'):
|
||||||
|
node.removeAttribute('fx')
|
||||||
|
num += 1
|
||||||
|
|
||||||
|
# fy: equal to ry
|
||||||
|
if node.getAttribute('fy') != '':
|
||||||
|
if node.getAttribute('fy') == node.getAttribute('cy'):
|
||||||
|
node.removeAttribute('fy')
|
||||||
|
num += 1
|
||||||
|
|
||||||
|
# cx: 50%
|
||||||
|
if node.getAttribute('cx') != '':
|
||||||
|
cx = SVGLength(node.getAttribute('cx'))
|
||||||
|
if (cx.value == 50 and cx.units == Unit.PCT) or (cx.value == 0.5 and cx.units == Unit.NONE):
|
||||||
|
node.removeAttribute('cx')
|
||||||
|
num += 1
|
||||||
|
|
||||||
|
# cy: 50%
|
||||||
|
if node.getAttribute('cy') != '':
|
||||||
|
cy = SVGLength(node.getAttribute('cy'))
|
||||||
|
if (cy.value == 50 and cy.units == Unit.PCT) or (cy.value == 0.5 and cy.units == Unit.NONE):
|
||||||
|
node.removeAttribute('cy')
|
||||||
|
num += 1
|
||||||
|
|
||||||
|
# r: 50%
|
||||||
|
if node.getAttribute('r') != '':
|
||||||
|
r = SVGLength(node.getAttribute('r'))
|
||||||
|
if (r.value == 50 and r.units == Unit.PCT) or (r.value == 0.5 and r.units == Unit.NONE):
|
||||||
|
node.removeAttribute('r')
|
||||||
|
num += 1
|
||||||
|
|
||||||
|
# recurse for our child elements
|
||||||
|
for child in node.childNodes :
|
||||||
|
num += removeDefaultAttributeValues(child,options)
|
||||||
|
|
||||||
|
return num
|
||||||
|
|
||||||
rgb = re.compile("\\s*rgb\\(\\s*(\\d+)\\s*\\,\\s*(\\d+)\\s*\\,\\s*(\\d+)\\s*\\)\\s*")
|
rgb = re.compile("\\s*rgb\\(\\s*(\\d+)\\s*\\,\\s*(\\d+)\\s*\\,\\s*(\\d+)\\s*\\)\\s*")
|
||||||
rgbp = re.compile("\\s*rgb\\(\\s*(\\d*\\.?\\d+)\\%\\s*\\,\\s*(\\d*\\.?\\d+)\\%\\s*\\,\\s*(\\d*\\.?\\d+)\\%\\s*\\)\\s*")
|
rgbp = re.compile("\\s*rgb\\(\\s*(\\d*\\.?\\d+)\\%\\s*\\,\\s*(\\d*\\.?\\d+)\\%\\s*\\,\\s*(\\d*\\.?\\d+)\\%\\s*\\)\\s*")
|
||||||
def convertColor(value):
|
def convertColor(value):
|
||||||
|
|
@ -1839,6 +1921,10 @@ def scourString(in_string, options=None):
|
||||||
if elem.getAttribute(attr) != '':
|
if elem.getAttribute(attr) != '':
|
||||||
elem.setAttribute(attr, scourLength(elem.getAttribute(attr)))
|
elem.setAttribute(attr, scourLength(elem.getAttribute(attr)))
|
||||||
|
|
||||||
|
# remove default values of attributes
|
||||||
|
# print doc.documentElement.toxml()
|
||||||
|
numAttrsRemoved += removeDefaultAttributeValues(doc.documentElement, options)
|
||||||
|
|
||||||
# convert rasters references to base64-encoded strings
|
# convert rasters references to base64-encoded strings
|
||||||
if options.embed_rasters:
|
if options.embed_rasters:
|
||||||
for elem in doc.documentElement.getElementsByTagNameNS(NS['SVG'], 'image') :
|
for elem in doc.documentElement.getElementsByTagNameNS(NS['SVG'], 'image') :
|
||||||
|
|
|
||||||
69
testscour.py
69
testscour.py
|
|
@ -461,8 +461,7 @@ class InheritGradientUnitsUponCollapsing(unittest.TestCase):
|
||||||
class OverrideGradientUnitsUponCollapsing(unittest.TestCase):
|
class OverrideGradientUnitsUponCollapsing(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
doc = scour.scourXmlFile('unittests/collapse-gradients-gradientUnits.svg')
|
doc = scour.scourXmlFile('unittests/collapse-gradients-gradientUnits.svg')
|
||||||
self.assertEquals(doc.getElementsByTagNameNS(SVGNS, 'radialGradient')[0].getAttribute('gradientUnits'),
|
self.assertEquals(doc.getElementsByTagNameNS(SVGNS, 'radialGradient')[0].getAttribute('gradientUnits'), '',
|
||||||
'objectBoundingBox',
|
|
||||||
'gradientUnits not properly overrode when collapsing gradients' )
|
'gradientUnits not properly overrode when collapsing gradients' )
|
||||||
|
|
||||||
class DoNotCollapseMultiplyReferencedGradients(unittest.TestCase):
|
class DoNotCollapseMultiplyReferencedGradients(unittest.TestCase):
|
||||||
|
|
@ -743,6 +742,72 @@ class RemoveRedundantSvgNamespacePrefix(unittest.TestCase):
|
||||||
self.assertEquals( r.tagName, 'rect',
|
self.assertEquals( r.tagName, 'rect',
|
||||||
'Redundant svg: prefix not removed')
|
'Redundant svg: prefix not removed')
|
||||||
|
|
||||||
|
class RemoveDefaultGradX1Value(unittest.TestCase):
|
||||||
|
def runTest(self):
|
||||||
|
g = scour.scourXmlFile('unittests/gradient-default-attrs.svg').getElementsByTagNameNS(SVGNS, 'linearGradient')[0]
|
||||||
|
self.assertEquals( g.getAttribute('x1'), '',
|
||||||
|
'x1="0" not removed')
|
||||||
|
|
||||||
|
class RemoveDefaultGradY1Value(unittest.TestCase):
|
||||||
|
def runTest(self):
|
||||||
|
g = scour.scourXmlFile('unittests/gradient-default-attrs.svg').getElementsByTagNameNS(SVGNS, 'linearGradient')[0]
|
||||||
|
self.assertEquals( g.getAttribute('y1'), '',
|
||||||
|
'y1="0" not removed')
|
||||||
|
|
||||||
|
class RemoveDefaultGradX2Value(unittest.TestCase):
|
||||||
|
def runTest(self):
|
||||||
|
g = scour.scourXmlFile('unittests/gradient-default-attrs.svg').getElementsByTagNameNS(SVGNS, 'linearGradient')[0]
|
||||||
|
self.assertEquals( g.getAttribute('x2'), '',
|
||||||
|
'x2="100%" not removed')
|
||||||
|
|
||||||
|
class RemoveDefaultGradY2Value(unittest.TestCase):
|
||||||
|
def runTest(self):
|
||||||
|
g = scour.scourXmlFile('unittests/gradient-default-attrs.svg').getElementsByTagNameNS(SVGNS, 'linearGradient')[0]
|
||||||
|
self.assertEquals( g.getAttribute('y2'), '',
|
||||||
|
'y2="0" not removed')
|
||||||
|
|
||||||
|
class RemoveDefaultGradGradientUnitsValue(unittest.TestCase):
|
||||||
|
def runTest(self):
|
||||||
|
g = scour.scourXmlFile('unittests/gradient-default-attrs.svg').getElementsByTagNameNS(SVGNS, 'linearGradient')[0]
|
||||||
|
self.assertEquals( g.getAttribute('gradientUnits'), '',
|
||||||
|
'gradientUnits="objectBoundingBox" not removed')
|
||||||
|
|
||||||
|
class RemoveDefaultGradSpreadMethodValue(unittest.TestCase):
|
||||||
|
def runTest(self):
|
||||||
|
g = scour.scourXmlFile('unittests/gradient-default-attrs.svg').getElementsByTagNameNS(SVGNS, 'linearGradient')[0]
|
||||||
|
self.assertEquals( g.getAttribute('spreadMethod'), '',
|
||||||
|
'spreadMethod="pad" not removed')
|
||||||
|
|
||||||
|
class RemoveDefaultGradCXValue(unittest.TestCase):
|
||||||
|
def runTest(self):
|
||||||
|
g = scour.scourXmlFile('unittests/gradient-default-attrs.svg').getElementsByTagNameNS(SVGNS, 'radialGradient')[0]
|
||||||
|
self.assertEquals( g.getAttribute('cx'), '',
|
||||||
|
'cx="50%" not removed')
|
||||||
|
|
||||||
|
class RemoveDefaultGradCYValue(unittest.TestCase):
|
||||||
|
def runTest(self):
|
||||||
|
g = scour.scourXmlFile('unittests/gradient-default-attrs.svg').getElementsByTagNameNS(SVGNS, 'radialGradient')[0]
|
||||||
|
self.assertEquals( g.getAttribute('cy'), '',
|
||||||
|
'cy="50%" not removed')
|
||||||
|
|
||||||
|
class RemoveDefaultGradRValue(unittest.TestCase):
|
||||||
|
def runTest(self):
|
||||||
|
g = scour.scourXmlFile('unittests/gradient-default-attrs.svg').getElementsByTagNameNS(SVGNS, 'radialGradient')[0]
|
||||||
|
self.assertEquals( g.getAttribute('r'), '',
|
||||||
|
'r="50%" not removed')
|
||||||
|
|
||||||
|
class RemoveDefaultGradFXValue(unittest.TestCase):
|
||||||
|
def runTest(self):
|
||||||
|
g = scour.scourXmlFile('unittests/gradient-default-attrs.svg').getElementsByTagNameNS(SVGNS, 'radialGradient')[0]
|
||||||
|
self.assertEquals( g.getAttribute('fx'), '',
|
||||||
|
'fx matching cx not removed')
|
||||||
|
|
||||||
|
class RemoveDefaultGradFYValue(unittest.TestCase):
|
||||||
|
def runTest(self):
|
||||||
|
g = scour.scourXmlFile('unittests/gradient-default-attrs.svg').getElementsByTagNameNS(SVGNS, 'radialGradient')[0]
|
||||||
|
self.assertEquals( g.getAttribute('fy'), '',
|
||||||
|
'fy matching cy not removed')
|
||||||
|
|
||||||
# TODO; write a test for embedding rasters
|
# TODO; write a test for embedding rasters
|
||||||
# TODO: write a test for --disable-embed-rasters
|
# TODO: write a test for --disable-embed-rasters
|
||||||
# TODO: write tests for --keep-editor-data
|
# TODO: write tests for --keep-editor-data
|
||||||
|
|
|
||||||
10
unittests/gradient-default-attrs.svg
Normal file
10
unittests/gradient-default-attrs.svg
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<linearGradient id="g" x1="0" y1='0' x2='100%' y2='0.0' gradientUnits="objectBoundingBox" spreadMethod="pad">
|
||||||
|
<stop offset="0" stop-color="black"/>
|
||||||
|
<stop offset="1" stop-color="white"/>
|
||||||
|
</linearGradient>
|
||||||
|
<radialGradient id="g2" xlink:href="#g1" cx="50%" cy="0.5" r="50%" fx="50%" fy="0.5"/>
|
||||||
|
<rect width="100" height="100" fill="url(#g)"/>
|
||||||
|
<rect width="50" height="50" fill="url(#g2)"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 535 B |
Loading…
Add table
Add a link
Reference in a new issue