Develop and Download Open Source Software

Browse Subversion Repository

Contents of /writer.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5 - (show annotations) (download) (as text)
Thu Dec 8 06:02:21 2011 UTC (12 years, 4 months ago) by isao-hara
File MIME type: text/x-python
File size: 38329 byte(s)
fixed many bugs, and support csv table
1 # -*- coding: utf-8 -*-
2 """
3 sphinx-docxwriter
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~
5
6 Modified custom docutils writer for OpenXML (docx).
7 Original code from 'sphinxcontrib-documentwriter'
8
9 :copyright:
10 Copyright 2011 by haraisao at gmail dot com
11 :license: MIT, see LICENSE for details.
12 """
13 """
14 sphinxcontrib-docxwriter
15 ~~~~~~~~~~~~~~~~~~~~~~~~~~
16
17 Custom docutils writer for OpenXML (docx).
18
19 :copyright:
20 Copyright 2010 by shimizukawa at gmail dot com (Sphinx-users.jp).
21 :license: BSD, see LICENSE for details.
22 """
23
24 import re
25
26 from docutils import nodes, writers
27
28 from sphinx import addnodes
29 from sphinx.locale import admonitionlabels, versionlabels, _
30
31 import docx
32 import sys
33 import os
34 import zipfile
35 import tempfile
36 from lxml import etree
37
38 #
39 # Is the PIL imaging library installed?
40 try:
41 import Image
42 except ImportError, exp:
43 Image = None
44
45 #
46 # Logging for debugging
47 #
48 import logging
49 logging.basicConfig(filename='docx.log', filemode='w', level=logging.INFO,
50 format="%(asctime)-15s %(message)s")
51 logger = logging.getLogger('docx')
52
53
54 def dprint(_func=None, **kw):
55 f = sys._getframe(1)
56 if kw:
57 text = ', '.join('%s = %s' % (k, v) for k, v in kw.items())
58 else:
59 try:
60 text = dict((k, repr(v)) for k, v in f.f_locals.items()
61 if k != 'self')
62 text = unicode(text)
63 except:
64 text = ''
65
66 if _func is None:
67 _func = f.f_code.co_name
68
69 logger.info(' '.join([_func, text]))
70
71 ###### Utility functions
72 def remove_items(src, target):
73 for x in target:
74 src.remove(x)
75
76 def get_items_list(src):
77 result=[]
78 for x in src:
79 if x :
80 result.append(x)
81 return result
82
83 def findElement(elem, tag):
84 res = None
85 if not elem :
86 return res
87
88 for x in elem :
89 try:
90 if x.tagname == tag:
91 return x
92 else:
93 res = findElement(x.children, tag)
94 except:
95 res = None
96 return res
97
98 def get_toc_maxdepth(builder, docname):
99 toc_maxdepth = 0
100 try:
101 toc = findElement(builder.env.tocs[docname], 'toctree')
102
103 if toc :
104 toc_maxdepth = toc['maxdepth']
105 except:
106 toc_maxdepth = 0
107 return toc_maxdepth
108
109 #
110 # DocxWriter class for sphinx
111 #
112 class DocxWriter(writers.Writer):
113 supported = ('docx',)
114 settings_spec = ('No options here.', '', ())
115 settings_defaults = {}
116
117 output = None
118
119 def __init__(self, builder):
120 writers.Writer.__init__(self)
121 self.builder = builder
122 self.docx = docx.DocxComposer()
123
124 self.title = self.builder.config['docx_title']
125 self.subject = self.builder.config['docx_subject']
126 self.creator = self.builder.config['docx_creator']
127 self.company = self.builder.config['docx_company']
128 self.category = self.builder.config['docx_category']
129 self.descriptions = self.builder.config['docx_descriptions']
130 self.keywords = self.builder.config['docx_keywords']
131
132 stylefile = self.builder.config['docx_style']
133 if stylefile :
134 self.docx.new_document(stylefile)
135 else:
136 self.docx.new_document('style.docx')
137
138 def save(self, filename):
139 self.docx.set_props(title=self.title,
140 subject=self.subject,
141 creator=self.creator,
142 company=self.company,
143 category=self.category,
144 descriptions=self.descriptions,
145 keywords=self.keywords)
146
147 self.docx.save(filename)
148
149 def translate(self):
150 visitor = DocxTranslator(self.document, self.builder, self.docx)
151 self.document.walkabout(visitor)
152 self.output = '' # visitor.body
153
154 #
155 # DocxTranslator class for sphinx
156 #
157 class DocxTranslator(nodes.NodeVisitor):
158
159 def __init__(self, document, builder, docx):
160 self.builder = builder
161 self.docx = docx
162 nodes.NodeVisitor.__init__(self, document)
163
164 self.states = [[]]
165 self.list_style = []
166 self.sectionlevel = 0
167 self.table = None
168
169 self.line_block_level = 0
170
171 self.list_item_flushed = False
172
173 self.current_block = []
174 self.list_level = 0
175 self.block_level = 0
176 self.num_list_id = docx.get_max_numbering_id() + 1
177 self.max_num_list_id = self.num_list_id
178
179 self.enum_prefix_style = []
180
181 self.enumprefix = "%1."
182 self.enumprefix_type = "decimal"
183 self.start_num = 1
184
185 self.field_name = None
186
187 def add_text(self, text):
188 '''
189 Add text in states
190 '''
191 dprint()
192 if not self.states :
193 if self.states[-1] is not [] :
194 self.states.append([])
195
196 self.states[-1].append(text)
197
198 def add_linebreak(self):
199 '''
200 Add linebreak-text(:br) in states
201 '''
202 dprint()
203 self.add_text(':br')
204
205 def new_state(self):
206 '''
207 create a new state
208 '''
209 dprint()
210
211 if len(self.current_block) == 0 :
212 self.ensure_state()
213 if self.states[-1] is not [] :
214 self.states.append([])
215
216 def ensure_state(self):
217 '''
218 ensure state and flush all states
219 '''
220 dprint()
221 self.flush_state()
222
223 def flush_state(self, _sty=None, typ = -1, enumprefix=None, enumprefixtype=None, start_num=1):
224 '''
225 flush all states
226 '''
227 dprint()
228 result=False
229
230 if 'Admonition' in self.current_block :
231 return result
232
233 if _sty is 'List_item' :
234 self.flush_enum_list_item()
235 else:
236 if _sty is None :
237 if len(self.current_block) > 0 and self.current_block[-1] == 'List_item' :
238 self.flush_enum_list_item()
239 result=True
240
241 self.flush_state_all(_sty)
242
243 return result
244
245 def flush_state_all(self, _sty=None):
246 '''
247 flush all states
248 '''
249 dprint()
250
251 for texts in self.states:
252 if texts :
253 if _sty :
254 self.docx.paragraph(texts, style=_sty, block_level=self.block_level)
255 else:
256 self.docx.paragraph(texts, block_level=self.block_level)
257 self.states = [[]]
258
259 def end_state(self, first=None):
260 '''
261 clear states
262 '''
263 dprint()
264 try:
265 result = self.states.pop()
266 if first is not None and result:
267 item = result[0]
268 if item:
269 result.insert(0, [first + item[0]])
270 result[1] = item[1:]
271 if not self.states :
272 if self.states[-1] is not [] :
273 self.states.append([])
274 self.states[-1].extend(result)
275 except:
276 self.states=[[]]
277 pass
278
279 def flush_enum_list_item(self):
280 '''
281 flush an enum list item
282 '''
283 if len(self.current_block) > 1 and self.current_block[-2] == 'Number_list' :
284 num_style = self.enum_prefix_style[-1]
285 self.flush_list_item(num_style[0], start_num=num_style[1][0], enumprefix=num_style[1][1],
286 enumprefixtype=num_style[1][2] )
287 else:
288 self.flush_list_item()
289
290 def flush_list_item(self, typ=-1, enumprefix=None, enumprefixtype=None, start_num=1):
291 '''
292 flush a list item
293 '''
294 dprint()
295 text_list = get_items_list(self.states)
296
297 for i,x in enumerate(text_list) :
298 sty = self.list_style[-1]
299
300 if i == 0 and not self.list_item_flushed :
301 self.docx.list_item(x, sty, self.list_level, typ,
302 enum_prefix=enumprefix, enum_prefix_type=enumprefixtype, start=start_num)
303 self.list_item_flushed=True
304 else:
305 self.docx.list_item(x, sty, self.list_level, 0)
306
307 del self.states
308 self.states = [[]]
309
310 def append_style(self, style):
311 '''
312 append a list style...
313 '''
314 dprint()
315 txt_list = self.states.pop()
316 txt = txt_list.pop()
317 txt_list.append([txt, style])
318 self.states.append(txt_list)
319
320
321 def visit_start_of_file(self, node):
322 '''
323 start of a file
324 '''
325 dprint()
326 self.new_state()
327 self.sectionlevel = 0
328
329 self.docx.pagebreak(type='page', orient='portrait')
330
331 def depart_start_of_file(self, node):
332 '''
333 end of a file
334 '''
335 dprint()
336 self.end_state()
337
338 def visit_document(self, node):
339 '''
340 start of a document
341 '''
342 #print self.builder.env.tocs['index']
343 dprint()
344 self.toc_out=False
345 self.new_state()
346
347 def depart_document(self, node):
348 '''
349 end of a document
350 '''
351 dprint()
352 self.end_state()
353
354 def visit_highlightlang(self, node):
355 '''
356 start of a hight light
357 '''
358 dprint()
359 # raise nodes.SkipNode
360
361 def visit_section(self, node):
362 '''
363 start of a section
364 '''
365 dprint()
366 self.sectionlevel += 1
367
368 def depart_section(self, node):
369 '''
370 end of a section
371 '''
372 dprint()
373 self.ensure_state()
374 if self.sectionlevel > 0:
375 self.sectionlevel -= 1
376
377 def visit_topic(self, node):
378 '''
379 start of a topic (ignore)
380 '''
381 dprint()
382 #raise nodes.SkipNode
383 #self.new_state()
384
385 def depart_topic(self, node):
386 '''
387 end of a topic (ignore)
388 '''
389 dprint()
390 #raise nodes.SkipNode
391 #self.end_state()
392
393 visit_sidebar = visit_topic
394 depart_sidebar = depart_topic
395
396 def visit_rubric(self, node):
397 '''
398 start of a rubric (ignore)
399 '''
400 dprint()
401 #raise nodes.SkipNode
402 #self.new_state()
403 #self.add_text('-[ ')
404
405 def depart_rubric(self, node):
406 '''
407 end of a rubric (ignore)
408 '''
409 dprint()
410 raise nodes.SkipNode
411 #self.add_text(' ]-')
412 #self.end_state()
413
414 def visit_compound(self, node):
415 '''
416 start of a compound (pass a text)
417 '''
418 if not self.toc_out :
419 self.toc_out = True
420 self.ensure_state()
421 maxdepth = get_toc_maxdepth(self.builder, 'index')
422 self.docx.table_of_contents(toc_text=None, maxlevel=maxdepth )
423 dprint()
424 pass
425
426 def depart_compound(self, node):
427 '''
428 end of a compound (pass a text)
429 '''
430 dprint()
431 pass
432
433 def visit_glossary(self, node):
434 '''
435 start of a glossary (pass a text)
436 '''
437 dprint()
438 pass
439
440 def depart_glossary(self, node):
441 '''
442 end of a glossary (pass a text)
443 '''
444 dprint()
445 pass
446
447 def visit_title(self, node):
448 '''
449 start of a title
450 '''
451 dprint()
452 #if isinstance(node.parent, nodes.Admonition):
453 # self.add_text(node.astext()+': ')
454 # raise nodes.SkipNode
455 self.new_state()
456
457 def depart_title(self, node):
458 '''
459 end of a title
460 '''
461 dprint()
462 text = self.states.pop()
463 dprint(_func='* heading', text=repr(text), level=self.sectionlevel)
464
465 if self.table is not None :
466 self.docx.paragraph(text, style='TableHeading')
467 else :
468 self.docx.heading(text, self.sectionlevel)
469
470 def visit_subtitle(self, node):
471 '''
472 start of a subtitle (pass a text)
473 '''
474 dprint()
475 pass
476
477 def depart_subtitle(self, node):
478 '''
479 end of a subtitle (pass a text)
480 '''
481 dprint()
482 pass
483
484 def visit_attribution(self, node):
485 '''
486 start of a attribution (ignore)
487 '''
488 dprint()
489 #raise nodes.SkipNode
490 #self.add_text('-- ')
491
492 def depart_attribution(self, node):
493 '''
494 end of a attribution (ignore)
495 '''
496 dprint()
497 pass
498
499 def visit_desc(self, node):
500 '''
501 start of a desc (pass a text)
502 '''
503 dprint()
504 pass
505
506 def depart_desc(self, node):
507 '''
508 start of a desc (pass a text)
509 '''
510 dprint()
511 pass
512
513 def visit_desc_signature(self, node):
514 '''
515 start of a desc signature (ignore)
516 '''
517 dprint()
518 #raise nodes.SkipNode
519 #self.new_state()
520 #if node.parent['objtype'] in ('class', 'exception'):
521 # self.add_text('%s ' % node.parent['objtype'])
522
523 def depart_desc_signature(self, node):
524 '''
525 end of a desc signature (ignore)
526 '''
527 dprint()
528 #raise nodes.SkipNode
529 ## XXX: wrap signatures in a way that makes sense
530 #self.end_state()
531
532 def visit_desc_name(self, node):
533 '''
534 start of a desc name (pass a text)
535 '''
536 dprint()
537 pass
538
539 def depart_desc_name(self, node):
540 '''
541 end of a desc name (pass a text)
542 '''
543 dprint()
544 pass
545
546 def visit_desc_addname(self, node):
547 '''
548 start of a desc addname (pass a text)
549 '''
550 dprint()
551 pass
552
553 def depart_desc_addname(self, node):
554 '''
555 end of a desc addname (pass a text)
556 '''
557 dprint()
558 pass
559
560 def visit_desc_type(self, node):
561 '''
562 start of a desc type (pass a text)
563 '''
564 dprint()
565 pass
566
567 def depart_desc_type(self, node):
568 '''
569 end of a desc type (pass a text)
570 '''
571 dprint()
572 pass
573
574 def visit_desc_returns(self, node):
575 '''
576 start of a desc returns (ignore)
577 '''
578 dprint()
579 #raise nodes.SkipNode
580 #self.add_text(' -> ')
581
582 def depart_desc_returns(self, node):
583 '''
584 end of a desc returns (ignore)
585 '''
586 dprint()
587 pass
588
589 def visit_desc_parameterlist(self, node):
590 dprint()
591 #raise nodes.SkipNode
592 #self.add_text('(')
593 #self.first_param = 1
594
595 def depart_desc_parameterlist(self, node):
596 dprint()
597 #raise nodes.SkipNode
598 #self.add_text(')')
599
600 def visit_desc_parameter(self, node):
601 dprint()
602 #raise nodes.SkipNode
603 #if not self.first_param:
604 # self.add_text(', ')
605 #else:
606 # self.first_param = 0
607 #self.add_text(node.astext())
608 ##raise nodes.SkipNode
609
610 def visit_desc_optional(self, node):
611 dprint()
612 #raise nodes.SkipNode
613 #self.add_text('[')
614
615 def depart_desc_optional(self, node):
616 dprint()
617 #raise nodes.SkipNode
618 #self.add_text(']')
619
620 def visit_desc_annotation(self, node):
621 dprint()
622 pass
623
624 def depart_desc_annotation(self, node):
625 dprint()
626 pass
627
628 def visit_refcount(self, node):
629 dprint()
630 pass
631
632 def depart_refcount(self, node):
633 dprint()
634 pass
635
636 def visit_desc_content(self, node):
637 dprint()
638 #raise nodes.SkipNode
639 #self.new_state()
640 #self.add_text('\n')
641
642 def depart_desc_content(self, node):
643 dprint()
644 #raise nodes.SkipNode
645 #self.end_state()
646
647 def visit_figure(self, node):
648 # FIXME: figure text become normal paragraph instead of caption.
649 dprint()
650 self.new_state()
651
652 def depart_figure(self, node):
653 dprint()
654 self.end_state()
655
656 def visit_caption(self, node):
657 dprint()
658 pass
659
660 def depart_caption(self, node):
661 self.flush_state('ImageCaption')
662 dprint()
663 pass
664
665 def visit_productionlist(self, node):
666 dprint()
667 #raise nodes.SkipNode
668 #self.new_state()
669 #names = []
670 #for production in node:
671 # names.append(production['tokenname'])
672 #maxlen = max(len(name) for name in names)
673 #for production in node:
674 # if production['tokenname']:
675 # self.add_text(production['tokenname'].ljust(maxlen) + ' ::=')
676 # lastname = production['tokenname']
677 # else:
678 # self.add_text('%s ' % (' '*len(lastname)))
679 # self.add_text(production.astext() + '\n')
680 #self.end_state()
681 ##raise nodes.SkipNode
682
683 def visit_seealso(self, node):
684 dprint()
685 self.new_state()
686
687 def depart_seealso(self, node):
688 dprint()
689 self.end_state(first='')
690
691 def visit_footnote(self, node):
692 dprint()
693 #raise nodes.SkipNode
694 #self._footnote = node.children[0].astext().strip()
695 #self.new_state()
696
697 def depart_footnote(self, node):
698 dprint()
699 #raise nodes.SkipNode
700 #self.end_state(first='[%s] ' % self._footnote)
701
702 def visit_citation(self, node):
703 dprint()
704 #raise nodes.SkipNode
705 #if len(node) and isinstance(node[0], nodes.label):
706 # self._citlabel = node[0].astext()
707 #else:
708 # self._citlabel = ''
709 #self.new_state()
710
711 def depart_citation(self, node):
712 dprint()
713 #raise nodes.SkipNode
714 #self.end_state(first='[%s] ' % self._citlabel)
715
716 def visit_label(self, node):
717 dprint()
718 #raise nodes.SkipNode
719
720 # XXX: option list could use some better styling
721
722 def visit_option_list(self, node):
723 dprint()
724 pass
725
726 def depart_option_list(self, node):
727 dprint()
728 pass
729
730 def visit_option_list_item(self, node):
731 dprint()
732 #raise nodes.SkipNode
733 #self.new_state()
734
735 def depart_option_list_item(self, node):
736 dprint()
737 #raise nodes.SkipNode
738 #self.end_state()
739
740 def visit_option_group(self, node):
741 dprint()
742 #raise nodes.SkipNode
743 #self._firstoption = True
744
745 def depart_option_group(self, node):
746 dprint()
747 #raise nodes.SkipNode
748 #self.add_text(' ')
749
750 def visit_option(self, node):
751 dprint()
752 #raise nodes.SkipNode
753 #if self._firstoption:
754 # self._firstoption = False
755 #else:
756 # self.add_text(', ')
757
758 def depart_option(self, node):
759 dprint()
760 pass
761
762 def visit_option_string(self, node):
763 dprint()
764 pass
765
766 def depart_option_string(self, node):
767 dprint()
768 pass
769
770 def visit_option_argument(self, node):
771 dprint()
772 #raise nodes.SkipNode
773 #self.add_text(node['delimiter'])
774
775 def depart_option_argument(self, node):
776 dprint()
777 pass
778
779 def visit_description(self, node):
780 dprint()
781 pass
782
783 def depart_description(self, node):
784 dprint()
785 pass
786
787 def visit_tabular_col_spec(self, node):
788 dprint()
789 #raise nodes.SkipNode
790
791 def visit_colspec(self, node):
792 dprint()
793 self.table[0].append(node['colwidth'])
794
795 def depart_colspec(self, node):
796 dprint()
797
798 def visit_tgroup(self, node):
799 dprint()
800 pass
801
802 def depart_tgroup(self, node):
803 dprint()
804 pass
805
806 def visit_thead(self, node):
807 dprint()
808 pass
809
810 def depart_thead(self, node):
811 dprint()
812 pass
813
814 def visit_tbody(self, node):
815 dprint()
816 self.table.append('sep')
817
818 def depart_tbody(self, node):
819 dprint()
820 pass
821
822 def visit_row(self, node):
823 dprint()
824 self.table.append([])
825
826 def depart_row(self, node):
827 dprint()
828 pass
829
830 def visit_entry(self, node):
831 dprint()
832 if 'morerows' in node or 'morecols' in node:
833 raise NotImplementedError('Column or row spanning cells are '
834 'not implemented.')
835 self.new_state()
836
837 def depart_entry(self, node):
838 dprint()
839 text = self.states.pop()
840 #text = '\n'.join('\n'.join(x) for x in self.states.pop())
841 self.table[-1].append(text)
842
843 def visit_table(self, node):
844 dprint()
845 if self.table:
846 raise NotImplementedError('Nested tables are not supported.')
847 self.new_state()
848 self.table = [[]]
849
850 def depart_table(self, node):
851 dprint()
852 colsize_chars = self.table[0]
853 colsize = []
854 for i,x in enumerate(colsize_chars):
855 colsize.append( int(x)*110 )
856
857 lines = self.table[1:]
858 fmted_rows = []
859
860 # don't allow paragraphs in table cells for now
861 for line in lines:
862 if line == 'sep':
863 pass
864 else:
865 fmted_rows.append(line)
866
867 self.docx.table(fmted_rows, colsize)
868 self.docx.paragraph("")
869 self.table = None
870 self.end_state()
871
872 def visit_acks(self, node):
873 dprint()
874 #raise nodes.SkipNode
875 #self.new_state()
876 #self.add_text(', '.join(n.astext() for n in node.children[0].children)
877 # + '.')
878 #self.end_state()
879 #raise nodes.SkipNode
880
881 def visit_image(self, node):
882 dprint()
883 self.flush_state()
884 dprint(_func=' image ', uri=node.attributes['uri'])
885 uri = node.attributes['uri']
886 file_path = os.path.join(self.builder.env.srcdir, uri)
887 width, height = self.get_image_scaled_width_height(node, file_path)
888
889 self.docx.picture(file_path, '',width,height)
890
891 def depart_image(self, node):
892 dprint()
893
894 def get_image_width_height(self, node, attr):
895 size = None
896 if attr in node.attributes:
897 size = node.attributes[attr]
898 if size[-1] == '%' :
899 size = float(size[:-1])
900 size = [size, '%']
901 else:
902 unit = size[-2:]
903 if unit.isalpha():
904 size = size[:-2]
905 else:
906 unit = 'px'
907 try:
908 size = float(size)
909 except ValueError, e:
910 self.document.reporter.warning(
911 'Invalid %s for image: "%s"' % (
912 attr, node.attributes[attr]))
913 size = [size, unit]
914 return size
915
916 def get_image_scale(self, node):
917 if 'scale' in node.attributes:
918 try:
919 scale = int(node.attributes['scale'])
920 if scale < 1: # or scale > 100:
921 self.document.reporter.warning(
922 'scale out of range (%s), using 1.' % (scale, ))
923 scale = 1
924 scale = scale * 0.01
925 except ValueError, e:
926 self.document.reporter.warning(
927 'Invalid scale for image: "%s"' % (
928 node.attributes['scale'], ))
929 else:
930 scale = 1.0
931 return scale
932
933 def get_image_scaled_width_height(self, node, filename):
934 dpi = (72, 72)
935
936 if Image is not None :
937 try:
938 imageobj = Image.open(filename, 'r')
939 except:
940 raise RuntimeError('Fail to open image file: %s' % filename)
941
942 dpi = imageobj.info.get('dpi', dpi)
943 # dpi information can be (xdpi, ydpi) or xydpi
944 try: iter(dpi)
945 except: dpi = (dpi, dpi)
946 else:
947 imageobj = None
948 raise RuntimeError('image size not fully specified and PIL not installed')
949
950 scale = self.get_image_scale(node)
951 width = self.get_image_width_height(node, 'width')
952 height = self.get_image_width_height(node, 'height')
953
954 if width is not None and width[1] == '%':
955 width = [int(self.docx.styleDocx.document_width * width[0] * 0.00284 ), 'px']
956
957 if height is not None and height[1] == '%':
958 height = [int(self.docx.styleDocx.document_height * height[0] * 0.00284 ), 'px']
959
960 if width is None or height is None:
961 if imageobj is None:
962 raise RuntimeError(
963 'image size not fully specified and PIL not installed')
964 if width is None:
965 if height is None:
966 width = [imageobj.size[0], 'px']
967 height = [imageobj.size[1], 'px']
968 else:
969 scaled_width = imageobj.size[0] * height[0] /imageobj.size[1]
970 width = [scaled_width, 'px']
971 else:
972 if height is None:
973 scaled_height = imageobj.size[1] * width[0] / imageobj.size[0]
974 height = [scaled_height, 'px']
975 else:
976 height = [imageobj.size[1], 'px']
977
978 width[0] *= scale
979 height[0] *= scale
980 if width[1] == 'in': width = [width[0] * dip[0], 'px']
981 if height[1] == 'in': height = [height[0] *dip[1], 'px']
982
983 # Why we should shrink image size....
984 width[0] *= 0.77
985 height[0] *= 0.77
986
987 #
988 maxwidth = int(self.docx.styleDocx.document_width * 0.284 )
989
990 if width[0] > maxwidth :
991 ratio = height[0] / width[0]
992 width[0] = maxwidth
993 height[0] = width[0] * ratio
994
995 maxheight = int(self.docx.styleDocx.document_width * 0.284 )
996 if height[0] > maxheight :
997 ratio = width[0] / height[0]
998 height[0] = maxheight
999 width[0] = height[0] * ratio
1000
1001 return int(width[0]), int(height[0])
1002
1003 def visit_transition(self, node):
1004 dprint()
1005 #raise nodes.SkipNode
1006 #self.new_state()
1007 #self.add_text('=' * 70)
1008 #self.end_state()
1009
1010 def visit_bullet_list(self, node):
1011 dprint()
1012 self.new_state()
1013 self.flush_state()
1014
1015 self.current_block.append('Bullet_list')
1016 self.list_level += 1
1017 self.list_style.append('ListBullet')
1018
1019 def depart_bullet_list(self, node):
1020 dprint()
1021 self.current_block.pop()
1022 self.list_style.pop()
1023 self.list_level -= 1
1024
1025 def visit_enumerated_list(self, node):
1026 dprint()
1027
1028 if self.flush_state() :
1029 self.num_list_id += 1
1030
1031 self.new_state()
1032 suffix=""
1033 prefix=""
1034 enumtype="arabic"
1035 start=1
1036 try:
1037 enumtype=node['enumtype']
1038 suffix=node['suffix']
1039 prefix=node['prefix']
1040 except:
1041 pass
1042 try:
1043 start=node['start']
1044 except:
1045 pass
1046 self.enumprefix = "%s%%1%s" % (prefix,suffix)
1047 self.enumprefix_type = enumtype
1048 self.start_num = start
1049
1050 if self.current_block.count('Number_list') == 0 :
1051 self.num_list_id = self.max_num_list_id+1
1052
1053 self.enum_prefix_style.append([self.num_list_id, [self.start_num, self.enumprefix, self.enumprefix_type]])
1054 self.current_block.append('Number_list')
1055 self.list_style.append('ListNumber')
1056 self.list_level += 1
1057 self.max_num_list_id += 1
1058
1059 def depart_enumerated_list(self, node):
1060 dprint()
1061 if self.current_block :
1062 self.current_block.pop()
1063 self.enum_prefix_style.pop()
1064 self.list_style.pop()
1065 self.list_level -= 1
1066 self.num_list_id -= 1
1067
1068 def visit_definition_list(self, node):
1069 self.flush_state()
1070 dprint()
1071 ##raise nodes.SkipNode
1072 #self.list_style.append(-2)
1073
1074 def depart_definition_list(self, node):
1075 dprint()
1076 ##raise nodes.SkipNode
1077 #self.list_style.pop()
1078
1079 def visit_list_item(self, node):
1080 dprint()
1081 self.list_item_flushed=False
1082 self.current_block.append('List_item')
1083 self.new_state()
1084
1085 def depart_list_item(self, node):
1086 dprint()
1087 self.flush_state(_sty='List_item')
1088 if self.current_block :
1089 self.current_block.pop()
1090
1091 def visit_definition_list_item(self, node):
1092 dprint()
1093 self.flush_state()
1094
1095
1096 def depart_definition_list_item(self, node):
1097 dprint()
1098 self.flush_state()
1099 pass
1100
1101 def visit_term(self, node):
1102 dprint()
1103 self.flush_state()
1104 self.new_state()
1105
1106 def depart_term(self, node):
1107 dprint()
1108 self.flush_state('DefinitionTerm')
1109
1110 def visit_classifier(self, node):
1111 dprint()
1112 #raise nodes.SkipNode
1113 #self.add_text(' : ')
1114
1115 def depart_classifier(self, node):
1116 dprint()
1117 #raise nodes.SkipNode
1118 #self.end_state()
1119
1120 def visit_definition(self, node):
1121 dprint()
1122 self.flush_state()
1123 self.block_level += 1
1124
1125 def depart_definition(self, node):
1126 dprint()
1127 self.flush_state()
1128 self.block_level -= 1
1129
1130 def visit_field_list(self, node):
1131 dprint()
1132 pass
1133
1134 def depart_field_list(self, node):
1135 dprint()
1136 pass
1137
1138 def visit_field(self, node):
1139 self.flush_state()
1140 dprint()
1141 pass
1142
1143 def depart_field(self, node):
1144 dprint()
1145 pass
1146
1147 def visit_field_name(self, node):
1148 dprint()
1149 #raise nodes.SkipNode
1150 #self.new_state()
1151
1152 def depart_field_name(self, node):
1153 dprint()
1154 self.field_name = self.states.pop()[0]
1155 #raise nodes.SkipNode
1156 #self.add_text(':')
1157 #self.end_state()
1158
1159 def visit_field_body(self, node):
1160 dprint()
1161 #raise nodes.SkipNode
1162 #self.new_state()
1163
1164 def depart_field_body(self, node):
1165 dprint()
1166 registerd_style = ['Vendor','Version','Category' ]
1167
1168 if self.field_name in registerd_style :
1169 self.states[-1].insert(0, self.field_name+': ')
1170 style= "rst"+self.field_name
1171 else:
1172 self.states[-1].insert(0, ":"+self.field_name+":")
1173 style=None
1174
1175 self.flush_state(style)
1176 self.field_name = None
1177
1178 #raise nodes.SkipNode
1179 #self.end_state()
1180
1181 def visit_centered(self, node):
1182 dprint()
1183 pass
1184
1185 def depart_centered(self, node):
1186 dprint()
1187 pass
1188
1189 def visit_hlist(self, node):
1190 dprint()
1191 pass
1192
1193 def depart_hlist(self, node):
1194 dprint()
1195 pass
1196
1197 def visit_hlistcol(self, node):
1198 dprint()
1199 pass
1200
1201 def depart_hlistcol(self, node):
1202 dprint()
1203 pass
1204
1205 def visit_admonition(self, node):
1206 dprint()
1207 self.flush_state()
1208 #raise nodes.SkipNode
1209 #self.new_state()
1210
1211 def depart_admonition(self, node):
1212 dprint()
1213 #raise nodes.SkipNode
1214 #self.end_state()
1215
1216 def _visit_admonition(self, node):
1217 dprint()
1218 self.flush_state()
1219 self.current_block.append('Admonition')
1220 #raise nodes.SkipNode
1221 #self.new_state()
1222
1223 def _make_depart_admonition(name):
1224 def depart_admonition(self, node):
1225 dprint()
1226 #raise nodes.SkipNode
1227 #self.end_state(first=admonitionlabels[name] + ': ')
1228 self.current_block.remove('Admonition')
1229 self.states.insert(0, [[admonitionlabels[name] + ': ', 'label-'+name]])
1230 self.flush_state('Admonition-'+name)
1231 return depart_admonition
1232
1233 visit_attention = _visit_admonition
1234 depart_attention = _make_depart_admonition('attention')
1235 visit_caution = _visit_admonition
1236 depart_caution = _make_depart_admonition('caution')
1237 visit_danger = _visit_admonition
1238 depart_danger = _make_depart_admonition('danger')
1239 visit_error = _visit_admonition
1240 depart_error = _make_depart_admonition('error')
1241 visit_hint = _visit_admonition
1242 depart_hint = _make_depart_admonition('hint')
1243 visit_important = _visit_admonition
1244 depart_important = _make_depart_admonition('important')
1245 visit_note = _visit_admonition
1246 depart_note = _make_depart_admonition('note')
1247 visit_tip = _visit_admonition
1248 depart_tip = _make_depart_admonition('tip')
1249 visit_warning = _visit_admonition
1250 depart_warning = _make_depart_admonition('warning')
1251
1252 def visit_versionmodified(self, node):
1253 dprint()
1254 #raise nodes.SkipNode
1255 #self.new_state()
1256 #if node.children:
1257 # self.add_text(
1258 # versionlabels[node['type']] % node['version'] + ': ')
1259 #else:
1260 # self.add_text(
1261 # versionlabels[node['type']] % node['version'] + '.')
1262
1263 def depart_versionmodified(self, node):
1264 dprint()
1265 #raise nodes.SkipNode
1266 #self.end_state()
1267
1268 def visit_literal_block(self, node):
1269 # FIXME: working but broken.
1270 dprint()
1271 self.flush_state()
1272 self.new_state()
1273
1274 def depart_literal_block(self, node):
1275 dprint()
1276 self.flush_state(_sty='LiteralBlock')
1277 self.end_state()
1278
1279 def visit_doctest_block(self, node):
1280 dprint()
1281 #raise nodes.SkipNode
1282 #self.new_state()
1283
1284 def depart_doctest_block(self, node):
1285 dprint()
1286 #raise nodes.SkipNode
1287 #self.end_state()
1288
1289 def visit_line_block(self, node):
1290 dprint()
1291 self.line_block_level += 1
1292 #raise nodes.SkipNode
1293 #self.new_state()
1294
1295 def depart_line_block(self, node):
1296 dprint()
1297 self.line_block_level -= 1
1298 #self.flush_state(True)
1299 #raise nodes.SkipNode
1300 #self.end_state()
1301
1302 def visit_line(self, node):
1303 dprint()
1304 if self.line_block_level > 0 :
1305 for n in range(0,self.line_block_level):
1306 self.add_text(' ')
1307 pass
1308
1309 def depart_line(self, node):
1310 dprint()
1311 self.add_linebreak()
1312 #self.flush_state(True)
1313 pass
1314
1315 def visit_block_quote(self, node):
1316 # FIXME: working but broken.
1317 dprint()
1318 self.flush_state()
1319 self.list_level += 1
1320 self.block_level += 1
1321 self.new_state()
1322
1323 def depart_block_quote(self, node):
1324 dprint()
1325 self.list_level -= 1
1326 self.flush_state()
1327 self.block_level -= 1
1328 self.end_state()
1329
1330 def visit_compact_paragraph(self, node):
1331 dprint()
1332 pass
1333
1334 def depart_compact_paragraph(self, node):
1335 dprint()
1336 pass
1337
1338 def visit_paragraph(self, node):
1339 dprint()
1340 self.new_state()
1341 #self.ensure_state()
1342 #if not isinstance(node.parent, nodes.Admonition) or \
1343 # isinstance(node.parent, addnodes.seealso):
1344 # self.new_state()
1345
1346 def depart_paragraph(self, node):
1347 dprint()
1348 #self.ensure_state()
1349 #if not isinstance(node.parent, nodes.Admonition) or \
1350 # isinstance(node.parent, addnodes.seealso):
1351 # self.end_state()
1352
1353 def visit_target(self, node):
1354 dprint()
1355 #raise nodes.SkipNode
1356
1357 def visit_index(self, node):
1358 dprint()
1359 #raise nodes.SkipNode
1360
1361 def visit_substitution_definition(self, node):
1362 dprint()
1363 #raise nodes.SkipNode
1364
1365 def visit_pending_xref(self, node):
1366 dprint()
1367 pass
1368
1369 def depart_pending_xref(self, node):
1370 dprint()
1371 pass
1372
1373 def visit_reference(self, node):
1374 dprint()
1375 pass
1376
1377 def depart_reference(self, node):
1378 dprint()
1379 pass
1380
1381 def visit_download_reference(self, node):
1382 dprint()
1383 pass
1384
1385 def depart_download_reference(self, node):
1386 dprint()
1387 pass
1388
1389 def visit_emphasis(self, node):
1390 dprint()
1391 #print node.astext()
1392 #self.add_text('*')
1393
1394 def depart_emphasis(self, node):
1395 dprint()
1396 self.append_style('Emphasis')
1397 #self.add_text('*')
1398
1399 def visit_literal_emphasis(self, node):
1400 dprint()
1401 #print "literal_emphasis"
1402 #self.add_text('*')
1403
1404 def depart_literal_emphasis(self, node):
1405 dprint()
1406 self.append_style('LiteralEmphasise')
1407 #self.add_text('*')
1408
1409 def visit_strong(self, node):
1410 dprint()
1411
1412 def depart_strong(self, node):
1413 dprint()
1414 self.append_style('Strong')
1415
1416 def visit_abbreviation(self, node):
1417 dprint()
1418 #self.add_text('')
1419
1420 def depart_abbreviation(self, node):
1421 dprint()
1422 self.append_style('Abbreviation')
1423 #if node.hasattr('explanation'):
1424 # self.add_text(' (%s)' % node['explanation'])
1425
1426 def visit_title_reference(self, node):
1427 dprint()
1428 #self.add_text('*')
1429
1430 def depart_title_reference(self, node):
1431 dprint()
1432 self.append_style('TitleReference')
1433 #self.add_text('*')
1434
1435 def visit_literal(self, node):
1436 dprint()
1437 #self.add_text('``')
1438
1439 def depart_literal(self, node):
1440 dprint()
1441 self.append_style('Literal')
1442 #self.add_text('``')
1443
1444 def visit_subscript(self, node):
1445 dprint()
1446 #raise nodes.SkipNode
1447 #self.add_text('_')
1448
1449 def depart_subscript(self, node):
1450 dprint()
1451 self.append_style('Subscript')
1452 pass
1453
1454 def visit_superscript(self, node):
1455 dprint()
1456 #raise nodes.SkipNode
1457 #self.add_text('^')
1458
1459 def depart_superscript(self, node):
1460 dprint()
1461 self.append_style('Superscript')
1462 pass
1463
1464 def visit_footnote_reference(self, node):
1465 dprint()
1466 #raise nodes.SkipNode
1467 #self.add_text('[%s]' % node.astext())
1468
1469 def visit_citation_reference(self, node):
1470 dprint()
1471 #raise nodes.SkipNode
1472 #self.add_text('[%s]' % node.astext())
1473
1474 def visit_Text(self, node):
1475 dprint()
1476 self.add_text(node.astext())
1477
1478 def depart_Text(self, node):
1479 dprint()
1480 pass
1481
1482 def visit_generated(self, node):
1483 dprint()
1484 pass
1485
1486 def depart_generated(self, node):
1487 dprint()
1488 pass
1489
1490 def visit_inline(self, node):
1491 classes = node.get('classes', [])
1492 dprint()
1493 pass
1494
1495 def depart_inline(self, node):
1496 dprint()
1497 pass
1498
1499 def visit_problematic(self, node):
1500 dprint()
1501
1502 def depart_problematic(self, node):
1503 dprint()
1504 self.append_style('Problematic')
1505
1506 def visit_system_message(self, node):
1507 dprint()
1508 raise nodes.SkipNode
1509 #self.new_state()
1510 #self.add_text('<SYSTEM MESSAGE: %s>' % node.astext())
1511 #self.end_state()
1512
1513 def visit_comment(self, node):
1514 dprint()
1515 raise nodes.SkipNode
1516
1517 def visit_meta(self, node):
1518 dprint()
1519 raise nodes.SkipNode
1520 # only valid for HTML
1521
1522 def visit_raw(self, node):
1523 dprint()
1524 raise nodes.SkipNode
1525 #if 'text' in node.get('format', '').split():
1526 # self.body.append(node.astext())
1527
1528 def visit_graphviz(self, node):
1529 dprint()
1530 raise nodes.SkipNode
1531
1532 def depart_graphviz(self, node):
1533 dprint()
1534 raise nodes.SkipNode
1535
1536 def unknown_visit(self, node):
1537 dprint()
1538 raise nodes.SkipNode
1539 #raise NotImplementedError('Unknown node: ' + node.__class__.__name__)

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26