Bullets and numbered lists: Difference between revisions
Jump to navigation
Jump to search
m (→Caveats) |
m (→Caveats) |
||
Line 91: | Line 91: | ||
+'and apply <i>'+listStyle+'</i> style.' \ | +'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>' \ | +'<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 | +'<li>"<b>'+cleanOperation.lower()+'</b>" input will <b>delete</b> marks ' \ | ||
+'and apply <i>'+defaultStyle+'</i> style.</li>' \ | +'and apply <br><i>'+defaultStyle+'</i> style.</li>' \ | ||
+'<li>Any <b>other</b> input will <b>cancel</b> all operations.</li></ul>' \ | +'<li>Any <b>other</b> input will <b>cancel</b> all operations.</li></ul>' \ | ||
Revision as of 00:06, 15 January 2011
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 doesn't exists -- with proper 2 digits indentation, but is necessary set tabulation "by hand", 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 such number, and will 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 marks or 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 "Numbered List" or "Bullet", if it doesn't exist, with proper indentation. Tabulation need to be defined by user to identical identation value. * If there is no selection, will 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 such 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 ' \ +'and apply <br><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 # {,4} = 0 to 4 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)