411 lines
18 KiB
Text
411 lines
18 KiB
Text
== Inkscape Extensions ==
|
|
|
|
=== Introduction ===
|
|
|
|
The extensions system in Inkscape is a way for adding functionality to
|
|
Inkscape, without affecting the core of the program itself. We want
|
|
Inkscape to follow a core-plus-modules approach similar to that adopted
|
|
by many successful open source projects such as the Linux kernel, Perl,
|
|
Apache, Gimp, and so on. There are many different types of extension
|
|
mechanisms, including file format conversion tools, filter scripts that
|
|
process SVG, user interface elements that can be added at runtime, and
|
|
so forth.
|
|
|
|
This proposal defines a design for handling this wide variety of
|
|
extensions in a flexible manner. This document provides a way to
|
|
understand the extensions system, and how extensions fit into this
|
|
overall system.
|
|
|
|
Much of the documentation that will be useful for users of the extension
|
|
system is not included in this document, it is autogenerated from the
|
|
source code and placed on the Inkscape webpage. While this is less
|
|
convenient, it is more correct, and maintained as the source code is
|
|
modified. Please look aton the Inkscape webpage also.
|
|
|
|
|
|
=== Terminology ===
|
|
|
|
*Extension* - An extension is something that extends the functionality
|
|
of Inkscape without being directly part of the core. This implies
|
|
that it should be easy to remove or add, and nothing in the core should
|
|
depend on it directly.
|
|
|
|
*Extension Type* - Establishes the functional interface that the
|
|
Extension provides, including the types of messages it handles and what
|
|
is contained in its data structures.
|
|
|
|
*Extension Implementation* - Defines how the extension is accessed;
|
|
i.e. through message passing, pipe/exec calls with commandline
|
|
arguments, direct function calls, etc.
|
|
|
|
*Plug-in* - An extension that is implemented through a loadable library.
|
|
This is a .so file on Unix-like systems or a .dll on Win32. The
|
|
libraries should not be loaded until they are used.
|
|
|
|
*Script* - A script is a type of extension that is implemented through
|
|
an external program that receives and sets SVG data through files and
|
|
pipes. This allows Inkscape to use programs that handle SVG but are
|
|
targeted differently, seamlessly inside of Inkscape.
|
|
|
|
*Language Binding* - A special type of plug-in that wraps a scripting
|
|
language interpreter such as Perl, Python, Lisp, etc. A user
|
|
interested in programmatic access to Inkscape's internals via one of
|
|
these languages can install (or create) the relevant Language Binding
|
|
Plug-in to achieve this.
|
|
|
|
*INX* - *'INkscape eXtension'* - The filename extension used for XML
|
|
metadata files that describe each Inkscape Extension.
|
|
|
|
*Internal Extension* - A part of the Inkscape codebase which uses the
|
|
extension system in order to make it more modular. This code is
|
|
compiled into Inkscape, but appears as an extension to all other code
|
|
in the codebase.
|
|
|
|
|
|
=== Requirements ===
|
|
|
|
* Uses a general language binding system so it's easy to add new
|
|
language binding support.
|
|
* Allows direct interaction with the document object model including
|
|
changing.
|
|
* Allows some limited interaction with the Inkscape UI such as
|
|
manipulating grids, overlays, etc.
|
|
* Allows direct interaction with file load/save/export/print
|
|
subsystem.
|
|
* Guaranteed to work properly with the undo system, even if the
|
|
extension is not written carefully.
|
|
* Well documented so is easy for people to learn how to make new
|
|
extensions.
|
|
* Each extension can be implemented, distributed, and managed
|
|
independently of the core project.
|
|
* Icons, buttons, and other UI elements for extensions fit seamlessly
|
|
into main application GUI.
|
|
* User can easily select which extensions to automatically load into
|
|
application at startup.
|
|
* Loading of extensions shall not seriously slow startup time or make
|
|
a major impact on memory footprint.
|
|
* Failure of a extension shall not leave the drawing in an
|
|
inconsistent state.
|
|
* Main application must gracefully recover from extension crashes or
|
|
other serious problems with extension execution.
|
|
* Dependencies for particular extensions must be clearly identified for user if missing.
|
|
|
|
|
|
=== Overview ===
|
|
|
|
Different kinds of extensions can be categorized in two ways. First,
|
|
but what the extension does: File format converters, printing, SVG
|
|
manipulation, symbol libraries, etc. Second, by how the extension is
|
|
implemented: command-line scripts, dynamically loaded libraries,
|
|
internal compiled-in code, etc.
|
|
|
|
The first kind of categorization is called the *Extension Type*. This
|
|
essentially establishes a calling interface and the set of messages the
|
|
extension must be able to receive and handle. For example, extensions
|
|
of type Print must have a way to handle 'print' message.
|
|
|
|
The second is the *Extension Implementation*. This defines the
|
|
mechanism Inkscape must use for passing messages to the extension. For
|
|
example, commandline scripts would have messages passed as commandline
|
|
arguments, whereas loadable plug-ins would have the messages passed to
|
|
the plug-in's message handler routine.
|
|
|
|
The categories of both Extension Types and Extension Implementations are
|
|
left open ended. This way, if someone comes up with new ideas for ways
|
|
to extend Inkscape that doesn't fit within the existing models, they can
|
|
add these mechanisms in a straightforward fashion.
|
|
|
|
For the purposes of this document, however, we focus on just the
|
|
following Types and Implementations:
|
|
|
|
Extension
|
|
"Input" - loading various file formats
|
|
"Output" - saving as various file formats
|
|
"Effect" - apply some sort of change to SVG elements in the doc
|
|
"Print" - prints using different drivers or modes
|
|
"Collection" - a group of objects that have thumbnails and images that
|
|
can be used inside a document. Libraries can be
|
|
searchable and may be presented in a hierarchical
|
|
structure
|
|
|
|
"Extension Implementations"
|
|
"Internal" - code that is internal to Inkscape which uses the
|
|
extension system for some functionality
|
|
"Script" - a cmdline program that takes an SVG document to its
|
|
STDIN and emits a modified SVG document to its STDOUT,
|
|
with control messages given as commandline parameters.
|
|
|
|
"Plug-in" - a loadable module with a message handler routine that
|
|
receives messages and that operates on the Inkscape API
|
|
functions directly.
|
|
|
|
=== Extension System Basics ===
|
|
|
|
Leaving the topic of Types and Implementations aside, we can make some
|
|
generalizations about how all Extensions work, and behaviors or
|
|
attributes that all Extensions share. This includes how they are
|
|
registered, how they handle preferences, how dependency resolution is
|
|
achieved, and versioning. These common behaviors are all established
|
|
via a base class that all Extension Types derive from.
|
|
|
|
=== Extension Base Class ===
|
|
|
|
The Extension base class holds the attribute data that all extensions
|
|
must have and establishes the base functionality that all extensions
|
|
share. All extensions have the following properties:
|
|
|
|
"ID" - A unique identifier for this extension that is used for referring
|
|
to the extension and naming its parameters in the configuration files.
|
|
|
|
"Name" - The textual name of the extension, it is used for user
|
|
interaction with the extension. It is used for users to identify the
|
|
extension.
|
|
|
|
"Parameters" - Each extension keeps a record of all of the parameters
|
|
that it has. The can be changed internally, through a GUI, or by other
|
|
extensions. Parameters can be found and adjusted using functions that
|
|
are within the base class.
|
|
|
|
=== Extension Registry ===
|
|
|
|
Inkscape maintains a data structure of all the registered extensions.
|
|
This registry can be queried against to retrieve lists of extensions
|
|
meeting various conditions (such as all Input extensions).
|
|
|
|
The Extension Registry contains all extensions whether or not they
|
|
failed their dependency checking on startup. This allows for additional
|
|
information to be displayed on the reasoning behind marking the
|
|
extension as disabled.
|
|
|
|
The registry can be reloaded from the Inkscape GUI while Inkscape is
|
|
running. This can be used to add new extensions into the system, or
|
|
help debug new extensions. When the registry is reloaded all extensions
|
|
are first unloaded, then they're specification files are re-read.
|
|
|
|
=== Handling Preferences ===
|
|
|
|
Individual extensions can have their own preferences which are used by
|
|
the extension. These are typically attributes of the operation that can
|
|
be modified by the user through a dialog. It is also possible to have
|
|
other extensions modify these values when they are using an extension.
|
|
For most extensions, these will be edited by a dialog that relates to
|
|
the preferences of the user.
|
|
|
|
The preferences themselves are defined in the inx file that describes
|
|
the extension. In this definition there is the name, the type, and the
|
|
default value. The types are: boolean, integer, float and string.
|
|
Other types can be developed using these as a basis. If there is no
|
|
custom value set the default value is used.
|
|
|
|
When a value is written to a preference for an extension, that value is
|
|
saved in the global preferences for Inkscape using the ID of the module
|
|
as the basis for the naming. At next use (including after restarting
|
|
the application) this value is used instead of the default. This allows
|
|
user preferences on a extension to remain persistent throughout uses of
|
|
Inkscape.
|
|
|
|
=== INX Files ===
|
|
|
|
The INX file is the description of the Inkscape Extension. It provides
|
|
all of the information that is used to identify the extension, and
|
|
determine what type of extension it is. This file is loaded on startup
|
|
of Inkscape, and the objects relating to the extension are created. All
|
|
extensions have an inx file, but many internal extensions compile this
|
|
file into the codebase (to reduce dependencies).
|
|
|
|
The INX file also contains information on the dependencies that are
|
|
required for the extension to operate. These dependencies can be
|
|
everything from required files, required libraries or other extensions
|
|
that help this one. The dependencies are checked as the file is loaded,
|
|
and an extension is marked as dead if they are not met. Also
|
|
dependencies can check different versions of particular objects to see
|
|
if they are met.
|
|
|
|
|
|
=== Extension Types ===
|
|
|
|
Each Extension is identified by it's 'Type'. This determines the type
|
|
of programmatic interface that it adheres to, enabling Inkscape to know
|
|
what functionality it can expect from the extension.
|
|
|
|
=== Input ===
|
|
|
|
An input extension provides a way to get data into Inkscape. This type
|
|
of extension creates a document given a filename. This is done by using
|
|
the 'open' method within the class. Also, there is a 'prefs' function
|
|
which will generate a GtkDialog. This dialog is then used to get any
|
|
settings that the incoming file and extension may use. This function is
|
|
executed, and the dialog returns, before the open method is called.
|
|
|
|
There are also several other settings stored in an Input extension.
|
|
This includes information on the type of file the input module can take
|
|
in including its filename extension and mime type. Also, there is a
|
|
space to store a tooltip for additional information on the file type in
|
|
the file dialog. Lastly, there is the key of which Output extension is
|
|
recommended for saving this filetype. This is useful, as there is no
|
|
other direct links between the Input and Output functions, and a user
|
|
expects to be able to open and save without using the 'Save As...'
|
|
dialog.
|
|
|
|
=== Output ===
|
|
|
|
An output extension controls how SVG documents are exported from
|
|
Inkscape. This type of extension creates a file given a document
|
|
object. This is done using the 'save' method within the class.
|
|
|
|
The method for how files are exported depends on what type of
|
|
Implementation is used. For Scripts, the file is first saved as a
|
|
temporary SVG file, and then processed by calling the commandline
|
|
programs to convert it. For Plug-ins, the document object is passed to
|
|
the extension with a 'save' message and a filename, and the extension
|
|
program performs the file save operation itself.
|
|
|
|
=== Effect ===
|
|
|
|
Effect extensions cause a modification of a loaded document. For
|
|
example, it might add a new shape to the drawing, or change all selected
|
|
objects to be purple with green dotted borders.
|
|
|
|
=== Print ===
|
|
|
|
The Print Extension Type is for extensions that interface with printing
|
|
subsystems. Examples would be Win32, postscript, and GNOME Print.
|
|
|
|
=== Collection ===
|
|
|
|
|
|
=== Creating Extensions ===
|
|
|
|
In this chapter, we discuss how to create an extension from scratch,
|
|
incorporate into Inkscape, and release it for the general Inkscape
|
|
community to use. This chapter can be read independently of the rest of
|
|
the document, using the rest as reference material.
|
|
|
|
=== Selecting an Extension Strategy ===
|
|
|
|
First of all, you will need to select the method you'll use for creating your extension.
|
|
|
|
Scripts are the simplest extensions to create, because they work through
|
|
STDIN/STDOUT, so you need to know very little about Inkscape internals
|
|
to make them work. However, their ability to interact with the Inkscape
|
|
internals is limited compared with other approaches. For file format
|
|
converters, this is usually fine. You can also create filters programs
|
|
that take the entire document to its STDIN, process it, and return a
|
|
modified copy to STDOUT. Some control of the extension is possible via
|
|
its commandline arguments.
|
|
|
|
One of the nice things about Scripts is that they can be written in any
|
|
language. It need not even be a scripting language - as long as it
|
|
handles STDIN and STDOUT and uses commandline arguments, you can write
|
|
it however you wish.
|
|
|
|
Plug-ins are more powerful than Scripts, but require more knowledge of
|
|
Inkscape internals, and must be written according to specific criteria.
|
|
Generally, since these are loaded as dynamic objects, they'll need to be
|
|
written in a language that can generate them, such as C or C++.
|
|
|
|
The best of both worlds can be available through Language Bindings,
|
|
which are Plug-ins that wrapper a script interpreter. This enables you
|
|
to call various Inkscape internal routines through your scripting
|
|
language's functions. If someone has created a Language Binding for
|
|
your language of choice, you're all set, otherwise you'll have to create
|
|
a Plug-in for it. Language Binding Plug-ins have a few more
|
|
requirements than ordinary Plug-ins, and require a greater amount of
|
|
knowledge of the Inkscape internals, so it can take quite some time to
|
|
do properly.
|
|
|
|
Internal Extensions are in a way the reverse of a normal Extension, in
|
|
that instead of providing a way to hook into Inkscape from the outside,
|
|
they provide hooks from inside Inkscape. These are used directly by
|
|
Inkscape, such as in the case of compiled-in printing modules. Most
|
|
users will never need to write this type of extension, they are pretty
|
|
much for Inkscape core developers only.
|
|
|
|
=== Writing Your Extension ===
|
|
|
|
This section provides some guidance and examples for implementing
|
|
different kinds of Extensions.
|
|
|
|
=== Writing Script Extensions ===
|
|
|
|
=== Writing Plug-in Extensions ===
|
|
|
|
=== Writing Language Binding Plug-in Extensions ===
|
|
|
|
=== Creating an INX File ===
|
|
|
|
Every extension must have a corresponding *.inx file. This is an XML
|
|
file that provides Inkscape with information about the module and allows
|
|
it to load the info without needing to access the module itself. The
|
|
*.inx file contains enough info for Inkscape to set up menu items and
|
|
know what kinds of functionality to expect from the extension.
|
|
|
|
=== Packaging Your Extension ===
|
|
|
|
=== Contributing Your Extension to the Inkscape Community ===
|
|
|
|
Once your extension is complete, you may wish to share it with the
|
|
community. There are of course no hard and fast rules for how to share
|
|
your work, but this section illustrates some approaches.
|
|
|
|
=== Listing Your Extension ===
|
|
|
|
First, you will need to put your extension someplace that others can
|
|
find and download it. If you have adequate webspace, you could simply
|
|
upload it to your web server. More typically, you will want to upload
|
|
it to a mirroring system like SourceForge (http://www.sourceforge.net),
|
|
CPAN (http://www.cpan.org), and the like. The Inkscape project may also
|
|
be willing to host your extension; contact the admins for more info.
|
|
|
|
It can also be helpful to list your extension with one of the various
|
|
software registries, such as Freshmeat (http://www.freshmeat.net). You
|
|
should also list it on the Inkscape Wiki site.
|
|
|
|
=== Announcing Your Extension ===
|
|
|
|
After posting your extension someplace from which it can be downloaded,
|
|
you should also announce its availability, by sending an email to
|
|
inkscape-announce@lists.sourceforge.net. You may also want to announce
|
|
it on other related sites; for instance, if you've written a plug-in to
|
|
allow operation of Imagemagick from within Inkscape, it could be a good
|
|
idea to announce it to the Imagemagick list.
|
|
|
|
|
|
=== Incorporating Your Extension in to Inkscape ===
|
|
|
|
Because the intent with the extension system is to break things *out*
|
|
from the core, most extensions should be packaged and distributed
|
|
independently of the main Inkscape distribution. However, for ease of
|
|
user installation, an extension-pack can be shipped along with the core
|
|
Inkscape package. Also, certain extensions may be so critical to
|
|
Inkscape operation (such as for printing) that they should be included
|
|
in the core.
|
|
|
|
If your extension seems like it should be incorporated into the Inkscape
|
|
core, contact the Inkscape developers about this, and discuss how best
|
|
to include it in the distribution with them.
|
|
|
|
=== Conclusion ===
|
|
|
|
It is anticipated that the incorporation of this extensions capability
|
|
will bring Inkscape added power and flexibility while avoiding bloating
|
|
the core with cool-but-rarely-used functionality. Further, it empowers
|
|
users and non-core Inkscape developers to extend the application with
|
|
their own new capabilities, without needing to gain special access and
|
|
acceptance by the project. Dynamic loading of functionality will also
|
|
allow Inkscape to remain 'lean and mean', loading up functionality on an
|
|
as-needed basis, and conserving memory by unloading functionality when
|
|
it is not needed.
|
|
|
|
The key point of this design specification is the architectural concept
|
|
of separately identifying an extension's interface type, or 'Extension
|
|
Type', from its implementation method, or 'Extension Implementation'.
|
|
This feature enables Inkscape to be extended in a variety of mechanisms,
|
|
including ways not yet foreseen.
|
|
|
|
|
|
=== History and references ===
|
|
|
|
Base design taken from Ted Gould's Extension System work.
|
|
|
|
This document originally authored by Bryce Harrington, July 2004
|