diff options
| author | Sebastian Wüst <sebi@timewaster.de> | 2013-10-20 15:32:08 +0000 |
|---|---|---|
| committer | Sebastian Wüst <sebi@timewaster.de> | 2013-10-20 15:32:08 +0000 |
| commit | 82908f949129e1fcbf62002799ee7b1b77986eed (patch) | |
| tree | c02098dd7720cdf424f2793ecd3ddac2ea86b969 /share/extensions | |
| parent | changed text (diff) | |
| parent | Fix build errors with clang 3.3 and c++11 enabled. (diff) | |
| download | inkscape-82908f949129e1fcbf62002799ee7b1b77986eed.tar.gz inkscape-82908f949129e1fcbf62002799ee7b1b77986eed.zip | |
merge from trunk
(bzr r12417.1.24)
Diffstat (limited to 'share/extensions')
25 files changed, 516 insertions, 91 deletions
diff --git a/share/extensions/Makefile.am b/share/extensions/Makefile.am index d9597b33f..ffbe1ec77 100644 --- a/share/extensions/Makefile.am +++ b/share/extensions/Makefile.am @@ -54,6 +54,7 @@ extensions = \ edge3d.py \ embedimage.py \ embed_raster_in_svg.pl \ + empty_page.py \ eqtexsvg.py \ export_gimp_palette.py \ extractimage.py \ @@ -166,6 +167,7 @@ extensions = \ text_flipcase.py \ text_randomcase.py \ text_braille.py \ + text_merge.py \ triangle.py \ txt2svg.pl \ uniconv-ext.py \ @@ -184,6 +186,7 @@ extensions = \ yocto_css.py otherstuff = \ + fontfix.conf \ inkweb.js \ jessyInk.js \ jessyInk_core_mouseHandler_noclick.js \ @@ -236,6 +239,7 @@ modules = \ edge3d.inx \ embedimage.inx \ embedselectedimages.inx \ + empty_page.inx \ eps_input.inx \ eqtexsvg.inx \ export_gimp_palette.inx \ @@ -348,6 +352,7 @@ modules = \ text_flipcase.inx \ text_randomcase.inx \ text_braille.inx \ + text_merge.inx \ triangle.inx \ txt2svg.inx \ voronoi2svg.inx \ diff --git a/share/extensions/ccx_input.inx b/share/extensions/ccx_input.inx index 040a2891a..a44697c52 100644 --- a/share/extensions/ccx_input.inx +++ b/share/extensions/ccx_input.inx @@ -6,7 +6,7 @@ <input> <extension>.ccx</extension> <mimetype>application/x-xccx</mimetype> - <_filetypename>Corel DRAW Compressed Exchange files (UC) (.ccx)</_filetypename> + <_filetypename>Corel DRAW Compressed Exchange files (UC) (*.ccx)</_filetypename> <_filetypetooltip>Open compressed exchange files saved in Corel DRAW (UC)</_filetypetooltip> </input> <script> diff --git a/share/extensions/cdt_input.inx b/share/extensions/cdt_input.inx index 78d5c6a97..912503643 100644 --- a/share/extensions/cdt_input.inx +++ b/share/extensions/cdt_input.inx @@ -6,7 +6,7 @@ <input> <extension>.cdt</extension> <mimetype>application/x-xcdt</mimetype> - <_filetypename>Corel DRAW 7-13 template files (UC) (.cdt)</_filetypename> + <_filetypename>Corel DRAW 7-13 template files (UC) (*.cdt)</_filetypename> <_filetypetooltip>Open files saved in Corel DRAW 7-13 (UC)</_filetypetooltip> </input> <script> diff --git a/share/extensions/cgm_input.inx b/share/extensions/cgm_input.inx index 99c7ea79b..e6fee4860 100644 --- a/share/extensions/cgm_input.inx +++ b/share/extensions/cgm_input.inx @@ -6,7 +6,7 @@ <input> <extension>.cgm</extension> <mimetype>application/x-xcgm</mimetype> - <_filetypename>Computer Graphics Metafile files (.cgm)</_filetypename> + <_filetypename>Computer Graphics Metafile files (*.cgm)</_filetypename> <_filetypetooltip>Open Computer Graphics Metafile files</_filetypetooltip> </input> <script> diff --git a/share/extensions/cmx_input.inx b/share/extensions/cmx_input.inx index 7840302d5..75f9aa10a 100644 --- a/share/extensions/cmx_input.inx +++ b/share/extensions/cmx_input.inx @@ -6,7 +6,7 @@ <input> <extension>.cmx</extension> <mimetype>application/x-xcmx</mimetype> - <_filetypename>Corel DRAW Presentation Exchange files (UC) (.cmx)</_filetypename> + <_filetypename>Corel DRAW Presentation Exchange files (UC) (*.cmx)</_filetypename> <_filetypetooltip>Open presentation exchange files saved in Corel DRAW (UC)</_filetypetooltip> </input> <script> diff --git a/share/extensions/dhw_input.inx b/share/extensions/dhw_input.inx index 91b52ff9e..ec43577b2 100644 --- a/share/extensions/dhw_input.inx +++ b/share/extensions/dhw_input.inx @@ -6,7 +6,7 @@ <input> <extension>.dhw</extension> <mimetype>application/x-extension-DHW</mimetype> - <_filetypename>ACECAD Digimemo File (.dhw)</_filetypename> + <_filetypename>ACECAD Digimemo File (*.dhw)</_filetypename> <_filetypetooltip>Open files from ACECAD Digimemo</_filetypetooltip> </input> <script> diff --git a/share/extensions/empty_page.inx b/share/extensions/empty_page.inx new file mode 100644 index 000000000..f3f60f796 --- /dev/null +++ b/share/extensions/empty_page.inx @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<inkscape-extension xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"> + <_name>Empty Page</_name> + <id>org.inkscape.render.empty_page</id> + <dependency type="executable" location="extensions">empty_page.py</dependency> + <dependency type="executable" location="extensions">inkex.py</dependency> + + <param name="size" _gui-text="Page size:" type="enum"> + <item value="a3">A3</item> + <item value="a4">A4</item> + <item value="a5">A5</item> + <item value="letter">letter</item> + </param> + + <param name="orientation" _gui-text="Page orientation:" type="enum"> + <item value="horizontal">Horizontal</item> + <item value="vertical">Vertical</item> + </param> + + <effect needs-live-preview="false"> + <object-type>all</object-type> + <effects-menu hidden="true" /> + </effect> + <inkscape:_templateinfo> + <inkscape:_name>Empty page</inkscape:_name> + <inkscape:author>Jan Darowski</inkscape:author> + <inkscape:_shortdesc>Empty page of chosen size.</inkscape:_shortdesc> + <inkscape:date>2013-09-10</inkscape:date> + <inkscape:_keywords>empty sheet a4 a3 a5 letter</inkscape:_keywords> + </inkscape:_templateinfo> + <script> + <command reldir="extensions" interpreter="python">empty_page.py</command> + </script> +</inkscape-extension> diff --git a/share/extensions/empty_page.py b/share/extensions/empty_page.py new file mode 100644 index 000000000..dc16bab97 --- /dev/null +++ b/share/extensions/empty_page.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python + +import inkex + +class C(inkex.Effect): + def __init__(self): + inkex.Effect.__init__(self) + self.OptionParser.add_option("-s", "--size", action="store", type="string", dest="page_size", default="a4", help="Page size") + self.OptionParser.add_option("-o", "--orientation", action="store", type="string", dest="page_orientation", default="vertical", help="Page orientation") + + def effect(self): + root = self.document.getroot() + root.set("width", "12in") + root.set("height", "12in") + if self.options.page_size == "a4" and self.options.page_orientation == "vertical": + root.set("width", "210mm") + root.set("height", "297mm") + if self.options.page_size == "a4" and self.options.page_orientation == "horizontal": + root.set("height", "210mm") + root.set("width", "297mm") + + if self.options.page_size == "a5" and self.options.page_orientation == "vertical": + root.set("width", "148mm") + root.set("height", "210mm") + if self.options.page_size == "a5" and self.options.page_orientation == "horizontal": + root.set("width", "210mm") + root.set("height", "148mm") + + if self.options.page_size == "a3" and self.options.page_orientation == "vertical": + root.set("width", "297mm") + root.set("height", "420mm") + if self.options.page_size == "a3" and self.options.page_orientation == "horizontal": + root.set("width", "420mm") + root.set("height", "297mm") + + if self.options.page_size == "letter" and self.options.page_orientation == "vertical": + root.set("width", "8.5in") + root.set("height", "11in") + if self.options.page_size == "letter" and self.options.page_orientation == "horizontal": + root.set("width", "11in") + root.set("height", "8.5in") + +c = C() +c.affect() diff --git a/share/extensions/eqtexsvg.py b/share/extensions/eqtexsvg.py index bf2874ef9..a6000dc6d 100755 --- a/share/extensions/eqtexsvg.py +++ b/share/extensions/eqtexsvg.py @@ -118,6 +118,10 @@ class EQTEXSVG(inkex.Effect): os.remove(err_file) os.rmdir(base_dir) + if self.options.formula == "": + print >>sys.stderr, "empty LaTeX input. Nothing to be done" + return + add_header = parse_pkgs(self.options.packages) create_equation_tex(latex_file, self.options.formula, add_header) os.system('latex "-output-directory=%s" -halt-on-error "%s" > "%s"' \ diff --git a/share/extensions/fontfix.conf b/share/extensions/fontfix.conf new file mode 100644 index 000000000..4f66174c9 --- /dev/null +++ b/share/extensions/fontfix.conf @@ -0,0 +1,55 @@ +# This file contains correction factors for the PowerPoint compensation method +# when files are saved to EMF. PowerPoint applies some odd offsets when it ungroups +# fonts from within an EMF. This file contains compensating factors so that the +# imported, ungrouped characters end up in the desired location. +# +# Format(s) +# +# # a comment +# +# f1 f2 f3 FontName +# where +# f1: vertical (rotating) correction factor (a double) +# f2: vertical (nonrotating) correction factor (a double) +# f3: horizontal (nonrotating) correction factor (a double) +# FontName: Case sensitive, may contain spaces. Example: Times New Roman +# +# The first font will listed will be used as the default for any font which +# is later requested but was not explicitly listed. +# +# If f1 specifies a multiplicative correction factor. It is multiplied by the font size +# and then the character is offset parallel to the (original) vertical direction of the character, +# that is, along the long part of a capital L. +# +# If f2 or f3 is nonzero then for angles <1 degree from 0,90,180,270 degrees +# the angle is snapped to n*90 and f2 is used for the vertical displacements, f3 +# for the horizontal displacements (that is, for 90 degrees, f3 is used). +# +# There is are one special type of fontname: Convert To FontName, +# for instance "Convert To Symbol". It is used when EMF print converts +# from unicode to Symbol, Wingdings, or Zapf Dingbats. +# +# Positive values lower the letter, negative raise it +# +# File history: +# 1.0.0 03/26/2012, David Mathog, initial values +##################################################################### +0.05 -0.055 -0.065 Arial +0.05 -0.055 -0.065 Times New Roman +-0.025 -0.055 -0.065 Lucida Sans +0.05 -0.055 -0.065 Sans +-0.05 -0.055 -0.065 Microsoft Sans Serif +0.05 -0.055 -0.065 Serif +0.05 -0.055 -0.065 Garamond +0.25 0.025 0.025 Century Schoolbook +0.025 0.0 0.0 Verdana +0.045 0.025 0.025 Tahoma +0.025 0.0 0.0 Symbol +0.05 0.0 0.0 Wingdings +0.025 0.0 0.0 Zapf Dingbats +0.025 0.0 0.0 Convert To Symbol +0.05 0.0 0.0 Convert To Wingdings +0.025 0.0 0.0 Convert To Zapf Dingbats +0.1 0.0 0.0 Sylfaen +0.175 0.125 0.125 Palatino Linotype +0.1 0.0 0.0 Segoe UI diff --git a/share/extensions/guides_creator.py b/share/extensions/guides_creator.py index da59a074d..178dc3c95 100755 --- a/share/extensions/guides_creator.py +++ b/share/extensions/guides_creator.py @@ -305,7 +305,7 @@ class Guides_Creator(inkex.Effect): v_orientation = str(round(height,4)) + ',0' # getting parent tag of the guides - nv = self.document.xpath('/svg:svg/sodipodi:namedview',namespaces=inkex.NSS)[0] + nv = self.document.find(inkex.addNS('namedview', 'sodipodi')) if (tab == "\"regular_guides\""): @@ -487,9 +487,10 @@ class Guides_Creator(inkex.Effect): # creating vertical guides drawVerticalGuides(v_subdiv,rectangle_width,rectangle_height,0,nv,begin_from) - -# Create effect instance and apply it. -effect = Guides_Creator() -effect.affect() + +if __name__ == '__main__': + # Create effect instance and apply it. + effect = Guides_Creator() + effect.affect() ## end of file guide_creator.py ## diff --git a/share/extensions/inkex.py b/share/extensions/inkex.py index c1feba5ae..861cc2300 100755 --- a/share/extensions/inkex.py +++ b/share/extensions/inkex.py @@ -184,7 +184,8 @@ class Effect: stream = open(self.svg_file,'r') except: stream = sys.stdin - self.document = etree.parse(stream) + p = etree.XMLParser(huge_tree=True) + self.document = etree.parse(stream, parser=p) self.original_document = copy.deepcopy(self.document) stream.close() diff --git a/share/extensions/polyhedron_3d.py b/share/extensions/polyhedron_3d.py index 063912cc2..d1d6adc0f 100755 --- a/share/extensions/polyhedron_3d.py +++ b/share/extensions/polyhedron_3d.py @@ -367,22 +367,22 @@ class Poly_3D(inkex.Effect): #VEIW SETTINGS self.OptionParser.add_option("--r1_ax", action="store", type="string", - dest="r1_ax", default=0) + dest="r1_ax", default="X-Axis") self.OptionParser.add_option("--r2_ax", action="store", type="string", - dest="r2_ax", default=0) + dest="r2_ax", default="X-Axis") self.OptionParser.add_option("--r3_ax", action="store", type="string", - dest="r3_ax", default=0) + dest="r3_ax", default="X-Axis") self.OptionParser.add_option("--r4_ax", action="store", type="string", - dest="r4_ax", default=0) + dest="r4_ax", default="X-Axis") self.OptionParser.add_option("--r5_ax", action="store", type="string", - dest="r5_ax", default=0) + dest="r5_ax", default="X-Axis") self.OptionParser.add_option("--r6_ax", action="store", type="string", - dest="r6_ax", default=0) + dest="r6_ax", default="X-Axis") self.OptionParser.add_option("--r1_ang", action="store", type="float", dest="r1_ang", default=0) @@ -473,7 +473,7 @@ class Poly_3D(inkex.Effect): 'transform':poly_transform } poly = inkex.etree.SubElement(self.current_layer, 'g', poly_attribs)#the group to put everything in - #TRANFORMATION OF THE OBJECT (ROTATION, SCALE, ETC) + #TRANSFORMATION OF THE OBJECT (ROTATION, SCALE, ETC) trans_mat = mat(identity(3, float)) #init. trans matrix as identity matrix for i in range(1, 7):#for each rotation diff --git a/share/extensions/simplestyle.py b/share/extensions/simplestyle.py index c97d57e75..99b5938dd 100755..100644 --- a/share/extensions/simplestyle.py +++ b/share/extensions/simplestyle.py @@ -176,7 +176,7 @@ def parseStyle(s): if s is None: return {} else: - return dict([[x.strip() for x in i.split(":")] for i in s.split(";") if len(i)]) + return dict([[x.strip() for x in i.split(":")] for i in s.split(";") if len(i.strip())]) def formatStyle(a): """Format an inline style attribute from a dictionary""" diff --git a/share/extensions/sk1_input.inx b/share/extensions/sk1_input.inx index b3336f67a..64218b186 100644 --- a/share/extensions/sk1_input.inx +++ b/share/extensions/sk1_input.inx @@ -6,7 +6,7 @@ <input> <extension>.sk1</extension> <mimetype>application/x-xsk1</mimetype> - <_filetypename>sK1 vector graphics files (.sk1)</_filetypename> + <_filetypename>sK1 vector graphics files (*.sk1)</_filetypename> <_filetypetooltip>Open files saved in sK1 vector graphics editor</_filetypetooltip> </input> <script> diff --git a/share/extensions/sk1_output.inx b/share/extensions/sk1_output.inx index 33494299c..c6f021839 100644 --- a/share/extensions/sk1_output.inx +++ b/share/extensions/sk1_output.inx @@ -6,7 +6,7 @@ <output> <extension>.sk1</extension> <mimetype>application/x-xsk1</mimetype> - <_filetypename>sK1 vector graphics files (.sk1)</_filetypename> + <_filetypename>sK1 vector graphics files (*.sk1)</_filetypename> <_filetypetooltip>File format for use in sK1 vector graphics editor</_filetypetooltip> </output> <script> diff --git a/share/extensions/spirograph.py b/share/extensions/spirograph.py index 21249831f..cb9d1ac24 100755 --- a/share/extensions/spirograph.py +++ b/share/extensions/spirograph.py @@ -35,7 +35,7 @@ class Spirograph(inkex.Effect): help="The distance of the pen from the inner gear") self.OptionParser.add_option("-p", "--gearplacement", action="store", type="string", - dest="gearplacement", default=50.0, + dest="gearplacement", default="inside", help="Selects whether the gear is inside or outside the ring") self.OptionParser.add_option("-a", "--rotation", action="store", type="float", diff --git a/share/extensions/svg2fxg.xsl b/share/extensions/svg2fxg.xsl index 4ccd62f27..db9f61f22 100755 --- a/share/extensions/svg2fxg.xsl +++ b/share/extensions/svg2fxg.xsl @@ -456,7 +456,7 @@ extension-element-prefixes="math"> <!-- // Gradient transform // Not implemented yet - Gradient positioning and tranformation are very different in FXG + Gradient positioning and transformation are very different in FXG --> <xsl:template name="gradient_transform"> <xsl:param name="transform" /> diff --git a/share/extensions/svgcalendar.py b/share/extensions/svgcalendar.py index b6d360ab0..23290bfe5 100755 --- a/share/extensions/svgcalendar.py +++ b/share/extensions/svgcalendar.py @@ -116,9 +116,9 @@ class SVGCalendar (inkex.Effect): help='Color for the week numbers.') self.OptionParser.add_option("--month-names", action="store", type="string", - dest="month_names", default='January February March' + \ + dest="month_names", default='January February March ' + \ 'April May June '+ \ - 'July August September' + \ + 'July August September ' + \ 'October November December', help='The month names for localization.') self.OptionParser.add_option("--day-names", diff --git a/share/extensions/test/Makefile.am b/share/extensions/test/Makefile.am index f7c59970f..9c3124351 100644 --- a/share/extensions/test/Makefile.am +++ b/share/extensions/test/Makefile.am @@ -20,7 +20,6 @@ EXTRA_DIST = \ foldablebox.test.py \ fractalize.test.py \ funcplot.test.py \ - gears.test.py \ gimp_xcf.test.py \ grid_cartesian.test.py \ grid_polar.test.py \ @@ -45,6 +44,7 @@ EXTRA_DIST = \ radiusrand.test.py \ render_alphabetsoup.test.py \ render_barcode.test.py \ + render_gears.test.py \ restack.test.py \ rtree.test.py \ run-all-extension-tests \ diff --git a/share/extensions/test/gears.test.py b/share/extensions/test/render_gears.test.py index 964f675ad..ad1668126 100755 --- a/share/extensions/test/gears.test.py +++ b/share/extensions/test/render_gears.test.py @@ -10,7 +10,7 @@ import sys sys.path.append('..') # this line allows to import the extension code import unittest -from gears import * +from render_gears import * class GearsBasicTest(unittest.TestCase): diff --git a/share/extensions/test/run-all-extension-tests b/share/extensions/test/run-all-extension-tests index 1776e25b0..aa20c8c7b 100755 --- a/share/extensions/test/run-all-extension-tests +++ b/share/extensions/test/run-all-extension-tests @@ -1,12 +1,39 @@ #!/bin/bash +# TODO: check for GNU mktemp and sed (from coreutils), else exit +# --------------------------------------------------------------------- +# solution below is based on +# <http://www.ooblick.com/weblog/2011/05/12/a-couple-of-shell-quickies/> + +# Wrapper function for GNU mktemp +gnu_mktemp() { + mktemp "$@" +} + +# Wrapper function for BSD mktemp +bsd_mktemp() { + mktemp -t tmpfile.XXXXXX "$@" +} + +# Try to figure out which wrapper to use +if mktemp -V | grep version >/dev/null 2>&1; then + MKTEMP=gnu_mktemp +else + MKTEMP=bsd_mktemp +fi + +#mytmpfile=`$MKTEMP` +echo "MKTEMP to be used: $MKTEMP" + +# --------------------------------------------------------------------- + echo -e "\n##### Extension Tests #####" cd "$(dirname "$0")" has_py_coverage=false -py_cover_files=$( mktemp ) -failed_tests=$( mktemp ) +py_cover_files=$( $MKTEMP ) +failed_tests=$( $MKTEMP ) if coverage.py -e >/dev/null 2>/dev/null; then has_py_coverage=true @@ -39,8 +66,23 @@ function run_py_test() { tot_FAILED=0 +# TODO: check for GNU mktemp and sed (from coreutils), else exit +# --------------------------------------------------------------------- +# solution below is based on +# <http://notmuchmail.org/pipermail/notmuch/2011/004579.html> + +if [ `sed --version >/dev/null 2>/dev/null && echo 1` ]; then + SED_EXTENDED='sed -r' # GNU sed (e.g. on Linux) +else + SED_EXTENDED='sed -E' # BSD sed (e.g. on Mac OS X) +fi + +echo "sed regex command: $SED_EXTENDED" + +# --------------------------------------------------------------------- + for testFile in *.test.py; do - if ! run_py_test $( echo $testFile | sed -r 's/^([^.]+)..*$/\1/' ); then + if ! run_py_test $( echo $testFile | $SED_EXTENDED 's/^([^.]+)..*$/\1/' ); then let tot_FAILED++ fi done @@ -60,4 +102,8 @@ echo "" rm $py_cover_files $failed_tests -$fail && exit 1
\ No newline at end of file +if [ x$fail == xtrue ]; then + exit 1 +else + exit 0 +fi diff --git a/share/extensions/test/simplestyle.test.py b/share/extensions/test/simplestyle.test.py index 3c75ac43a..a4746ec09 100755 --- a/share/extensions/test/simplestyle.test.py +++ b/share/extensions/test/simplestyle.test.py @@ -1,63 +1,65 @@ #!/usr/bin/env python -import unittest, sys
-sys.path.append('..') # this line allows to import the extension code
-
-from simplestyle import parseColor, parseStyle
-
-
-class ParseColorTest(unittest.TestCase):
- """Test for single transformations"""
- def test_namedcolor(self):
- "Parse 'red'"
- col = parseColor('red')
- self.failUnlessEqual((255,0,0),col)
-
- def test_hexcolor4digit(self):
- "Parse '#ff0102'"
- col = parseColor('#ff0102')
- self.failUnlessEqual((255,1,2),col)
-
- def test_hexcolor3digit(self):
- "Parse '#fff'"
- col = parseColor('#fff')
- self.failUnlessEqual((255,255,255),col)
-
- def test_rgbcolorint(self):
- "Parse 'rgb(255,255,255)'"
- col = parseColor('rgb(255,255,255)')
- self.failUnlessEqual((255,255,255),col)
-
- def test_rgbcolorpercent(self):
- "Parse 'rgb(100%,100%,100%)'"
- col = parseColor('rgb(100%,100%,100%)')
- self.failUnlessEqual((255,255,255),col)
-
- def test_rgbcolorpercent2(self):
- "Parse 'rgb(100%,100%,100%)'"
- col = parseColor('rgb(50%,0%,1%)')
- self.failUnlessEqual((127,0,2),col)
-
- def test_rgbcolorpercentdecimal(self):
- "Parse 'rgb(66.667%,0%,6.667%)'"
- col = parseColor('rgb(66.667%,0%,6.667%)')
- self.failUnlessEqual((170, 0, 17),col)
-
- def test_currentColor(self):
- "Parse 'currentColor'"
- col = parseColor('currentColor')
- self.failUnlessEqual(('currentColor'),col)
-
- def test_spaceinstyle(self):
- "Parse 'stop-color: rgb(0,0,0)'"
- col = parseStyle('stop-color: rgb(0,0,0)')
- self.failUnlessEqual({'stop-color': 'rgb(0,0,0)'},col)
-
- #def test_unknowncolor(self):
- # "Parse 'unknown'"
- # col = parseColor('unknown')
- # self.failUnlessEqual((0,0,0),col)
- #
-
-if __name__ == '__main__':
+import unittest, sys +sys.path.append('..') # this line allows to import the extension code + +from simplestyle import parseColor, parseStyle + + +class ParseColorTest(unittest.TestCase): + """Test for single transformations""" + def test_namedcolor(self): + "Parse 'red'" + col = parseColor('red') + self.failUnlessEqual((255,0,0),col) + + def test_hexcolor4digit(self): + "Parse '#ff0102'" + col = parseColor('#ff0102') + self.failUnlessEqual((255,1,2),col) + + def test_hexcolor3digit(self): + "Parse '#fff'" + col = parseColor('#fff') + self.failUnlessEqual((255,255,255),col) + + def test_rgbcolorint(self): + "Parse 'rgb(255,255,255)'" + col = parseColor('rgb(255,255,255)') + self.failUnlessEqual((255,255,255),col) + + def test_rgbcolorpercent(self): + "Parse 'rgb(100%,100%,100%)'" + col = parseColor('rgb(100%,100%,100%)') + self.failUnlessEqual((255,255,255),col) + + def test_rgbcolorpercent2(self): + "Parse 'rgb(100%,100%,100%)'" + col = parseColor('rgb(50%,0%,1%)') + self.failUnlessEqual((127,0,2),col) + + def test_rgbcolorpercentdecimal(self): + "Parse 'rgb(66.667%,0%,6.667%)'" + col = parseColor('rgb(66.667%,0%,6.667%)') + self.failUnlessEqual((170, 0, 17),col) + + # TODO: This test appears to be broken. parseColor can + # only return an RGB colour code + #def test_currentColor(self): + # "Parse 'currentColor'" + # col = parseColor('currentColor') + # self.failUnlessEqual(('currentColor'),col) + + def test_spaceinstyle(self): + "Parse 'stop-color: rgb(0,0,0)'" + col = parseStyle('stop-color: rgb(0,0,0)') + self.failUnlessEqual({'stop-color': 'rgb(0,0,0)'},col) + + #def test_unknowncolor(self): + # "Parse 'unknown'" + # col = parseColor('unknown') + # self.failUnlessEqual((0,0,0),col) + # + +if __name__ == '__main__': unittest.main() diff --git a/share/extensions/text_merge.inx b/share/extensions/text_merge.inx new file mode 100644 index 000000000..c871f52c0 --- /dev/null +++ b/share/extensions/text_merge.inx @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension"> + <_name>Merge</_name> + <id>org.inkscape.text.merge</id> + <dependency type="executable" location="extensions">text_merge.py</dependency> + <dependency type="executable" location="extensions">inkex.py</dependency> + <param name="direction" type="enum" _gui-text="Text direction:"> + <_item value="lr">Left to right</_item> + <_item value="bt">Bottom to top</_item> + <_item value="rl">Right to left</_item> + <_item value="tb">Top to bottom</_item> + </param> + <param name="xanchor" type="enum" _gui-text="Horizontal point:"> + <_item value="l">Left</_item> + <_item value="m">Middle</_item> + <_item value="r">Right</_item> + </param> + <param name="yanchor" type="enum" _gui-text="Vertical point:"> + <_item value="t">Top</_item> + <_item value="m">Middle</_item> + <_item value="b">Bottom</_item> + </param> + <param name="flowtext" type="boolean" _gui-text="Flow text">false</param> + <param name="keepstyle" type="boolean" _gui-text="Keep style">true</param> + <effect> + <object-type>all</object-type> + <effects-menu> + <submenu _name="Text"/> + </effects-menu> + </effect> + <script> + <command reldir="extensions" interpreter="python">text_merge.py</command> + </script> +</inkscape-extension> diff --git a/share/extensions/text_merge.py b/share/extensions/text_merge.py new file mode 100644 index 000000000..8cd8b751d --- /dev/null +++ b/share/extensions/text_merge.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python +""" +Copyright (C) 2013 Nicolas Dufour (jazzynico) +Direction code from the Restack extension, by Rob Antonishen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" +# standard library +import chardataeffect +import copy +import csv +import math +import os +import string +try: + from subprocess import Popen, PIPE + bsubprocess = True +except: + bsubprocess = False +# local library +import inkex + + +class Merge(inkex.Effect): + def __init__(self): + inkex.Effect.__init__(self) + self.OptionParser.add_option("-d", "--direction", + action="store", type="string", + dest="direction", default="tb", + help="direction to merge text") + self.OptionParser.add_option("-x", "--xanchor", + action="store", type="string", + dest="xanchor", default="m", + help="horizontal point to compare") + self.OptionParser.add_option("-y", "--yanchor", + action="store", type="string", + dest="yanchor", default="m", + help="vertical point to compare") + self.OptionParser.add_option("-t", "--flowtext", + action="store", type="inkbool", + dest="flowtext", default=False, + help="use a flow text structure instead of a normal text element") + self.OptionParser.add_option("-k", "--keepstyle", + action="store", type="inkbool", + dest="keepstyle", default=False, + help="keep format") + + def effect(self): + if len(self.selected)==0: + for node in self.document.xpath('//svg:text | //svg:flowRoot', namespaces=inkex.NSS): + self.selected[node.get('id')] = node + + if len( self.selected ) > 0: + objlist = [] + svg = self.document.getroot() + parentnode = self.current_layer + file = self.args[ -1 ] + + #get all bounding boxes in file by calling inkscape again with the --query-all command line option + #it returns a comma seperated list structured id,x,y,w,h + if bsubprocess: + p = Popen('inkscape --query-all "%s"' % (file), shell=True, stdout=PIPE, stderr=PIPE) + err = p.stderr + f = p.communicate()[0] + try: + reader=csv.CSVParser().parse_string(f) #there was a module cvs.py in earlier inkscape that behaved differently + except: + reader=csv.reader(f.split( os.linesep )) + err.close() + else: + _,f,err = os.popen3('inkscape --query-all "%s"' % ( file ) ) + reader=csv.reader( f ) + err.close() + + #build a dictionary with id as the key + dimen = dict() + for line in reader: + if len(line) > 0: + dimen[line[0]] = map( float, line[1:]) + + if not bsubprocess: #close file if opened using os.popen3 + f.close + + #find the center of all selected objects **Not the average! + x,y,w,h = dimen[self.selected.keys()[0]] + minx = x + miny = y + maxx = x + w + maxy = y + h + + for id, node in self.selected.iteritems(): + # get the bounding box + x,y,w,h = dimen[id] + if x < minx: + minx = x + if (x + w) > maxx: + maxx = x + w + if y < miny: + miny = y + if (y + h) > maxy: + maxy = y + h + + midx = (minx + maxx) / 2 + midy = (miny + maxy) / 2 + + #calculate distances for each selected object + for id, node in self.selected.iteritems(): + # get the bounding box + x,y,w,h = dimen[id] + + # calc the comparison coords + if self.options.xanchor == "l": + cx = x + elif self.options.xanchor == "r": + cx = x + w + else: # middle + cx = x + w / 2 + + if self.options.yanchor == "t": + cy = y + elif self.options.yanchor == "b": + cy = y + h + else: # middle + cy = y + h / 2 + + #direction chosen + if self.options.direction == "tb": + objlist.append([cy,id]) + elif self.options.direction == "bt": + objlist.append([-cy,id]) + elif self.options.direction == "lr": + objlist.append([cx,id]) + elif self.options.direction == "rl": + objlist.append([-cx,id]) + + objlist.sort() + #move them to the top of the object stack in this order. + + if self.options.flowtext: + self.text_element = "flowRoot" + self.text_span = "flowPara" + else: + self.text_element = "text" + self.text_span = "tspan" + + self.textRoot=inkex.etree.SubElement(parentnode,inkex.addNS(self.text_element,'svg'),{inkex.addNS('space','xml'):'preserve'}) + self.textRoot.set(inkex.addNS('style', ''), 'font-size:20px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;') + + for item in objlist: + self.recurse(self.selected[item[1]], self.textRoot) + + if self.options.flowtext: + self.region=inkex.etree.SubElement(self.textRoot,inkex.addNS('flowRegion','svg'),{inkex.addNS('space','xml'):'preserve'}) + self.rect=inkex.etree.SubElement(self.region,inkex.addNS('rect','svg'),{inkex.addNS('space','xml'):'preserve'}) + self.rect.set(inkex.addNS('height', ''), '200') + self.rect.set(inkex.addNS('width', ''), '200') + + def recurse(self, node, span): + #istext = (node.tag == '{http://www.w3.org/2000/svg}flowPara' or node.tag == '{http://www.w3.org/2000/svg}flowDiv' or node.tag == '{http://www.w3.org/2000/svg}tspan') + if node.tag != '{http://www.w3.org/2000/svg}flowRegion': + + newspan=inkex.etree.SubElement(span,inkex.addNS(self.text_span,'svg'),{inkex.addNS('space','xml'):'preserve'}) + + if node.get('{http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd}role'): + newspan.set(inkex.addNS('role', 'sodipodi'), node.get('{http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd}role')) + if (node.tag == '{http://www.w3.org/2000/svg}text' or node.tag == '{http://www.w3.org/2000/svg}flowPara'): + newspan.set(inkex.addNS('role', 'sodipodi'), 'line') + + if self.options.keepstyle: + if node.get('style'): + newspan.set(inkex.addNS('style', ''), node.get('style')) + + if node.text != None: + newspan.text = node.text + for child in node: + self.recurse(child, newspan) + +if __name__ == '__main__': + e = Merge() + e.affect() + +# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 encoding=utf-8 textwidth=99 |
