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

- look if a document is open, else exit with a meaningful message

- look if a object is selected and if it is a text object, else exit with a meaningful message

- save current measurement unit

- set own measurement unit

- resize text box

- append text

- restore old measurement unit

  Wouldn't it be better if a script could specify in its meta-data that it relies on a selected text object? Otherwise the menu entry of the script should be disabled.

### 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

- hooks into menus, toolbars and context menus

- call gettext-importer plug-in

- access and change configuration

- callbacks to events (signals)

- more functions to work with styles and text

- trigger actions

- support for i18n – currently scripts only speak English

##

## 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).

- Screenshots of add-on manager: http://wiki.mozilla.org/Firefox:Add-ons_Manager_UI_interim_rev2

- Add-on repository: http://addons.mozilla.org

### 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.

- Screenshot of extension manager: http://www.teamir8.com/pictures/extmng.jpg

- Extensions-repository: http://extensions.services.openoffice.org/

### 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.

- Script-Repository: http://www.blender.org/download/python-scripts/

- Python-API: http://www.blender.org/documentation/244PythonDoc/API_intro-module.html

### 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.

- Scripting manual: http://docs.gimp.org/en/gimp-scripting.html

- Gimp Plugin Registry: http://registry.gimp.org/list_content

### 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.

- http://techbase.kde.org/Development/Tutorials/KSpread_Scripting

- http://techbase.kde.org/index.php?title=Development/Tutorials/KWord_Scripting

- http://techbase.kde.org/index.php?title=Development/Tutorials/Krita_Scripting

### 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

- OpenClipArt (perhaps also Flickr etc) browser as a dockwidget with ability to import media into current document

- create optimized PDF for the web (http://wiki.scribus.net/index.php/Web_optimised_PDF)

- simple IRC dockwidget for live-help and collaboration

- mailmerge (http://www.assembla.com/wiki/show/scribusmailmerge)

- import anything by converting foreign media formats to known formats like HTML, ODT or SVG and then call the SVG-/gettext-importer plug-in: RTF (unrtf, pyrtf), DOC (antiword), MathML (SVGMath, http://www.grigoriev.ru/svgmath/), vector-formats (Uniconvertor)

- import using OpenOffice.org-filters via UNO-bridge (requires running OOo): http://websvn.kde.org/trunk/koffice/kword/plugins/scripting/scripts/oouno.py?view=markup

- import scanned images (Sane on Unix with Python Imaging Library)

- script editor

- script debugger

- ghns-client (get hot new stuff) for templates (http://www.kde-files.org/index.php?xcontentmode=642)

- fullscreen feature

- connect to a database or CMS

- alternative spell checker using PyEnchant

- import plots from gnuplot

- import CSV (or Excel via antixls -> CSV) into table

- calendar wizard

- advanced search&replace with regular expressions

- an alternative story editor in fullscreen format

- and of course a paper clip assistant ;)