Scribusoid

Author Topic: Issues while trying to implement template handling  (Read 822 times)

michaelu

  • Newbie
  • *
  • Posts: 13
  • Karma: 0
  • Scribus User
Issues while trying to implement template handling
« on: October 11, 2019, 04:59:59 pm »
Hi,
I am trying to implement a template mechanism in a script. The idea is to have a text containing placeholders like ${date}, $[title}, ${name}, plus a data set containing dates, titles and names, and create for each data a copy of the text with the placeholders replaced by the actual data. The trick is now that the text features such as font, font size, text color, line spacing, tabs etc. shall be preserved as faithfully as possible. My current findings are, that this is not possible in general, but that we can come close. The main obstacle is that there is not enough functionality in the script API (at least I was unable to find it). For example, there is no function getCharacterStyle. Or you can get style names (getAllStyles), but you cannot get style details. Only today I found a getStyle() in 1.5.6, which did not yet exist in 1.5.2, but which returns only paragraph styles.

So far I came up with this code:
Code: [Select]
textlen = scribus.getTextLength(textbox)
scribus.selectText(0, 1, textbox)
last_style = scribus.getStyle(textbox)
last_fontname = scribus.getFont(textbox)
last_fontsize = scribus.getFontSize(textbox)
last_textcolor = scribus.getTextColor(textbox)
last_textshade = scribus.getTextShade(textbox)
text = ""

pos = textlen
changed = False

for c in range(0, textlen):
    scribus.selectText(c, 1, textbox)
    char = scribus.getText(textbox)
    style = scribus.getStyle(textbox)
    if style != last_style:
        changed = True
    fontname = scribus.getFont(textbox)
    if fontname != last_fontname:
        changed = True
    fontsize = scribus.getFontSize(textbox)
    if fontsize != last_fontsize:
        changed = True
    textcolor = scribus.getTextColor(textbox)
    if textcolor != last_textcolor:
        changed = True
    textshade = scribus.getTextShade(textbox)
    if textshade != last_textshade:
        changed = True
    if changed:
        scribus.insertText(text, pos, textbox)
        tlen = scribus.getTextLength(textbox)
        scribus.selectText(pos, tlen - pos, textbox)
        scribus.setStyle(noStyle if last_style is None else last_style, textbox)
        scribus.selectText(pos, tlen - pos, textbox)
        scribus.setFont(last_fontname, textbox)
        scribus.selectText(pos, tlen - pos, textbox)
        scribus.setFontSize(last_fontsize, textbox)
        scribus.selectText(pos, tlen - pos, textbox)
        scribus.setTextColor(last_textcolor, textbox)
        scribus.selectText(pos, tlen - pos, textbox)
        scribus.setTextShade(last_textshade, textbox)
        pos = tlen
        text = ""
        last_fontname = fontname
        last_fontsize = fontsize
        last_textcolor = textcolor
        last_textshade = textshade
        last_style = style
        changed = False
    text = text + char

As you can see, I go through the text one character at a time, collecting all characters with the same formatting, as far as I can determine it, then insert  the text at the end, and applying the formatting as much as possible.
Some remarks:
- I had to repeat the selectText before each set..., apparently the set...-functions unselect the current selection
- I had to specify the second parameter textbox to avoid error messages
- The template contains special characters. Adding len(text) to pos did not work, because Scribus character count is not the same as Python character len. So, because a getCurrentPos() is missing, and insertText does not return the last pos, I use getTextLength to go to the end of the inserted text. This works of course only if you do not start with a position in the middle of text.
- I found no way to getText text that I had inserted with insertText. The text length is increased luckily, and you can selectText the new text, but you cannot getText it. getText returns only an empty string for the new text.
- We can obtain font, font size, color, shade, and paragraph style. But when you look at the story editor, you can do more to text, e.g. underline it. You can also apply a character style to piece of text (select in the main window, F3). But I could not find out (yet) how to get at these properties. So the replicated text looses e.g. underlining. It does not loose font or font size, if the character style changed that from the paragraph style.



a.l.e

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2176
  • Karma: 28
    • the graphics lab
Re: Issues while trying to implement template handling
« Reply #1 on: October 11, 2019, 05:27:49 pm »
getCharStyle()?

michaelu

  • Newbie
  • *
  • Posts: 13
  • Karma: 0
  • Scribus User
Re: Issues while trying to implement template handling
« Reply #2 on: October 11, 2019, 05:32:47 pm »
Nope

a.l.e

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2176
  • Karma: 28
    • the graphics lab
Re: Issues while trying to implement template handling
« Reply #3 on: October 11, 2019, 05:40:26 pm »
ah, no... there is only getCharStyles() ...

since now there is getStyle() for paragraph styles, it should not be hard to add getCharStyle()...

... from what i understood from your description, it's likely that you will need to add or tweak other scripter commands, so i dare to recommend you to have a try at adding getCharStyle().

it should be simple enough (i can of course give you a few other hints) for a first scribus contribution...

a.l.e

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2176
  • Karma: 28
    • the graphics lab
Re: Issues while trying to implement template handling
« Reply #4 on: October 11, 2019, 06:12:27 pm »
if you want some interactive help, you might want to connect to the #scribus channel on irc or the matrix.org scribus channel...

 

palmate