Mimsy Were the Borogoves

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

42 Astoundingly Useful Scripts and Automations for the Macintosh

Work faster and more reliably. Use Perl, Python, AppleScript, Swift, and Automator to automate the drudgery of computer use. Add actions to the services menu and the menu bar, and create drag-and-drop apps.

Use simple scripts and make your Macintosh play music, roll dice, and talk to you. Create ASCII art from your photos. There’s a script for all of that in my new book, 42 Astoundingly Useful Scripts and Automations for the Macintosh.

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.