Bullets

From Scribus Wiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
This article is part of the Scripts series.

Usage

Select paragraphs at any points. Run script.

Caveats

  • Weak insertion point algorithm. Select unique text.
  • Script cleans all text format of text selection (font, bold, subscript, etc).
  • Script creates paragraph style "Bullet", if it doesn't exist.
  • If there is no selection, script apply bullets to all text in current frame.


#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
Format selected paragraphs with bullets.
Author: prof. MS. José Antonio Meira da Rocha
mailto:joseantoniomeira@gmail.com
http://meiradarocha.jor.br
License GPL 2.0
2011-01-14b

======
Usage:
Select paragraphs at any points. Run script.
Caveats:
* Cleans all text format of text selection (font, bold, subscript, etc).
* Creates paragraph style "Bullet", if it doesn't exist.
* If there is no selection, apply bullets to all text in current frame.
"""

import sys

try:
    import scribus
except ImportError,err:
    print "This Python script is written for the Scribus scripting interface."
    print "It can only be run from within Scribus."
    sys.exit(1)
from scribus import BUTTON_OK, ICON_WARNING

#########
# Locales
#########

# Message to ask frame selection
scriptWindowTitle = "Format bullets"
askSelectText = "<h2>Select a text</h2>\n" \
        +"Select a <b>story text</b> where you want insert bullets."
# Message to open a document
askOpenDoc = "<h2>Open a document</h2>" \
        +"Open a document befora run this script."
# Message asking select more text
askSelectMoreText = "<h2>Select more text</h2>" \
        +"Not unique text selected. Select more text before run this script."
wrongFrameTypeErrorMsg = "<h2>Wrong object selected</h2>" \
        +"You must select a <b>text frame</b>."

#######################
# Change this variables
# to match your needs
#######################
bulletStyle = 'Bullet'
# Put your favorite unicode char and tab: '\u2022\t' 
# Get hex code from "Insert > Special character..." palette
bulletString = u'•\t' # u'-\t' # 

###################
# Apply style
def applyStyle(style,frame):
    '''Apply a style in selected text. 
    If style doesn't exist, create it.'''
    try:
            scribus.setStyle(style,frame)
    except:
            scribus.createParagraphStyle(style)
            scribus.setStyle(style,frame)
    return frame

##########################
# Get text cursor position
def getTextCursor(story):
    '''Find position of text cursor in text frame.
    Text need to be selected.'''
    selectedFrame = scribus.getSelectedObject()
    try:
        selectedText = scribus.getText()
    except:
        scribus.messageBox(scriptWindowTitle,wrongFrameTypeErrorMsg,ICON_WARNING,BUTTON_OK)
        sys.exit()
    scribus.deselectAll()
    allText = scribus.getAllText(selectedFrame)
    
    if allText.count(unicode(selectedText)) == 1:
        cur = allText.find(unicode(selectedText))
        return cur,allText,selectedText
    else:
        scribus.messageBox(scriptWindowTitle,askSelectMoreText,ICON_WARNING,BUTTON_OK)
        sys.exit(1)

###################
def cleanBullets(t):
    '''Delete bullets.'''
    global bulletString
    while t.count(bulletString):
        t = t.replace(bulletString,'')
    return t

######################
# Get paragraph begin
def getParagraphLimits(cur,allText,selectedText,story):
    '''Get paragraph begin/end and delete old bullets'''
    # Get selected paragraph begin
    # (last line break position after selection, plus 1)
    begin = allText.rfind(u'\r',0,cur)+1 # Why not '\n'?
    # Get selection end
    end = cur+len(unicode(selectedText))
    scribus.selectText(begin,(end - begin),story)
    selectedText = scribus.getText(story)
    # Clean old bullets
    cleanedText = cleanBullets(unicode(selectedText))
    scribus.deleteText(story)
    scribus.insertText(cleanedText,begin,story)
    
    # Text was modified. Get all text again.
    scribus.deselectAll()
    allText = scribus.getAllText(story)
    # Get selection new end
    end = begin+len(unicode(cleanedText))
    return begin,end,allText

############################
# Do all the job
def insertAllBullets(story):
    '''Insert bullets in front selected paragraphs.'''
    global bulletString,bulletStyle
    cur,allText,selectedText = getTextCursor(story)
    begin,end,allText = getParagraphLimits(cur,allText,selectedText,story)
    # Insert bullets
    bulletsLen = 0
    bl = len(unicode(bulletString)) # len() needs unicode()
    nextPoint = begin
    while True:
        scribus.insertText(bulletString,begin,story)
        applyStyle(bulletStyle,story)
        bulletsLen = bulletsLen + bl  # total strings inserted lenght
        nextPoint = allText.find(u'\r',nextPoint+1,end)
        if nextPoint == -1: break
        begin = nextPoint + bulletsLen + 1

#####################
def handleSelected():
    """Handle frame selection."""
    story = scribus.getSelectedObject(0) 
    if story: 
        insertAllBullets(story)
        scribus.docChanged(True)
    else:
        scribus.messageBox(scriptWindowTitle,askSelectText,ICON_WARNING,BUTTON_OK)

############### 
def main(argv):
    """Main entry point."""
    if scribus.haveDoc():
        scribus.setRedraw(False)
        handleSelected()
    else:  
        scribus.messageBox(scriptWindowTitle,askOpenDoc,ICON_WARNING,BUTTON_OK)

#######################
def main_wrapper(argv):
    try:
        scribus.statusMessage("Running script...")
        scribus.progressReset()
        main(argv)
    finally:
        if scribus.haveDoc():
            scribus.setRedraw(True)
        scribus.statusMessage("")
        scribus.progressReset()

if __name__ == '__main__':
    main_wrapper(sys.argv)