o
    j!                  	   @   s*  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
dZded	efddZded	efddZded	efddZdeded	efddZdeded	efddZdededed	dfddZded eded	dfd!d"Zdeded	eee ee f fd#d$ZdS )%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                    s4   g d dt dtt f fdd}d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   sF     D ]\}}t | |\}}|| V  | || 8 } | dkr  d S qd S )Nr   )divmod)r   decimal
roman_reprx_roman X/var/www/html/fyndo/pharma/fyndo/venv/lib/python3.10/site-packages/pypdf/_page_labels.py	roman_num\   s   
z1number2uppercase_roman_numeral.<locals>.roman_num )intr   strjoinlist)r   r.   r,   r*   r-   number2uppercase_roman_numeralK   s   r4   numberc                 C      t |  S N)r4   lowerr5   r,   r,   r-   number2lowercase_roman_numeralg      r:   c                 C   s|   | dkrt ddd ttdtdd D }d}| dkr<| d	 }|dkr(d	}||d  | }| |8 } | d	 } | dks|S )
Nr   zExpecting a positive numberc                 S   s   g | ]}t |qS r,   )chr).0ir,   r,   r-   
<listcomp>n   s    z+number2uppercase_letter.<locals>.<listcomp>AZr   r/      )
ValueErrorrangeord)r5   alphabetrep	remainderr,   r,   r-   number2uppercase_letterk   s    rI   c                 C   r6   r7   )rI   r8   r9   r,   r,   r-   number2lowercase_letter{   r;   rJ   dictionary_objectindexc           
      C   s   t t| d }d}d }d}|t|k r;|| }||d   }|d t|kr(n||d  |kr1n
|d7 }|t|k sdd tttttd}t	|t
sQt|d S |dd}t t|d	d
}||d }	||	|| |  S )N/Numsr   r      c                 S   s   dS )Nr/   r,   )r)   r,   r,   r-   <lambda>   s    z%get_label_from_nums.<locals>.<lambda>)Nz/Dz/Rz/rz/Az/az/Stz/Pr/   z/S)r   r	   len
get_objectr1   r4   r:   rI   rJ   
isinstancedictget)
rK   rL   numsr>   valuestart_indexmstartprefixmapping_functionr,   r,   r-   get_label_from_nums   s4   	
	r\   readerc                 C   s  t t| j}d|vrt|d S t t|d  }d|v r"t||S d|v r~t|d ts~d}|dk r~t tt |d }|D ]:}t tt	 |d }|d |  krW|d krxn q>t
|ddsq|d7 }|dkrmtd	|} n	t||  S q>n|dk s3td
| dt t|d 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   rM   z/Kidsr   r   z/LimitsNz"Too deep nesting is not supported.z,Could not reliably determine page label for .)r   r
   root_objectr1   rQ   r\   rR   r   r3   r0   r   rT   NotImplementedErrorr   __name__)r]   rL   rootnumber_treelevelkidskidlimitsr,   r,   r-   index2label   s6   
 rh   keyrV   rU   Nc                 C   s   t |d dkrtdt |}|dkr,| ||d  kr,|d }|dkr,| ||d  ks|t |k r@| || kr@|||d < dS |||  ||d | dS )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

    rN   r   6A nums like array must have an even number of elementsr   N)rP   rC   insert)ri   rV   rU   r>   r,   r,   r-   nums_insert   s   rl   page_index_toc                 C   s   t |d dkrtd|| k rtd|| d }|t |k r?|| |krC|| || |t |k rA|| |ks'dS dS dS dS )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

    rN   r   rj   z/page_index_to must be greater or equal than keyN)rP   rC   rL   pop)ri   rm   rU   r>   r,   r,   r-   nums_clear_range   s   

(ro   c                 C   sJ   t |d dkrtd|| d }|t |k r#|| ||d  fS dS )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

    rN   r   rj   r   )NN)rP   rC   rL   )ri   rU   r>   r,   r,   r-   	nums_next  s   rp   )__doc__collections.abcr   r   typingr   r   
_protocolsr   _utilsr   genericr	   r
   r   r   r   r0   r1   r4   r:   rI   rJ   r\   rh   rl   ro   tuplerp   r,   r,   r,   r-   <module>   sJ    <	%1

