From 67fd432dbd964902ffbe07e79cc2995b65c82d13 Mon Sep 17 00:00:00 2001 From: Eric Lapouyade Date: Thu, 5 Nov 2015 09:30:23 +0100 Subject: [PATCH] better xml code cleaning around Jinja2 tags --- CHANGES.rst | 4 ++++ docs/index.rst | 2 ++ docxtpl/__init__.py | 10 ++++------ setup.py | 10 +++++++++- tests/test_files/cellbg.docx | Bin 8311 -> 8195 bytes tests/test_files/order.docx | Bin 9472 -> 9339 bytes tests/test_files/richtext.docx | Bin 8927 -> 8890 bytes tests/test_files/subdoc.docx | Bin 8556 -> 8538 bytes 8 files changed, 19 insertions(+), 7 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 88d3861..6d30e3d 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,3 +1,7 @@ +0.1.8 (2015-11-05) +------------------ +- better xml code cleaning around Jinja2 tags + 0.1.7 (2015-09-09) ------------------ - python 3 support diff --git a/docs/index.rst b/docs/index.rst index b9b9d68..ffe40b4 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -38,6 +38,8 @@ You save the document as a .docx file (xml format) : it will be your .docx templ Now you can use python-docx-template to generate as many word documents you want from this .docx template and context variables you will associate. +Note : python-docx-template as been tested with MS Word 97, it may not work with other version. + Jinja2-like syntax ------------------ diff --git a/docxtpl/__init__.py b/docxtpl/__init__.py index 5244a3b..ae6f821 100644 --- a/docxtpl/__init__.py +++ b/docxtpl/__init__.py @@ -26,18 +26,16 @@ class DocxTemplate(object): return self.docx def get_xml(self): - return etree.tostring(self.docx._element.body, encoding='unicode', pretty_print=True) + # Be careful : pretty_print MUST be set to False, otherwise patch_xml() won't work properly + return etree.tostring(self.docx._element.body, encoding='unicode', pretty_print=False) def write_xml(self,filename): with open(filename,'w') as fh: fh.write(self.get_xml()) def patch_xml(self,src_xml): - # strip all xml tags inside {% %} and {{ }} - # that Microsoft word can insert into xml code for this part of the document - - # A essayer : src_xml = re.sub(r'(?<={)(<[^>]*>)+(?=[\{%])|(?<=[%\}])(<[^>]*>)+(?=\})','',src_xml,flags=re.DOTALL) - + # strip all xml tags inside {% %} and {{ }} that MS word can insert into xml source + src_xml = re.sub(r'(?<={)(<[^>]*>)+(?=[\{%])|(?<=[%\}])(<[^>]*>)+(?=\})','',src_xml,flags=re.DOTALL) def striptags(m): return re.sub('.*?(|]*>)','',m.group(0),flags=re.DOTALL) src_xml = re.sub(r'{%(?:(?!%}).)*|{{(?:(?!}}).)*',striptags,src_xml,flags=re.DOTALL) diff --git a/setup.py b/setup.py index e66b15c..4cf4093 100644 --- a/setup.py +++ b/setup.py @@ -23,8 +23,16 @@ News %(CHANGES)s """ % read('README', 'CHANGES') +def get_version(pkg): + path = os.path.join(os.path.dirname(__file__),pkg,'__init__.py') + with open(path) as fh: + m = re.search(r'^__version__\s*=\s*[\'"]([^\'"]+)[\'"]',fh.read(),re.M) + if m: + return m.group(1) + raise RuntimeError("Unable to find __version__ string in %s." % path) + setup(name='docxtpl', - version='0.1.7', + version=get_version('docxtpl'), description='Python docx template engine', long_description=long_description, classifiers=[ diff --git a/tests/test_files/cellbg.docx b/tests/test_files/cellbg.docx index 89411a2135fd758d8a663c97c123aa842951d7d1..4668431804979be08e41d0075669ef25cba503d5 100644 GIT binary patch delta 1482 zcmY+Ec|6n!7{-6YU`m)l!)(kLSFDVy203PS8h4H%v(c6`&S*l!I(9~uoH?dMR1`uI zjiU&~mMg}wtTV?Ta^%*c>=>WgPwzj^^LgIqegFJ!;3M!tHWs{KaR2}y0M){^R44+( z%TXo+B(i66d9wG68Q2d*nLg8?R`^IvQzatYDo^fwLH3IzD0uce>X3`r1vqZ64$4ama}j)l4JXD3AByr~Ika3fk z1yUk+BCgULbaU*awCp`P)y2}qHB}|2Fst{SdsRuabH6`VLDZHERdt(Y$0(re8T~eQs;Xm@zF=or&H^$O) zz_IyNr&lzRH{*<^{AZhIyBFc@Caj~7ez)Q}@eeBrnCy4@PpCU?ipV!pZAy;Xcj!AX#aD%pg)5cc^wmMcMZV7_N?VD@W z!^|bpHHaz=|$3$IkV0JCiC_C#@n^Rjm*7bVhU(VKLybg(;Fbu@41rZI%)>)14 z?YC^LF7{g6XBHF2K4#6*(8gBYHxGRz>UDTv_}(qi>kmhe?H^v~Dbn|NdxOYVR#*q0j7F^AWddYp650yq~BL z=3g#n>IX?Zzm;hfYV@krQ4SYo(cf`<#{CdwO|@i0?FSAq6Zb3ZVW(1XosUbT5?BT| zVOWW=xxrEKEgr7XlnCbEHH@dyhFo2g#&T5|smE1!q`vTv#dKv+qL(2{S+_74Eqj>JSLaut3RkFV?~hXjBjY2yhT6`n?YTbdVb31_~{+`_;TJ zHl>WS19N)2Z2dNLP@5=&g_7l#mYt2!EFJ*JX2bIDZHZo}bBhtI+e*htVmH+?% delta 1489 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 Yf;<9FVJKQLOlg4)1pF$g{`af@0=Y=1DgXcg delta 1707 zcmY*adpOez82-)NSuPu<#b%}~Swx&D>L5Z9QjI-_T#{nSHC7X$$To&aE+?X*<+5os zDJxwQYo7gxm0SMS&ws`zJK2DdB692zyIFvw$p1Th^HG^76t%-BJlMhwjPoS z0!xrZ2dVvPDrMwlq|8lOB8V&*IoB4sL&szRAYB&#G$f1h#1p|AgNZ@05h0N=xP*vf zqJuq=2y6A$_t*n^<*>TSd=a0biH$Pl_88n$w>3^&f9>TE0quWchgU9V2VlQ5Y3lmM zr`9v{m{9VZ_oIdh!L`+MSKjt^lRn?SXfXe+XCHb9enAT#JH;fY??3!ENl#HLb_$8> zjiY|-wz(;TYfOpU2KFQOCoLpCRbtz_Zr_r=CQo$XvR_t-n{7|ke2`01#3T%cOBY~9 zM*AFl&R(Kc#0(DZ;+MdcvHk-ipIhRX!4=%boV_Kv?U86w1#^{NPD~738Oblp zVv$akH^r0)0c&Pq+ildfLwsE{anJIyZ;O6j7s~T-*#)d3Y|5?4zzvXC+I*>bdKvao zjM?hc#g|3zPbR%;3Y2X0&%EgvYJj(i+(wJi@ib5geSYv|yTxqSPkZHJ(ghc3n)7i;rVO&)fP zDB9)SD-JbBf-QK|gROHs8$%aLl=(D6Abg|LgAvwUE@)c?rMQh+M2UOmk$=$xti6q# zX;bWO@~bT0A3Wji96>#H(cH@$tlbR{zf;yH?&`F$Y6ug-Uu;U%`lidg?;Ye>{>Ur% zkT-3XcYJ((GZlgS=gE7<@Wa!7Z28o1v0G5Jnqp4r*435R=Z>>hhP5+8;0Koquc zjA^6FxjsDKhcm16#XQ|EMem4CCO9>Ejl&RNrEHvHVY}M*lv>rWMredH2H&-Tb5d5> zy?%?w0I_!?IiT~FRa?Q-?NLps@m#4il zBbbV~{O`q#wT@mp4j3FA7{h7BFtTQ?60|JqDKRxrW5oOHE9316m7iK%_lGJu^s3x% zypc1mt6~~xadadjBk>%y&MM_l(x)c%)8y;ICpIX*zV7pcVm~N>S2?0M%r?2Lh9Bla zn1x&&fu|!Pu>2hHnB(!xMF-P~vb(I>f|_Ur0|I+DYmkRupO&IPo4!m$y4)t}yW_=M z8PoZ-jU@f%{VM*xl@qLfB3>cmk=N`PKOpks2b|VVjY2A6uD2095GZ8wFA2%EM_aGY zAq)Ky?Fc#XKBG;kB`w@;6K!s@I5sJ<>TZ5Nd0^8I#M;(oF{GBQUCT_k3qd`wREMQ4 z5#}8`CpXvCv-c7f`!M@4aJ_3>8fI(EWwLskbEP8iFUJ zG{CSgao0~}cN_E59O?q~UCJNXuV%LLV_o$eY648kU-YCqWM{5p)t`-u+$^sTjM>al z!r5v0}y$Ar%T2V_d8RSl<7+{dgrof)@SQ-cb)FnF2-!xA2Ck6)6!>%tfbJ>!a ztVFl$zEa5`IT&3NjW%935~I~4zRLiBzrwEv@xN$FvLk&L(R4kuj@0qoc($NjB9w6g W0JRmR1d~D9a5^1rAg_p8X8#3Bv+9BX diff --git a/tests/test_files/subdoc.docx b/tests/test_files/subdoc.docx index 0d5ff32eeb23d6810dd0b5c016f5bd987f968b5f..02c6f0b75bca0f31e3e34a61c5bbd73ca2aca224 100644 GIT binary patch delta 1488 zcmY+EdpOg39LImdT;{SdLaSNmp*S(OQ9H?XGDnjn9Uk}VanIb6jTNbbw$TM0mkm!U zLs3Yz=GKlRciZE3kRl-=xt&?Zd7eK1yg$$T^ZtCk-@jg;EP0l)1iYx2A^-rA01@wB zElUB33iJ^j1pU#JiZFjP4q{;-l3;{mP)6?=hyj2p3;^T>i*XUretLcpzQi#9@R%d< zVWBOq!{K}rm8Q4OkqwLD%{L2}SsKkp@}8B|em-^=-`>J=yHf3Jz-q+rzp^NjP#fz6?94OLb1X4^Khx;Fd_XGQ zsa&&SDLE<1^BYxiDJL=$NYNo#*gBRF-#1o5;545;xazpRsj@-K-UfqMXI=AYH;iI% znz5`lqalWcjTr0I_nDlets7foN{bckJ8IqjxxQAA#!NQSnMAMi4$||YYZ*FHqH?MC zF9%du;7{35*d!*%ZKM6F4L2{rCblD-+6=y|;UCMeY}cl%YudB<8T;MUSDG~T1)*;0 zWEEG{2XZu9a`e2vg>T%txau{}3s&mo!WLRoq7T8Gg8x!IoMhMX;VpF{;R%JmHO%OF zmUqLf^Nxu|Hgtf~7T3oOJ^aRsC&9s{tx0#-%8d^XknT)m%?~FIdb|nOFOQb~tWxlb z6+PmrD#!ldpkOnZYC7SX>)Xo3pSia0V7vv)q|~K^Jm%h$&`EGMip?5(U=2>&+bwdX zzFWQ2Q_A32aHD6-J#aPJ_AppMn{!%&OLdgA4^~8X^U21YgNyNVS2;))uIzo^BxTh* zl9&i1p$eNf7)I4y{^D6@RJ}vXQl7e1!Al!wXX7x?EaN5C<%M4`b8YMG49vR~+=XK@ zVQZCZxNPH-h6KbH=Yj!wXk@?XS^mc!UZn1mgu0V#(IWRCQ#Wg*mdUEKdkH~dLF!Bf zm*O8>RAgOGRn5sgD!&iC*G~74({$&Uhw5umK!YE%`ty~Lli!KjJSm5K+NC3zo5Q7> zTgirP%91W!3lGjGZqNu<#8Uf!*JULC z*jn{d&@YdxTGu=sCxe$RwsC6*3(%a|2htTxIWW8?qrHbNVV*xXeH2FuK;(~|BWsCUvnMLe247US{<&V%N_jW6Y156$RmM>p~O(46Fu7 zFZ4YWjoj?F$`wCv#kTEIhIpETQq(2*CGM5>O|@uL1))Fi@uW4f_6FN!YJ1wJX6jGf zkYy~j!#;*jRh{3a5j1<9hiZHRtAgh0PDfo0^z>E?KfAegx1P5rS!6Dhy^t8>=C^2A zsRDTltVDc&qNI`uZ<-Oezub|?2;t4%X>3@^-Uk1~qDOj=gFn#YD!l?0Qi&kn zBy{L7_=M0{fv<}Qo3DEwO6)XrCi1vYr;sK>MXDVWs=FFi?q_<@%hb@q5l;;v0)x(X9`ti&Kz0=D(lAgLeP` delta 1547 zcmY+Edpy&79L9e$v9ckzLTw{yLkox8uXCT{u8T|5&;`SeyR^m0p*Yw|qva^dC6^pT za>+!HF=GLFKbAQFFM8?xHtWhD#%@zMaWoBuH;j2LhvAPgTB8c2x5#D<2j zPxKOo^d(zf-)@J@0q)}y2y+yQ05tDkX`I5H3GKn5JGfQYJ6lbMeB@@y9 z{m;!~hMl=h-kIRZVl4>PCHdu;tRwvyE#Td3uvrpqD&Nt3WYn#UrXb__CbM*fqU!6{ zxl^|XPtPqUO*LYRJq{dlD(h(QU}fZ173JXYnduY6=ND0CWzrWAPZ-%JCy9jWDsrKO z+vn7Sjs0?@Ru4st%?%2>FX;rMiBs?Ny;=^{*csW;q*f1_?1&cRr8d+J_B%DI;xbQXEL08?6`Wi9S~ptXb_ZJ1%q zoe7Vd_VDZVw|6J-UM#ZTeqO1-OUQP8EQ@6xWZRJ*_mo0hpI@C%1K&+(4PRNDS?`Qi zf0b9B|6<<9M0-UIyZo^!s?+d}>6x3Tmj%a09A~2(4EmhxRNbXmvXU2!bPm8@zIqt= z!k(SLfTLq=Udwp1>_&?@&uEFs?+VV3a#E-KL5^samLX2640<|=2C?f&B4fjDE$`!o zreR3g?{9x51`=BH62r})&Y8Cp%3~g{m4xi1X|zEnh4uaRrq}k*HCST$n8W#g28Ywv z)6IE3jA(U)^_+&{kl6W{9Zjf5a=gG0kx}83GUD=FIU}RdUvyqQd9Ze`#I??d-d@KP zAG1{0_f#8Jc()#(x7!b7nXXabUPVY84OAi3g*Z}rtlT7-#@4dn#17`F!539AYD5XL z0dLdh4^9U6&wqgMj@Fb!2YYlmCmp|ZbeJ~j+o97&;=E=E2eHk`5_Ub;V>O@_O1^rF zo_Q!($nn-@H&aDAOyR5$WZvaH7&cAwRL5DUqL`D7irx>sD<(vYvhy`-9u#3ENd+a0 z)4h%!H-ddz`iS|{3pFmmZ5u0=X4gdGWdd_=jXh$vt9@TN%)04QrWUBDhgmn6-oL?t zeL9!VZno;poF(DS`mR|6f5I0n z5;5`!ZpDV*r6EJp#;%D1!;-Oz(jOPPik*j%x=TTo`SxyN#fW3&;ar73^oMy=v&9*aNA=( z4&%)>Pv$`*~R#lG(lfXZ}tvml|aON|MFap_edff<#n5ZyFX3fxqn1Ms5)g(8du z>VPm7{~2i1>j*96W~8iJPMqPhO%n_N`}n&3$ROoiRE=G5br&2+NCx~LH*G7!C_dZ7#|-mmcgB0)YD>TLk{UG|6YOfXBa4n~{42R|g7Vm6t^UARG$-65CC_ Ql0l!S+DghIH{hG$zn)!