2 # Contact: bilbo@hobbit-hole.org
5 # Copyright: This module is copyright 2007 by Jay Kint, licensed under the BSD License.
8 WordML writer for Docutils. WordML is the XML format for MS Word documents.
10 The output conforms to basic WordML and can be read by MS Word to be output in any of the formats it supports
13 The way it works is that it uses a template file *(default template.xml)* and looks for the <w:rest /> node
14 for where to insert the generated WordML. This allows you to save a preformatted template with the formatting
15 you want (e.g., styles, fonts, paper size).
19 - Mixing bulleted lists and enumerated lists doesn't work quite the same way that MS Word does it. It works,
20 but the output isn't the same as if you'd typed it in Word.
22 - You can't mix paper types. That stands to reason, but it's still a limitation.
24 - Titles and subtitles are only allowed up to 3 levels for now.
26 Of course, there's nothing to prevent you from loading up the generated file and
27 fixing these things yourself in MS Word.
31 __docformat__
= 'reStructuredText'
36 from docutils
import frontend
, writers
, nodes
, utils
, languages
37 import xml
.parsers
.expat
38 from xml
.etree
.ElementTree
import TreeBuilder
, dump
, tostring
45 class Writer(writers
.Writer
):
47 supported
= ('wordml',)
48 """Formats this writer supports."""
50 default_template
= 'template.xml'
52 default_template_path
= utils
.relative_path(
53 os
.path
.join(os
.getcwd(), 'dummy'),
54 os
.path
.join(os
.path
.dirname(__file__
), default_template
))
57 '"Docutils WordML" Writer Options',
59 (('Specify the template file (UTF-8 encoded). Default is "%s".'
60 % default_template_path
,
62 {'default': default_template_path
, 'metavar': '<file>'}),))
64 settings_defaults
= {'output-encoding-error-handler': 'xmlcharrefreplace'}
66 config_section
= 'docutils_wordml writer'
67 config_section_dependencies
= ('writers',)
70 writers
.Writer
.__init
__(self
)
71 self
.translator_class
= WordMLTranslator
74 self
.visitor
= visitor
= self
.translator_class(self
.document
)
75 self
.document
.walkabout(visitor
)
76 self
.output
= visitor
.astext()
79 class TextNoEncoding(nodes
.Text
):
81 """A text node that is meant to take its contents literally and not
84 def __init__( self
, data
, rawsource
=''):
85 nodes
.Text
.__init
__( self
, data
, rawsource
)
88 class TextWithStyle( nodes
.Text
):
90 """A text node that has an attached style."""
92 def __init__( self
, data
, style
, rawsource
='' ):
93 nodes
.Text
.__init
__( self
, data
, rawsource
)
96 # contain an xml tag within a region (with styles if needed)
97 class XMLRegion( nodes
.General
, nodes
.Element
): pass
100 class WordMLTranslator(nodes
.NodeVisitor
):
103 This WordML writer handles most of the features for now, You can get the gist of it rather easily. It's not nearly
104 as complicated as the HTML writer, surprisingly.
107 title_styles
= [ "Heading1", "Heading2", "Heading3" ]
110 # these are meant to be default lists, one for bullet and one for enumerated.
111 # other list types should be added here later.
113 def __init__(self
, document
):
114 nodes
.NodeVisitor
.__init
__(self
, document
)
115 self
.document
= document
117 self
.body
= [] # the body of the document
118 self
.in_docinfo
= None
119 self
.in_sidebar
= None
120 self
.settings
= settings
= document
.settings
121 self
.section_level
= 0
123 self
.text_properties
= {} # the list of properties for a run of test
124 self
.text_prefix
= [] # text or commands inserted before next text run
125 self
.paragraph_properties
= {}
128 self
.no_text
= 0 # flag to suppress any text output
129 self
.literal_text
= 0 # flag to output newlines in text
130 self
.skip_encode
= 0 # flag to skip the encoding of text to xml friendly output
131 self
.has_text_output
= 0 # flag if any text output since last reset
132 self
.figure_count
= 0
135 # list related variables
139 self
.list_properties
= []
141 self
.template_list_defs
= []
142 self
.current_listdef
= []
144 self
.show_list_properties
= 0
145 self
.extract_listdefs()
146 self
.substitutions
= {}
147 # table related variables
152 self
.spans
= {} # for multispan columns and rows
153 self
.total_col_width
= 0
154 # xml output variables
155 self
.doc_tree
= TreeBuilder()
156 self
.doc_tree
.start( 'w:document', {} )
165 def template_start_element( self
, name
, attr
):
167 self
.doc_tree
.end( 'w:document' )
168 tree
= self
.doc_tree
.close()
169 doc_string
= tostring( tree
)
170 p
= xml
.parsers
.expat
.ParserCreate();
171 p
.StartElementHandler
= self
.body_start_element
172 p
.EndElementHandler
= self
.body_end_element
173 p
.CharacterDataHandler
= self
.body_data
174 p
.Parse( doc_string
)
175 # for b in self.body:
177 elif name
== 'w:rstlists':
180 elif name
== 'w:rstlistdefs':
181 for l
in self
.list_defs
:
184 self
.doc
+= "<" + name
+ " "
185 for k
, v
in attr
.iteritems():
186 self
.doc
+= k
+ '="' + v
+ '" '
190 def template_end_element( self
, name
):
191 if name
== 'w:rest' or name
== 'w:rstlists' or name
== 'w:rstlistdefs':
194 self
.doc
+= '</' + name
+ '>'
197 def template_char_data( self
, data
):
201 # routines for extracting the listdef elements from the template
202 def start_listdef_extract( self
, name
, attr
):
203 if name
== 'w:listDef':
205 self
.current_listdef
= []
208 if self
.in_listdef
== 1:
209 self
.current_listdef
.append( [ name
, attr
] )
212 def end_listdef_extract( self
, name
):
213 self
.current_listdef
.append( [ "/" + name
] )
214 if name
== 'w:listDef':
215 self
.template_list_defs
.append( self
.current_listdef
)
220 def list_def_data( self
, data
):
224 def extract_listdefs( self
):
225 p
= xml
.parsers
.expat
.ParserCreate();
226 p
.StartElementHandler
= self
.start_listdef_extract
227 p
.EndElementHandler
= self
.end_listdef_extract
228 p
.CharacterDataHandler
= self
.list_def_data
229 template
= file( self
.document
.settings
.template
)
230 p
.ParseFile( template
)
233 def listdef_to_xml( self
, list_number
, level
, start
, nfc
):
234 """Modify a listdef to include an alternate numbering scheme and new starting number.
235 Then convert it to XML and return the XML string."""
238 for x
in self
.template_list_defs
[ list_number
]:
239 # change the listDefId to match the new list
240 if x
[0] == 'w:listDef':
241 x
[1]['w:listDefId'] = str( self
.list_count
+ 1 )
242 # get the level if it has changed
244 lvl
= int( x
[1]['w:ilvl'] )
245 # skip an existing nfc node
246 if ( x
[0] == 'w:nfc' or x
[0] == '/w:nfc' ) and level
== lvl
:
248 xml
+= '<' + x
[0] + ' '
250 for k
, v
in x
[1].iteritems():
251 if x
[0] == 'w:start' and k
== 'w:val' and lvl
== level
:
252 xml
+= k
+ '="' + str( start
) + '" '
254 xml
+= k
+ '="' + v
+ '" '
256 # add in our nfc node right after the start node
257 if x
[0] == '/w:start' and level
== lvl
:
258 xml
+= '<w:nfc w:val="' + str( nfc
) + '" />\n'
262 def body_start_element( self
, name
, attr
):
263 if name
== 'w:document':
265 element
= self
.xml_spaces
[ 0 : self
.xml_spacing
] + "<" + name
+ " "
266 for k
, v
in attr
.iteritems():
267 element
+= k
+ '="' + v
+ '" '
268 element
= element
[:-1]
272 self
.xml_spacing
+= 2
276 def body_end_element( self
, name
):
277 if name
== 'w:document':
279 self
.xml_spacing
-= 2
282 element
+= self
.xml_spaces
[ 0 : self
.xml_spacing
]
283 element
+= '</' + name
+ '>\n'
286 def body_data( self
, data
):
290 def check_for_span( self
, col
, row
):
291 check_span
= '{' + str( col
) + ',' + str( row
) + '}'
292 if self
.spans
.has_key( check_span
):
293 self
.doc_tree
.start( 'w:tc', {} )
294 self
.doc_tree
.start( 'w:tcPr', {} )
295 self
.doc_tree
.start( 'w:tcW', { 'w' : str( self
.calc_col_pct( self
.col
)), 'w:type' : 'pct' })
296 self
.doc_tree
.start( self
.spans
[ check_span
][0], self
.spans
[ check_span
][1] )
297 self
.doc_tree
.end( self
.spans
[ check_span
][0] )
298 self
.doc_tree
.end( 'w:tcW' )
299 self
.doc_tree
.end( 'w:tcPr' )
300 self
.doc_tree
.start( 'w:p', {} )
301 self
.doc_tree
.end( 'w:p' )
302 self
.doc_tree
.end( 'w:tc' )
303 self
.body
.append( '<w:tc>\n <w:tcPr>\n <w:tcW w="' + str( self
.calc_col_pct( col
)) + '" w:type="pct" />\n <' + self
.spans
[ check_span
][0] + ' />\n </w:tcPr>\n <w:p />\n</w:tc>\n' )
309 p
= xml
.parsers
.expat
.ParserCreate();
310 p
.StartElementHandler
= self
.template_start_element
311 p
.EndElementHandler
= self
.template_end_element
312 p
.CharacterDataHandler
= self
.template_char_data
313 template
= file( self
.document
.settings
.template
)
314 p
.ParseFile( template
)
318 def encode(self
, text
):
319 """Encode special characters in `text` & return."""
320 text
= text
.replace("&", "&")
321 text
= text
.replace("<", "<")
322 text
= text
.replace('"', """)
323 text
= text
.replace(">", ">")
324 if self
.literal_text
== 1:
325 text
= text
.replace( "\n", "</w:t><w:br /><w:t>" )
327 text
= text
.replace("\n", " " )
331 def visit_Text(self
, node
):
332 # if we have turned off text input, then just return
335 # skip encode allows us to inject custom wordml as a text node without
336 self
.doc_tree
.start( 'w:r', {} )
337 self
.body
.append( "<w:r>" )
338 if len( self
.text_properties
) > 0:
339 self
.doc_tree
.start( 'w:rPr', {} )
340 self
.body
.append( "<w:rPr>\n" )
341 for v
in self
.text_properties
.values():
342 if type( v
) == type( () ):
343 element
= '<' + v
[0] + ' '
344 for k
,a
in v
[1].iteritems():
345 element
+= k
+ '="' + a
+ '" '
347 self
.doc_tree
.start( v
[0], v
[1] )
348 self
.doc_tree
.end( v
[0] )
349 self
.body
.append( element
)
351 self
.body
.append( v
)
352 self
.doc_tree
.end( 'w:rPr' )
353 self
.body
.append( "</w:rPr>\n" )
354 self
.doc_tree
.start( 'w:t', {} )
355 self
.body
.append( "<w:t>" )
357 encoded
= self
.encode(text
)
358 self
.doc_tree
.data( encoded
)
359 self
.body
.append(encoded
)
360 self
.has_text_output
= 1
363 def depart_Text(self
, node
):
364 # if we have turned off text input, then just return
367 self
.doc_tree
.end( 'w:t' )
368 self
.doc_tree
.end( 'w:r' )
369 self
.body
.append( "</w:t></w:r>\n" )
372 def visit_TextNoEncoding( self
, node
):
375 self
.doc_tree
.data( node
.astext() )
376 self
.body
.append( node
.astext() )
379 def depart_TextNoEncoding( self
, node
):
383 def visit_TextWithStyle( self
, node
):
384 self
.text_properties
[ node
.style
[0] ] = node
.style
[1]
385 self
.visit_Text( node
)
388 def depart_TextWithStyle( self
, node
):
389 del self
.text_properties
[ node
.style
[0] ]
390 self
.depart_Text( node
)
393 def visit_abbreviation(self
, node
):
397 def depart_abbreviation(self
, node
):
401 def visit_acronym(self
, node
):
405 def depart_acronym(self
, node
):
409 def visit_address(self
, node
):
413 def depart_address(self
, node
):
417 def visit_admonition(self
, node
, name
=''):
421 def depart_admonition(self
, node
=None):
425 def visit_attention(self
, node
):
429 def depart_attention(self
, node
):
433 def visit_attribution(self
, node
):
437 def depart_attribution(self
, node
):
441 def visit_author(self
, node
):
442 self
.paragraph_properties
[ 'author' ] = ('w:pStyle', { 'w:val' : 'AuthorName' })
443 # self.paragraph_properties[ 'author' ] = '<w:pStyle w:val="AuthorName" />'
444 self
.visit_paragraph( node
)
447 def depart_author(self
, node
):
448 del self
.paragraph_properties
[ 'author' ]
449 self
.depart_paragraph( node
)
452 def visit_authors(self
, node
):
456 def depart_authors(self
, node
):
460 def visit_block_quote(self
, node
):
461 self
.indentation
+= 720
464 def depart_block_quote(self
, node
):
465 self
.indentation
-= 720
468 def visit_bullet_list(self
, node
):
471 self
.lists
.append( '<w:list w:ilfo="' + str( self
.list_count
) + '">\n <w:ilst w:val="1">\n </w:ilst>\n</w:list>\n' )
472 self
.list_properties
.append( '<w:listPr>\n<w:ilvl w:val="' + str( self
.list_level
) + '" />\n<w:ilfo w:val="' + str( self
.list_count
) + '" />\n</w:listPr>\n' )
475 def depart_bullet_list(self
, node
):
476 self
.list_properties
.pop()
480 def visit_caption(self
, node
):
481 self
.figure_count
+= 1
482 self
.text_properties
[ 'caption' ] = ('w:rStyle', { 'w:val' : 'Caption' })
483 # self.text_properties[ 'caption' ] = '<w:rStyle w:val="Caption" />'
484 node
.children
.insert( 0, nodes
.Text( 'Figure ' + str( self
.figure_count
) + ' ' ));
487 def depart_caption(self
, node
):
488 del self
.text_properties
[ 'caption' ]
491 def visit_caution(self
, node
):
495 def depart_caution(self
, node
):
499 def visit_citation(self
, node
):
500 if not self
.in_footnote
:
504 def depart_citation(self
, node
):
505 if not self
.in_footnote
:
509 def visit_citation_reference(self
, node
):
510 citation
= self
.document
.ids
[ node
['refid'] ]
511 citation_reference_text
= ''
512 if not isinstance( citation
, nodes
.citation
):
513 raise TypeError( 'not a citation node mapped to id' )
514 self
.doc_tree
.start( 'w:r', {} )
515 self
.doc_tree
.start( 'w:rPr', {} )
516 self
.doc_tree
.start( 'w:rStyle', { 'w:val' : 'CitationReference' })
517 self
.doc_tree
.end( 'w:rStyle' )
518 self
.doc_tree
.end( 'w:rPr' )
519 self
.doc_tree
.start( 'w:endnote', { 'w:suppressRef' : 'on' } )
520 self
.body
.append( '<w:r>\n<w:rPr>\n<w:rStyle w:val="CitationReference"/>\n</w:rPr>\n<w:endnote w:suppressRef="on">\n' )
522 former_paragraph_properties
= self
.paragraph_properties
.copy()
523 self
.paragraph_properties
= {}
524 self
.paragraph_properties
[ 'citation' ] = ( 'w:pStyle', { 'w:val' : 'EndnoteText' })
525 # self.paragraph_properties[ 'citation' ] = '<w:pStyle w:val="EndnoteText"/>'
526 labels
= citation
.traverse( condition
=nodes
.label
)
528 citation_reference_text
+= n
.astext()
529 citation
.children
.remove( n
)
530 p
= citation
.traverse( condition
=nodes
.paragraph
)
531 # t_head = TextNoEncoding( '<w:r>\n<w:rPr>\n<w:rStyle w:val="CitationReference" />\n</w:rPr>\n<w:t>' )
532 # t_tail = TextNoEncoding( '</w:t>\n</w:r>\n')
533 # p[0].children.insert( 0, t_tail )
534 # p[0].children.insert( 0, TextNoEncoding( '[' + citation_reference_text + '] ' ))
535 # p[0].children.insert( 0, nodes.Text( '[' + citation_reference_text + '] ' ))
536 t
= TextWithStyle( '[' + citation_reference_text
+ '] ', ( 'citation', ( 'w:rStyle', { 'w:val' : 'CitationReference' })))
537 p
[0].children
.insert( 0, t
)
538 # p[0].children.insert( 0, t_head )
539 citation
.walkabout( self
)
540 p
[0].children
.remove( t
)
541 self
.doc_tree
.end( 'w:endnote' )
542 self
.doc_tree
.start( 'w:t', {} )
543 self
.doc_tree
.data( '[' + citation_reference_text
+ ']' )
544 self
.doc_tree
.end( 'w:t' )
545 self
.doc_tree
.end( 'w:r' )
546 self
.body
.append( '</w:endnote>\n' )
547 self
.body
.append( '<w:t>' )
548 self
.body
.append( '[' + citation_reference_text
+ ']' )
549 self
.body
.append( '</w:t>\n</w:r>\n' )
550 del self
.paragraph_properties
[ 'citation' ]
553 self
.paragraph_properties
= former_paragraph_properties
556 def depart_citation_reference(self
, node
):
561 def visit_classifier(self
, node
):
565 def depart_classifier(self
, node
):
569 def visit_colspec(self
, node
):
570 self
.colspecs
.append( node
)
571 self
.total_col_width
+= node
['colwidth']
574 def depart_colspec(self
, node
):
578 def visit_comment(self
, node
):
582 def depart_comment( self
, node
):
586 def visit_compound(self
, node
):
590 def depart_compound(self
, node
):
594 def visit_contact(self
, node
):
595 self
.paragraph_properties
[ 'contact' ] = ( 'w:pStyle', { 'w:val' : 'AuthorContact' })
596 # self.paragraph_properties[ 'contact' ] = '<w:pStyle w:val="AuthorContact" />'
597 self
.visit_paragraph( node
)
600 def depart_contact(self
, node
):
601 del self
.paragraph_properties
[ 'contact' ]
602 self
.depart_paragraph( node
)
605 def visit_container(self
, node
):
609 def depart_container(self
, node
):
613 def visit_copyright(self
, node
):
614 self
.paragraph_properties
[ 'copyright' ] = ( 'w:pStyle', { 'w:val' : 'BibliographMatter' })
615 # self.paragraph_properties[ 'copyright' ] = '<w:pStyle w:val="BibliographMatter" />'
616 self
.visit_paragraph( node
)
619 def depart_copyright(self
, node
):
620 del self
.paragraph_properties
[ 'copyright' ]
621 self
.depart_paragraph( node
)
624 def visit_danger(self
, node
):
628 def depart_danger(self
, node
):
632 def visit_date(self
, node
):
633 self
.paragraph_properties
[ 'date' ] = ( 'w:pStyle', { 'w:val' : 'BibliographMatter' })
634 # self.paragraph_properties[ 'date' ] = '<w:pStyle w:val="BibliographMatter" />'
635 self
.visit_paragraph( node
)
638 def depart_date(self
, node
):
639 del self
.paragraph_properties
[ 'date' ]
640 self
.depart_paragraph( node
)
643 def visit_decoration(self
, node
):
647 def depart_decoration(self
, node
):
651 def visit_definition(self
, node
):
652 self
.indentation
+= 720
653 self
.paragraph_properties
[ 'definition' ] = ( 'w:pStyle', { 'w:val' : 'Definition' })
654 # self.paragraph_properties[ 'definition' ] = '<w:pStyle w:val="Definition" />'
657 def depart_definition(self
, node
):
658 self
.indentation
-= 720
659 del self
.paragraph_properties
[ 'definition' ]
662 def visit_definition_list(self
, node
):
666 def depart_definition_list(self
, node
):
670 def visit_definition_list_item(self
, node
):
674 def depart_definition_list_item(self
, node
):
678 def visit_description(self
, node
):
682 def depart_description(self
, node
):
686 def visit_docinfo(self
, node
):
690 def depart_docinfo(self
, node
):
694 def visit_docinfo_item(self
, node
, name
, meta
=1):
698 def depart_docinfo_item(self
):
702 def visit_doctest_block(self
, node
):
706 def depart_doctest_block(self
, node
):
710 def visit_document(self
, node
):
714 def depart_document(self
, node
):
718 def visit_emphasis(self
, node
):
719 self
.text_properties
[ '*' ] = ('w:i', {})
720 # self.text_properties[ '*' ] = '<w:i/>'
723 def depart_emphasis(self
, node
):
724 del self
.text_properties
[ '*' ]
727 def calc_col_pct( self
, col
):
728 width
= int( self
.colspecs
[ col
][ 'colwidth' ] * 100.0 / self
.total_col_width
+ 0.5 )
732 def visit_entry(self
, node
):
733 width
= self
.calc_col_pct( self
.col
)
734 self
.doc_tree
.start( 'w:tc', {} )
735 self
.doc_tree
.start( 'w:tcPr', {} )
736 self
.doc_tree
.start( 'w:tcW', { 'w' : str( width
), 'w:type' : 'pct' } )
737 self
.doc_tree
.end( 'w:tcW' )
738 self
.body
.append( '<w:tc>\n <w:tcPr>\n <w:tcW w="' + str( width
) + '" w:type="pct" />\n' )
739 self
.has_text_output
= 0
740 if node
.has_key('morecols') and node
.has_key('morerows'):
741 raise NotImplementedError( "Table cell " + str( self
.col
) + "," + str( self
.row
) + " can't have both merged rows and columns." )
742 if node
.has_key('morecols'):
743 self
.doc_tree
.start( 'w:hmerge', { 'w:val' : 'restart' } )
744 self
.doc_tree
.end( 'w:hmerge' )
745 self
.body
.append( '<w:hmerge w:val="restart" />' )
746 for i
in range( node
['morecols'] ):
747 span
= '{' + str( self
.col
+ i
+ 1 ) + ',' + str( self
.row
) + '}'
748 self
.spans
[ span
] = ('w:hmerge', {}) # '<w:hmerge />'
749 if node
.has_key('morerows'):
750 self
.doc_tree
.start( 'w:vmerge', { 'w:val' : 'restart' })
751 self
.doc_tree
.end( 'w:vmerge' )
752 self
.body
.append( '<w:vmerge w:val="restart" />' )
753 for i
in range( node
['morerows'] ):
754 span
= '{' + str( self
.col
) + ',' + str( self
.row
+ i
+ 1 ) + '}'
755 self
.spans
[ span
] = ('w:vmerge', {} ) # '<w:vmerge />'
756 self
.doc_tree
.end( 'w:tcPr' )
757 self
.body
.append( '</w:tcPr>\n' )
760 def depart_entry(self
, node
):
761 if self
.has_text_output
== 0:
762 self
.doc_tree
.start( 'w:p', {} )
763 self
.doc_tree
.end( 'w:p' )
764 self
.body
.append( ' <w:p />\n' )
765 self
.doc_tree
.end( 'w:tc' )
766 self
.body
.append( '</w:tc>\n' )
767 # if there are any cells that are part of a span, then include them here as empty cells.
770 while self
.check_for_span( col
, row
):
776 def visit_enumerated_list(self
, node
):
777 # to put any sort of customization in, it's necessary to add an entirely new listDef element.
778 # so, I need to load the listDefs at the beginning of the run, and then customize them as needed.
781 list_props
= '<w:listPr>\n<w:ilvl w:val="' + str( self
.list_level
) + '" />\n<w:ilfo w:val="' + str( self
.list_count
) + '" />\n'
782 #if the list has an explicit start, then set the text for it
784 if node
.has_key('start'):
785 start
= int( node
['start'] )
787 if node
['enumtype'] == 'arabic':
789 elif node
['enumtype'] == 'upperalpha':
791 elif node
['enumtype'] == 'loweralpha':
793 elif node
['enumtype'] == 'lowerroman':
795 elif node
['enumtype'] == 'upperroman':
797 self
.list_defs
.append( self
.listdef_to_xml( 0, self
.list_level
, start
, nfc
))
798 self
.lists
.append( '<w:list w:ilfo="' + str( self
.list_count
) + '">\n <w:ilst w:val="' + str( self
.list_count
+ 1 ) + '">\n </w:ilst>\n</w:list>\n' )
799 list_props
+= '</w:listPr>\n'
800 self
.list_properties
.append( list_props
)
803 def depart_enumerated_list(self
, node
):
804 self
.show_list_properties
-= 1
805 self
.list_properties
.pop()
809 def visit_error(self
, node
):
813 def depart_error(self
, node
):
817 def visit_field(self
, node
):
818 self
.paragraph_properties
[ 'field' ] = ( 'w:pStyle', { 'w:val' : 'BibliographMatter' })
819 # self.paragraph_properties[ 'field' ] = '<w:pStyle w:val="BibliographMatter" />'
820 self
.visit_paragraph( node
)
823 def depart_field(self
, node
):
824 del self
.paragraph_properties
[ 'field' ]
825 self
.depart_paragraph( node
)
828 def visit_field_body(self
, node
):
832 def depart_field_body(self
, node
):
836 def visit_field_list(self
, node
):
840 def depart_field_list(self
, node
):
844 def visit_field_name(self
, node
):
848 def depart_field_name(self
, node
):
852 def visit_figure(self
, node
):
856 def depart_figure(self
, node
):
858 self
.doc_tree
.end( 'w:p' )
859 self
.body
.append( '</w:p>\n' )
863 def visit_footer(self
, node
):
867 def depart_footer(self
, node
):
871 def visit_footnote(self
, node
):
872 if not self
.in_footnote
:
876 def depart_footnote(self
, node
):
877 if not self
.in_footnote
:
881 def visit_footnote_reference(self
, node
):
882 if not node
.has_key( 'auto' ):
883 raise TypeError( 'footnotes required to be auto numbered' )
884 footnote
= self
.document
.ids
[ node
['refid'] ]
885 if not isinstance( footnote
, nodes
.footnote
):
886 raise TypeError( 'not a footnote node mapped to id' )
887 self
.doc_tree
.start( 'w:r', {} )
888 self
.doc_tree
.start( 'w:rPr', {} )
889 self
.doc_tree
.start( 'w:rStyle', { 'w:val' : 'EndnoteReference' })
890 self
.doc_tree
.end( 'w:rStyle' )
891 self
.doc_tree
.end( 'w:rPr' )
892 self
.doc_tree
.start( 'w:endnote', {} )
893 self
.body
.append( '<w:r>\n<w:rPr>\n<w:rStyle w:val="EndnoteReference"/>\n</w:rPr>\n<w:endnote>\n' )
894 # figure out how to get the <w:endnoteRef/>
896 former_paragraph_properties
= self
.paragraph_properties
.copy()
897 self
.paragraph_properties
= {}
898 self
.paragraph_properties
[ 'footnote' ] = ( 'w:pStyle', { 'w:val' : 'EndnoteText' })
899 # self.paragraph_properties[ 'footnote' ] = '<w:pStyle w:val="EndnoteText"/>'
900 # self.body.append( '<w:p>\n<w:pPr>\n<w:pStyle w:val="EndnoteText"/>\n</w:pPr>\n<w:r>\n<w:r>\n<w:rPr>\n<w:rStyle w:val="EndnoteReference"/>\n</w:rPr>\n<w:endnoteRef/>\n' )
901 # Find the label in the target footnode node and add it here.
902 labels
= footnote
.traverse( condition
=nodes
.label
)
903 # replace label text with <w:endnoteRef />
905 footnote
.children
.remove( n
)
906 # n.children.append( nodes.Text('<w:r>\n<w:rPr>\n<w:rStyle w:val="EndnoteReference" />\n</w:rPr>\n<w:endnoteRef />\n</w:r>\n'))
907 p
= footnote
.traverse( condition
=nodes
.paragraph
)
908 # t = TextNoEncoding( '<w:r>\n<w:rPr>\n<w:rStyle w:val="EndnoteReference" />\n</w:rPr>\n<w:endnoteRef />\n</w:r>\n')
909 t
= XMLRegion( xml
=[( 'w:endnoteRef', {} )], styles
=[( 'w:rStyle', { 'w:val' : 'EndnoteReference' })] )
910 p
[0].children
.insert( 0, t
)
911 footnote
.walkabout( self
)
912 p
[0].children
.remove(t
)
913 self
.doc_tree
.end( 'w:endnote' )
914 self
.doc_tree
.end( 'w:r' )
915 self
.body
.append( '</w:endnote>\n</w:r>\n' )
916 del self
.paragraph_properties
[ 'footnote' ]
919 self
.paragraph_properties
= former_paragraph_properties
922 def depart_footnote_reference(self
, node
):
923 # del self.paragraph_properties[ 'footnote' ]
924 # self.in_footnote = 0
928 def visit_generated(self
, node
):
932 def depart_generated(self
, node
):
936 def visit_header(self
, node
):
940 def depart_header(self
, node
):
944 def visit_hint(self
, node
):
948 def depart_hint(self
, node
):
952 def visit_image(self
, node
):
960 im
= Image
.open( node
['uri'] )
965 except (IOError, UnicodeError):
967 if node
.has_key( 'width' ):
968 width
= node
[ 'width' ]
970 if node
.has_key( 'height' ):
971 height
= node
[ 'height' ]
973 if node
.has_key( 'align' ):
974 align
= node
[ 'align' ]
975 self
.doc_tree
.start( 'w:p', {} )
976 self
.doc_tree
.start( 'w:pPr', {} )
977 self
.doc_tree
.start( 'w:jc', { 'w:val' : str( align
) } )
978 self
.doc_tree
.end( 'w:jc' )
979 self
.doc_tree
.end( 'w:pPr' )
980 self
.doc_tree
.start( 'w:pict', {} )
981 style
= 'position:absolute;left:0;text-align:left;margin-left:0;margin-top:0;width:'
983 style
+= str(width
) + 'px'
988 style
+= str( height
) + 'px'
991 style
+= ';z-index:1;mso-position-horizontal:center'
992 self
.doc_tree
.start( 'v:shape', { 'id' : str( self
.gen_id() ), 'style' : style
, 'coordsize' : '', 'o:spt' : '100', 'adj' : '0,,0', 'path' : '', 'stroked' : 'f' } )
993 self
.doc_tree
.start( 'v:imagedata', { 'src' : node
['uri'] } )
994 self
.doc_tree
.end( 'v:imagedata' )
995 self
.doc_tree
.start( 'w10:wrap', { 'type' : 'square' } )
996 self
.doc_tree
.end( 'w10:wrap' )
997 self
.doc_tree
.end( 'v:shape' )
998 self
.doc_tree
.end( 'w:pict' )
999 self
.body
.append( '<w:p>\n<w:pPr>\n<w:jc w:val="' + str( align
) + '" />\n</w:pPr>\n<w:pict>\n<v:shape id="' + str( self
.gen_id() ) + '" ')
1000 self
.body
.append( 'style="position:absolute;left:0;text-align:left;margin-left:0;margin-top:0;width:' )
1002 self
.body
.append( str(width
) + 'px' )
1004 self
.body
.append( 'auto' )
1005 self
.body
.append(';height:')
1007 self
.body
.append( str(height
) + 'px')
1009 self
.body
.append( 'auto' )
1010 self
.body
.append( ';z-index:1;mso-position-horizontal:center" coordsize="" o:spt="100" adj="0,,0" path="" stroked="f" >\n' )
1011 self
.body
.append( '<v:imagedata src="' + node
['uri'] + '"/>\n<w10:wrap type="square"/>\n</v:shape>\n</w:pict>\n' )
1014 def depart_image(self
, node
):
1015 if not self
.in_figure
:
1016 self
.doc_tree
.end( 'w:p' )
1017 self
.body
.append( '</w:p>\n' )
1020 def visit_important(self
, node
):
1024 def depart_important(self
, node
):
1028 def visit_inline(self
, node
):
1032 def depart_inline(self
, node
):
1036 def visit_label(self
, node
):
1037 self
.text_properties
[ 'label' ] = ( 'w:rStyle', { 'w:val' : '"EndnoteReference"' } )
1038 # self.text_properties[ 'label' ] = '<w:rStyle w:val="EndnoteReference"/>\n'
1039 #if self.in_footnote:
1041 # self.body.append( '<w:r>\n<w:rPr>\n<w:rStyle w:val="EndnoteReference"/>\n</w:rPr>\n<w:endnoteRef/>\n</w:r>\n' )
1044 def depart_label(self
, node
):
1045 del self
.text_properties
[ 'label' ]
1046 #if self.in_footnote:
1050 def visit_legend(self
, node
):
1054 def depart_legend(self
, node
):
1058 def visit_line(self
, node
):
1062 def depart_line(self
, node
):
1066 def visit_line_block(self
, node
):
1070 def depart_line_block(self
, node
):
1074 def visit_list_item(self
, node
):
1078 def depart_list_item(self
, node
):
1082 def visit_literal(self
, node
):
1083 self
.text_properties
[ 'literal' ] = ( 'w:rStyle', { 'w:val' : 'Literal' } )
1084 # self.text_properties[ 'literal' ] = '<w:rStyle w:val="Literal"/>\n'
1087 def depart_literal( self
, node
):
1088 del self
.text_properties
[ 'literal' ]
1091 def visit_literal_block(self
, node
):
1092 self
.paragraph_properties
[ 'literal' ] = ( 'w:pStyle', { 'w:val' : 'LiteralBlock' })
1093 #~ self.paragraph_properties[ 'literal' ] = '<w:pStyle w:val="LiteralBlock" />\n'
1094 self
.visit_paragraph( node
)
1095 self
.literal_text
= 1
1098 def depart_literal_block(self
, node
):
1099 del self
.paragraph_properties
[ 'literal' ]
1100 self
.depart_paragraph( node
)
1101 self
.literal_text
= 0
1104 def visit_meta(self
, node
):
1108 def depart_meta(self
, node
):
1112 def visit_note(self
, node
):
1116 def depart_note(self
, node
):
1120 def visit_option(self
, node
):
1124 def depart_option(self
, node
):
1128 def visit_option_argument(self
, node
):
1132 def depart_option_argument(self
, node
):
1136 def visit_option_group(self
, node
):
1140 def depart_option_group(self
, node
):
1144 def visit_option_list(self
, node
):
1148 def depart_option_list(self
, node
):
1152 def visit_option_list_item(self
, node
):
1156 def depart_option_list_item(self
, node
):
1160 def visit_option_string(self
, node
):
1164 def depart_option_string(self
, node
):
1168 def visit_organization(self
, node
):
1169 self
.paragraph_properties
[ 'organization' ] = ( 'w:pStyle', { 'w:val' : 'BibliographMatter' } )
1170 #~ self.paragraph_properties[ 'organization' ] = '<w:pStyle w:val="BibliographMatter" />'
1171 self
.visit_paragraph( node
)
1174 def depart_organization(self
, node
):
1175 del self
.paragraph_properties
[ 'organization' ]
1176 self
.depart_paragraph( node
)
1179 def visit_paragraph(self
, node
):
1180 self
.doc_tree
.start( 'w:p', {} )
1181 self
.body
.append( "<w:p>\n" )
1182 if len( self
.paragraph_properties
) > 0 or len( self
.list_properties
) > 0 or (self
.indentation
> 0 and not self
.in_footnote
):
1183 self
.doc_tree
.start( 'w:pPr', {} )
1184 self
.body
.append( "<w:pPr>\n" )
1185 if self
.indentation
> 0 and not self
.in_footnote
:
1186 self
.doc_tree
.start( 'w:ind', { 'w:left' : str( self
.indentation
), 'w:right' : str( self
.indentation
) })
1187 self
.doc_tree
.end( 'w:ind' )
1188 self
.body
.append( '<w:ind w:left="' + str( self
.indentation
) +
1189 '" w:right="' + str( self
.indentation
) + '" />\n' )
1190 for v
in self
.paragraph_properties
.values():
1191 if type( v
) == type( () ):
1192 element
= '<' + v
[0] + ' '
1193 for k
,a
in v
[1].iteritems():
1194 element
+= k
+ '="' + a
+ '" '
1196 self
.doc_tree
.start( v
[0], v
[1] )
1197 self
.doc_tree
.end( v
[0] )
1198 self
.body
.append( element
)
1200 self
.body
.append( v
)
1201 if len( self
.list_properties
) > 0 and isinstance( node
.parent
, nodes
.list_item
):
1202 if type( self
.list_properties
[ -1 ] ) == type( () ):
1203 t
= self
.list_properties
[ -1 ]
1204 element
= '<' + t
[0] + ' '
1205 for k
,a
in t
[1].iteritems():
1206 element
+= k
+ '="' + a
+ '" '
1208 self
.doc_tree
.start( t
[0], t
[1] )
1209 self
.doc_tree
.end( t
[0] )
1210 self
.body
.append( element
)
1212 self
.body
.append( self
.list_properties
[ -1 ] )
1213 self
.doc_tree
.end( 'w:pPr' )
1214 self
.body
.append( "\n</w:pPr>\n" )
1217 def depart_paragraph(self
, node
):
1218 self
.doc_tree
.end( 'w:p' );
1219 self
.body
.append( "</w:p>\n" )
1222 def visit_problematic(self
, node
):
1226 def depart_problematic(self
, node
):
1230 def visit_raw(self
, node
):
1234 def visit_reference(self
, node
):
1235 if node
.has_key('refid'):
1236 self
.doc_tree
.start( 'w:hlink', { 'w:bookmark' : node
[ 'refid' ] })
1237 self
.body
.append( '<w:hlink w:bookmark="' + node
['refid'] + '" >\n' )
1238 if node
.has_key('refuri'):
1239 self
.doc_tree
.start( 'w:hlink', { 'w:dest' : node
['refuri'] })
1240 self
.body
.append( '<w:hlink w:dest="' + node
['refuri'] + '" >\n' )
1241 if not node
.has_key('refuri') and not node
.has_key('refid'):
1242 raise NotImplementedError('Unknown reference type')
1243 self
.text_properties
[ 'ref' ] = ( 'w:rStyle', { 'w:val' : 'Hyperlink' })
1244 #~ self.text_properties['ref'] = '<w:rStyle w:val="Hyperlink" />\n'
1247 def depart_reference(self
, node
):
1248 del self
.text_properties
[ 'ref' ]
1249 self
.doc_tree
.end( 'w:hlink' )
1250 self
.body
.append( '</w:hlink>\n' )
1253 def visit_revision(self
, node
):
1257 def depart_revision(self
, node
):
1261 def visit_row(self
, node
):
1262 self
.doc_tree
.start( 'w:tr', {} )
1263 self
.body
.append( '<w:tr>\n' )
1264 while self
.check_for_span( self
.col
, self
.row
):
1267 def depart_row(self
, node
):
1270 self
.doc_tree
.end( 'w:tr' )
1271 self
.body
.append( '</w:tr>\n' )
1274 def visit_rubric(self
, node
):
1278 def depart_rubric(self
, node
):
1282 def visit_section(self
, node
):
1283 self
.section_level
+= 1
1284 if self
.section_level
> 3:
1285 raise NotImplementedError( "Only 3 levels of headings supported." )
1286 if node
.has_key( 'ids' ):
1287 for id in node
['ids']:
1288 refid
= self
.gen_id()
1289 self
.doc_tree
.start( 'aml:annotation', { 'aml:id' : str( refid
), 'w:type' : 'Word.Bookmark.Start', 'w:name' : id })
1290 self
.doc_tree
.end( 'aml:annotation' )
1291 self
.doc_tree
.start( 'aml:annotation', { 'aml:id' : str( refid
), 'w:type' : 'Word.Bookmark.End', 'w:name' : id })
1292 self
.doc_tree
.end( 'aml:annotation' )
1293 self
.body
.append('<aml:annotation aml:id="' + str( refid
) + '" w:type="Word.Bookmark.Start" w:name="' + id + '" />' )
1294 self
.body
.append('<aml:annotation aml:id="' + str( refid
) + '" w:type="Word.Bookmark.End" w:name="' + id + '" />' )
1297 def depart_section(self
, node
):
1298 self
.section_level
-= 1
1301 def visit_sidebar(self
, node
):
1305 def depart_sidebar(self
, node
):
1309 def visit_status(self
, node
):
1310 self
.paragraph_properties
[ 'status' ] = ( 'w:pStyle', { 'w:val' : 'BibliographMatter' })
1311 #~ self.paragraph_properties[ 'status' ] = '<w:pStyle w:val="BibliographMatter" />'
1312 self
.visit_paragraph( node
)
1315 def depart_status(self
, node
):
1316 del self
.paragraph_properties
[ 'status' ]
1317 self
.depart_paragraph( node
)
1320 def visit_strong(self
, node
):
1321 self
.text_properties
[ '**' ] = ( 'w:b', {} )
1322 #~ self.text_properties[ '**' ] = '<w:b/>'
1325 def depart_strong(self
, node
):
1326 del self
.text_properties
[ '**' ]
1329 def visit_subscript(self
, node
):
1330 self
.text_properties
[ 'subscript' ] = ( 'w:vertAlign', { 'w:val' : 'subscript' })
1331 #~ self.text_properties[ 'subscript' ] = '<w:vertAlign w:val="subscript" />'
1334 def depart_subscript(self
, node
):
1335 del self
.text_properties
[ 'subscript' ]
1338 def visit_substitution_definition(self
, node
):
1339 raise nodes
.SkipNode
1342 def visit_substitution_reference(self
, node
):
1343 raise NotImplementedError( "substitution references not implemented" )
1346 def visit_subtitle(self
, node
):
1347 self
.paragraph_properties
[ 'subtitle' ] = ( 'w:pStyle', { 'w:val' : self
.title_styles
[ self
.section_level
+ 1 ] })
1348 #~ self.paragraph_properties[ 'subtitle' ] = '<w:pStyle w:val="' + self.title_styles[ self.section_level + 1 ] + '"/>\n'
1349 self
.visit_paragraph( node
)
1352 def depart_subtitle(self
, node
):
1353 del self
.paragraph_properties
[ 'subtitle' ]
1354 self
.depart_paragraph( node
)
1357 def visit_superscript(self
, node
):
1358 self
.text_properties
[ 'superscript' ] = ( 'w:vertAlign', { 'w:val' : 'superscript' })
1359 #~ self.text_properties[ 'superscript' ] = '<w:vertAlign w:val="superscript" />\n'
1362 def depart_superscript(self
, node
):
1363 del self
.text_properties
[ 'superscript' ]
1366 def visit_system_message(self
, node
):
1370 def depart_system_message(self
, node
):
1374 def visit_table(self
, node
):
1375 #include for now the default border around the table with a top vertical alignment
1379 self
.total_col_width
= 0
1382 self
.doc_tree
.start( 'w:tbl', {} )
1383 self
.doc_tree
.start( 'w:tblPr', {} )
1384 self
.doc_tree
.start( 'w:tblStyle', { 'w:val' : 'Normal' } )
1385 self
.doc_tree
.end( 'w:tblStyle' )
1386 self
.doc_tree
.start( 'w:tblW', { 'w:w' : '5000', 'w:type' : 'pct' })
1387 self
.doc_tree
.end( 'w:tblW' )
1388 self
.doc_tree
.start( 'w:tblBorders', {} )
1389 self
.doc_tree
.start( 'w:top', { 'w:val' : 'single', 'w:sz' : '4', 'wx:bdrwidth' : '10', 'w:space' : '0', 'w:color' : 'auto' })
1390 self
.doc_tree
.end( 'w:top' )
1391 self
.doc_tree
.start( 'w:left', { 'w:val' : 'single', 'w:sz' : '4', 'wx:bdrwidth' : '10', 'w:space' : '0', 'w:color' : 'auto' })
1392 self
.doc_tree
.end( 'w:left' )
1393 self
.doc_tree
.start( 'w:bottom', { 'w:val' : 'single', 'w:sz' : '4', 'wx:bdrwidth' : '10', 'w:space' : '0', 'w:color' : 'auto' })
1394 self
.doc_tree
.end( 'w:bottom' )
1395 self
.doc_tree
.start( 'w:right', { 'w:val' : 'single', 'w:sz' : '4', 'wx:bdrwidth' : '10', 'w:space' : '0', 'w:color' : 'auto' })
1396 self
.doc_tree
.end( 'w:right' )
1397 self
.doc_tree
.start( 'w:insideH', { 'w:val' : 'single', 'w:sz' : '6', 'wx:bdrwidth' : '15', 'w:space' : '0', 'w:color' : 'auto' })
1398 self
.doc_tree
.end( 'w:insideH' )
1399 self
.doc_tree
.start( 'w:insideV', { 'w:val' : 'single', 'w:sz' : '6', 'wx:bdrwidth' : '15', 'w:space' : '0', 'w:color' : 'auto' })
1400 self
.doc_tree
.end( 'w:insideV' )
1401 self
.doc_tree
.end( 'w:tblBorders' )
1402 self
.doc_tree
.start( 'w:tblLook', { 'w:val' : '000001e0' } )
1403 self
.doc_tree
.end( 'w:tblLook' )
1404 self
.doc_tree
.end( 'w:tblPr' )
1405 self
.body
.append( '<w:tbl>\n'
1407 ' <w:tblStyle w:val="Normal" />\n'
1408 ' <w:tblW w:w="5000" w:type="pct" />\n'
1410 ' <w:top w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/>\n'
1411 ' <w:left w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/>\n'
1412 ' <w:bottom w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/>\n'
1413 ' <w:right w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/>\n'
1414 ' <w:insideH w:val="single" w:sz="6" wx:bdrwidth="15" w:space="0" w:color="auto"/>\n'
1415 ' <w:insideV w:val="single" w:sz="6" wx:bdrwidth="15" w:space="0" w:color="auto"/>\n'
1416 ' </w:tblBorders>\n'
1417 ' <w:tblLook w:val="000001e0" />\n'
1421 def depart_table(self
, node
):
1422 self
.doc_tree
.end( 'w:tbl' )
1423 self
.doc_tree
.start( 'w:p', {} )
1424 self
.doc_tree
.end( 'w:p' )
1425 self
.body
.append( '</w:tbl>\n' )
1426 self
.body
.append( '<w:p />' ) # add a blank line after the table
1430 def visit_target(self
, node
):
1431 if node
.has_key('refid'):
1432 refid
= self
.gen_id()
1433 self
.doc_tree
.start( 'aml:annotation', { 'aml:id' : str(refid
), 'w:type' : 'Word.Bookmark.Start', 'w:name' : node
['refid'] })
1434 self
.doc_tree
.end( 'aml:annotation' )
1435 self
.doc_tree
.start( 'aml:annotation', { 'aml:id' : str(refid
), 'w:type' : 'Word.Bookmark.End', 'w:name' : node
['refid'] })
1436 self
.doc_tree
.end( 'aml:annotation' )
1437 self
.body
.append('<aml:annotation aml:id="' + str( refid
) + '" w:type="Word.Bookmark.Start" w:name="' + node
['refid'] + '" />\n' )
1438 self
.body
.append('<aml:annotation aml:id="' + str( refid
) + '" w:type="Word.Bookmark.End" w:name="' + node
['refid'] + '" />\n' )
1441 def depart_target(self
, node
):
1445 def visit_tbody(self
, node
):
1448 def depart_tbody(self
, node
):
1452 def visit_term(self
, node
):
1453 self
.paragraph_properties
[ 'term' ] = ( 'w:pStyle', { 'w:val' : 'DefinitionTerm' })
1454 #~ self.paragraph_properties[ 'term' ] = '<w:pStyle w:val="DefinitionTerm" />'
1455 self
.visit_paragraph( node
)
1458 def depart_term(self
, node
):
1459 del self
.paragraph_properties
[ 'term' ]
1460 self
.depart_paragraph( node
)
1463 def visit_tgroup(self
, node
):
1467 def depart_tgroup(self
, node
):
1471 def visit_thead(self
, node
):
1475 def depart_thead(self
, node
):
1479 def visit_tip(self
, node
):
1483 def depart_tip(self
, node
):
1487 def visit_title(self
, node
, move_ids
=1):
1488 self
.paragraph_properties
[ 'title' ] = ( 'w:pStyle', { 'w:val' : self
.title_styles
[ self
.section_level
] })
1489 #~ self.paragraph_properties[ 'title' ] = '<w:pStyle w:val="' + self.title_styles[ self.section_level ] + '"/>\n'
1490 self
.visit_paragraph( node
)
1493 def depart_title(self
, node
):
1494 del self
.paragraph_properties
[ 'title' ]
1495 self
.depart_paragraph( node
)
1498 def visit_title_reference(self
, node
):
1502 def depart_title_reference(self
, node
):
1506 def visit_topic(self
, node
):
1507 self
.paragraph_properties
[ 'topic' ] = ( 'w:pStyle', { 'w:val' : 'Topic' })
1508 #~ self.paragraph_properties[ 'topic' ] = '<w:pStyle w:val="BibliographMatter" />'
1509 self
.visit_paragraph( node
)
1512 def depart_topic(self
, node
):
1513 del self
.paragraph_properties
[ 'topic' ]
1514 self
.depart_paragraph( node
)
1517 def visit_transition(self
, node
):
1521 def depart_transition(self
, node
):
1525 def visit_version(self
, node
):
1526 self
.paragraph_properties
[ 'version' ] = ( 'w:pStyle', { 'w:val' : 'BibliographMatter' })
1527 # self.paragraph_properties[ 'version' ] = '<w:pStyle w:val="BibliographMatter" />'
1528 self
.visit_paragraph( node
)
1531 def depart_version(self
, node
):
1532 del self
.paragraph_properties
[ 'version' ]
1533 self
.depart_paragraph( node
)
1536 def visit_warning(self
, node
):
1540 def depart_warning(self
, node
):
1544 def visit_XMLRegion( self
, node
):
1545 self
.doc_tree
.start( 'w:r', {} )
1546 self
.doc_tree
.start( 'w:rPr', {} )
1547 for style
in node
['styles']:
1548 self
.doc_tree
.start( style
[0], style
[1] )
1549 self
.doc_tree
.end( style
[0] )
1550 self
.doc_tree
.end( 'w:rPr' )
1551 for tag
in node
['xml']:
1552 self
.doc_tree
.start( tag
[0], tag
[1] )
1553 self
.doc_tree
.end( tag
[0] )
1556 def depart_XMLRegion( self
, node
):
1557 self
.doc_tree
.end( 'w:r' )
1560 def unimplemented_visit(self
, node
):