o
    \Rp                     @   sT  d Z ddlZddlZddlZddlZddlZddlmZ ddlm	Z	m
Z
mZ zddlmZ W n ey;   ddlZY nw zddlmZ W n eyO   i ZY nw ddlmZ ddlmZ ddlZeeZeejed	Zejes}eejed
Zi dddddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1Zd2d3 Zd4d5 Z 		dhd6d7Z!did:d;Z"djd?d@Z#dAdB Z$dkdDdEZ%dFddGddHi dfdIdJZ&		F	dldKdLZ'dMdN Z(dOdP Z)dQdR Z*dSdT Z+dmdVdWZ,dmdXdYZ-dZd[ Z.dnd\d]Z/d^d_ Z0d`da Z1dbdc Z2ddde Z3	dndfdgZ4dS )oz
Open and modify Microsoft Word 2007 docx files (called 'OpenXML' and
'Office OpenXML' by Microsoft)

Part of Python's docx module - http://github.com/mikemaccana/python-docx
See LICENSE for licensing information.
    N)etree)abspathbasenamejoin)Image)TAGS)PendingDeprecationWarning)warnzdocx-templatetemplatemoz8http://schemas.microsoft.com/office/mac/office/2008/mainoz'urn:schemas-microsoft-com:office:officevez;http://schemas.openxmlformats.org/markup-compatibility/2006wz<http://schemas.openxmlformats.org/wordprocessingml/2006/mainw10z%urn:schemas-microsoft-com:office:wordwnez4http://schemas.microsoft.com/office/word/2006/wordmlaz5http://schemas.openxmlformats.org/drawingml/2006/mainmz:http://schemas.openxmlformats.org/officeDocument/2006/mathmvz!urn:schemas-microsoft-com:mac:vmlpic8http://schemas.openxmlformats.org/drawingml/2006/picturevzurn:schemas-microsoft-com:vmlwpzFhttp://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawingcpzGhttp://schemas.openxmlformats.org/package/2006/metadata/core-propertiesdcz http://purl.org/dc/elements/1.1/epzIhttp://schemas.openxmlformats.org/officeDocument/2006/extended-propertiesxsiz)http://www.w3.org/2001/XMLSchema-instancectz<http://schemas.openxmlformats.org/package/2006/content-typeszChttp://schemas.openxmlformats.org/officeDocument/2006/relationshipsz<http://schemas.openxmlformats.org/package/2006/relationshipszhttp://purl.org/dc/dcmitype/zhttp://purl.org/dc/terms/)rprdcmitypedctermsc                 C   s"   t | }|d}t|}|S )z,Open a docx file, return a document XML treeword/document.xml)zipfileZipFilereadr   
fromstring)filemydoc
xmlcontentdocument r*   U/home/skpark/git/infrasmart_work/infrasmart/venv/lib/python3.10/site-packages/docx.pyopendocxQ   s   


r,   c                  C   s   t d} | t d | S )Nr)   bodymakeelementappend)r)   r*   r*   r+   newdocumentY   s   r1   c                 C   s   d}t |tri }|D ]}t| ||< q|d }|r!dt|  }nd}tj||  |d}|rQ|s:|dkr7|}	nd}	ndt|  d }	|D ]}
||	|
 ||
  qD|rV||_|S )	zCreate an element & return itNr   z{%s} )nsmapr   {})
isinstancelist
nsprefixesr   Elementsettext)tagnametagtextnsprefix
attributesattrnsprefixnamespacemapprefix	namespace
newelementattributenamespacetagattributer*   r*   r+   r/   _   s.   

r/   pageportraitc           
      C   s   ddg}| |vrd}t || |f td}| dkr2td}tdd| id}|| || |S | dkritd	}td
}|dkrLtddddd}	n|dkrZtdddddd}	||	 || || |S )z~Insert a break, default 'page'.
    See http://openxmldeveloper.org/forums/thread/4075.aspx
    Return our page break element.rG   sectionz8Page break style "%s" not implemented. Valid styles: %s.pr   brtyper?   pPrsectPrrH   pgSz1224015840)r   h	landscape)rS   r   orient)
ValueErrorr/   r0   )
rL   rU   
validtypestmpl	pagebreakrunrK   rN   rO   rP   r*   r*   r+   rY      s0   





rY   BodyTextFleftc                 C   st  t d}t| ts| dfg} g }| D ].}t|ttfr|n|df\}}t d|d}	t| t|k r9|	dd ||	|g qt d}
t dd	|id
}t dd	|id
}|
| |
| ||
 |D ]Q\}	}t d}t d}d|v rt d}|| d|v rt d}|| d|v rt dd	did
}|| || |rt d}|| ||	 || qf|S )a=  
    Return a new paragraph element containing *paratext*. The paragraph's
    default style is 'Body Text', but a new style may be set using the
    *style* parameter.

    @param string jc: Paragraph alignment, possible values:
                      left, center, right, both (justified), ...
                      see http://www.schemacentral.com/sc/ooxml/t-w_ST_Jc.html
                      for a full list

    If *paratext* is a list, add a run for each (text, char_format_str)
    2-tuple in the list. char_format_str is a string containing one or more
    of the characters 'b', 'i', or 'u', meaning bold, italic, and underline
    respectively. For example:

        paratext = [
            ('some bold text', 'b'),
            ('some normal text', ''),
            ('some italic underlined text', 'iu')
        ]
    rJ   r2   tr=   z+{http://www.w3.org/XML/1998/namespace}spacepreserverN   pStylevalrM   jcr   rPrbiusinglelastRenderedPageBreak)r/   r6   r7   tuplelenstripr:   r0   )paratextstylebreakbeforerb   	paragraphtext_tuplesptr;   char_styles_strtext_elmrN   r`   pJcrZ   rc   rd   re   rf   rh   r*   r*   r+   ro      sN   










ro   c               
   C   s   t d} dddddddd	d
d	}|D ]}| tdd ||| dd qddddddd}|D ]}||| d}tdd |d}| | q0| S )NzT<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"></Types>z7application/vnd.openxmlformats-officedocument.theme+xmlzLapplication/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xmlz:application/vnd.openxmlformats-package.core-properties+xmlzEapplication/vnd.openxmlformats-officedocument.extended-properties+xmlzPapplication/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xmlzKapplication/vnd.openxmlformats-officedocument.wordprocessingml.settings+xmlzLapplication/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xmlzIapplication/vnd.openxmlformats-officedocument.wordprocessingml.styles+xmlzNapplication/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml)	z/word/theme/theme1.xmlz/word/fontTable.xmlz/docProps/core.xmlz/docProps/app.xmlz/word/document.xmlz/word/settings.xmlz/word/numbering.xmlz/word/styles.xmlz/word/webSettings.xmlOverride)PartNameContentTyper>   r?   z	image/gifz
image/jpegz	image/pngz8application/vnd.openxmlformats-package.relationships+xmlzapplication/xml)gifjpegjpgpngrelsxml)	Extensionrw   Default)r   r%   r0   r/   )typespartspart	filetypes	extensionattrsdefault_elmr*   r*   r+   contenttypes   sB   

r   enc           	      C   sv   ddd}t d}t d}t dd|| t| id}t d	}t d
| d}|| || || || |S )z.Make a new heading, return the heading elementHeadingTitolo)r   itrJ   rN   r`   ra   rM   r   r]   r^   )r/   strr0   )	headingtextheadinglevellanglmapro   r   r`   rZ   r;   r*   r*   r+   heading  s   




r   Tdxaautoc           #   	   C   s  t d}t| d }	t d}
t dddid}|
| t dt|t|d	d}|
| t| rwt d
}dD ]8}|| v sGd| v rqd| v rOdn|}i }||  D ]}t|| | ||< qYt ||d}|| q9|
| t dddid}|
| ||
 t d}t|	D ]}d|rt|| ndi}|t d|d q|| t d}t d}t dddid}|| || |rDd}| d D ]m}t d}t d}|rt|| |d	}nddd	}t d|d}t dddddd d!d}|| || || t|tt	fs|g}|D ]}t|t
jr*|| q|t|d"d# q|| |d$7 }q|| | |rJd$ndd% D ]}t d}d}|D ]s} t d}t d}|rpt|| |d	}nddd	}t d|d}|| || t| tt	fs| g} | D ]/}!t|!t
jr||! q|rd&||  v r|| d& }"nd'}"|t|!|"d# q|| |d$7 }qY|| qO|S )(a/  
    Return a table element based on specified parameters

    @param list contents: A list of lists describing contents. Every item in
                          the list can be a string or a valid XML element
                          itself. It can also be a list. In that case all the
                          listed elements will be merged into the cell.
    @param bool heading:  Tells whether first line should be treated as
                          heading or not
    @param list colw:     list of integer column widths specified in wunitS.
    @param str  cwunit:   Unit used for column width:
                            'pct'  : fiftieths of a percent
                            'dxa'  : twentieths of a point
                            'nil'  : no width
                            'auto' : automagically determined
    @param int  tblw:     Table width
    @param str  twunit:   Unit used for table width. Same possible values as
                          cwunit.
    @param dict borders:  Dictionary defining table border. Supported keys
                          are: 'top', 'left', 'bottom', 'right',
                          'insideH', 'insideV', 'all'.
                          When specified, the 'all' key has precedence over
                          others. Each key must define a dict of border
                          attributes:
                            color : The color of the border, in hex or
                                    'auto'
                            space : The space, measured in points
                            sz    : The size of the border, in eighths of
                                    a point
                            val   : The style of the border, see
                http://www.schemacentral.com/sc/ooxml/t-w_ST_Border.htm
    @param list celstyle: Specify the style for each colum, list of dicts.
                          supported keys:
                          'align' : specify the alignment, see paragraph
                                    documentation.
    @return lxml.etree:   Generated XML etree element
    tblr   tblPrtblStylera   r2   rM   tblW)r   rL   
tblBorders)topr\   bottomrightinsideHinsideValltblLook0400tblGridr   2390gridColtrtrPrcnfStyle000000100000tctcPr0r   tcWshdclearFFFFFFtext299)ra   colorfill	themeFillthemeFillTintcenter)rb      Nalignr\   )r/   rj   r0   r   keysunicoderanger6   r7   ri   r   _Elementro   )#contentsr   colwcwunittblwtwunitborderscelstyletablecolumns
tableprops
tablestyle
tablewidthtablebordersrd   kr   r   
borderelem	tablelook	tablegridre   rowrowpropsr   cell	cellpropswattr	cellwidth	cellstylerS   
contentrowcontentcr   r*   r*   r+   r   )  s   '




















r   c           ,   	   C   s|  |du r	t dt d}t|}	|dur8|	|vr3dtt| d  }
|
||	< | dd|
t|	f g n2||	 }
n-dtt| d  }
| dd| g ttd	d
}t	j
|s\t	| t|t|| t|	}z| }|du rui n|}W n   i }Y i }| D ]\}}||t||< q|dd}ddddddddd| }|dv rdnd}|dkrdnd}|r|s|jdd \}}|dv r||}}d}t|| }t|| }tddd}|tdddd|
id td dd}|td!dd |td"dd || td#dd}td$dd%d&|d'd(}|| td)dd}|td*dtt|tt|d+d( || td,dd-d.id(}td/dt|d0 ||d1d(}|td2dd%d%d3d( |td4d||d5d( td6dd7d8id(}|td9dd || || tddd} | | | | | | td:dd;d<id(}!|!|  td=dd}"|"|! td>dd?d@id(}#tdAdBd}$|$|# tdCdB|d&|d'd(}%tdDdBdEd%d%d%dFd(}&tdGdB||d5d(}'tdHd%d%d%d%dIdBdJ}(|(|' |(|& |(|% |(|$ |(|" tdK})|)|( td}*|*|) tdL}+|+|* |dur:| |+|fS | |+fS )Mz
    Take a relationshiplist, picture file name, and return a paragraph
    containing the image and an updated relationshiplist
    NzQUsing picture() without imagefiledict parameter will be deprecated in the future.2rIdr   zIhttp://schemas.openxmlformats.org/officeDocument/2006/relationships/imagezmedia/%s_%szmedia/wordmediaOrientationr      Z   i  )r                        )r   r   r   truefalser   r   )r   r   r   r   i1  blipFillr   r>   blipr   r   embed)r>   r@   r?   stretchfillRectsrcRectnvPicPrcNvPrr   z	Picture 1)idnamedescrrx   cNvPicPrpicLocks)noChangeAspectnoChangeArrowheadsspPrbwModer   xfrmi`  )rotflipHflipVoff)xyext)cxcyprstGeomprstrectavLstgraphicDataurir   graphicgraphicFrameLocksr   1cNvGraphicFramePrr   docPreffectExtent25400)lr]   r   rd   extentinline)distTdistBdistLdistR)r?   r>   drawingrJ   )r	   r   r   r   rj   r0   r   r   template_dirospathisdirmkdirshutilcopyfiler   open_getexifitemsr   getsizer/   int),relationshiplistpicnamepicdescription
pixelwidthpixelheightnochangeaspectnochangearrowheadsimagefiledictpicidpicpathpicrelid	media_dirimageexif	imageExiftagvalueimageOrientation
imageAngle
imageFlipH
imageFlipVemuperpixelwidthheightblipfillr   nvpicprcnvprcnvpicprspprr   prstgeomr   graphicdatar
  
framelocksframeprdocpreffectextentr  r  r  rZ   ro   r*   r*   r+   picture  s  





























rI  c                 C   sH   d}t |}|  D ]}|jdtd  kr!|jr!||jr!d}q|S )z;Search a document for a regex, return success / fail resultF{%s}tr   T)recompileiterr5  r8   r;   search)r)   rN  resultsearchreelementr*   r*   r+   rN  i  s   
rN  c                 C   sV   | }t |}| D ]}|jdtd  kr(|jr(||jr(t |||j|_q|S )z_
    Replace all occurences of string with a different string, return updated
    document
    rJ  r   )rK  rL  rM  r5  r8   r;   rN  sub)r)   rN  replacer1   rP  rQ  r*   r*   r+   rS  u  s   
rS  c                 C   sj   | }dD ].}g }|  D ]}|jdtd |f kr%|js%t|s%|| q|D ]	}| | q(q|S )zV Perform misc cleaning operations on documents.
        Returns cleaned document.
    )r]   r   z{%s}%sr   )rM  r5  r8   r;   rj   r0   	getparentremove)r)   r1   r]   rmlistrQ  r*   r*   r+   clean  s   
rW  c                 C   s   | }	 |  }|j|kr|S q)z Finds fist parent of element of the given type

    @param object element: etree element
    @param string the tag parent to search for

    @return object element: the found parent or None when not found
    )rT  r5  )rQ  r5  rJ   r*   r*   r+   findTypeParent  s   	
rX  r   c                 C   s   t |}g }g }|  D ]j}|jdtd  krw|jrw|| t||kr+|d d}t	dt|d D ]@}|r< n;t	t|D ]3}	|rH n.|	| t|krut	|	|	| }
d}|
D ]	}||| j7 }q[|
|}|ru||  d}qBq6qt|S )aW  Return set of all regex matches

    This is an advanced version of python-docx.search() that takes into
    account blocks of <bs> elements at a time.

    What it does:
    It searches the entire document body for text blocks.
    Since the text to search could be spawned across multiple text blocks,
    we need to adopt some sort of algorithm to handle this situation.
    The smaller matching group of blocks (up to bs) is then adopted.
    If the matching group has more than one block, blocks other than first
    are cleared and all the replacement text is put on first block.

    Examples:
    original text blocks : [ 'Hel', 'lo,', ' world!' ]
    search : 'Hello,'
    output blocks : [ 'Hello,' ]

    original text blocks : [ 'Hel', 'lo', ' __', 'name', '__!' ]
    search : '(__[a-z]+__)'
    output blocks : [ '__name__' ]

    @param instance  document: The original document
    @param str       search: The text to search for (regexp)
                          append, or a list of etree elements
    @param int       bs: See above

    @return set      All occurences of search string

    rJ  r   r   Fr   r2   T)rK  rL  rM  r5  r8   r;   r0   rj   popr   rN  groupr:   )r)   rN  bsrP  matches	searchelsrQ  foundr  se	txtsearchr   matchr*   r*   r+   	AdvSearch  s6   
!


rc  c                 C   s  d}| }t |}g }| D ]6}|jdtd  krF|jrF|| t||kr0|d d}	t	dt|d D ]	}
|	rC nt	t|D ]}|	rO n||
 t|krDt	|||
 }d}|D ]	}||| j7 }qc|
|}|rDd}	|rtd td	|j td
| td| tdtdd | td|  td| t|tjrtd nt|ttrtd ntdt ||| d}d}|D ]o}|t|| j7 }|| kr>|s>t|tjr|g}t|ttfr+t|| dtd  }t |d||| _| |d }|D ]}| || |d7 }qn
t ||||| _d}td| qd|| _qqIq;q|S )a	  
    Replace all occurences of string with a different string, return updated
    document

    This is a modified version of python-docx.replace() that takes into
    account blocks of <bs> elements at a time. The replace element can also
    be a string or an xml etree element.

    What it does:
    It searches the entire document body for text blocks.
    Then scan thos text blocks for replace.
    Since the text to search could be spawned across multiple text blocks,
    we need to adopt some sort of algorithm to handle this situation.
    The smaller matching group of blocks (up to bs) is then adopted.
    If the matching group has more than one block, blocks other than first
    are cleared and all the replacement text is put on first block.

    Examples:
    original text blocks : [ 'Hel', 'lo,', ' world!' ]
    search / replace: 'Hello,' / 'Hi!'
    output blocks : [ 'Hi!', '', ' world!' ]

    original text blocks : [ 'Hel', 'lo,', ' world!' ]
    search / replace: 'Hello, world' / 'Hi!'
    output blocks : [ 'Hi!!', '', '' ]

    original text blocks : [ 'Hel', 'lo,', ' world!' ]
    search / replace: 'Hel' / 'Hal'
    output blocks : [ 'Hal', 'lo,', ' world!' ]

    @param instance  document: The original document
    @param str       search: The text to search for (regexp)
    @param mixed     replace: The replacement text or lxml.etree element to
                         append, or a list of etree elements
    @param int       bs: See above

    @return instance The document with replacement applied

    FrJ  r   r   r   r2   TzFound element!zSearch regexp: %szRequested replacement: %szMatched text: %szMatched text (splitted): %sc                 S   s   | j S N)r;   )re   r*   r*   r+   <lambda>V  s    zadvReplace.<locals>.<lambda>zMatched at position: %szmatched in elements: %szWill replace with XML CODEz"Will replace with LIST OF ELEMENTSzWill replace with:z{%s}pzReplacing in element #: %s)rK  rL  rM  r5  r8   r;   r0   rj   rY  r   rN  logdebugpatternmapstartr6   r   r   r7   ri   rR  rX  rT  indexinsert)r)   rN  rS  r[  DEBUGr1   rP  r]  rQ  r^  r  r_  r`  ra  r   rb  curlenreplacedre   rJ   insindexr   r*   r*   r+   
advReplace  s   )







rq  c                 C   s   g }g }|   D ]}|jdtd  d kr|| q|D ]9}d}|  D ]%}|jdtd  d kr;|jr:||j }q%|jdtd  d krJ|d }q%t|dksV|| q|S )	z;Return the raw text of a document, as a list of paragraphs.r4   r   z}pr2   z}tz}tab	r   )rM  r5  r8   r0   r;   rj   )r)   paratextlistparalistrQ  pararl   r*   r*   r+   getdocumenttext  s(   


rv  c           	      C   s   t ddd}|t d| dd |t d|dd |t d|dd |t d	d
|dd |s5|}|t d|dd |t dddd |t dddd |t dddd td}dD ]}d|||f }|t| qd|S )z
    Create core properties (common document properties referred to in the
    'Dublin Core' specification). See appproperties() for other stuff.
    corePropertiesr   r   titler   r=   r>   subjectcreatorkeywords,lastModifiedByrevisionr  categoryExamplesdescriptionz%Y-%m-%dT%H:%M:%SZ)createdmodifiedz<dcterms:%s xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dcterms="http://purl.org/dc/terms/" xsi:type="dcterms:W3CDTF">%s</dcterms:%s>)r/   r0   r   timestrftimer   r%   )	rx  rz  r{  r|  lastmodifiedby	corepropscurrenttimedoctimeelm_strr*   r*   r+   coreproperties  s4   

r  c                  C   s`   t ddd} td} ddddd	d
dddddddddd}|D ]}| t ||| dd q| S )zg
    Create app-specific properties. See docproperties() for more common
    document properties.

    
Propertiesr   r   z<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"></Properties>zNormal.dotm6r  83475zMicrosoft Word 12.0.0r   128r   583z12.0000)Template	TotalTimePagesWords
CharactersApplicationDocSecurityLines
Paragraphs	ScaleCropLinksUpToDateCharactersWithSpaces	SharedDocHyperlinksChanged
AppVersionNry  )r/   r   r%   r0   )apppropspropspropr*   r*   r+   appproperties  s0   r  c                  C   s(   t d} | t d | t d | S )zGenerate websettingswebSettingsallowPNGdoNotSaveAsSingleFiler.   )webr*   r*   r+   websettings  s   r  c                  C   s,   ddgddgddgddgd	d
gddgg} | S )NzMhttp://schemas.openxmlformats.org/officeDocument/2006/relationships/numberingznumbering.xmlzJhttp://schemas.openxmlformats.org/officeDocument/2006/relationships/stylesz
styles.xmlzLhttp://schemas.openxmlformats.org/officeDocument/2006/relationships/settingszsettings.xmlzOhttp://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettingszwebSettings.xmlzMhttp://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTablezfontTable.xmlzIhttp://schemas.openxmlformats.org/officeDocument/2006/relationships/themeztheme/theme1.xmlr*   )r&  r*   r*   r+   r&    s*   r&  c                 C   sX   t d}d}| D ] }tdddt|d  |d |d dd}|| |d7 }q	|S )	z"Generate a Word relationships filezd<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"></Relationships>r   RelationshipNr   r   )IdTypeTargetrx   )r   r%   r/   r   r0   )r&  relationshipscountrelationshiprel_elmr*   r*   r+   wordrelationships  s   

r  c                 C   sb  |du r	t dt tjtsJ tj|dtjd}tj	d}	t
t | d|d|d|d	|d
|di}
|
D ]}td|
|   tj|dd}||
| | q5|durq| D ]\}}d|t|f }td| ||| qXdg}tdD ]&\}}}|D ]}||v rqt||}|dd }td| ||| qqytd| |  t
|	 dS )z"
    Save a modified document
    NzRUsing savedocx() without imagefiledict parameter will be deprecated in the future.r   )modecompression.r!   zdocProps/core.xmlzdocProps/app.xmlz[Content_Types].xmlzword/webSettings.xmlzword/_rels/document.xml.relsz
Saving: %sT)pretty_printzword/media/%s_%sz	.DS_Storer   zSaved new file to: %r)r	   r   r  r  r  r  r"   r#   ZIP_DEFLATEDr   chdirrf  infor   tostringwritestrr"  r   writewalkr   close)r)   r  r  r   r  r  outputr-  docxfileprev_dirtreesandfilestree
treestring	imagepathr0  archivenamefiles_to_ignoredirpathdirnames	filenamesfilenametemplatefiler*   r*   r+   savedocx  sR   


r  )Nr   NN)rG   rH   )r[   Fr\   )r   )NNTTN)r   rd  )5__doc__r  rK  r  r  r"   lxmlr   os.pathr   r   r   PILr   ImportErrorPIL.ExifTagsr   
exceptionsr   warningsr	   logging	getLogger__name__rf  r  dirname__file__r  r  r8   r,   r1   r/   rY   ro   r   r   r   rI  rN  rS  rW  rX  rc  rq  rv  r  r  r  r&  r  r  r*   r*   r*   r+   <module>   s   
	
"

'
E
.
 
 8

L 
#!