FLOSS Manuals

 English |  Español |  Français |  Italiano |  Português |  Русский |  Shqip

Python Scripting with Scribus

replacetext.py

Here is another variant of this text changing scheme, but on a larger scale. Someone asked me if there was a way to scramble the text in a document. The reason he wanted to do this, was that he wanted to use the document as an example of its layout, but the actual text content was information he didn't want to share. One answer might have been to delete the text and substitute Lorem Ipsum or the like, but this could be a lot of work.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# File: replacetext.py

"""
USAGE

You must have a document open.
WARNING: this script irreversibly scrambles your text on all pages.
You would be wise to work on a copy of the original to avoid
accidentally saving this scrambled version only to lose the original.


"""
import scribus
import random

if scribus.haveDoc():
    c = 0
        
else:
    scribus.messageBox('Usage Error', 'You need a Document open', scribus.ICON_NONE, scribus.BUTTON_OK)
    sys.exit(2)
scribus.messagebarText("Getting ready to process Page 1")
scribus.redrawAll()

warnresult = scribus.valueDialog('Warning!', 'This script is going to irreveribly alter the text in your document.\nChange this default value to abort', 'Ok!')

if (warnresult != 'Ok!'):
    sys.exit(2)

page = 1
pagenum = scribus.pageCount()
while (page <= pagenum):
  scribus.gotoPage(page)
  scribus.messagebarText("Processing Page "+str(page))
  scribus.redrawAll()
  pageitems = scribus.getPageItems()

  for item in pageitems:
    if (item[1] == 4):
      c = 0
      textbox = item[0]
      scribus.selectObject(textbox)
      contents = scribus.getTextLength(textbox)

      while 1:
      if ((c == contents) or (c > contents)): break
      if ((c + 1) > contents - 1):
          nextchar = ' '
      else:
          scribus.selectText(c+1, 1, textbox)
          nextchar = scribus.getText(textbox)
      scribus.selectText(c, 1, textbox)
      char = scribus.getText(textbox)
      if (len(char) != 1):
          c += 1
          continue
      alpha = random.randint(1,26)
      letter = chr(alpha + 96)
      LETTER = chr(alpha + 64)
      if ((ord(char)>96)and(ord(char)<123)):
          scribus.deleteText(textbox)
          scribus.insertText(letter, c, textbox)
      if ((ord(char)>64)and(ord(char)<91)):
          scribus.deleteText(textbox)
          scribus.insertText(LETTER, c, textbox)
          
      c += 1
      contents = scribus.getTextLength(textbox)
  page += 1

scribus.setRedraw(1)
scribus.docChanged(1)
scribus.messageBox("Finished", "That should do it!",icon=scribus.ICON_NONE,button1=scribus.BUTTON_OK)

We start out with page 1, and get a count of the pages using pageCount(). One of the things I have done here is to add a messagebarText() command. It takes some time to process a mulitipage document, so this message in the lower left corner of the window gives an indicator of where the script is working. You've seen this method before of getting all the objects on a page, then sifting out which ones are text frames. So next we're marching through the characters in the text frame. Look at this clause:

      if (len(char) != 1):
          c += 1
          continue

All the printable characters will have a length of 1, so if a char fails this test, then it must be some kind of control character, and we don't want to scramble those, so we just move on to the next. Now look at this:

      alpha = random.randint(1,26)
      letter = chr(alpha + 96)
      LETTER = chr(alpha + 64)

Here is the generator of the randomness, where I pick a number between 1 and 26 (as in letters of the alphabet), then create two possible replacements, one a lower case letter, the other an upper case. I wanted to retain the appearance of normal text, with capitalization where it occurred in the original, and thus it might appear like some foreign language.

The next step was to see if the original char was an upper case or lower case letter, then make the appropriate switch. I elected not to change numbers, for one reason considering there might be lists in the text, and there was no reason to disturb these. If someone had some sensitive numbers they did not want preserved, then numbers might also need scrambling.

Once we have marched through the document we then end with a succinct message.

As I review this script and then try it out on a multipage document, something occurs to me. I don't know if I might be recursively going over this text. As we will see in the next script, ExtractText.py, when you pull out the text from a series of linked frames, you will find that accessing the first frame in the link gets all of the text for the linked frames. In a sense, this isn't a huge issue here, but might make a script run longer than necessary, since it may be rescrambling the same text over and over.

A note about Windows and packages like random

Scribus versions for Windows which are downloadable from Sourceforge have Python 2.7 included with them, so you don't have to have Python on your system to use Scripter. On the other hand, this included Python has only a few additional packages. Even if you have Python on your system, you will notice that Scribus in its basic state will not use it. The answer comes from finding inside the Scribus folder in C:\Program Files the directory named python\. If you change its name to anything else, then Scribus will look to your system for Python  – make sure that you have Python 2.7 (as of this writing).

There has been error in communication with Booktype server. Not sure right now where is the problem.

You should refresh this page.