Some Research for ScripterNG


Evaluation of current Scripter

Written by hand

This makes maintenance and extension hard if one does not know what PyArg_ParseTuple&friends mean. Besides this approach is very error-prone.

Imperative API – mostly

The plug-in exposes mainly functions to Python. Normally it would make sense that each object on the Scribus canvas is represented by a Python object. Instead the API works with (unique) names as handles which have to be passed as arguments to functions to access and manipulate particular canvas objects. There are also inconsequences, e.g there is an object for PDF export which indeed should better be a function with keyword arguments.

On the other hand there are good reasons for a simple imperative API. This enables even beginners quick success without having to learn about object-oriented programming. Therefore a new API should not use objects exessively. The use of advanced techniques like factory classes should be avoided.

Stateless API

If a script is called, it first has to investigate the current state, if it can run and how. This work should not be needed. Imagine there is a sane script which resizes a selected text box and appends “lorem ipsum..”. It has to do the following

Problems with measurement units

As the previous example showed a script always has to lookup and change the measurement units. This makes the code unnecessarily complicated. Besides, understanding the complete script code requires to find the last setUnit-call to know which unit is set. A better approach would be to use one defined internal unit plus some helper functions for conversion.

Integration

Currently to call scripts you have to browse them by filename in a standard open-file-dialog. There is no title or description and scripts are not ordered by any category. If you want to repeat a script, you have to find the file again in the open-file-dialog. This makes working with scripts hard and the typical user will probably not know what functionality is available via scripts. A better way would be a script menu similar to the effects menu in Inkscape (http://www.ekips.org/comp/inkscape/inx/InkexEffects.png). Scripts also cannot have keyboard shortcuts.

Missing features

Not everything that is possible in Scribus is also possible in Scripter. These limitations become noticeable sooner or later while writing scripts. This should be changed little by little.

Missing in current Scripter


Evaluation of scripting in other applications

It is always good to look beyond one's own nose so we can learn from other people's experiences. I selected some of the major applications which all support scripting.

Firefox

The core of the web browser including the rendering engine is programmed in C/C++. Nearly everything else is programmed in JavaScript. Support for Python is planned (http://wiki.mozilla.org/Gecko_1.9_Roadmap#Python_for_XUL). The whole user interface can be completely modified with JavaScript and a XML-user interface description language (XUL).

OpenOffice.org

OOo can be extended with a VisualBasic-like language, Java and Python. With the upcoming release they plan to improve extension support to a level similar to Firefox. The OOo component model exposes a lot of the functionality to scripts. Unfortunately this is also a problem because the API is q uite complex and you have to spend a lot of time to learn and to understand it completely.

Blender

This popular 3D modeler can be extended and automated with Python. It has a nice object-oriented API which reflects the objects you see in Blender.

Gimp

Plug-ins and scripts in Gimp are external programs. They can be programmed in C, Scheme (Script-Fu, similar to Lisp in Emacs), Python and Perl.

Inkscape

Inkscape can use any language for scripting because it works the Unix-way by using pipes which manipulate the SVG document. But most scripts and extensions seem to use Python, Perl or Bash. For Python there is a helper module called inkex which helps to create extensions. For each script there is a .inx-file in XML-format which describes the extension (dependencies, menu name, category, etc.).

This approach could also be very interesting for Scribus.

KOffice

Krita, KWord, and KSpread contain scripting plug-ins which support Ruby, JavaScript and Python.

Python scripts can use PyQt to create integral GUI elements like dockwidgets.

Quantum GIS

Quantum GIS has a totally different target group, because it is a geographical application. But is interesting for this evaluation because it also uses the Qt framework and strongly incorporates scripting. The QGIS code looks very clean. Hence is is possible to wrap the API nearly automatically. Python plug-ins can be installed from online repositories at runtime with a plug-in installer. Is is also possible to write complete applications in Python which use QGIS as a library.

In Scribus there come up questions regularly if one can use Scribus as an engine for PDF creation. This would be possible if the Scribus core could be used as a library from Python as well. But unfortunately we are still far away from the realization of this idea.



Evaluation of scripting technologies

Completely written by hand: Python C-API (Scribus)

This will probably result in the fastest bindings. But they are not fast to write. The code is very verbose because parameters need to be parsed and converted, references have to be counted and errors have to be handled correctly.

Bindings generators: swig, boost, sip (QGIS)

Ideally you only have to copy the header files. Then the program would generate the calls to the Python API. But some data structures or return types are not supported in Python and so you have to write some additional code for these cases. Besides every program has its flaws. Swig is not good for C++, boost is hard to debug and sip has a sparse documentation. But sip is the best tool if you want to use Qt because it handles Qt's special features like signals/slots.

Binding languages: Pyrex/Cython

You still have to write bindings but in a more friendly language which looks mostly like Python and contains everything to write bindings. This is a nice idea but I see no real advantage for Scribus.

Dynamic invocation: ctypes, dl-module

Unfortunately this only works great with C libraries but not for C++ because there is no common ABI (application binary interface).

Component models: UNO (OpenOffice), XPCOM (Firefox), Corba

This is the “enterprise-solution” to the scripting problem. Methods are defined in a IDL (interface description language) and are compiled with a separate idl-compiler. For most projects this is totally overkill, requires a strong software architecture and discipline. Distributed objects across the network might be a cool feature but are normally not needed.

Qt specific: Kross (KOffice), Smoke, PythonQt

The Qt meta-object-compiler (moc) generates code with meta-data which make it possible to query and call properties, slots and signals at runtime. With this concept no additional binding-code is needed for a scripting language to work with any Qt object.




Ideas which could be done with ScripterNG