
    4vj                       d Z ddlmZ ddlmZ ddlmZ ddlmZ ddl	Z	 e	j                  d      Z e	j                  de	j                        Z e	j                  d	e	j                        Z e	j                  d
      Z e	j                  d      Z e	j                  d      Z e	j                  de	j                        Z e	j                  d      Z e	j                  d      Z e	j                  d      ZdZh dZh dZdNdZdNdZdOdZdPdZdPdZdQdZdRdZdRdZ dSdZ!dRdZ"dTdZ#dTdZ$dTd Z%dTd!Z&dTd"Z'dUd#Z(dTd$Z)dTd%Z*dVd&Z+dWd'Z,dTd(Z-dXd)Z.dTd*Z/dTd+Z0dXd,Z1dYd-Z2dYd.Z3dYd/Z4dTd0Z5dTd1Z6dTd2Z7dTd3Z8dZd4Z9d[d5Z:d\d6Z;d]d7Z<	 d^	 	 	 	 	 	 	 d_d8Z=d`d9Z>dad:Z?	 	 	 	 	 	 	 	 	 	 dbd;Z@	 	 	 	 dcd<ZAddd=ZBdYd>ZCdTd?ZDded@ZEdAdB	 	 	 	 	 	 	 dfdCZF	 	 	 	 dgdDZG edEF       G dG dH             ZHdhdIZIdQdJZJdQdKZKdQdLZLdidjdMZMy)kaw  
Copyright (C) 2023 Artifex Software, Inc.

This file is part of PyMuPDF.

PyMuPDF is free software: you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option)
any later version.

PyMuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
details.

You should have received a copy of the GNU Affero General Public License
along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>

Alternative licensing terms are available from the licensor.
For commercial licensing, see <https://www.artifex.com/> or contact
Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
CA 94129, USA, for further information.

---------------------------------------------------------------------

PyMuPDF table header detection and HTML serialization (opt-in extension).

Pure text-grid module (no pymupdf import): the header-region rules operate on a
row-major ``[[cell text]]`` grid, and the serializer turns a tagged placement
grid into an HTML ``<table>``. Used only by find_tables(refine=True) (via
pymupdf.table) and Table.to_html(); never runs on the default detection path.
    )annotations)	dataclass)mean)AnyNu2   [A-Za-z]+|\d+(?:[.,:/-]\d+)*|[%$€£¥()–—-]+zE\b(?:jan|feb|mar|apr|may|jun|jul|aug|sep|sept|oct|nov|dec)[a-z]*\.?\bu.   (?:[$€£¥]\s*[-(]?\d|(?:usd|eur|gbp|jpy)\b)z[-(]?\d+(?:\.\d+)?\s*%z\b(?:19|20)\d{2}\bz:^(?=.*[A-Za-z])(?=.*\d)[A-Za-z0-9][A-Za-z0-9._/# -]{0,24}$u:   (?:>=|<=|<|>| thru | through | to |\b\d+\s*[-–]\s*\d+\b)z^\s*\d+(?:\.\d+){2,}\bz)[\[(]\s*\d{1,2}\s*[\])]|\[\s*\d{1,2}\s*\)z^[\s\d\[\]\(\)=+\-*/xX.]+$)z
in millionzin thousandz
in billionz$ inusdz'000%>   moneynumberpercent>   unitcode_id	long_text
text_labeldate_periodc                &    t        d | D              S )Nc              3  B   K   | ]  }|j                         sd   yw   Nisalpha.0chars     I/root/.hermes/venv/lib/python3.12/site-packages/pymupdf/_table_headers.py	<genexpr>zcount_alpha.<locals>.<genexpr>=        4TT\\^q4   sumtexts    r   count_alphar"   <       4T444    c                &    t        d | D              S )Nc              3  B   K   | ]  }|j                         sd   ywr   )isdigitr   s     r   r   zcount_digit.<locals>.<genexpr>A   r   r   r   r    s    r   count_digitr(   @   r#   r$   c                ,    t         j                  |       S N)	_TOKEN_REfindallr    s    r   tokensr-   D   s    T""r$   c                    | j                         }|syt        |      }t        |      }|dk(  ryt        j	                  |      ry|t        d||z         z  dk  S )NFr   r   333333?)stripr"   r(   	_MONTH_REsearchmax)r!   strippedalphadigits       r   numeric_liker7   H   s]    zz|H!E!Ez!3q%%-((D00r$   c                    | j                         }|syt        t        j                  |      xs% t	        j                  d|t        j
                              S )NFz#\b(?:q[1-4]|fy|year|month|period)\b)r0   boolr1   r2   reI)r!   r4   s     r   date_or_period_liker<   U   sD    zz|H	  *obii8^`hjljnjn.oppr$   c                v   dj                  | j                         j                               }|syt        |      }t	        |      }t        t        |            }|j                         }t        j                  |      ryt        j                  |      s|j                  d      r|dkD  r|dk(  ryt        |      st        j                  |      r|dk(  ryt        j                  |      r|dkD  r|d	k  ry
t!        |      ry|dv ryt"        j%                  |      r|dk  ry|dkD  r|dkD  r|dk  ry|d	k\  ryy)N emptyr	   r   r   r   r   r      ranger
   >
   $m$000eurgbpr   rateratioamount$r   r      r      r   r   )joinr0   splitr"   r(   lenr-   lower	_MONEY_REr2   _PERCENT_RE	fullmatchendswithr<   _YEAR_RE	_RANGE_REr7   _CODE_REmatch)r!   r4   r5   r6   token_countlowereds         r   	cell_typerZ   \   s"   xx

**,-H!E!EfX&'KnnG!X&8+<+<S+AeaiTY]^T^8$););H)E+YZJZ!eaiK14DHZZ~~hK1$4qyUQY;!#3ar$   c           	        | D cg c]  }|j                         st        |        }}|s	dddddddS t        |      }t        d |D              |z  t        d |D              |z  t        d |D              |z  t        d |D              |z  t        d |D              |z  t        d |D              |z  dS c c}w )	N        )value_type_ratiolabel_type_ratiolong_text_type_ratiocode_type_ratiodate_period_type_ratiorange_type_ratioc              3  2   K   | ]  }|t         v sd   ywr   VALUE_TYPESr   items     r   r   z#cell_type_ratios.<locals>.<genexpr>        Td@ST   c              3  2   K   | ]  }|t         v sd   ywr   LABEL_TYPESrf   s     r   r   z#cell_type_ratios.<locals>.<genexpr>   rh   ri   c              3  ,   K   | ]  }|d k(  s	d  ywr   r   N rf   s     r   r   z#cell_type_ratios.<locals>.<genexpr>   s     #X$DKDWA#X   
c              3  ,   K   | ]  }|d k(  s	d  yw)r   r   Nro   rf   s     r   r   z#cell_type_ratios.<locals>.<genexpr>   s     QTty?PqQrp   c              3  ,   K   | ]  }|d k(  s	d  ywr   r   Nro   rf   s     r   r   z#cell_type_ratios.<locals>.<genexpr>   s     %\DdmF[a%\rp   c              3  ,   K   | ]  }|d k(  s	d  yw)rA   r   Nro   rf   s     r   r   z#cell_type_ratios.<locals>.<genexpr>   s     PdPrp   )r0   rZ   rN   r   )textsr!   nonempty_typestotals       r   cell_type_ratiosrx   {   s    27H$4::<ioHNH # #$'"&) #
 	
 ETnTTW\\TnTTW\\ ##X.#X X[` `Q^QQTYY"%%\N%\"\_d"dPnPPSXX  Is
   B;B;c                   | D cg c]  }|j                         s| }}| sdddddddddt        g       S t        t        |             t        t        |            t        |      t        |       z  t        |       t        |      z
  t        |       z  t	        d |D              t        dt        |            z  t	        d |D              t        dt        |            z  t	        d |D              t        dt        |            z  |r+t        |D cg c]  }t        t        |             c}      nddt        |       S c c}w c c}w )Nr\   )
cell_countnonempty_countnonempty_ratioempty_rationumeric_ratioalpha_ratiodate_period_ratio
avg_tokensc              3  8   K   | ]  }t        |      sd   ywr   r7   r   r!   s     r   r   zrow_features.<locals>.<genexpr>   s     J4|D7IQJ   r   c              3  >   K   | ]  }t        |      d kD  sd  ywr   r   Nr"   r   s     r   r   zrow_features.<locals>.<genexpr>   s     K[5F5J1K   c              3  8   K   | ]  }t        |      sd   ywr   )r<   r   s     r   r   zrow_features.<locals>.<genexpr>   s      Ut;Nt;T Ur   )r0   rx   floatrN   r   r3   r   r-   )ru   r!   nonemptys      r   row_featuresr      s@   !&7$**,7H7!! !$

 r"

 
	
 CJ'H.h-#e*4E
S]2c%j@J8JJSQRTWX`TaMbbKKKcRSUXYaUbNcc  Ux UUX[\]_bck_lXmmHPd(C$Ct-CDVY
 5
!
 
 8* Ds   EEEc                ,    |t        |       k  r| |   S dS )N rN   )rowcols     r   column_textr      s    SX~3s8-2-r$   c                :   t        |       }t        | d      }| dd  D cg c]  }|j                         s| }}|D cg c]  }t        |       }}t	        |j                               }i ||rdndt        |      dkD  rdndt        |      rdndt        |      t        v rdndt        |      t        v rdndt        d |D              t        dt        |            z  t        d |D              t        dt        |            z  t        d |D              t        dt        |            z  t        d |D              t        dt        |            z  t        d	 |D              t        dt        |            z  t        d|d
   dz        dS c c}w c c}w )Nr   r   r\   g      ?c              3  8   K   | ]  }t        |      sd   ywr   r   r   s     r   r   zrow_vector.<locals>.<genexpr>   s     !KT8J!!Kr   c              3  >   K   | ]  }t        |      d kD  sd  ywr   r   r   s     r   r   zrow_vector.<locals>.<genexpr>   s     Ldk$6G!6KLr   c              3  2   K   | ]  }|t         v sd   ywr   rd   rf   s     r   r   zrow_vector.<locals>.<genexpr>        $U4ATQ$Uri   c              3  2   K   | ]  }|t         v sd   ywr   rk   rf   s     r   r   zrow_vector.<locals>.<genexpr>   r   ri   c              3  ,   K   | ]  }|d k(  s	d  ywrn   ro   rf   s     r   r   zrow_vector.<locals>.<genexpr>   s     (YtT[EX(Yrp   r          @)first_emptyfirst_alphafirst_numericfirst_value_typefirst_label_typerest_numeric_ratiorest_alpha_ratiorest_value_type_ratiorest_label_type_ratiorest_long_text_type_ratioavg_tokens_norm)r   r   r0   rZ   r9   r"   r7   re   rl   r   r3   rN   min)ru   featuresfirstr!   rest
rest_typesfirst_nonemptys          r   
row_vectorr      s   E"Hq!E"12Y7T$**,D7D7.23d)D/3J3%++-(N
,s#)%014s# ,U 3#,U#3{#BC#,U#3{#BC!!K!KKcRSUXY]U^N__LdLLsSTVYZ^V_O``!$$U:$U!UX[\]_bcm_nXo!o!$$U:$U!UX[\]_bcm_nXo!o%((Yz(Y%Y\_`acfgqcr\s%ssH\$:S$@A  83s   FFFc                d    t        |       }|d   dk(  ry|d   dk  xs |d   dk\  }t        |      S )Nr{   r   Fr   g      @r}   皙?r   r9   )r   r   short_or_sparses      r   header_candidate_rowr      sG    C H !Q&|,3Vx7NRV7VO  r$   c                   t        |       }|d   dk(  ry| D cg c]  }|j                          }}|D cg c]  }|s|	 }}|D ch c]  }|j                          }}t        |      dk\  xr$ t        |      t	        dt        |      dz        k  }|d   dk\  xs |d	   d
k  }t        |xs |      S c c}w c c}w c c}w )Nrz   r   F   r      r}   r   r|   ffffff?)r   r0   rO   rN   r3   r9   )r   r   r!   ru   r   unique_nonemptyrepeated_labelssparse_labelss           r   grouped_header_scaffoldr      s    C H"&)*dTZZ\*E*!&/$/H/089tzz|9O9(mq(_S-ASCPXM]^L^E_-_O]+t3Yx@P7QUY7YM011 +/9s   B6B;B;C c                v    t        |       }t        |d   dkD  xr |d   dk(  xr |d   dk\  xr |d   dk\        S )Nr   r   r   r   ffffff?r~         ?r   r9   r   vectors     r   data_row_liker      s^    _F}! 	,?#q(	,'(D0	, ?#t+	 r$   c                N    t        |       }t        |d   dk\  xr |d   dk        S )Nr~   r   r   r   r   r   s     r   dense_numeric_row_liker      s/    _F'4/QF=4IT4QRRr$   c                    | D cg c]  }|j                         st        |        }}|syt        d |D              t        |      z  dk\  S c c}w )NFc              3  *   K   | ]  }|d v sd  yw)>   r	   r   r   Nro   rf   s     r   r   z)money_or_percent_heavy.<locals>.<genexpr>   s     CTd.B&BqC   	r   )r0   rZ   r   rN   )r   r!   typess      r   money_or_percent_heavyr      sL    ),=

Yt_=E=CUCCc%jPTXXX >s
   AAc                    | dd  D cg c]  }|j                         s| }}|syt        d |D              t        |      z  S c c}w )Nr   r\   c              3  >   K   | ]  }t        |      d k(  sd  ywrs   )rZ   )r   cells     r   r   z)rest_date_period_ratio.<locals>.<genexpr>   s     FTYt_%EqFr   )r0   r   rN   )r   r   r   s      r   rest_date_period_ratior      sH     W5T

D5D5FTFFTRR 6s
   AAc                Z    t        |       }t        |d   dk\  xs t        |       dk\        S )Nra   r   r   )r   r9   r   r   r   s     r   first_row_period_restore_guardr      s4    C H12d:a>TUX>Y]a>abbr$   c                   | dd  D cg c]  }|j                         s| }}|sy|D cg c]  }t        |       }}t        d |D              t        |      z  }t	        d |D              }dj                  |       j                         t	        fdt        D              }t        |dk\  xs |xr |       S c c}w c c}w )Nr   Fc              3  *   K   | ]  }|d v sd  yw)>   r   r   r   Nro   rf   s     r   r   z7first_row_date_or_unit_restore_guard.<locals>.<genexpr>  s     TdD<S4STr   c              3  $   K   | ]  }|d v  
 yw)>   r	   r   Nro   rf   s     r   r   z7first_row_date_or_unit_restore_guard.<locals>.<genexpr>  s     OD4#77Os   r>   c              3  &   K   | ]  }|v  
 y wr*   ro   )r   termrow_texts     r   r   z7first_row_date_or_unit_restore_guard.<locals>.<genexpr>  s     @48#@s         ?)	r0   rZ   r   rN   anyrL   rO   _UNIT_ROW_TERMSr9   )r   r   r   r   dp_unit_ratiomoney_or_percentunit_rowr   s          @r   $first_row_date_or_unit_restore_guardr      s     W5T

D5D5.23d)D/3J3TjTTWZ[eWffMOJOOxx}""$H@@@H$&2(L<L8LMM 6 4s   B>B>Cc                z    g }t        |       r|j                  d       t        |       r|j                  d       |S )Nfirst_row_period_restorefirst_row_date_or_unit_restore)r   appendr   )r   guardss     r   first_row_restore_guardsr     s6    F%c*01+C067Mr$   c                   t        |       dk  ry| d   }|D cg c]&  }|s|j                         s|j                         ( }}|rt        j                  |d         syt	        |      }t        |d   dk\  xs |d   dk\        S c c}w )Nr   Fr   r_   r   r   g      @)rN   r0   _DOTTED_ENUM_REr2   r   r9   )rowsr   r   cellsr   s        r   headerless_dotted_enum_guardr     s    
4y1}
q'C&)CdTdjjlTZZ\CEC..uQx8C H/0D8YH\<RVY<YZZ	 Ds   BBBc                   t        |       }|d   dk  s|d   dkD  ryg }| dd  D cg c]#  }|j                         s|j                         % c}D ]4  }t        j                  d|      s y|j	                  t        |             6 t        |      dk  ry|t        |      k(  }t        t        |            t        |      k(  }t        |      t        |      z
  t        |      dz
  k(  }t        |xr |xr |      S c c}w )Nr   r   r   Fr   \d{1,2}r   )r   r0   r:   rR   r   intrN   sortedsetr3   r   r9   )r   r   valuesr!   orderedunique
contiguouss          r   simple_integer_enum_header_liker     s    _F !Q&&1C*Dq*HF*-ab'B$TZZ\B !||J-c$i ! 6{Qv&GVV,FVs6{*c&kAo=J1F1z22 Cs
   C>C>c                   | D cg c]#  }|j                         s|j                         % }}t        |      dk  ryt        d |D              ryt        d |D              ryt        d |D              sy|D cg c]  }t        j                  |      s| }}|D cg c]+  }d|v st        t        j                  |            dk\  s*|- }}t        |      t        |      z  dk  ry|st        |      d	k  ryt        |      dk  ryt        |      }t        |d
      }t        |      ry|d
   d   r%t        |      dk\  rt        |d      }t        |      S yc c}w c c}w c c}w )zMA bracket/formula reference row under a grouped header, e.g. [3] = [1] * [2].r   Fc              3  @   K   | ]  }t        d  |D                yw)c              3  <   K   | ]  }|j                           y wr*   r   r   s     r   r   z>reference_formula_header_row_like.<locals>.<genexpr>.<genexpr>4  s     /$t||~/   N)r   r   s     r   r   z4reference_formula_header_row_like.<locals>.<genexpr>4  s     
ED3/$//
E   c              3  <   K   | ]  }d |v xs
 d|v xs d|v   yw)rI   r   ,Nro   r   s     r   r   z4reference_formula_header_row_like.<locals>.<genexpr>6  s)     
L4C4K53$;5#+5
Lr   c              3  F   K   | ]  }t         j                  |        y wr*   )_REF_FORMULA_ALLOWED_RErW   r   s     r   r   z4reference_formula_header_row_like.<locals>.<genexpr>8  s     Ht&,,T2H   !=r         ?rJ   r   Tsection_label_rowr   )
r0   rN   r   all_REF_TOKEN_REr2   r,   row_profiles"body_window_features_from_profilesbody_window_is_stable)		candidatefollowing_rowsr!   r   	ref_cellsformula_cellsfollowing_profilesbody_featuresshifteds	            r   !reference_formula_header_row_liker  /  sY   )2Cdjjl

CHC
8}q

EH
EE

L8
LLHxHH"*I$m.B.B4.HIII&.hd#+#mF[F[\`FaBbfgBgThMh
9~H%,S^a/
>Q%n567I1MM]+!01c:L6MQR6R45GK$W--3 D Jhs(   EE;E#E# 	E(*!E(E(c                   g }d}| D cg c]#  }|j                         s|j                         % }}|D ]L  }t        j                  d|      r|j                  t	        |             4t        d |D              r|dz  }L y t        |      dk  ryt        t        |            }|t        t        |d   |d   dz               k7  ry|d   dvry|t        d	t        |      dz        kD  ryy
c c}w )Nr   r   c              3  <   K   | ]  }|j                           y wr*   r   r   s     r   r   z.dense_integer_axis_row_like.<locals>.<genexpr>T  s     1D1r   r   F   >   r   r   rJ   T)r0   r:   rR   r   r   r   rN   r   r   listrA   r3   )r   r   alpha_cellsr!   r   r   s         r   dense_integer_axis_row_liker  M  s    FK),=



=H= <<
D)MM#d)$1D111K 6{QCK FeF1IvbzA~677aySCMQ.//# >s
   C.C.c                    t        |       }|d   dk(  ry|d   dk  r|d   dk\  xs |d   dk\  S |d	   d
k  ryt        |d   dk\  xs |d   dk\        S )Nr{   r   Fr   r   r   r   r   r}   r   r   r   s     r   #sparse_prefix_extension_prefix_liker  d  s    C H !Q& !Q&&$.W(;N2OSW2WW%'4/X8<O3PTX3XYYr$   c                   t        |       }t        |       }|d   dk  ry|d   dkD  s|d   dk\  ryt        |       ryt        | |      ry|d	   d
kD  ryt	        |d   |d         }|d   dk\  xs |dk\  xs |d   dkD  }|syt        |      dk  ryt        |      }t        |d      }t        |      sy|d   dk\  s|d	   dk\  r|d   dk  r|dk  ry|d   dkD  ry| D cg c]  }|j                         st        |        }	}t        |	      }
|
syt        d |	D              |
z  }t        d |	D              |
z  }|d	   dkD  rt        |       S |dk\  r|dk  rt        |       S yc c}w )Nr{   r   Fr   g      @r_   r   Tr]   g333333?r   ra   r   r/   r   r   r   r~   r   r   c              3  ,   K   | ]  }|d k(  s	d  ywrs   ro   rf   s     r   r   z.next_header_row_value_guard.<locals>.<genexpr>  s     G1F!Grp   c              3  *   K   | ]  }|d v sd  yw)>   rA   r
   r   r   Nro   rf   s     r   r   z.next_header_row_value_guard.<locals>.<genexpr>  s     !`A_9_!!`r   r   )r   r   r   r  r3   rN   r  r  r  r0   rZ   r   r   )r  r  r   r   date_period_signalhas_label_signalr  r	  r!   r   
type_countdate_type_ratiocode_range_number_ratios                r   next_header_row_value_guardr  o  s   I&H	"F !A%#x0F'G4'Oi((NC"#d* X&9:HE]<^_4' 	*%	*$%) 
 
>Q%n567I1MM / D(H5G,HD,P$%*/AD/H$%))2CdjjlYt_CECUJGGG*TO!!`!``cmm"#d*.y99$&?T+A.y99 Ds   E$4E$c                <   |dk7  st        |       dk  ry| d   }| d   }t        |      }t        |      }|d   dk  ry|d   dk  r	|d   dk  ryt        |      sy|d	   dk  ry|d
   dk\  ryt        |      ryt	        | dd        }t        |d      }t        |      S )Nr   r   Fr   r}   r   r{   r   r^   r]   r   )rN   r   r  section_label_row_liker  r  r  )r   top_header_rowsprefixr  prefix_featurescandidate_featuresr  r	  s           r   *sparse_prefix_conservative_extension_guardr$    s    !s4y1}!WFQI"6*O%i0}%,*+a/4FGZ4[^b4b.v6,-4,-5i(%d12h/67I1MM //r$   c                H    |dk  s|t        |       dz
  k\  ryt        | |      S )zNReturn True when the first body row should be included as a second header row.r   F)rN   r$  )r   r   s     r   sparse_prefix_next_header_guardr&    s)    oTQ>5dOLLr$   c                   |dk7  st        |       dk  ryt        d | D        d      }|dk  ry| d   }| d   }t        |      }t        |      }t        |      }t        |      |k  }t	        |d      j                         r|syt        |      |k  xr$ t        |      t        dt        |dz              k  }	t        |      s|d	   d
k\  s|	sy|d   t        dt        |dz              k  ry|d   dkD  s|d   d
kD  ry|d   dk  r	|d   dk  ryt        |      st        |      ryt        | dd       }
t        |
d      }t        |      S )zPromote a leaf-label row under a sparse/grouped rowspan header scaffold.

    An empty first cell in the candidate row is the textual shadow of the row-0
    rowspan label; treat it as header only when later rows form a stable body.
    r   r   Fc              3  2   K   | ]  }t        |        y wr*   r   r   r   s     r   r   z,rowspan_leaf_header_guard.<locals>.<genexpr>       -CH-   r   defaultr   r   r}   r   r{   ?r]   r   r~   r   r   N)rN   r3   r   r   r   r0   r   r   r  r   r  r  r  )r   r   max_colsr!  r  r"  r#  candidate_vectorshifted_by_rowspansparse_rowspan_prefixr  r	  s               r   rowspan_leaf_header_guardr3    su    !s4y1}--q9H!|!WFQI"6*O%i0!),Y(29a &&(1CK(2bs6{c!SQY\`Q`MaFb7b#F+}/MQU/UYn*+c!SD5I.JJ,-48J?8[^b8b/047<N}<]`d<di(,B9,M%d12h/67I1MM //r$   c                    t        |       }|d   dk  ry|d   dkD  xr |d   dk(  }|d   dk\  xs |d	   dk\  }|d
   dk\  xs |d   dk\  }t        |xr |xr |xr t        |              S )Nr{   r   Fr   r   r   r   r   r   r~   r   r]   )r   r9   r   )r   r   first_is_labelrest_is_valuesvalue_heavys        r   leading_body_record_liker8    s    _F!#./!3W?Q8RVW8WN01T9dVD[=\`d=dN)T1WV<N5OSW5WKf>fkfJabeJfFfggr$   c                v    t        |       }t        |d   dk\  xr |d   dk\  xr |d   dk  xr |d   dk        S )	Nr{   rJ   r_   r/   r]   r   r}   r   r   r   s     r   leading_long_form_row_liker:    s`    _F A% 	*)*d2	*%&$.	* =!T)	 r$   c                   t        |       dk  ryt        |       }t        | d      j                         }| D cg c]  }|j                         s| }}t	        |xr% | dd  D cg c]  }|j                         s| c}       }|d   dk  xr |d   dk\  xr |d	   d
k\  }t	        |xs |xr |      S c c}w c c}w )Nr   Fr   r   r{   r   r}   333333?r   r   )rN   r   r   r0   r9   )r   r   r   r!   r   
first_onlysparse_labels          r   r  r    s    
3x!|C HQ%%'E!$5

5H5eNc!"g$NdT$N NOJ!"a' 	,]#t+	,]#t+ 
 
9x8L:: 6$Ns   B6B6%B;;B;c                    t        |       syt        |       D cg c]  \  }}|j                         s| }}}t        t	        |      dk(  xr |d   dkD  xr t	        |       dk\        S c c}}w )NFr   r   r   )r  	enumerater0   r9   rN   )r   idxr!   nonempty_indicess       r   centered_section_label_row_likerC  
  sk    !#&-6s^L	Ttzz|LL$%*X/?/BQ/FX3s8WX=YY Ms
   A,A,c                   g }t        | d|       D ]s  \  }}|dk(  st        |      s|D cg c]#  }|j                         s|j                         % }}t        |      dk7  rTt        |      dk  rc|j	                  |       u |S c c}w )zGReturn sparse section-label rows inside the detected top header prefix.Nr   r   r   )r@  rC  r0   rN   r   )r   r   section_rowsrow_idxr   r!   r   s          r   section_header_rowsrG    s    L!$'7"89 %a<>sC-0ATDJJLDJJLAAx=As8a<G$%  Bs   B	B	c                   t        |       }t        |       }|d   dkD  xr |d   dk(  xr |d   dk\  xr |d   dk\  }|d   dk\  xr |d	   dk  }|d
   dkD  xr& |d   dk(  xr |d   dk\  xr |d   dk  xr |d   dk  }|rd}d}d}|||d   dkD  ||||xs |xs ||t        |       t        |       t	        |       t        |       t        |       dS )Nr   r   r   r   r   r~   r   r   r   r   r   r   r   r]   r}   Fr{   )indexr   r   body_value_rowbody_dense_rowbody_long_form_rowbody_like_rowcoordinate_header_rowleading_body_record_rowleading_long_form_rowr   r   header_candidate)r   r  r8  r:  r  r   r   )r   rI  r   rN  rJ  rK  rL  s          r   row_profilerR     sY   _F7<}! 	,?#q(	,'(D0	, ?#t+	  O,4V9NRV9VN!"Q& 	*%&!+	*./47	* %&$.	* =!T)  "+,q0((0'O>O=O!6#;C#@!;C!@3C8#:3#?05 r$   c                ^    t        |       D cg c]  \  }}t        ||       c}}S c c}}w r*   )r@  rR  )r   rI  r   s      r   r  r  F  s%    6?oF
sKU#FFFs   )c                
   | sddddddddddddddS t        t        |             t        d | D              t        |       z  t        d | D              t        |       z  t        d | D              t        |       z  t        d | D              t        |       z  t        d | D              t        |       z  t        d | D              t        |       z  t        d	 | D              t        |       z  t        d
 | D              t        |       z  t        d | D              t        |       z  t        d | D              t        |       z  t        d | D              t        |       z  t        d | D              t        |       z  dS )Nr\   )countfirst_label_ratior   r~   r   r   body_row_ratiodense_numeric_row_ratiolong_form_row_ratior]   r   r   r_   c              3  D   K   | ]  }|d    dkD  s|d   dk(  sd  yw)r   r   r   r   Nro   rf   s     r   r   z'combine_body_vectors.<locals>.<genexpr>]  s-      yt$?Q:RUV:V[_`r[swx[x y      c              3  &   K   | ]	  }|d      yw)r   Nro   rf   s     r   r   z'combine_body_vectors.<locals>.<genexpr>_  s     !Q$';"<!Q   c              3  &   K   | ]	  }|d      yw)r~   Nro   rf   s     r   r   z'combine_body_vectors.<locals>.<genexpr>`  s     GtT/2Gr]  c              3  &   K   | ]	  }|d      yw)r   Nro   rf   s     r   r   z'combine_body_vectors.<locals>.<genexpr>a  s     C44.Cr]  c              3  &   K   | ]	  }|d      yw)r   Nro   rf   s     r   r   z'combine_body_vectors.<locals>.<genexpr>b  s     K4t$56Kr]  c              3  &   K   | ]	  }|d      yw)r]   Nro   rf   s     r   r   z'combine_body_vectors.<locals>.<genexpr>c  s     MT%7 8Mr]  c              3  &   K   | ]	  }|d      yw)r   Nro   rf   s     r   r   z'combine_body_vectors.<locals>.<genexpr>d  s     $WtT*A%B$Wr]  c              3  &   K   | ]	  }|d      yw)r   Nro   rf   s     r   r   z'combine_body_vectors.<locals>.<genexpr>e  s     (_t.I)J(_r]  c              3  &   K   | ]	  }|d      yw)r_   Nro   rf   s     r   r   z'combine_body_vectors.<locals>.<genexpr>f  s     #UTD)?$@#Ur]  c              3     K   | ]6  }|d    dkD  r|d   dk(  r|d   dk\  r|d   dk\  s|d   dk\  r|d   dk  rd	 8 y
w)r   r   r   r   r   r~   r   r   r   r   Nro   rf   s     r   r   z'combine_body_vectors.<locals>.<genexpr>g  sf      

]#a')Q.-.$6)T1_%-$}2E2M 

s   <>c              3  D   K   | ]  }|d    dk\  s|d   dk  sd  yw)r~   r   r   r   r   Nro   rf   s     r   r   z'combine_body_vectors.<locals>.<genexpr>s  s.      '
T/%:d%BtMGZ^bGbA'
r[  c              3  p   K   | ].  }|d    dkD  r$|d   dk(  r|d   dk\  r|d   dk  r|d   dk  rd	 0 y
w)r   r   r   r   r   r]   r   r}   r   r   Nro   rf   s     r   r   z'combine_body_vectors.<locals>.<genexpr>w  s]      
#
'(1,+,145=+,4'4/ 
#
s   46)rU  rV  r   r~   r   r   r]   r   r   r_   rW  rX  rY  )r   rN   r   )vectorss    r   combine_body_vectorsri  J  s   !$"% "!'*#& #%(),$'
 	
  s7|$  yw yy
g,!!Q!QQTWX_T``GwGG#g,VC7CCc'lRK7KKcRYlZMWMMPST[P\\!$$Ww$W!WZ]^eZf!f%((_W^(_%_befmbn%n ##UW#U UX[\cXd d 



 

 g, $' '
!'
 $
 g,$  # 
#

#
 
 
 g, 9( (r$   c                ^    | |||z    D cg c]  }|d   s	|d    }}t        |      S c c}w )Nr   r   )ri  )profilesstartsizeprofilerh  s        r   r  r    sA     190NfWRYZdRewx fGf(( gs   
**c                    | d   dk  ry| d   dk\  xr | d   dk\  xr | d   d	k\  }| d
   dk\  xr | d   dk\  xr | d   dk  }| d   dk\  xr& | d   dk\  xr | d   dk\  xr | d   dk  xr | d   dk  }|xs |xs |S )NrU  r   FrW  r   r   r.  rV  r   rX  r~   r<  r   g?rY  r   r]   r   ro   )r   
value_bodydense_numeric_bodylong_form_bodys       r   r  r    s    1!"d* 	2)*d2	2()T1  	*+t3 	,_%-	,]#t+  	&'4/ 	.()T1	.01T9	. '(D0	. _%-  =+=~=r$   c                &   t        |       }d}|t        |d   |d   z
        z  }|t        |d   |d   z
        z  }|t        |d   |d   z
        z  }|t        |d   |d   z
        z  }|dt        |d   |d   z
        z  z  }|d	   d
k\  r|dz  }|S )Nr\   r~   r   r   r   rV  r   r   r}   r   r   )r   abs)
header_rowr	  headerdistances       r   boundary_distancerx    s    
#FHF?+mO.LLMMHF=)M-,HHIIHF/0=AU3VVWWHF=)M:M,NNOOHc&!23mDU6VVWWWHm$DOr$   c                    g }|dk  ry|dkD  ry|d| }|syt         fd|D              }t        d |D              }g }|D ]u  }	|	d   s	t        |	d         }
|xr8 |
|dz
  k(  xr. |	d	   xr' |	d
    xr |	d   d   dk  xr |
dkD  xr ||
dz
     d	   }t         |
         rb|re|j	                  |	       w t        d |D              r|s|r%|j	                  d       n|r|j	                  d       t        d |D              r|j	                  d       t        d |D              s|j	                  d       ||dz
     }||dz
     }t         |dz
     |      }|dk(  r,|d   d   dk(  r!|d   d   dkD  r|d   s|j	                  d       |d   r|d   s|j	                  d       |d   d   dk  r|d   s|j	                  d       |d k  r|j	                  d!       | S )"Nr   Tr  Fc              3  @   K   | ]  }t        |d               yw)rI  N)rC  )r   rn  r   s     r   r   z#header_prefix_ok.<locals>.<genexpr>  s"      {]d!@ggFVAW!X {s   c              3  @   K   | ]  }|j                  d d        yw)rN  FNgetr   rn  s     r   r   z#header_prefix_ok.<locals>.<genexpr>  s     jGGKK(?Gjr   r   rI  rQ  rM  r   r{   r   c              3  &   K   | ]	  }|d      yw)r   Nro   r~  s     r   r   z#header_prefix_ok.<locals>.<genexpr>  s     
JG7&'
Jr]  section_label_before_bodyc              3  &   K   | ]	  }|d      yw)rM  Nro   r~  s     r   r   z#header_prefix_ok.<locals>.<genexpr>  s     
F7?#
Fr]  body_like_row_before_bodyc              3  &   K   | ]	  }|d      yw)rQ  Nro   r~  s     r   r   z#header_prefix_ok.<locals>.<genexpr>  s     Mww)*Mr]   non_header_candidate_before_bodyr   r   r   r~   r\   r   (numeric_first_row_without_group_scaffoldrK  &dense_candidate_without_group_scaffoldr   r   *low_alpha_candidate_without_group_scaffoldg?weak_header_body_contrast)r   r   r   rC  r   rx  )r   rk  
body_startr	  reasonscandidate_profilesallowed_section_prefixcoordinate_prefixdisallowed_section_profilesrn  rA  sparse_coordinate_tailpreviouslast_candidatecontrasts   `              r   header_prefix_okr    s]    GQA~!!J/  {hz {{jWijj"$% 8*+''"# 6zA~%6*+6 O,,6 !"23q8	6
 a6 q!"45 	 /tCy9BX'..w78 
J7I
JJSi&NN67	$23

F3E
FF23M:LMM9:
Q'Hj1n-N j1n!5}EHa8$]3q88$_5;23AB&'9R0S?@h.5hG`>aCD$23;r$   c           	         g }t        dt        |       dz
        }t        d|dz         D ]Q  }t        | |      }| |   d   }|xr t	        |      }t        d | d| D              }|j                  |||||d       S |S )Nr  r   r   rM  c              3  P   K   | ]  }|d    xr |j                  dd          yw)rM  rN  FNr|  r~  s     r   r   z(body_start_candidates.<locals>.<genexpr>  s5      
 O$XW[[9PRW-X)XX
s   $&)r  	body_likestart_row_body_likeprior_body_seenbody)r   rN   rA   r  r  r   r   )rk  
candidates	max_startrl  r	  r  stabler  s           r   body_start_candidatesr    s     JAs8}q()Iq)a-( 
:8UK&uoo>$M)>})M 
#Ae,
 
 	##':#2%	

" r$   c                    t        t        |t        |                   D ch c]  }t        | |      j	                         s|! c}S c c}w r*   )rA   r   rN   r   r0   )r   r/  rA  s      r   _nonempty_col_indicesr  
  s8     Xs3x!89[C[c=R=X=X=ZC[[[s   AAc                   |dk  ryt        d | D        d      }|dk  ryt               }| d | D ]  }|j                  t        ||              t	        |      |k  xr$ t	        |      t        dt        |dz              k  S )Nr   Fc              3  2   K   | ]  }t        |        y wr*   r   r)  s     r   r   z,_header_column_incomplete.<locals>.<genexpr>  r*  r+  r,  r   r   r   )r3   r   updater  rN   r   )r   r   r/  filledr   s        r   _header_column_incompleter    s    !--q9H!|uF$_% <+C:;<v;!Qc&kSC4<P5Q&QQr$   c                    | D cg c]#  }|j                         s|j                         % }}t        |      dk  ryt        d |D              S c c}w )Nr   Fc              3  F   K   | ]  }t         j                  |        y wr*   )rT   rR   r   s     r   r   z,_bare_year_value_row_like.<locals>.<genexpr>  s     =Dx!!$'=r   )r0   rN   r   )r   r!   r   s      r   _bare_year_value_row_liker    sH    ),=



=H=
8}q=H=== >s
   AAc           	        t        |       }t        | d      }t        t        | |            }t	        dt        |t        |                   D cg c])  }t        | |      j                         st        | |      + }}g }|d   dk  st        |      dk  r|j                  d       t        |      dk  r|j                  d       |d   st        |       st        |       r|j                  d       t        |       s|d   d	kD  s|d
   dkD  r|j                  d       t        |       r|j                  d       t        |       r|j                  d       |d   dkD  s|d   d	k\  r|j                  d       t        |      dk\  r3t        |      }	t!        |	d      }
t#        |
      s|j                  d       |d   dk\  xs |d   dk\  }|s|j                  d       | S c c}w )Nr   r   r{   r   single_or_sparse_row!no_column_header_cells_after_stubrM  r]   r   r~   r   strong_value_rowbare_year_value_rowr   r   r   r_   long_text_rowfollowing_body_not_stabler   r   r   r   weak_label_signal)r   rR  r   r  rA   r   rN   r   r0   r   r   r   r   r  r  r  r  r  )r   r  r/  r   rn  filled_colsr   nonempty_after_stubr  r  r	  label_signals               r   _undertag_extension_candidater  !  s   C H#q!G.sH=>K<A!SSVWZS[E\<]Salmpruava|a|a~;sC0G !A%[)9A)=-.
!#:;=#59OPS9T'c"h/A&BT&IXVeMfimMm)* %,-c"*+#x0F'G4'O'
>a).9:;MqQ$]3NN67M*d2[h?R6SW[6[L*+;7 @s   G .G r   )capc               2   t        d | D        d      }|dk  r|S |t        |       k\  r|S t        | |      s|S |}t        |t	        t        |       ||z               D ]6  }|t        |       dz
  k\  r |S t        | |   | |dz   d |      }|s |S |dz   }8 |S )zLPromote under-tagged column-header rows immediately below the base boundary.c              3  2   K   | ]  }t        |        y wr*   r   r)  s     r   r   z)extend_header_undertag.<locals>.<genexpr>J  r*  r+  r   r,  r   N)r3   rN   r  rA   r   r  )r   r   r  r/  new_toprF  oks          r   extend_header_undertagr  C  s     --q9H!#d)#$T?;G#c$i39N*OP c$i!m# N +4=$w{}:MxX N A+ Nr$   c                   | syt        |       dk(  ryt        |       }t        |      }|D ]  }t        |d         }|d   r|d   r|dk(  ri|d   d   rt	        | d         }|r y yt        |       r yt        | d      r yt        | d      r yt        |       dk\  rt        | d   | dd        r y yt        | |||d	         s|c S  t        |       ryt        | d      ryt        | d      ryy)
Nr   r   r  r  r  rO  r   r   r  )
rN   r  r  r   r   r   r&  r3  r  r  )r   rk  r  r  r  restore_guardss         r   #find_top_header_rows_by_body_changer  ^  s    
4yA~D!H&x0J 	<01
%3D)E?{45!9$q'!B!+D1.tQ7(q1 4yA~"=d1gtABx"PD(J	&8IJ14 $D)&tQ/ q)r$   T)frozenc                  "    e Zd ZU ded<   ded<   y)HeaderRegionr   r   ztuple[int, ...]rG  N)__name__
__module____qualname____annotations__ro   r$   r   r  r    s    ((r$   r  c                t    t        |       }t        | |      }t        t        | |            }t	        ||      S )N)r   rG  )r  r  tuplerG  r  )r   r   rE  s      r   find_header_regionr    s?    9$?O -T?CO,T?CDL'( r$   c                @    dj                  | j                               S )zMWhitespace-collapse a cell's text (runs of whitespace/newlines -> one space).r>   )rL   rM   r    s    r   collapse_cell_wsr    s    88DJJL!!r$   c                f    | j                  dd      j                  dd      j                  dd      S )zNEscape a cell's text for the serializer: only ``& < >`` (quotes left literal).&z&amp;<z&lt;>z&gt;)replacer    s    r   escape_html_textr    s-    <<W%--c6:BB3OOr$   c                N    dj                  d | j                         D              S )zAA cell's inner HTML: escaped non-empty lines joined by ``<br/>``.z<br/>c              3  p   K   | ].  }|j                         st        |j                                0 y wr*   )r0   r  )r   parts     r   r   z_cell_inner.<locals>.<genexpr>  s(     e4X\XbXbXd(6es   66)rL   
splitlinesr    s    r   _cell_innerr    s    <<e4??CTeeer$   c                   t        |xs d      }dg}t        |       D ];  \  }}||v r|D cg c]-  }t        |j                        st        |j                        / }}t	        |      dk(  r:t	        |      dk\  r,|j                  dt	        |      t        |d         fz         |j                  d       |D ]  }d}|j                  dkD  r|d	|j                  z  z  }|j                  dkD  r|d
|j                  z  z  }|j                  d|j                  |dt        |j                        d|j                  d        |j                  d       > |j                  d       dj                  |      S c c}w )a  Serialize a tagged placement grid to its final ``<table>`` HTML in one pass.

    ``rows`` is a row-major grid of cells duck-typed with ``text`` / ``colspan``
    / ``rowspan`` / ``tag`` (e.g. :class:`pymupdf.table.SpanCell`): each cell
    emits its tag, its ``colspan`` / ``rowspan`` attributes and its ``<br/>``-
    joined escaped inner HTML. A row whose index is in ``section_header_rows``
    and that carries a single non-empty label collapses to one
    ``<th colspan=N>`` spanning the row.ro   z<table>r   r   z!<tr><th colspan="%d">%s</th></tr>r   z<tr>r   z colspan="%d"z rowspan="%d"r  r  z</z</tr>z</table>)r   r@  r  r!   rN   r   r  colspanrowspantagr  rL   )	r   rG  rE  partsrF  r   r   r   attrss	            r   render_table_htmlr    sc    *0b1LKE#D/ l"@EeIYZ^ZcZcId(3eHe8}!c%jAo75z#3HQK#@AB V 	DE||a4<<77||a4<<77LL#'88UK		4JDHHU	 	W'( 
LL775>' fs   E?E?)r!   strreturnr   )r!   r  r  	list[str])r!   r  r  r9   )r!   r  r  r  )ru   r  r  dict[str, float])r   r  r   r   r  r  )r   r  r  r9   )r   r  r  r   )r   r  r  r  )r   list[list[str]]r  r9   )r  r  r  r  r  r9   )r   r  r   r   r  r9   )r   r  r   r   r  z	list[int])r   r  rI  r   r  zdict[str, Any])r   r  r  list[dict[str, Any]])rh  zlist[dict[str, float]]r  r  )rJ   )rk  r  rl  r   rm  r   r  r  )r   r  r  r9   )ru  r  r	  r  r  r   )
r   r  rk  r  r  r   r	  r  r  r9   )rk  r  r  r  )r   r  r/  r   r  zset[int])r   r  r  r  r/  r   r  r9   )r   r  r   r   r  r   r  r   )r   r  r  r   )r   r  r  r  )ro   )r  r  )N__doc__
__future__r   dataclassesr   
statisticsr   typingr   r:   compiler+   
IGNORECASEr1   rP   rQ   rT   rV   rU   r   r   r   r   re   rl   r"   r(   r-   r7   r<   rZ   rx   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r$  r&  r3  r8  r:  r  rC  rG  rR  r  ri  r  r  rx  r  r  r  r  r  r  r  r  r  r  r  r  r  r  ro   r$   r   <module>r     s  @ # !   	 BJJLM	BJJLMM	 BJJH"--X	bjj232::+,2::STBJJTVXVcVcd	"**67

GH$"**%BC Y,K55#
1q>,6.,!	2S
YSc
	N[3"<.Z1h00M"0Jh;Z#LG9z =>)")+.)69))>.
=
="= = $	=
 
=@"2\	R>L 	
 
	
 	6-
--` $) ) )
	"
P
f
 r$   