Bullets and numbered lists
Jump to navigation
Jump to search
Improved bullets simple script using regular expressions Python module. Build bulleted lists, numbered lists starting with any number plus separator and delete list marks. Create styles, if it don't exists, with proper indentation to 2 digits numbers, but is necessary set tabulation, as this can't be done by script.
Usage
Select a frame or some paragraphs and run the script. Asked, input the operation type:
- "b" input will create bullet marks and apply "Bullet" style.
- Any number input will create numbered list starting with that number and apply "Numbered List" style. Optional last char will be used as separator. Default: dot. Example: "1)", "16#", "256-".
- "x" input will delete marks and apply "Default Paragraph Style" style.
- Any other response will cancel all operations.
Caveats
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.
#!/usr/bin/env python # -*- coding: utf-8 -*- """ Insert numbers 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-14a ====== Usage: Select paragraphs at any points. Run script. Response 'yes' will clear all numbers. Any other response will create numbered list. Caveats: * Cleans all text format of text selection (font, bold, subscript, etc). * Creates paragraph style "List", if it doesn't exist, with proper indentation. Tabulation need to be defined by user to identical identation value. * If there is no selection, apply bullets to all text in current frame. """ import sys import re 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 ####################### listStyle = 'Numbered list' bulletStyle = 'Bullet' defaultStyle = 'Default Paragraph Style' separator = '.' indent = 18 # points # Put your favorite unicode char and tab: '\u2022\t' # Get hex code from "Insert > Special character..." palette bulletString = u'•\t' ########### # 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 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>." markOperation = '' bulletOperation = 'B' numberOperation = '1' cleanOperation = 'X' defaultResponse = bulletOperation askOperationMsg = "<h2>What mark operation?</h2>" \ +'<ul><li>"<b>'+bulletOperation.lower()+'</b>" input will create <b>bullet</b> marks.</li>' \ +'and apply <i>'+bulletStyle+'</i> style.' \ +'<li><b>Any number</b> input will create <b>numbered list</b> <br>starting with that number ' \ +'and apply <i>'+listStyle+'</i> style.' \ +'<br><font color="#0000ff">Optional last char will be used as separator.<br>Default: dot. Example: "<b>1)</b>"</font>' \ +'<li>"<b>'+cleanOperation.lower()+'</b>" input will <b>delete</b> marks.<br>' \ +'and apply <i>'+defaultStyle+'</i> style.</li>' \ +'<li>Any <b>other</b> input will <b>cancel</b> all operations.</li></ul>' \ # No need to change: justClean = 0 # Regular expression to match any mark: # '\r' = carriage return in Python # '\t' = tabulation in Python # [^\t] = non-tab chars # {,5} = 0 to 5 ocurrencies from paragraph begin to tab reAnyMark = r'\r[^\t]{,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 s = u'\r'+str(num)+separator+'\t' num += 1 return s #################### def insertMarks(t): '''Delete old marks and insert new ones.''' # Clear old numbers s = re.sub(reAnyMark,u'\r',t) if markOperation == numberOperation: # Insert numbers s = re.sub(u'\r',numbering,s) elif markOperation == bulletOperation: # Insert bullets b = u'\r'+bulletString s = re.sub(u'\r',b,s) return s ################# # 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 numbers and insert new ones cleanedText = insertMarks(unicode(selectedText)) # Strip temp initial CR cleanedText = unicode(cleanedText)[1:] scribus.deleteText(story) scribus.insertText(cleanedText,begin,story) # Apply style scribus.deselectAll() # Get selection new end end = len(unicode(cleanedText)) scribus.selectText(begin,end,story) if markOperation == bulletOperation: style = bulletStyle elif markOperation == numberOperation: style = listStyle else: style = defaultStyle applyStyle(style,story) scribus.selectObject(story) def decodeInput(res): '''Parse user input.''' global num,separator f = res.upper()[0] if f.isdigit(): n = re.search('\d{1,3}',res).group() num = int(n) s = re.search('[^\d]{1,1}',res) if s: separator = s.group() return '1' else: return f ##################### def handleSelected(): """Handle frame selection.""" global markOperation,separator story = scribus.getSelectedObject(0) if story: res = scribus.valueDialog(scriptWindowTitle,askOperationMsg,defaultResponse) res = res.strip() if res: markOperation = decodeInput(res) operation = bulletOperation+numberOperation+cleanOperation if operation.count(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)