From 23387d6a5c8094521ec9e3bed1e455a63c267cd9 Mon Sep 17 00:00:00 2001 From: pinky <> Date: Sun, 7 Jan 2007 21:24:58 +0000 Subject: Removed reportlab -> 2.0 Better report on timesheets bzr revid: pinky-f7e72504718a6a358300c76ac783f3eb37406dbd --- bin/reportlab/tools/pythonpoint/pythonpoint.py | 1129 ------------------------ 1 file changed, 1129 deletions(-) delete mode 100755 bin/reportlab/tools/pythonpoint/pythonpoint.py (limited to 'bin/reportlab/tools/pythonpoint/pythonpoint.py') diff --git a/bin/reportlab/tools/pythonpoint/pythonpoint.py b/bin/reportlab/tools/pythonpoint/pythonpoint.py deleted file mode 100755 index 18ef842be0a..00000000000 --- a/bin/reportlab/tools/pythonpoint/pythonpoint.py +++ /dev/null @@ -1,1129 +0,0 @@ -#! /usr/bin/python2.3 - -""" -This is PythonPoint! - -The idea is a simple markup languages for describing presentation -slides, and other documents which run page by page. I expect most -of it will be reusable in other page layout stuff. - -Look at the sample near the top, which shows how the presentation -should be coded up. - -The parser, which is in a separate module to allow for multiple -parsers, turns the XML sample into an object tree. There is a -simple class hierarchy of items, the inner levels of which create -flowable objects to go in the frames. These know how to draw -themselves. - -The currently available 'Presentation Objects' are: - - The main hierarchy... - PPPresentation - PPSection - PPSlide - PPFrame - - PPAuthor, PPTitle and PPSubject are optional - - Things to flow within frames... - PPPara - flowing text - PPPreformatted - text with line breaks and tabs, for code.. - PPImage - PPTable - bulk formatted tabular data - PPSpacer - - Things to draw directly on the page... - PPRect - PPRoundRect - PPDrawingElement - user base class for graphics - PPLine - PPEllipse - -Features added by H. Turgut Uyar -- TrueType support (actually, just an import in the style file); - this also enables the use of Unicode symbols -- para, image, table, line, rectangle, roundrect, ellipse, polygon - and string elements can now have effect attributes - (careful: new slide for each effect!) -- added printout mode (no new slides for effects, see item above) -- added a second-level bullet: Bullet2 -- small bugfixes in handleHiddenSlides: - corrected the outlineEntry of included hidden slide - and made sure to include the last slide even if hidden - -Recently added features are: - -- file globbing -- package structure -- named colors throughout (using names from reportlab/lib/colors.py) -- handout mode with arbitrary number of columns per page -- stripped off pages hidden in the outline tree (hackish) -- new tag for speaker notes (paragraphs only) -- new tag for syntax-colorized Python code -- reformatted pythonpoint.xml and monterey.xml demos -- written/extended DTD -- arbitrary font support -- print proper speaker notes (TODO) -- fix bug with partially hidden graphics (TODO) -- save in combined presentation/handout mode (TODO) -- add pyRXP support (TODO) -""" - -import os, sys, imp, string, pprint, getopt, glob - -from reportlab import rl_config -from reportlab.lib import styles -from reportlab.lib import colors -from reportlab.lib.units import cm -from reportlab.lib.utils import getStringIO -from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY -from reportlab.pdfbase import pdfmetrics -from reportlab.pdfgen import canvas -from reportlab.platypus.doctemplate import SimpleDocTemplate -from reportlab.platypus.flowables import Flowable -from reportlab.platypus.xpreformatted import PythonPreformatted -from reportlab.platypus import Preformatted, Paragraph, Frame, \ - Image, Table, TableStyle, Spacer - - -USAGE_MESSAGE = """\ -PythonPoint - a tool for making presentations in PDF. - -Usage: - pythonpoint.py [options] file1.xml [file2.xml [...]] - - where options can be any of these: - - -h / --help prints this message - -n / --notes leave room for comments - -v / --verbose verbose mode - -s / --silent silent mode (NO output) - --handout produce handout document - --printout produce printout document - --cols specify number of columns - on handout pages (default: 2) - -To create the PythonPoint user guide, do: - pythonpoint.py pythonpoint.xml -""" - - -##################################################################### -# This should probably go into reportlab/lib/fonts.py... -##################################################################### - -class FontNameNotFoundError(Exception): - pass - - -class FontFilesNotFoundError(Exception): - pass - - -##def findFontName(path): -## "Extract a Type-1 font name from an AFM file." -## -## f = open(path) -## -## found = 0 -## while not found: -## line = f.readline()[:-1] -## if not found and line[:16] == 'StartCharMetrics': -## raise FontNameNotFoundError, path -## if line[:8] == 'FontName': -## fontName = line[9:] -## found = 1 -## -## return fontName -## -## -##def locateFilesForFontWithName(name): -## "Search known paths for AFM/PFB files describing T1 font with given name." -## -## join = os.path.join -## splitext = os.path.splitext -## -## afmFile = None -## pfbFile = None -## -## found = 0 -## while not found: -## for p in rl_config.T1SearchPath: -## afmFiles = glob.glob(join(p, '*.[aA][fF][mM]')) -## for f in afmFiles: -## T1name = findFontName(f) -## if T1name == name: -## afmFile = f -## found = 1 -## break -## if afmFile: -## break -## break -## -## if afmFile: -## pfbFile = glob.glob(join(splitext(afmFile)[0] + '.[pP][fF][bB]'))[0] -## -## return afmFile, pfbFile -## -## -##def registerFont(name): -## "Register Type-1 font for future use." -## -## rl_config.warnOnMissingFontGlyphs = 0 -## rl_config.T1SearchPath.append(r'C:\Programme\Python21\reportlab\test') -## -## afmFile, pfbFile = locateFilesForFontWithName(name) -## if not afmFile and not pfbFile: -## raise FontFilesNotFoundError -## -## T1face = pdfmetrics.EmbeddedType1Face(afmFile, pfbFile) -## T1faceName = name -## pdfmetrics.registerTypeFace(T1face) -## T1font = pdfmetrics.Font(name, T1faceName, 'WinAnsiEncoding') -## pdfmetrics.registerFont(T1font) - - -def registerFont0(sourceFile, name, path): - "Register Type-1 font for future use, simple version." - - rl_config.warnOnMissingFontGlyphs = 0 - - p = os.path.join(os.path.dirname(sourceFile), path) - afmFiles = glob.glob(p + '.[aA][fF][mM]') - pfbFiles = glob.glob(p + '.[pP][fF][bB]') - assert len(afmFiles) == len(pfbFiles) == 1, FontFilesNotFoundError - - T1face = pdfmetrics.EmbeddedType1Face(afmFiles[0], pfbFiles[0]) - T1faceName = name - pdfmetrics.registerTypeFace(T1face) - T1font = pdfmetrics.Font(name, T1faceName, 'WinAnsiEncoding') - pdfmetrics.registerFont(T1font) - -##################################################################### - - -def checkColor(col): - "Converts a color name to an RGB tuple, if possible." - - if type(col) == type('') and col in dir(colors): - col = getattr(colors, col) - col = (col.red, col.green, col.blue) - - return col - - -def handleHiddenSlides(slides): - """Filters slides from a list of slides. - - In a sequence of hidden slides all but the last one are - removed. Also, the slide before the sequence of hidden - ones is removed. - - This assumes to leave only those slides in the handout - that also appear in the outline, hoping to reduce se- - quences where each new slide only adds one new line - to a list of items... - """ - - itd = indicesToDelete = map(lambda s:s.outlineEntry == None, slides) - - for i in range(len(itd)-1): - if itd[i] == 1: - if itd[i+1] == 0: - itd[i] = 0 - if i > 0 and itd[i-1] == 0: - itd[i-1] = 1 - - itd[len(itd)-1] = 0 - - for i in range(len(itd)): - if slides[i].outlineEntry: - curOutlineEntry = slides[i].outlineEntry - if itd[i] == 1: - slides[i].delete = 1 - else: - slides[i].outlineEntry = curOutlineEntry - slides[i].delete = 0 - - slides = filter(lambda s:s.delete == 0, slides) - - return slides - - -def makeSlideTable(slides, pageSize, docWidth, numCols): - """Returns a table containing a collection of SlideWrapper flowables. - """ - - slides = handleHiddenSlides(slides) - - # Set table style. - tabStyle = TableStyle( - [('GRID', (0,0), (-1,-1), 0.25, colors.black), - ('ALIGN', (0,0), (-1,-1), 'CENTRE') - ]) - - # Build table content. - width = docWidth/numCols - height = width * pageSize[1]/pageSize[0] - matrix = [] - row = [] - for slide in slides: - sw = SlideWrapper(width, height, slide, pageSize) - if (len(row)) < numCols: - row.append(sw) - else: - matrix.append(row) - row = [] - row.append(sw) - if len(row) > 0: - for i in range(numCols-len(row)): - row.append('') - matrix.append(row) - - # Make Table flowable. - t = Table(matrix, - [width + 5]*len(matrix[0]), - [height + 5]*len(matrix)) - t.setStyle(tabStyle) - - return t - - -class SlideWrapper(Flowable): - """A Flowable wrapping a PPSlide object. - """ - - def __init__(self, width, height, slide, pageSize): - Flowable.__init__(self) - self.width = width - self.height = height - self.slide = slide - self.pageSize = pageSize - - - def __repr__(self): - return "SlideWrapper(w=%s, h=%s)" % (self.width, self.height) - - - def draw(self): - "Draw the slide in our relative coordinate system." - - slide = self.slide - pageSize = self.pageSize - canv = self.canv - - canv.saveState() - canv.scale(self.width/pageSize[0], self.height/pageSize[1]) - slide.effectName = None - slide.drawOn(self.canv) - canv.restoreState() - - -class PPPresentation: - def __init__(self): - self.sourceFilename = None - self.filename = None - self.outDir = None - self.description = None - self.title = None - self.author = None - self.subject = None - self.notes = 0 # different printing mode - self.handout = 0 # prints many slides per page - self.printout = 0 # remove hidden slides - self.cols = 0 # columns per handout page - self.slides = [] - self.effectName = None - self.showOutline = 1 #should it be displayed when opening? - self.compression = rl_config.pageCompression - self.pageDuration = None - #assume landscape - self.pageWidth = rl_config.defaultPageSize[1] - self.pageHeight = rl_config.defaultPageSize[0] - self.verbose = rl_config.verbose - - - def saveAsPresentation(self): - """Write the PDF document, one slide per page.""" - if self.verbose: - print 'saving presentation...' - pageSize = (self.pageWidth, self.pageHeight) - if self.sourceFilename: - filename = os.path.splitext(self.sourceFilename)[0] + '.pdf' - if self.outDir: filename = os.path.join(self.outDir,os.path.basename(filename)) - if self.verbose: - print filename - #canv = canvas.Canvas(filename, pagesize = pageSize) - outfile = getStringIO() - if self.notes: - #translate the page from landscape to portrait - pageSize= pageSize[1], pageSize[0] - canv = canvas.Canvas(outfile, pagesize = pageSize) - canv.setPageCompression(self.compression) - canv.setPageDuration(self.pageDuration) - if self.title: - canv.setTitle(self.title) - if self.author: - canv.setAuthor(self.author) - if self.subject: - canv.setSubject(self.subject) - - slideNo = 0 - for slide in self.slides: - #need diagnostic output if something wrong with XML - slideNo = slideNo + 1 - if self.verbose: - print 'doing slide %d, id = %s' % (slideNo, slide.id) - if self.notes: - #frame and shift the slide - #canv.scale(0.67, 0.67) - scale_amt = (min(pageSize)/float(max(pageSize)))*.95 - #canv.translate(self.pageWidth / 6.0, self.pageHeight / 3.0) - #canv.translate(self.pageWidth / 2.0, .025*self.pageHeight) - canv.translate(.025*self.pageHeight, (self.pageWidth/2.0) + 5) - #canv.rotate(90) - canv.scale(scale_amt, scale_amt) - canv.rect(0,0,self.pageWidth, self.pageHeight) - slide.drawOn(canv) - canv.showPage() - - #ensure outline visible by default - if self.showOutline: - canv.showOutline() - - canv.save() - return self.savetofile(outfile, filename) - - - def saveAsHandout(self): - """Write the PDF document, multiple slides per page.""" - - styleSheet = getSampleStyleSheet() - h1 = styleSheet['Heading1'] - bt = styleSheet['BodyText'] - - if self.sourceFilename : - filename = os.path.splitext(self.sourceFilename)[0] + '.pdf' - - outfile = getStringIO() - doc = SimpleDocTemplate(outfile, pagesize=rl_config.defaultPageSize, showBoundary=0) - doc.leftMargin = 1*cm - doc.rightMargin = 1*cm - doc.topMargin = 2*cm - doc.bottomMargin = 2*cm - multiPageWidth = rl_config.defaultPageSize[0] - doc.leftMargin - doc.rightMargin - 50 - - story = [] - orgFullPageSize = (self.pageWidth, self.pageHeight) - t = makeSlideTable(self.slides, orgFullPageSize, multiPageWidth, self.cols) - story.append(t) - -## #ensure outline visible by default -## if self.showOutline: -## doc.canv.showOutline() - - doc.build(story) - return self.savetofile(outfile, filename) - - def savetofile(self, pseudofile, filename): - """Save the pseudo file to disk and return its content as a - string of text.""" - pseudofile.flush() - content = pseudofile.getvalue() - pseudofile.close() - if filename : - outf = open(filename, "wb") - outf.write(content) - outf.close() - return content - - - - def save(self): - "Save the PDF document." - - if self.handout: - return self.saveAsHandout() - else: - return self.saveAsPresentation() - - -#class PPSection: -# """A section can hold graphics which will be drawn on all -# pages within it, before frames and other content are done. -# In other words, a background template.""" -# def __init__(self, name): -# self.name = name -# self.graphics = [] -# -# def drawOn(self, canv): -# for graphic in self.graphics: -### graphic.drawOn(canv) -# -# name = str(hash(graphic)) -# internalname = canv._doc.hasForm(name) -# -# canv.saveState() -# if not internalname: -# canv.beginForm(name) -# graphic.drawOn(canv) -# canv.endForm() -# canv.doForm(name) -# else: -# canv.doForm(name) -# canv.restoreState() - - -definedForms = {} - -class PPSection: - """A section can hold graphics which will be drawn on all - pages within it, before frames and other content are done. - In other words, a background template.""" - - def __init__(self, name): - self.name = name - self.graphics = [] - - def drawOn(self, canv): - for graphic in self.graphics: - graphic.drawOn(canv) - continue - name = str(hash(graphic)) - #internalname = canv._doc.hasForm(name) - if definedForms.has_key(name): - internalname = 1 - else: - internalname = None - definedForms[name] = 1 - if not internalname: - canv.beginForm(name) - canv.saveState() - graphic.drawOn(canv) - canv.restoreState() - canv.endForm() - canv.doForm(name) - else: - canv.doForm(name) - - -class PPNotes: - def __init__(self): - self.content = [] - - def drawOn(self, canv): - print self.content - - -class PPSlide: - def __init__(self): - self.id = None - self.title = None - self.outlineEntry = None - self.outlineLevel = 0 # can be higher for sub-headings - self.effectName = None - self.effectDirection = 0 - self.effectDimension = 'H' - self.effectMotion = 'I' - self.effectDuration = 1 - self.frames = [] - self.notes = [] - self.graphics = [] - self.section = None - - def drawOn(self, canv): - if self.effectName: - canv.setPageTransition( - effectname=self.effectName, - direction = self.effectDirection, - dimension = self.effectDimension, - motion = self.effectMotion, - duration = self.effectDuration - ) - - if self.outlineEntry: - #gets an outline automatically - self.showOutline = 1 - #put an outline entry in the left pane - tag = self.title - canv.bookmarkPage(tag) - canv.addOutlineEntry(tag, tag, self.outlineLevel) - - if self.section: - self.section.drawOn(canv) - - for graphic in self.graphics: - graphic.drawOn(canv) - - for frame in self.frames: - frame.drawOn(canv) - -## # Need to draw the notes *somewhere*... -## for note in self.notes: -## print note - - -class PPFrame: - def __init__(self, x, y, width, height): - self.x = x - self.y = y - self.width = width - self.height = height - self.content = [] - self.showBoundary = 0 - - def drawOn(self, canv): - #make a frame - frame = Frame( self.x, - self.y, - self.width, - self.height - ) - frame.showBoundary = self.showBoundary - - #build a story for the frame - story = [] - for thingy in self.content: - #ask it for any flowables - story.append(thingy.getFlowable()) - #draw it - frame.addFromList(story,canv) - - -class PPPara: - """This is a placeholder for a paragraph.""" - def __init__(self): - self.rawtext = '' - self.style = None - - def escapeAgain(self, text): - """The XML has been parsed once, so '>' became '>' - in rawtext. We need to escape this to get back to - something the Platypus parser can accept""" - pass - - def getFlowable(self): -## print 'rawText for para:' -## print repr(self.rawtext) - p = Paragraph( - self.rawtext, - getStyles()[self.style], - self.bulletText - ) - return p - - -class PPPreformattedText: - """Use this for source code, or stuff you do not want to wrap""" - def __init__(self): - self.rawtext = '' - self.style = None - - def getFlowable(self): - return Preformatted(self.rawtext, getStyles()[self.style]) - - -class PPPythonCode: - """Use this for colored Python source code""" - def __init__(self): - self.rawtext = '' - self.style = None - - def getFlowable(self): - return PythonPreformatted(self.rawtext, getStyles()[self.style]) - - -class PPImage: - """Flowing image within the text""" - def __init__(self): - self.filename = None - self.width = None - self.height = None - - def getFlowable(self): - return Image(self.filename, self.width, self.height) - - -class PPTable: - """Designed for bulk loading of data for use in presentations.""" - def __init__(self): - self.rawBlocks = [] #parser stuffs things in here... - self.fieldDelim = ',' #tag args can override - self.rowDelim = '\n' #tag args can override - self.data = None - self.style = None #tag args must specify - self.widths = None #tag args can override - self.heights = None #tag args can override - - def getFlowable(self): - self.parseData() - t = Table( - self.data, - self.widths, - self.heights) - if self.style: - t.setStyle(getStyles()[self.style]) - - return t - - def parseData(self): - """Try to make sense of the table data!""" - rawdata = string.strip(string.join(self.rawBlocks, '')) - lines = string.split(rawdata, self.rowDelim) - #clean up... - lines = map(string.strip, lines) - self.data = [] - for line in lines: - cells = string.split(line, self.fieldDelim) - self.data.append(cells) - - #get the width list if not given - if not self.widths: - self.widths = [None] * len(self.data[0]) - if not self.heights: - self.heights = [None] * len(self.data) - -## import pprint -## print 'table data:' -## print 'style=',self.style -## print 'widths=',self.widths -## print 'heights=',self.heights -## print 'fieldDelim=',repr(self.fieldDelim) -## print 'rowDelim=',repr(self.rowDelim) -## pprint.pprint(self.data) - - -class PPSpacer: - def __init__(self): - self.height = 24 #points - - def getFlowable(self): - return Spacer(72, self.height) - - - ############################################################# - # - # The following are things you can draw on a page directly. - # - ############################################################## - -##class PPDrawingElement: -## """Base class for something which you draw directly on the page.""" -## def drawOn(self, canv): -## raise "NotImplementedError", "Abstract base class!" - - -class PPFixedImage: - """You place this on the page, rather than flowing it""" - def __init__(self): - self.filename = None - self.x = 0 - self.y = 0 - self.width = None - self.height = None - - def drawOn(self, canv): - if self.filename: - x, y = self.x, self.y - w, h = self.width, self.height - canv.drawImage(self.filename, x, y, w, h) - - -class PPRectangle: - def __init__(self, x, y, width, height): - self.x = x - self.y = y - self.width = width - self.height = height - self.fillColor = None - self.strokeColor = (1,1,1) - self.lineWidth=0 - - def drawOn(self, canv): - canv.saveState() - canv.setLineWidth(self.lineWidth) - if self.fillColor: - r,g,b = checkColor(self.fillColor) - canv.setFillColorRGB(r,g,b) - if self.strokeColor: - r,g,b = checkColor(self.strokeColor) - canv.setStrokeColorRGB(r,g,b) - canv.rect(self.x, self.y, self.width, self.height, - stroke=(self.strokeColor<>None), - fill = (self.fillColor<>None) - ) - canv.restoreState() - - -class PPRoundRect: - def __init__(self, x, y, width, height, radius): - self.x = x - self.y = y - self.width = width - self.height = height - self.radius = radius - self.fillColor = None - self.strokeColor = (1,1,1) - self.lineWidth=0 - - def drawOn(self, canv): - canv.saveState() - canv.setLineWidth(self.lineWidth) - if self.fillColor: - r,g,b = checkColor(self.fillColor) - canv.setFillColorRGB(r,g,b) - if self.strokeColor: - r,g,b = checkColor(self.strokeColor) - canv.setStrokeColorRGB(r,g,b) - canv.roundRect(self.x, self.y, self.width, self.height, - self.radius, - stroke=(self.strokeColor<>None), - fill = (self.fillColor<>None) - ) - canv.restoreState() - - -class PPLine: - def __init__(self, x1, y1, x2, y2): - self.x1 = x1 - self.y1 = y1 - self.x2 = x2 - self.y2 = y2 - self.fillColor = None - self.strokeColor = (1,1,1) - self.lineWidth=0 - - def drawOn(self, canv): - canv.saveState() - canv.setLineWidth(self.lineWidth) - if self.strokeColor: - r,g,b = checkColor(self.strokeColor) - canv.setStrokeColorRGB(r,g,b) - canv.line(self.x1, self.y1, self.x2, self.y2) - canv.restoreState() - - -class PPEllipse: - def __init__(self, x1, y1, x2, y2): - self.x1 = x1 - self.y1 = y1 - self.x2 = x2 - self.y2 = y2 - self.fillColor = None - self.strokeColor = (1,1,1) - self.lineWidth=0 - - def drawOn(self, canv): - canv.saveState() - canv.setLineWidth(self.lineWidth) - if self.strokeColor: - r,g,b = checkColor(self.strokeColor) - canv.setStrokeColorRGB(r,g,b) - if self.fillColor: - r,g,b = checkColor(self.fillColor) - canv.setFillColorRGB(r,g,b) - canv.ellipse(self.x1, self.y1, self.x2, self.y2, - stroke=(self.strokeColor<>None), - fill = (self.fillColor<>None) - ) - canv.restoreState() - - -class PPPolygon: - def __init__(self, pointlist): - self.points = pointlist - self.fillColor = None - self.strokeColor = (1,1,1) - self.lineWidth=0 - - def drawOn(self, canv): - canv.saveState() - canv.setLineWidth(self.lineWidth) - if self.strokeColor: - r,g,b = checkColor(self.strokeColor) - canv.setStrokeColorRGB(r,g,b) - if self.fillColor: - r,g,b = checkColor(self.fillColor) - canv.setFillColorRGB(r,g,b) - - path = canv.beginPath() - (x,y) = self.points[0] - path.moveTo(x,y) - for (x,y) in self.points[1:]: - path.lineTo(x,y) - path.close() - canv.drawPath(path, - stroke=(self.strokeColor<>None), - fill=(self.fillColor<>None)) - canv.restoreState() - - -class PPString: - def __init__(self, x, y): - self.text = '' - self.x = x - self.y = y - self.align = TA_LEFT - self.font = 'Times-Roman' - self.size = 12 - self.color = (0,0,0) - self.hasInfo = 0 # these can have data substituted into them - - def normalizeText(self): - """It contains literal XML text typed over several lines. - We want to throw away - tabs, newlines and so on, and only accept embedded string - like '\n'""" - lines = string.split(self.text, '\n') - newtext = [] - for line in lines: - newtext.append(string.strip(line)) - #accept all the '\n' as newlines - - self.text = newtext - - def drawOn(self, canv): - # for a string in a section, this will be drawn several times; - # so any substitution into the text should be in a temporary - # variable - if self.hasInfo: - # provide a dictionary of stuff which might go into - # the string, so they can number pages, do headers - # etc. - info = {} - info['title'] = canv._doc.info.title - info['author'] = canv._doc.info.author - info['subject'] = canv._doc.info.subject - info['page'] = canv.getPageNumber() - drawText = self.text % info - else: - drawText = self.text - - if self.color is None: - return - lines = string.split(string.strip(drawText), '\\n') - canv.saveState() - - canv.setFont(self.font, self.size) - - r,g,b = checkColor(self.color) - canv.setFillColorRGB(r,g,b) - cur_y = self.y - for line in lines: - if self.align == TA_LEFT: - canv.drawString(self.x, cur_y, line) - elif self.align == TA_CENTER: - canv.drawCentredString(self.x, cur_y, line) - elif self.align == TA_RIGHT: - canv.drawRightString(self.x, cur_y, line) - cur_y = cur_y - 1.2*self.size - - canv.restoreState() - -class PPDrawing: - def __init__(self): - self.drawing = None - def getFlowable(self): - return self.drawing - -class PPFigure: - def __init__(self): - self.figure = None - def getFlowable(self): - return self.figure - -def getSampleStyleSheet(): - from reportlab.tools.pythonpoint.styles.standard import getParagraphStyles - return getParagraphStyles() - - -#make a singleton and a function to access it -_styles = None -def getStyles(): - global _styles - if not _styles: - _styles = getSampleStyleSheet() - return _styles - - -def setStyles(newStyleSheet): - global _styles - _styles = newStyleSheet - - -##def test(): -## p = stdparser.PPMLParser() -## p.feed(sample) -## p.getPresentation().save() -## p.close() - -_pyRXP_Parser = None -def validate(rawdata): - global _pyRXP_Parser - if not _pyRXP_Parser: - try: - import pyRXP - except ImportError: - return - from reportlab.lib.utils import open_and_read, _RL_DIR, rl_isfile - dtd = 'pythonpoint.dtd' - if not rl_isfile(dtd): - dtd = os.path.join(_RL_DIR,'tools','pythonpoint','pythonpoint.dtd') - if not rl_isfile(dtd): return - def eocb(URI,dtdText=open_and_read(dtd),dtd=dtd): - if os.path.basename(URI)=='pythonpoint.dtd': return dtd,dtdText - return URI - _pyRXP_Parser = pyRXP.Parser(eoCB=eocb) - return _pyRXP_Parser.parse(rawdata) - -def process(datafile, notes=0, handout=0, printout=0, cols=0, verbose=0, outDir=None, datafilename=None, fx=1): - "Process one PythonPoint source file." - if not hasattr(datafile, "read"): - if not datafilename: datafilename = datafile - datafile = open(datafile) - else: - if not datafilename: datafilename = "PseudoFile" - rawdata = datafile.read() - - #if pyRXP present, use it to check and get line numbers for errors... - validate(rawdata) - - return _process(rawdata, datafilename, notes, handout, printout, cols, verbose, outDir, fx) - -def _process(rawdata, datafilename, notes=0, handout=0, printout=0, cols=0, verbose=0, outDir=None, fx=1): - #print 'inner process fx=%d' % fx - from reportlab.tools.pythonpoint.stdparser import PPMLParser - parser = PPMLParser() - parser.fx = fx - parser.sourceFilename = datafilename - parser.feed(rawdata) - pres = parser.getPresentation() - pres.sourceFilename = datafilename - pres.outDir = outDir - pres.notes = notes - pres.handout = handout - pres.printout = printout - pres.cols = cols - pres.verbose = verbose - - if printout: - pres.slides = handleHiddenSlides(pres.slides) - - #this does all the work - pdfcontent = pres.save() - - if verbose: - print 'saved presentation %s.pdf' % os.path.splitext(datafilename)[0] - parser.close() - - return pdfcontent -##class P: -## def feed(self, text): -## parser = stdparser.PPMLParser() -## d = pyRXP.parse(text) -## -## -##def process2(datafilename, notes=0, handout=0, cols=0): -## "Process one PythonPoint source file." -## -## import pyRXP, pprint -## -## rawdata = open(datafilename).read() -## d = pyRXP.parse(rawdata) -## pprint.pprint(d) - - -def handleOptions(): - # set defaults - from reportlab import rl_config - options = {'cols':2, - 'handout':0, - 'printout':0, - 'help':0, - 'notes':0, - 'fx':1, - 'verbose':rl_config.verbose, - 'silent':0, - 'outDir': None} - - args = sys.argv[1:] - args = filter(lambda x: x and x[0]=='-',args) + filter(lambda x: not x or x[0]!='-',args) - try: - shortOpts = 'hnvsx' - longOpts = string.split('cols= outdir= handout help notes printout verbose silent nofx') - optList, args = getopt.getopt(args, shortOpts, longOpts) - except getopt.error, msg: - options['help'] = 1 - - if not args and os.path.isfile('pythonpoint.xml'): - args = ['pythonpoint.xml'] - - # Remove leading dashes (max. two). - for i in range(len(optList)): - o, v = optList[i] - while o[0] == '-': - o = o[1:] - optList[i] = (o, v) - - if o == 'cols': options['cols'] = int(v) - elif o=='outdir': options['outDir'] = v - - if filter(lambda ov: ov[0] == 'handout', optList): - options['handout'] = 1 - - if filter(lambda ov: ov[0] == 'printout', optList): - options['printout'] = 1 - - if optList == [] and args == [] or \ - filter(lambda ov: ov[0] in ('h', 'help'), optList): - options['help'] = 1 - - if filter(lambda ov: ov[0] in ('n', 'notes'), optList): - options['notes'] = 1 - - if filter(lambda ov: ov[0] in ('x', 'nofx'), optList): - options['fx'] = 0 - - if filter(lambda ov: ov[0] in ('v', 'verbose'), optList): - options['verbose'] = 1 - - #takes priority over verbose. Used by our test suite etc. - #to ensure no output at all - if filter(lambda ov: ov[0] in ('s', 'silent'), optList): - options['silent'] = 1 - options['verbose'] = 0 - - - return options, args - -def main(): - options, args = handleOptions() - - if options['help']: - print USAGE_MESSAGE - sys.exit(0) - - if options['verbose'] and options['notes']: - print 'speaker notes mode' - - if options['verbose'] and options['handout']: - print 'handout mode' - - if options['verbose'] and options['printout']: - print 'printout mode' - - if not options['fx']: - print 'suppressing special effects' - for fileGlobs in args: - files = glob.glob(fileGlobs) - for datafile in files: - if os.path.isfile(datafile): - file = os.path.join(os.getcwd(), datafile) - notes, handout, printout, cols, verbose, fx = options['notes'], options['handout'], options['printout'], options['cols'], options['verbose'], options['fx'] - process(file, notes, handout, printout, cols, verbose, options['outDir'], fx=fx) - else: - print 'Data file not found:', datafile - -if __name__ == '__main__': - main() -- cgit v1.2.3