o
    Zh0h"                     @   sN   d Z ddlZddlmZ G dd dZG dd dZd	d
 ZG dd dZdS )zHandle target-counter, target-counters and target-text.

The TargetCollector is a structure providing required targets' counter_values
and stuff needed to build pending targets later, when the layout of all
targeted anchors has been done.

    N   )LOGGERc                   @   s   e Zd ZdZdddZdS )TargetLookupItemzItem controlling pending targets and page based target counters.

    Collected in the TargetCollector's ``target_lookup_items``.

    pendingc                 C   s"   || _ d | _i | _d | _i | _d S )N)state
target_boxparse_again_functionspage_maker_indexcached_page_counter_values)selfr    r   L/var/www/html/rh/venv/lib/python3.10/site-packages/weasyprint/css/targets.py__init__   s
   
zTargetLookupItem.__init__N)r   __name__
__module____qualname____doc__r   r   r   r   r   r      s    r   c                   @   s   e Zd ZdZdd ZdS )CounterLookupItemzmItem controlling page based counters.

    Collected in the TargetCollector's ``counter_lookup_items``.

    c                 C   s(   || _ || _|| _d | _d| _i | _d S )NF)parse_againmissing_countersmissing_target_countersr	   r   r
   )r   r   r   r   r   r   r   r   -   s   
zCounterLookupItem.__init__Nr   r   r   r   r   r   '   s    r   c                 C   sZ   | d dkr| d  dr| d dd S | d dkr)| d d dkr+| d d S dS dS )z)Get anchor name from string or uri token.r   string   #Nurlinternal)
startswith)anchor_tokenr   r   r   anchor_name_from_token?   s
   r   c                   @   sH   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dS )TargetCollectorz@Collector of HTML targets used by CSS content with ``target-*``.c                 C   s   i | _ i | _d| _d| _d S )NTF)target_lookup_itemscounter_lookup_items
collectinghad_pending_targets)r   r   r   r   r   J   s   
zTargetCollector.__init__c                 C   sB   t |tr| j|durtd| dS | j|t  dS dS )z7Create a TargetLookupItem for the given `anchor_name``.NzAnchor defined twice: %r)
isinstancestrr!   getr   warning
setdefaultr   )r   anchor_namer   r   r   collect_anchorZ   s   
zTargetCollector.collect_anchorc                 C   sV   t |}| j|td}|jdkrd| _|j||f| |jdkr)t	d| |S )zGet a TargetLookupItem corresponding to ``anchor_token``.

        If it is already filled by a previous anchor-element, the status is
        'up-to-date'. Otherwise, it is 'pending', we must parse the whole
        tree again.

        	undefinedr   Tz7Content discarded: target points to undefined anchor %r)
r   r!   r'   r   r   r$   r   r)   r   error)r   r   
source_box	css_tokenr   r*   itemr   r   r   lookup_targetc   s   

zTargetCollector.lookup_targetc                 C   sT   | j |}|r$|jdkr&d|_||_|jdu r(dd | D |_dS dS dS dS )zStore a target called ``anchor_name``.

        If there is a pending TargetLookupItem, it is updated. Only previously
        collected anchors are stored.

        r   
up-to-dateNc                 S   s   i | ]	\}}||  qS r   )copy).0keyvaluer   r   r   
<dictcomp>   s    z0TargetCollector.store_target.<locals>.<dictcomp>)r!   r'   r   r   cached_counter_valuesitems)r   r*   target_counter_valuesr   r0   r   r   r   store_target{   s   
zTargetCollector.store_targetc                 C   sH   | j sdS |s	|r"|jdu r||_t|||}| j||f| dS dS )a$  Collect missing (probably page-based) counters during formatting.

        The ``missing_counters`` are re-used during pagination.

        The ``missing_link`` attribute added to the parent_box is required to
        connect the paginated boxes to their originating ``parent_box``.

        N)r#   missing_linkr   r"   r)   )r   
parent_boxr/   parse_again_functionr   r   counter_lookup_itemr   r   r   collect_missing_counters   s   
z(TargetCollector.collect_missing_countersc                 C   s<   | j r| j D ]}|j D ]}|  qqd| _ d| _dS )z Check pending targets if needed.FN)r$   r!   valuesr   r#   )r   r0   functionr   r   r   check_pending_targets   s   
z%TargetCollector.check_pending_targetsc                 C   s   | j rdS | j|}|rm|jdkro||_|j|krqt||_| j	 D ]M\\}}}|dkr0q%|j
|}|du r;q%|jdu sG|jt|krKd|_q%|D ]}	||	}
|
durk||j d }d|d< ||j  nqMq%dS dS dS dS )zStore target's current ``page_maker_index`` and page counter values.

        Eventually update associated targeting boxes.

        Nr2   contentTcontent_changed)r#   r!   r'   r   r	   r
   r3   deepcopyr"   r9   r   lenr   r   )r   r*   page_counter_valuesr	   
page_makerr0   _r/   r   counter_namecounter_valueremake_stater   r   r   cache_target_page_counters   sD   


z*TargetCollector.cache_target_page_countersN)r   r   r   r   r   r+   r1   r;   r@   rC   rO   r   r   r   r   r    G   s    	
r    )r   r3   loggerr   r   r   r   r    r   r   r   r   <module>   s    