From 1b58ff94aa2afa37729aa1173c60c85eaef75f7c Mon Sep 17 00:00:00 2001 From: airmang <38392618+airmang@users.noreply.github.com> Date: Sat, 3 Oct 2026 04:29:21 +0900 Subject: [PATCH] fix(layout): place a square-wrapped object after text on its first line from the paragraph's top A square-wrapped object whose control follows text in its paragraph was unsupported. Hancom places such an object from the top of the line its control falls on, the paragraph laid out the column's whole width: on the first line that is the paragraph's top, as for an object before the text, and the lines reaching its band go beside it, the paragraph's own included. The estimate now follows that when FormFit puts the control on the paragraph's first line; past it, the object stays unsupported. Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 5 +++ src/hwpx/layout/pages.py | 33 +++++++++++++++--- .../pages_square_table_after_text.hwpx | Bin 0 -> 8383 bytes ...ges_square_table_after_text_2383_down.hwpx | Bin 0 -> 8376 bytes ...e_table_after_text_on_the_second_line.hwpx | Bin 0 -> 8458 bytes .../pages_square_table_before_text.hwpx | Bin 0 -> 8379 bytes tests/test_layout_page_estimate.py | 17 +++++++++ 7 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 tests/fixtures/hancom_saved/pages_square_table_after_text.hwpx create mode 100644 tests/fixtures/hancom_saved/pages_square_table_after_text_2383_down.hwpx create mode 100644 tests/fixtures/hancom_saved/pages_square_table_after_text_on_the_second_line.hwpx create mode 100644 tests/fixtures/hancom_saved/pages_square_table_before_text.hwpx diff --git a/CHANGELOG.md b/CHANGELOG.md index 9cae9b4b..d8d19cba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,11 @@ ### 고침 +- 쪽 수 추정(실험, `estimate_pages`)이 문단 글 뒤에 놓인 어울림(SQUARE) 개체를 지원 밖 + (`... wrapped square after text`)으로 두던 것을, 그 개체의 조판 부호가 문단 첫 줄에 있을 때 고친다. + - 한/글은 개체의 문단 기준 세로 자리를 부호가 놓인 줄(문단을 단 전체 폭으로 놓았을 때)의 윗선에서 잰다. + 부호가 첫 줄에 있으면 문단 윗선이라, 글 앞에 놓인 개체와 같다. 띠에 닿는 줄은 그 문단의 줄도 곁으로 간다. + - 첫 줄은 FormFit으로 문단을 단 전체 폭에서 나누어 가린다. 부호가 뒤 줄에 있으면 전처럼 지원 밖이다. - 쪽 수 추정(실험, `estimate_pages`)이 글과 함께 움직이고 나뉠 수 있는 어울림(SQUARE) 표가 본문 바닥을 넘을 때, 줄 캐시가 없으면 지원 밖으로 두던 것을 고친다. - 한/글은 그런 표를 흐르는 표처럼 쪽 끝에서 행 사이나 칸 줄 사이로 나눈다. 표가 걸친 쪽마다 곁 줄은 그 쪽 diff --git a/src/hwpx/layout/pages.py b/src/hwpx/layout/pages.py index ff81f213..4a9955f4 100644 --- a/src/hwpx/layout/pages.py +++ b/src/hwpx/layout/pages.py @@ -170,7 +170,7 @@ import copy import os -from collections.abc import Collection +from collections.abc import Callable, Collection from dataclasses import dataclass, field, replace from typing import TYPE_CHECKING, Any @@ -2007,9 +2007,12 @@ def _wraps_top_and_bottom(obj: Any, column: int) -> bool: return start < _MIN_SIDE and column - start - width < _MIN_SIDE -def _square_object(objects: list[Any], runs: list[Any], column: int) -> Any: +def _square_object(objects: list[Any], runs: list[Any], column: int, + on_first_line: Callable[[Any], bool] | None = None) -> Any: """The one object of a paragraph wrapped square across the column from the paragraph's top, before - any text, or ``None`` (:func:`_square_sides` says where the text goes beside it).""" + any text or after text that *on_first_line* says ends on the paragraph's first line (Hancom places it from + the top of the line its control falls on, the paragraph laid out the column's whole width), or ``None`` + (:func:`_square_sides` says where the text goes beside it).""" if len(objects) != 1: return None @@ -2025,10 +2028,29 @@ def _square_object(objects: list[Any], runs: list[Any], column: int) -> Any: if child is obj: break if _local(child) == "t" and _t_text(child): - raise _Unsupported(f"{_local(obj)} wrapped square after text") + if on_first_line is None or not on_first_line(obj): + raise _Unsupported(f"{_local(obj)} wrapped square after text") + break return obj +def _on_first_line(measure: _Measure, page: _Page, paragraph: Any, runs: list[Any], obj: Any) -> bool: + """Whether *obj*'s control falls on the paragraph's first line laid out the column's whole width (FormFit's + lines, the object taking no room in them).""" + + place = 0 + for child in (child for run in runs for child in run): + if child is obj: + break + if _local(child) == "t": + place += len(_t_text(child)) + size, refs, _ = _text_size(measure, runs) + style = measure.style(paragraph.get("paraPrIDRef"), refs, paragraph) + shape = measure.shape(paragraph.get("paraPrIDRef")) + starts = measure.line_starts(_run_text(runs), _line_widths(shape, page.column_width, style), size, style) + return all(start > place for start in starts[1:]) + + def _square_sides(obj: Any, page: _Page) -> tuple[int, int]: """How wide the text beside a square-wrapped object is on its left and on its right in the column: a side narrower than 1440, or one its text flow leaves out, takes none (0). Placed from the column, @@ -2082,7 +2104,8 @@ def _wrapped_paragraph(measure: _Measure, page: _Page, paragraph: Any, wrap: _Wr para = _paragraph(measure, page, paragraph, stacked=tuple(stacked)) shape = measure.shape(paragraph.get("paraPrIDRef")) return replace(para, stack=_stack(measure, stacked, page.column_width, shape)), None - square = _square_object(objects, runs, page.column_width) + square = _square_object(objects, runs, page.column_width, + lambda obj: _on_first_line(measure, page, paragraph, runs, obj)) pusher = _pushing_object(objects, _run_text(runs), page.column_width) if moved: # the object went on to the next page's top: the paragraph's lines as if it were not there # the object: wrapped square, pushing the lines below it, or alone below the empty line (a table that diff --git a/tests/fixtures/hancom_saved/pages_square_table_after_text.hwpx b/tests/fixtures/hancom_saved/pages_square_table_after_text.hwpx new file mode 100644 index 0000000000000000000000000000000000000000..1372a3e626fd55cd290bc40e10410273e7ba7aec GIT binary patch literal 8383 zcmZ{J1y~%*()QvIEI0&$6Wk@p;_mJcbb-YKi-r(9xH|-gKyY^t9^Bm_I0Oj<` zcXLjj`_DYR)7{hcPIYZ}RacdYJRCeO;O~n9;CCu2jRS2w6=Z0!1KWWh9*!UrM@L(* znF$2!V9#ph=E&#?c2xNnA?~}Q za|CAl-i#NOP**1;YmNa+D`rX&{@0$RE9%ZN*9{f$Hp1+jPL zw{jJvw1Pk!`B_=r+}v2KOrSt^EM^WYHcn5B+1avku(7kV{^x6ygvjBl;n0M)(%dBl-$r7*#4=;{!}w_a`>xe>H@YkS8}m41wr3H`F3y? zq~xG{;^jYVJak77A8@Baky^Mqan-IT!H4Q zEfZr*pAg#yRwFUxM4?}&aE7as6ofJoOIKHr3f2Qcfp?8dJv}{<7&16BkwLB_%jw?h zIu=U9jB*&fkt8y_^0K@g2vh{TzciEvSSfUsqAwEn$NgWtszc7N$Qa#~k_$+6 zV5lPDT|Q-VVijk%p{GZ6Cv0*fVM{fI1UV2~a=p~+I2k8Gm&8Xe~- zHvq8+AO&FKBV@NAE|JIF-EvqtD1E7Sa<;5= z(x97^k7^YTnJ`PC+oeQmH29Rmgmr6@g!X2p`J*8O;{%ET)s!}D*>q3RtNL&hcA_2e zExi&eBDl$lo7~Z;d!ghAr?xlM&lnsSu7AuQlxH~9_%#N9j$2y!a+zwke#v~!k8<^n z`>FD)b>UvGdE5@U&mm+R`Q78OU6o%5}(_E*o|Po&HqUJt=bFpwy; z$#8{>P^Uv(W3rOw=cG;*{DfJku0=5(j1YY^x#r1NV6oM}wH6G;YScaJXF+$_4s4_F z8OOv4v*pdfRwGC$>(k@OJTmfLZx)aiJYJVZqkO#f0kcuLn4ncCSs&5Gf>e=`gOOX4 zEI;^puyJn-44Q7WZ zu8A|z1SuX9oqViz9)9{~Czdm}^5cW=q@^Rg_{hu>bE(=>xRyBdcW%%OzqKnnG08ZU z1k~C*@b+6?l3SVznqBjijWYBgerKYH6m*y1C@kw%>j5^Ou|w>x7Q*BV^k_Q-F_GQ| zmwUKB`^X9ArpIBN%Vjr;dM!KC7boO&uHI25gn&_z-RBGpaN*~{n~^1ZOFz*{tlRlH zWwS>0i`ba0kg#3y8|l=7o~$!3p$RV`GS}xA7*SSA@#q36uIxv~1vlW$n1b%0Zew4I zpJ4}*kwM~^8=7!ri(fmrFf-TjI2dWFS$du?H*qk zA$OKVog;A2&RG#DSJ>ldinjwU)<=;t|OZvTj?YZ>O zXW(EL=te~%B!n(Za!Rr_z~RKwv0Ce}a{40+Q8O0zo#NVhE+FaSe3|>BCd&JFP6|;5 z*Y)#CezeibPCnr9esXK>NKac^E;~%&HOBikF+~mucgs6G5xdj9xz$P$+0WfxU2cL) z4(T(*M{h1*ZfI!nP`aqL^n7qJ)7;YX5Pv2pGfLL#l_WA+*GiCy9FbfoK784Ysp>w& z`d%SIafy$+LA*xhMpma+>#t?zF+HX61#f0mJJ2XkwXi|9jiErTwC1YK^HG&PL24V_ zY34R+un1DT^-Axu2{i09U0ST9Qz6Ipz@_(r2xkyG@A9ohKS8?D}G>=UD5FnfY=Aim-> zS@ir=+uhsTw~uH3BYWBH-T4uR{geKaQb%Tw>}MQJ-y1Lnj&)ggpYvm)mDGnwt)qY8 z*G|m<0JE4$J1CqQQNRoL9SD)D6;V-<1!clme%zw~*Y3>6Gi-KHR(SQU;TToyp&A@% ze1AL3ovm$yqvOYyCR@$}@w>D{7^n?Y-4^8H0LtX5M27BJ*u)o6%~Nxax9^5R&y;d&_XS##vCN*XSIr_{LA49$bydU%IBRdr-{6iLU@xxQK1=SmYgw3Ag)^-tOUC_5KnOL%xlhs*iiCkujQS2a;dPFSSpgHuaNDAC!z-Hs^+olRAW&b z1R6`|8WbGo1zOA1?N42ncg9nG&E%=GEnITw$+D#y*VJOp51Z9&=NOVfG1~a>HYn4IXQ>%1ZM2Tl`>NdHU6ToDHUz_)FxZ z_#dU=GfVFeR+jNfsV&Yff~&sR2@-qwn0pGIUov4DrE(hOp0)#ek3W*-uDKR|nlTRv z8gB!7+#FtNkACpHj1R~bw61<<_X`F+u9xSCMl5dJ!77^LQZ|W4xD^EZZVH&kSwUGD z5>n&*i#w8DT5+5%#OmSF`p0H5ay%SYLpY2oKAh?VKsCqSsvS$|76j0`#03^}yXV^d%=_*7$eZC%Nu=P5T_}LyHGu3`rNf z=_}R+qQ5&Wb5vumi!&VLoMbS~Ktc{hK)n+wPXnV(Ccz?4v zfVnD7e#!5$mprPv*}nl+rH9dFSkb}`S(GmLD$*0jMU#P-fU}loYR4T@`<~YtO$jKi zz9Fj$OTw+$UmOyC)J^|&?W;O;7!FORY?218#kBV0&GCNyszk?>uRpqZ-}+Y+I{N%K z@#?!>d|2(S>lGk(uhe3SA(*-EX{XP@W?>`F>?!u53OgE91Uj}tg*yq#*SLf5Nmk(p zZP6w#t|v~`hJ%tj0N|GeI&4^iuMa6G5XWcnHPWZS5Cqzn>3c3Kqo- z7rIj`*opsXexvO*aj^Q?r2@6a*|Y_#gzBADcwRP&RL0|~-p(COKIS9lzg-n|X5#u4 zsMlg91OVVcotOW*D$XFYC;yP`FK0zx*?F-6>a37lO^GYO-j(Zuq!YL2)Fqvm`7*9H zvgu^Df+!owaV3Q=7i=t>J_=q;VOC7OYgcK$$9NBr30?TAYd2iAWY3Wi>~luCa=U&X z_?@-Qt34#aEnr7A^+FR;Q2b2R4?;w9(B}EN-D~}e+{m5zULRQO*M7#ehLR$vvv zy-BxQzph5N^uem6P!Dm#WhW~1e=2kxsKXAxm#Nw?jamx z;U)*)F#A<(VR(Y0O}d;uu$$4l7Zx9Qa(iv|y`L@_btLg!ydPfP@+@Q6OYBhaK$@qK6W0(BsWTQNd=;5-0pP2saYwe*M4MJsfeCWs@zS-9d z%z2a0#Ojk42nhLrP#Y_8dCPX-PoL4ihTaHK1xniCxV90D4h2j9%re#?cl{bcg^-9V zj?oX7S>4dyMi}t{spGu*pg7Ueq#v6iWQL;SB(=X*6VwXIYFu&#Hl+(I(27v;+Iuxc zV$(3Oaa9Jw1j7pQ#ZHM8CYSJP%Oeft_28S5D@;|{C2bDsG|>l(+Lp%Z+xB}X`@Cnr zsAoc8&Tpkt2zGyaAG&zTLkpo3L(xH`DgOSRZ?L}D`oc!&+YcWp-QgANIbSj)ne-Aq zHr9?inxFF!ulK4j1(_5jwme<6>c&4A4eyF8Q+&0>5Vi0Fj*w*=4%a@-af@hT52^1q z34GaLop6(ggh`D3$SXb~dMpg@(4MiRcw+G-Hu_Tqqeg}U8kUbVvn23xdfeFkk}W;* zT{ft8GdZPlxm;McGH)5c5n+?QNp#erC1A4c zCV^CxID83IgT9UuH#+<|gwrHvb+B*SGrca9_WA8GmQ<0YU4s14g9odAJ~w zKK1DyVM{?E(_)R`6n@j{;|*(QWJXkhuR!oCC-fnJ*`;H#iZaUz^Yfbd{< z2w0J10b0B=iPd1xVIcBr|3%-Lanqc`!0S{|l2RProV^GGwQvy1R{{k|L#>n>6S@Q+ zzr9-951{P=ZBW{qDcfJ!#*863Tfx0zNDOBNGoI4nS|Nks(EjYOi8v6`%cmt)a7%9+Fzo3JHzik*P~F?mKx9> zIa=%7{svD-wo0{3u$)0+81qbCB|=}M5kF`wcKT%#GF6j_XJnXReJPvY!{snpCRyC0 zJ`532#%&yIl`HT2d3KRCLZ+m6xUa%Pgz7>z(+rLa0p%N+T@A*XHwOBeJ-Fu6U4a^v zBgeuJthd;mmSi^pQSNij%#+o6LpANZ1fs&I1mo6wTh3ZH@qHrMC*L!MSuq#S2=C<2 zlRec$KV2q|viyLog9I{=BKYfsZe>t)^P7d#EbtVs2GEyo2g^&-`15lTNtOdoMfIe?xNXgw7}?H@&{1B3PZujIeU+%HYcvDZMTy_b#0=Q z$UYB%{@6OGDod72q0e?!t`(7-yE!$xB2sZH%hjKLg4kzj-`bC(0_4e3VvjS9_=4^b z!Xwy-|G@;d_Jy1(+&zwK^YxFAFd*upN=n@`OSsm!Y_}iVIHQi0sIj$I*6|(HzP%ys z;2BY%;&P2bpVez0o-s}$DS}o1uaRbpLE|f7?_fs|7ihZox5AWo;et1$DK& z!?w*2<*!B$#Q#1J=_-F8^oAaUNTH$cr?|O_6UY?|a${9-a@7F2Ls%g0kj-t+TJTAl zE^!HNC@RjRoLbn1yc(k%+OT`$io&PQ#>U9`5m`0tth2@F=+qR%-Sw0FN95G3NfB7d zmhkJX88z^>NXa~Y6TK=6@N#KlU`{$ajC|&-8kzteE}sdNbF}OoBC%o4fK*Fl?$PJg z85C1M@j{OvmGf|)9T>pB*-g;B1oc4KB!IFDjW`3GK@bQu67T$UY;%cHl!s$~9`q=e z+?-a16jL!zi9fD?1~)41YAqHgD^pPR@J{_~EUeGhWA&#;!I5_8ew;OG3UhcjB5vi7 z{2C^zLpi2)eO4+tD@nOS(lf< zs}ZgSAW89+jjXDXL$9hC{b`b83TC!L218mnGgo(VA<^4c1RFHX>Xi7-H+CZ}?My#) zWUm?nIYUFU2PThGFz}m{J3|Sy?U&CHFMxZG)H`JVo-S=-*D?xps%CJ|oP@#&VzR996z`X))_|h{{|mWeLQluq;d{(lfNYyDvo}<)xx^p%KVs-{i!$ zO!KlU9=*t?OCg($|E1YWyc>jTocfA=8O6*dIF{O%Er=K6F2cv+Xp3d6W&<@#M6K>+ z`l!Wi?Hyb0P=oL^Zb3wzC3u;=>m*%*Yr^JAjHt49OhJ5Altk+1SZ*Af?E#)JIdd#g z>5rW#DS@fTEK%KTJklWwqwbXcD2pV*A)hoPAZm-$)m{hVB1XCEuiZN2X(9GIeIwfV zG_I?r=O6Uv(b1me_O7%aI{`^P$ULC`TX?{*{SItc0H78T0C-9g{r9Z@Bs^$-g2l?w z;*;i3Y#Q71J3Kizs+Nz`l0+w+MH(!PAYo%BbSZXE3GAU?C!EO$B#XMmPFOPg$3(;8 z3&8e0o_CUD@!WX&y9h&L$czbm8i(7v_0t52fyh!~Ht1T10luKo#RwOdJrR<1A0pXg z6&{t!S5n$eD?i__00zDr%-wzWm=sw4@!7O>XN@F{kR@cjqr21J27jeV#@M^58%-7; zE>z|$S(h?|rlc=rf?D+je51-lx{XHgOr}Muk|`J&>wZwREs<^Ju>f&AE66RZEQ8kx zCGfy2P5;B1nxn01ZisLBId^8om7I~Rb|#9l@HTCk->-@khF|ddkU2YatZj2U0oNZ7Z;&EKkII1Ic z{BZ1;Pfej&I))i0H^FH9&`H8Cw|Qmt`mQ`MB^ez}qGO5>(kmG1N{-)AS|6saO(JmpA*3B@@E z7;(0nih=U26^HB%DaVCtvH`+93(UAJE@icidTC50A_Lp#S1Ejq%9U0qY+T!?_NUGL z+sWEG-X^|AEw2}a|GkFDl4+*kpc`-zTK+#95UP3Js}5VkvOo7uh_;yzztZq4mMIz& z4@0^IPzW@2-o<=7-d}Y4s#T%l5I5lUfirBH-ksgFh^0qsWLn`_IFAbpsoqWPA{VQg z21g~QkfiN4Q88}uHsyS49ewOutT5wP9qylceDQ^GMP>U|uv&^*pTjHVU6Bc8jien^ zZv2lp&EDmdz!ZShT1^N<=kp>Fz8tX=x@QdUcKH8bFjC8DJ=ZzOG!=GVH5Y%+Xrvn? z$v9_|&0>XB;argIyaRk?c~U|ViFqI2jR20?@ligM?|PhC^vmr=sRJ#ohv0tto{`dk zI`2Fv%|+(W>~j9l=({MTu}A8@HELveYKh|L7PtNS-(quMTr+qJ-Eu+D^5ka!S8v&w z*n=%V&X6a4%^e~CteXuDp`5bj#DPE}{m|3z3ec++O5x2AqrR|6n-957PMM85;h&Tz zU=8X>+Dws+VIly+t~$($_iZs#_RVMc3hygyj_GIQNyW>yj<5I(2_d{82$p1J3Dz{! z!+yt5m0!z{dN00Map(fTVOc2#DkWL&FTMbaxEh($Yu?Qj&snNp}fIgQLVZ z-247t@AY}VnP<=0XP>=(XYDn6uT)n;K_v$K{hm;3ntCqk90rUBf~Wx`ADw$jO`@_I4uT$RFDO42S|j zoZLWKu!Fgy1;oKh6sV&u%OMD)g~Ci7EKKbj9l)YMPcRfnD=sEt?ItWQC9C^45-k$M z0V-_mCJMBM!JLG-xZK^{Ijv2RK=z#Gj-0kGcZ}KFaq)12KwSTM8;}-eY6XT#{^nj3 zsHdhWt*)siC8MRKrU|6AH??te5e4!idk}}a9_X%T?&A1Y&&(BKXQAq9Zw5v_LGtYg z6$SDD?|AtSTX*Y0(*8p}qCok-n4(p)w1k+0X_0qUu6BP-`7aHSOYHx|cPC{!04jow z%L^L-Sa|oh?4=wXU|M42wUjHl8D$T{t?Egly|j%?ogg&>uEt+-Q5pTky9@mBKTRGQakAHa%gxqIaOODRcNAK4`hrBJ%44+gDT^PjcU zZkU?j`GwmxaTz~XOBVZigkrQjK}RMpy>M{>tLEAxd*=ONp{J)O23MYFIwr(zcrnvw z^@XMC5St>dU<{?appt@M2O2%8;7@JU&s=o+s&Qw@-^KzTKWV@ytSc_=&k+USy?0^ErsvmXobz1_xS}{KXLT|!9GR0-D&Z}e~n708(`H*Ak({V6V z_S=lYbuQ*k)Gz3&m!t~LtW=^~ z__zRr#V3#1c(4k^D9PQt?Gz^E&MNt&G3GH&??VJXx?x9ONB(-^dofF9vQ(XE9{s`T zD{wu?2roW5R3b3j!o<3UlkMaS(Pvb?$ynQi7Auaqs%U+FR|6Fu^j|z0{<_O4#^S!t z=Z95H%h!U4>%+>MGdS%BSpUJRL-}OvD%0~-6F?fk)=$iSPD;9fqwC{-&4Apw!Qt_u z>S2?9N+FhY6l~l)jd>gR;KR$Tx9kMJOjEF5O}B&^!Ek*sU(!$N-LIVLNqN#3g$W|x zlG-pRw|Ry2V_m?9u;RpprFZA)_N(U{r^1*Q z-u!o+pRIG(1}$Uu7=4au>zJQdm6&@O*s}wr~#? zi#-vgd=}xduWv$A-hxlLs%4%{K^6|ZLkh3-f@gTQU5(}` z2ydyI%+;(4vAQhLWc^%UEz1hP8L3QEE)PHIfqgMp(r}F$&*esy%_ARZn|3{zq>$B} zz%Jz*KbB0A6)=5KNYE}I%<}NiYWkPb*nqd3T=Z)p8uR3Q`t~%w1s=mK1h&zab~P7v zd6)8_dfOYpeyej@D>G5^A3~KQtUc&E>~t}r9@0D|m0g-WA}z-tnEl0Eq~c2hrVdfO z2hL$to*oZFc_I8PL~LL4LB_F96{h zoyBSEbsF!UkJ^ce+o!&gOE2olJ$@}V{#uO24IdXb)>;*g^DNB`bYN11fUL(Cb%k`9 z_*-5^?#aZ2Na3yNpwP^BckZ{GVhc~W zj!KBC-4arz&gG~pp$3PRuMi2uhI@E0+mcY1J+=UfNPCnsh)hB}v}IsnJNRP+(J`Nd zWkTgEq+#VcFya{&VS&rWbyb%Az*j$wMh78ybsO#yT!9z6{Epc#!)f*VXjx>oXf{3I zCDDqJ>c}Kd0{jJ1l04?)DwFq$0=2B1AWF_oFucwaC8GZ$?~ap8dvb; z28%@oK7kSH(&6FEkusAqtwD~5R!;AA_iLs?ImufH_^(t}R`UTVp|h19w>p?_yj_%I zU;b#ERSjT@Q*-fyMD^3!@W*)B+40%qiLbC-w>?+kk@m2$ z=z?SBG{wQIvwH|eCKAj~^cx0##CRF*83pK1xQfOl>(yXYvX!E+&U`dkQ z#BrJa6+2K0D_aO~INyS_P6@uw{A3%nPop!wQ|}$=)tY!%64CeF`Kb47m;D(K z8tD^q+L+r1*)Ev&Sr9F)HyHHl8&UZLqt`uq&Y!5s$)6CdoXDBH{o{IT)<^zrK~CGa zKKkM*ft`JUXE{zLb@Lv&=kQnOmph(yx*45E9=yc$?PY=KE2Fe5;4=3C0&XoOVV7tw zc|1SCl_mYg84<7k;W<;O{6<`xMcFcP%XepA7*(p@mc9dFnEdj=ZZsavVlxT@C7A?2 zQkkNOo1JXCa?W?YJq{e+&1>%}jNb2`2%L~TFuw&I^EB@?;eP(E&$W#&jE7y`7%sbt z^G;YVJsTjB%R${i=kfs)GI!m97PDL(8yizpDNYc;KLT*;%DFuz1c7s--ftU?(kJX| zqEN&8+c~f7?3$dMLa9tQpr7H}Oysy&P4r!shBDX`iJcsx_qM*~q$Z>@e5GCxw+8^gxn;W5`EK;S&8S!d4-x3!)!is*>QJRJ6X;<_>`7=K$Zh@L= zWs|f~+7CP2*cVp}9I8Kvx}98lB3EHwxGv*}Sg5L7HShiUs=ls+DHBI4Y?}U~GY)H( zP1PcTwpK7+Ci@|E22q6~OHP`fkx&xJ$t-Ait2#}1&{7dTG+AHtepo+NlqkwABPuyB z*GMS8l$>XHi`#%MFscYcwuMD@P;<00b1dTTQ4n(U;a{WU-8P$1y2EkK0-6>vw@kd^@gn##iXWZDHY2s;>HyN#vLNYYx&+A zh!%n&Y0gk)`=^0$-A8aYEx7Jy_0h^~q3J$vkAwlpFKQ;T0OZq3rlMp6-|%a}dEupb(a9cZYXC2Y`0 zz;t}}p`5u%*=hD!Yn7J6k?Z2tSlZ9&0xj;ja~=Z)?sSv7dc4^o^SU*|?eKuH%9OD! zD%>UwS;I3+Xi}aE4mVIFe-P6SadBYR0`0p!$$aJ>7WTAuW~gTh+aBHUT35(fc2C#C zV<{ZHv+F&B0f|T^8ujqxY^g1RCY{GT3kSI7xy_AAFj8wRgYWz(Oi+ns`5Vz1JJq8F zTIxrka;P~K*LzEgBoz#n$7f-+@9ae>JpC-ZL{HDz@r=`Xjq{J%0lnWtY4TUxO0uRc z!b8T|L_87u=XxW)Ugz+jJW-qX-u6H5;UxA7956ml9CNge<2hGI5fE<$-}jyrDd4RJ z)`W-GL4Wecu*j*5F^5~EEZ;AS2Jk;m|fmC`SrTB;pdF{`CWVue5}cie2n``L=vBj3$LS|CT-+bgpw z9q%c&a~J_SS|C#(=vUY~%&>RP(n{ELj8sBQwNQx&1cUCEK1mKx3|w2fB1qXtyfOh|Y1uG?roq31~7tm}t-L`HF(9}@|fEj&{c z(O0G~g5!Nu>7)s2NRXdRJj_w?@gVSr-sd3hBUB5CzwPg-oFOXV7aHyx}-}OJ}+0)Ezy(6$Cyo$M6^<1X3rmA|3=UTTUA6( zYfVApJ|(|Se_43cK^IH+O1Bnr8WCfsLW(w%<&@qn;`_J8W$BJd|3DmzzSV9_W|qQN zaINi6LImw@tJPqS*Xd<+gZIAfWE|l`%p-@Ppfm?b>%* z+Tu(f{}?}9845}506?gUUT_nLKHaASDvrleo$x0XRY=Wr+(ZyAkI^3i2>zvu~FTwyqcp@ow?{9jcrPd2Ws) zqm~&_0DuG;y!`F()xS8nAhzENfgzLI+c#0nM zNNL3Nv&-<%))^osZL880@I=oh@#1z{jhR*2rDy;NZ);~OhV{qMXeaLns!(Sa5UFandvttTC+BQ1w+Hc5Uv5Q1QOZ zRu!K27hM{wp};tYE3+OuofCFEbqm8sIR$nVTqs$+Fe#$!y&cqDM*E*Ah%p{R1#~;I z7~Df@W-Sk#=Q+o6RD1p(HNh$NiD8i+N~(s6RDPhZ-W)9G-Hq1oG+2tdJQd zpJ|E5p7^XeS}$$iD^X4aKej_7yB2me79Q_MAh(BkJ`WsvLIQQH+7M#qOFi ztA2~pxUHZ>gM3_M2t5v|yhZ+Q)D{dX!9h#yk zN<^4oD_QwSgt}l>O9m<5-?%aB)jCq2;f}KT(HpDgT_8s9gbHz=X-q8hR8wjci6Iom zx-Qp74?l1i{|V1)I1S;UM)P@1%HipO*_I1SEb_wniAVIRwAOM=ljyB+&3%bHC;qR6 zpS`kt$c+l@)|EJo=sG%;pUg*hL!Y1{i0i~NhPg<3AMP`&XBc#!B>B{zlPDKvx@%B# zycJyY=7>r@1DXkuJ}Xk@(T0*j27CoCn>FQ!xip{5TBc02{OTk-GL~_ENu!q;@Ib(q z-J$OD4SQNpN5o?L3!!RT>KZbZVW24 zXvxG&}w{w`_)vcg%dmvjDO1 zrsG**#k%T_I1?-sd^9hcf~L(Pvt~j~4ixr85~Y5BK8?W!BY(E--6E3^`@N~Q&4A|@ zsNJMezJpq$nzNC;n~z4SUSU!!ZNYKC%=ZROU?itu zR7|$_zF=|tGQJU@GS1TTBWJ>}&4`8_5O-hq#)!|AG00>az`57Z$ z3K~_o3}DGgqY5R_zw?JlpT7`(OF2b(Tzwc@#^c4Ceid87BPxEI1bLgn7)VU*R8)tu zEu>ALS^s&*L3dx|;xg`3$0Nl@fH+*{Tbh(UpLYqhF+zW+JPBq*!j;2r*5sqi#AB#B zBW8ZnCPwExq`BEPIz%bDJ%+MRQ96LOGay}P`N&6geV`F6%HU07_>sJ5KaZF(JBc|S z++EXs^LU9zl!(4%^1vgMaM$3#D&vtf$6A7$jl|7KOZ)BmulCpTGbdG7BxF;qqcpRZ zgRqqTq2uC}NCsJ|z^}lfO%wKa0dBN6HyQ0V=w8CmZr#TCa$<^9gu{vyl!GvOEAkMFjlNe3?Tp{o4uQ$uvXv0Sue><&gLqoH7jZhE z(w~Kh6+02lA4{NkVXO8Qss&XEs(?v1(qAXy@!YniiGWBB$oE78doJY)4V zzmrt12{(@_p&ktXNHUJA`f^xV;^^3D+-U5$bd0g08g(j&0A9x()KLC?LgvLqb)@pV zHAh^o?=?bA4R4@bTUxeg`=%hQoCepJ9|vC;eUOm|5I(~*03Y#^L37B!U_EBF$0`}v zeyl^H6Q_ekrr6Wml(S2B!Vq9ZiU^7n%(hLZrW<}AdG(w#z=wqM?M&@ws3yWfvlGKS z0N-KI{OC5LZ!+=WxAH!bmVP;-AlfxxAAh!JL2%}{5grRPqVnekI;YRn_B2&Xr9?k> ze7I;?y}){o@ohzXhCPw#w6`t4~LamgmP2Via}v z%Gz>7c27D0w2I%85AblTg_kAjf?OYWOzzo)xTws_kh%Dl#Wkyi5>prrsb||a$H-LA zvKG8TiCe3D!n`j?hPz-xqG`bgVA-_`s1+sk4oj_Ae6FNSv6EXpHH!-NPCn>J^R6(P zlfVkjx}*5e&7;ydCH#WCuqb@c+)edgIdirlCXr2g| z8HjX#=#lB}yIi@t3)l?;cIQ%eanlBSz&K$Zu=P!^ddOjhK1Dfk1QyYRqGsfpk|vuX z_RyNv$>6EShb85#ViOaL!sy&O5Z6o@4h{nyMOWj5@Bu9YS4uQNsuk*LYjz!~-Gfwt zfbm}SIaI}r=MY|Id)z{f+&ab}0Y1NR^;7J;E%N6>yg}(!82lsnHraHOB2p!uA?l}5 zep~kd|K>SK{~X+dEsI-EI4g$86S&C=R}^)Dm*%C!}kPEn2`wP=x*P$9DG17YY|2f_Wn%@;*;| zPs4rGtkxMps^_qHihd@td&{sz^Y7&{C4XAPL@w1F1zD9qE>}fHTarUTRhG*fnOir7 zI3Tm?E*6&ciGvP--1suSJucH8eu_Gh{_GLzDLOPXE9oq`e$gUDLG4vUwF<;KiW!{O zsnFP}jdRNx_kApmdRZ$GLOQFGq*4PTtE=k@Y-&MzCRfI1`Ji=PLaU6|_GKeyh0JL* zGw`1}y%gIa#3t!aK#Q2>wqXej{@fvgxL47BmIoW0qjhUoxe}TURGA}|zv{2J^9P&6 zr-+N93#=fEpihUH(tP8#7thIS>PMBOmL(}=FGuqex$X8y#A!Ja$SY2^Vr8FA#^g%s z=aEnk(iwN9^~YMKkPZ4}JP^V9D0{Kn!8VUu<@R&C0b@!GbY*DF1kd2RXvX(7oW;R@ znBTk9{@q1{(pUZl=ikB;iTu_CQWso61>@3yh`~Vg=VaJgLc}Wuv{ygMOMWdY8FLNP~|Ms1HNNP@`eOJI+h6c`0 zVz`YqIEulRB&5B+x!pKLnjDNF``i{scR$DbfgIx#~x*kg6`AUh_m&&t>WI z%@W}A&daY?JDwBI7Eg-JTDMjxGsrl@S39~o18pBIHOrg$G$UjAX^h3xm6?@ombbUGEI zc#(?Zf)~lX7=*y6_a$bLudf_CDTNi+FRY(lRRyP|;^68id!VwCB*){$?`yNK8CqPS zlQmy+u_F2;!X-U6d$&AL9ZEOue_XpcBWs~}DT7D~>06Do9>95I`~Mt3q~>{}F=TTegzu9SXFD5pp&d{rUpguk`QR6T?pbr^ zRs5Il-{#%Bb*t4K6FImUC1`1Rn63d%rEe zR|L^)H6@jtEr>yTcK{;u$R6762s~jm)_mJ~`rPHTc{ zXi*+?OXP{wVL4q4-Zi`n4HCQMr?#*3>2`8HAioQ<0lcspPMo!qoz{dk3muT-qj79; zJ-zwhKQF7jOYN~SVr+F}h3Vv;xcP@^ab#P0>5M#bA;@+YU;kHc*_%2*EWuFNoxbLe zR(jaQjg3|XtUGihmCoGv3b+9D>PFD{u*Pf6%`+9kex;_(#2yMyD3Nl7bfm1ODa5mr zirimzoRR9=-~jf`=K70&Q(hl6%r20HE3}R+`3;Jpy&?^h;o=O_F)|?ZX00u(XHCBv zZD(2Tny9{~u5|A{@n5O{$r7?)`DdZ{ZWI8Z1^D^jUH`9a{3q3)RpPt3e^Ut|um369 z-mUL9;s36W{zdoK>pYOV>%ZFRceV6SfIqVqzX9lR{{isN9LApzf7<-t5X_|i(*yVu z;7^J2g**|v3zbxCI7=Nnt-xwH={~>{YDEL1S{yfmX5tJ$a oCl~+YkNk6Y|HcTU`Ul28_qw_g8qx{@01uI0Z=_9PqQ1NPf6;oVApigX literal 0 HcmV?d00001 diff --git a/tests/fixtures/hancom_saved/pages_square_table_after_text_on_the_second_line.hwpx b/tests/fixtures/hancom_saved/pages_square_table_after_text_on_the_second_line.hwpx new file mode 100644 index 0000000000000000000000000000000000000000..8f2c6b0c560de4220508fc3bf5fc39cb9528c3a9 GIT binary patch literal 8458 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 literal 0 HcmV?d00001 diff --git a/tests/fixtures/hancom_saved/pages_square_table_before_text.hwpx b/tests/fixtures/hancom_saved/pages_square_table_before_text.hwpx new file mode 100644 index 0000000000000000000000000000000000000000..60ae213a43142eb2051e6aeec86c4828e8d6a5b2 GIT binary patch literal 8379 zcmZ{J1z23k()OT1gIkb6gS!NGcPBt_1{gdrI7@JMw-5*(G`PD@aCZrkAVC5I=O1?O zcXv0>{m*%NPIsTK_f*$(S9MjXDPLAw09?s0(U}yDz5%N8JxFUoD0G|yuvv+a?iBNliT&XF=M1^hK1?8n=b^k)5gn>A^ z3fj1fP}@Kt&Vuah9v&WSHfAs&2Q~{QHanLm#vJU~xi~mE+5hu3YD$QiH3%Z{H}@jc zdTN@|>Y8d&GFn<{n$(mIX0}c)BGkOF8rbov#`#pUaB=#xX6^>Iw^Vg=FbBcj!1#7@ z6`|&$e&XdnY(32fM*9!>h)~P_$rPoUl@-_mL&A>~sYkUN?u5jBSjKV##=5qXI&b8tLyEv1RC zqVzF;HKpV;)^7YyE5GA*FR^x#v2>vCc{4~+E%$(AXe}+}eH)8}p%g+d#SzrHJzuD` zX4}jZ%Rj=tiQPm}Emid91i@&1nu=IndgbyGQq6uqEacO?(%;`7`&=GxE;iJCY&F|& z^R<=gD6`^o{#Y`3ekBF|E+iTv{u^!8VRkBg)%f$&{mGygFB?z_>k12awtLj2O%#JO zotSFK_*YLjT-c>J?HC!+J&9X9$T%|1A)!u07d+$!UB{Co$Xr3CjM<;KjN(D&|EY$zPKEZGrM0e^G}eDd_^%-nPTfBXSo8$ET~R z$4&Zah3GcXkSU7{hCS+M&2Qd+WWl*LOT#dpYYj7kJb#D!hGs?&zH+ud?PX&$DksUV z)V4vn4GF?@^>zMu+`VXej7x`cEgF*()79DHK~;`ZU0`!~anj1#r;AL7%?s9_f~c21 zyib*z_N9A+)=3AHL8pwbs67LvCpW2H?YAe}xinlY4z9QQdVSsl?_JB;2?1r z)6vT3kuHb&roi%6YzmiZLE>C=_tFF}W{4q%V(auvu;hBkM%#0hTJ-O>XrXs`P8{Qi zIX_5K=Brx6ZN{EuY|c)m^T{ju8ZSLt@_JPfj~aI659Xk8GsCD>wLM};1Zg}=4@YTF zvwj!o#lgEHG-AHpmTw6(i!S%Tryw>Bwl}>ATvaXeY6`Y=92iwF)(e^E-g7frCdGZE zXtGeVE=2FOLX!1&GhUbFOQs_?Rrz(?rU!b5!kF>gsPRH>LfInfnYLN)vl&uZ-D!+c zo~cub6j?sA*M&Hpe1eQ<$JTSVN|Pf#a&j@g0ziw@e45S-o)s>`-D?b^FP&;GEb=bp z!S!|z{6p3kl-A}V7FPn5<4pa?-&m+(MLeasN-BFb`-NLiIUx?0OHqn%4CuQ=u%5jQ zuk!Ll3*!d!GU72WwWQ89;fW4X+t{@hbv(J5b1pgZ>S=W#Zw$(TYJ?wm)aMc3f32}Ql3y`}+H zzoHIgVnd~{wsa7H%YEHESRXbCxSXl;l88aHtFOkWUVP2vN>eUZvh8m@AvMDgoOYWK z7g2k}B~M@apss`%5>~!}#}^mj>B(S6KvDL>l3G~Wvz%6V2JERV0}20zJ&6+&+ao9w zCSM^9Dc6DE&oc`0{c8NG%6J%Ld}A~L1!L81dx*0KU4G|v%6St(sXs``D6 zQ9RA1{V07GYH#P6OtYC64#dHsSf-$uJ}^B^tNIw^H|63ikt2$!8`MplPw}mB16vMS zEIiT!x>lEth+v44nUQG^b~?6puGKyKJR8PF(u%`-r?Rn`4@e7Jtn_@;LH)zWMLF)x zRpX*+Abq@=i$6Geh|-of*4y5m#{o-hgZaKgQiV&})B27;+~MT=!un@%h2mb{9uJWf zr|db>BjaSu_E(r0rNH>5Uzy^c*AYBWu*%|Fm1as?pAtnVHB~1z)OhuX%b(bC9j~a|AvOAbA zbGLCLrI50fK*x(+aQiI3Z+4Ge@F7rV>RY`}ly`g5aY<+^n5TSgt)xv)=sSxLwQH1L z=+DO7LGWI|oZpH_X}tl|dvIK(2STHJF3Fpu$;O))qnyN+x_5QIyXYtXvEW0;ls@w6 zPaJ!P0JixWUsM>w{O0A)#+w+pLlZP*LRi$Wo}GRGJ?uHMsPT^lmuO3*yXYO z`8U?|8|Q_+hsKu7r1Be|+pfx%kyw2?|3ary{ju~DCyMESdkbR@ho*z3WsfW#IZwG-zBN4`{-Mvlhb@SOQQjCKyNUTp zP%kqFAe_re(M9Fbj0#@5??Q@Qua1k0Evgj53FI9Ixc7c|JjLY%>` zBoB46-PzkWIXj1un{B%eC-2ddJV$S$>9sPH!5~fQW)*?kUHFimm`S@pu_9)N7r5Q3 z^vy9FNoOG^3(0LL-m4}zQbk#~N|7zncs<|hIYy*4&4iOQBmJx1n2~ZJe<=>W&(+GN z855Mv-#9QX?`T<7ukiYuUHYRoAz#>k#p5xOSGQ}z-7ctq)j^esrxY~Hyy}ieUu0Ib zjHImLPmsw$qsYRmP-Og&;cq06LU6XoIksD!AqcfnOdg%7FRC5Wj}yU*cF&4V&C4|s z$S)<~8r$VCpbCmELXmA{l!aqYyscdE~JCt7zb{w-hFq#}uBU7%@Q zmU$gZAr-TA-6{r&wJUK&wuCJ6pM#k}3^saWHj1KBbBkn(WtQ<%ih)y(kyAB1wFV-E zAaKT8R|bbyLCLy=$?jUoy2I)dl{v7N%CP%4<6s)Vn8K42KEGf%#(_mAs zg!FctN{{5g#O`?3^3X3oN7l(JFeIO;OyFHsyur{YE$Y8G)DG!jvr zgqq74nv|Uvh1#pM98cU*}!sbF$Y3+F>o?XNG7>|0$2AJ4LdJi^0Y)y$9f&tf*yp=uB_4Hhe zK<@6Xr8OWB&PJjbn^`Qiy9Q=*S-i)j-tyYxK*SlZv5~=kOBl|t#JIkXx5YwExI#%m z7$%4Kq2m5vZIz&c*6Q>;yylaG2&tF9rMJk>3l=PsOm36>lTN_Ek1$~VhI`5TIm?L9 z$qr$!>%$AZ@ps-A$-#LdwzWPEH*lCq1AIqxl1Y|?I3uc8Q}u%YUL=v+Y8NVlCrVYF~a9Tr@N!r~Jzdu}`lOD@y^W?o= zj!Wu%qza7it31HupCu;a?RG6?F!VyVe!SUde~j@Lkc6GhdavXovx?*W=?Os05!oWw zgJt@{m_8?!&YGMJiSmm{#~)PuJaGbC;aTwqan(X2QD19*u1}Po*JC$P?(ktUy1!l? z##)!7ybyHzo<6Seb!ZE$!3d|%w5E$2u`E~AC*GgLLzhF4g11p%?!cQ+{|CPJQ=UfP+3IuQ7>cPMxPdJ7#>}>LYg+c)vVs*^^g6=b?L5|fFMlE!OcEY2F60; zWUaj(0h~_v&1#URZ)O=46mH>L)(JM)B5KT)Gs96rc~_f;=(W9Q$!?0;75)ffnoaaU zN4(jKtEuCS(a`iR0GPb!H3yE!t3xVk#i=;*Gv1`43aR<7he*7=_92nZ`^8X}a0#qv z(L2qe-Q-`E*LuEF2kXUd)#!Du=509TG(I-b1$n5lIgjfGyLWVjSdUo$c2yPy$j+8w zUWVYFt&k!v{I|Ab=gcJn?Y zoxQ`iGa|(!cvmCyTnAEAhNch*A)!0y@P5_lyZK3R?9TH0AXxHdKWF>X*$$Mwr!6f> z9B!ZXIKbvwuD2kl^A3vh0enit$WJ)}tO^m;SA`F9jLNvxSTdIcm=rtVfvT<&xf6hN6 zshyoJ@WM`vF*!`HP|Vzci?mnzTAN&156VqQx0mm6!F*3u@h0oR|6Sb|-9W%WOMZ7_ zSPG*ra-Q0v!l3tS5!t*d{|`^0gUV2A`Vxn}(6CzydX zQ0=z+%#xu2Kq@`NVbAAvthTy{W`+i91`PhIev>vqw>dW_0=U~AW+8RiJSBj*1 zwjD68zhYt%J?=7#`<(HO7@FBgaGm8g+i z1TGQTmWsLt)x~<8t-@!8rPY^#3ktHZm=e&b#XIY2$h8Jk%C7xey<%D|J6^B5pI!BgH zWcrYJYcJT*Q39AA$JXT|-CSapx#sp~4a z&MDD%A?iVZ(y&xE)gI+9U|^$(+K(a+ZXJao)dd2k@mHZJUHPfhIXC+@9Btmjs)HU? z^uDdZS1j2x8%0qX7SZ(P>cOPt1OAu6rpP)< z_#ryP7;{6CQNr1Cs*^JYALG8PtnSfox~#%K1c#||P*e)1XX*X>0h%fb)O@OXW!cp| zI0+HiBRD(a{2zT;$TgyEV?E<c8V%#cqHI~?45M&G8H-y8OBun^6 zR>#qXE#6@Xn1p(4T1(};4$cusmZ=@wKTY{C`^CUz-tzQpm^u_Zc;IOT9bPJ)S)Zpz ztkh>(C2GmY-xKymY)&YDV``L9vi+rJT;a`iLrIwQvBgjJ-el3#@~c|Q{#p#N)CH4X zy-;gY%d{49C5HIQSwDFX%w>puPR9}h{37(--O=&-yIUi*;m%7vQynbynm}V2l!2Te zR@^HHhVdW=Io1ePJ}ad2@uvwsxd>1N!2?@mo6?>%w70C8aI={Az*x^Pc?IM`^9s1a@2U{!>)nmB zguc^qVYqvmSro)!T5^`orQI-9p?54$YbkuF3q)zlYf10fp1Rrks9cyX7F5RNs{2#4 zBsty;lPAAlNC1<4JX8{Bb3cnV7k!Xe3CO)IVF}F(Jh4d62)ysFi3Z$8qy^CexL?ph z7wc-~B!jcMkHlZ-b87H$`;Jn^&P}Y07r$~*;7sMkFySBw(E$~QT-ODRk< zo;C8;fP4>&ETfG~qxM<4t<(3^!hY+3fDyN65yWE@g$dY)=l@ItD z^}XMri9q;4)8+y)$_M>{^fUc3-GJ$rz66i>14v~fdrO~~iYUtn*$N`v+#mCz!jn)$ zZ-?l85%t;5AcrIsIxe03KnXE);H2&KwyVK)GL*Oh)DjzGU`Kb#K5DVAkK{IIA=)~W z#Ad#9mj+aOJfvdXPX6I7pP|LGNSF32cKv>n{{D}L?h#;Fmf-To$BOsIc&`Y6cWhm9@#jF`1-zKBvsi*iyzcZ2>J``xhOSo8fR(}D%prI=z}gmgip zQH_ZplA$x@6{Z4rgm~}wDjIAB^u4micAZkF%J26qA}_{@7@&1-^DgCce)B}>EtsZ} zLRlX%h=f`|-W5jOD9Y`~9K5ZWAFF?STc~9zo5c?~N9L#(%=(D!LO!@z)zyFkMliy6 zhjl0)HW6|yS6pd4wS}(tBMzF8FW*$no(I49mW$CIb)2)1v*$S^Q=wZ}60jT5X+0;x zZ-nyW&ZKp2QGDH!*vJ@>XeUL-X73u-;ue z{rfbO5&R4F57;S)0v7jv3Yx3CfZV|#4|a7IcWsa-gbm^e`MTp>4?fP)CoRX1M8}&} z)Qs9n(wshv()4OxQ+{7;YKl@AlUv8ho))vY41Vv9jXT5*|Fdhm3=@-<%D8eqDb@c7 zFfFUTM68%44%T9DKrS53t3yg|2%ZQY*r1Okh~yFMM++~QP}5IC_z9~IMEvnrn@R4-B! zP8yyfj7z!ON+v1D7gav^Xq`?(4F-6v|MDt2(u>?rvPI8ejqXLp{|r^yz(RMb!qRKZ z&7@=}=1vN6vdwMyxjiY|aeS;8(VcgGf*x@mzyHTdv>du|0dd8=8@cf17*CThS=ptX zf`*CHfQAL*Nt$y8R-RK1Q&u!9Pj7k&$=jDiTXd~j)P%0r4r6VdEWchWTsDVrM@Hri zPyfhxPS~Q>9Z96;xcU?MT=@GV?Jn@&)1^=CSw)3S)dB&Qn1D@JMMhhKRY6sj-2xU~ zHv>Du0_!f8R`p3x#~==DnRopzbDsW+IuZdak?LtWK;T9uW3GRUa8Yn)6<&=3zK&uR z+kLugT-El4)x5_cI%~bGwJ0}@G57|akezil-;Ey$>;hBWvO)uGTC1f`AHo12Lxi2tcfHQXS;E-LNl?s z68d=r6i_OY-i)C*t2AP$f7UZ$^fuYc?_JEx&#T;T_8L%TMLF*bP3V)ecrIJ8-x)4q zVxZ*@tabiy5hi;l|A6^#;R#3Wcj3YV0QJZKz*BI0BC$U#?9@!IN7E@i9)(MpZe#QvU)CS zzy4SQ41asGaQDq?T4?pG*t~srgDi`fEn>5)w>!v=aIHn&)UTx%LxB(>QvNhupE`oB zd@y5*R^tU?v-(uFop$)#2dhj~b1(|d{fI_KD#zSo5%Oeis7F*~4!;X($boN`;kyk@ zXM2tOh=8h}ydSDB6-^ZMKA@_}oMue_2&_9Nz`RONo7vO^J=Y?sOK0( zOd3 zd(A0tOV)Ym3OG#s-3lvdn@3G^t5FV1mE?_m{L2ghX0^{Ys2n^yCypnrLp$kuul>vd zOxj*8i~V~I0n_Pb5MUc{8CL#38xW>>{?Hh;h3CZfONqBzjK0(kER!#tkcxVC3!oBe z>Ap+&@?(G5qffV5-6?6<_Z@fCETboAj{W1@`rZ(4SZc!Qg z9g;HqvK{Kh_6Ekpw>VLziLZHo83-hoB$Za~+raCp=oUwRR&qxnRxpusQojy5;-+#-=XhL6f9g*V! zI<>m}d}t0>meu}F;ki9-Vtrzb>gVFrul#kwFsDE^S)qM$%^xa?WK0w;!_F42V`PBq!&FmP z&y;yL(aE^pJ6#Q@t^@~<|EDT|u>{Lm{+=s->IDEO0sa9`&;QFD|4#LLqWEd-UsM9H z=YR6HPxJem@PDUB|D^l#bDpr(^ None: + # The same table, its control after 60 characters: on the paragraph's second line laid out the column's + # whole width. Hancom places it from that line's top (9600), the lines from there on beside it. Not + # followed. + data = (FIXTURES / "pages_square_table_after_text_on_the_second_line.hwpx").read_bytes() + + assert estimate_pages(data).unsupported == ("section 0: tbl wrapped square after text",) + assert estimate_pages(_without_caches(data)).unsupported == ("section 0: tbl wrapped square after text",) + + def test_a_page_break_in_a_row_holding_a_table_beside_a_taller_cell_is_unsupported() -> None: # Row 1's cell (1, 0) holds more lines than the cell beside it holding a table; the page end falls # among them.