diff options
Diffstat (limited to 'doc/extension_system.txt')
-rw-r--r-- | doc/extension_system.txt | 411 |
1 files changed, 411 insertions, 0 deletions
diff --git a/doc/extension_system.txt b/doc/extension_system.txt new file mode 100644 index 0000000..72ac282 --- /dev/null +++ b/doc/extension_system.txt @@ -0,0 +1,411 @@ +== 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 |