U
    ߦwh                  	   @   s   d Z ddlZddlmZmZmZmZ ddlmZ dZ	de	 de	 d	e	 d	e	 d
	Z
G dd dZedZeeeedf  eeeef  dddZeeeeeef eeeef ee f ZdS )z
Representation and utils for ranges of PDF file pages.

Copyright (c) 2014, Steve Witham <switham_github@mac-guyver.com>.
All rights reserved. This software is available under a BSD license;
see https://github.com/py-pdf/pypdf/blob/main/LICENSE
    N)AnyListTupleUnion   )
ParseErrorz(0|-?[1-9]\d*)z^(z|(z?(:z?)?)))$c                   @   s   e Zd ZdZeed ef ddddZee	e
dddZed	d
dZed	ddZed	ddZeeeeef dddZee
dddZed	ddZd d dddZdS )	PageRangeaJ  
    A slice-like representation of a range of page indices.

    For example, page numbers, only starting at zero.

    The syntax is like what you would put between brackets [ ].
    The slice is one of the few Python types that can't be subclassed,
    but this class converts to and from slices, and allows similar use.

      -  PageRange(str) parses a string representing a page range.
      -  PageRange(slice) directly "imports" a slice.
      -  to_slice() gives the equivalent slice.
      -  str() and repr() allow printing.
      -  indices(n) is like slice.indices(n).
    N)argreturnc                 C   s   t |tr|| _dS t |tr,| | _dS t |to@tt|}|sNt	||
drt|
d}|dkrv|d nd}t||| _ntdd |
ddd	D  | _dS )
a  
        Initialize with either a slice -- giving the equivalent page range,
        or a PageRange object -- making a copy,
        or a string like
            "int", "[int]:[int]" or "[int]:[int]:[int]",
            where the brackets indicate optional ints.
        Remember, page indices start with zero.
        Page range expression examples:

            :     all pages.                   -1    last page.
            22    just the 23rd page.          :-1   all but the last page.
            0:3   the first three pages.       -2    second-to-last page.
            :3    the first three pages.       -2:   last two pages.
            5:    from the sixth page onward.  -3:-1 third & second to last.
        The third, "stride" or "step" number is also recognized.
            ::2       0 2 4 ... to the end.    3:0:-1    3 2 1 but not 0.
            1:10:2    1 3 5 7 9                2::-1     2 1 0.
            ::-1      all pages in reverse order.
        Note the difference between this notation and arguments to slice():
            slice(3) means the first three pages;
            PageRange("3") means the range of only the fourth page.
            However PageRange(slice(3)) means the first three pages.
        N   r   c                 S   s   g | ]}|rt |nd qS N)int).0g r   3/tmp/pip-unpacked-wheel-r8zeli8p/pypdf/pagerange.py
<listcomp>M   s     z&PageRange.__init__.<locals>.<listcomp>         )
isinstanceslice_slicer   to_slicestrrematchPAGE_RANGE_REr   groupr   )selfr	   mstartstopr   r   r   __init__$   s    



zPageRange.__init__)inputr
   c                 C   s(   t | ttfp&t | to&ttt| S )z
        True if input is a valid initializer for a PageRange.

        Args:
            input: A possible PageRange string or a PageRange object.

        Returns:
            True, if the ``input`` is a valid PageRange.

        )r   r   r   r   boolr   r   r   )r%   r   r   r   validO   s    zPageRange.valid)r
   c                 C   s   | j S )z/Return the slice equivalent of this page range.)r   r    r   r   r   r   _   s    zPageRange.to_slicec                 C   sf   | j }|jdkrB|jdk	r4|j|jd kr4t|jS |j|jf}n|j|j|jf}ddd |D S )zA string like "1:2:3".Nr   :c                 s   s"   | ]}|d krdnt |V  qd S )N )r   )r   ir   r   r   	<genexpr>n   s     z$PageRange.__str__.<locals>.<genexpr>)r   stepr"   r#   r   join)r    sindicesr   r   r   __str__c   s    

zPageRange.__str__c                 C   s   dt t|  d S )z#A string like "PageRange('1:2:3')".z
PageRange())reprr   r(   r   r   r   __repr__p   s    zPageRange.__repr__)nr
   c                 C   s   | j |S )a/  
        Assuming a sequence of length n, calculate the start and stop indices,
        and the stride length of the PageRange.

        See help(slice.indices).

        Args:
            n:  the length of the list of pages to choose from.

        Returns:
            Arguments for range().

        )r   r0   )r    r5   r   r   r   r0   t   s    zPageRange.indices)otherr
   c                 C   s   t |tsdS | j|jkS )NF)r   r   r   )r    r6   r   r   r   __eq__   s    
zPageRange.__eq__c                 C   s    t | j| jj| jj| jjffS r   )hash	__class__r   r"   r#   r-   r(   r   r   r   __hash__   s    zPageRange.__hash__c                 C   s   t |tstdt| | jjd k	s4|jjd k	r<td| jj| jjf}|jj|jjf}|d |d krv|| }}|d |d krtdtt	|d t
|d |d S )NzCan't add PageRange and zCan't add PageRange with strider   r   zCan't add PageRanges with gap)r   r   	TypeErrortyper   r-   
ValueErrorr"   r#   r   max)r    r6   abr   r   r   __add__   s    

zPageRange.__add__)__name__
__module____qualname____doc__r   r   r   r$   staticmethodr   r&   r'   r   r1   r4   r   r   r0   objectr7   r:   rA   r   r   r   r   r      s   +r   r)   )argsr
   c                 C   s   g }d}d}| dD ]n}t |rR|s.td|dk	s:t||t |f d}q|rh|sh||tf t|t rzt||}d}q|S )a  
    Given a list of filenames and page ranges, return a list of (filename, page_range) pairs.

    Args:
        args: A list where the first element is a filename. The other elements are
            filenames, page-range expressions, slice objects, or PageRange objects.
            A filename not followed by a page range indicates all pages of the file.

    Returns:
        A list of (filename, page_range) pairs.

    NFz8The first argument must be a filename, not a page range.T)N)r   r'   r=   AssertionErrorappendPAGE_RANGE_ALLr   )rH   pairsZpdf_filenameZdid_page_ranger	   r   r   r   parse_filename_page_ranges   s$    
rM   )rE   r   typingr   r   r   r   errorsr   Z_INT_REr   r   rK   r   rM   r   ZPageRangeSpecr   r   r   r   <module>   s    '