
    mj&              	          d Z ddlmZmZ ddlmZmZ ddlmZ ddl	m
Z
 ddlmZmZmZmZmZ ded	efd
Zded	efdZded	efdZded	efdZdeded	efdZdeded	efdZdededed	dfdZdededed	dfdZdeded	eee   ee   f   fdZy)u  
Page labels are shown by PDF viewers as "the page number".

A page has a numeric index, starting at 0. Additionally, the page
has a label. In the most simple case:

    label = index + 1

However, the title page and the table of contents might have Roman numerals as
page labels. This makes things more complicated.

Example 1
---------

>>> reader.root_object["/PageLabels"]["/Nums"]
[0, IndirectObject(18, 0, 139929798197504),
 8, IndirectObject(19, 0, 139929798197504)]
>>> reader.get_object(reader.root_object["/PageLabels"]["/Nums"][1])
{'/S': '/r'}
>>> reader.get_object(reader.root_object["/PageLabels"]["/Nums"][3])
{'/S': '/D'}

Example 2
---------
The following is a document with pages labeled
i, ii, iii, iv, 1, 2, 3, A-8, A-9, ...

1 0 obj
    << /Type /Catalog
       /PageLabels << /Nums [
                        0 << /S /r >>
                        4 << /S /D >>
                        7 << /S /D
                             /P ( A- )
                             /St 8
                        >>
                        % A number tree containing
                        % three page label dictionaries
                        ]
                   >>
    ...
    >>
endobj


§12.4.2 PDF Specification 1.7 and 2.0
=====================================

Entries in a page label dictionary
----------------------------------
The /S key:
D       Decimal Arabic numerals
R       Uppercase Roman numerals
r       Lowercase Roman numerals
A       Uppercase letters (A to Z for the first 26 pages,
                           AA to ZZ for the next 26, and so on)
a       Lowercase letters (a to z for the first 26 pages,
                           aa to zz for the next 26, and so on)
    )CallableIterator)Optionalcast   )PdfCommonDocProtocol)logger_warning)ArrayObjectDictionaryObject
NullObjectNumberObjectis_null_or_nonenumreturnc                 ~    g ddt         dt        t           ffd}dj                  t	         ||                   S )N))i  M)i  CM)i  D)i  CD)d   C)Z   XC)2   L)(   XL)
   X)	   IX)   V)   IV)r   Ir   r   c              3   l   K   D ]*  \  }}t        | |      \  }}||z   | ||z  z  } | dk  s* y  y w)Nr   )divmod)r   decimal
roman_reprx_romans        E/root/.hermes/venv/lib/python3.12/site-packages/pypdf/_page_labels.py	roman_numz1number2uppercase_roman_numeral.<locals>.roman_num\   sM     #( 	GZ#w'DAqq. 7Q;Cax	s   ,44 )intr   strjoinlist)r   r/   r-   s     @r.   number2uppercase_roman_numeralr5   K   s;    E s x}  774	#'((    numberc                 4    t        |       j                         S N)r5   lowerr7   s    r.   number2lowercase_roman_numeralr<   g   s    )&17799r6   c                     | dk  rt        d      t        t        d      t        d      dz         D cg c]  }t        |       }}d}| dkD  r'| dz  }|dk(  rd}||dz
     |z   }| |z  } | dz  } | dkD  r'|S c c}w )Nr   zExpecting a positive numberAZr   r0      )
ValueErrorrangeordchr)r7   ialphabetrep	remainders        r.   number2uppercase_letterrI   k   s    {677 %c#hC1 =>1A>H>
C
1*RK	>Iy1}%+)2 1* J ?s   A8c                 4    t        |       j                         S r9   )rI   r:   r;   s    r.   number2lowercase_letterrK   {   s    "6*0022r6   dictionary_objectindexc                    t        t        | d         }t        |      }d}d }d}||k  rU|dz   |k\  rt        dt               n;||   }||dz      j                         }|dz   |k(  rn||dz      |kD  rn|dz  }||k  rUd t        t        t        t        t        d}t        |t              st        |dz         S |j                  d	d      }t        t        |j                  d
d            }	|j                  |j                  d            }
|
/t        dt        |j                  d             t        |dz         S 	 |	 |
||z
  |z         z   S # t        t        f$ r$ t        dt        ||	       t        |dz         cY S w xY w)N/Numsr   r   z(Ignoring last /Nums key without a value.source   c                      y)Nr0    )r,   s    r.   <lambda>z%get_label_from_nums.<locals>.<lambda>   s    r6   )Nz/Dz/Rz/rz/Az/az/Stz/Pr0   z/Sz?Ignoring unknown page label numbering style %(style)r in /Nums.)rQ   stylezLIgnoring malformed page label entry in /Nums (/St=%(start)r, /P=%(prefix)r).)rQ   startprefix)r   r
   lenr	   __name__
get_objectr2   r5   r<   rI   rK   
isinstancedictget	TypeErrorrA   )rL   rM   numsnums_lengthrE   valuestart_indexmrW   rX   mapping_functions              r.   get_label_from_numsrf      s    .w78Dd)K	AEK
k/q5K:8 1gQU&&(q5KA;	Q k/ ,,%%4A eT"519~IIeQE#uyyr*+FuuUYYt_-M))D/	

 519~
()<u)DEEEz" Z		
 519~s   ?E 0FFreaderc                    t        t        | j                        }d|vrt        |dz         S t        t        |d   j	                               }d|v rt        ||      S d|v rt        |d   t              sd}|dk  rt        t        t           |d         }|D ]  }|j                  dt                     j	                         }t        |t              rt        |      dk  rt        d	t        
       [|d   |cxk  r	|d   k  smn pt        |j                  dd            s|dz  }|dk(  rt        d      |} nt        ||      c S  n|dk  rt        dt        |       t        |dz         S )z
    See 7.9.7 "Number Trees".

    Args:
        reader: The PdfReader
        index: The index of the page

    Returns:
        The label of the page, e.g. "iv" or "4".

    z/PageLabelsr   rO   z/Kidsr   r   z/LimitsrR   z>Ignoring kid with missing or malformed /Limits in /PageLabels.rP   Nz"Too deep nesting is not supported.z6Could not reliably determine page label for %(index)d.)rQ   rM   )r   r   root_objectr2   r[   rf   r\   r   r4   r^   rY   r	   rZ   r   NotImplementedError)rg   rM   rootnumber_treelevelkidskidlimitss           r.   index2labelrq      sw     &"4"45DD 519~'m)<)G)G)IJK+";66+jW1Ez&R ck-.G0DED JL9DDF!&$/3v;?"X' !922*3777D+AB
 C<"5 D#  '* .sE::-4 9 ck< KT\dijuqy>r6   keyrb   r`   Nc                 *   t        |      dz  dk7  rt        d      t        |      }|dk7  r!| ||dz
     k  r|dz
  }|dk7  r| ||dz
     k  r|t        |      k  r| ||   k(  r	|||dz   <   y|j                  ||        |j                  |dz   |       y)z
    Insert a key, value pair in a Nums array.

    See 7.9.7 "Number Trees".

    Args:
        key: number key of the entry
        value: value of the entry
        nums: Nums array to modify

    rR   r   6A nums like array must have an even number of elementsr   N)rY   rA   insert)rr   rb   r`   rE   s       r.   nums_insertrv      s      4y1}QRRD	A
q&SDQK'E q&SDQK' 	3t9}QQUAsAE5!r6   page_index_toc                 (   t        |      dz  dk7  rt        d      || k  rt        d      |j                  |       dz   }|t        |      k  rD||   |k  r;|j                  |       |j                  |       |t        |      k  r
||   |k  r9yyyy)a  
    Remove all entries in a number tree in a range after an entry.

    See 7.9.7 "Number Trees".

    Args:
        key: number key of the entry before the range
        page_index_to: The page index of the upper limit of the range
        nums: Nums array to modify

    rR   r   rt   z/page_index_to must be greater or equal than keyN)rY   rA   rM   pop)rr   rw   r`   rE   s       r.   nums_clear_rangerz     s      4y1}QRRsJKK

3!A
c$i-DG}4 c$i-DG}4-4-r6   c                     t        |      dz  dk7  rt        d      |j                  |       dz   }|t        |      k  r||   ||dz      fS y)z
    Return the (key, value) pair of the entry after the given one.

    See 7.9.7 "Number Trees".

    Args:
        key: number key of the entry
        nums: Nums array

    rR   r   rt   r   )NN)rY   rA   rM   )rr   r`   rE   s      r.   	nums_nextr|   -  sW     4y1}QRR

3!A3t9}Qa!e%%r6   )__doc__collections.abcr   r   typingr   r   
_protocolsr   _utilsr	   genericr
   r   r   r   r   r1   r2   r5   r<   rI   rK   rf   rq   rv   rz   tupler|   rT   r6   r.   <module>r      s-  :x / ! , " ) ) )8:3 :3 :C C  3C 3C 3:+; :C :C :z5, 5S 5S 5p"	"" " 
	"<	  
	6	
 8L!8,<#==>r6   