Inkscape extensions

Must Watch!



MustWatch



Inkscape extensions by non developers

Lets begin with the extensions structure. A basic Inkscape extension is formed by two files: A python script (extension_name.py)The responsible for the magic A inkscape extension description file (extension_name.inx) This will be the responsible of communicating the inkscape UI with our script. Lets split this files up!

Extension description file (.inx)

The INX file (extension description file) will be the responsible of defining how the UI user interaction should be to connect Inkscape with our python script. Lets see how a basic INX file is and lets analyze its parts: The XML definition since this file is a valid XML <?xml version="1.0" encoding="UTF-8"?> A simple Inkscape extension tag <inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension"> </inkscape-extension> The extension name. Remember, this will become the name in the UI button so add a nice name. <_name>Your extension awesome Name</_name> The extension ID. This ID should be unique, you could just replace ‘org.inkscape.id’ with ‘org.inkscape.extension_name’. <id>org.inkscape.id</id> The dependencies. Here you should add the relative path to your python script (.py) file. If this file does not exist the extension will not be loaded. <dependency type="executable" location="extensions">plugin_name.py</dependency> Extension params. Here we will set the UI of our extension. Will the user need a textfield? A range selector? Tabs? We will use the user options in our python script afterwards. Lets see a basic example: <param name="some_name" type="string" _gui-text="Some text label">Some default text</param> name: Its the name of your option. Set an easy name because it will be used in your script to get this param value type: By default, Inkscape offers a very small set of GUI options: strings (textfields), interger(numbers field from 1 to 10), float(decimal numbers field), booleans (a checkbox selector), enum (a dropdown list), optiongroup (a multiselect), color (a colorpicker), desc (a free text) and notebook (a tab selector). _gui-text: This will be the label of the UI element so add a self explanatory copy Content: In some cases you can add a default text or set a boolean to true or false. _gui-hidden: A hidden parameter that can have a value. The inkscape wiki page of INX file params is well documented. The GUI menu. Here you will set the name of the button your users will click to perform the action. It will be useful to set your plugin at the submenu tag. Forget about the rest in this tutorial, its just the structure. <effect> <object-type>all</object-type> <effects-menu> <submenu _name="Your plugin name"/> </effects-menu> </effect> The reference script. As in the dependencies you set at the beggining, you should tell inkscape which file it has to execute. Add here the relative path to your python script. <script> <command reldir="extensions" interpreter="python">plugin_name.py</command> </script> And that's it for the INX file! Now, if we install this plugin, you should be able to see a new option under extensions menu, and your plugin name sub option on hover. Example capture of my extension inkscape-placehoder

The Python Script (.py)

As we have seen, the INX requires a python script to be executed. This script will be the responsible for the transformation of our SVG (everything in the inkscape work area is an SVG). As said in the inkscape wiki this file can do three things:
- Input, providing translation from a file format to SVG - Output, providing translation from SVG to a format - Effect, taking in SVG, changing it, and then outputting SVG
inkscape wiki extension tutorial. Lets see how it looks, in its simplest version: Ok, lets open our file and follow (and understand) the code: First, set the file as executable so Inkscape can execute its content and the character encoding #!/usr/bin/env python #-*- coding: utf-8 -*- Import Inkex, a inkscape dependency, that will do some magic for us applying our changes to the SVG. import inkex Declare a new Class() inheriting from inkex class MyExtensionName(inkex.Effect): Declare the init() function that will be executed when the class is invoked and add the option params defined at the INX (remember we set this params to be used later in the INX section? Yes, its now!) def __init__(self): inkex.Effect.__init__(self) self.OptionParser.add_option('-x', '--something', action='store', type='string', dest='optionName', default='defaultvalue', help='Helper text for this option') Lets review the OptionParser according to the inkscape Wiki action — An action that will do something with our value. In this case we store the value in the dest value (following point) dest — Destination of option action specified by action argument. Using opti nName value we say that we want to store this value to self.options.optionName. type — Type of option value. We use string here but could anything of the defined in the INX file. default — Defalut value for this option if it is not specified. help — A help string that will be displayed if script will be given no arguments or some option or argument will have wrong syntax. Create a new effect() function to get this values from the optionParser. It receives as first argument self, which is its parent class, in this case is MyExtensionName def effect(self): option = self.options.optionName self._main_function() In the first line, we store the value we set in the optionParser in the variable option so we could use it anywhere in the function. In the second line, we just ask the parent to call a second function called _main_function that receives the option variable as a second parameter.

main function

Although it is not necessary, it helps keep clarity. Do whatever you can to your SVG. In this case, we just print the value. This will have no effects on inkscape SVG. Find a simple extension example on my extensions, since are quite simple because I am not a python developer def _main_function(self, option): print option Last step: Invoke the class and execute the affect() function that will do its inkscape magic to execute it on the SVG. if __name__ == ‘__main__’: MyExtension = MyExtensionName() MyExtension.affect()

To install the extension

Just copy the two files (extension_name.py and extension_name.inx) into your local inkscape extensions folder ~/.config/inkscape/extensions Its a nice place to find how others made things and find clues on how to solve your own extension challenges. There are also dozens of extensions out there and there to learn from.

Python modules for extensions

These modules are provided as part of Inkscape and can be found in /usr/share/inkscape/extensions on GNU/Linux, ... on Windows along with the extensions bundled with Inkscape. They can be imported from an extension just like any other python module.

inkex.py

This module encapsulates the basic behavior of a script extension, allowing the author to concentrate on manipulating the SVG data. It relies on lxml.etree to work with the XML tree. inkex.py was originally designed to provide the Effect (filter) extension type, but has been used for Input/Output extensions simply by overriding additional class methods.

Functions

inkex.py provides the following functions: errormsg( msg ) End-user visible error message, it should always be used with translation: inkex.errormsg(_("This extension requires two selected paths")) addNS( tag, ns=None ) Returns the selected tag, with the namespace applied. The namespace is selected from a list supplied with the module.

The Effect class

The most important part of inkex.py is the Effect class. To implement an effect type extension in Python see PythonEffectTutorial

Methods

effect() You should overwrite this method with your own, as shown in PythonEffectTutorial#Effect Extension Script getElementById( id ) Returns the firs found element with given id, as a lxml element. getParentNode( node ) Returns the parent of node. Probably the same as node.getparent() from lxml? createGuide( x, y, angle ) Creates guide at position (x,y), with angle angle. affect() Actuate the script. xpathSingle( path ) An xpath wrapper to return a single node. uniqueId( old_id ) Return an id that is unique in the document given a proposed id, by appending random alphanumeric characters to it. getDocumentWidth() Return width of document, as a string. getDocumentHeight() Return height of document, as a string. getDocumentUnit() Return a string representing the default unit for the document. Full list of possible units is defined in the module. unittouu( string ) Convert given value (as a string, e.g: "4px") to units used by the document. Returns float. uutounit( value, unit ) Convert a value (float) in document default units to given units.

Properties

document DOM document, as a lxml.etree. selected A dict mapping ids to nodes, for all nodes selected in Inkscape. doc_ids A dict mapping ids to the constant 1, for all of the ids used in the original document. Does not get automatically updated when adding elements. options Options passed to the script.

simplestyle.py

Provides methods for dealing with css data embedded in SVG's style attribute. When a color is represented as integers they should be in the (0, 255) range, when represented as floats, they should be in the (0.0, 1.0) range. parseStyle( string ) Create a dictionary of attribute-value pairs from the value of an inline style attribute. formatStyle( dict ) Format an inline style attribute from a dictionary of attribute-value pairs, values are converted to strings by str(). isColor( c ) Determine if c is a valid color. parseColor( c ) Creates a rgb int array. c can be any type of string representation of a color. formatColoria( a ) Convert int array to #rrggbb string. formatColorfa( a ) Convert float array to #rrggbb string. formatColor3i( r, g, b ) Convert 3 ints to #rrggbb string. formatColor3f( r, g, b ) Convert 3 floats to #rrggbb string. svgcolors A dictionary defining legal color names and corresponding color values.

simplepath.py

Provides functions to round trip svg path d="" attribute data and a simple path format mimicking that datastructure, and additional functions for scaling translating and rotating path data. parsePath( d ) Parse SVG path and return an array of segments. Removes all shorthand notation. Converts coordinates to absolute. Returns list of [ command, params ] list. formatPath( l ) Format path data from a list. Returns the string representing the path, l should have the same format as returned by parsePath. translatePath( p, x, y ), scalePath( p, x, y ), rotatePath( p, angle, cx=0, cy=0 ) Transforms path p.

cubicsuperpath.py

An alternative path representation, accessing both handles of a node at once. Loses a path's open/closed identity. CubicSuperPath( simplepath ) Given a path as a list returned by simplepath.parsePath, it returns a list of lists in [ [ [ h1_0, pt_0, h2_0 ], [ h1_1, pt_1, h2_1 ], ... ], [ [ h1_m, pt_m, h2_m ], ...], ... ] format, where h1_n and h2_n are handles for the node at point pt_n. All points/handles are lists of two floats ([ x, y ]). The list is the representation of the whole path, the first level sub-lists are representations of sub-paths, and the lists containing 3 points represent the individual control nodes. unCubicSuperPath( csp ) Given a path in the format returned by CubicSuperPath returns it in the format used by simplepath. parsePath( d ) Parse a string representation directly. formatPath( p ) Format path as a string.

simpletransform.py

Provides code to easily transform objects. Transformations are represented as affine transformation matrices. Since the last row of such matrices is always the same ([0,0,1]) it is not included, so the final matrix is a list of two lists of 3 floats containing the first two rows of the matrix. Wherever E is used as a default argument it means the identity matrix, a transformation that does nothing. parseTransform( transform, mat=E ) Takes a string representing a transformation (like a SVG nodes transform attribute), and returns a transformation matrix. If mat is supplied, the returned matrix is composeTransform( mat, matrix). formatTransform( mat ) Returns string representation for transform (for use in transform attribute). invertTransform( mat ) Returns inverse of transformation given by mat. composeTransform( mat1, mat2 ) Returns matrix representing a transformation equal to applying mat1 then mat2. composeParents( node, mat ) Returns mat composed with every transformation that applies to node. If a node has a transformation applied to it, and is part of a group that has an other transformation applied to it, both apply to the node. This function composes all the nodes ancestors' transformations. applyTransformToNode( mat, node ) Apply transform to node by setting its transform attribute, does not change coordinates in any part of node. applyTransformToPath( mat, path ) Apply transform to path, by changing the coordinates of points and handles. path has to be a representation used by SuperCubicPath. applyTransformToPoint( mat, point ) Apply transform to a point given as a list [ x, y ]. fuseTransform( node ) Removes the transform attribute from a node, and applies it to the node, changing the nodes points' coordinates. The following functions might be broken out into a separate module in the future (see comment in code). roughBBox( path ) Returns four floats xmin, xMax, ymin, yMax, the coordinates for a rough bounding box. path has to be a representation used by SuperCubicPath. refinedBBox( path ) Same as the above, takes longer to calculate but more precise. computeBBox( node_list, mat = E ) Returns the bounding box for a list of nodes. If supplied mat is applied to the nodes before calculating the bounding box. Uses refinedBBox when applicable, text nodes are not yet supported. computePointInNode( pt, node, mat = E ) Given a point and a node, returns the coordinates that when transformed by the nodes and its ancestors transformations are the same as pt. For example take a circle created with its centre at (0,0) and then transformed by applying a pure translation to (1,0). If the centre is now set to (0,1) the centre of the circle will actually be at (1,1) because the transformation still applies. It can be avoided by using computePointInNode( [ 0, 1 ], circle ) which gives (-1,1), setting the centre to this the circle will appear at the desired (0,1).

pturtle.py

Provides turtle graphics primitives with svg path data output

beziermisc.py

Utility functions for working with bezier curves

cspsubdiv.py

Decompose a path into polylines

ff*.py

an obscure set of tools for dealing with musical scales. Retrieved from "https://wiki.inkscape.org/wiki/index.php?title=Python_modules_for_extensions&oldid=114116" Category: Extensions

Navigation menu

Personal tools

English Log in

Namespaces

Page Discussion

Variants

Views

Read View source View history

More

Navigation

Main page Current events Recent changes Random page Help

Tools

What links here Related changes Special pages Printable version Permanent link Page information Cite this page