[Scribus] Yet ANOTHER scripting bug

Craig Ringer craig
Mon Dec 3 06:45:58 CET 2007


Chris Bergstresser wrote:

> but
> with the scripting support I need I'm holding off until it's
> considered somewhat stable.

Sensible, especially since 1.3.5 (as of the last discussion I saw) is
definitely not production ready yet.

>> 1.3.3.x should generally be OK.
> 
>    Someone verified the problem earlier -- apparently the code where
> you select a range of characters and set the style on it simply fails
> under a large number of conditions.  I've no idea what "traceback" is
> or how I would enable it; for me it just fails silently.

I don't find that at all hard to believe. Any idea if it's failing in
the core code or in the scripter function wrapper?

As for a traceback ... Scribus reports errors with exceptions. They're a
core feature in Python that (in general terms) allows a program to
interrupt its execution with an informative message that can be caught
and processed by higher level parts of the program. You can see this in
the following simple snippet, which you could run in the interactive
console:

x = 0

def raiseme():
   global x
   x = 1
   raise Exception("Exception - bored now")
   x = 2

print "Before: ", x
try:
    raiseme()
except (Exception,),err:
    print "Caught exeception: ",err
    print "Continuing anyway"
print "After: ", x


... where you can see that when the exception is thrown in raiseme() it
interrupts execution, running the exception handler in the main body of
the script. That handler prints the exception's message and continues on.

The scripter has a similar mechanism. It should print an exception
traceback to the script console like (eg):

Traceback (most recent call last):
  File "<console>", line 1, in ?
NoValidObjectError: Object not found

when you do something like:

scribus.selectObject("fred")

in the script console and "fred" does not exist. If you're running a
saved script rather than running on through the console an error dialog
should appear if an exception is thrown and you don't handle it in your
script.

If something is failing without an exception being thrown that is
definitely a scripter bug. It'd be very helpful to have the shortest
example you can come up with that demonstrates the problem, preferably
without relying on a specific document.

> I've
> rewritten the code so instead of selecting text I simply insert empty
> strings at the beginning of the paragraph (thus positioning the cursor
> there) and call setStyle(...), this (somewhat unintuitively) sets the
> style for the entire paragraph.

That's because 1.3.3.x only supports paragraph styles. There are no
character styles at all until 1.3.5 .

>     I've further discovered the problem where the length of a string
> in Python (as reported with the len() function) is different from the
> length as reported by Scribus.  It's apparently to do with
> incompatible encodings between Python and Scribus; I still can't quite
> get my head around that.

Currently the scripter relies on a rather dirty hack, using utf-8
encoded byte strings to pass data between Scribus and Python (my fault -
but in my defense, it used to be even more broken).

On byte strings (normal python strings), len measures the length in
bytes, not the length in characters. A character may be more than one
byte in the UTF-8 string encoding. More specifically, any character
that's not in the 7-bit ASCII range will use two or more bytes in UTF-8.

You can, and probably should, work with unicode strings where possible.
Literals can be written with the u prefix, eg:

u"this is a unicode string"

You can convert from a utf-8 encoded byte string to a unicode string with:

bstr = "the byte string"
ustr = decode("utf-8", bstr)

len(ustr) will then produce the answer you expected.

Scribus will always produce utf-8 byte string literals ("strings you
write") when working in the scripter, etc, irrespective of your locale.
When you're writing scripts in a text editor you should use the encoding
specifier as per PEP 0263:

http://www.python.org/dev/peps/pep-0263/

... to make sure that strings you write are interpreted correctly by Python.

Note that the scripter really should be using Python `Unicode' strings
everywhere, converting directly between them and the internally Unicode
QString. Unfortunately this involves rewriting practically all the
string-using functions.

Any new interface really *MUST* use the python Unicode string type,
preferably via an automatic adapter.

--
Craig Ringer



More information about the scribus mailing list