Difference between revisions of "Bullets and numbered lists"

From Scribus Wiki
Jump to: navigation, search
m (Caveats)
m (Code: You can't run from the GEISHI!!)
 
(25 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 
{{Scripting Index}}
 
{{Scripting Index}}
Improved bullets simple script using regular expressions Python module. Build bulleted lists, numbered lists starting with any number plus separator and delete list marks.  
+
Improved bullets simple script using regular expressions Python module. Build bulleted lists; numbered lists starting with any number plus separator; upper case or lower case lettered list; and delete list marks.  
 
Create styles -- if it doesn't exists -- with proper 2 digits indentation, but is necessary set tabulation "by hand", as this can't be done by script.
 
Create styles -- if it doesn't exists -- with proper 2 digits indentation, but is necessary set tabulation "by hand", as this can't be done by script.
  
 
==Install==
 
==Install==
  
1. Copy the code and paste in a file named "Bullets.py" or whatever "*.py".
+
# Copy the code and paste in a text file named "Bullets.py" or whatever "*.py".
2. Run it by "Scripts > Execute script..."
+
# Run it by "Scripts > Execute script..."
2. In order to scripts appear in "Scripts > Scribus scripts..." menu, put the file in:* Windows folder "x:\Program files\Scribus 1.3.9\share\scripts\" or in * Linux directory (copy as root) "/usr/share/scribus-nt/scripts/" (I gess). But this folders is for official scripts and could be overwritting when Scribus reinstalls.
+
# In order to scripts appear in "Scripts > Scribus scripts..." menu, put the file in:
 +
#* Windows folder "'''x:\Program files\Scribus 1.3.9\share\scripts\'''" or in
 +
#* Linux directory (copy as root) "'''/usr/share/scribus-ng/scripts/'''". But these folders are for official scripts and could be overwritten when Scribus reinstalls.
  
 
==Usage==
 
==Usage==
  
Select a text frame or some paragraphs and run the script by choosing "Scripts" menu, options "Execute script..." or "SCribus scripts". Asked, input the operation type:
+
Select a text frame or some paragraphs and run the script by choosing "Scripts" menu, options "Execute script..." or "Scribus scripts". Asked, input the operation type:
  
 
* "*" will create bulleted list.
 
* "*" will create bulleted list.
* A number (up 3 digit) will create a numbered list begining with such number. Ex.: "1)"
+
* A number (up 3 digit) will create a numbered list begining with such number. Ex.: "1)". Range: 0 to 999.
* One or two letters, uppper or lower case, will create a lettered list begining with such letters with same case. Ex.: "a)"
+
* One or two letters, upper or lower case, will create a lettered list begining with such letters with same case. Ex.: "a)". Range: "a" to "zz".
 
* "/" will clear all marks.
 
* "/" will clear all marks.
 
* An optional character after numbers or letters will be used as separator. Default: dot.
 
* An optional character after numbers or letters will be used as separator. Default: dot.
 +
==Options==
 +
* You can change bullets size putting any value but zero in '''bulletedListCharSize''' variable.
 +
* You can change bullets font putting it ''Scribus name'' in '''bulletedListCharFont''' variable.
 +
* This works for numbers and letters too, with its propers variables.
 +
* Get character hex code from menu: "Insert > Special character > [magnifying glass button]".
 +
* Change bullet character putting it code in '''bulletString''' variable, in place "006F" and "F06F":
 +
<pre>
 +
if os.name == 'posix':
 +
    bulletString = u'\u006F\t'  #  lower right drop-shadowed white square U+274F
 +
else:
 +
    bulletString = u'\uF06F\t'
 +
</pre>
 +
 +
'''Tested and working in Scribus 1.3.9 running in Windows XP, Wine and Ubuntu 10.10'''.
  
 
==Caveats==
 
==Caveats==
 
+
* The script will '''clear''' any character formating in selected paragraphs (fonts, bold, superscripts, soft hyphens etc), as '''scribus.getText()''' Python function get just plain text, not formating.
Maybe will FREEZE Scribus in Ubuntu 10.04 and 10.10, as script use Pyhton module ('''re''', regular expressions). This is a Ubuntu +  Scribus Scripter bug.
+
* Some fonts can have different encodings depending operational system. Bullets glyphs '''may not appear''' if a publication made in Linux is opened in Windows, and vice-versa. This is true for "Dingbats" font from URW foundry.
 
+
  
 
==Code==
 
==Code==
  
<pre>
+
<syntaxhighlight lang='python'>
#!/usr/bin/env python
+
#!/usr/bin/env python
 
# -*- coding: utf-8 -*-
 
# -*- coding: utf-8 -*-
 
+
 
"""
 
"""
 
Insert marks, numbers or letters in front selected paragraphs.
 
Insert marks, numbers or letters in front selected paragraphs.
Line 36: Line 51:
 
http://meiradarocha.jor.br
 
http://meiradarocha.jor.br
 
License GPL 2.0
 
License GPL 2.0
2011-01-15a
+
2011-01-17a
 
+
 
Usage:
 
Usage:
 
======
 
======
 
Select paragraphs at any points. Dialog will ask mark type.
 
Select paragraphs at any points. Dialog will ask mark type.
Input:  
+
Input:
 
* "*" will create bulleted list.
 
* "*" will create bulleted list.
 
* A number (up 3 digit) will create a numbered list begining with such number. Ex.: "1)"
 
* A number (up 3 digit) will create a numbered list begining with such number. Ex.: "1)"
 
* One or two letters uppper or lower case will create a lettered list begining with such letters. Ex.: "a)"
 
* One or two letters uppper or lower case will create a lettered list begining with such letters. Ex.: "a)"
 +
* An optional character after numbers or letters will be used as separator. Default: dot.
 
* "/" will clear all marks.
 
* "/" will clear all marks.
* An optional character after numbers or letters will be used as separator. Default: dot.
+
 
+
 
Caveats:
 
Caveats:
 
* Cleans all text format of text selection (font, bold, subscript, etc).
 
* Cleans all text format of text selection (font, bold, subscript, etc).
* Creates paragraph style "Numbered List", "Lettered list" or "Bullet", if it doesn't exist, with proper indentation. Tabulation need to be defined by user to identical identation value.
+
* Creates paragraph style "Numbered List", "Lettered list" or "Bullet", if it doesn't exist, with proper indentation.  
 +
  Tabulation need to be defined by user to identical indentation value.
 
* If there is no selection, script will apply marks to all text in current frame.
 
* If there is no selection, script will apply marks to all text in current frame.
 +
* Some fonts can have different encodings depending operational system.
 +
  Bullets glyphs can't appear if a publication made in Linux is opened in Windows, and vice-versa.
 +
  This is true for "Dingbats" font from URW foundry.
 
"""
 
"""
 
+
 
import sys
 
import sys
 
import re
 
import re
 
+
import os
 +
 
try:
 
try:
 
     import scribus
 
     import scribus
Line 64: Line 84:
 
     sys.exit(1)
 
     sys.exit(1)
 
from scribus import BUTTON_OK, ICON_WARNING
 
from scribus import BUTTON_OK, ICON_WARNING
 
+
 
#######################
 
#######################
 
# Change this variables
 
# Change this variables
 
# to match your needs
 
# to match your needs
 
#######################
 
#######################
numberedListStyle = 'Numbered list'
+
numberedListParaStyle = 'Numbered list'
letteredListStyle = 'Lettered list'
+
# Font name in Scribus style. Empty string don't apply font.
bulletStyle = 'Bullet'
+
# Get font list with 'getFontNames()' <F9> in Scripter console
defaultStyle = 'Default Paragraph Style'
+
numberedListCharFont = '' 
 +
numberedListCharSize = 0  # In points. Zero don't apply font size
 +
 +
letteredListParaStyle = 'Lettered list'
 +
letteredListCharFont = '' # 
 +
letteredListCharSize = 0 # 
 +
 +
bulletedListParaStyle = 'Bullet'
 +
bulletedListCharFont = 'Dingbats Regular' # 'Wingdings Regular' # 
 +
bulletedListCharSize = 0
 +
# Put your favorite unicode char and tab: '\u2022\t' # u'•\t' # bullet U+2022
 +
# Get hex code from menu: "Insert > Special character > [magnifying button]".
 +
# Modern dingbat fonts, as Zapf Dingbats or Wingdings, need special hex codes.
 +
# URW "Dingbats Regular" Type 1 font have different code in Linux and in Windows,
 +
# none of them Unicode.
 +
# "ITC Zapf Dingbats Regular" have same code in both OS, but not Unicode encoding.
 +
if os.name == 'posix':
 +
    bulletString = u'\u006F\t'  #  lower right drop-shadowed white square U+274F
 +
else:
 +
    bulletString = u'\uF06F\t'
 +
 +
defaultParaStyle = 'Default Paragraph Style'
 +
defaultCharStyle = 'Default Character Style'
 
separator = '.'
 
separator = '.'
 
indent = 22 # points
 
indent = 22 # points
# Put your favorite unicode char and tab: '\u2022\t'
+
# Get hex code from "Insert > Special character..." palette
+
bulletString = u'•\t'
+
 
+
 
###########
 
###########
 
# Locales
 
# Locales
 
###########
 
###########
 +
  
 
# Message to ask frame selection
 
# Message to ask frame selection
 
scriptWindowTitle = "Format list"
 
scriptWindowTitle = "Format list"
 
askSelectText = "<h2>Select a text</h2>\n" \
 
askSelectText = "<h2>Select a text</h2>\n" \
        +"Select a <b>story text</b> where you want insert numbers."
+
+"Select a <b>story text</b> where you want insert numbers."
 +
 
 
# Message to open a document
 
# Message to open a document
 
askOpenDoc = "<h2>Open a document</h2>" \
 
askOpenDoc = "<h2>Open a document</h2>" \
        +"Open a document befora run this script."
+
+"Open a document before run this script."
 +
 
 
# Message asking select more text
 
# Message asking select more text
 
askSelectMoreText = "<h2>Select more text</h2>" \
 
askSelectMoreText = "<h2>Select more text</h2>" \
        +"Not unique text selected. Select more text before run this script."
+
+"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>."
+
  
 +
wrongFrameTypeErrorMsg = "<h2>Wrong object selected</h2>" \
 +
+"You must select a <b>text frame</b>."
 +
 
markOperation = ''
 
markOperation = ''
 
bulletOperation = '*'
 
bulletOperation = '*'
 
numberOperation = '1'
 
numberOperation = '1'
 
cleanOperation = '/'
 
cleanOperation = '/'
alphaOperation = 'Aa'
+
alphaOperation = 'a'
 
defaultOperation = bulletOperation
 
defaultOperation = bulletOperation
 
alphabet = 'abcdefghijklmnopqrstuvwxyz'
 
alphabet = 'abcdefghijklmnopqrstuvwxyz'
Line 106: Line 150:
  
 
askOperationMsg = '<h2>What mark operation?</h2>' \
 
askOperationMsg = '<h2>What mark operation?</h2>' \
        +'<ul><li>"<b>'+bulletOperation.lower()+'</b>" input will create <b>bullet</b> marks.' \
+
+'<ul><li>"<b>'+bulletOperation+'</b>" input will create <b>bullet</b> marks.' \
        +'and apply <i>'+bulletStyle+'</i>&nbsp;&nbsp;style.' \
+
+'and apply <i>'+bulletedListParaStyle+'</i> style.' \
        +'<li>A <b>number</b> input will create <b>numbered list</b> starting <br>with such number and apply <i>'+numberedListStyle+'</i>&nbsp;&nbsp;style.' \
+
+'<li>A <b>number</b> input will create <b>numbered list</b> starting <br>' \
        +'<li>One or two <b>letters</b> input, upper or lower case, <br>will create <b>lettered list</b> starting with such letters,<br>' \
+
+'with such number and apply <i>'+numberedListParaStyle+'</i> style.' \
        +'and apply <i>'+letteredListStyle+'</i>&nbsp;&nbsp;style.' \
+
+'<li>One or two <b>letters</b> input, upper or lower case, <br>' \
        +'<li><font color="#0000ff">Optional char after number or letter<br> will be used as separator. Default: dot. Ex.: "<b>a)</b>"</font>' \
+
+'will create <b>lettered list</b> starting with such letters,<br>' \
        +'<li>"<b>'+cleanOperation.lower()+'</b>" input will <b>delete</b> marks ' \
+
+'and apply <i>'+letteredListParaStyle+'</i> style.' \
        +'and apply <br><i>'+defaultStyle+'</i>&nbsp;&nbsp;style.</li>' \
+
+'<li><font color="#0000ff">Optional char after number or letter<br>' \
        +'<li>Any <b>other</b> input will <b>cancel</b> all operations.</li></ul>' \
+
+'will be used as separator. Default: dot. Ex.: "<b>a)</b>"</font>' \
 
+
+'<li>"<b>'+cleanOperation.lower()+'</b>" input will <b>delete</b> marks ' \
 +
+'and apply <br><i>'+defaultParaStyle+'</i> style.</li>' \
 +
+'<li>Any <b>other</b> input will <b>cancel</b> all operations.</li></ul>' \
 +
 
###### No need to change after this line #############
 
###### No need to change after this line #############
 
+
 
# Regular expression to match any mark:
 
# Regular expression to match any mark:
 
#  '\r' = carriage return in Python
 
#  '\r' = carriage return in Python
 
#  '\t' = tabulation in Python
 
#  '\t' = tabulation in Python
 
#  [^\t|^\r] = non-tab or non-CR chars
 
#  [^\t|^\r] = non-tab or non-CR chars
#  {,4} = 0 to 4 ocurrencies from paragraph begin to tab
+
#  {,4} = 0 to 4 currencies from paragraph begin to tab
reAnyMark  = r'\r[^\t|^\r]{,4}\t'  
+
reAnyMark  = r'(\r[^\t|^\r]{,4}\t)'
 
+
 
##############
 
##############
 
# Apply style
 
# Apply style
 
def applyStyle(style,frame):
 
def applyStyle(style,frame):
     '''Apply a style in selected text.  
+
     '''Apply a style in selected text.
 
     If style doesn't exist, create it.'''
 
     If style doesn't exist, create it.'''
 
     try:
 
     try:
Line 136: Line 183:
 
         scribus.setStyle(style,frame)
 
         scribus.setStyle(style,frame)
 
     return frame
 
     return frame
 
+
 
##########################
 
##########################
 
# Get text cursor position
 
# Get text cursor position
Line 151: Line 198:
 
     scribus.deselectAll()
 
     scribus.deselectAll()
 
     allText = scribus.getAllText(selectedFrame)
 
     allText = scribus.getAllText(selectedFrame)
   
+
   
 
     if allText.count(unicode(selectedText)) == 1:
 
     if allText.count(unicode(selectedText)) == 1:
 
         cur = allText.find(unicode(selectedText))
 
         cur = allText.find(unicode(selectedText))
Line 158: Line 205:
 
         scribus.selectObject(story)
 
         scribus.selectObject(story)
 
         sys.exit(1)
 
         sys.exit(1)
   
+
   
 
     return cur,allText,selectedText
 
     return cur,allText,selectedText
 
+
 
############
 
############
 
# Numbering
 
# Numbering
Line 173: Line 220:
 
     num += 1
 
     num += 1
 
     return s
 
     return s
 
+
 
####################
 
####################
 
# Lettering
 
# Lettering
 
def lettering(matchObj):
 
def lettering(matchObj):
 
     '''Function to re.sub use.'''
 
     '''Function to re.sub use.'''
    ######## bugged ################
 
 
     global num
 
     global num
 
     # Define limit to list (zz)
 
     # Define limit to list (zz)
Line 194: Line 240:
 
     num += 1
 
     num += 1
 
     return s
 
     return s
 
+
 
####################
 
####################
def insertMarks(t):
+
def processMarks(t):
 
     '''Delete old marks and insert new ones.'''
 
     '''Delete old marks and insert new ones.'''
 
     # Clear old numbers
 
     # Clear old numbers
 +
    splitedText = []
 
     s = re.sub(reAnyMark,u'\r',t)
 
     s = re.sub(reAnyMark,u'\r',t)
 
     if markOperation == numberOperation:
 
     if markOperation == numberOperation:
 
         # Insert numbers
 
         # Insert numbers
 
         s = re.sub(u'\r',numbering,s)
 
         s = re.sub(u'\r',numbering,s)
 +
        splitedText = re.split(reAnyMark,s)
 +
        print 'Split:\n',splitedText
 
     elif markOperation.isalpha():
 
     elif markOperation.isalpha():
 
         # Insert letters
 
         # Insert letters
 
         s = re.sub(u'\r',lettering,s)
 
         s = re.sub(u'\r',lettering,s)
 +
        splitedText = re.split(reAnyMark,s)
 +
        print 'Split:\n',splitedText
 
     elif markOperation == bulletOperation:
 
     elif markOperation == bulletOperation:
 
         # Insert bullets
 
         # Insert bullets
 
         b = u'\r'+bulletString
 
         b = u'\r'+bulletString
 
         s = re.sub(u'\r',b,s)
 
         s = re.sub(u'\r',b,s)
   
+
        splitedText = re.split(reAnyMark,s)
     return s
+
        print 'Split:\n',splitedText
 
+
   
 +
     return s,splitedText
 +
 +
#################
 +
# Format marks
 +
def formatMarks(begin,splitedText,story):
 +
    '''Format marks inserted by processMarks().
 +
    Use splitedText array as map to point text in story frame.'''
 +
    for m in range (1,len(splitedText),2): # element 0 is ''
 +
        text = splitedText[m]
 +
        length = len(splitedText[m])-2  # don't count '\r' and '\t'
 +
        print repr(text[1:len(text)-1])
 +
        if markOperation == bulletOperation:
 +
            if bulletedListCharFont:
 +
                scribus.selectText(begin,length,story)
 +
                try: scribus.setFont(bulletedListCharFont,story)
 +
                except: print "Can't find font:",bulletedListCharFont
 +
            if bulletedListCharSize:
 +
                scribus.selectText(begin,length,story)
 +
                try: scribus.setFontSize(bulletedListCharSize,story)
 +
                except: print "Couldn't apply list char size"
 +
        if markOperation == numberOperation:
 +
            if numberedListCharFont:
 +
                scribus.selectText(begin,length,story)
 +
                try: scribus.setFont(numberedListCharFont,story)
 +
                except: print "Can't find font:",numberedListCharFont
 +
            if numberedListCharSize:
 +
                scribus.selectText(begin,length,story)
 +
                try: scribus.setFontSize(numberedListCharSize,story)
 +
                except: print "Couldn't apply list char size"
 +
        if markOperation.isalpha():
 +
            if letteredListCharFont:
 +
                scribus.selectText(begin,length,story)
 +
                try: scribus.setFont(letteredListCharFont,story)
 +
                except: print "Can't find font:",letteredListCharFont
 +
            if letteredListCharSize:
 +
                scribus.selectText(begin,length,story)
 +
                try: scribus.setFontSize(letteredListCharSize,story)
 +
                except: print "Couldn't apply list char size"
 +
        lineAfterBullet = splitedText[m+1]
 +
        print begin,lineAfterBullet
 +
        begin = begin + length + 2 + len(unicode(lineAfterBullet))
 +
 
#################
 
#################
 
# Do all the job
 
# Do all the job
Line 232: Line 325:
 
     # Put temporary carriage return to allow numbering at string begin
 
     # Put temporary carriage return to allow numbering at string begin
 
     selectedText = u'\r'+selectedText
 
     selectedText = u'\r'+selectedText
     # Clean old numbers and insert new ones
+
     # Clean old marks and insert new ones
     cleanedText = insertMarks(unicode(selectedText))
+
     processedText,splitedText = processMarks(unicode(selectedText))
     # Strip temp initial CR
+
     # Strip temporary initial CR
     cleanedText = unicode(cleanedText)[1:]
+
     processedText = unicode(processedText)[1:]
 
     scribus.deleteText(story)
 
     scribus.deleteText(story)
     scribus.insertText(cleanedText,begin,story)
+
     scribus.insertText(processedText,begin,story)
 
     # Apply style
 
     # Apply style
 
     scribus.deselectAll()
 
     scribus.deselectAll()
 
     # Get selection new end
 
     # Get selection new end
     end = len(unicode(cleanedText))
+
     length = len(unicode(processedText))
     scribus.selectText(begin,end,story)
+
     scribus.selectText(begin,length,story)
 
     if markOperation == bulletOperation:
 
     if markOperation == bulletOperation:
         applyStyle(bulletStyle,story)
+
         applyStyle(bulletedListParaStyle,story)
 
     elif markOperation == numberOperation:
 
     elif markOperation == numberOperation:
         applyStyle(numberedListStyle,story)
+
         applyStyle(numberedListParaStyle,story)
 
     elif markOperation == cleanOperation:
 
     elif markOperation == cleanOperation:
         applyStyle(defaultStyle,story)
+
         applyStyle(defaultParaStyle,story)
 
     elif markOperation.isalpha():
 
     elif markOperation.isalpha():
         applyStyle(letteredListStyle,story)
+
         applyStyle(letteredListParaStyle,story)
 +
    # Apply special formating
 +
    formatMarks(begin,splitedText,story)
 
     scribus.selectObject(story)
 
     scribus.selectObject(story)
 
+
 
#####################
 
#####################
 
def decodeInput(res):
 
def decodeInput(res):
Line 292: Line 387:
 
     else: f = ''
 
     else: f = ''
 
     return f
 
     return f
   
+
   
 
#####################
 
#####################
 
def handleSelected():
 
def handleSelected():
 
     """Handle frame selection."""
 
     """Handle frame selection."""
 
     global markOperation,separator
 
     global markOperation,separator
     story = scribus.getSelectedObject(0)  
+
     story = scribus.getSelectedObject(0)
 
     if story:
 
     if story:
 
         res = scribus.valueDialog(scriptWindowTitle,askOperationMsg,defaultOperation)
 
         res = scribus.valueDialog(scriptWindowTitle,askOperationMsg,defaultOperation)
Line 308: Line 403:
 
     else:
 
     else:
 
         scribus.messageBox(scriptWindowTitle,askSelectText,ICON_WARNING,BUTTON_OK)
 
         scribus.messageBox(scriptWindowTitle,askSelectText,ICON_WARNING,BUTTON_OK)
 
+
###############  
+
###############
 
def main(argv):
 
def main(argv):
 
     """Main entry point."""
 
     """Main entry point."""
Line 315: Line 410:
 
         scribus.setRedraw(False)
 
         scribus.setRedraw(False)
 
         handleSelected()
 
         handleSelected()
     else:
+
     else:  
 
         scribus.messageBox(scriptWindowTitle,askOpenDoc,ICON_WARNING,BUTTON_OK)
 
         scribus.messageBox(scriptWindowTitle,askOpenDoc,ICON_WARNING,BUTTON_OK)
 
+
 
#######################
 
#######################
 
def main_wrapper(argv):
 
def main_wrapper(argv):
Line 329: Line 424:
 
         scribus.statusMessage("")
 
         scribus.statusMessage("")
 
         scribus.progressReset()
 
         scribus.progressReset()
 
+
 
if __name__ == '__main__':
 
if __name__ == '__main__':
 
     main_wrapper(sys.argv)
 
     main_wrapper(sys.argv)
 
+
</syntaxhighlight>
 
+
</pre>
+

Latest revision as of 04:19, 20 January 2014

This article is part of the Scripts series.

Improved bullets simple script using regular expressions Python module. Build bulleted lists; numbered lists starting with any number plus separator; upper case or lower case lettered list; and delete list marks. Create styles -- if it doesn't exists -- with proper 2 digits indentation, but is necessary set tabulation "by hand", as this can't be done by script.

Install

  1. Copy the code and paste in a text file named "Bullets.py" or whatever "*.py".
  2. Run it by "Scripts > Execute script..."
  3. In order to scripts appear in "Scripts > Scribus scripts..." menu, put the file in:
    • Windows folder "x:\Program files\Scribus 1.3.9\share\scripts\" or in
    • Linux directory (copy as root) "/usr/share/scribus-ng/scripts/". But these folders are for official scripts and could be overwritten when Scribus reinstalls.

Usage

Select a text frame or some paragraphs and run the script by choosing "Scripts" menu, options "Execute script..." or "Scribus scripts". Asked, input the operation type:

  • "*" will create bulleted list.
  • A number (up 3 digit) will create a numbered list begining with such number. Ex.: "1)". Range: 0 to 999.
  • One or two letters, upper or lower case, will create a lettered list begining with such letters with same case. Ex.: "a)". Range: "a" to "zz".
  • "/" will clear all marks.
  • An optional character after numbers or letters will be used as separator. Default: dot.

Options

  • You can change bullets size putting any value but zero in bulletedListCharSize variable.
  • You can change bullets font putting it Scribus name in bulletedListCharFont variable.
  • This works for numbers and letters too, with its propers variables.
  • Get character hex code from menu: "Insert > Special character > [magnifying glass button]".
  • Change bullet character putting it code in bulletString variable, in place "006F" and "F06F":
if os.name == 'posix':
    bulletString = u'\u006F\t'  #  lower right drop-shadowed white square U+274F
else:
    bulletString = u'\uF06F\t' 

Tested and working in Scribus 1.3.9 running in Windows XP, Wine and Ubuntu 10.10.

Caveats

  • The script will clear any character formating in selected paragraphs (fonts, bold, superscripts, soft hyphens etc), as scribus.getText() Python function get just plain text, not formating.
  • Some fonts can have different encodings depending operational system. Bullets glyphs may not appear if a publication made in Linux is opened in Windows, and vice-versa. This is true for "Dingbats" font from URW foundry.

Code

#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
"""
Insert marks, numbers or letters in front selected paragraphs.
Author: prof. MS. José Antonio Meira da Rocha
mailto:joseantoniomeira@gmail.com
http://meiradarocha.jor.br
License GPL 2.0
2011-01-17a
 
Usage:
======
Select paragraphs at any points. Dialog will ask mark type.
Input:  
* "*" will create bulleted list.
* A number (up 3 digit) will create a numbered list begining with such number. Ex.: "1)"
* One or two letters uppper or lower case will create a lettered list begining with such letters. Ex.: "a)"
* An optional character after numbers or letters will be used as separator. Default: dot.
* "/" will clear all marks.
 
Caveats:
* Cleans all text format of text selection (font, bold, subscript, etc).
* Creates paragraph style "Numbered List", "Lettered list" or "Bullet", if it doesn't exist, with proper indentation. 
  Tabulation need to be defined by user to identical indentation value.
* If there is no selection, script will apply marks to all text in current frame.
* Some fonts can have different encodings depending operational system. 
  Bullets glyphs can't appear if a publication made in Linux is opened in Windows, and vice-versa. 
  This is true for "Dingbats" font from URW foundry. 
"""
 
import sys
import re
import os
 
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
 
#######################
# Change this variables
# to match your needs
#######################
numberedListParaStyle = 'Numbered list'
# Font name in Scribus style. Empty string don't apply font.
# Get font list with 'getFontNames()' <F9> in Scripter console
numberedListCharFont = ''  
numberedListCharSize = 0  # In points. Zero don't apply font size
 
letteredListParaStyle = 'Lettered list'
letteredListCharFont = '' #  
letteredListCharSize = 0 #  
 
bulletedListParaStyle = 'Bullet'
bulletedListCharFont = 'Dingbats Regular' # 'Wingdings Regular' #  
bulletedListCharSize = 0
# Put your favorite unicode char and tab: '\u2022\t' # u'•\t' # bullet U+2022
# Get hex code from menu: "Insert > Special character > [magnifying button]".
# Modern dingbat fonts, as Zapf Dingbats or Wingdings, need special hex codes.
# URW "Dingbats Regular" Type 1 font have different code in Linux and in Windows,
# none of them Unicode.
# "ITC Zapf Dingbats Regular" have same code in both OS, but not Unicode encoding.
if os.name == 'posix':
    bulletString = u'\u006F\t'  #  lower right drop-shadowed white square U+274F
else:
    bulletString = u'\uF06F\t' 
 
defaultParaStyle = 'Default Paragraph Style'
defaultCharStyle = 'Default Character Style'
separator = '.'
indent = 22 # points
 
 
###########
# Locales
###########
 
 
# Message to ask frame selection
scriptWindowTitle = "Format list"
askSelectText = "<h2>Select a text</h2>\n" \
+"Select a <b>story text</b> where you want insert numbers."
 
# Message to open a document
askOpenDoc = "<h2>Open a document</h2>" \
+"Open a document before 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>."
 
markOperation = ''
bulletOperation = '*'
numberOperation = '1'
cleanOperation = '/'
alphaOperation = 'a'
defaultOperation = bulletOperation
alphabet = 'abcdefghijklmnopqrstuvwxyz'
alphabetLen = len(alphabet)
 
askOperationMsg = '<h2>What mark operation?</h2>' \
+'<ul><li>"<b>'+bulletOperation+'</b>" input will create <b>bullet</b> marks.' \
+'and apply <i>'+bulletedListParaStyle+'</i>  style.' \
+'<li>A <b>number</b> input will create <b>numbered list</b> starting <br>' \
+'with such number and apply <i>'+numberedListParaStyle+'</i>  style.' \
+'<li>One or two <b>letters</b> input, upper or lower case, <br>' \
+'will create <b>lettered list</b> starting with such letters,<br>' \
+'and apply <i>'+letteredListParaStyle+'</i>  style.' \
+'<li><font color="#0000ff">Optional char after number or letter<br>' \
+'will be used as separator. Default: dot. Ex.: "<b>a)</b>"</font>' \
+'<li>"<b>'+cleanOperation.lower()+'</b>" input will <b>delete</b> marks ' \
+'and apply <br><i>'+defaultParaStyle+'</i>  style.</li>' \
+'<li>Any <b>other</b> input will <b>cancel</b> all operations.</li></ul>' \
 
###### No need to change after this line #############
 
# Regular expression to match any mark:
#  '\r' = carriage return in Python
#  '\t' = tabulation in Python
#  [^\t|^\r] = non-tab or non-CR chars
#  {,4} = 0 to 4 currencies from paragraph begin to tab
reAnyMark  = r'(\r[^\t|^\r]{,4}\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(name=style,leftmargin=indent,firstindent=(indent*-1))
        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)
        scribus.selectObject(story)
        sys.exit()
    scribus.deselectAll()
    allText = scribus.getAllText(selectedFrame)
 
    if allText.count(unicode(selectedText)) == 1:
        cur = allText.find(unicode(selectedText))
    else:
        scribus.messageBox(scriptWindowTitle,askSelectMoreText,ICON_WARNING,BUTTON_OK)
        scribus.selectObject(story)
        sys.exit(1)
 
    return cur,allText,selectedText
 
############
# Numbering
num = 0
def numbering(matchObj):
    '''Function to re.sub use.'''
    global num
    # Define limit to list
    limit = 999
    if num > limit: num = limit
    s = u'\r'+str(num)+separator+'\t'
    num += 1
    return s
 
####################
# Lettering
def lettering(matchObj):
    '''Function to re.sub use.'''
    global num
    # Define limit to list (zz)
    limit = ((alphabetLen+1) * alphabetLen)
    if num > limit: num = limit
    d1 = ((num-1) % alphabetLen)
    s1 = alphabet[d1]
    d2 = ((num-1) / alphabetLen)-1
    if d2 > -1:
        s2 = alphabet[d2]
        s1 = s2+s1
    s = u'\r'+s1+separator+'\t'
    if markOperation.isupper():
        s = s.upper()
    num += 1
    return s
 
####################
def processMarks(t):
    '''Delete old marks and insert new ones.'''
    # Clear old numbers
    splitedText = []
    s = re.sub(reAnyMark,u'\r',t)
    if markOperation == numberOperation:
        # Insert numbers
        s = re.sub(u'\r',numbering,s)
        splitedText = re.split(reAnyMark,s)
        print 'Split:\n',splitedText
    elif markOperation.isalpha():
        # Insert letters
        s = re.sub(u'\r',lettering,s)
        splitedText = re.split(reAnyMark,s)
        print 'Split:\n',splitedText
    elif markOperation == bulletOperation:
        # Insert bullets
        b = u'\r'+bulletString
        s = re.sub(u'\r',b,s)
        splitedText = re.split(reAnyMark,s)
        print 'Split:\n',splitedText
 
    return s,splitedText
 
#################
# Format marks
def formatMarks(begin,splitedText,story):
    '''Format marks inserted by processMarks().
    Use splitedText array as map to point text in story frame.'''
    for m in range (1,len(splitedText),2): # element 0 is ''
        text = splitedText[m]
        length = len(splitedText[m])-2  # don't count '\r' and '\t'
        print repr(text[1:len(text)-1])
        if markOperation == bulletOperation:
            if bulletedListCharFont:
                scribus.selectText(begin,length,story)
                try: scribus.setFont(bulletedListCharFont,story)
                except: print "Can't find font:",bulletedListCharFont
            if bulletedListCharSize:
                scribus.selectText(begin,length,story)
                try: scribus.setFontSize(bulletedListCharSize,story)
                except: print "Couldn't apply list char size"
        if markOperation == numberOperation:
            if numberedListCharFont:
                scribus.selectText(begin,length,story)
                try: scribus.setFont(numberedListCharFont,story)
                except: print "Can't find font:",numberedListCharFont
            if numberedListCharSize:
                scribus.selectText(begin,length,story)
                try: scribus.setFontSize(numberedListCharSize,story)
                except: print "Couldn't apply list char size"
        if markOperation.isalpha():
            if letteredListCharFont:
                scribus.selectText(begin,length,story)
                try: scribus.setFont(letteredListCharFont,story)
                except: print "Can't find font:",letteredListCharFont
            if letteredListCharSize:
                scribus.selectText(begin,length,story)
                try: scribus.setFontSize(letteredListCharSize,story)
                except: print "Couldn't apply list char size"
        lineAfterBullet = splitedText[m+1]
        print begin,lineAfterBullet
        begin = begin + length + 2 + len(unicode(lineAfterBullet))
 
#################
# Do all the job
def doAllOperation(story):
    '''Insert marks in front selected paragraphs or clean marks.'''
    # Get selection begin
    cur,allText,selectedText = getTextCursor(story)
    # Get first selected paragraph begin
    # (last line break position after selection)
    begin = allText.rfind(u'\r',0,cur)+1 # Scribus not use '\n'?
    # Get selection end
    end = cur+len(unicode(selectedText))
    # Get last selected paragraph end
    end = allText.find(u'\r',end)
    totalLen = end - begin
    scribus.selectText(begin,totalLen,story)
    selectedText = scribus.getText(story)
    #print '\nSelected:\n',repr(selectedText.encode('utf-8')) # debug
    # Put temporary carriage return to allow numbering at string begin
    selectedText = u'\r'+selectedText
    # Clean old marks and insert new ones
    processedText,splitedText = processMarks(unicode(selectedText))
    # Strip temporary initial CR
    processedText = unicode(processedText)[1:]
    scribus.deleteText(story)
    scribus.insertText(processedText,begin,story)
    # Apply style
    scribus.deselectAll()
    # Get selection new end
    length = len(unicode(processedText))
    scribus.selectText(begin,length,story)
    if markOperation == bulletOperation:
        applyStyle(bulletedListParaStyle,story)
    elif markOperation == numberOperation:
        applyStyle(numberedListParaStyle,story)
    elif markOperation == cleanOperation:
        applyStyle(defaultParaStyle,story)
    elif markOperation.isalpha():
        applyStyle(letteredListParaStyle,story)
    # Apply special formating
    formatMarks(begin,splitedText,story)
    scribus.selectObject(story)
 
#####################
def decodeInput(res):
    '''Parse user input.'''
    global num,separator
    f = res[0]
    # Test numbered list
    if f.isdigit():
        n = re.search('\d{1,3}',res).group()
        num = int(n)
        # Get separator
        s = re.search('[^\d]{1,1}',res)
        if s:
            separator = s.group()
        return '1'
    # Test alphabetic list
    elif f.isalpha():
        if len(res) > 1: # if there is second letter or separator
            f2 = re.search('[a-zA-Z]{1,2}',res).group()
            if len(f2) > 1:
                digit1 = f2[1].lower()
                num = alphabet.find(digit1)+1
                digit2 = f2[0].lower()
                num2 = alphabet.find(digit2)+1
                num2 = num2 * len(alphabet)
                num = num + num2
            else:
                digit1 = f2[0].lower()
                num = alphabet.find(digit1)+1
        else:
            digit1 = f.lower()
            num = alphabet.find(digit1)+1
        # Get separator
        s = re.search('[^a-zA-Z]{1,1}',res)
        if s:
            separator = s.group()
    elif f == bulletOperation: pass
    elif f == cleanOperation: pass
    else: f = ''
    return f
 
#####################
def handleSelected():
    """Handle frame selection."""
    global markOperation,separator
    story = scribus.getSelectedObject(0)  
    if story:
        res = scribus.valueDialog(scriptWindowTitle,askOperationMsg,defaultOperation)
        res = res.strip()
        if res:
            markOperation = decodeInput(res)
            if markOperation:
                doAllOperation(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)