Prev Up Next
The Undo Mechanism Developer's Guide User Interface

Plugins

Plugins provide a way to extend Sketch with external modules that can be maintained independently from Sketch itself. Plugin modules can define Import Filters for new file formats or they can define new object types.

For this to work, Sketch has to provide a standardized interface to these modules to allow them to create and manipulate graphics objects. In addition, there has to be some fall-back method if someone loads a document containing objects defined by a plugin into an installation where that particular plugin is not available.

Plugin Configuration

On startup, Sketch searches for plugins on the plugin path. Every Python source file found is scanned for configuration information. Later, when the the plugin is needed it is imported.

The plugin path is a list of directories stored in Sketch.config.plugin_path. The directory names should be absolute pathnames. Sketch uses a notation borrowed from the kpathsea library (which is used by many TeX programs to search files):

The configuration information is a series of Python statements (assignments), each on its own line, between the lines '###Sketch Config' and `###End'.

One of the assingments must be to a variable named `type'. This specifies the type of the plugin (import filter, plugin object, etc.).

Another variable that may be used in the future, is `version' which will be used to specify the version of the plugin-config conventions used (not the version of the plugin itself).

Other variable names are type dependent.

Each of the lines may be commented out.

Example:
###Sketch Config
#type = Import
#class_name = 'SKLoader'
#rx_magic = '^##Sketch 1 *(?P[0-9]+)'
#tk_file_type = ('Sketch Document', '.sk')
format_name = 'SK-1'
###End

Sketch uses this method--instead of importing every plugin module and requiring that they register themselves with the plugin manager--to avoid loading unnecessary modules.

Implementation Note: currently Sketch reads the lines between `###Sketch Config' and `###End' into a single string (after removing the initial `#'s if present) and exec's it with a globals dictionary containing the predefined plugin types and an empty locals dictionary which receives all the variables. A consequence of this approach is that it is currently possible to use arbitrary Python statements and not just assignments. Don't rely on this, it could be changed in the future.

Import Filters

Sketch uses import filters to read vector drawings from files.

Configuration Variables

For import filter configuration, Sketch uses the following variables:

type

The type must be Import. This identifier is defined in the globals() dictionary.

class_name

A string containing the name of a Python class defined in the module. See below for the interface this class has to provide.

rx_magic

A string containing a regular expression suitable for the re module. This regular expression is matched against the first line of the file. if it matches, the import mechanism assumes that the filter understands the file's format and then procedes to use that filter to load the file. So, if possible, this regular expression should match those files the filter can handle and only those.

While this method of identifying files is not really sufficient to handle all file types, it works well enough for now. In the future we will probably have to extend this mechanism.

tk_file_type

A tuple containing two elements. The first is the name of the file format presented to the user in the file open dialog. The second element is eithe a string or a tuple of strings. Each of the strings defines a file name extension used for that filename.

Examples:

#tk_file_type = ('Sketch Document', '.sk')

#tk_file_type = ('PostScript file', ('.ps', '.eps'))

unload (optional)

A boolean. True means that the filter module should be unloaded after use, false means that it shouldn't be unloaded. If the module is unloaded it will be imported again the next time the filter is needed. Infrequently used filters should set this to true, frequently used filters (like the filter for Sketch's own format) should set it to true.

If omitted, it defaults to false.

It's a good idea to set this variable to true at least while developing a filter because that way the filter will be automatically reloaded when the source file changes.

format_name

The name of the format as a string. This name is currently used internally to find out whether a document was loaded from a file in Sketch's format or from a different format (in the latter case `Save' is treated like `Save As...', i.e. the user has to provide a filename).

The Class Interface

External Interface

The interface a loader class presents to the document loading mechanism is quite simple. The loading mechanism works roughly as follows:

  1. Read the first line of the file
  2. Match it in turn agains all the regular expressions defined for import filter plugins (defined by the rx_magic variable).
  3. If a match is found, instantiate the plugins class (defined by the class_name variable) with three positional parameters file, filename and match. file is the open input file object, positioned just after the first line. filename is the name of the file. match is the match-object returned from regular expression match. If possible, filters should read the input file sequentially and not use seeks. Sketch automatically pipes gzipped files through gzip and in that case the file object is actually a pipe, so seeks would be impossible. If a filter needs to access the first line it can do so by using match.string or by defing suitable groups in the regular expression.
  4. Call the instance's Load() method (without arguments). This method does the actual work and returns an instance of the document class.
  5. Call the instance's Messages() method without arguments. The return value is expected to be a list of strings with messages that are usually presented to the user by the UI.
  6. If the unload configuration variable is true, unload the plugin's module.

Common Base Classes

To make things easier, Sketch defines some base classes that plugins can inherit, LoaderWithComposites and, derived from that, GenericLoader and SimplifiedLoader, derived in turn from GenericLoader.

GenericLoader

The class GenericLoader provides a default implementation of the constructor, a mechanism for warning and error messages and methods to easily define standard objects like rectangles, ellipses and groups.

GenericLoader defines these methods:

__init__(file, filename, match)

Assign the arguments to self.file, self.filename and self.match respectively.

document()

Start the construction of a document. This method must be called before any other of the object creation methods are called.

layer([name])

Start a new layer. This method must be called after calling document and before any of the other object creation methods.

name is the name of the layer. If omitted, it defaults to "Layer 1".

begin_group()

Start a new group. Groups can be arbitrarily nested. Each call to begin_group must have a corresponding call to end_group.

end_group()

End the current group.

rectangle(m11, m21, m12, m22, v1, v2[, radius1 = 0][, radius2 = 0])

Create a new rectangle object and append it to the current compound object.

The first six positional parameters (m11, m21, m12, m22, v1, v2) define a transformation matrix that transforms the unit square (opposite corners (0,0) and (1,1)) onto the rectangle.

radius1 and radius2 define the rounded corners.

For more details see the documentation for the class Rectangle

ellipse(m11, m21, m12, m22, v1, v2[, start_angle = 0.0][, end_angle = 0.0][, arc_type = ArcPieSlice])

Create a new ellipse object and append it to the current compound object.

The first six positional parameters (m11, m21, m12, m22, v1, v2) define a transformation matrix that transforms the unit circle (center (0,0) and radius 1) onto the ellipse.

start_angle and end_angle, if given, define the start end end angles for pie slices, arc and chords.

arc_type defines whether and how the arc of an incomplete ellipse is closed. Valid values are ArcArc, ArcPieSlice and ArcChord. These constants are defined in Sketch.const

For more details see the documentation for the class Ellipse

bezier(paths)

Create a new bézier object in the current compound object.

paths must be a tuple of curve objects.

Plugin Objects

Plugin objects define new object types for Sketch.

Other Plugins

Other plugin types Sketch should have:


The Undo Mechanism Developer's Guide User Interface
Prev Up Next