author | rptlab |
Tue, 30 Apr 2013 14:28:14 +0100 | |
branch | py33 |
changeset 3723 | 99aa837b6703 |
parent 3721 | 0c93dd8ff567 |
child 3793 | cc3f9cc828f7 |
permissions | -rw-r--r-- |
2963 | 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 |
|
3250 | 11 |
from reportlab.lib.utils import isSeqType |
2963 | 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 |
|
2966 | 16 |
from tools.pythonpoint import pythonpoint |
2963 | 17 |
from reportlab.platypus import figures |
18 |
||
19 |
||
2966 | 20 |
def getModule(modulename,fromPath='tools.pythonpoint.styles'): |
2963 | 21 |
"""Get a module containing style declarations. |
22 |
||
23 |
Search order is: |
|
2966 | 24 |
tools/pythonpoint/ |
25 |
tools/pythonpoint/styles/ |
|
2963 | 26 |
./ |
27 |
""" |
|
28 |
||
29 |
try: |
|
3721 | 30 |
exec('from tools.pythonpoint import '+modulename) |
2963 | 31 |
return eval(modulename) |
32 |
except ImportError: |
|
33 |
try: |
|
3721 | 34 |
exec('from tools.pythonpoint.styles import '+modulename) |
2963 | 35 |
return eval(modulename) |
36 |
except ImportError: |
|
3721 | 37 |
exec('import '+modulename) |
2963 | 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 |
def _arg(self,tag,args,name): |
|
216 |
"What's this for???" |
|
3326 | 217 |
if name in args: |
2963 | 218 |
v = args[name] |
219 |
else: |
|
3326 | 220 |
if tag in self.attributes: |
2963 | 221 |
v = self.attributes[tag][name] |
222 |
else: |
|
223 |
v = None |
|
224 |
return v |
|
225 |
||
226 |
def ceval(self,tag,args,name): |
|
3326 | 227 |
if name in args: |
2963 | 228 |
v = args[name] |
229 |
else: |
|
3326 | 230 |
if tag in self.attributes: |
2963 | 231 |
v = self.attributes[tag][name] |
232 |
else: |
|
233 |
return None |
|
234 |
||
235 |
# handle named colors (names from reportlab.lib.colors) |
|
236 |
if name in ('color', 'stroke', 'fill'): |
|
237 |
v = str(pythonpoint.checkColor(v)) |
|
238 |
||
239 |
return eval(v) |
|
240 |
||
241 |
def getPresentation(self): |
|
242 |
return self._curPres |
|
243 |
||
244 |
||
245 |
def handle_data(self, data): |
|
246 |
#the only data should be paragraph text, preformatted para |
|
247 |
#text, 'string text' for a fixed string on the page, |
|
248 |
#or table data |
|
249 |
if self._curPara: |
|
250 |
self._curPara.rawtext = self._curPara.rawtext + data |
|
251 |
elif self._curPrefmt: |
|
252 |
self._curPrefmt.rawtext = self._curPrefmt.rawtext + data |
|
253 |
elif self._curPyCode: |
|
254 |
self._curPyCode.rawtext = self._curPyCode.rawtext + data |
|
255 |
elif self._curString: |
|
256 |
self._curString.text = self._curString.text + data |
|
257 |
elif self._curTable: |
|
258 |
self._curTable.rawBlocks.append(data) |
|
3326 | 259 |
elif self._curTitle != None: # need to allow empty strings, |
2963 | 260 |
# hence explicitly testing for None |
261 |
self._curTitle = self._curTitle + data |
|
3326 | 262 |
elif self._curAuthor != None: |
2963 | 263 |
self._curAuthor = self._curAuthor + data |
3326 | 264 |
elif self._curSubject != None: |
2963 | 265 |
self._curSubject = self._curSubject + data |
266 |
||
267 |
def handle_cdata(self, data): |
|
268 |
#just append to current paragraph text, so we can quote XML |
|
269 |
if self._curPara: |
|
270 |
self._curPara.rawtext = self._curPara.rawtext + data |
|
271 |
elif self._curPrefmt: |
|
272 |
self._curPrefmt.rawtext = self._curPrefmt.rawtext + data |
|
273 |
elif self._curPyCode: |
|
274 |
self._curPyCode.rawtext = self._curPyCode.rawtext + data |
|
275 |
elif self._curString: |
|
276 |
self._curString.text = self._curString.text + data |
|
277 |
elif self._curTable: |
|
278 |
self._curTable.rawBlocks.append(data) |
|
3326 | 279 |
elif self._curAuthor != None: |
2963 | 280 |
self._curAuthor = self._curAuthor + data |
3326 | 281 |
elif self._curSubject != None: |
2963 | 282 |
self._curSubject = self._curSubject + data |
283 |
||
284 |
def start_presentation(self, args): |
|
285 |
self._curPres = pythonpoint.PPPresentation() |
|
286 |
self._curPres.filename = self._arg('presentation',args,'filename') |
|
287 |
self._curPres.effectName = self._arg('presentation',args,'effect') |
|
288 |
self._curPres.pageDuration = self._arg('presentation',args,'pageDuration') |
|
289 |
||
290 |
h = self._arg('presentation',args,'pageHeight') |
|
291 |
if h: |
|
292 |
self._curPres.pageHeight = h |
|
293 |
w = self._arg('presentation',args,'pageWidth') |
|
294 |
if w: |
|
295 |
self._curPres.pageWidth = w |
|
296 |
#print 'page size =', self._curPres.pageSize |
|
297 |
||
298 |
def end_presentation(self): |
|
299 |
pass |
|
300 |
## print 'Fully parsed presentation',self._curPres.filename |
|
301 |
||
302 |
def start_title(self, args): |
|
303 |
self._curTitle = '' |
|
304 |
||
305 |
||
306 |
def end_title(self): |
|
307 |
self._curPres.title = self._curTitle |
|
308 |
self._curTitle = None |
|
309 |
||
310 |
def start_author(self, args): |
|
311 |
self._curAuthor = '' |
|
312 |
||
313 |
def end_author(self): |
|
314 |
self._curPres.author = self._curAuthor |
|
315 |
self._curAuthor = None |
|
316 |
||
317 |
def start_subject(self, args): |
|
318 |
self._curSubject = '' |
|
319 |
||
320 |
def end_subject(self): |
|
321 |
self._curPres.subject = self._curSubject |
|
322 |
self._curSubject = None |
|
323 |
||
324 |
def start_stylesheet(self, args): |
|
325 |
#makes it the current style sheet. |
|
326 |
path = self._arg('stylesheet',args,'path') |
|
327 |
if path=='None': path = [] |
|
3250 | 328 |
if not isSeqType(path): path = [path] |
2963 | 329 |
path.append('styles') |
330 |
path.append(os.getcwd()) |
|
331 |
modulename = self._arg('stylesheet', args, 'module') |
|
332 |
funcname = self._arg('stylesheet', args, 'function') |
|
333 |
try: |
|
334 |
found = imp.find_module(modulename, path) |
|
335 |
(file, pathname, description) = found |
|
336 |
mod = imp.load_module(modulename, file, pathname, description) |
|
337 |
except ImportError: |
|
338 |
#last gasp |
|
339 |
mod = getModule(modulename) |
|
340 |
||
341 |
#now get the function |
|
342 |
func = getattr(mod, funcname) |
|
343 |
pythonpoint.setStyles(func()) |
|
344 |
## print 'set global stylesheet to %s.%s()' % (modulename, funcname) |
|
345 |
||
346 |
def end_stylesheet(self): |
|
347 |
pass |
|
348 |
||
349 |
def start_section(self, args): |
|
350 |
name = self._arg('section',args,'name') |
|
351 |
self._curSection = pythonpoint.PPSection(name) |
|
352 |
||
353 |
def end_section(self): |
|
354 |
self._curSection = None |
|
355 |
||
356 |
||
357 |
def start_slide(self, args): |
|
358 |
s = pythonpoint.PPSlide() |
|
359 |
s.id = self._arg('slide',args,'id') |
|
360 |
s.title = self._arg('slide',args,'title') |
|
361 |
a = self._arg('slide',args,'effectname') |
|
3326 | 362 |
if a != 'None': |
2963 | 363 |
s.effectName = a |
364 |
s.effectDirection = self.ceval('slide',args,'effectdirection') |
|
365 |
s.effectDimension = self._arg('slide',args,'effectdimension') |
|
366 |
s.effectDuration = self.ceval('slide',args,'effectduration') |
|
367 |
s.effectMotion = self._arg('slide',args,'effectmotion') |
|
368 |
||
369 |
#HACK - may not belong here in the long run... |
|
370 |
#by default, use the slide title for the outline entry, |
|
371 |
#unless it is specified as an arg. |
|
372 |
a = self._arg('slide',args,'outlineentry') |
|
373 |
if a == "Hide": |
|
374 |
s.outlineEntry = None |
|
3326 | 375 |
elif a != 'None': |
2963 | 376 |
s.outlineEntry = a |
377 |
else: |
|
378 |
s.outlineEntry = s.title |
|
379 |
||
380 |
s.outlineLevel = self.ceval('slide',args,'outlinelevel') |
|
381 |
||
382 |
#let it know its section, which may be none |
|
383 |
s.section = self._curSection |
|
384 |
self._curSlide = s |
|
385 |
||
386 |
def end_slide(self): |
|
387 |
self._curPres.slides.append(self._curSlide) |
|
388 |
self._curSlide = None |
|
389 |
||
390 |
def start_frame(self, args): |
|
391 |
self._curFrame = pythonpoint.PPFrame( |
|
392 |
self.ceval('frame',args,'x'), |
|
393 |
self.ceval('frame',args,'y'), |
|
394 |
self.ceval('frame',args,'width'), |
|
395 |
self.ceval('frame',args,'height') |
|
396 |
) |
|
397 |
if self._arg('frame',args,'border')=='true': |
|
398 |
self._curFrame.showBoundary = 1 |
|
399 |
||
400 |
def end_frame(self): |
|
401 |
self._curSlide.frames.append(self._curFrame) |
|
402 |
self._curFrame = None |
|
403 |
||
404 |
def start_notes(self, args): |
|
405 |
name = self._arg('notes',args,'name') |
|
406 |
self._curNotes = pythonpoint.PPNotes() |
|
407 |
||
408 |
def end_notes(self): |
|
409 |
self._curSlide.notes.append(self._curNotes) |
|
410 |
self._curNotes = None |
|
411 |
||
412 |
def start_registerFont(self, args): |
|
413 |
name = self._arg('font',args,'name') |
|
414 |
path = self._arg('font',args,'path') |
|
415 |
pythonpoint.registerFont0(self.sourceFilename, name, path) |
|
416 |
||
417 |
||
418 |
def end_registerFont(self): |
|
419 |
pass |
|
420 |
||
421 |
||
422 |
def pack_slide(self, element, args): |
|
423 |
if self.fx: |
|
424 |
effectName = self._arg(element,args,'effectname') |
|
3326 | 425 |
if effectName != 'None': |
2963 | 426 |
curSlide = copy.deepcopy(self._curSlide) |
427 |
if self._curFrame: |
|
428 |
curFrame = copy.deepcopy(self._curFrame) |
|
429 |
curSlide.frames.append(curFrame) |
|
430 |
self._curPres.slides.append(curSlide) |
|
431 |
self._curSlide.effectName = effectName |
|
432 |
self._curSlide.effectDirection = self.ceval(element,args,'effectdirection') |
|
433 |
self._curSlide.effectDimension = self._arg(element,args,'effectdimension') |
|
434 |
self._curSlide.effectDuration = self.ceval(element,args,'effectduration') |
|
435 |
self._curSlide.effectMotion = self._arg(element,args,'effectmotion') |
|
436 |
self._curSlide.outlineEntry = None |
|
437 |
||
438 |
def start_para(self, args): |
|
439 |
self.pack_slide('para', args) |
|
440 |
self._curPara = pythonpoint.PPPara() |
|
441 |
self._curPara.style = self._arg('para',args,'style') |
|
442 |
||
443 |
# hack - bullet character if bullet style |
|
444 |
bt = self._arg('para',args,'bullettext') |
|
445 |
if bt == '': |
|
446 |
if self._curPara.style == 'Bullet': |
|
447 |
bt = '\xe2\x80\xa2' # Symbol Font bullet character, reasonable default |
|
448 |
elif self._curPara.style == 'Bullet2': |
|
449 |
bt = '\xe2\x80\xa2' # second-level bullet |
|
450 |
else: |
|
451 |
bt = None |
|
452 |
||
453 |
self._curPara.bulletText = bt |
|
454 |
||
455 |
def end_para(self): |
|
456 |
if self._curFrame: |
|
457 |
self._curFrame.content.append(self._curPara) |
|
458 |
self._curPara = None |
|
459 |
elif self._curNotes: |
|
460 |
self._curNotes.content.append(self._curPara) |
|
461 |
self._curPara = None |
|
462 |
||
463 |
||
464 |
def start_prefmt(self, args): |
|
465 |
self._curPrefmt = pythonpoint.PPPreformattedText() |
|
466 |
self._curPrefmt.style = self._arg('prefmt',args,'style') |
|
467 |
||
468 |
||
469 |
def end_prefmt(self): |
|
470 |
self._curFrame.content.append(self._curPrefmt) |
|
471 |
self._curPrefmt = None |
|
472 |
||
473 |
||
474 |
def start_pycode(self, args): |
|
475 |
self._curPyCode = pythonpoint.PPPythonCode() |
|
476 |
self._curPyCode.style = self._arg('pycode',args,'style') |
|
477 |
||
478 |
||
479 |
def end_pycode(self): |
|
480 |
self._curFrame.content.append(self._curPyCode) |
|
481 |
self._curPyCode = None |
|
482 |
||
483 |
||
484 |
def start_image(self, args): |
|
485 |
self.pack_slide('image',args) |
|
486 |
sourceFilename = self.sourceFilename # XXX |
|
487 |
filename = self._arg('image',args,'filename') |
|
488 |
filename = os.path.join(os.path.dirname(sourceFilename), filename) |
|
489 |
self._curImage = pythonpoint.PPImage() |
|
490 |
self._curImage.filename = filename |
|
491 |
self._curImage.width = self.ceval('image',args,'width') |
|
492 |
self._curImage.height = self.ceval('image',args,'height') |
|
493 |
||
494 |
||
495 |
def end_image(self): |
|
496 |
self._curFrame.content.append(self._curImage) |
|
497 |
self._curImage = None |
|
498 |
||
499 |
||
500 |
def start_table(self, args): |
|
501 |
self.pack_slide('table',args) |
|
502 |
self._curTable = pythonpoint.PPTable() |
|
503 |
self._curTable.widths = self.ceval('table',args,'widths') |
|
504 |
self._curTable.heights = self.ceval('table',args,'heights') |
|
505 |
#these may contain escapes like tabs - handle with |
|
506 |
#a bit more care. |
|
3326 | 507 |
if 'fieldDelim' in args: |
2963 | 508 |
self._curTable.fieldDelim = eval('"' + args['fieldDelim'] + '"') |
3326 | 509 |
if 'rowDelim' in args: |
2963 | 510 |
self._curTable.rowDelim = eval('"' + args['rowDelim'] + '"') |
3326 | 511 |
if 'style' in args: |
2963 | 512 |
self._curTable.style = args['style'] |
513 |
||
514 |
||
515 |
def end_table(self): |
|
516 |
self._curFrame.content.append(self._curTable) |
|
517 |
self._curTable = None |
|
518 |
||
519 |
||
520 |
def start_spacer(self, args): |
|
521 |
"""No contents so deal with it here.""" |
|
522 |
sp = pythonpoint.PPSpacer() |
|
523 |
sp.height = eval(args['height']) |
|
524 |
self._curFrame.content.append(sp) |
|
525 |
||
526 |
||
527 |
def end_spacer(self): |
|
528 |
pass |
|
529 |
||
530 |
||
531 |
## the graphics objects - go into either the current section |
|
532 |
## or the current slide. |
|
533 |
def start_fixedimage(self, args): |
|
534 |
sourceFilename = self.sourceFilename |
|
535 |
filename = self._arg('image',args,'filename') |
|
536 |
filename = os.path.join(os.path.dirname(sourceFilename), filename) |
|
537 |
img = pythonpoint.PPFixedImage() |
|
538 |
img.filename = filename |
|
539 |
img.x = self.ceval('fixedimage',args,'x') |
|
540 |
img.y = self.ceval('fixedimage',args,'y') |
|
541 |
img.width = self.ceval('fixedimage',args,'width') |
|
542 |
img.height = self.ceval('fixedimage',args,'height') |
|
543 |
self._curFixedImage = img |
|
544 |
||
545 |
||
546 |
def end_fixedimage(self): |
|
547 |
if self._curSlide: |
|
548 |
self._curSlide.graphics.append(self._curFixedImage) |
|
549 |
elif self._curSection: |
|
550 |
self._curSection.graphics.append(self._curFixedImage) |
|
551 |
self._curFixedImage = None |
|
552 |
||
553 |
||
554 |
def start_rectangle(self, args): |
|
555 |
self.pack_slide('rectangle', args) |
|
556 |
rect = pythonpoint.PPRectangle( |
|
557 |
self.ceval('rectangle',args,'x'), |
|
558 |
self.ceval('rectangle',args,'y'), |
|
559 |
self.ceval('rectangle',args,'width'), |
|
560 |
self.ceval('rectangle',args,'height') |
|
561 |
) |
|
562 |
rect.fillColor = self.ceval('rectangle',args,'fill') |
|
563 |
rect.strokeColor = self.ceval('rectangle',args,'stroke') |
|
564 |
self._curRectangle = rect |
|
565 |
||
566 |
||
567 |
def end_rectangle(self): |
|
568 |
if self._curSlide: |
|
569 |
self._curSlide.graphics.append(self._curRectangle) |
|
570 |
elif self._curSection: |
|
571 |
self._curSection.graphics.append(self._curRectangle) |
|
572 |
self._curRectangle = None |
|
573 |
||
574 |
||
575 |
def start_roundrect(self, args): |
|
576 |
self.pack_slide('roundrect', args) |
|
577 |
rrect = pythonpoint.PPRoundRect( |
|
578 |
self.ceval('roundrect',args,'x'), |
|
579 |
self.ceval('roundrect',args,'y'), |
|
580 |
self.ceval('roundrect',args,'width'), |
|
581 |
self.ceval('roundrect',args,'height'), |
|
582 |
self.ceval('roundrect',args,'radius') |
|
583 |
) |
|
584 |
rrect.fillColor = self.ceval('roundrect',args,'fill') |
|
585 |
rrect.strokeColor = self.ceval('roundrect',args,'stroke') |
|
586 |
self._curRoundRect = rrect |
|
587 |
||
588 |
||
589 |
def end_roundrect(self): |
|
590 |
if self._curSlide: |
|
591 |
self._curSlide.graphics.append(self._curRoundRect) |
|
592 |
elif self._curSection: |
|
593 |
self._curSection.graphics.append(self._curRoundRect) |
|
594 |
self._curRoundRect = None |
|
595 |
||
596 |
||
597 |
def start_line(self, args): |
|
598 |
self.pack_slide('line', args) |
|
599 |
self._curLine = pythonpoint.PPLine( |
|
600 |
self.ceval('line',args,'x1'), |
|
601 |
self.ceval('line',args,'y1'), |
|
602 |
self.ceval('line',args,'x2'), |
|
603 |
self.ceval('line',args,'y2') |
|
604 |
) |
|
605 |
self._curLine.strokeColor = self.ceval('line',args,'stroke') |
|
606 |
||
607 |
||
608 |
def end_line(self): |
|
609 |
if self._curSlide: |
|
610 |
self._curSlide.graphics.append(self._curLine) |
|
611 |
elif self._curSection: |
|
612 |
self._curSection.graphics.append(self._curLine) |
|
613 |
self._curLine = None |
|
614 |
||
615 |
||
616 |
def start_ellipse(self, args): |
|
617 |
self.pack_slide('ellipse', args) |
|
618 |
self._curEllipse = pythonpoint.PPEllipse( |
|
619 |
self.ceval('ellipse',args,'x1'), |
|
620 |
self.ceval('ellipse',args,'y1'), |
|
621 |
self.ceval('ellipse',args,'x2'), |
|
622 |
self.ceval('ellipse',args,'y2') |
|
623 |
) |
|
624 |
self._curEllipse.strokeColor = self.ceval('ellipse',args,'stroke') |
|
625 |
self._curEllipse.fillColor = self.ceval('ellipse',args,'fill') |
|
626 |
||
627 |
||
628 |
def end_ellipse(self): |
|
629 |
if self._curSlide: |
|
630 |
self._curSlide.graphics.append(self._curEllipse) |
|
631 |
elif self._curSection: |
|
632 |
self._curSection.graphics.append(self._curEllipse) |
|
633 |
self._curEllipse = None |
|
634 |
||
635 |
||
636 |
def start_polygon(self, args): |
|
637 |
self.pack_slide('polygon', args) |
|
638 |
self._curPolygon = pythonpoint.PPPolygon(self.ceval('polygon',args,'points')) |
|
639 |
self._curPolygon.strokeColor = self.ceval('polygon',args,'stroke') |
|
640 |
self._curPolygon.fillColor = self.ceval('polygon',args,'fill') |
|
641 |
||
642 |
||
643 |
def end_polygon(self): |
|
644 |
if self._curSlide: |
|
645 |
self._curSlide.graphics.append(self._curPolygon) |
|
646 |
elif self._curSection: |
|
647 |
self._curSection.graphics.append(self._curPolygon) |
|
648 |
self._curEllipse = None |
|
649 |
||
650 |
||
651 |
def start_string(self, args): |
|
652 |
self.pack_slide('string', args) |
|
653 |
self._curString = pythonpoint.PPString( |
|
654 |
self.ceval('string',args,'x'), |
|
655 |
self.ceval('string',args,'y') |
|
656 |
) |
|
657 |
self._curString.color = self.ceval('string',args,'color') |
|
658 |
self._curString.font = self._arg('string',args,'font') |
|
659 |
self._curString.size = self.ceval('string',args,'size') |
|
660 |
if args['align'] == 'left': |
|
661 |
self._curString.align = TA_LEFT |
|
662 |
elif args['align'] == 'center': |
|
663 |
self._curString.align = TA_CENTER |
|
664 |
elif args['align'] == 'right': |
|
665 |
self._curString.align = TA_RIGHT |
|
666 |
elif args['align'] == 'justify': |
|
667 |
self._curString.align = TA_JUSTIFY |
|
668 |
#text comes later within the tag |
|
669 |
||
670 |
||
671 |
def end_string(self): |
|
672 |
#controller should have set the text |
|
673 |
if self._curSlide: |
|
674 |
self._curSlide.graphics.append(self._curString) |
|
675 |
elif self._curSection: |
|
676 |
self._curSection.graphics.append(self._curString) |
|
677 |
self._curString = None |
|
678 |
||
679 |
||
680 |
def start_infostring(self, args): |
|
681 |
# like a string, but lets them embed page no, author etc. |
|
682 |
self.start_string(args) |
|
683 |
self._curString.hasInfo = 1 |
|
684 |
||
685 |
||
686 |
def end_infostring(self): |
|
687 |
self.end_string() |
|
688 |
||
689 |
||
690 |
def start_customshape(self, args): |
|
691 |
#loads one |
|
692 |
path = self._arg('customshape',args,'path') |
|
693 |
if path=='None': |
|
694 |
path = [] |
|
695 |
else: |
|
696 |
path=[path] |
|
697 |
||
698 |
# add package root folder and input file's folder to path |
|
699 |
path.append(os.path.dirname(self.sourceFilename)) |
|
700 |
path.append(os.path.dirname(pythonpoint.__file__)) |
|
701 |
||
702 |
modulename = self._arg('customshape',args,'module') |
|
703 |
funcname = self._arg('customshape',args,'class') |
|
704 |
try: |
|
705 |
found = imp.find_module(modulename, path) |
|
706 |
(file, pathname, description) = found |
|
707 |
mod = imp.load_module(modulename, file, pathname, description) |
|
708 |
except ImportError: |
|
709 |
mod = getModule(modulename) |
|
710 |
||
711 |
#now get the function |
|
712 |
||
713 |
func = getattr(mod, funcname) |
|
714 |
initargs = self.ceval('customshape',args,'initargs') |
|
3326 | 715 |
self._curCustomShape = func(*initargs) |
2963 | 716 |
|
717 |
def end_customshape(self): |
|
718 |
if self._curSlide: |
|
719 |
self._curSlide.graphics.append(self._curCustomShape) |
|
720 |
elif self._curSection: |
|
721 |
self._curSection.graphics.append(self._curCustomShape) |
|
722 |
self._curCustomShape = None |
|
723 |
||
724 |
def start_drawing(self, args): |
|
725 |
#loads one |
|
726 |
moduleName = args["module"] |
|
727 |
funcName = args["constructor"] |
|
728 |
showBoundary = int(args.get("showBoundary", "0")) |
|
729 |
hAlign = args.get("hAlign", "CENTER") |
|
730 |
||
731 |
||
732 |
# the path for the imports should include: |
|
733 |
# 1. document directory |
|
734 |
# 2. python path if baseDir not given, or |
|
735 |
# 3. baseDir if given |
|
736 |
try: |
|
737 |
dirName = sdict["baseDir"] |
|
738 |
except: |
|
739 |
dirName = None |
|
740 |
importPath = [os.getcwd()] |
|
741 |
if dirName is None: |
|
742 |
importPath.extend(sys.path) |
|
743 |
else: |
|
744 |
importPath.insert(0, dirName) |
|
745 |
||
746 |
modul = recursiveImport(moduleName, baseDir=importPath) |
|
747 |
func = getattr(modul, funcName) |
|
748 |
drawing = func() |
|
749 |
||
750 |
drawing.hAlign = hAlign |
|
751 |
if showBoundary: |
|
752 |
drawing._showBoundary = 1 |
|
753 |
||
754 |
self._curDrawing = pythonpoint.PPDrawing() |
|
755 |
self._curDrawing.drawing = drawing |
|
756 |
||
757 |
def end_drawing(self): |
|
758 |
self._curFrame.content.append(self._curDrawing) |
|
759 |
self._curDrawing = None |
|
760 |
||
761 |
def start_pageCatcherFigure(self, args): |
|
762 |
filename = args["filename"] |
|
763 |
pageNo = int(args["pageNo"]) |
|
764 |
width = float(args.get("width", "595")) |
|
765 |
height = float(args.get("height", "842")) |
|
766 |
||
767 |
||
768 |
fig = figures.PageCatcherFigureNonA4(filename, pageNo, args.get("caption", ""), width, height) |
|
769 |
sf = args.get('scaleFactor', None) |
|
770 |
if sf: sf = float(sf) |
|
771 |
border = not (args.get('border', None) in ['0','no']) |
|
772 |
||
773 |
fig.scaleFactor = sf |
|
774 |
fig.border = border |
|
775 |
||
776 |
#self.ceval('pageCatcherFigure',args,'scaleFactor'), |
|
777 |
#initargs = self.ceval('customshape',args,'initargs') |
|
778 |
self._curFigure = pythonpoint.PPFigure() |
|
779 |
self._curFigure.figure = fig |
|
780 |
||
781 |
def end_pageCatcherFigure(self): |
|
782 |
self._curFrame.content.append(self._curFigure) |
|
783 |
self._curFigure = None |
|
784 |
||
785 |
## intra-paragraph XML should be allowed through into PLATYPUS |
|
786 |
def unknown_starttag(self, tag, attrs): |
|
787 |
if self._curPara: |
|
788 |
echo = '<%s' % tag |
|
3723
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset
|
789 |
for key, value in attrs.items(): |
2963 | 790 |
echo = echo + ' %s="%s"' % (key, value) |
791 |
echo = echo + '>' |
|
792 |
self._curPara.rawtext = self._curPara.rawtext + echo |
|
793 |
else: |
|
3721 | 794 |
print('Unknown start tag %s' % tag) |
2963 | 795 |
|
796 |
||
797 |
def unknown_endtag(self, tag): |
|
798 |
if self._curPara: |
|
799 |
self._curPara.rawtext = self._curPara.rawtext + '</%s>'% tag |
|
800 |
else: |
|
3721 | 801 |
print('Unknown end tag %s' % tag) |
2963 | 802 |
|
803 |
def handle_charref(self, name): |
|
804 |
try: |
|
805 |
if name[0]=='x': |
|
806 |
n = int(name[1:],16) |
|
807 |
else: |
|
808 |
n = int(name) |
|
809 |
except ValueError: |
|
810 |
self.unknown_charref(name) |
|
811 |
return |
|
3721 | 812 |
self.handle_data(chr(n).encode('utf8')) |