<s> from __future__ import ( <EOL> absolute_import , <EOL> print_function , <EOL> unicode_literals , <EOL> ) <EOL> import posixpath <EOL> import re <EOL> import os . path <EOL> from io import BytesIO <EOL> from xml . dom import minidom <EOL> from xml . parsers . expat import ExpatError <EOL> from pydocx . packaging import PackageRelationship , ZipPackagePart <EOL> from pydocx . export . html import PyDocXHTMLExporter <EOL> from pydocx . openxml . packaging import ( <EOL> FootnotesPart , <EOL> MainDocumentPart , <EOL> NumberingDefinitionsPart , <EOL> StyleDefinitionsPart , <EOL> WordprocessingDocument , <EOL> ) <EOL> from pydocx . test . document_builder import DocxBuilder as DXB <EOL> def prettify ( xml_string ) : <EOL> """<STR_LIT>""" <EOL> parsed = minidom . parseString ( xml_string ) <EOL> return parsed . toprettyxml ( indent = '<STR_LIT:\t>' ) <EOL> def html_is_equal ( a , b ) : <EOL> a = collapse_html ( a ) <EOL> b = collapse_html ( b ) <EOL> return a == b <EOL> def assert_html_equal ( actual_html , expected_html , filename = None ) : <EOL> if not html_is_equal ( actual_html , expected_html ) : <EOL> try : <EOL> html = prettify ( actual_html ) <EOL> except ExpatError : <EOL> html = actual_html <EOL> if filename : <EOL> with open ( '<STR_LIT>' % filename , '<STR_LIT:w>' ) as f : <EOL> f . write ( html ) <EOL> raise AssertionError ( html ) <EOL> def collapse_html ( html ) : <EOL> """<STR_LIT>""" <EOL> def smart_space ( match ) : <EOL> before = match . group ( <NUM_LIT:1> ) <EOL> after = match . group ( <NUM_LIT:2> ) <EOL> space = '<STR_LIT:U+0020>' <EOL> if before == '<STR_LIT:>>' or after == '<STR_LIT:<>' : <EOL> space = '<STR_LIT>' <EOL> return before + space + after <EOL> html = re . sub ( <EOL> r'<STR_LIT>' , <EOL> smart_space , <EOL> html , <EOL> ) <EOL> return html . strip ( ) <EOL> class PyDocXHTMLExporterNoStyle ( PyDocXHTMLExporter ) : <EOL> def style ( self ) : <EOL> return '<STR_LIT>' <EOL> class WordprocessingDocumentFactory ( object ) : <EOL> PARTS_TO_PATHS = { <EOL> FootnotesPart : '<STR_LIT>' , <EOL> MainDocumentPart : '<STR_LIT>' , <EOL> StyleDefinitionsPart : '<STR_LIT>' , <EOL> NumberingDefinitionsPart : '<STR_LIT>' , <EOL> } <EOL> PARTS_TO_PREPARE_CONTENT_FUNCS = { <EOL> FootnotesPart : '<STR_LIT>' , <EOL> MainDocumentPart : '<STR_LIT>' , <EOL> StyleDefinitionsPart : '<STR_LIT>' , <EOL> NumberingDefinitionsPart : '<STR_LIT>' , <EOL> } <EOL> relationship_format = '''<STR_LIT>''' <EOL> content_types = '''<STR_LIT>''' <EOL> def __init__ ( self , items = None , xml_header = None ) : <EOL> self . items = items <EOL> if not self . items : <EOL> self . items = { } <EOL> if xml_header is None : <EOL> xml_header = '<STR_LIT>' <EOL> self . xml_header = xml_header <EOL> def to_zip_dict ( self ) : <EOL> '''<STR_LIT>''' <EOL> zip_dict = { } <EOL> part_class_to_uri = { } <EOL> for item_class , ( content , rels ) in self . items . items ( ) : <EOL> uri = self . PARTS_TO_PATHS [ item_class ] <EOL> part_class_to_uri [ item_class ] = uri <EOL> zip_dict [ uri ] = content <EOL> if rels : <EOL> rels_uri = ZipPackagePart . get_relationship_part_uri ( uri ) <EOL> zip_dict [ rels_uri ] = rels <EOL> base_uri , base_content = self . get_base_relationships ( part_class_to_uri ) <EOL> zip_dict [ base_uri ] = base_content <EOL> content_types_uri , content_types = self . get_content_types ( ) <EOL> zip_dict [ content_types_uri ] = content_types <EOL> return zip_dict <EOL> def add ( self , item_part_class , content , relationships = None ) : <EOL> '''<STR_LIT>''' <EOL> func_name = self . PARTS_TO_PREPARE_CONTENT_FUNCS . get ( item_part_class ) <EOL> func = getattr ( self , func_name ) <EOL> if callable ( func ) : <EOL> content = func ( content ) <EOL> relationships = self . prepare_relationship_data ( <EOL> content = relationships , <EOL> item_part_class = item_part_class , <EOL> ) <EOL> self . items [ item_part_class ] = ( content , relationships ) <EOL> def prepare_xml_content ( self , xml ) : <EOL> return '<STR_LIT>' . format ( header = self . xml_header , xml = xml ) <EOL> def prepare_relationship_data ( self , content , item_part_class = None ) : <EOL> if item_part_class : <EOL> relevant_part_classes = ( <EOL> set ( item_part_class . child_part_types ) & set ( self . items . keys ( ) ) <EOL> ) <EOL> automatic_rels = '<STR_LIT>' . join ( self . build_relationship_content ( dict ( <EOL> ( <EOL> part_class , <EOL> self . get_part_name ( item_part_class , part_class ) , <EOL> ) <EOL> for part_class in relevant_part_classes <EOL> ) ) ) <EOL> if content : <EOL> content = content + automatic_rels <EOL> else : <EOL> content = automatic_rels <EOL> xml = '<STR_LIT>' . format ( <EOL> ns = PackageRelationship . namespace , <EOL> rels = content , <EOL> ) <EOL> return self . prepare_xml_content ( xml = xml ) <EOL> def get_part_name ( self , parent_part_class , part_class ) : <EOL> parent_uri = self . PARTS_TO_PATHS [ parent_part_class ] <EOL> uri = self . PARTS_TO_PATHS [ part_class ] <EOL> return os . path . relpath ( uri , os . path . dirname ( parent_uri ) ) <EOL> def get_base_relationships ( self , part_class_to_uri ) : <EOL> uri = ZipPackagePart . get_relationship_part_uri ( '<STR_LIT>' ) <EOL> content = '<STR_LIT>' . join ( self . build_relationship_content ( part_class_to_uri ) ) <EOL> content = self . prepare_relationship_data ( content = content ) <EOL> return uri , content <EOL> def build_relationship_content ( self , part_class_to_uri ) : <EOL> for rid , ( part_class , uri ) in enumerate ( part_class_to_uri . items ( ) ) : <EOL> yield self . relationship_format . format ( <EOL> id = '<STR_LIT>' . format ( rid = rid ) , <EOL> type = part_class . relationship_type , <EOL> target = uri , <EOL> target_mode = '<STR_LIT>' , <EOL> ) <EOL> def prepare_main_document_content ( self , xml ) : <EOL> xml = '<STR_LIT>' . format ( xml = xml ) <EOL> return self . prepare_xml_content ( xml = xml ) <EOL> def prepare_style_content ( self , xml ) : <EOL> xml = '<STR_LIT>' . format ( xml = xml ) <EOL> return self . prepare_xml_content ( xml = xml ) <EOL> def prepare_footnotes_content ( self , xml ) : <EOL> xml = '<STR_LIT>' . format ( xml = xml ) <EOL> return self . prepare_xml_content ( xml = xml ) <EOL> def prepare_numbering_content ( self , xml ) : <EOL> xml = '<STR_LIT>' . format ( xml = xml ) <EOL> return self . prepare_xml_content ( xml = xml ) <EOL> def get_content_types ( self ) : <EOL> content_types = self . prepare_xml_content ( xml = self . content_types ) <EOL> return '<STR_LIT>' , content_types <EOL> class XMLDocx2Html ( PyDocXHTMLExporter ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> self . document_xml = kwargs . pop ( '<STR_LIT>' ) <EOL> self . relationships = kwargs . pop ( '<STR_LIT>' ) or [ ] <EOL> self . numbering_dict = kwargs . pop ( '<STR_LIT>' , None ) or { } <EOL> self . styles_xml = kwargs . pop ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> super ( XMLDocx2Html , self ) . __init__ ( path = None , * args , ** kwargs ) <EOL> def load_document ( self ) : <EOL> document = WordprocessingDocument ( path = None ) <EOL> package = document . package <EOL> document_part = package . create_part ( <EOL> uri = '<STR_LIT>' , <EOL> ) <EOL> if self . numbering_dict is not None : <EOL> numbering_xml = DXB . numbering ( self . numbering_dict ) <EOL> self . relationships . append ( { <EOL> '<STR_LIT>' : False , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT:data>' : numbering_xml , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : NumberingDefinitionsPart . relationship_type , <EOL> } ) <EOL> if self . styles_xml : <EOL> self . relationships . append ( { <EOL> '<STR_LIT>' : False , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT:data>' : self . styles_xml , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : StyleDefinitionsPart . relationship_type , <EOL> } ) <EOL> for relationship in self . relationships : <EOL> target_mode = '<STR_LIT>' <EOL> if relationship [ '<STR_LIT>' ] : <EOL> target_mode = '<STR_LIT>' <EOL> target_uri = relationship [ '<STR_LIT>' ] <EOL> if '<STR_LIT:data>' in relationship : <EOL> full_target_uri = posixpath . join ( <EOL> package . uri , <EOL> '<STR_LIT>' , <EOL> target_uri , <EOL> ) <EOL> package . streams [ full_target_uri ] = BytesIO ( <EOL> relationship [ '<STR_LIT:data>' ] , <EOL> ) <EOL> package . create_part ( uri = full_target_uri ) <EOL> document_part . create_relationship ( <EOL> target_uri = target_uri , <EOL> target_mode = target_mode , <EOL> relationship_type = relationship [ '<STR_LIT>' ] , <EOL> relationship_id = relationship [ '<STR_LIT>' ] , <EOL> ) <EOL> package . streams [ document_part . uri ] = BytesIO ( self . document_xml ) <EOL> package . create_relationship ( <EOL> target_uri = document_part . uri , <EOL> target_mode = '<STR_LIT>' , <EOL> relationship_type = MainDocumentPart . relationship_type , <EOL> ) <EOL> self . _page_width = <NUM_LIT> <EOL> return document </s>
