<s> import os <EOL> from . . import results , lists <EOL> from . document_xml import read_document_xml_element <EOL> from . content_types_xml import read_content_types_xml_element <EOL> from . relationships_xml import read_relationships_xml_element , Relationships <EOL> from . numbering_xml import read_numbering_xml_element , Numbering <EOL> from . styles_xml import read_styles_xml_element <EOL> from . notes_xml import create_footnotes_reader , create_endnotes_reader <EOL> from . files import Files <EOL> from . import body_xml , office_xml <EOL> from . . zips import open_zip <EOL> def read ( fileobj ) : <EOL> zip_file = open_zip ( fileobj , "<STR_LIT:r>" ) <EOL> body_readers = _body_readers ( getattr ( fileobj , "<STR_LIT:name>" , None ) , zip_file ) <EOL> return _read_notes ( zip_file , body_readers ) . bind ( lambda notes : <EOL> _read_document ( zip_file , body_readers , notes ) ) <EOL> def _read_notes ( zip_file , body_readers ) : <EOL> empty_result = results . success ( [ ] ) <EOL> read_footnotes_xml = create_footnotes_reader ( body_readers ( "<STR_LIT>" ) ) <EOL> footnotes = _try_read_entry_or_default ( <EOL> zip_file , "<STR_LIT>" , read_footnotes_xml , default = empty_result ) <EOL> read_endnotes_xml = create_endnotes_reader ( body_readers ( "<STR_LIT>" ) ) <EOL> endnotes = _try_read_entry_or_default ( <EOL> zip_file , "<STR_LIT>" , read_endnotes_xml , default = empty_result ) <EOL> return results . combine ( [ footnotes , endnotes ] ) . map ( lists . flatten ) <EOL> def _read_document ( zip_file , body_readers , notes ) : <EOL> with zip_file . open ( "<STR_LIT>" ) as document_fileobj : <EOL> document_xml = office_xml . read ( document_fileobj ) <EOL> return read_document_xml_element ( <EOL> document_xml , <EOL> body_reader = body_readers ( "<STR_LIT>" ) , <EOL> notes = notes , <EOL> ) <EOL> def _body_readers ( document_path , zip_file ) : <EOL> with zip_file . open ( "<STR_LIT>" ) as content_types_fileobj : <EOL> content_types = read_content_types_xml_element ( office_xml . read ( content_types_fileobj ) ) <EOL> numbering = _try_read_entry_or_default ( <EOL> zip_file , "<STR_LIT>" , read_numbering_xml_element , default = Numbering ( { } ) ) <EOL> with zip_file . open ( "<STR_LIT>" ) as styles_fileobj : <EOL> styles = read_styles_xml_element ( office_xml . read ( styles_fileobj ) ) <EOL> def for_name ( name ) : <EOL> relationships_path = "<STR_LIT>" . format ( name ) <EOL> relationships = _try_read_entry_or_default ( <EOL> zip_file , relationships_path , read_relationships_xml_element , <EOL> default = Relationships ( { } ) ) <EOL> return body_xml . reader ( <EOL> numbering = numbering , <EOL> content_types = content_types , <EOL> relationships = relationships , <EOL> styles = styles , <EOL> docx_file = zip_file , <EOL> files = Files ( None if document_path is None else os . path . dirname ( document_path ) ) , <EOL> ) <EOL> return for_name <EOL> def _try_read_entry_or_default ( zip_file , name , reader , default ) : <EOL> if zip_file . exists ( name ) : <EOL> with zip_file . open ( name ) as fileobj : <EOL> return reader ( office_xml . read ( fileobj ) ) <EOL> else : <EOL> return default </s>
