Attachment 'text_pdf.py'
Download 1 # -*- coding: iso-8859-1 -*-
2 """
3 MoinMoin - "text/pdf" Formatter
4
5 Copyright (c) 2005 by OR Soft GmbH, based on other formatters (c) by Jürgen Hermann <jh@web.de>
6 All rights reserved, see COPYING for details.
7
8 ORS modifications:
9 14.09.05 RS derived from text_html and text_word
10 27.09.05 RS upgrade to 1.3.5, old code removed
11 """
12
13 # Imports
14 import cgi, string, sys, time, os, copy, traceback
15 from MoinMoin.formatter.base import FormatterBase
16 from MoinMoin import wikiutil, config, user, webapi, i18n
17
18 from MoinMoin.Page import Page
19 #ABP REPORTLAB
20 from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Frame, Image
21 from reportlab.lib.units import inch, cm
22 from reportlab.lib.pagesizes import A4
23 from reportlab.lib.styles import getSampleStyleSheet
24 from reportlab.lib.colors import Color
25 from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY
26 from reportlab.lib.sequencer import Sequencer
27 from reportlab.lib.utils import ImageReader
28 from reportlab.pdfgen.canvas import Canvas
29
30
31 #from reportlab.rl_config import defaultPageSize
32 #ABP end
33
34 DOC_SUFFIX = ".pdf" # perhaps put this in config.py as pdf_suffix?
35
36 #############################################################################
37 ### PDF Formatter
38 #############################################################################
39
40 _debug=1
41
42
43 class Formatter(FormatterBase):
44 """
45 Send HTML data.
46 """
47
48 hardspace = ' '
49 hardspace = ' '
50
51
52
53 def __init__(self, request, **kw):
54 if _debug:
55 traceback.print_stack(limit=1,file=sys.stdout)
56 apply(FormatterBase.__init__, (self, request), kw)
57 #RS additional property "mimetype"
58 self.mimetype="text/pdf"
59 sys.stderr.write("\nThis is the PDF Formatter....\n")
60 #RS end
61 self.dead=0
62 self.store_text=0 # store text in self._text instead of emitting it
63 self.recordedtext=""
64 self.recordedcursor=0
65 # inline tags stack. When an inline tag is called, it goes into
66 # the stack. When a block element starts, all inline tags in
67 # the stack are closed.
68 self._inlineStack = []
69
70 self._in_li = 0
71 self._first_li = 0
72 self._first_tr = 0
73 self._first_td = 0
74 self._table_start=0
75 self._ignore_next_paragraph=0
76 self.list_levels={'ul':0,'ol':0,'dl':0,'table':0,'all':0}
77 self.last_indent_type=''
78 self._in_code = 0
79 self._base_depth = 0
80 self._in_code_area = 0
81 self._in_code_line = 0
82 self._code_area_num = 0
83 self._code_area_js = 0
84 self._code_area_state = ['', 0, -1, -1, 0]
85 self._show_section_numbers = None
86 self._content_ids = []
87 self.pagelink_preclosed = False
88 self._is_included = kw.get('is_included',False)
89 self.request = request
90 self.cfg = request.cfg
91 # self.targetdir=kw.get('targetdir',config.data_dir)
92 self.targetdir=kw.get('targetdir',request.cfg.data_dir)
93
94 # pdf style-definitions
95 self.styles= getSampleStyleSheet()
96 self.styleTitle= copy.deepcopy(self.styles['Title'])
97 self.styleH1= copy.deepcopy(self.styles['Heading1'])
98 self.styleH1.fontSize= 18
99 self.styleH1.spaceBefore= 12 #is ignored at the top of a frame
100 self.styleH1.spaceAfter= 7 #is ignored at the bottom of a frame
101 self.styleH1.leading= 22 #is the spacing between adjacent lines of text
102 self.styleH2= copy.deepcopy(self.styles['Heading2'])
103 self.styleH2.fontSize= 16
104 self.styleH2.spaceBefore= 12
105 self.styleH2.spaceAfter= 7
106 self.styleH2.leading= 20
107 self.styleH3= copy.deepcopy(self.styles['Heading3'])
108 self.styleH3.fontSize= 14
109 self.styleH3.spaceBefore= 12
110 self.styleH3.spaceAfter= 7
111 self.styleH3.leading= 18
112 self.styleH4= copy.deepcopy(self.styles['Heading3'])
113 self.styleH4.fontName= "Times-BoldItalic"
114 self.styleH4.fontSize= 12
115 self.styleH4.spaceBefore= 12
116 self.styleH4.spaceAfter= 7
117 self.styleH4.leading= 16
118 self.styleH5= copy.deepcopy(self.styles['Heading3'])
119 self.styleH5.fontName= "Times-Italic"
120 self.styleH5.fontSize= 12
121 self.styleH5.spaceBefore= 12
122 self.styleH5.spaceAfter= 7
123 self.styleH5.leading= 14
124 self.standardstyle= copy.deepcopy(self.styles['Normal'])
125 self.standardstyle.spaceBefore= 6
126 self.standardstyle.spaceAfter= 6
127 self.standardstyle.leading= 13
128 self.styleCode= copy.deepcopy(self.styles['Code'])
129 self.styleBullet= copy.deepcopy(self.styles['Bullet'])
130 self.styleBullet.spaceBefore= 6
131 self.styleBullet.spaceAfter= 6
132 self.styleBullet.leading= 13
133 self.styleBullet.bulletFontName= "Symbol"
134 self.styleBullet.leftIndent= 14
135 self.styleBullet.bulletIndent= 4
136 self.styleBullet.firstLineIndent= 0
137 self.styleItalic= copy.deepcopy(self.styles['Italic'])
138 self.styleDefinition= copy.deepcopy(self.styles['Definition'])
139 self.currentstyle= copy.deepcopy(self.standardstyle)
140
141 self.story= []
142 self.para_story= ""
143 self.title= ''
144 self.bulletText= None
145 self.seq= Sequencer()
146 self.OLnumber= ""
147 self.oltype= None
148 self.olstart= None
149 self.nobullet= 0
150 self.li_marker= []
151 self.p_marker= None
152 self.styleStack= Privatestack()
153 self.bulletStack= Privatestack()
154 self.indenttypeStack= Privatestack()
155 self.oltypeStack= Privatestack()
156 self.p_markerStack= Privatestack()
157
158 if not hasattr(request, '_fmt_hd_counters'):
159 request._fmt_hd_counters = []
160 self.document=None
161 self.pdf_host= None
162 self.doc= None
163 self.doccount=0
164 self.tt_start=0
165 self.PAGE_HEIGHT= A4[1]
166 self.PAGE_WIDTH= A4[0]
167
168 # not by SimpleDocTemplate self.f = Frame(inch, inch, 6*inch, 9*inch, showBoundary=1)
169
170 def _reset_indents(self):
171 if _debug:
172 traceback.print_stack(limit=1,file=sys.stdout)
173 self._in_li = 0
174 self._first_li = 0
175 self._first_tr = 0
176 self._first_td = 0
177 self._table_start=0
178 self._ignore_next_paragraph=0
179 self.list_levels={'ul':0,'ol':0,'dl':0,'table':0,'all':0}
180 self.last_indent_type=''
181 def FatalEnd(self):
182 """
183 make sure we do not leave any ActiveX corpses behind if errors occur
184 """
185 if _debug:
186 traceback.print_stack(limit=1,file=sys.stdout)
187 try:
188 if self.document is not None:
189 # pass
190 #TODO
191 ## self.pdf_host.drawText(self.document)
192 ## self.pdf_host.showPage()
193 ## self.pdf_host.save()
194 # self.document.Close(-1)
195 # if self.pdf_host is not None:
196 # self.pdf_host.Quit()
197 self.pdf_host.save()
198
199 self.document=None
200 self.pdf_host=None
201 except:
202 pass
203 # raise
204 self.dead=1
205
206 def _save(self):
207 #RS fatal error handling
208 if self.dead==1:
209 return
210 #RS end
211 if self.document!=None:
212 pass
213 #not doctemplate based
214 ## self.pdf_host.save()
215
216 # Primitive formatter functions #####################################
217
218 # all other methods should use these to format tags. This keeps the
219 # code clean and handle pathological cases like unclosed p and
220 # inline tags.
221
222 def langAttr(self, lang=None):
223 """ Return lang and dir attribute
224
225 Must be used on all block elements - div, p, table, etc.
226 @param lang: if defined, will return attributes for lang. if not
227 defined, will return attributes only if the current lang is
228 different from the content lang.
229 @rtype: dict
230 @retrun: language attributes
231 """
232 if not lang:
233 lang = self.request.current_lang
234 # Actions that generate content in user language should change
235 # the content lang from the default defined in cfg.
236 if lang == self.request.content_lang:
237 # lang is inherited from content div
238 return {}
239
240 attr = {'lang': lang, 'dir': i18n.getDirection(lang),}
241 return attr
242
243 def formatAttributes(self, attr=None):
244 """ Return formatted attributes string
245
246 @param attr: dict containing keys and values
247 @rtype: string ?
248 @return: formated attributes or empty string
249 """
250 if attr:
251 attr = [' %s="%s"' % (k, v) for k, v in attr.items()]
252 return ''.join(attr)
253 return ''
254
255 # TODO: use set when we require Python 2.3
256 # TODO: The list is not complete, add missing from dtd
257 #RS Word: use _blocks for all tags that can only be interpreted on close, i.e. text between open and close must be recorded
258 ## _blocks = 'p div pre table tr td ol ul dl li dt dd h1 h2 h3 h4 h5 h6 hr form'
259 _blocks = 'div pre table tr td ol ul dl li dt dd h1 h2 h3 h4 h5 h6 hr form pagelink'
260 _blocks = 'div pre dt dd h1 h2 h3 h4 h5 h6 form url pagelink'
261 _blocks= 'h1 h2 h3 h4 h5'
262 #RS end
263 _blocks = dict(zip(_blocks.split(), [1] * len(_blocks)))
264
265
266 def open(self, tag, newline=False, attr=None):
267 """ Open a tag with optional attributes
268
269 @param tag: html tag, string
270 @param newline: render tag on a separate line
271 @parm attr: dict with tag attributes
272 @rtype: string ?
273 @return: open tag with attributes
274 """
275 # if _debug:
276 # traceback.print_stack(limit=1,file=sys.stdout)
277 if tag in self._blocks:
278 # Block elements
279 #RS word
280 if _debug:
281 print "OPEN %s (recording)" % tag
282 self.store_text=1
283 self.recordedtext=""
284 #TODO
285 # if self.word_host:
286 # self.recordedcursor=int(self.word_host.Selection.Range.End)
287
288 #RS end
289 result = []
290
291 # Add language attributes, but let caller overide the default
292 attributes = self.langAttr()
293 if attr:
294 attributes.update(attr)
295
296 # Format
297 attributes = self.formatAttributes(attributes)
298 result.append('<%s%s>' % (tag, attributes))
299 if newline:
300 if _debug:
301 print "OPEN with NEWLINE"
302 #TODO
303 # if self.document:
304 # self.word_host.Selection.TypeParagraph()
305
306 result.append('\n')
307 return ''.join(result)
308 else:
309 # Inline elements
310 # Add to inlineStack
311 if _debug:
312 print "OPEN %s (inline)" % tag
313 self._inlineStack.append(tag)
314
315 self.para_story += '<%s>' % tag
316 # Format
317 return '<%s%s>' % (tag, self.formatAttributes(attr))
318
319 def close(self, tag, newline=False):
320 """ Close tag
321
322 @param tag: html tag, string
323 @rtype: string ?
324 @return: closing tag
325 """
326 # if _debug:
327 # traceback.print_stack(limit=1,file=sys.stdout)
328 if tag in self._blocks:
329 # Block elements
330 # Close all tags in inline stack
331 # Work on a copy, because close(inline) manipulate the stack
332 #RS word
333 if _debug:
334 try:
335 print 'CLOSE %s (recorded="%s")' % (tag,self.recordedtext)
336 except:
337 print 'CLOSE %s (recorded=???)' % (tag)
338 self.store_text=0
339 self.recordedtext=""
340 # self.recordedcursor=0
341 #RS end
342 result = []
343 stack = self._inlineStack[:]
344 stack.reverse()
345 for inline in stack:
346 result.append(self.close(inline))
347 # Format with newline
348 if newline:
349 if _debug:
350 print "CLOSE with NEWLINE"
351 result.append('\n')
352 result.append('</%s>\n' % (tag))
353 return ''.join(result)
354 else:
355 # Inline elements
356 # Pull from stack, ignore order, that is not our problem.
357 # The code that calls us should keep correct calling order.
358 if _debug:
359 print "CLOSE %s (inline)" % tag
360 if tag in self._inlineStack:
361 if _debug:
362 print "CLOSE %s (inline stack remove)" % tag
363 self._inlineStack.remove(tag)
364 ###bulletlistentag nicht in die para_story
365 ## if tag == 'ul':
366 ## pass
367 ## else:
368 ## self.para_story += "</%s>" % tag
369 self.para_story += "</%s>" % tag
370 return '</%s>' % tag
371
372
373 def startDocument(self, pagename):
374 if _debug:
375 traceback.print_stack(limit=1,file=sys.stdout)
376 sys.stderr.write("\nThis is the PDF Formatter::startDocument....")
377 self.doccount+=1
378 self.title= self.request.getPragma('title', pagename)
379
380 if self.pdf_host==None:
381
382 try:
383 file = wikiutil.quoteWikinameFS(pagename) + DOC_SUFFIX
384 filepath = os.path.abspath(os.path.join(self.targetdir, file))
385 #not doctemplate based
386 ## self.pdf_host = Canvas(filepath)
387 ## self.pdf_host.setTitle(title)
388 ### TODO self.pdf_host.setAuthor(TODO author)
389 ###not implemented yet self.pdf_host.setSubject(notimplementedyet subject)
390 #SimpleDocTemplate based
391 # pagesize per wikiaction? / showBoundary= 1 only for tests / allowSplitting= 1 allows the split of flowables
392 self.doc= SimpleDocTemplate(filepath, pagesize= A4, showBoundary= 1, allowSplitting= 1, title= self.title, author= '')
393 #debug self.request.write( "#SimpleDocTemplate initialised! Title: %s Filename: %s" % (self.title, filepath))
394
395 except:
396 self.request.write( "#STARTDOC %s %s failed at Host Initialisation" % (self.doccount,pagename))
397 self.pdf_host=None
398 raise
399
400 else:
401 self.request.write("\nPDF HOST already active!\n")
402 if self.document!=None:
403 self.request.write("ignore#STARTDOC %s %s" % (self.doccount,pagename))
404 return "ignore#STARTDOC %s %s" % (self.doccount,pagename)
405 try:
406
407 self.story = []
408 self.story.append(Spacer(1, 7* cm))
409 # self.story.append(Paragraph(pagename, self.styleTitle))
410
411 except:
412 self.FatalEnd()
413 self.request.write("#STARTDOC %s %s failed at" % (self.doccount,pagename))
414 #self.request.write("#STARTDOC %s %s failed at Documents.Add(%s..." % (self.doccount,pagename,self.doctemplate))
415 raise
416
417 try:
418 self._reset_indents()
419
420
421 # self.document.SaveAs(filepath,0)
422 # self.request.write("#STARTDOC %s %s" % (self.doccount,pagename)) # identisch der returnanweisung
423 return "#STARTDOC %s %s" % (self.doccount,pagename)
424
425 except:
426 self.FatalEnd()
427 self.request.write("#STARTDOC %s %s failed" % (self.doccount,pagename))
428 raise
429
430 def endDocument(self):
431
432 def myFirstPage(canvas, doc):
433 self.request.write( "#myFirstPage reached! ")
434 canvas.saveState()
435 rect=(8.8* cm, (self.PAGE_HEIGHT/5*4)-32, 12.2* cm, (self.PAGE_HEIGHT/5*4)-16)
436 rgb=Color(0,0,1)
437 url='www.orsoft.de'
438 canvas.linkURL(url, rect, 1, 1, rgb)
439 canvas.setFont('Times-Bold', 16)
440 canvas.drawCentredString(self.PAGE_WIDTH/2, self.PAGE_HEIGHT/5*4, self.title)
441 canvas.setFont('Times-Roman', 9)
442 canvas.drawCentredString(self.PAGE_WIDTH/2, (self.PAGE_HEIGHT/5*4)-27, "OR Soft Jänicke GmbH")
443 canvas.drawCentredString(self.PAGE_WIDTH/2, self.PAGE_HEIGHT-(0.75* inch), '') #eg a pageinfo
444 canvas.drawCentredString(self.PAGE_WIDTH/2, 0.75* inch, "Page 1")
445 canvas.restoreState()
446 self.request.write( "#end of myFirstPage reached! " )
447
448 def myLaterPages(canvas, doc):
449 self.request.write( "#myLaterPages reached! ")
450 canvas.saveState()
451 canvas.setFont('Times-Roman',9)
452 canvas.drawCentredString(self.PAGE_WIDTH/2, self.PAGE_HEIGHT-(0.75* inch), '') #eg a pageinfo
453 canvas.drawCentredString(self.PAGE_WIDTH/2, 0.75* inch, "Page %d" % (doc.page))
454 canvas.restoreState()
455 self.request.write( "#end of myLaterPages reached! ")
456
457 #RS fatal error handling
458 if _debug:
459 traceback.print_stack(limit=1,file=sys.stdout)
460 if self.dead==1:
461 return u""
462 #RS end
463 self.doccount-=1
464 if self.doccount==0:
465 try:
466
467 ### self.pdf_host.drawText(self.document)
468 ### self.pdf_host.showPage()
469 # self.f.addFromList(self.story,self.pdf_host)
470 # self.pdf_host.save()
471 #SimpleDocTemplate based
472 self.request.write( "#endDocument reached! len(self.story): %s " % len(self.story))
473 self.doc.build(self.story, onFirstPage= myFirstPage, onLaterPages= myLaterPages)
474 # self.document=None
475 # self.pdf_host=None
476 return u"#ENDDOC"
477 except:
478 return u"#ENDDOC failed"
479 raise
480
481 return u"#ENDDOC %s" % self.doccount
482
483 def startContent(self, content_id='content', **kwargs):
484 """ Start page content div """
485 return ""
486 if _debug:
487 traceback.print_stack(limit=1,file=sys.stdout)
488 # Setup id
489 if content_id!='content':
490 aid = 'top_%s' % (content_id,)
491 else:
492 aid = 'top'
493 self._content_ids.append(content_id)
494 result = []
495 # Use the content language
496 attr = self.langAttr(self.request.content_lang)
497 attr['id'] = content_id
498 result.append(self.open('div', newline=1, attr=attr))
499 result.append(self.anchordef(aid))
500 return ''.join(result)
501
502 def endContent(self):
503 """ Close page content div """
504 return ""
505 if _debug:
506 traceback.print_stack(limit=1,file=sys.stdout)
507
508 # Setup id
509 try:
510 cid = self._content_ids.pop()
511 except:
512 cid = 'content'
513 if cid!='content':
514 aid = 'bottom_%s' % (cid,)
515 else:
516 aid = 'bottom'
517
518 result = []
519 result.append(self.anchordef(aid))
520 result.append(self.close('div', newline=1))
521 return ''.join(result)
522
523 def lang(self, on, lang_name):
524 """ Insert text with specific lang and direction.
525
526 Enclose within span tag if lang_name is different from
527 the current lang
528 """
529 tag = 'span'
530 if lang_name != self.request.current_lang:
531 # Enclose text in span using lang attributes
532 if on:
533 attr = self.langAttr(lang=lang_name)
534 ret=self.open(tag, attr=attr)
535 return ret
536 else:
537 if self.document!=None:
538 pass
539 #TODO : text with language info?
540 ### self.document.XXXX
541 ret=self.close(tag)
542 return ret
543
544 # Direction did not change, no need for span
545 return ''
546
547
548 def _langAttr(self):
549 result = ''
550 lang = self.request.current_lang
551 if lang != config.default_lang:
552 result += ' lang="%s" dir="%s"' % (
553 lang, i18n.getDirection(self.request, lang))
554
555 return result
556
557 def sysmsg(self, text, **kw):
558 if _debug:
559 traceback.print_stack(limit=1,file=sys.stdout)
560 #RS fatal error handling
561 if self.dead==1:
562 return u""
563 #RS end
564 tag = 'div'
565 if on:
566 ret=self.open(tag, attr={'class': 'message'})
567 return ret
568 else:
569 text=self.recordedtext
570 if self.document!=None and text!=None:
571 pass
572 #TODO
573 # self.document.Content.TypeText('#SYSMSG#'+text+'#')
574 ret=self.close(tag)
575 return ret
576
577
578 def pagelink(self, on, pagename='', page=None, **kw):
579 """ Link to a page.
580
581 formatter.text_python will use an optimized call with a page!=None
582 parameter. DO NOT USE THIS YOURSELF OR IT WILL BREAK.
583
584 See wikiutil.link_tag() for possible keyword parameters.
585 """
586 if _debug:
587 traceback.print_stack(limit=1,file=sys.stdout)
588 #RS fatal error handling
589 if self.dead==1:
590 return u""
591 #RS end
592 apply(FormatterBase.pagelink, (self, on, pagename, page), kw)
593 if page is None:
594 page = Page(self.request, pagename, formatter=self);
595 tag = 'pagelink'
596 url = wikiutil.quoteWikinameFS(pagename) + DOC_SUFFIX
597 if on:
598 ret=self.open(tag, attr={'class': 'pagelink'})
599 return ret
600 else:
601 text=self.recordedtext
602 if text==None:
603 text=pagename
604 if self.document!=None:
605 pass
606 #TODO
607 # self.word_host.ActiveDocument.Hyperlinks.Add(\
608 # Anchor=self.word_host.Selection.Range, Address=url,\
609 # SubAddress="", ScreenTip="", TextToDisplay=text)
610 ret=self.close(tag)
611 return ret
612
613
614
615 def interwikilink(self, on, interwiki='', pagename='', **kw):
616 if not on: return '</a>'
617
618 wikitag, wikiurl, wikitail, wikitag_bad = wikiutil.resolve_wiki(self.request, '%s:%s' % (interwiki, pagename))
619 wikiurl = wikiutil.mapURL(self.request, wikiurl)
620
621 if wikitag == 'Self': # for own wiki, do simple links
622 import urllib
623 if wikitail.find('#')>-1:
624 wikitail, kw['anchor'] = wikitail.split('#', 1)
625 wikitail = urllib.unquote(wikitail)
626 return apply(self.pagelink, (on, wikiutil.AbsPageName(self.request, self.page.page_name, wikitail)), kw)
627 else: # return InterWiki hyperlink
628 href = wikiutil.join_wiki(wikiurl, wikitail)
629 if wikitag_bad:
630 html_class = 'badinterwiki'
631 else:
632 html_class = 'interwiki'
633
634 icon = ''
635 if self.request.user.show_fancy_links:
636 icon = self.request.theme.make_icon('interwiki', {'wikitag': wikitag})
637 return (self.url(1, href, title=wikitag, unescaped=0,
638 pretty_url=kw.get('pretty_url', 0), css = html_class) +
639 icon)
640 # unescaped=1 was changed to 0 to make interwiki links with pages with umlauts (or other non-ascii) work
641
642
643 #SYNC URL
644
645 def url(self, on, url=None, css=None, **kw):
646 """ render URL
647
648 @keyword type: "www" or "mailto" to use that icon
649 @keyword title: <a> title attribute
650 @keyword attrs: just include those <a> attrs "as is"
651 """
652 if _debug:
653 traceback.print_stack(limit=1,file=sys.stdout)
654 #RS fatal error handling
655 if self.dead==1:
656 return u""
657 #RS end
658 if url is not None:
659 url = wikiutil.mapURL(self.request, url)
660 title = kw.get('title', None)
661 attrs = kw.get('attrs', None)
662 #RS 1.1
663 target = kw.get('target', None)
664 #RS stop
665 str = ''
666 if css:
667 str = '%s class="%s"' % (str, css)
668 if title:
669 str = '%s title="%s"' % (str, title)
670 else:
671 title=""
672 if attrs:
673 str = '%s %s' % (str, attrs)
674
675 # create link
676 #TODO? insert link icons and other pretty stuff?
677 tag = 'url'
678 if on:
679 #store this for the close action
680 self.url_url=url
681 self.url_title=title
682
683 ret=self.open(tag, attr=attrs)
684 return ret
685 else:
686 text=self.recordedtext
687 url=self.url_url
688 title=self.url_title
689 if text is None:
690 text = url
691 if self.document!=None:
692 pass
693 #TODO
694 # self.word_host.ActiveDocument.Hyperlinks.Add(\
695 # Anchor=self.word_host.Selection.Range, Address=wikiutil.escape(url, 1),\
696 # SubAddress="", ScreenTip=title, TextToDisplay=text)
697
698
699 ret=self.close(tag)
700 return ret
701
702
703 def anchordef(self, id):
704 if _debug:
705 traceback.print_stack(limit=1,file=sys.stdout)
706 #RS fatal error handling
707 if self.dead==1:
708 return u""
709 #RS end
710 if self.document!=None:
711 self.document.Bookmarks.Add(Range=self.word_host.Selection.Range,Name=id)
712 return '<a id="%s"></a>\n' % (id, )
713
714 def anchorlink(self, on, name='', id = None):
715 if _debug:
716 traceback.print_stack(limit=1,file=sys.stdout)
717 ## if self.document!=None:
718 ## self.word_host.Selection.TypeText('_'+text+'_')
719 #RS fatal error handling
720 if self.dead==1:
721 return u""
722 #RS end
723 extra = ''
724 if id:
725 extra = ' id="%s"' % id
726 tag = 'a'
727 if on:
728 ret=self.open(tag, attr={'id':'%s' % id})
729 return ret
730 else:
731 text=self.recordedtext
732 if text==None:
733 text=name
734 if self.document!=None:
735 pass
736 #TODO
737 # self.word_host.ActiveDocument.Hyperlinks.Add(\
738 # Anchor=self.word_host.Selection.Range, Address="",\
739 # SubAddress=name, ScreenTip="", TextToDisplay=text)
740 ret=self.close(tag)
741 return ret
742
743
744 def pure(self, text):
745 """
746 this handles the "not in any markup" case
747 used in formatters with "side effects"
748 """
749 if _debug:
750 traceback.print_stack(limit=1,file=sys.stdout)
751 print "PURE, recording=%s" % self.store_text
752 #RS fatal error handling
753 if self.dead==1:
754 raise
755 return u""
756 #RS end
757 if (self._table_start == 1):
758 raise
759 return u''
760 # if self.document!=None:
761 # pass
762 #TODO
763 # self.word_host.Selection.TypeText(text)
764 return self._text(text)
765
766 def _text(self, text):
767 # return '{'+text+'}'
768 #RS fatal error handling
769 if _debug:
770 traceback.print_stack(limit=2,file=sys.stdout)
771 if self.dead==1:
772 raise
773 return u""
774 #RS end
775 tx=self.escapedText(text)
776 if self._in_code:
777 tx=string.replace(self.escapedText(text), u' ', self.hardspace)
778 # if self.document!=None:
779 # self.document.Content.InsertAfter('#'+text+'#')
780 if self.store_text==1:
781 if _debug:
782 print "_TEXT (recording)"
783 self.recordedtext+=tx
784 return tx
785 else:
786 self.para_story += tx
787 if _debug:
788 print "_TEXT (inline), tx=%s, STORY:%s" % (tx,self.para_story)
789
790 return tx
791
792 # Inline ###########################################################
793 def strong(self, on):
794 #RS fatal error handling
795 if self.dead==1:
796 return u""
797 #RS end
798 tag = 'b'
799 if on:
800 ret=self.open(tag)
801 # if self.document!=None:
802 # pass
803 #TODO
804 # self.word_host.Selection.Font.Bold=\
805 # win32com.client.constants.wdToggle
806 # self.word_host.Selection.TypeText('')
807
808 # is now part of open()
809 ## self.para_story += "<b>"
810 return ret
811 else:
812 # if self.document!=None:
813 # pass
814 #TODO
815 # self.word_host.Selection.Font.Bold=\
816 # win32com.client.constants.wdToggle
817 # self.word_host.Selection.TypeText('')
818 # is now part of close()
819 ## self.para_story += "</b>"
820 ret=self.close(tag)
821 return ret
822
823
824 def emphasis(self, on):
825 #RS fatal error handling
826 if self.dead==1:
827 return u""
828 #RS end
829 tag = 'em'
830 if on:
831 ret=self.open(tag)
832 # if self.document!=None:
833 # pass
834 #TODO
835 # self.word_host.Selection.Font.Italic=\
836 # win32com.client.constants.wdToggle
837 # self.word_host.Selection.TypeText('')
838 # is now part of open()
839 ## self.para_story += "<i>"
840 return ret
841 else:
842 # if self.document!=None:
843 # pass
844 #TODO
845 # self.word_host.Selection.Font.Italic=\
846 # win32com.client.constants.wdToggle
847 # self.word_host.Selection.TypeText('')
848 # is now part of close()
849 ## self.para_story += "</i>"
850 ret=self.close(tag)
851 return ret
852
853 def underline(self, on):
854 if _debug:
855 traceback.print_stack(limit=1,file=sys.stdout)
856 #RS fatal error handling
857 if self.dead==1:
858 return u""
859 #RS end
860 tag = 'span'
861 # new tagname for in-paragraph formatting matters
862 tag = 'u'
863 if on:
864 ret=self.open(tag,attr={'class': 'u'})
865 if self.document!=None:
866 pass
867 #TODO
868 # self.word_host.Selection.Font.Underline=\
869 # win32com.client.constants.wdUnderlineSingle
870 # self.word_host.Selection.TypeText('')
871 # is now part of open()
872 ## self.para_story += "<u>"
873 return ret
874 else:
875 # if self.document!=None:
876 # pass
877 #TODO
878 # self.word_host.Selection.Font.Underline=\
879 # win32com.client.constants.wdUnderlineNone
880 # self.word_host.Selection.TypeText('')
881 # is now part of close()
882 ## self.para_story += "</u>"
883 ret=self.close(tag)
884 return ret
885
886 def highlight(self, on):
887 #RS fatal error handling
888 if self.dead==1:
889 return u""
890 #RS end
891 tag = 'strong'
892 if on:
893 ret=self.open(tag, attr={'class': 'highlight'})
894 if self.document!=None:
895 pass
896 #TODO
897 # self.word_host.Selection.Font.Bold=\
898 # win32com.client.constants.wdToggle
899 # self.word_host.Selection.TypeText('')
900 return ret
901 else:
902 if self.document!=None:
903 pass
904 #TODO
905 # self.word_host.Selection.Font.Bold=\
906 # win32com.client.constants.wdToggle
907 # self.word_host.Selection.TypeText('')
908 ret=self.close(tag)
909 return ret
910
911 def sup(self, on):
912 #RS fatal error handling
913 if self.dead==1:
914 return u""
915 #RS end
916 tag = 'sup'
917 # new tagname for in-paragraph formatting matters
918 tag = 'super'
919 if on:
920 ret=self.open(tag)
921 # if self.document!=None:
922 # pass
923 #TODO
924 # self.word_host.Selection.Font.Superscript=\
925 # win32com.client.constants.wdToggle
926 # self.word_host.Selection.TypeText('')
927 ## self.para_story += "<super>"
928 return ret
929 else:
930 if self.document!=None:
931 pass
932 #TODO
933 # self.word_host.Selection.Font.Superscript=\
934 # win32com.client.constants.wdToggle
935 # self.word_host.Selection.TypeText('')
936 ## self.para_story += "</super>"
937 ret=self.close(tag)
938 return ret
939
940 def sub(self, on):
941 #RS fatal error handling
942 if _debug:
943 traceback.print_stack(limit=1,file=sys.stdout)
944 if self.dead==1:
945 return u""
946 #RS end
947 tag = 'sub'
948 if on:
949 ret=self.open(tag)
950 # if self.document!=None:
951 # pass
952 #TODO
953 # self.word_host.Selection.Font.Subscript=\
954 # win32com.client.constants.wdToggle
955 # self.word_host.Selection.TypeText('')
956 ## self.para_story += "<sub>"
957 return ret
958 else:
959 # if self.document!=None:
960 # pass
961 #TODO
962 # self.word_host.Selection.Font.Subscript=\
963 # win32com.client.constants.wdToggle
964 # self.word_host.Selection.TypeText('')
965 ## self.para_story += "</sub>"
966 ret=self.close(tag)
967 return ret
968 #RS end
969
970
971 def code(self, on):
972 if _debug:
973 traceback.print_stack(limit=1,file=sys.stdout)
974 #RS fatal error handling
975 if self.dead==1:
976 return u""
977 #RS end
978 tag = 'tt'
979 tag = 'font'
980 self._in_code = on
981 if on:
982 fontattr={'name': 'Courier','size':8}
983 ## self.para_story += '<font name="Courier" size=8>'
984 ret=self.open(tag,attr=fontattr)
985 return ret
986 else:
987 if self.document!=None:
988 pass
989 #TODO
990 # lastend=self.recordedcursor
991 # currend=int(self.word_host.Selection.Range.End)
992 # if lastend<currend and lastend>0:
993 # ttrange=self.document.Range(lastend,currend)
994 # ttrange.Style=self.tt_style
995 # else:
996 # self.request.write("TT formatter error, ignored")
997 # self.word_host.Selection.TypeText('')
998 ## self.para_story += "</font>"
999 ret=self.close(tag)
1000 return ret
1001
1002
1003 def small(self, on):
1004 tag = 'small'
1005 if on:
1006 ret=self.open(tag)
1007 if self.document!=None:
1008 pass
1009 #TODO
1010 # self.word_host.Selection.Font.Subscript=\
1011 # win32com.client.constants.wdToggle
1012 # self.word_host.Selection.TypeText('')
1013 return ret
1014 else:
1015 if self.document!=None:
1016 pass
1017 #TODO
1018 # self.word_host.Selection.Font.Subscript=\
1019 # win32com.client.constants.wdToggle
1020 # self.word_host.Selection.TypeText('')
1021 ret=self.close(tag)
1022 return ret
1023
1024 def big(self, on):
1025 tag = 'big'
1026 if on:
1027 ret=self.open(tag)
1028 if self.document!=None:
1029 pass
1030 #TODO
1031 # self.word_host.Selection.Font.Subscript=\
1032 # win32com.client.constants.wdToggle
1033 # self.word_host.Selection.TypeText('')
1034 return ret
1035 else:
1036 if self.document!=None:
1037 pass
1038 #TODO
1039 # self.word_host.Selection.Font.Subscript=\
1040 # win32com.client.constants.wdToggle
1041 # self.word_host.Selection.TypeText('')
1042 ret=self.close(tag)
1043 return ret
1044
1045
1046 # Block elements ####################################################
1047
1048 def preformatted(self, on):
1049 if _debug:
1050 traceback.print_stack(limit=1,file=sys.stdout)
1051 #RS fatal error handling
1052 if self.dead==1:
1053 return u""
1054 #RS end
1055 self.in_pre = on != 0
1056 tag = 'pre'
1057 if on:
1058 ret=self.open(tag,newline=1)
1059 return ret
1060 else:
1061 if self.document!=None:
1062 pass
1063 #TODO
1064 # lastend=self.recordedcursor
1065 # currend=int(self.word_host.Selection.Range.End)
1066 # if lastend<currend and lastend>0:
1067 # ttrange=self.document.Range(lastend,currend)
1068 # ttrange.Style=self.pre_style
1069 # else:
1070 # self.request.write("PRE formatter error, ignored")
1071 # self.word_host.Selection.TypeParagraph()
1072 # self.word_host.Selection.Style=self.defpara_style
1073 ret=self.close(tag)
1074 return ret
1075
1076 # special markup for syntax highlighting #############################
1077
1078 def code_area(self, on, code_id, code_type='code', show=0, start=-1, step=-1):
1079 #RS word: for now, just use preformatted?
1080 if on:
1081 # Open a code area
1082 self._in_code_area = 1
1083 self._in_code_line = 0
1084 else:
1085 # Close code area
1086 self._in_code_area = 0
1087 self._code_area_num += 1
1088 return self.preformatted(on)
1089 #RS end
1090 res = []
1091 ci = self.request.makeUniqueID('CA-%s_%03d' % (code_id, self._code_area_num))
1092 if on:
1093 # Open a code area
1094 self._in_code_area = 1
1095 self._in_code_line = 0
1096 self._code_area_state = [ci, show, start, step, start]
1097
1098 # Open the code div - using left to right always!
1099 attr = {'class': 'codearea', 'lang': 'en', 'dir': 'ltr'}
1100 res.append(self.open('div', attr=attr))
1101
1102 # Add the script only in the first code area on the page
1103 if self._code_area_js == 0 and self._code_area_state[1] >= 0:
1104 res.append(self._toggleLineNumbersScript)
1105 self._code_area_js = 1
1106
1107 # Add line number link, but only for JavaScript enabled browsers.
1108 if self._code_area_state[1] >= 0:
1109 toggleLineNumbersLink = r'''
1110 <script type="text/javascript">
1111 document.write('<a href="#" onClick="return togglenumber(\'%s\', %d, %d);" \
1112 class="codenumbers">Toggle line numbers<\/a>');
1113 </script>
1114 ''' % (self._code_area_state[0], self._code_area_state[2], self._code_area_state[3])
1115 res.append(toggleLineNumbersLink)
1116
1117 # Open pre - using left to right always!
1118 attr = {'id': self._code_area_state[0], 'lang': 'en', 'dir': 'ltr'}
1119 res.append(self.open('pre', newline=True, attr=attr))
1120 else:
1121 # Close code area
1122 res = []
1123 if self._in_code_line:
1124 res.append(self.code_line(0))
1125 res.append(self.close('pre'))
1126 res.append(self.close('div'))
1127
1128 # Update state
1129 self._in_code_area = 0
1130 self._code_area_num += 1
1131
1132 return ''.join(res)
1133
1134 def code_line(self, on):
1135 #RS word: for now, just use preformatted?
1136 self._in_code_line = on != 0
1137 return self.preformatted(on)
1138 #RS end
1139 #RS end
1140 res = ''
1141 if not on or (on and self._in_code_line):
1142 res += '</span>\n'
1143 if on:
1144 res += '<span class="line">'
1145 if self._code_area_state[1] > 0:
1146 res += '<span class="LineNumber">%4d </span>' % (self._code_area_state[4], )
1147 self._code_area_state[4] += self._code_area_state[3]
1148 self._in_code_line = on != 0
1149 return res
1150
1151 def code_token(self, on, tok_type):
1152 #RS word: for now, just use code?
1153 return self.code(on)
1154 #RS end
1155 return ['<span class="%s">' % tok_type, '</span>'][not on]
1156
1157
1158 # Paragraphs, Lines, Rules ###########################################
1159
1160 def linebreak(self, preformatted=1):
1161 if _debug:
1162 traceback.print_stack(limit=1,file=sys.stdout)
1163 #RS fatal error handling
1164 if self.dead==1:
1165 return u""
1166 #RS end
1167 if self._in_code_area:
1168 preformatted = 1
1169 #TODO
1170 # self.word_host.Selection.TypeText("\x0B ")
1171 # self.document.Content.InsertAfter("\x0B ")
1172
1173 return ['\n', '<br>\n'][not preformatted]
1174
1175 def paragraph(self, on):
1176 if _debug:
1177 traceback.print_stack(limit=1,file=sys.stdout)
1178 #RS fatal error handling
1179 if self.dead==1:
1180 return u""
1181 #RS end
1182 if self._terse:
1183 return ''
1184 FormatterBase.paragraph(self, on)
1185 ## if self._in_li:
1186 ## self._in_li = self._in_li + 1
1187 tag = 'p'
1188 if on:
1189 ret=self.open(tag)
1190 #versuch indents
1191 if self.li_marker!= [] and self.li_marker[-1]> 0 and self.last_indent_type=='ul':
1192 if self.p_marker== None:
1193 self.p_marker= 0
1194 self.p_marker+=1
1195 # versuch ende
1196 ## if self.document!=None:
1197 ## if self._ignore_next_paragraph: #we already inserted a paragraph
1198 ## self._ignore_next_paragraph=0
1199 ## return u''
1200 ## else:
1201 ###TODO
1202 ### self.word_host.Selection.TypeParagraph()
1203 ## return u'<pli>'
1204 return ret
1205 else:
1206 ## text=self.recordedtext
1207 ## if self.document!=None:
1208 ## if self._ignore_next_paragraph: #we already inserted a paragraph
1209 ## self._ignore_next_paragraph=0
1210 ## return u''
1211 ## else:
1212 ###TODO
1213 ### self.word_host.Selection.TypeParagraph()
1214 ## return u'<pli>'
1215 self.para_story += ""
1216 # versuch indents
1217 if self.li_marker!= [] and self.li_marker[-1] > 0 and self.p_marker > 1 and self.last_indent_type=='ul':
1218 self.bulletStack.ppush(self.bulletText)
1219 self.bulletText= ''
1220 #versuch pause
1221 self.story.append(Paragraph(str(self.para_story), self.currentstyle, self.bulletText))
1222 #versuch weiter
1223 if self.li_marker!= [] and self.li_marker[-1] > 0 and self.p_marker > 1 and self.last_indent_type=='ul':
1224 self.bulletText= self.bulletStack.ppop()
1225 #versuch ende
1226 if _debug:
1227 sys.stderr.write(self.para_story+"\n")
1228 print "\nSTORY: %s" % self.para_story
1229 self.para_story = ""
1230 ret=self.close(tag)
1231 return ret
1232
1233
1234 def rule(self, size=None):
1235 if _debug:
1236 traceback.print_stack(limit=1,file=sys.stdout)
1237 #RS fatal error handling
1238 if self.dead==1:
1239 return u""
1240 #RS end
1241 #TODO RS draw a line?
1242 if size:
1243 # Add hr class: hr1 - hr6
1244 return self.open('hr', newline=1, attr={'class': 'hr%d' % size})
1245 return self.open('hr', newline=1)
1246
1247 def icon(self, type):
1248 #TODO RS or just ignore (probably just wiki control icons)?
1249 return self.request.theme.make_icon(type)
1250
1251 def img_url(self, img):
1252 """ Generate an image href
1253
1254 @param img: the image filename
1255 @rtype: string
1256 @return: the image href
1257 """
1258 return "%s%s\\img\\%s" % (self.cfg.url_prefix_dir, self.request.theme.name, img)
1259
1260
1261 def smiley(self, text):
1262 w, h, b, img = config.smileys[text.strip()]
1263 href = img
1264 if not href.startswith('/'):
1265 href = self.img_url(img)
1266 return self.image(src=href, alt=text, width=str(w), height=str(h))
1267
1268 # Lists ##############################################################
1269
1270
1271
1272
1273 def number_list(self, on, type=None, start=None):
1274 if _debug:
1275 traceback.print_stack(limit=1,file=sys.stdout)
1276 #RS fatal error handling
1277 if self.dead==1:
1278 return u""
1279 #RS end
1280 tag = 'ol'
1281 self.request.write("<number_list>:on=%s,type=%s,start=%s" % (str(on),str(type),str(start)))
1282 if on:
1283 self.oltypeStack.ppush(self.oltype)
1284 self.oltype= type
1285 self.olstart= start
1286 self.list_levels['ol']=self.list_levels['ol']+1
1287 self.list_levels['all']=self.list_levels['all']+1
1288 attr = {}
1289 if _debug:
1290 print " oltype (ol=on): %s \n" % self.oltype
1291 print " olstart: %s \n" % self.olstart
1292 if type is not None:
1293 attr['type'] = type
1294 if start is not None:
1295 attr['start'] = start
1296 ret=self.open(tag, newline=1, attr=attr)
1297
1298 if self.document!=None:
1299 # self.word_host.Selection.TypeParagraph()
1300 self.request.write("<OL> List type was: %s" % str(self.word_host.Selection.Range.ListFormat.ListType))
1301 #TODO
1302 # if self.list_levels['ol']==1: #only first
1303 # if self.word_host.Selection.Range.ListFormat.ListType != self.ol_type:
1304 # self.word_host.Selection.Range.ListFormat.ApplyNumberDefault(win32com.client.constants.wdWord9ListBehavior)
1305 # if self.last_indent_type=='ul':
1306 # #need more indent
1307 # self.request.write("UL->OL 1")
1308 # self.word_host.Selection.Range.ListFormat.ListIndent()
1309 # else:
1310 # if self.word_host.Selection.Range.ListFormat.ListType != self.ol_type:
1311 # self.word_host.Selection.TypeText("{bulleton}")
1312 # self.word_host.Selection.Range.ListFormat.ApplyNumberDefault(win32com.client.constants.wdWord9ListBehavior)
1313 # if self.last_indent_type=='ul':
1314 # #need more indent
1315 # self.request.write("UL->OL 2")
1316 # self.word_host.Selection.Range.ListFormat.ListIndent()
1317 # self.word_host.Selection.Range.ListFormat.ListIndent()
1318
1319 #self._ignore_next_paragraph=1
1320 self._first_li = 1
1321 self.indenttypeStack.ppush(self.last_indent_type)
1322 self.last_indent_type='ol'
1323 self.bulletStack.ppush(self.bulletText)
1324 self.styleStack.ppush(self.currentstyle)
1325
1326 self.styleBullet.bulletFontName= "Times-Roman"
1327 self.styleBullet.bulletFontSize= 10
1328 self.currentstyle= copy.deepcopy(self.styleBullet)
1329
1330 self.styleBullet.leftIndent+= 14
1331 self.styleBullet.bulletIndent+= 14
1332 return ret
1333
1334 else:
1335 self.seq.reset("OL%s" % self.list_levels['ol']) #reset current OLnumber
1336 self.list_levels['ol']=self.list_levels['ol']-1
1337 self.list_levels['all']=self.list_levels['all']-1
1338
1339 if self.document!=None:
1340 pass
1341 #TODO
1342 # self.word_host.Selection.TypeParagraph()
1343 # self.request.write("</OL> List type was: %s" % str(self.word_host.Selection.Range.ListFormat.ListType))
1344 # if self.list_levels['ul']==0:
1345 # if self.word_host.Selection.Range.ListFormat.ListType == self.ol_type:
1346 # self.word_host.Selection.Range.ListFormat.ApplyNumberDefault(win32com.client.constants.wdWord9ListBehavior)
1347 # if self.last_indent_type=='ul':
1348 # #need more outdent
1349 # self.request.write("UL->OL ??1??")
1350 # self.word_host.Selection.Range.ListFormat.ListOutdent()
1351
1352 # else:
1353 # if self.word_host.Selection.Range.ListFormat.ListType == self.ol_type:
1354 # self.word_host.Selection.Range.ListFormat.ApplyNumberDefault(win32com.client.constants.wdWord9ListBehavior)
1355 # self.word_host.Selection.Range.ListFormat.ListOutdent()
1356 #self._ignore_next_paragraph=1
1357 self.last_indent_type='' #obsolete
1358 ret=self.close(tag)
1359
1360 self.bulletText= self.bulletStack.ppop()
1361 self.currentstyle= self.styleStack.ppop()
1362 self.last_indent_type= self.indenttypeStack.ppop()
1363 self.oltype= self.oltypeStack.ppop()
1364 if _debug:
1365 print " oltype (ol=off): %s " % self.oltype
1366 self.styleBullet.leftIndent-= 14
1367 self.styleBullet.bulletIndent-= 14
1368 #styleStack returns None; set currentstyle
1369 if self.currentstyle==None:
1370 self.currentstyle= self.standardstyle
1371
1372 return ret
1373
1374
1375 def bullet_list(self, on):
1376 if _debug:
1377 traceback.print_stack(limit=1,file=sys.stdout)
1378 #RS fatal error handling
1379 if self.dead==1:
1380 return u""
1381 #RS end
1382 tag = 'ul'
1383 self.request.write("<bullet_list>:on=%s" % (str(on)))
1384 if on:
1385 ret=self.open(tag, newline=1)
1386 self.list_levels['ul']=self.list_levels['ul']+1
1387 self.list_levels['all']=self.list_levels['all']+1
1388 ## if self.document!=None:
1389 #TODO
1390 ## self.request.write("<UL> List type was: %s" % str(self.word_host.Selection.Range.ListFormat.ListType))
1391 # if self.list_levels['ul']==1: #only first
1392 # if self.word_host.Selection.Range.ListFormat.ListType != self.ul_type:
1393 # self.word_host.Selection.Range.ListFormat.ApplyBulletDefault(win32com.client.constants.wdWord9ListBehavior)
1394 # else:
1395 # if self.word_host.Selection.Range.ListFormat.ListType != self.ul_type:
1396 # self.word_host.Selection.Range.ListFormat.ApplyBulletDefault(win32com.client.constants.wdWord9ListBehavior)
1397 # self.word_host.Selection.Range.ListFormat.ListIndent()
1398 #self._ignore_next_paragraph=1
1399
1400 self.indenttypeStack.ppush(self.last_indent_type)
1401 self.last_indent_type='ul'
1402 self.bulletStack.ppush(self.bulletText)
1403 self.styleStack.ppush(self.currentstyle)
1404 if self.list_levels['ul'] == 1:
1405 self.bulletText= '\267'
1406 self.styleBullet.bulletFontSize= 11
1407 # elif elf.list_levels['ul'] == 2:
1408 else:
1409 self.bulletText= '\267'
1410 self.styleBullet.bulletFontSize= 8
1411 self.styleBullet.bulletFontName= "Symbol"
1412 self.currentstyle= copy.deepcopy(self.styleBullet)
1413 self.styleBullet.leftIndent+= 14
1414 self.styleBullet.bulletIndent+= 14
1415
1416 return ret
1417 else:
1418 self.list_levels['ul']=self.list_levels['ul']-1
1419 self.list_levels['all']=self.list_levels['all']-1
1420 if self.document!=None:
1421 self.request.write("<bullet_list>:on=%s" % (str(on)))
1422 # pass
1423 #TODO
1424 # self.word_host.Selection.TypeParagraph()
1425 # self.request.write("</UL> List type was: %s" % str(self.word_host.Selection.Range.ListFormat.ListType))
1426 # if self.list_levels['ul']==0:
1427 # if self.word_host.Selection.Range.ListFormat.ListType == self.ul_type:
1428 # self.word_host.Selection.Range.ListFormat.ApplyBulletDefault(win32com.client.constants.wdWord9ListBehavior)
1429 # else:
1430 # if self.word_host.Selection.Range.ListFormat.ListType == self.ul_type:
1431 # self.word_host.Selection.Range.ListFormat.ApplyBulletDefault(win32com.client.constants.wdWord9ListBehavior)
1432 # self.word_host.Selection.Range.ListFormat.ListOutdent()
1433
1434 self._ignore_next_paragraph=1
1435 self.last_indent_type=''
1436 ret=self.close(tag)
1437
1438 self.bulletText= self.bulletStack.ppop()
1439 self.currentstyle= self.styleStack.ppop()
1440 self.last_indent_type= self.indenttypeStack.ppop()
1441 self.styleBullet.leftIndent-= 14
1442 self.styleBullet.bulletIndent-= 14
1443 #styleStack returns None; set currentstyle
1444 if self.currentstyle==None:
1445 self.currentstyle= self.standardstyle
1446 #verusch indents
1447 if self.list_levels['ul']== 0:
1448 while self.p_marker>0:
1449 self.p_marker= self.p_markerStack.ppop()
1450 del self.li_marker[0:]
1451 # versuch ende
1452 return ret
1453
1454 def listitem(self, on, **kw):
1455 if _debug:
1456 traceback.print_stack(limit=1,file=sys.stdout)
1457 #RS fatal error handling
1458 if self.dead==1:
1459 return u""
1460 #RS end
1461 ## self._in_li = on != 0
1462 tag = 'li'
1463 self._in_li = on != 0
1464 if on:
1465 #versuch indents
1466 if self.last_indent_type=='ul':
1467 self.li_marker.append(1)
1468 self.p_markerStack.ppush(self.p_marker)
1469 self.p_marker= None
1470 #versuch ende
1471 attr = {}
1472 css_class = kw.get('css_class', None)
1473 if css_class:
1474 attr['class'] = css_class
1475 style = kw.get('style', None)
1476 if style:
1477 attr['style'] = style
1478 if style=="list-style-type:none" : # ? or css_class == 'gap':
1479 self.nobullet= 1
1480 self.bulletStack.ppush(self.bulletText)
1481 self.bulletText= ''
1482 #this is indent, not bullet
1483 ret=self.open(tag, attr=attr)
1484 #only by numbered lists - OLnumber depends on the ol indent;set the sequence-format
1485 if self.last_indent_type=='ol':
1486 self.OLnumber="OL%s" % self.list_levels['ol']
1487 self.seq.setFormat(self.OLnumber, self.oltype)
1488 # difference between the default and a nondefault startvalue
1489 if self.olstart>0:
1490 self.seq.reset(self.OLnumber) #reset current OLnumber (nondefault startvalue)
1491 i= 0
1492 while i< (self.olstart-1): #increase to startvalue-1
1493 self.seq.nextf(self.OLnumber)
1494 i+= 1
1495 self.olstart= None
1496 # increase the sequence of the current OLnumber and store it in self.bulletText
1497 self.bulletText= "%s." % self.seq.nextf(self.OLnumber)
1498 ## if not self.oltype == "1":
1499 ## self.seq.setFormat(self.OLnumber, self.oltype)
1500 ## self.bulletText= "%s" % self.seq.nextf(self.OLnumber)
1501 ## else:
1502 ## self.bulletText= "%d." % self.seq.next(self.OLnumber)
1503 # return
1504 return ret
1505 else:
1506 #versuch indents
1507 if self.last_indent_type=='ul':
1508 del self.li_marker[-1]
1509 self.p_marker= self.p_markerStack.ppop()
1510 #versuch ende
1511 if self.nobullet == 1:
1512 self.bulletText= self.bulletStack.ppop()
1513 self.nobullet= 0
1514 ret=self.close(tag)
1515 # return
1516 return ret
1517 #RS end
1518
1519 def definition_list(self, on):
1520 if _debug:
1521 traceback.print_stack(limit=1,file=sys.stdout)
1522 #RS fatal error handling
1523 if self.dead==1:
1524 return u""
1525 #RS end
1526 tag = 'dl'
1527 if on:
1528 ret=self.open(tag, newline=1)
1529 self.list_levels['dl']=self.list_levels['dl']+1
1530 self.list_levels['all']=self.list_levels['all']+1
1531 return ret
1532 else:
1533 self.list_levels['dl']=self.list_levels['dl']-1
1534 self.list_levels['all']=self.list_levels['all']-1
1535 ret=self.close(tag)
1536 return ret
1537
1538 def definition_term(self, on):
1539 if _debug:
1540 traceback.print_stack(limit=1,file=sys.stdout)
1541 #RS fatal error handling
1542 if self.dead==1:
1543 return u""
1544 #RS end
1545 tag = 'dt'
1546 if on:
1547 ret=self.open(tag)
1548 return ret
1549 else:
1550 ret=self.close(tag)
1551 return ret
1552
1553
1554 def definition_desc(self, on):
1555 if _debug:
1556 traceback.print_stack(limit=1,file=sys.stdout)
1557 #RS fatal error handling
1558 if self.dead==1:
1559 return u""
1560 #RS end
1561 tag = 'dd'
1562 if on:
1563 ret=self.open(tag)
1564 return ret
1565 else:
1566 ret=self.close(tag)
1567 return ret
1568
1569
1570
1571 def heading(self, on, depth, id = None, **kw):
1572 # remember depth of first heading, and adapt current depth accordingly
1573 if _debug:
1574 traceback.print_stack(limit=1,file=sys.stdout)
1575 #RS fatal error handling
1576 if self.dead==1:
1577 return u""
1578 #RS end
1579 tag= 'h'
1580
1581 self._reset_indents()
1582 if not self._base_depth:
1583 self._base_depth = depth
1584 #RS adapt base depth if included
1585 self._base_depth=long(self.request.getPragma('_base_depth',str(self._base_depth)))
1586 oridepth=depth
1587
1588 #RS isn't this nonsense???
1589 # depth = max(depth - (self._base_depth - 1), 1)
1590 count_depth = max(depth - (self._base_depth - 1), 1)
1591
1592 #? depth = max(depth + (self._base_depth - 1), self._base_depth)
1593 #RS 1.1
1594 # check numbering, possibly changing the default
1595 if self._show_section_numbers is None:
1596 self._show_section_numbers = self.cfg.show_section_numbers
1597 numbering = self.request.getPragma('section-numbers', '').lower()
1598 if numbering in ['0', 'off']:
1599 self._show_section_numbers = 0
1600 elif numbering in ['1', 'on']:
1601 self._show_section_numbers = 1
1602 elif numbering in ['2', '3', '4', '5', '6']:
1603 # explicit base level for section number display
1604 self._show_section_numbers = int(numbering)
1605 #RS stop
1606
1607 heading_depth = depth + 1
1608 if on:
1609 # create section number
1610 number = ''
1611 if self._show_section_numbers:
1612 # count headings on all levels
1613 self.request._fmt_hd_counters = self.request._fmt_hd_counters[:count_depth]
1614 while len(self.request._fmt_hd_counters) < count_depth:
1615 self.request._fmt_hd_counters.append(0)
1616 self.request._fmt_hd_counters[-1] = self.request._fmt_hd_counters[-1] + 1
1617 number = '.'.join(map(str, self.request._fmt_hd_counters[self._show_section_numbers-1:]))
1618 if number: number += ". "
1619 attr = {}
1620 if id:
1621 attr['id'] = id
1622 # Add space before heading, easier to check source code
1623 ret='\n' +self.open('h%d' % depth, attr=attr)
1624 return "%s%s" % (ret,number)
1625
1626 else:
1627 ## # closing tag, with empty line after, to make source more readable
1628 title=self.recordedtext
1629 # if self.document!=None:
1630 # pass
1631 #TODO
1632 # self.word_host.Selection.TypeParagraph()
1633 # style=win32com.client.constants.wdStyleHeading1 - depth +1
1634 # self.word_host.Selection.Paragraphs.Last.Style=style
1635 # self.word_host.Selection.TypeText('%s' % (title))
1636 # self.word_host.Selection.TypeParagraph()
1637 # self.word_host.Selection.Paragraphs.Last.Style=win32com.client.constants.wdStyleNormal
1638 self.currentstyle= copy.deepcopy(self.standardstyle)
1639 heading=""
1640 if depth == 1:
1641 self.currentstyle=self.styleH1
1642 for i in range(2,6):
1643 self.seq.reset("H%s" % i) # reset all deeper heading numbers
1644 heading= "%(H1+)s " % self.seq # increase the current depth and write heading numbers till the current depth
1645 elif depth == 2:
1646 self.currentstyle=self.styleH2
1647 for i in range(3,6):
1648 self.seq.reset("H%s" % i) # reset all deeper heading numbers
1649 heading= "%(H1)s.%(H2+)s " % self.seq # increase the current depth and write heading numbers till the current depth
1650 elif depth == 3:
1651 self.currentstyle=self.styleH3
1652 for i in range(4,6):
1653 self.seq.reset("H%s" % i) # reset all deeper heading numbers
1654 heading= "%(H1)s.%(H2)s.%(H3+)s " % self.seq # increase the current depth and write heading numbers till the current depth
1655 elif depth == 4:
1656 self.currentstyle=self.styleH4
1657 for i in range(5,6):
1658 self.seq.reset("H%s" % i) # reset all deeper heading numbers
1659 heading= "%(H1)s.%(H2)s.%(H3)s.%(H4+)s " % self.seq # increase the current depth and write heading numbers till the current depth
1660 elif depth == 5:
1661 self.currentstyle=self.styleH5
1662 for i in range(5,6):
1663 self.seq.reset("H%s" % i) # reset all deeper heading numbers
1664 heading= "%(H1)s.%(H2)s.%(H3)s.%(H4)s.%(H5+)s " % self.seq # increase the current depth and write heading numbers till the current depth
1665 heading += title
1666 # self.story.append(Paragraph("[%s]%s" % (depth,title),self.currentstyle))
1667 self.story.append(Paragraph("%s" % (heading),self.currentstyle))
1668 if _debug:
1669 sys.stderr.write(self.para_story+"\n")
1670 self.currentstyle= copy.deepcopy(self.standardstyle)
1671
1672 ret=self.close('h%d' % depth)
1673 return ret
1674
1675
1676
1677 # Tables #############################################################
1678
1679 _allowed_table_attrs = {
1680 'table': ['class', 'id', 'style'],
1681 'row': ['class', 'id', 'style'],
1682 '': ['colspan', 'rowspan', 'class', 'id', 'style'],
1683 }
1684
1685 def _checkTableAttr(self, attrs, prefix):
1686 if _debug:
1687 traceback.print_stack(limit=1,file=sys.stdout)
1688 if not attrs: return u''
1689
1690 result = ''
1691 for key, val in attrs.items():
1692 if prefix and key[:len(prefix)] != prefix: continue
1693 key = key[len(prefix):]
1694 if key not in self._allowed_table_attrs[prefix]: continue
1695 result = '%s %s=%s' % (result, key, val)
1696
1697 return result
1698
1699 def table(self, on, attrs=None):
1700 """ Create table
1701
1702 @param on: start table
1703 @param attrs: table attributes
1704 @rtype: string
1705 @return start or end tag of a table
1706 """
1707 if _debug:
1708 traceback.print_stack(limit=1,file=sys.stdout)
1709 #RS fatal error handling
1710 if self.dead==1:
1711 return u""
1712 #RS end
1713 result = []
1714 if on:
1715 # Open div to get correct alignment with table width smaller
1716 # than 100%
1717 # ret=self.open('div', newline=1)
1718 # result.append(ret)
1719
1720 # Open table
1721 if not attrs:
1722 attrs = {}
1723 else:
1724 attrs = self._checkTableAttr(attrs, 'table')
1725 ret= self.open('table', newline=1, attr=attrs)
1726
1727 self.list_levels['table']=self.list_levels['table']+1
1728 self.list_levels['all']=self.list_levels['all']+1
1729 if self.document!=None:
1730 pass
1731 #TODO
1732 # if self.word_host.Selection.Range.ListFormat.ListType == win32com.client.constants.wdListBullet:
1733 # self.word_host.Selection.Range.ListFormat.ApplyBulletDefault(win32com.client.constants.wdWord9ListBehavior)
1734 # self.word_host.Selection.TypeParagraph()
1735 # self.document.Tables.Add(Range=self.word_host.Selection.Range,
1736 # NumRows=1, NumColumns= 1, DefaultTableBehavior=win32com.client.constants.wdWord9TableBehavior,
1737 # AutoFitBehavior= win32com.client.constants.wdAutoFitContent)
1738 self._first_tr = 1
1739 self._first_td = 1
1740 self._table_start=1
1741 return ret
1742 else:
1743 self.list_levels['table']=self.list_levels['table']-1
1744 self.list_levels['all']=self.list_levels['all']-1
1745 if self.document!=None:
1746 pass
1747 #TODO
1748 # self.word_host.Selection.MoveDown(Unit=win32com.client.constants.wdLine, Count=1)
1749 # self.word_host.Selection.TypeParagraph()
1750
1751 ret=self.close('table')
1752 # ret=self.close('div')
1753
1754 return ret
1755
1756 def table_row(self, on, attrs=None):
1757 if _debug:
1758 traceback.print_stack(limit=1,file=sys.stdout)
1759 #RS fatal error handling
1760 if self.dead==1:
1761 return u""
1762 #RS end
1763 tag = 'tr'
1764 if on:
1765 if not attrs:
1766 attrs = {}
1767 else:
1768 attrs = self._checkTableAttr(attrs, 'row')
1769 ret=self.open(tag, newline=1, attr=attrs)
1770 if self._first_tr == 0:
1771 #first row always existing
1772 if self.document!=None:
1773 pass
1774 #TODO
1775 # self.word_host.Selection.InsertRowsBelow(1)
1776 self._first_td = 1
1777 elif self._first_td == 1:
1778 # if self.document!=None:
1779 # self.word_host.Selection.TypeText('#')
1780 self._table_start = 0
1781 return ret
1782 else:
1783 self._first_tr = 0
1784 ret=self.close(tag)
1785 return ret
1786
1787
1788 def table_cell(self, on, attrs=None):
1789 if _debug:
1790 traceback.print_stack(limit=1,file=sys.stdout)
1791 #RS fatal error handling
1792 if self.dead==1:
1793 return u""
1794 #RS end
1795 tag = 'tr'
1796 if on:
1797 if not attrs:
1798 attrs = {}
1799 else:
1800 attrs = self._checkTableAttr(attrs, 'row')
1801 ret=self.open(tag, newline=1, attr=attrs)
1802 if self.document!=None:
1803 pass
1804 #TODO
1805 # self.word_host.Selection.Style=self.defchar_style
1806 if self._first_tr == 1:
1807 if self._first_td == 0:
1808 #first cell always existing
1809 if self.document!=None:
1810 pass
1811 #TODO
1812 # self.word_host.Selection.InsertColumnsRight()
1813 # self.word_host.Selection.Style=self.defchar_style
1814
1815 else:
1816 #jump into cell
1817 if self.document!=None:
1818 pass
1819 #TODO
1820 # self.word_host.Selection.MoveRight(Unit=win32com.client.constants.wdCell)
1821 # self.word_host.Selection.Style=self.defchar_style
1822 self._first_td = 0
1823 return ret
1824 else:
1825 self._first_td = 0
1826 ret=self.close(tag)
1827 return ret
1828
1829 def macro(self, macro_obj, name, args):
1830 #not implemented yet
1831 return ""
1832 # call the macro
1833 if name in ['TableOfContents',]:
1834 #skip call, emulate behavior
1835 ## With ActiveDocument
1836 ## .TablesOfContents.Add Range:=Selection.Range, RightAlignPageNumbers:= _
1837 ## True, UseHeadingStyles:=True, UpperHeadingLevel:=1, _
1838 ## LowerHeadingLevel:=3, IncludePageNumbers:=True, AddedStyles:="", _
1839 ## UseHyperlinks:=True, HidePageNumbersInWeb:=True
1840 ## .TablesOfContents(1).TabLeader = wdTabLeaderSpaces
1841 ## .TablesOfContents.Format = wdIndexIndent
1842 try:
1843 self.mindepth = max(int(self.request.getPragma('section-numbers', 1)),1)
1844 except (ValueError, TypeError):
1845 self.mindepth = 1
1846
1847 try:
1848 self.maxdepth = max(int(args), 1)
1849 except (ValueError, TypeError):
1850 self.maxdepth = 9
1851 sys.stdout.write("TOCrange:%s-%s" % (self.mindepth,self.maxdepth))
1852 if self.document!=None:
1853 self.word_host.ActiveDocument.TablesOfContents.Add(\
1854 Range=self.word_host.Selection.Range, UpperHeadingLevel=self.mindepth,\
1855 LowerHeadingLevel=self.maxdepth,UseHyperlinks=vbTrue)
1856 return "<TOC/>"
1857
1858 return macro_obj.execute(name, args)
1859
1860
1861
1862 def escapedText(self, text):
1863 return text
1864 return wikiutil.escape(text)
1865
1866
1867 def _img(self,imgurl,**kw):
1868
1869 imageWidth= 0
1870 imageHeight= 0
1871 if _debug:
1872 traceback.print_stack(limit=1,file=sys.stdout)
1873 #RS fatal error handling
1874 if self.dead==1:
1875 return u""
1876 #RS end
1877 trusted=1
1878 scheme = string.split(imgurl, ":", 1)[0]
1879 if scheme in tuple(string.split('http|https|ftp|nntp','|')):
1880 trusted=0
1881 filepath=imgurl
1882 self.request.write("adding http picture, filepath=%s " % (filepath))
1883 #retrieve remote file to temp
1884 try:
1885 (filename, headers)=urllib.urlretrieve( imgurl)
1886 print "remote url %s retrieved to %s" % (imgurl,filename)
1887 filepath=filename
1888 except:
1889 filepath=imgurl
1890 self.request.write("adding http picture, filepath=%s" % (filepath))
1891 elif scheme in tuple(string.split('file|self|wiki','|')):
1892 trusted=0
1893 #filepath=imgurl
1894 ## filepath= string.split(imgurl, ':', 1)[1]
1895 ## if filepath[3]==':': # eg: (file:)//C:\bla
1896 ## filepath= string.split(filepath, '//', 1)[1]
1897 ## self.request.write("adding file|self|wiki picture, filepath=%s " % (filepath))
1898 #RS
1899 if scheme=="file":
1900 filepath = string.split(imgurl, ":", 1)[1]
1901 if filepath.find(":")!=-1:
1902 filepath=filepath[2:]
1903 self.request.write("adding file picture with drive, filepath=%s" % (filepath))
1904 else:
1905 filepath='\\\\'+filepath[2:]
1906 self.request.write("adding file picture with UNC, filepath=%s" % (filepath))
1907 else:
1908 filepath=imgurl
1909 self.request.write("adding self|wiki picture, filepath=%s" % (filepath))
1910 else:
1911 trusted=1
1912 if imgurl.startswith("./"):
1913 imgfile=imgurl[2:]
1914 filepath = os.path.abspath(os.path.join(self.cfg.url_prefix_dir, imgfile))
1915 elif imgurl.startswith(".\\"):
1916 imgfile=imgurl[2:]
1917 print "attachment?"
1918 filepath = os.path.abspath(os.path.join(self.cfg.data_dir,"pages", imgfile))
1919 else:
1920 imgfile=imgurl
1921 filepath = os.path.abspath(os.path.join(self.cfg.url_prefix_dir, imgfile))
1922 self.request.write("\n adding .. picture, imgfile=%s, targetdir=%s, filepath=%s" % (imgfile,self.targetdir,filepath))
1923 if self.document!=None:
1924 pass
1925
1926 imageReader=ImageReader(filepath)
1927 imageWidth, imageHeight= imageReader.getSize()
1928 #scale imagesize (only a fixed maximum size at present : (PAGE_WIDTH- 6* cm):(PAGE_HEIGHT- 8* cm))
1929 if imageWidth > (self.PAGE_WIDTH- 6* cm) or imageHeight > (self.PAGE_HEIGHT- 8* cm):
1930 if imageWidth/ (self.PAGE_WIDTH- 6* cm) < imageHeight/ (self.PAGE_HEIGHT- 8* cm):
1931 imageWidth= imageWidth/ (imageHeight/ (self.PAGE_HEIGHT- 8* cm))
1932 imageHeight= imageHeight/ (imageHeight/ (self.PAGE_HEIGHT- 8* cm))
1933 else:
1934 imageHeight= imageHeight/ (imageWidth/ (self.PAGE_WIDTH- 6* cm))
1935 imageWidth= imageWidth/ (imageWidth/ (self.PAGE_WIDTH- 6* cm))
1936 self.story.append(Image(filepath, width= imageWidth, height= imageHeight))
1937
1938 #word
1939 # if self.word_host.Selection.Range.ListFormat.ListType == win32com.client.constants.wdListBullet:
1940 # self.word_host.Selection.Range.ListFormat.ApplyBulletDefault(win32com.client.constants.wdWord9ListBehavior)
1941 # try:
1942 # self.word_host.Selection.InlineShapes.AddPicture(FileName=filepath,\
1943 # LinkToFile=False, SaveWithDocument=True)
1944 # except:
1945 # if trusted:
1946 # self.request.write("error in img, imgfile=%s, docpath=%s" % (filepath,str(self.document.Path)))
1947 # self.request.write("Active %s" % str(self.word_host.Selection.Active))
1948 # raise
1949 # errtext='[internal image not found:%s]' % filepath
1950 # self.document.Undo()
1951 # try:
1952 # self.word_host.Selection.TypeText(errtext)
1953 # except:
1954 # self.request.write("error reset did not work, may need Office 2000 SP3?")
1955 # raise "error reset did not work, may need Office 2000 SP3?"
1956 # else:
1957 # self.request.write("warning in img, imgfile=%s, docpath=%s" % (filepath,str(self.document.Path)))
1958 # self.word_host.Selection.TypeText('[external image not found:%s]' % filepath)
1959 #
1960 # self.word_host.Selection.TypeText(' ')
1961 # self._save()
1962
1963
1964 def image(self, **kw):
1965 """ Take HTML <IMG> tag attributes in `attr`.
1966
1967 Attribute names have to be lowercase!
1968 """
1969 #self.request.write("#def image" )
1970 if _debug:
1971 traceback.print_stack(limit=1,file=sys.stdout)
1972 #RS fatal error handling
1973 if self.dead==1:
1974 return u""
1975 #RS end
1976 attrstr = u''
1977 for attr, value in kw.items():
1978 if attr=='html_class':
1979 attr='class'
1980 attrstr = attrstr + u' %s="%s"' % (attr, wikiutil.escape(value))
1981 imgurl=kw.get('src','')
1982 self.request.write("\ntry image, imgurl=%s " % (imgurl))
1983 if imgurl!='':
1984 self._img(imgurl,**kw)
1985 result= u'<img%s/>' % attrstr
1986 return result
1987
1988
1989
1990 def rawHTML(self, markup):
1991 """ This allows emitting pre-formatted HTML markup, and should be
1992 used wisely (i.e. very seldom).
1993
1994 Using this event while generating content results in unwanted
1995 effects, like loss of markup or insertion of CDATA sections
1996 when output goes to XML formats.
1997 """
1998 return '<<'+markup+'>>'
1999
2000 class Privatestack:
2001 '''a private LIFO Stack
2002 you can ppush an element on and ppop it from'''
2003
2004 def __init__(self):
2005 self.__privatestack_= []
2006 def ppush(self, element):
2007 '''push an element on the stack'''
2008 self.__privatestack_.append(element)
2009 return
2010 def ppop(self):
2011 '''returns the last element from the stack
2012 (returns None for an empty stack)'''
2013 if not len(self.__privatestack_):
2014 return None
2015 element= self.__privatestack_.pop()
2016 return element
2017
2018 ###abp flow start
2019 ##styles = getSampleStyleSheet()
2020 ###Title = wikiutil.quoteFilename(pagename)
2021 ###Author = self.request.user.name
2022 ###goFile = Title + DOC_SUFFIX
2023 ###goFilePath = os.path.abspath(os.path.join(self.targetdir, goFile))
2024 ##goFilePath = ''
2025 ##
2026 ##def myFirstPage(canvas, doc):
2027 ## canvas.saveState()
2028 ## canvas.restoreState()
2029 ##
2030 ##def myLaterPages(canvas, doc):
2031 ## canvas.saveState()
2032 ## canvas.setFont('Times-Roman',9)
2033 ## canvas.drawString(inch, 0.75 * inch, "Page %d" % doc.page)
2034 ## canvas.restoreState()
2035 ##
2036 ##def go(goFilePath):
2037 ## doc = SimpleDocTemplate(goFilePath,showBoundary='showboundary' in sys.argv)
2038 ## doc.allowSplitting = not 'nosplitting' in sys.argv
2039 ## doc.build(Elements,myFirstPage,myLaterPages)
2040 ##
2041 ##Elements = []
2042 ##
2043 ##ChapterStyle = copy.copy(styles["Heading1"])
2044 ##ChapterStyle.alignment = TA_CENTER
2045 ##ChapterStyle.fontsize = 16
2046 ##InitialStyle = copy.deepcopy(ChapterStyle)
2047 ##InitialStyle.fontsize = 16
2048 ##InitialStyle.leading = 20
2049 ##PreStyle = styles["Code"]
2050 ##
2051 ##def newPage():
2052 ## Elements.append(PageBreak())
2053 ##
2054 ##def chapter(txt, style=ChapterStyle):
2055 ## newPage()
2056 ## Elements.append(Paragraph(txt, style))
2057 ## Elements.append(Spacer(0.2*inch, 0.3*inch))
2058 ##
2059 ##def fTitle(txt,style=InitialStyle):
2060 ## Elements.append(Paragraph(txt, style))
2061 ##
2062 ##ParaStyle = copy.deepcopy(styles["Normal"])
2063 ##ParaStyle.spaceBefore = 0.1*inch
2064 ##
2065 ##if 'right' in sys.argv:
2066 ## ParaStyle.alignment = TA_RIGHT
2067 ##elif 'left' in sys.argv:
2068 ## ParaStyle.alignment = TA_LEFT
2069 ##elif 'justify' in sys.argv:
2070 ## ParaStyle.alignment = TA_JUSTIFY
2071 ##elif 'center' in sys.argv or 'centre' in sys.argv:
2072 ## ParaStyle.alignment = TA_CENTER
2073 ##else:
2074 ## ParaStyle.alignment = TA_JUSTIFY
2075 ##
2076 ##def spacer(inches):
2077 ## Elements.append(Spacer(0.1*inch, inches*inch))
2078 ##
2079 ##def p(txt, style=ParaStyle):
2080 ## Elements.append(Paragraph(txt, style))
2081 ##
2082 ##def pre(txt, style=PreStyle):
2083 ## spacer(0.1)
2084 ## p = Preformatted(txt, style)
2085 ## Elements.append(p)
2086 ##
2087 ##def parseOdyssey(output, pfilepath, ptitle, pauthor):
2088 ##
2089 ### from time import time
2090 ## E = []
2091 ### t0=time()
2092 ### L = open(fn,'r').readlines()
2093 ## L = []
2094 ## #L.append(output)
2095 ## #for a in output:
2096 ## # L.append(a)
2097 ## L=output.split("\n") #jedes Listenelement ist eine Textzeile ohne \n
2098 ### L.insert(0,'')
2099 ### L.insert(0,'-----')
2100 ## L.insert(0,'')
2101 ## global goFilePath
2102 ## goFilePath = pfilepath
2103 ## Title = ptitle
2104 ## Author = pauthor
2105 ### t1 = time()
2106 ### print "open stream took %.4f seconds" %(t1-t0)
2107 #### L=replace(L,'\012','')
2108 #### L=map(lambda x:x+"\012",L)
2109 #### for i in xrange(len(L)):
2110 #### if L[i][-1]=='\012':
2111 #### L[i] = L[i][:-1]
2112 ### t2 = time()
2113 ### print "Removing all linefeeds took %.4f seconds" %(t2-t1)
2114 ### L.append('')
2115 ### L.append('-----')
2116 ### lo=L[0]
2117 ### lp=L[1]
2118 ### print testen,lo,lp
2119 ##
2120 #### def findNext(L, i):
2121 #### kind=1
2122 #### while 1: #moegliche abbruchbedingungen fuer die schleife:
2123 #### # -> es existiert eine Leerzeile
2124 #### # a) und dann keine weitere zeile -> ende (Leerzeile und dann nichts mehr)
2125 #### # b) weitere zeilen, dann werden
2126 #### #anschliessende leerzeilen entfernt
2127 #### # b) dann existiert keine weitere zeile -> ende (Leerzeilen und dann nichts mehr)
2128 #### # c) weitere zeilen existieren
2129 #### # naechste zeile beginnt und endet mit -?
2130 #### # c) ja: dann wird die zeile geloescht
2131 #### # c) danach keine weitere Zeile? -> ende (Leerzeile(n) direkt danach von '-' umrahmte zeile und dann nichts mehr)
2132 #### # d) danach weitere zeilen: loesche nachfolgende leerzeilen und dann -> ende (Leerzeile(n) direkt danach von '-' umrahmte zeile)
2133 #### # e) nein: -> ende mit kind=0 und sofortiger neubeginn mit index 0
2134 #### if string.strip(L[i])=='': #ist zeile i ohne sonderzeichen leer?
2135 #### del L[i] #dann loesche die zeile i (zeilenanzahl verringert sich um 1)
2136 #### kind = 1
2137 #### if i<len(L): #index i kleiner als die neue Zeilengesamtzahl?
2138 #### while string.strip(L[i])=='': #solange zeile i ohne sonderzeichen leer?;loescht nach der leerzeile jetzt alle nachfolgenden leerzeilen
2139 #### del L[i] # loesche zeile i
2140 ####
2141 #### if i<len(L): #index i kleiner als die neue Zeilengesamtzahl?
2142 #### #kind = L[i][-1]=='-' and L[i][0]=='-'
2143 #### if L[i][-1]=='-' and L[i][0]=='-': #letzte und erste zeichen der zeile i ein '-'?
2144 #### kind = 1
2145 #### else:
2146 #### kind = 0
2147 #### if kind: #wenn kind wahr, also zeile i von '-' eingerahmt, dann:
2148 #### del L[i] #loesche diese zeile
2149 #### if i<len(L):#index i kleiner als die neue Zeilengesamtzahl?
2150 #### while string.strip(L[i])=='':#solange zeile i ohne sonderzeichen leer?
2151 #### del L[i] #loesche zeile i
2152 #### break
2153 #### else:
2154 #### i = i + 1
2155 ####
2156 #### return i, kind
2157 ##
2158 ## def findNext(L, i):
2159 ## while 1:
2160 #### if string.strip(L[i])=='': #ist zeile i ohne sonderzeichen leer?
2161 #### del L[i] #dann loesche die zeile i (zeilenanzahl verringert sich um 1)
2162 #### kind = 1
2163 ## kind=1
2164 ## if i>=len(L): #index i groesser als die neue Zeilengesamtzahl?
2165 ## break
2166 ## else:
2167 ## while string.strip(L[i])=='': #solange zeile i ohne sonderzeichen leer?
2168 ## del L[i] # loesche zeile i
2169 ## if i>=len(L): #index i groesser als die neue Zeilengesamtzahl?
2170 ## break
2171 ##
2172 ## if i>len(L): #index i groesser als die neue Zeilengesamtzahl?
2173 ## break
2174 ## else:
2175 ## if L[i][0:9] == '#STARTDOC' or L[i][-7:] == '#ENDDOC':
2176 ## kind = 1
2177 ## else:
2178 ## kind = 0
2179 ## if kind:
2180 ## # del L[i] #loesche diese zeile
2181 ## if i<=len(L):#index i kleiner gleich die neue Zeilengesamtzahl?
2182 ## while string.strip(L[i])=='':#solange zeile i ohne sonderzeichen leer?
2183 ## del L[i] #loesche zeile i
2184 ## break
2185 ## i = i + 1
2186 ##
2187 ## return i, kind
2188 ##
2189 ##
2190 ## f = s = 0
2191 ## while 1:
2192 ## f, k = findNext(L,0)
2193 ## if k: break
2194 ##
2195 ## E.append([spacer,2])
2196 ## E.append([fTitle, Title, InitialStyle])
2197 ## E.append([fTitle,'<font size=-4>translated by</font> %s' % Author, InitialStyle])
2198 ### print testen,L,E,f,k
2199 ##
2200 ## while 1:
2201 ## if f>=len(L): break
2202 ### print testen,L,E,f,k
2203 ## if string.upper(L[f].strip()[0:5])=='BOOK ':
2204 ## E.append([chapter,L[f]])
2205 ## f=f+1
2206 ## while string.strip(L[f])=='': del L[f]
2207 ## style = ParaStyle
2208 ## func = p
2209 ## else:
2210 ## style = PreStyle
2211 ## func = pre
2212 ##
2213 ## while 1:
2214 ## s=f
2215 ## f, k=findNext(L,s)
2216 ## sep= (func is pre) and '\012' or ' '
2217 ## #print testen,L,E,s,f
2218 ##
2219 ## E.append([func,string.join(L[s:f],sep),style])
2220 ## if k: break
2221 ### t3 = time()
2222 ### print "Parsing into memory took %.4f seconds" %(t3-t2)
2223 ### print testen,L,E
2224 ## del L
2225 ### t4 = time()
2226 ### print "Deleting list of lines took %.4f seconds" %(t4-t3)
2227 ## for i in xrange(len(E)):
2228 ## apply(E[i][0],E[i][1:])
2229 ### t5 = time()
2230 ### print "Moving into platypus took %.4f seconds" %(t5-t4)
2231 ## del E
2232 ### t6 = time()
2233 ### print "Deleting list of actions took %.4f seconds" %(t6-t5)
2234 ## go(goFilePath)
2235 ### t7 = time()
2236 ### print "saving to PDF took %.4f seconds" %(t7-t6)
2237 ### print "Total run took %.4f seconds"%(t7-t0)
2238 ##
2239 ### for fn in ('odyssey.full.txt','odyssey.txt'):
2240 ### if os.path.isfile(fn):
2241 ### break
2242 ##
2243 ##
2244 ###abp flow pause
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.