~openerp-dev/openobject-server/trunk-bug-712254-ysa

« back to all changes in this revision

Viewing changes to bin/reportlab/tools/pythonpoint/stdparser.py

  • Committer: pinky
  • Date: 2006-12-07 13:41:40 UTC
  • Revision ID: pinky-3f10ee12cea3c4c75cef44ab04ad33ef47432907
New trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""
 
2
Parser for PythonPoint using the xmllib.py in the standard Python
 
3
distribution.  Slow, but always present.  We intend to add new parsers
 
4
as Python 2.x and the XML package spread in popularity and stabilise.
 
5
 
 
6
The parser has a getPresentation method; it is called from
 
7
pythonpoint.py.
 
8
"""
 
9
 
 
10
import string, imp, sys, os, copy
 
11
from reportlab.lib.utils import SeqTypes
 
12
from reportlab.lib import xmllib
 
13
from reportlab.lib import colors
 
14
from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY
 
15
from reportlab.lib.utils import recursiveImport
 
16
from reportlab.tools.pythonpoint import pythonpoint
 
17
from reportlab.platypus import figures
 
18
 
 
19
 
 
20
def getModule(modulename,fromPath='reportlab.tools.pythonpoint.styles'):
 
21
    """Get a module containing style declarations.
 
22
 
 
23
    Search order is:
 
24
        reportlab/tools/pythonpoint/
 
25
        reportlab/tools/pythonpoint/styles/
 
26
        ./
 
27
    """
 
28
 
 
29
    try:
 
30
        exec 'from reportlab.tools.pythonpoint import '+modulename
 
31
        return eval(modulename)
 
32
    except ImportError:
 
33
        try:
 
34
            exec 'from reportlab.tools.pythonpoint.styles import '+modulename
 
35
            return eval(modulename)
 
36
        except ImportError:
 
37
            exec 'import '+modulename
 
38
            return eval(modulename)
 
39
 
 
40
 
 
41
class PPMLParser(xmllib.XMLParser):
 
42
    attributes = {
 
43
        #this defines the available attributes for all objects,
 
44
        #and their default values.  Although these don't have to
 
45
        #be strings, the ones parsed from the XML do, so
 
46
        #everything is a quoted string and the parser has to
 
47
        #convert these to numbers where appropriate.
 
48
        'stylesheet': {
 
49
            'path':'None',
 
50
            'module':'None',
 
51
            'function':'getParagraphStyles'
 
52
            },
 
53
        'frame': {
 
54
            'x':'0',
 
55
            'y':'0',
 
56
            'width':'0',
 
57
            'height':'0',
 
58
            'border':'false',
 
59
            'leftmargin':'0',    #this is ignored
 
60
            'topmargin':'0',     #this is ignored
 
61
            'rightmargin':'0',   #this is ignored
 
62
            'bottommargin':'0',  #this is ignored
 
63
            },
 
64
        'slide': {
 
65
            'id':'None',
 
66
            'title':'None',
 
67
            'effectname':'None',     # Split, Blinds, Box, Wipe, Dissolve, Glitter
 
68
            'effectdirection':'0',   # 0,90,180,270
 
69
            'effectdimension':'H',   # H or V - horizontal or vertical
 
70
            'effectmotion':'I',      # Inwards or Outwards
 
71
            'effectduration':'1',    #seconds,
 
72
            'outlineentry':'None',
 
73
            'outlinelevel':'0'       # 1 is a child, 2 is a grandchild etc.
 
74
            },
 
75
        'para': {
 
76
            'style':'Normal',
 
77
            'bullettext':'',
 
78
            'effectname':'None',
 
79
            'effectdirection':'0',
 
80
            'effectdimension':'H',
 
81
            'effectmotion':'I',
 
82
            'effectduration':'1'
 
83
            },
 
84
        'image': {
 
85
            'filename':'',
 
86
            'width':'None',
 
87
            'height':'None',
 
88
            'effectname':'None',
 
89
            'effectdirection':'0',
 
90
            'effectdimension':'H',
 
91
            'effectmotion':'I',
 
92
            'effectduration':'1'
 
93
            },
 
94
        'table': {
 
95
            'widths':'None',
 
96
            'heights':'None',
 
97
            'fieldDelim':',',
 
98
            'rowDelim':'\n',
 
99
            'style':'None',
 
100
            'effectname':'None',
 
101
            'effectdirection':'0',
 
102
            'effectdimension':'H',
 
103
            'effectmotion':'I',
 
104
            'effectduration':'1'
 
105
            },
 
106
        'rectangle': {
 
107
            'x':'0',
 
108
            'y':'0',
 
109
            'width':'100',
 
110
            'height':'100',
 
111
            'fill':'None',
 
112
            'stroke':'(0,0,0)',
 
113
            'linewidth':'0',
 
114
            'effectname':'None',
 
115
            'effectdirection':'0',
 
116
            'effectdimension':'H',
 
117
            'effectmotion':'I',
 
118
            'effectduration':'1'
 
119
            },
 
120
        'roundrect': {
 
121
            'x':'0',
 
122
            'y':'0',
 
123
            'width':'100',
 
124
            'height':'100',
 
125
            'radius':'6',
 
126
            'fill':'None',
 
127
            'stroke':'(0,0,0)',
 
128
            'linewidth':'0',
 
129
            'effectname':'None',
 
130
            'effectdirection':'0',
 
131
            'effectdimension':'H',
 
132
            'effectmotion':'I',
 
133
            'effectduration':'1'
 
134
            },
 
135
        'line': {
 
136
            'x1':'0',
 
137
            'y1':'0',
 
138
            'x2':'100',
 
139
            'y2':'100',
 
140
            'stroke':'(0,0,0)',
 
141
            'width':'0',
 
142
            'effectname':'None',
 
143
            'effectdirection':'0',
 
144
            'effectdimension':'H',
 
145
            'effectmotion':'I',
 
146
            'effectduration':'1'
 
147
            },
 
148
        'ellipse': {
 
149
            'x1':'0',
 
150
            'y1':'0',
 
151
            'x2':'100',
 
152
            'y2':'100',
 
153
            'stroke':'(0,0,0)',
 
154
            'fill':'None',
 
155
            'linewidth':'0',
 
156
            'effectname':'None',
 
157
            'effectdirection':'0',
 
158
            'effectdimension':'H',
 
159
            'effectmotion':'I',
 
160
            'effectduration':'1'
 
161
            },
 
162
        'polygon': {
 
163
            'points':'(0,0),(50,0),(25,25)',
 
164
            'stroke':'(0,0,0)',
 
165
            'linewidth':'0',
 
166
            'stroke':'(0,0,0)',
 
167
            'fill':'None',
 
168
            'effectname':'None',
 
169
            'effectdirection':'0',
 
170
            'effectdimension':'H',
 
171
            'effectmotion':'I',
 
172
            'effectduration':'1'
 
173
            },
 
174
        'string':{
 
175
            'x':'0',
 
176
            'y':'0',
 
177
            'color':'(0,0,0)',
 
178
            'font':'Times-Roman',
 
179
            'size':'12',
 
180
            'align':'left',
 
181
            'effectname':'None',
 
182
            'effectdirection':'0',
 
183
            'effectdimension':'H',
 
184
            'effectmotion':'I',
 
185
            'effectduration':'1'
 
186
            },
 
187
        'customshape':{
 
188
            'path':'None',
 
189
            'module':'None',
 
190
            'class':'None',
 
191
            'initargs':'None'
 
192
            }
 
193
        }
 
194
 
 
195
    def __init__(self):
 
196
        self.presentations = []
 
197
        #yes, I know a generic stack would be easier...
 
198
        #still, testing if we are 'in' something gives
 
199
        #a degree of validation.
 
200
        self._curPres = None
 
201
        self._curSection = None
 
202
        self._curSlide = None
 
203
        self._curFrame = None
 
204
        self._curPara = None    #the only places we are interested in
 
205
        self._curPrefmt = None
 
206
        self._curPyCode = None
 
207
        self._curString = None
 
208
        self._curTable = None
 
209
        self._curTitle = None
 
210
        self._curAuthor = None
 
211
        self._curSubject = None
 
212
        self.fx = 1
 
213
        xmllib.XMLParser.__init__(self)
 
214
 
 
215
 
 
216
    def _arg(self,tag,args,name):
 
217
        "What's this for???"
 
218
        if args.has_key(name):
 
219
            v = args[name]
 
220
        else:
 
221
            if self.attributes.has_key(tag):
 
222
                v = self.attributes[tag][name]
 
223
            else:
 
224
                v = None
 
225
        return v
 
226
 
 
227
 
 
228
    def ceval(self,tag,args,name):
 
229
        if args.has_key(name):
 
230
            v = args[name]
 
231
        else:
 
232
            if self.attributes.has_key(tag):
 
233
                v = self.attributes[tag][name]
 
234
            else:
 
235
                return None
 
236
 
 
237
        # handle named colors (names from reportlab.lib.colors)
 
238
        if name in ('color', 'stroke', 'fill'):
 
239
            v = str(pythonpoint.checkColor(v))
 
240
 
 
241
        return eval(v)
 
242
 
 
243
 
 
244
    def getPresentation(self):
 
245
        return self._curPres
 
246
 
 
247
 
 
248
    def handle_data(self, data):
 
249
        #the only data should be paragraph text, preformatted para
 
250
        #text, 'string text' for a fixed string on the page,
 
251
        #or table data
 
252
 
 
253
        if self._curPara:
 
254
            self._curPara.rawtext = self._curPara.rawtext + data
 
255
        elif self._curPrefmt:
 
256
            self._curPrefmt.rawtext = self._curPrefmt.rawtext + data
 
257
        elif self._curPyCode:
 
258
            self._curPyCode.rawtext = self._curPyCode.rawtext + data
 
259
        elif  self._curString:
 
260
            self._curString.text = self._curString.text + data
 
261
        elif self._curTable:
 
262
            self._curTable.rawBlocks.append(data)
 
263
        elif self._curTitle <> None:  # need to allow empty strings,
 
264
            # hence explicitly testing for None
 
265
            self._curTitle = self._curTitle + data
 
266
        elif self._curAuthor <> None:
 
267
            self._curAuthor = self._curAuthor + data
 
268
        elif self._curSubject <> None:
 
269
            self._curSubject = self._curSubject + data
 
270
 
 
271
 
 
272
    def handle_cdata(self, data):
 
273
        #just append to current paragraph text, so we can quote XML
 
274
        if self._curPara:
 
275
            self._curPara.rawtext = self._curPara.rawtext + data
 
276
        elif self._curPrefmt:
 
277
            self._curPrefmt.rawtext = self._curPrefmt.rawtext + data
 
278
        elif self._curPyCode:
 
279
            self._curPyCode.rawtext = self._curPyCode.rawtext + data
 
280
        elif  self._curString:
 
281
            self._curString.text = self._curString.text + data
 
282
        elif self._curTable:
 
283
            self._curTable.rawBlocks.append(data)
 
284
        elif self._curAuthor <> None:
 
285
            self._curAuthor = self._curAuthor + data
 
286
        elif self._curSubject <> None:
 
287
            self._curSubject = self._curSubject + data
 
288
 
 
289
 
 
290
    def start_presentation(self, args):
 
291
        self._curPres = pythonpoint.PPPresentation()
 
292
        self._curPres.filename = self._arg('presentation',args,'filename')
 
293
        self._curPres.effectName = self._arg('presentation',args,'effect')
 
294
        self._curPres.pageDuration = self._arg('presentation',args,'pageDuration')
 
295
 
 
296
        h = self._arg('presentation',args,'pageHeight')
 
297
        if h:
 
298
            self._curPres.pageHeight = h
 
299
        w = self._arg('presentation',args,'pageWidth')
 
300
        if w:
 
301
            self._curPres.pageWidth = w
 
302
        #print 'page size =', self._curPres.pageSize
 
303
 
 
304
 
 
305
    def end_presentation(self):
 
306
        pass
 
307
##        print 'Fully parsed presentation',self._curPres.filename
 
308
 
 
309
 
 
310
    def start_title(self, args):
 
311
        self._curTitle = ''
 
312
 
 
313
 
 
314
    def end_title(self):
 
315
        self._curPres.title = self._curTitle
 
316
        self._curTitle = None
 
317
 
 
318
 
 
319
    def start_author(self, args):
 
320
        self._curAuthor = ''
 
321
 
 
322
 
 
323
    def end_author(self):
 
324
        self._curPres.author = self._curAuthor
 
325
        self._curAuthor = None
 
326
 
 
327
 
 
328
    def start_subject(self, args):
 
329
        self._curSubject = ''
 
330
 
 
331
 
 
332
    def end_subject(self):
 
333
        self._curPres.subject = self._curSubject
 
334
        self._curSubject = None
 
335
 
 
336
 
 
337
    def start_stylesheet(self, args):
 
338
        #makes it the current style sheet.
 
339
        path = self._arg('stylesheet',args,'path')
 
340
        if path=='None': path = []
 
341
        if type(path) not in SeqTypes: path = [path]
 
342
        path.append('styles')
 
343
        path.append(os.getcwd())
 
344
        modulename = self._arg('stylesheet', args, 'module')
 
345
        funcname = self._arg('stylesheet', args, 'function')
 
346
        try:
 
347
            found = imp.find_module(modulename, path)
 
348
            (file, pathname, description) = found
 
349
            mod = imp.load_module(modulename, file, pathname, description)
 
350
        except ImportError:
 
351
            #last gasp
 
352
            mod = getModule(modulename)
 
353
 
 
354
        #now get the function
 
355
        func = getattr(mod, funcname)
 
356
        pythonpoint.setStyles(func())
 
357
##        print 'set global stylesheet to %s.%s()' % (modulename, funcname)
 
358
 
 
359
 
 
360
    def end_stylesheet(self):
 
361
        pass
 
362
 
 
363
 
 
364
    def start_section(self, args):
 
365
        name = self._arg('section',args,'name')
 
366
        self._curSection = pythonpoint.PPSection(name)
 
367
 
 
368
 
 
369
    def end_section(self):
 
370
        self._curSection = None
 
371
 
 
372
 
 
373
    def start_slide(self, args):
 
374
        s = pythonpoint.PPSlide()
 
375
        s.id = self._arg('slide',args,'id')
 
376
        s.title = self._arg('slide',args,'title')
 
377
        a = self._arg('slide',args,'effectname')
 
378
        if a <> 'None':
 
379
            s.effectName = a
 
380
        s.effectDirection = self.ceval('slide',args,'effectdirection')
 
381
        s.effectDimension = self._arg('slide',args,'effectdimension')
 
382
        s.effectDuration = self.ceval('slide',args,'effectduration')
 
383
        s.effectMotion = self._arg('slide',args,'effectmotion')
 
384
 
 
385
        #HACK - may not belong here in the long run...
 
386
        #by default, use the slide title for the outline entry,
 
387
        #unless it is specified as an arg.
 
388
        a = self._arg('slide',args,'outlineentry')
 
389
        if a == "Hide":
 
390
            s.outlineEntry = None
 
391
        elif a <> 'None':
 
392
            s.outlineEntry = a
 
393
        else:
 
394
            s.outlineEntry = s.title
 
395
 
 
396
        s.outlineLevel = self.ceval('slide',args,'outlinelevel')
 
397
 
 
398
        #let it know its section, which may be none
 
399
        s.section = self._curSection
 
400
        self._curSlide = s
 
401
 
 
402
 
 
403
    def end_slide(self):
 
404
        self._curPres.slides.append(self._curSlide)
 
405
        self._curSlide = None
 
406
 
 
407
 
 
408
    def start_frame(self, args):
 
409
        self._curFrame = pythonpoint.PPFrame(
 
410
            self.ceval('frame',args,'x'),
 
411
            self.ceval('frame',args,'y'),
 
412
            self.ceval('frame',args,'width'),
 
413
            self.ceval('frame',args,'height')
 
414
            )
 
415
        if self._arg('frame',args,'border')=='true':
 
416
            self._curFrame.showBoundary = 1
 
417
 
 
418
 
 
419
    def end_frame(self):
 
420
        self._curSlide.frames.append(self._curFrame)
 
421
        self._curFrame = None
 
422
 
 
423
 
 
424
    def start_notes(self, args):
 
425
        name = self._arg('notes',args,'name')
 
426
        self._curNotes = pythonpoint.PPNotes()
 
427
 
 
428
 
 
429
    def end_notes(self):
 
430
        self._curSlide.notes.append(self._curNotes)
 
431
        self._curNotes = None
 
432
 
 
433
 
 
434
    def start_registerFont(self, args):
 
435
        name = self._arg('font',args,'name')
 
436
        path = self._arg('font',args,'path')
 
437
        pythonpoint.registerFont0(self.sourceFilename, name, path)
 
438
 
 
439
 
 
440
    def end_registerFont(self):
 
441
        pass
 
442
 
 
443
 
 
444
    def pack_slide(self, element, args):
 
445
        if self.fx:
 
446
            effectName = self._arg(element,args,'effectname')
 
447
            if effectName <> 'None':
 
448
                curSlide = copy.deepcopy(self._curSlide)
 
449
                if self._curFrame:
 
450
                    curFrame = copy.deepcopy(self._curFrame)
 
451
                    curSlide.frames.append(curFrame)
 
452
                self._curPres.slides.append(curSlide)
 
453
                self._curSlide.effectName = effectName
 
454
                self._curSlide.effectDirection = self.ceval(element,args,'effectdirection')
 
455
                self._curSlide.effectDimension = self._arg(element,args,'effectdimension')
 
456
                self._curSlide.effectDuration = self.ceval(element,args,'effectduration')
 
457
                self._curSlide.effectMotion = self._arg(element,args,'effectmotion')
 
458
                self._curSlide.outlineEntry = None
 
459
 
 
460
    def start_para(self, args):
 
461
        self.pack_slide('para', args)
 
462
        self._curPara = pythonpoint.PPPara()
 
463
        self._curPara.style = self._arg('para',args,'style')
 
464
 
 
465
        # hack - bullet character if bullet style
 
466
        bt = self._arg('para',args,'bullettext')
 
467
        if bt == '':
 
468
            if self._curPara.style == 'Bullet':
 
469
                bt = '\267'  # Symbol Font bullet character, reasonable default
 
470
            elif self._curPara.style == 'Bullet2':
 
471
                bt = '\267'  # second-level bullet
 
472
            else:
 
473
                bt = None
 
474
 
 
475
        self._curPara.bulletText = bt
 
476
 
 
477
 
 
478
    def end_para(self):
 
479
        if self._curFrame:
 
480
            self._curFrame.content.append(self._curPara)
 
481
            self._curPara = None
 
482
        elif self._curNotes:
 
483
            self._curNotes.content.append(self._curPara)
 
484
            self._curPara = None
 
485
 
 
486
 
 
487
    def start_prefmt(self, args):
 
488
        self._curPrefmt = pythonpoint.PPPreformattedText()
 
489
        self._curPrefmt.style = self._arg('prefmt',args,'style')
 
490
 
 
491
 
 
492
    def end_prefmt(self):
 
493
        self._curFrame.content.append(self._curPrefmt)
 
494
        self._curPrefmt = None
 
495
 
 
496
 
 
497
    def start_pycode(self, args):
 
498
        self._curPyCode = pythonpoint.PPPythonCode()
 
499
        self._curPyCode.style = self._arg('pycode',args,'style')
 
500
 
 
501
 
 
502
    def end_pycode(self):
 
503
        self._curFrame.content.append(self._curPyCode)
 
504
        self._curPyCode = None
 
505
 
 
506
 
 
507
    def start_image(self, args):
 
508
        self.pack_slide('image',args)
 
509
        sourceFilename = self.sourceFilename # XXX
 
510
        filename = self._arg('image',args,'filename')
 
511
        filename = os.path.join(os.path.dirname(sourceFilename), filename)
 
512
        self._curImage = pythonpoint.PPImage()
 
513
        self._curImage.filename = filename
 
514
        self._curImage.width = self.ceval('image',args,'width')
 
515
        self._curImage.height = self.ceval('image',args,'height')
 
516
 
 
517
 
 
518
    def end_image(self):
 
519
        self._curFrame.content.append(self._curImage)
 
520
        self._curImage = None
 
521
 
 
522
 
 
523
    def start_table(self, args):
 
524
        self.pack_slide('table',args)
 
525
        self._curTable = pythonpoint.PPTable()
 
526
        self._curTable.widths = self.ceval('table',args,'widths')
 
527
        self._curTable.heights = self.ceval('table',args,'heights')
 
528
        #these may contain escapes like tabs - handle with
 
529
        #a bit more care.
 
530
        if args.has_key('fieldDelim'):
 
531
            self._curTable.fieldDelim = eval('"' + args['fieldDelim'] + '"')
 
532
        if args.has_key('rowDelim'):
 
533
            self._curTable.rowDelim = eval('"' + args['rowDelim'] + '"')
 
534
        if args.has_key('style'):
 
535
            self._curTable.style = args['style']
 
536
 
 
537
 
 
538
    def end_table(self):
 
539
        self._curFrame.content.append(self._curTable)
 
540
        self._curTable = None
 
541
 
 
542
 
 
543
    def start_spacer(self, args):
 
544
        """No contents so deal with it here."""
 
545
        sp = pythonpoint.PPSpacer()
 
546
        sp.height = eval(args['height'])
 
547
        self._curFrame.content.append(sp)
 
548
 
 
549
 
 
550
    def end_spacer(self):
 
551
        pass
 
552
 
 
553
 
 
554
    ## the graphics objects - go into either the current section
 
555
    ## or the current slide.
 
556
    def start_fixedimage(self, args):
 
557
        sourceFilename = self.sourceFilename
 
558
        filename = self._arg('image',args,'filename')
 
559
        filename = os.path.join(os.path.dirname(sourceFilename), filename)
 
560
        img = pythonpoint.PPFixedImage()
 
561
        img.filename = filename
 
562
        img.x = self.ceval('fixedimage',args,'x')
 
563
        img.y = self.ceval('fixedimage',args,'y')
 
564
        img.width = self.ceval('fixedimage',args,'width')
 
565
        img.height = self.ceval('fixedimage',args,'height')
 
566
        self._curFixedImage = img
 
567
 
 
568
 
 
569
    def end_fixedimage(self):
 
570
        if self._curSlide:
 
571
            self._curSlide.graphics.append(self._curFixedImage)
 
572
        elif self._curSection:
 
573
            self._curSection.graphics.append(self._curFixedImage)
 
574
        self._curFixedImage = None
 
575
 
 
576
 
 
577
    def start_rectangle(self, args):
 
578
        self.pack_slide('rectangle', args)
 
579
        rect = pythonpoint.PPRectangle(
 
580
                    self.ceval('rectangle',args,'x'),
 
581
                    self.ceval('rectangle',args,'y'),
 
582
                    self.ceval('rectangle',args,'width'),
 
583
                    self.ceval('rectangle',args,'height')
 
584
                    )
 
585
        rect.fillColor = self.ceval('rectangle',args,'fill')
 
586
        rect.strokeColor = self.ceval('rectangle',args,'stroke')
 
587
        self._curRectangle = rect
 
588
 
 
589
 
 
590
    def end_rectangle(self):
 
591
        if self._curSlide:
 
592
            self._curSlide.graphics.append(self._curRectangle)
 
593
        elif self._curSection:
 
594
            self._curSection.graphics.append(self._curRectangle)
 
595
        self._curRectangle = None
 
596
 
 
597
 
 
598
    def start_roundrect(self, args):
 
599
        self.pack_slide('roundrect', args)
 
600
        rrect = pythonpoint.PPRoundRect(
 
601
                    self.ceval('roundrect',args,'x'),
 
602
                    self.ceval('roundrect',args,'y'),
 
603
                    self.ceval('roundrect',args,'width'),
 
604
                    self.ceval('roundrect',args,'height'),
 
605
                    self.ceval('roundrect',args,'radius')
 
606
                    )
 
607
        rrect.fillColor = self.ceval('roundrect',args,'fill')
 
608
        rrect.strokeColor = self.ceval('roundrect',args,'stroke')
 
609
        self._curRoundRect = rrect
 
610
 
 
611
 
 
612
    def end_roundrect(self):
 
613
        if self._curSlide:
 
614
            self._curSlide.graphics.append(self._curRoundRect)
 
615
        elif self._curSection:
 
616
            self._curSection.graphics.append(self._curRoundRect)
 
617
        self._curRoundRect = None
 
618
 
 
619
 
 
620
    def start_line(self, args):
 
621
        self.pack_slide('line', args)
 
622
        self._curLine = pythonpoint.PPLine(
 
623
                    self.ceval('line',args,'x1'),
 
624
                    self.ceval('line',args,'y1'),
 
625
                    self.ceval('line',args,'x2'),
 
626
                    self.ceval('line',args,'y2')
 
627
                    )
 
628
        self._curLine.strokeColor = self.ceval('line',args,'stroke')
 
629
 
 
630
 
 
631
    def end_line(self):
 
632
        if self._curSlide:
 
633
            self._curSlide.graphics.append(self._curLine)
 
634
        elif self._curSection:
 
635
            self._curSection.graphics.append(self._curLine)
 
636
        self._curLine = None
 
637
 
 
638
 
 
639
    def start_ellipse(self, args):
 
640
        self.pack_slide('ellipse', args)
 
641
        self._curEllipse = pythonpoint.PPEllipse(
 
642
                    self.ceval('ellipse',args,'x1'),
 
643
                    self.ceval('ellipse',args,'y1'),
 
644
                    self.ceval('ellipse',args,'x2'),
 
645
                    self.ceval('ellipse',args,'y2')
 
646
                    )
 
647
        self._curEllipse.strokeColor = self.ceval('ellipse',args,'stroke')
 
648
        self._curEllipse.fillColor = self.ceval('ellipse',args,'fill')
 
649
 
 
650
 
 
651
    def end_ellipse(self):
 
652
        if self._curSlide:
 
653
            self._curSlide.graphics.append(self._curEllipse)
 
654
        elif self._curSection:
 
655
            self._curSection.graphics.append(self._curEllipse)
 
656
        self._curEllipse = None
 
657
 
 
658
 
 
659
    def start_polygon(self, args):
 
660
        self.pack_slide('polygon', args)
 
661
        self._curPolygon = pythonpoint.PPPolygon(self.ceval('polygon',args,'points'))
 
662
        self._curPolygon.strokeColor = self.ceval('polygon',args,'stroke')
 
663
        self._curPolygon.fillColor = self.ceval('polygon',args,'fill')
 
664
 
 
665
 
 
666
    def end_polygon(self):
 
667
        if self._curSlide:
 
668
            self._curSlide.graphics.append(self._curPolygon)
 
669
        elif self._curSection:
 
670
            self._curSection.graphics.append(self._curPolygon)
 
671
        self._curEllipse = None
 
672
 
 
673
 
 
674
    def start_string(self, args):
 
675
        self.pack_slide('string', args)
 
676
        self._curString = pythonpoint.PPString(
 
677
                            self.ceval('string',args,'x'),
 
678
                            self.ceval('string',args,'y')
 
679
                            )
 
680
        self._curString.color = self.ceval('string',args,'color')
 
681
        self._curString.font = self._arg('string',args,'font')
 
682
        self._curString.size = self.ceval('string',args,'size')
 
683
        if args['align'] == 'left':
 
684
            self._curString.align = TA_LEFT
 
685
        elif args['align'] == 'center':
 
686
            self._curString.align = TA_CENTER
 
687
        elif args['align'] == 'right':
 
688
            self._curString.align = TA_RIGHT
 
689
        elif args['align'] == 'justify':
 
690
            self._curString.align = TA_JUSTIFY
 
691
        #text comes later within the tag
 
692
 
 
693
 
 
694
    def end_string(self):
 
695
        #controller should have set the text
 
696
        if self._curSlide:
 
697
            self._curSlide.graphics.append(self._curString)
 
698
        elif self._curSection:
 
699
            self._curSection.graphics.append(self._curString)
 
700
        self._curString = None
 
701
 
 
702
 
 
703
    def start_infostring(self, args):
 
704
        # like a string, but lets them embed page no, author etc.
 
705
        self.start_string(args)
 
706
        self._curString.hasInfo = 1
 
707
 
 
708
 
 
709
    def end_infostring(self):
 
710
        self.end_string()
 
711
 
 
712
 
 
713
    def start_customshape(self, args):
 
714
        #loads one
 
715
        path = self._arg('customshape',args,'path')
 
716
        if path=='None':
 
717
            path = []
 
718
        else:
 
719
            path=[path]
 
720
 
 
721
        # add package root folder and input file's folder to path
 
722
        path.append(os.path.dirname(self.sourceFilename))
 
723
        path.append(os.path.dirname(pythonpoint.__file__))
 
724
 
 
725
        modulename = self._arg('customshape',args,'module')
 
726
        funcname = self._arg('customshape',args,'class')
 
727
        try:
 
728
            found = imp.find_module(modulename, path)
 
729
            (file, pathname, description) = found
 
730
            mod = imp.load_module(modulename, file, pathname, description)
 
731
        except ImportError:
 
732
            mod = getModule(modulename)
 
733
 
 
734
        #now get the function
 
735
 
 
736
        func = getattr(mod, funcname)
 
737
        initargs = self.ceval('customshape',args,'initargs')
 
738
        self._curCustomShape = apply(func, initargs)
 
739
 
 
740
 
 
741
    def end_customshape(self):
 
742
        if self._curSlide:
 
743
            self._curSlide.graphics.append(self._curCustomShape)
 
744
        elif self._curSection:
 
745
            self._curSection.graphics.append(self._curCustomShape)
 
746
        self._curCustomShape = None
 
747
 
 
748
 
 
749
 
 
750
    def start_drawing(self, args):
 
751
        #loads one
 
752
 
 
753
        moduleName = args["module"]
 
754
        funcName = args["constructor"]
 
755
 
 
756
        showBoundary = int(args.get("showBoundary", "0"))
 
757
 
 
758
        hAlign = args.get("hAlign", "CENTER")
 
759
 
 
760
 
 
761
        # the path for the imports should include:
 
762
        # 1. document directory
 
763
        # 2. python path if baseDir not given, or
 
764
        # 3. baseDir if given
 
765
        try:
 
766
            dirName = sdict["baseDir"]
 
767
        except:
 
768
            dirName = None
 
769
        importPath = [os.getcwd()]
 
770
        if dirName is None:
 
771
            importPath.extend(sys.path)
 
772
        else:
 
773
            importPath.insert(0, dirName)
 
774
 
 
775
        modul = recursiveImport(moduleName, baseDir=importPath)
 
776
        func = getattr(modul, funcName)
 
777
        drawing = func()
 
778
 
 
779
        drawing.hAlign = hAlign
 
780
        if showBoundary:
 
781
            drawing._showBoundary = 1
 
782
 
 
783
        self._curDrawing = pythonpoint.PPDrawing()
 
784
        self._curDrawing.drawing = drawing
 
785
 
 
786
 
 
787
    def end_drawing(self):
 
788
        self._curFrame.content.append(self._curDrawing)
 
789
        self._curDrawing = None
 
790
 
 
791
 
 
792
    def start_pageCatcherFigure(self, args):
 
793
        filename = args["filename"]
 
794
        pageNo = int(args["pageNo"])
 
795
        width = float(args.get("width", "595"))
 
796
        height = float(args.get("height", "842"))
 
797
        
 
798
 
 
799
        fig = figures.PageCatcherFigureNonA4(filename, pageNo, args.get("caption", ""), width, height)
 
800
        sf = args.get('scaleFactor', None)
 
801
        if sf: sf = float(sf)
 
802
        border = not (args.get('border', None) in ['0','no'])
 
803
        
 
804
        fig.scaleFactor = sf
 
805
        fig.border = border
 
806
 
 
807
        #self.ceval('pageCatcherFigure',args,'scaleFactor'),
 
808
        #initargs = self.ceval('customshape',args,'initargs')
 
809
        self._curFigure = pythonpoint.PPFigure()
 
810
        self._curFigure.figure = fig
 
811
 
 
812
 
 
813
 
 
814
    def end_pageCatcherFigure(self):
 
815
        self._curFrame.content.append(self._curFigure)
 
816
        self._curFigure = None
 
817
 
 
818
    ## intra-paragraph XML should be allowed through into PLATYPUS
 
819
    def unknown_starttag(self, tag, attrs):
 
820
        if  self._curPara:
 
821
            echo = '<%s' % tag
 
822
            for (key, value) in attrs.items():
 
823
                echo = echo + ' %s="%s"' % (key, value)
 
824
            echo = echo + '>'
 
825
            self._curPara.rawtext = self._curPara.rawtext + echo
 
826
        else:
 
827
            print 'Unknown start tag %s' % tag
 
828
 
 
829
 
 
830
    def unknown_endtag(self, tag):
 
831
        if  self._curPara:
 
832
            self._curPara.rawtext = self._curPara.rawtext + '</%s>'% tag
 
833
        else:
 
834
            print 'Unknown end tag %s' % tag