Mimsy Were the Borogoves

Hacks: Articles about programming in Python, Perl, Swift, BASIC, and whatever else I happen to feel like hacking at.

Updated Inkscape extension

Jerry Stratton, March 15, 2014

I noticed on the Inkscape forum that a couple of parts of this tutorial are out of date.

First, the line that includes “/Applications/Inkscape.app/Contents/Resources/extensions” is no longer necessary. The path is now known to all extensions, and by removing this line you can make your extensions more portable. For one thing, you no longer have to worry about the location of the Inkscape app.

Second, the .inx files are now full-fledged XML. This means that they need a real declaration at the top. Replace the “inkscape-extension” root element with:

  • <?xml version="1.0" encoding="UTF-8"?>
  • <inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">

This makes the full code:

[toggle code]

  • #!/usr/bin/python
  • import copy
  • import inkex, simpletransform
  • class DuplicateMultiple(inkex.Effect):
    • def __init__(self):
      • inkex.Effect.__init__(self)
      • self.OptionParser.add_option('-n', '--number-of-copies', action='store', type='int', dest='number', default=2, help='How many copies would you like?')
      • self.OptionParser.add_option('-x', '--horizontal', action='store', type='float', dest='horizontal', default=0, help='Horizontal distance?')
      • self.OptionParser.add_option('-y', '--vertical', action='store', type='float', dest='vertical', default=0, help='Vertical distance?')
    • def effect(self):
      • transformation = 'translate(' + str(self.options.horizontal) + ', ' + str(self.options.vertical) + ')'
      • transform = simpletransform.parseTransform(transformation)
      • if self.selected:
        • for id, node in self.selected.iteritems():
          • counter = self.options.number
          • while counter > 0:
            • newNode = copy.deepcopy(node)
            • #newNode.set('style', 'fill:none;stroke:#ff0000;stroke-width:2px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1')
            • simpletransform.applyTransformToNode(transform, newNode)
            • self.current_layer.append(newNode)
            • counter = counter - 1
            • node = newNode
      • #inkex.debug(newNode.attrib)
  • effect = DuplicateMultiple()
  • effect.affect()

And the full .inx file:

[toggle code]

  • <?xml version="1.0" encoding="UTF-8"?>
  • <inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
    • <_name>Multiple Copies</_name>
    • <id>com.hoboes.filter.duplicates</id>
    • <dependency type="executable" location="extensions">inkex.py</dependency>
    • <dependency type="executable" location="extensions">simpletransform.py</dependency>
    • <dependency type="executable" location="extensions">duplicates.py</dependency>
    • <param name="number" type="int" min="1" max="1000" _gui-text="How many copies would you like?">2</param>
    • <param name="horizontal" type="float" min="-10000.0" max="10000.0" _gui-text="X Offset">0.0</param>
    • <param name="vertical" type="float" min="-10000.0" max="10000.0" _gui-text="Y Offset">0.0</param>
    • <effect>
      • <object-type>all</object-type>
      • <effects-menu>
        • <submenu _name="Mine" />
      • </effects-menu>
    • </effect>
    • <script>
      • <command reldir="extensions" interpreter="python">duplicates.py</command>
    • </script>
  • </inkscape-extension>

In response to Write an Inkscape extension: create multiple duplicates: Once you get past the complete lack of simple real-world examples, it’s pretty easy to make Inkscape extensions. So, here’s a simple real-world example.