Ted,
I've written up a first draft of a proposal specification for the Extensions System. This derives heavily from your extensions code, although I've made some tweaks here and there, such as using 'isx' instead of 'inkmod' and some terminology changes.
There is still a good bit of work to be done on it. The API's need to be reviewed, displayed in a more consistent manner, and more thoroughly documented, for example. Also, it needs more and better examples. There are probably also a number of places where it is unclear or ambiguous, so those areas will need a lot more work.
But I think it's fleshed out enough that it is ready for some review. Read it over when you get a chance, and we can talk about it more in a couple of weeks. :-)
http://inkscape.org/cgi-bin/wiki.pl?ExtensionArchProposal
Bryce
=== 1.0.0 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.
=== 2.0.0 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 .o 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 recieves and sets SVG data through files and pipes. This allows Inkscape to use programs that handle SVG but are targeted differently, seemlessly inside of Inkscape.
* Language Binding - A special type of plug-in that wrappers a script 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.
* ISX - 'InkScape eXtension' - The filename extension used for XML metadata files that describe each Inkscape Extension.
=== 3.0.0 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 styles, adding/removing defs and elements, etc. * 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
=== 4.0.0 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 Types 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
Extension Implementations Internal - code callable directly within Inkscape, 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. Library - a collection of SVG files that can be queried and loaded from the file system into the document. Each item in a library has a thumbnail and metadata.
=== 5.0.0 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.
==== 5.1.0 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.
class Extension { gchar * id; gchar * name; state_t state; SPRepr * repr; GSList * parameters;
public: void set_state (state_t in_state); state_t get_state (); bool loaded (); virtual bool check (); SPRepr * get_repr (); gchar * get_id (); gchar * get_name (); void deactivate (); bool deactivated (); void get_param (gchar * name, bool * value); void get_param (gchar * name, int * value); void get_param (gchar * name, gchar ** value); bool set_param (gchar * name, bool value); int set_param (gchar * name, int value); gchar * set_param (gchar * name, gchar * value); };
==== 5.2.0 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 recently-used extensions, or all Input extensions).
===== 5.2.1 Extension Attributes =====
name - the human readible name of the extension, with spaces and capitalization, suitable for display in dropdown menus. E.g. 'Dia Import'
id - a unique key for identifying the extension, using the java-style naming convention. E.g., 'org.inkscape.input.dia'
last_used - an indicator of the time that the extension was last invoked. This permits Inkscape to identify extensions not in regular use, and unload them to conserve memory.
num_used - the number of times the extension has been used since program start-up. This allows Inkscape to keep heavily used extensions in memory, even if they've not been used in a while.
===== 5.2.2 Extension Functionality =====
load - allocates memory usage when extension is to be used. E.g., loadable libraries can be loaded up
unload - deallocates memory when extension is not in use, to help conserve memory. E.g., loadable libraries can be freed
register - called by the Extension constructor to add the extension to the Extension Registry
unregister - called by the Extension destructor to dereference the extension from the Extension Registry
===== 5.2.3 Refreshing Registry =====
Inkscape will have a command accessible from its menus for reloading the entirety of the registry. This provides a mechanism for the user to access newly-installed extensions without needing to restart Inkscape.
When the registry is refreshed, all currently-loaded extensions should first be unloaded. When refreshed, no extensions (except for the standard defaults) should be loaded in memory.
==== 5.3.0 Handling Preferences ====
Extensions may wish to persist certain values or settings selected by the user or specified at installation time.
User settings can be handled via the Inkscape Preferences system. This is particularly appropriate for setting expected to change during use and that have suitable defaults that can be used if this is the first time the user has run it. See section 7.1.6 for details on use of this system.
Installation settings are best handled by writing into the extension metadata file (*.isx, see below) during installation. These files are stored in a global location and shared by all users on the system, thus are appropriate for storing general defaults or values that won't change during use. This is covered in the following section.
==== 5.4.0 ISX File Format ====
Every Extension must have a definition file, *.isx. Inkscape loads these files during initialization (and subsequently as requested) to learn what extensions are available to it. The file is an XML format with a top-level element 'inkscape-extension', which contains the following sub-elements:
name - required id - required version - required deps - optional; lists the dependencies type - "input", "output", etc. impl - "internal", "script", "plug-in", etc.
The deps section contains a list of elements that indicate pre-requisites for use of the extension. For instance, it may require that other extensions be present, or require a certain version level of internal functionality, or require the presence of a certain file in the file system, or require a certain service be active like a database or mail service. Each dependency can also be marked as required or optional, or if it satisfies another dependency.
Deps type - required; "extension", "file", "service", etc. id - required; the identity of the dependency it requires. E.g., 'org.inkscape.dia_import', '/etc/foo.conf', 'mysqld' version - optional; a simple regexp pattern used to find if the available version is sufficient to satisfy the dependency required - if present, the dependency is required; if not present, it's treated as an optional dependency satisfies - optional; gives a list of other deps that it will satisfy. For instance, either 'postgres' or 'mysql' could satisfy a 'sql_database' dependency.
The type and impl elements can contain sub-elements of their own:
Type extension mimetype filetypename filetypetooltip
Impl command helper_extension check
Also see section 8.4.0.
==== 5.5.0 Checking Dependencies ====
Inkscape loads all of the *.isx files by default. Later, it performs a dependency check on all of the extensions, dropping any whose dependency needs have not been met. This is performed by first checking that there is a valid extension id matching the deps->id, and then comparing each of the deps->version regexp patterns against the available extension version.
==== 5.6.0 Accessing the Inkscape Internal APIs ====
Extensions interact with the published API's of other extensions and with Inkscape itself. Inkscape provides its internal functionality via special "Internal" Extensions. See Section 7.1 for details of what is available.
The manner that the internal API's are invoked is dependent on the kind of Extension Implementation. Plug-ins, for instance, generate messages that are returned to the application. Scripts, on the other hand, do not handle messages or work interactively, but instructions can be passed via commandline arguments.
=== 6.0.0 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.
==== 6.1.0 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 incomming file and extension my 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 Ouput functions, and a user expects to be able to open and save without using the 'Save As...' dialog.
class Input : public Extension { gchar * mimetype; // What is the mime type this inputs? gchar * extension; // The extension of the input files gchar * filetypename; // A userfriendly name for the file type gchar * filetypetooltip; // A more detailed description of the filetype gchar * output_extension; // Setting of what output extension should be used
virtual bool check (); SPDocument * open (gchar const *uri); gchar * get_extension (); gchar * get_filetypename (); gchar * get_filetypetooltip (); GtkDialog * prefs (gchar const *uri); };
==== 6.2.0 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.
class Output : public Extension { gchar *mimetype; // What is the mime type this inputs? gchar *extension; // The extension of the input files gchar *filetypename; // A userfriendly name for the file type gchar *filetypetooltip; // A more detailed description of the filetype bool dataloss; // The extension causes data loss on save
public: virtual bool check (void); void save (SPDocument *doc, gchar const *uri); GtkDialog * prefs (); gchar * get_extension(); gchar * get_filetypename(); gchar * get_filetypetooltip(); };
==== 6.3.0 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.
class Effect : public Extension {
public: virtual bool check (); GtkDialog * prefs (); void effect (SPDocument * doc); };
==== 6.4.0 Print ====
The Print Extension Type is for extensions that interface with printing subsystems. Examples would be Win32, postscript, and GNOME Print.
class Print : public Extension { SPItem *base; NRArena *arena; NRArenaItem *root; unsigned int dkey;
public: bool check ();
/* FALSE means user hit cancel */ unsigned int setup (); unsigned int set_preview ();
unsigned int begin (SPDocument *doc); unsigned int finish ();
/* Rendering methods */ unsigned int bind (NRMatrix const *transform, float opacity); unsigned int release (); unsigned int fill (NRBPath const *bpath, NRMatrix const *ctm, SPStyle const *style, NRRect const *pbox, NRRect const *dbox, NRRect const *bbox); unsigned int stroke (NRBPath const *bpath, NRMatrix const *transform, SPStyle const *style, NRRect const *pbox, NRRect const *dbox, NRRect const *bbox); unsigned int image (unsigned char *px, unsigned int w, unsigned int h, unsigned int rs, NRMatrix const *transform, SPStyle const *style); unsigned int text (char const *text, NR::Point p, SPStyle const *style); bool textToPath (); };
=== 7.0.0 Extension Implementations ===
==== 7.1.0 Internal ====
Access to Inkscape internals is provided through the Internal classes. These classes expose APIs for various compiled-in functionality that can be used by other extensions.
The Internal functionality is grouped into different sets, as follows.
===== 7.1.1 File Operations =====
Ability to load/print/save/close documents
doc file_open (gchar * uri, Inkscape::Extension::Input * ext)
bool file_save (SPDocument * doc, gchar * uri, Inkscape::Extension::Output * ext)
bool print_doc (SPDOcument * doc)
===== 7.1.2 SVG DOM Object Hierarchy =====
Access to the document's SVG::DOM object hierarchy
array getElements(string element_name) string getElementName() string getElementByID(string id) string getElementID() hash getAttributes() string getAttribute(string attribute) bool SetAttribute(string name, string value) bool SetAttributes(hash) bool hasChildren() array getChildren() obj getFirstChild() obj getLastChild() array getSiblings() obj getNextSibling() obj getPrevSibling() int getChildIndex() obj getChildAtIndex(int index) obj getParent() array getParents() bool isAncestor(obj) bool isDescendant(obj) cdata getCDATA()
===== 7.1.5 Inkscape Verbs =====
A verb is an identifier used to retrieve standard Actions for particular views. Verbs are used to invoke a wide variety of operations, called Actions, in the Inkscape application. For instance, typical verbs include 'FileOpen', 'FileImport', 'EditDuplicate', 'SelectionLower', 'ObjectToCurve', 'DrawText', 'ToggleGrid', and the like. Essentially, everything invokable via a menu in Inkscape can be similarly activated using its verb.
The following routines are provided to extensions in order to interact with the verb system:
int verb_find(string verb_name) - looks up the numerical ID of the given verb name. (E.g., it could pull it out of the SPVerbActionDef props[] static object)
action verb_get_action(int verb, view) - retrieves the Action object for the verb in the given view
view action_get_view(action) - retrieves the view, given the action object
void action_perform(action, data, pdata) - invokes the Action for the verb. It validates the parameters and calls the appropriate listener that will handle the action.
void action_set_active(action, state, data)
void action_set_sensitive(action, state, data)
===== 7.1.6 Inkscape Preferences =====
These Internal methods permit access to the Inkscape Preferences system. Extensions can look up, set, or add values to the user preferences, and they will be persistently stored in the file ~/.inkscape/preferences.xml
void prefs_set_int_attribute(string path, string attr, int value);
int prefs_get_int_attribute(string path, string attr, gint def);
int prefs_get_int_attribute_limited(string path, string attr, int def, int min, int max);
void prefs_set_double_attribute(string path, string attr, double value);
double prefs_get_double_attribute(string path, string attr, double def);
double prefs_get_double_attribute_limited(string path, string attr, double def, double min, double max);
string prefs_get_string_attribute(string path, string attr);
void prefs_set_string_attribute(string path, string attr, string value);
void prefs_set_recent_file(string uri, string name);
string[] prefs_get_recent_files();
See HandlingPreferences in Wiki for further details.
===== 7.1.7 Stock SVG Defs =====
These routines provide access to the default SVG defs in Inkscape, including things like gradients, markers, and patterns. Note that this does not cover the defs in the documents themselves, which can be accessed via the document's SVG DOM.
obj get_stock_item(string urn) - returns a pointer to an instance of the desired stock object in the current doc, importing the object if necessary.
void set_stock_item_from_svg(???) - adds a new stock SVG def to the Inkscape Application. All currently loaded and new documents will have access to the item.
===== 7.1.8 Extension based variables
These are the variables that control settings for the individual extension. Things that are held internally, but should be saved with the Inkscape preferences. These are:
get_param (gchar * name, [bool, int, gchar *] data) - This function gets the variable by the name 'name' with the data in 'data'. It can be a boolean, integer or a string.
set_param (gchar * name, [bool, int, gchar *] data) - This function sets the variable by the name 'name' with the data in 'data'. It can be a boolean, integer or a string. In the case of the string it is copied.
For examples of API functions, see the perl SVG, SVG::DOM, et al modules
===== 7.1.9 Extension Manager =====
The Extension Manager Extension enables extensions such as Plug-ins to access other extensions.
acquireExtension(extension_name, extension_version, &ext_obj);
releaseExtension(extension_name, extension_version);
==== 7.2.0 Scripts ====
Script Extensions are external executables that Inkscape can invoke to enact needed changes. A Perl script such as ill2svg.pl is a typical example, but the Script Extension actually need not be a scripting language at all - it could be a binary application such as Sketch. The key thing is that it must operate like a commandline utility, taking input from STDIN and producing its changed version to STDOUT.
The class Extension::Implementation::Script is the interface to the scripts, and includes the following methods:
SPDocument *open(Extension *key, gchar const *filename);
void save(Extension *key, SPDocument *doc, gchar const *filename, bool setextension, bool check_overwrite, bool official);
void filter(GtkObject *object, gchar const *key);
Print * get_print(gchar const *key);
Extension * build_from_file(gchar const *filename);
Extension * build_from_mem(gchar const *buffer, Implementation *in_imp);
==== 7.3.0 Plug-Ins ====
Plug-ins are extensions implemented via loadable modules such as DLL's (on Windows) or .so's (on *nix), using C linkage. Each plug-in has a message handler function that Inkscape can call.
A plug-in is able to request access to blocks of functionality, such as data structure functions or UI elements. The plug-in can use the blocks of functionality it has been granted access to. The plug-in can also publish its own block of functions, to be used by other plug-ins.
Each block of functionality can be versioned, so that interfaces can change with backwards compatibility later.
===== 7.3.1 Plug-in Shared Object Format =====
A Plug-in must define a function with C binding to create the extension. This function creates an Extension object for itself and returns the memory pointer:
extern "C" void *CreateExtension() { return (void *)new MyPluginExtension(); }
The Plug-in's Extension returned by this function must behave according to the Extension base class; it must provide member functions for load, unload, register, and unregister.
Additionally, Plug-ins must support the following interface:
error do_message(char *message_sender, char *message_category, char *message_action, void *data, void *extensions)
All Plug-ins must handle the following five message actions:
'load' - load into memory and setup or restore state info 'unload' - unload from memory, saving state info if appropriate 'startup' - allocate global memory, add UI elements, register, etc. 'shutdown' - flush files, preserve preferences, etc. 'about' - info about the plug-in
Additionally, the Plug-in will receive messages particular to its Extension Type. File export extensions will receive the 'save' message, for example. Inkscape will indicate a message_action each time it calls the Plug-in, to specify what should be done or to signal it that an event has occurred.
The Plug-in may register listeners for events that it would like Inkscape to notify it about. Plug-ins can also generate their own events to send to other extensions.
The data argument of the do_message() routine permits passing an arbitrary structure to the Plug-in. The type of structure used is indicated by the message_category parameter. For example, this data object can provide a way for the plug-in to preserve information between calls (such as in a memory block allocated by the Plug-in during startup that will be preserved if the Plug-in is unloaded and loaded).
The extensions argument is a collection of interfaces to other extensions that the Plug-in is allowed to call. These enable the Plug-in to access other functionality within Inkscape. Typically, these will be Internal Extensions (see Section 7.1), which provide access to core functionality in Inkscape, but from the Plug-in's perspective it is transparent whether the extensions it uses are internal core functionality or other external plugins.
To use a function in another extension, the Plug-in must first 'acquire' the extension. This lets Inkscape know that it should load the extension into memory if it isn't already. When it has finished with the extension, the Plug-in should 'release' the extension, allowing Inkscape to recover the memory for other things if needed.
When the Plug-in is first called, it will be passed a single extension, the ExtensionManager. The Plug-in can then request additional extensions through it.
===== 7.3.2 Plug-in Initialization Algorithm =====
On the application side, Inkscape uses the following pseudocode to load the Plug-in:
// determine the path and filename of the shared object filename = "/usr/share/inkscape/extensions/foo/foo.so"
// load the library and get the extension creation function #if USE_DLOPEN void *obj = dlopen(filename, RTLD_LAZY|RTLD_GLOBAL) f_createExtension = dlsym(obj, "CreateExtension")
#else HMODULE obj = LoadLibrary(filename)
f_createExtension = GetProcAddress(obj, "CreateExtension") #endif
extension = (Extension *) f_createExtension()
// When the extension is needed, load it into memory extension->load()
// Pass messages to and from the extension extension->do_message(my_message)
// When done, remove it from memory extension->shutdown()
See experimental/extension_example in Inkscape CVS for a working example.
===== 7.3.3 Scripting Language Bindings =====
Scripting support is provided via special kinds of Plug-Ins called Language Bindings. These provide loadable script interpreter modules. These may be useful for users to quickly program custom functionality, for testers to automate testing procedures, and so forth.
These bindings can be operated in one of three ways:
Document - The code to be interpreted is embedded in the SVG document itself. The language interpreter thus parses the document and invokes a given function within it. For example, it could run some embedded ECMA script.
User - The code to be interpreted is typed in by the user themselves. For example, this could be done via a pop-up text editor dialog the user types or pastes code into, or it could be passed to Inkscape via its STDIN when using inkscape in commandline mode, or it could be provided by another extension (such as one that loads it from a database).
File - The code to be interpreted is loaded from a file stored in the file system.
===== 7.4.0 SVG Libraries =====
Library Extensions are interfaces to collections of data files that can be queried and loaded directly into the document.
int library_count(query_condition) - returns the quantity of items meeting the query condition.
item[] library_list(query_condition, int start, int end) - returns a list of items meeting the query condition. Optionally, the requestor can specify that a subset specified by [start,end] be returned (this is for paging purposes).
doc library_get_item(id) - retrieves a specific item from the library.
Each item in a library has the following data items associated with it:
id - the unique identifier for the library item thumbnail - a rendered bitmap that illustrates what the item would look like in the document. metadata - a collection of RDF data for the object, including information such as the author, license, title, etc.
=== 8.0.0 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.
==== 8.1.0 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.
Library Extensions are basically collections of symbols that can be queried, browsed, and imported into documents in Inkscape. An example might be drawing symbols for electrical diagrams.
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 can be used directly by Inkscape, such as in the case of compiled-in printing modules, or used by other extensions, such as to provide access to the verb system.
==== 8.2.0 Writing Your Extension ====
This section provides some guidance and examples for implementing different kinds of Extensions.
===== 8.2.1 Writing Internal Extensions =====
# TODO
===== 8.2.2 Writing Script Extensions =====
# TODO
===== 8.2.3 Writing Plug-in Extensions =====
# TODO
===== 8.2.4 Writing Language Binding Plug-in Extensions =====
# TODO
===== 8.2.5 Writing Library Extensions =====
# TODO
==== 8.3.0 Creating an ISX File ====
Every extension must have a corrosponding *.isx 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 *.isx file contains enough info for Inkscape to set up menu items and know what kinds of functionality to expect from the extension.
# TODO: Insert an example ISX XML here
==== 8.4.0 Packaging Your Extension ====
==== 8.5.0 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.
===== 8.5.1 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.
===== 8.5.2 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@...460... 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.
===== 8.5.3 Incorporating Your Extension 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.
=== 9.0.0 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.
On Sun, 18 Jul 2004, MenTaLguY wrote:
On Sun, 2004-07-18 at 17:40, bulia byak wrote:
- ISX - 'InkScape eXtension' - The filename extension used for XML metadata files that describe each Inkscape Extension.
"inx" sounds much better than "isx", IMHO. Easier to remember and pronounce.
Seconded.
I've made this alteration in the document. Neither inx nor isx appear to be common file format extensions so we look reasonably safe either way.
Of course, you do realize that users aren't going to be exposed to this file - it's just the metadata file for extensions (what we currently call inkmod - I figured 3 letters and something without 'module' in the name was necessary.)
Bryce
On Sun, 18 Jul 2004, bulia byak wrote:
Date: Sun, 18 Jul 2004 18:40:49 -0300 From: bulia byak <buliabyak@...400...> To: Bryce Harrington <bryce@...260...> Cc: inkscape-devel@lists.sourceforge.net Subject: Re: [Inkscape-devel] Extension Proposal (First Draft)
- ISX - 'InkScape eXtension' - The filename extension used for XML metadata files that describe each Inkscape Extension.
"inx" sounds much better than "isx", IMHO. Easier to remember and pronounce.
I quite like that.
If you had more than one of them they'd be Ozzie rockband INXS (resisting temptation to make crude joke).
But still this system might be good enough that Gnome-Office will want to take part.
It is probably better not to heavily brand it with Inkscape (how much hassle was it changing all the sodipodi branding?)
Would it be so bad to use the .xml extension? The context of these files might be enough to identify them without a funky file extension.
.xml is probably already associated with a text (or sometimes even a specialised xml) editor and by using .xml there will be no need to educate other applicatins about this new format.
- Alan
On Tue, 2004-07-20 at 11:20, Alan Horkan wrote:
Would it be so bad to use the .xml extension? The context of these files might be enough to identify them without a funky file extension.
.xml is probably already associated with a text (or sometimes even a specialised xml) editor and by using .xml there will be no need to educate other applicatins about this new format.
Well, I don't think we've ever really intended for other applications to use this format. Another thing that it saves us is actually having to look at files and detect what they are. Now we're pretty much assuming that an 'inkmod' file is a module definition - a .xml file would probably require more validation and checking. I don't know that we really gain anything by having other applications understand this format.
--Ted
On Wed, 21 Jul 2004, Ted Gould wrote:
Date: Wed, 21 Jul 2004 00:16:00 -0700 From: Ted Gould <ted@...11...> To: inkscape-devel@lists.sourceforge.net Subject: Re: [Inkscape-devel] Extension Proposal (First Draft)
On Tue, 2004-07-20 at 11:20, Alan Horkan wrote:
Would it be so bad to use the .xml extension? The context of these files might be enough to identify them without a funky file extension.
.xml is probably already associated with a text (or sometimes even a specialised xml) editor and by using .xml there will be no need to educate other applicatins about this new format.
Well, I don't think we've ever really intended for other applications to
I realise that but my point was that it would only require minor changes to keep that option open.
use this format. Another thing that it saves us is actually having to look at files and detect what they are. Now we're pretty much assuming that an 'inkmod' file is a module definition - a .xml file would probably require more validation and checking. I don't know that we really gain anything by having other applications understand this format.
Again it is not so much other applications understanding the format so much as having the immediately be able to recognise them as XML without requiring any magic.
In terms of the file extension I am thinking of wanting to have .xml associated with either your favourite text editor (vim, emacs, nano, kate, nedit, whatever) or your favourite genric XML editor (conglomerate, mlview, vex, kxmleditor, xmlspy). It is not about the other applications understanding the actual format of the xml so much as not putting up any barriers to editing it in your favourite (XML) editor. Changing the extension means needing to add mime types or associations.
I would urge you to keep using .xml for the reasons I have outlined until there are a specific benefits to using a different extension.
-- Alan Horkan
Alan Horkan wrote:
Again it is not so much other applications understanding the format so much as having the immediately be able to recognise them as XML without requiring any magic.
That's pretty much a non-issue. Most every XML-savvy editor will autodetect an XML file from it's preamble.
In terms of the file extension I am thinking of wanting to have .xml associated with either your favourite text editor (vim, emacs, nano, kate, nedit, whatever) or your favourite genric XML editor (conglomerate, mlview, vex, kxmleditor, xmlspy). It is not about the other applications understanding the actual format of the xml so much as not putting up any barriers to editing it in your favourite (XML) editor. Changing the extension means needing to add mime types or associations.
And what ammount of work is needed for that?
In general, just double-click on the .inx file, the OS will ask what program to open it with and give you a checkbox to remember the choice.
That's all. Problem solved in a few seconds, only once for any given user/computer. So it's both trivial to solve and rarely encountered.
I would urge you to keep using .xml for the reasons I have outlined until there are a specific benefits to using a different extension.
I would urge to avoid ".xml" as much as possible. That's overloading a generic term with specific meaning. In general, the concept is akin passing all parameters in Java as String or Object, or passing all parameters in C/C++ as void *.
What about people who want to edit .inx in a different XML editor than other types? If you overload the name, there is no easy way for them to do it. However, if it has a different name, then it is trivial for a user to have a single application open both that and .xml, but still allows a different user to assign specific editors to specific file types.
Aditionally, I work with many different types of XML files constantly. (My first step when documenting anything is to write a .xml and a .xsl to generate HTML from it, etc.). There's a *huge* benefit also in being able to browse a directory and sort by extension to see the different types of files.
Just imagine if Microsoft had called .ini files .txt files instead. That's pretty much the route you're advocating.
On Wed, 21 Jul 2004, Jon A. Cruz wrote:
Date: Wed, 21 Jul 2004 09:17:45 -0700 From: Jon A. Cruz <jon@...18...> To: inkscape-devel@lists.sourceforge.net Subject: Re: [Inkscape-devel] Extension Proposal (First Draft)
Alan Horkan wrote:
Again it is not so much other applications understanding the format so much as having the immediately be able to recognise them as XML without requiring any magic.
That's pretty much a non-issue. Most every XML-savvy editor will autodetect an XML file from it's preamble.
you are presuming opening the application first and opening the document from there. I'm thinking of clicking on a document from withing a file manager. Of course if the new extension is properly registered the point is moot, but the small point I'm making is that you would need to bother adding any sort of association if the file was named .xml
And what ammount of work is needed for that?
In general, just double-click on the .inx file, the OS will ask what program to open it with and give you a checkbox to remember the choice.
i dont know about you but I find the interface for that in Windows to be slightly unpleasant and downright horrible in Gnome.
That's all. Problem solved in a few seconds, only once for any given user/computer. So it's both trivial to solve and rarely encountered.
if the extension was left as .xml it wouldnt be necessary at all.
What about people who want to edit .inx in a different XML editor than other types? If you overload the name, there is no easy way for them to
there is no benefit _yet_ in associating the files with anything especially, if and when there is a benefit I'll drop the objection.
Just imagine if Microsoft had called .ini files .txt files instead. That's pretty much the route you're advocating.
ini files are by default associated with a text editor
if the proposed extensions will be automatically be associated with some useful applications without users needing to do anything extra I wouldn't have an objection.
now that I think of it the .inx files would probably want to be associated with Inkscape.
- Alan
Alan Horkan wrote:
you are presuming opening the application first and opening the document from there.
Well, actually I was thinking of once an application is sent a doc, generally by double-clicking on it in some file manager. The app gets opened and fed a file, at which point it can figure out what it is.
I'm thinking of clicking on a document from withing a file manager. Of course if the new extension is properly registered the point is moot, but the small point I'm making is that you would need to bother adding any sort of association if the file was named .xml
Actually, I don't.
I just copied a file to have both .xml and .inx versions. Nautilus tried to preview the .svg version, but then drew the generic SVG icon for the .xml and .inx versions with no work at all on my part. They all show up with a MIME type of image/svg when I right-click on them and get properties.
Also... when I double-click them, they all open up in an automatically-spawned instance of Sodipodi.
So my guess would be that the file manager recognized them as XML and then further knows how to inspect XML and take a peek at doctypes and such to know what it is.
And what ammount of work is needed for that?
In general, just double-click on the .inx file, the OS will ask what program to open it with and give you a checkbox to remember the choice.
i dont know about you but I find the interface for that in Windows to be slightly unpleasant and downright horrible in Gnome.
Then your Gnome must be very different from mine.
I just right-click and pick "open with" and choose the app.
Then I can also add the new mime type with minimal effort.
there is no benefit _yet_ in associating the files with anything especially, if and when there is a benefit I'll drop the objection.
Actually, for me there *is* a benefit today. I can get them to open in Emacs instead of Mozilla. I'd want to edit them, not view them as raw XML.
Oh, and if I create a new file with XML content but an unknown extension, it opens it with the default text editor. Sounds like about what I'd want it to do for general users.
On Wed, 21 Jul 2004, Jon A. Cruz wrote:
Date: Wed, 21 Jul 2004 10:42:29 -0700 From: Jon A. Cruz <jon@...18...> To: inkscape-devel@lists.sourceforge.net Subject: Re: [Inkscape-devel] Extension Proposal (First Draft)
Alan Horkan wrote:
you are presuming opening the application first and opening the document from there.
Well, actually I was thinking of once an application is sent a doc, generally by double-clicking on it in some file manager. The app gets opened and fed a file, at which point it can figure out what it is.
I'm thinking of clicking on a document from withing a file manager. Of course if the new extension is properly registered the point is moot, but the small point I'm making is that you would need to bother adding any sort of association if the file was named .xml
Actually, I don't.
I just copied a file to have both .xml and .inx versions. Nautilus tried to preview the .svg version, but then drew the generic SVG icon for the .xml and .inx versions with no work at all on my part. They all show up with a MIME type of image/svg when I right-click on them and get properties.
Also... when I double-click them, they all open up in an automatically-spawned instance of Sodipodi.
So my guess would be that the file manager recognized them as XML and then further knows how to inspect XML and take a peek at doctypes and such to know what it is.
Nautilus has an option to determine file type other than by file extension, an option I turn off for performance reasons. (I thought it was the default but I must be mistaken).
Then your Gnome must be very different from mine.
I just right-click and pick "open with" and choose the app.
Try opening it with an application not already included on your 'open with' list. It is just messy and unpleasant.
Actually, for me there *is* a benefit today. I can get them to open in Emacs instead of Mozilla. I'd want to edit them, not view them as raw XML.
does that not just mean that the having Mozilla as your defualt instead of Emacs what is wrong?
Oh, and if I create a new file with XML content but an unknown extension, it opens it with the default text editor. Sounds like about what I'd want it to do for general users.
pretty close yeah.
Further to your point about ini files, surely there is an existing XML based format for configuration files could be used rather than needing something overly inkscape specific?
- Alan
On Wed, 2004-07-21 at 13:58, Alan Horkan wrote:
Then your Gnome must be very different from mine.
I just right-click and pick "open with" and choose the app.
Try opening it with an application not already included on your 'open with' list. It is just messy and unpleasant.
But you should only have to do it once -- and how many end-users will be editing these files?
Actually, for me there *is* a benefit today. I can get them to open in Emacs instead of Mozilla. I'd want to edit them, not view them as raw XML.
does that not just mean that the having Mozilla as your defualt instead of Emacs what is wrong?
Well, there we also get into issues of "open" (view) versus "edit" being separate verbs (or not) in the desktop environment as well..
Oh, and if I create a new file with XML content but an unknown extension, it opens it with the default text editor. Sounds like about what I'd want it to do for general users.
pretty close yeah.
Further to your point about ini files, surely there is an existing XML based format for configuration files could be used rather than needing something overly inkscape specific?
It's probably worth looking at other configuration formats, but I think we're better of using a specialized schema rather than trying to shoehorn in something _too_ generic (like OS X proplists).
By the way, while I think it's a good idea to have extension preferences in separate XML files from the main preferences, I would like to preserve a single namespace for preferences as viewed from the actual preferences API.
That might involve something like "mounting" a file into the namespace (but that should be handled automatically as part of extension registration/unregistration).
-mental
On Wed, 2004-07-21 at 19:59, MenTaLguY wrote:
By the way, while I think it's a good idea to have extension preferences in separate XML files from the main preferences, I would like to preserve a single namespace for preferences as viewed from the actual preferences API.
That might involve something like "mounting" a file into the namespace (but that should be handled automatically as part of extension registration/unregistration).
I don't like this, and I think the biggest reason is that I'd like to see us eventually move use something like GConf for configuration in the future. And, putting things in different files pretty much excludes us from doing that.
Currently, the extension preferences are put in their own group in the preferences file, and they don't touch any of the other stuff. They are identified by their ID (which should be unique) and so they aren't going to harm anything else.
I like the idea of them being more modular, but I like the idea of using GConf better (yes, I do realize that GConf won't work on all platforms).
--Ted
On Thu, 22 Jul 2004, Ted Gould wrote:
On Wed, 2004-07-21 at 19:59, MenTaLguY wrote:
By the way, while I think it's a good idea to have extension preferences in separate XML files from the main preferences, I would like to preserve a single namespace for preferences as viewed from the actual preferences API.
That might involve something like "mounting" a file into the namespace (but that should be handled automatically as part of extension registration/unregistration).
I don't like this, and I think the biggest reason is that I'd like to see us eventually move use something like GConf for configuration in the future. And, putting things in different files pretty much excludes us from doing that.
Currently, the extension preferences are put in their own group in the preferences file, and they don't touch any of the other stuff. They are identified by their ID (which should be unique) and so they aren't going to harm anything else.
I like the idea of them being more modular, but I like the idea of using GConf better (yes, I do realize that GConf won't work on all platforms).
Anyone know anything about UniConf? http://open.nit.ca/wiki/?page=UniConf
It seems like it would provide both Gconf and Windows Registry but I dont know how good it is.
- Alan H.
On Sun, 2004-07-18 at 12:34 -0700, Bryce Harrington wrote:
I've written up a first draft of a proposal specification for the Extensions System. This derives heavily from [Ted's] extensions code, although I've made some tweaks here and there, such as using 'isx' instead of 'inkmod' and some terminology changes.
[snip]
http://inkscape.org/cgi-bin/wiki.pl?ExtensionArchProposal
Doesn't this cover things (ie plugins) which are part of libgoffice? If so, what similarities does this have with the libgoffice implementation?
I guess this question is directed at Jody (unless anybody else knows).
I've sliced and diced some with internal comments. I'm very excited that this got written.
On Sun, 2004-07-18 at 12:34, Bryce Harrington wrote:
Internal - code callable directly within Inkscape,
I think this is a little unclear in the document. I guess my definition of an 'Internal Extension' would be code which is in the core of Inkscape, but would like to use the extension interfaces for consistency. These would be things like SVG save, where it is built into Inkscape and will never leave, but it is easier to have it as an 'extension' and get it listed on the same menus and such.
Inkscape will have a command accessible from its menus for reloading the entirety of the registry. This provides a mechanism for the user to access newly-installed extensions without needing to restart Inkscape.
When the registry is refreshed, all currently-loaded extensions should first be unloaded. When refreshed, no extensions (except for the standard defaults) should be loaded in memory.
Do we think this is that important? I don't think that it will be worth the pain to implement, it seems just as easy to me to restart Inkscape.
Extensions may wish to persist certain values or settings selected by the user or specified at installation time.
User settings can be handled via the Inkscape Preferences system. This is particularly appropriate for setting expected to change during use and that have suitable defaults that can be used if this is the first time the user has run it. See section 7.1.6 for details on use of this system.
Installation settings are best handled by writing into the extension metadata file (*.isx, see below) during installation. These files are stored in a global location and shared by all users on the system, thus are appropriate for storing general defaults or values that won't change during use. This is covered in the following section.
I was thinking of this a touch differently, and it is implemented a touch differently. The idea of the preferences in the inx files is that those define what they are called, and default values, but they are stored in preferences.xml just like any other preference. I don't think that, in general, extensions should be setting up user preferences. I do think that some of the extension preferences do need to be per-file instead of global.
Every Extension must have a definition file, *.isx. Inkscape loads these files during initialization (and subsequently as requested) to learn what extensions are available to it. The file is an XML format with a top-level element 'inkscape-extension', which contains the following sub-elements:
name - required id - required version - required deps - optional; lists the dependencies type - "input", "output", etc. impl - "internal", "script", "plug-in", etc.
The deps section contains a list of elements that indicate pre-requisites for use of the extension. For instance, it may require that other extensions be present, or require a certain version level of internal functionality, or require the presence of a certain file in the file system, or require a certain service be active like a database or mail service. Each dependency can also be marked as required or optional, or if it satisfies another dependency.
Deps type - required; "extension", "file", "service", etc. id - required; the identity of the dependency it requires. E.g., 'org.inkscape.dia_import', '/etc/foo.conf', 'mysqld' version - optional; a simple regexp pattern used to find if the available version is sufficient to satisfy the dependency required - if present, the dependency is required; if not present, it's treated as an optional dependency satisfies - optional; gives a list of other deps that it will satisfy. For instance, either 'postgres' or 'mysql' could satisfy a 'sql_database' dependency.
I know that we have discussed this in the past, but I'm curious whether we need a dependency system that is this advanced. I'm worried that it will move us into the Eclipse/Mozilla world of 'being a platform' which I'm not that interested in becoming.
Currently, this is being taken care of by the implementation section. If the implementation of a script requires another extension, it is taken care of there.
Now, the problem then comes with language bindings were we'd really not like to have to load the whole interpreter of a relatively unused language just to run the 'check' function.
==== 7.1.0 Internal ====
Access to Inkscape internals is provided through the Internal classes. These classes expose APIs for various compiled-in functionality that can be used by other extensions.
The Internal functionality is grouped into different sets, as follows.
I'm not sure, we may be talking about different things here... but I think of Internal extensions like what was defined above, C code that is using the extensions interfaces to make things easier. I don't really see it as APIs. But, I think most of these APIs are probably necessary writing an extension.
===== 7.1.9 Extension Manager =====
The Extension Manager Extension enables extensions such as Plug-ins to access other extensions.
acquireExtension(extension_name, extension_version, &ext_obj); releaseExtension(extension_name, extension_version);
I think this is overkill also. I don't really have a problem with one effect calling another (or something basic like that). But once we get to things like publishing APIs and the such for Extensions we might as well figure out how to embed Emacs :)
===== 7.3.2 Plug-in Initialization Algorithm =====
This looks fine for now, but I think when we get to implementing this we should probably use the g_module interface in glib.
===== 7.4.0 SVG Libraries =====
Library Extensions are interfaces to collections of data files that can be queried and loaded directly into the document.
I'm not sure if this is a good use of extensions, I think that this should probably be implemented separately. I think that it is deferent enough to warrant its own implementation.
Cool. That's my initial set of comments, I think there are various topics here that need to be discussed. Bryce, thanks for bringing them up!
--Ted
Inkscape will have a command accessible from its menus for reloading the entirety of the registry. This provides a mechanism for the user to access newly-installed extensions without needing to restart Inkscape.
When the registry is refreshed, all currently-loaded extensions should first be unloaded. When refreshed, no extensions (except for the standard defaults) should be loaded in memory.
Do we think this is that important? I don't think that it will be worth the pain to implement, it seems just as easy to me to restart Inkscape.
If I am understanding this correctly it would be particularly useful when you are developing and testing a new extension as it would allow you to refresh rather than restart the whole application each time you try out new modifications to you script. (The Gimp allows this for Scheme but not for Python (at least not that I've seen, I'm probably missing a trick) and in my early attempts to script the Gimp using Python it was frustrating trying to fix an incorrect script, needing to restart the program each time I made a minor change).
Extensions may wish to persist certain values or settings selected by the user or specified at installation time.
User settings can be handled via the Inkscape Preferences system. This is particularly appropriate for setting expected to change during use
This seems overly centralised like a registry to me and potentially brittle. perhaps each extension would keep its own preferences (lists of differnt kinds of preset values for an extension could be extensive) and the main preferences file would keep only a reference to it. by this extra seperation it could be easier to isolate problems and if an extion messed up its preferences some how it could be unloaded without messing up the main preferences file?
# include standard-disclaimer.h
all opinion, pinch of salt, etc.
Sincerely
Alan Horkana
It's in Wiki
Bryce
On Wed, 21 Jul 2004, MenTaLguY wrote:
On Wed, 2004-07-21 at 03:42, Ted Gould wrote:
I've sliced and diced some with internal comments. I'm very excited that this got written.
Er, is the extension proposal available online anywhere? I seem to have missed the original email..
-mental
On Wednesday 21 July 2004 3:42 am, Ted Gould wrote:
On Sun, 2004-07-18 at 12:34, Bryce Harrington wrote:
Internal - code callable directly within Inkscape,
I think this is a little unclear in the document. I guess my definition of an 'Internal Extension' would be code which is in the core of Inkscape, but would like to use the extension interfaces for consistency. These would be things like SVG save, where it is built into Inkscape and will never leave, but it is easier to have it as an 'extension' and get it listed on the same menus and such.
*Nod* I think it's a good idea; having this consistency should simplify other areas as well.
When the registry is refreshed, all currently-loaded extensions should first be unloaded. When refreshed, no extensions (except for the standard defaults) should be loaded in memory.
Do we think this is that important? I don't think that it will be worth the pain to implement, it seems just as easy to me to restart Inkscape.
Hmm, well if done right it shouldn't be that hard to implement, since you'd have the per-module load/unload already. I do think it's important from the standpoint of being able to test modules as well as installing modules dynamically while the app runs. It's not a huge feature, so if it can't be done, it can't be done, but it would add a convenience that I think we will want.
Extensions may wish to persist certain values or settings selected by the user or specified at installation time.
User settings can be handled via the Inkscape Preferences system. This is particularly appropriate for setting expected to change during use and that have suitable defaults that can be used if this is the first time the user has run it. See section 7.1.6 for details on use of this system.
Installation settings are best handled by writing into the extension metadata file (*.isx, see below) during installation. These files are stored in a global location and shared by all users on the system, thus stored in a global location and shared by all users on the system, thus are appropriate for storing general defaults or values that won't change during use. This is covered in the following section.
I was thinking of this a touch differently, and it is implemented a touch differently. The idea of the preferences in the inx files is that those define what they are called, and default values, but they are stored in preferences.xml just like any other preference. I don't think that, in general, extensions should be setting up user preferences. I do think that some of the extension preferences do need to be per-file instead of global.
I'm a bit confused as to what you're saying here... Could you explain a bit more what you mean?
I know that we have discussed this in the past, but I'm curious whether we need a dependency system that is this advanced. I'm worried that it will move us into the Eclipse/Mozilla world of 'being a platform' which I'm not that interested in becoming.
I don't know if we need a dependency system, but I suspect we may. If we do implement a dependency system, though, it would probably be unwise to go half-way with it; if we're going to have something we may as well make it powerful enough to handle the usual cases (multiple-dependencies, satisfies, etc.)
Currently, this is being taken care of by the implementation section. If the implementation of a script requires another extension, it is taken care of there.
But the problem with this is that it's all run-time, and seems a bit hacky.
Now, the problem then comes with language bindings were we'd really not like to have to load the whole interpreter of a relatively unused language just to run the 'check' function.
I'm not sure what you mean by this. This wouldn't be a problem if you have dependency checking since the interpreter module would only be loaded if something actually needed it.
==== 7.1.0 Internal ====
Access to Inkscape internals is provided through the Internal classes. These classes expose APIs for various compiled-in functionality that can be used by other extensions.
The Internal functionality is grouped into different sets, as follows.
I'm not sure, we may be talking about different things here... but I think of Internal extensions like what was defined above, C code that is using the extensions interfaces to make things easier. I don't really see it as APIs. But, I think most of these APIs are probably necessary writing an extension.
Yeah, I elaborated on your concept of internal extensions. It is logical: If you allow extensions to reference and use other extensions, and if you allow internal code to be used the same way as extensions, then when you need API's for the extensions to talk to, why _not_ implement the internal functional APIs as extensions? This way you have a single calling system that's used for everything. PLUS, if you ever wish to break out internal functionality into loaded modules, you don't have to redo a bunch of interfaces - the functionality could be called in the same way regardless of whether its implemented internally or as an extension.
===== 7.1.9 Extension Manager =====
The Extension Manager Extension enables extensions such as Plug-ins to access other extensions.
acquireExtension(extension_name, extension_version, &ext_obj); releaseExtension(extension_name, extension_version);
I think this is overkill also. I don't really have a problem with one effect calling another (or something basic like that). But once we get to things like publishing APIs and the such for Extensions we might as well figure out how to embed Emacs :)
Well, I did lift this concept from another extensions system, that was shooting for a pretty ambitious level of extensibility. I'm not sure I'd call it 'overkill'... 'advanced' perhaps. I do think that it is needed, though. An extension that needs to call another extension cannot blithely assume the extension is always going to be there and start making calls.
===== 7.4.0 SVG Libraries =====
Library Extensions are interfaces to collections of data files that can be queried and loaded directly into the document.
I'm not sure if this is a good use of extensions, I think that this should probably be implemented separately. I think that it is deferent enough to warrant its own implementation.
Why do you think that? You've got this very flexible system for adding new kinds of extensible functionality, why not make use of it? I'm surprised you didn't like this - it seems to fit into the concept quite well. Really, it's not that much different requesting to call a script to generate some SVG; in this case you simply request the SVG directly from file or db. Certainly the mechanisms are different, but that's the idea with Extension Implementations anyway.
Bryce
Okay,
So I think what this comes down to in general, is that I'm not in favor of extensions publishing APIs. I have no problem with one extension calling another on what ever is selected (ie one effect using another), but I'm really against publishing an API and having another extension use that API.
At my heart, I love theoretical computer science as much as the next guy (okay, probably more than the next guy), but I don't want to this to turn into a computer science project. I see no reason to write a multi-language loader into Inkscape that can resolve everything and make one big happy application. I'll leave that project to the Mono guys.
I think that, we should allow plug-ins to be dependent on external libraries. And, we should provide a way to check versioning on those libraries, but we should not provide linking. If someone comes up with functionality that is useful for a large set of Inkscape extensions, they are welcome to publish that as a library in their language of choice, and other people can use it - infact, I'd promote people using libraries like SVG.pm and the such, I just don't want to do the handling of APIs and pulling everything together.
We do, however, need to provide an API for extensions to be able to touch much of the Inkscape internals to be useful, that is a must. And we must provide some way for extensions to use that functionality. I think this should be our focus.
So, I'm sorry to hijack this thread and bring it down to this point, but I think it is an important point to discuss and come to agreement on.
--Ted
participants (8)
-
Alan Horkan
-
Bob Jamison
-
Bryce Harrington
-
bulia byak
-
Charles Goodwin
-
Jon A. Cruz
-
MenTaLguY
-
Ted Gould