o
    Zh0hy                     @   sN  d Z ddlZddlZddlmZ ddlmZmZ ddlm	Z	 ddl
mZ ddlmZ d	d
lmZ i dejdejdejdejdejdejdejdejdejdejdejdejdejdejdejdejdejdejiZdd edd D Z e !d!d"d# e"d$Z#e"d%Z$e"d&Z%d'd( Z&d)d* Z'd+d, Z(	ded-d.Z)d/d0 Z*d1d2 Z+			dfd3d4Z,	dgd5d6Z-d7d8 Z.d9d: Z/d;d< Z0d=d> Z1e"d?j2fd@dAZ3dedBdCZ4dDdE Z5dFdG Z6dHdI Z7dJdK Z8dLdM Z9dNdO Z:dPdQ Z;dhdSdTZ<dUdV Z=dWdX Z>dYdZ Z?d[d\ Z@ded]d^ZAd_d` ZBdadb ZCdcdd ZDdS )izTurn an element tree with style into a "before layout" box tree.

This includes creating anonymous boxes and processing whitespace as necessary.

    N   )html)
propertiestargets)collapse_table_borders)LOGGER)get_lang_quotes   )boxesblockflowinliner   )r   	flow-root)r   r   )r   table)r   r   )r   flex)r   r   )r   grid)r   r   )z	table-row)ztable-row-groupztable-header-groupztable-footer-group)ztable-column)ztable-column-group)z
table-cell)ztable-captionc                 C   s   i | ]	}|t |d  qS )i  )chr).0i r   [/var/www/html/rh/venv/lib/python3.10/site-packages/weasyprint/formatting_structure/build.py
<dictcomp>-   s    r   !      u   　u   −)    -   z
?z[	 ]*
[	 ]*z[	 ]+c                 C   s,   t | } t| } t| } t| } t| } | S )zDCreate anonymous boxes in box descendants according to layout rules.)anonymous_table_boxes
flex_boxes
grid_boxesinline_in_blockblock_in_inlineboxr   r   r   create_anonymous_boxes5   s   r'   c           
         sh   t  |||||}|r|\}nd fdd	}	t  |	|||||\}|  d|_t|}t|}|S )z=Build a formatting structure (box tree) from an element tree.Nc                    s2   | |}|d ur|  krd|d< |S d|d< |S )Nr   displaynoner   )elementpseudo_typestyleelement_tree	style_forr   r   root_style_forJ   s   
z2build_formatting_structure.<locals>.root_style_forTN)element_to_boxcheck_pending_targetsis_for_root_elementr'   set_viewport_overflow)
r/   r0   get_image_from_uribase_urltarget_collectorcounter_style	footnotesbox_listr&   r1   r   r.   r   build_formatting_structure?   s    r=   c                 C   s   t |d d d  | |||S )Nr(   r   )BOX_TYPE_FROM_DISPLAY)element_tagr-   contentr+   r   r   r   make_box_   s   rA   c              
   C   sV  t | jtsg S || }|d }	|	dkrg S |d dkr+|d dkr'd|d< nd|d< t| j|g | }
|d	u rBd
gdd
gidhgf}|\}}}t|| g }|t  || d|
_|| d|
_g }d|d v ryt	t
| ||||||}|| |t| d||||| |d r||d ||
 | j}|r|tj|
| | D ]u}t||||||||}|r|d
 jd dkr|d
 }d|jd< || || d}t| j d|g | }t||||||||_||_|g}|| |j}|rtj|
|}|rt |d tjr|d  j|j7  _q|| q|t| d||||| | D ]}||   || s=|| q+||
_t|
 t| |
|||| t|
 |rpt|
jdkrp|d dkrp|
jtj|
d |d dkr|d d  d7  < || d}t| j d|g | }t||
||||||_|
jd
| t| |
||S )a!  Convert an element and its children into a box with children.

    Return a list of boxes. Most of the time the list will have one item but
    may have zero or more than one.

    Eg.::

        <p>Some <em>emphasised</em> text.</p>

    gives (not actual syntax)::

        BlockBox[
            TextBox['Some '],
            InlineBox[
                TextBox['emphasised'],
            ],
            TextBox[' text.'],
        ]

    ``TextBox``es are anonymous inline boxes:
    See https://www.w3.org/TR/CSS21/visuren.html#anonymous

    r(   r)   floatfootnotefootnote_displayr   r   r   Nr   first-letterz
first-line	list-itembeforeanchorr*   zfootnote-callz::footnote-callafterr	   list_style_positionoutsideu   ​zfootnote-markerz::footnote-marker) 
isinstancetagstrrA   update_countersappendsetfirst_letter_stylefirst_line_stylelistmarker_to_boxextendbefore_after_to_boxstore_targettextr
   TextBoxanonymous_fromr3   r-   content_to_boxeschildrenrC   tailpopprocess_whitespaceset_content_listsprocess_text_transformleninsertr   handle_element)r+   r0   r7   r8   r9   r:   r;   stater-   r(   r&   quote_depthcounter_valuescounter_scopesr^   marker_boxesrZ   child_elementchild_boxesrC   
call_stylefootnote_calltext_boxnamemarker_stylemarkerr   r   r   r3   d   s   















r3   c              
   C   s   || |}|r|du rg S |d }|dkrg S |d }	|	dv r!g S t | j d| |g | }
|\}}}t|| g }d|v rOtt| ||||||}|| |t||
||||| ||
_|d d	kru|\}}}t| |
|d
 ||| |
gS )z8Return the boxes for ::before or ::after pseudo-element.Nr(   r)   r@   )normalinhibitr*   ::rF   bookmark_levelr*   bookmark_label)	rA   rN   rP   rU   rV   rW   r]   r^   compute_bookmark_label)r+   r,   rg   r0   r7   r9   r:   r-   r(   r@   r&   rh   ri   _counter_scopesr^   rk   _quote_depthr   r   r   rX     s>   






rX   c              
   c   s   || d}g }|\}	}
}t | j d||| }|d dkr dS |d \}}|d dvr:|t|||	|
||| nJ|d	krV|||d
 d}|durVtj||}|| |s|d dkr|
ddgd }|d }|	|| }rtj
||}d|jd< || |sdS |d dkrtj||}d|jd< |d dkrtdd}ntdd}tj}d||fff|jd< ntj||}|V  dS )zyYield the box for ::marker pseudo-element if there is one.

    https://drafts.csswg.org/css-lists-3/#marker-pseudo

    rs   ::markerr(   r)   Nlist_style_imager@   )rt   ru   urlimage_orientationr~   orientationlist_style_typer*   rF   r   rI   zpre-wrapwhite_spacerK   rL   absoluteposition	directionltri%d   	translate	transform)rA   rN   rW   r]   r
   InlineReplacedBoxr\   rQ   getrender_markerr[   r-   BlockBoxr   	DimensionZERO_PIXELS	InlineBox)r+   rg   parent_styler0   r7   r9   r:   r-   r^   rh   ri   rz   r&   
image_typeimagecounter_valuecounter_typemarker_text
marker_boxtranslate_xtranslate_yr   r   r   rV   3  sP   








rV   c           .         s(  g  t   fdd}g }i }|duo|du}|jo| }jdu r.dd | D _| D ]O\}}|dkr>|| q0|dkrg|durg|\}}|dkrOq0||jd	 d
}|durf tj| q0|dkrwt	|}||
  q0|dkr|stdd| q0||j|g|R   q0|dv r|d |d }dkrq0|r|t|| vr|| |dkr||dgd }|}n|d }|fdd||dgD }|| q0|dv rt|dd |d \}}dkrq0||||}|jdkr nv|jj}|r,||vr,t|} || g }||vr,|| |j }!|!| |dkrK|!|dgd }|}n$|d }|d dkrY n(|d }"|"fdd|!|dgD }|| q0|dkr|\}}#||||}|jdkr|j}$t	|#|$}||
  q0 n|dkrd||	fvrd|v }%|d o|	dk}&|%std|d d |d< |&r|	d krt|
\}'}(n|	\}'}(|%r|'n|(})||)t|d t|)d   |%r|d  d7  < q0|d!krR|std"d| q0|j |g|R  }*|*du rq0|*! }*d#|*jd$< t"|*tj#rL|*$ D ]}+|+jd% d&v r;q/t%|+j|+||||||d'	|+_&q/ |* q0|d(kr|d s]q0tj'|d },tj(|,f}-d)|-jd*< d)|,jd*< d+|-_) |- q0s r|*||||  S dS ),ae  Compute and return the boxes corresponding to the ``content_list``.

    ``parse_again`` is called to compute the ``content_list`` again when
    ``target_collector.lookup_target()`` detected a pending target.

    ``build_formatting_structure`` calls
    ``target_collector.check_pending_targets()`` after the first pass to do
    required reparsing.

    c                    sT    d | r( rt d tjr d  j| 7  _d S  tj|  d S d S )NTrI   )addrM   r
   r[   rZ   rQ   r\   rZ   )content_boxeshas_text
parent_boxr   r   add_text  s   
z&compute_content_list.<locals>.add_textNc                 S   s   i | ]	\}}||  qS r   )copy)r   keyvaluer   r   r   r     s    z(compute_content_list.<locals>.<dictcomp>stringr~   externalr   r   z	content()zstring()z,"string(%s)" is only allowed in page margins )	counter()z
counters()r   rI   r*   r   r	   c                 3       | ]	}  |V  qd S r2   render_valuer   r   r:   r   r   r   	<genexpr>  
    

z'compute_content_list.<locals>.<genexpr>)target-counter()ztarget-counters()r   z
up-to-dater   c                 3   r   r2   r   r   r   r   r   r     r   ztarget-text()quoteopenzno-autoz	element()z-"element(%s)" is only allowed in page marginsstaticr   r@   )rt   r*   )contextpagezleader()prer   T)+rR   
collectingcached_counter_valuesitemsr-   rQ   r
   r   r\   extract_textstripr   warningjoinget_string_set_forrU   r   r   lookup_targetrg   
target_boxr   anchor_name_from_token
setdefaultcached_page_counter_valuesr   update
startswithmaxr   minrd   get_running_element_fordeepcopyrM   	ParentBoxdescendantsr]   r^   r[   r   	is_leadercollect_missing_counters).content_listr   ri   	css_tokenparse_againr9   r:   r7   rh   quote_stylelangr   r   r+   r   missing_countersmissing_target_countersin_page_contextneed_collect_missingtype_r   originurir   
added_textcounter_namer   rZ   	separatoranchor_tokenr   target_valuesanchor_namelocal_countersseparator_string
text_styler   is_openre   open_quotesclose_quotesquotesnew_boxchildrp   
leader_boxr   )r   r:   r   r   r   r   compute_content_listu  s&  	

























r   c	                    sl   d fdd	}	d dkrg S |dd d}
t d ||
|	 |d d ||}|p5g S )	z:Take the value of a ``content`` property and return boxes.Nc              
      sz   | du ri }n|   }|j g }|t|  tjdkr8tjd tj	r8|jd _dS |_dS )z9Closure to parse the ``parent_boxes`` children all again.Nr	   r   )
r   r   r   rW   r]   rd   r^   rM   r
   LineBox)mixin_pagebased_countersr   local_childrenr:   r7   orig_quote_depthr   r-   r9   r   r   r   5  s   
z%content_to_boxes.<locals>.parse_againr@   ru   r   r   r2   )r   )r-   r   rh   ri   r7   r9   r:   r   r   r   r   r<   r   r   r   r]   1  s   r]   c              
      s   d
 fdd	}d }t  |||d}	|	durIddd |	D }
 jD ]}|d	 kr> j|  nq. j|
f dS dS )zCParse the content-list value of ``string_name`` for ``string-set``.Nc                    s:   | du ri }n|   }| j t | dS )z7Closure to parse the string-set string value all again.N)r   r   r   compute_string_setr   r   r&   r   r:   r+   string_namer9   r   r   r   ^  s   
z'compute_string_set.<locals>.parse_againzstring-set::r+    c                 s   s"    | ]}t |tjr|jV  qd S r2   rM   r
   r[   rZ   r   r&   r   r   r   r   r  s    
z%compute_string_set.<locals>.<genexpr>r   r2   )r   r   
string_setremoverQ   )r+   r&   r   r   ri   r9   r:   r   r   r<   r   string_set_tupler   r   r   r   [  s"   



r   c           	   
      sV   i f fdd	}d}t  |||d}|r)ddd |D  _dS dS )	z5Parses the content-list value for ``bookmark-label``.c                    s@   | du ri }n|   }|   }| j t | dS )z.Closure to parse the bookmark-label all again.N)r   r   r   ry   r   r&   r   r:   r+   r9   r   r   r     s   
z+compute_bookmark_label.<locals>.parse_againzbookmark-labelr   r   c                 s   s    | ]}t |V  qd S r2   )box_textr   r   r   r   r     s    z)compute_bookmark_label.<locals>.<genexpr>N)r   r   rx   )	r+   r&   r   ri   r9   r:   r   r   r<   r   r   r   ry   }  s   
ry   c           	   	   C   sj   g |_ |d dkr t|d D ]\}\}}t| |||||| q|d dkr3t| ||d ||| dS dS )zSet the content-lists values.

    These content-lists are used in GCPM properties like ``string-set`` and
    ``bookmark-label``.

    r   r*   rw   rx   N)r   	enumerater   ry   )	r+   r&   r-   ri   r9   r:   r   r   string_valuesr   r   r   rb     s   
rb   c           
      C   s  | \}}}|d }|d D ]\}}||v r||    n|| ||g | q|d D ] \}}||g }|sK||vsAJ || |d ||d< q/|d }	|	dkrdd|d v rbd	g}	ng }	|	D ]$\}}||g }|s||vsxJ || |d |d  |7  < qfd
S )z$Handle the ``counter-*`` properties.rI   counter_resetcounter_setr   counter_incrementr   rF   r(   )rF   r	   N)r`   r   r   rQ   )
rg   r-   r{   ri   rj   sibling_scopesrq   r   valuesr  r   r   r   rP     s6   






rP   z\Sc                 C   s   t | tjo|| j S )z9Return True if ``box`` is a TextBox with only whitespace.r   )r&   _has_non_whitespacer   r   r   is_whitespace  s   r  c                 #   s    |du r fdd}g }|D ] }||r*|r& j | g d}t||V  g }|V  q|| q|rA j | g d}t||V  dS dS )zWrap consecutive children that do not pass ``test`` in a ``wrapper_type`` box.

    ``test`` defaults to children being of the same type as ``wrapper_type``.

    Nc                    s
   t |  S r2   )rM   r   wrapper_typer   r   test  s   
zwrap_improper.<locals>.test)r^   )r\   table_boxes_childrenrQ   )r&   r^   r	  r
  improperr   wrapperr   r  r   wrap_improper  s    r  c                 C   s2   t | tjr
|  r| S dd | jD }t| |S )zRemove and add boxes according to the table model.

    Take and return a ``Box`` object.

    See https://www.w3.org/TR/CSS21/tables.html#anonymous-boxes

    c                 S      g | ]}t |qS r   )r    r   r   r   r   r   
<listcomp>      z)anonymous_table_boxes.<locals>.<listcomp>)rM   r
   r   
is_runningr^   r  r&   r^   r   r   r   r      s   
r    c                    s  t  tjr	g }n*t  tjr3dd |D }|s3 jdu s" jdk r%d}n j} fddt|D } jrit|dkri|dd \}}|jrOt	|rO|
  t|dkri|dd \}}|jrit	|ri|
d d	d tdg|dd
  ||dd dg D }t  tjrt |tjdd }nt  tjrt |tj}t  tjrt |tj}n
t |tjdd }t  tjrt |tjdd }nt t |tjfdd}t  tjrt |S t| _ S )z3Internal implementation of anonymous_table_boxes().c                 S   s   g | ]
}t |tjr|qS r   )rM   r
   TableColumnBoxr  r   r   r   r    s    
z(table_boxes_children.<locals>.<listcomp>Nr	   c                    s   g | ]	}t j g qS r   )r
   r  r\   )r   _r%   r   r   r    s    r   r   c                 S   s2   g | ]\}}}|r|j r|r|j rt|s|qS r   )internal_table_or_captionr  )r   
prev_childr   
next_childr   r   r   r  *  s    	

rI   c                 S   s   | j S r2   proper_table_childr  r   r   r   <lambda>=  s    z&table_boxes_children.<locals>.<lambda>c                 S   s   t | tj S r2   )rM   r
   TableCellBoxr  r   r   r   r  I  s    c                 S   s   | j  S r2   r  r  r   r   r   r  O      c                    s   | j  p | jv S r2   )r  proper_parentsr  )parent_typer   r   r  T  s    
)rM   r
   r  TableColumnGroupBoxspanrangetabular_containerrd   r  r  r`   zipTableBoxr  TableRowBoxTableRowGroupBoxr  r   InlineTableBoxtype
wrap_tablerU   r^   )r&   r^   r#  internalrZ   r   )r&   r!  r   r     sn   




r  c           !   
   C   s  g }g }g }t j|t j|t j|t j|t j|i}|D ]}|t| | qg g d}|D ]}||jd  | q,t	t
| |t j}	d}
|	D ]}|
|_|jr\|jD ]	}|
|_|
d7 }
qQqF|
|j7 }
qF|
}t
| |t j}g }d}d}|D ](}|jd }|dkr|du rd|_|}qs|d	kr|du rd|_|}qs|| qs|dur|gng | |dur|gng  }d}|D ]v}d
d |jD }|jD ]a}|d}d}
|jD ]T}|
|v r|
d7 }
|
|v s|
|_|
|j }|jdkrt|d }|jdkr|}||_nt|j||_|d|jd  }t|
|}|D ]}|| q|}
t||
}qq|t|j7 }q| |}|j |_t|	|_|jd dkrJt||||_t| t jrUt j }nt j!}|"| |d |g |d  }|j |_d|_#t$j%D ]} |j|  |j| < t$j&|  |j| < qs|S )a  Take a table box and return it in its table wrapper box.

    Also re-order children and assign grid positions to each column and cell.

    Because of colspan/rowspan works, grid_y is implicitly the index of a row,
    but grid_x is an explicit attribute on cells, columns and column group.

    https://www.w3.org/TR/CSS21/tables.html#model
    https://www.w3.org/TR/CSS21/tables.html#table-layout

    )topbottomcaption_sider   r	   Nr(   r   Tr   c                 S   s   g | ]}t  qS r   )rR   )r   rowr   r   r   r    s    zwrap_table.<locals>.<listcomp>border_collapsecollapser.  r/  )'r
   r  r"  r(  r)  TableCaptionBoxr+  rQ   r-   rU   r  grid_xr^   r#  	is_header	is_footerr`   colspanrowspanrd   r   r$  r   r   copy_with_childrenr   tuplecolumn_groupsr   collapsed_border_gridrM   r*  InlineBlockBoxr   r\   is_table_wrapperr   TABLE_WRAPPER_BOX_PROPERTIESINITIAL_VALUES)!r&   r^   columnsrowsall_captionsby_typer   captionscaptionr<  r5  groupcolumn
grid_width
row_groupsbody_row_groupsheaderfooterr(   grid_heightoccupied_cells_by_rowr1  occupied_cells_in_this_rowcell
new_grid_xmax_rowspanspanned_rowsspanned_columnsoccupied_cellsr   r	  r  rq   r   r   r   r,  ^  s   












r,  c                 C   8   t | tjr
|  r| S dd | jD }t| || _| S )zRemove and add boxes according to the flex model.

    Take and return a ``Box`` object.

    See https://www.w3.org/TR/css-flexbox-1/#flex-items

    c                 S   r  r   )r!   r  r   r   r   r    r  zflex_boxes.<locals>.<listcomp>)rM   r
   r   r  r^   flex_childrenr  r   r   r   r!     
   r!   c                 C   s   t | tjrcg }|D ]V}dd |_| rd|_t |tjr%|jds%q
t |tj	r@tj
||j}|j|_d|_|| q
t |tjr[tj
||g}|j|_d|_|| q
|| q
|S |S )Nc                   S   s   dS )NFr   r   r   r   r   r    s    zflex_children.<locals>.<lambda>Tr   )rM   r
   FlexContainerBox
is_floatedis_in_normal_flowis_flex_itemr[   rZ   r   r>  r   r\   r^   r-   rQ   InlineLevelBox)r&   r^   rY  r   	anonymousr   r   r   rY    s*   
rY  c                 C   rX  )zRemove and add boxes according to the grid model.

    Take and return a ``Box`` object.

    See https://drafts.csswg.org/css-grid-2/#grid-item

    c                 S   r  r   )r"   r  r   r   r   r    r  zgrid_boxes.<locals>.<listcomp>)rM   r
   r   r  r^   grid_childrenr  r   r   r   r"     rZ  r"   c                 C   s   t | tjrag }|D ]T}| rd|_t |tjr |jds q
t |tjr;tj	
||j}|j|_d|_|| q
t |tjrYtj	
||g}|j|_d|_d|_|| q
|| q
|S |S )NTr   F)rM   r
   GridContainerBoxr]  is_grid_itemr[   rZ   r   r>  r   r\   r^   r-   rQ   r_  )r&   r^   ra  r   r`  r   r   r   ra     s*   ra  Fc                 C   s  t | tjrW| j}|s|S td|}| jd dv }| jd dv }|r)td|}|r1|dd}|rQt	d| }}|rK|
drK|dd }d| _|d}nd	}|| _n%| jD ]!}t |tjtjfrut||}|  rt| rt|}qZ| r{d	}qZ|o|   S )
zFirst part of "The 'white-space' processing model".

    See https://www.w3.org/TR/CSS21/text.html#white-space-model
    https://drafts.csswg.org/css-text-3/#white-space-rules

    
r   )rt   nowraprt   re  zpre-liner   r	   NTF)rM   r
   r[   rZ   LINE_FEED_REsubr-   TAB_REreplaceSPACE_REr   leading_collapsible_spaceendswithr^   r   ra   r]  r  )r&   following_collapsible_spacerZ   new_line_collapsespace_collapseprevious_textr   child_collapsible_spacer   r   r   ra   =  s>   
ra   c                 C   s   t | tjr5| jd }|dkr"dd dd tdd d| | j| _| jd dkr3| jd	d
| _d S d S |  sL| jD ]}t |tjtj	frKt
| q<d S d S )Ntext_transformr*   c                 S      |   S r2   )upperr   r   r   r   r  x  r  z(process_text_transform.<locals>.<lambda>c                 S   rt  r2   )lowerr   r   r   r   r  y  r  c                 S   s
   |  tS r2   )r   ASCII_TO_WIDEr   r   r   r   r  {  s   
 )	uppercase	lowercase
capitalizez
full-widthhyphens   ­r   )rM   r
   r[   r-   rz  rZ   rj  r  r^   r   rc   )r&   rs  r   r   r   r   rc   s  s,   

rc   c                 C   sR   d}d}| D ] }t |d }|s|dv rd}| }n|dkr"d}||7 }q|S )uC   Capitalize words according to CSS’s "text-transform: capitalize".Fr   r   )LNTZ)unicodedatacategoryru  )rZ   letter_foundoutputletterr  r   r   r   rz    s   

rz  c           
      C   s  | j r|  r	| S t| j }|r| jdu r|d j| _g }d}|D ]}|r(d|_t|tjr5|js5|j}q!d}|t	| q!| j
du rG|| _
t| tjsR|| _ | S g }g }|D ]Y}t|tjrbJ |rn| rn|| qXt|tjsz|r| s|st|tjr|jdkr|jd dv s|| qX|rtj| |}tj| |g}	||	 g }|| qX|rtj| |}|rtj| |g}	||	 n|| || _ | S )a  Build the structure of lines inside blocks and return a new box tree.

    Consecutive inline-level boxes in a block container box are wrapped into a
    line box, itself wrapped into an anonymous block box.

    This line box will be broken into multiple lines later.

    This is the first case in
    https://www.w3.org/TR/CSS21/visuren.html#anonymous-block-level

    Eg.::

        BlockBox[
            TextBox['Some '],
            InlineBox[TextBox['text']],
            BlockBox[
                TextBox['More text'],
            ]
        ]

    is turned into::

        BlockBox[
            AnonymousBlockBox[
                LineBox[
                    TextBox['Some '],
                    InlineBox[TextBox['text']],
                ]
            ]
            BlockBox[
                LineBox[
                    TextBox['More text'],
                ]
            ]
        ]

    Fr   Tr   r   rf  )r^   r  rU   rl  rM   r
   r[   rZ   rQ   r#   trailing_collapsible_spaceBlockContainerBoxr   is_absolutely_positionedr_  r]  r-   r\   r   )
r&   box_childrenr^   r  r   new_line_childrennew_children	child_boxline_boxr`  r   r   r   r#     sh   &






r#   c           	      C   s   | j r|  r	| S g }d}| j D ]Y}t|tjrZt| j dks&J d| j  d}	 t||d\}}}|du r7ntj| |g}|	| |	t
| q)|rWtj| |g}n|}nt
|}||urdd}|	| q|ro|| _ | S )a  Build the structure of blocks inside lines.

    Inline boxes containing block-level boxes will be broken in two
    boxes on each side on consecutive block-level boxes, each side wrapped
    in an anonymous block-level box.

    This is the second case in
    https://www.w3.org/TR/CSS21/visuren.html#anonymous-block-level

    Eg. if this is given::

        BlockBox[
            LineBox[
                InlineBox[
                    TextBox['Hello.'],
                ],
                InlineBox[
                    TextBox['Some '],
                    InlineBox[
                        TextBox['text']
                        BlockBox[LineBox[TextBox['More text']]],
                        BlockBox[LineBox[TextBox['More text again']]],
                    ],
                    BlockBox[LineBox[TextBox['And again.']]],
                ]
            ]
        ]

    this is returned::

        BlockBox[
            AnonymousBlockBox[
                LineBox[
                    InlineBox[
                        TextBox['Hello.'],
                    ],
                    InlineBox[
                        TextBox['Some '],
                        InlineBox[TextBox['text']],
                    ]
                ]
            ],
            BlockBox[LineBox[TextBox['More text']]],
            BlockBox[LineBox[TextBox['More text again']]],
            AnonymousBlockBox[
                LineBox[
                    InlineBox[
                    ]
                ]
            ],
            BlockBox[LineBox[TextBox['And again.']]],
            AnonymousBlockBox[
                LineBox[
                    InlineBox[
                    ]
                ]
            ],
        ]

    Fr	   z9Line boxes should have no siblings at this stage, got %r.NT)
skip_stack)r^   r  rM   r
   r   rd   _inner_block_in_inliner   r\   rQ   r$   )	r&   r  changedr   stacknew_liner   anon	new_childr   r   r   r$     s@   =

	r$   c                 C   s  g }d}d}d}|du }|rd}n|  \\}}t| j|d D ]V\}}	|| }
t|	tjr@|	 r@|du s9J |	}|
d7 }
n(t|	tjrSt|	|}d}|\}}}n
|du sYJ t	|	}||	urcd}|
| |durw|
|i}| |}  n
q!|s||r| |} | ||fS )a  Find a block-level box in an inline formatting context.

    If one is found, return ``(new_box, block_level_box, resume_at)``.
    ``new_box`` contains all of ``box`` content before the block-level box.
    ``resume_at`` can be passed as ``skip_stack`` in a new call to
    this function to resume the search just after the block-level box.

    If no block-level box is found after the position marked by
    ``skip_stack``, return ``(new_box, None, None)``

    NFr   r	   T)r   r   r^   rM   r
   BlockLevelBoxr]  r   r  r$   rQ   r:  )r&   r  r  block_level_box	resume_atr  is_startskipr   r   index	recursionr  r   r   r   r  k  sB   





r  c                 C   s\   | }| j  dkr!| jd dkr!| jD ]}|j  dkr |} nq|jd | _d|jd< | S )z
    Set a ``viewport_overflow`` attribute on the box for the root element.

    Like backgrounds, ``overflow`` on the root element must be propagated
    to the viewport.

    See https://www.w3.org/TR/CSS21/visufx.html#overflow
    r   overflowvisiblebody)r?   rv  r-   r^   viewport_overflow)root_box
chosen_boxr   r   r   r   r6     s   	

r6   c                 C   s:   t | tjr	| jS t | tjrddd |  D S dS )Nr   c                 s   sF    | ]}|j d s|j ds|j dst|tjr|jV  qdS )z::beforez::afterr|   N)r?   rm  rM   r
   r[   rZ   r  r   r   r   r     s    




zbox_text.<locals>.<genexpr>)rM   r
   r[   rZ   r   r   r   r%   r   r   r   r     s   
r   c                    s    dv rt |S  dv r"t|tjr d fdd| D S dS  dkrId}d}t |}|D ]}t|}|dvrB|r@ |S d	}||7 }q0|S d S )
N)rZ   r@   )rG   rJ   r   c                 3   s6    | ]}|j d   rt|tjst|V  qdS )rv   N)r?   rm  rM   r
   r   r   r  	text_partr   r   r     s    

zextract_text.<locals>.<genexpr>rE   F)PsPePiPfPoT)r   rM   r
   r   r   r   r  r  )r  r&   character_foundfirst_letterrZ   r  r  r   r  r   r     s,   

r   r2   )NNNNNNN)NN)F)E__doc__rer  r   r   cssr   r   layout.tabler   loggerr   text.constantsr   r
   r   r   r>  r'  r*  FlexBoxInlineFlexBoxGridBoxInlineGridBoxr(  r)  r  r"  r  r4  r>   r$  rw  r   compilerg  ri  rk  r'   r=   rA   r3   rX   rV   r   r]   r   ry   rb   rP   searchr  r  r    r  r,  r!   rY  r"   ra  ra   rc   rz  r#   r$   r  r6   r   r   r   r   r   r   <module>   s    




 
 ".D
 ?
*"'
^ 
6p
f5