Prev Up Next
Import Filters Plugins User Interface

Export Filters

Sketch uses export filters to write documents to files.

Configuration Variables

For export filter configuration, Sketch uses the following variables:

type

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

tk_file_type
unload (optional)
format_name

These variables have the same meaning as in an export filter.

extensions

A string with the standard file extension of the export format. Alternatively this can be a tuple of file extension strings.

Sketch uses the file extension to find the export filter. See below.

External Interface

Given a document object and a filename for the output file, Sketch does the following to find an export filter and to export the drawing:

  1. Take the extension of the output filename and find the export filter that uses that extension.
  2. Load the module of the plugin
  3. Call the module's save function.

The save function

The function save is the main entry point for an export plugin. It is called with four positional parameters document, file, filename and options.

document is the document that is to be saved. file is the output file object open for writing and filename is the corresponding filename. Finally, options is a dictionary with (user specified) options. Currently options is always an empty dictinary as there is no way yet to specify such options.

Implementation Strategy

Apart from the save function entry point Sketch requires very little from the plugin. The only other thing it expects is that the plugin traverses the object tree by itself and uses the interface provided by the Protocols to distinguish the different object types.

In the following, the svg export filter serves as the basis for a a brief of this technique:

Both the svg and the ai filter use the same basic approach. They implement the filter as a class and use an instance of that class to do the work:

def save(document, file, filename, options = {}):
    saver = SVGSaver(file, filename, document, options)
    saver.Save()
    saver.close()

The interesting parts happen in the class. The constructor doesn't do much, it just saves the parameters in instance varibles:
class SVGSaver:

    def __init__(self, file, filename, document, options):
        self.file = file
        self.filename = filename
        self.document = document
        self.options = options

The Save method is where the real work begins. First it writes a kind of file header:
    def Save(self):
        self.file.write('\n')
        left, bottom, right, top = self.document.BoundingRect()
        width = right - left
        height = top - bottom
        self.trafo = Trafo(1, 0, 0, -1, -left, top)
        self.file.write('\n')
The document method BoundingRect returns the bounding rectangle of the entire document

After the header it loops over all the layers in the document...
        for layer in self.document.Layers():
...and if the layer is not a special layer, such as grid or guide layers, and if the layer is printable...
            if not layer.is_SpecialLayer and layer.Printable():
... save the layer as a group:
                self.BeginGroup()
                self.save_objects(layer.GetObjects())
                self.EndGroup()
GetObjects() returns a list of all objects in the layer. All compund objects have this method. In the svg filter, the BeginGroup and EndGroup methods write the <g> and <g> tags that mark groups in SVG.

Finally, the trailer to close the <svg> tag.
        self.file.write('</svg>')

The next interesting method is save_objects. It loops over the list of objects...
    def save_objects(self, objects):
        for object in objects:
...and if the object is a compound object...
            if object.is_Compound:
...save it as a group
                self.BeginGroup()
                self.save_objects(object.GetObjects())
                self.EndGroup()

otherwise, if the object is a bezier object, a rectangle or an ellipse...
            elif object.is_Bezier or object.is_Rectangle or object.is_Ellipse:
...save the object as bezier curves.
                self.PolyBezier(object.Paths(), object.Properties(),
                                object.bounding_rect)

The Paths method returns a tuple of path objects. Properties returns an object that has members like fill_pattern and line_width that define the properties of the object.


Import Filters Plugins User Interface
Prev Up Next