a
    Qhy                     @   s  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 ejejejejejejejejejejejejejejejejejejd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(dTddZ)dd Z*d d! Z+dUd"d#Z,dVd$d%Z-d&d' Z.d(d) Z/d*d+ Z0d,d- Z1e"d.j2fd/d0Z3dWd1d2Z4d3d4 Z5d5d6 Z6d7d8 Z7d9d: Z8d;d< Z9d=d> Z:d?d@ Z;dXdBdCZ<dDdE Z=dFdG Z>dHdI Z?dJdK Z@dYdLdMZAdNdO ZBdPdQ ZCdRdS ZDdS )ZzTurn 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/sistema_ama/venv/lib/python3.9/site-packages/weasyprint/formatting_structure/build.py
<dictcomp>-       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                    s0   | |}|d ur,|  kr$d|d< n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_boxZcheck_pending_targetsis_for_root_elementr(   set_viewport_overflow)
r0   r1   get_image_from_uribase_urltarget_collectorcounter_style	footnotesbox_listr'   r2   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    r@   c              
   C   s`  t | jtsg S || }|d }	|	dkr,g S |d dkrV|d dkrNd|d< nd|d< t| j|g | }
|d	u rd
gdd
gidhgf}|\}}}t|| g }|t  || d|
_|| d|
_g }d|d v rt	t
| ||||||}|| |t| d||||| |d r(||d ||
 | j}|rH|tj|
| | D ]}t||||||||}|r|d
 jd dkr|d
 }d|jd< || || d}t| j d|g | }t||||||||_||_|g}|| |j}|rLtj|
|}|r0t |d tjr0|d  j|j7  _n
|| qL|t| d||||| | D ]&}||   || s`|| q`||
_t|
 t| |
|||| t|
 |rt|
jdkr|d dkr|
jtj|
d |d dkrP|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strr@   update_countersappendsetZfirst_letter_styleZfirst_line_stylelistmarker_to_boxextendbefore_after_to_boxZstore_targettextr
   TextBoxanonymous_fromr3   r.   content_to_boxeschildrenrB   tailpopprocess_whitespaceset_content_listsprocess_text_transformleninsertr   handle_element)r,   r1   r6   r7   r8   r9   r:   stater.   r)   r'   quote_depthcounter_valuescounter_scopesrZ   marker_boxesrV   Zchild_elementZchild_boxesrB   Z
call_styleZfootnote_calltext_boxnameZ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 rBg S t | j d| |g | }
|\}}}t|| g }d|v rtt| ||||||}|| |t||
||||| ||
_|d d	kr|\}}}t| |
|d
 ||| |
gS )z8Return the boxes for ::before or ::after pseudo-element.Nr)   r*   r?   )normalinhibitr+   ::rE   bookmark_levelr+   bookmark_label)	r@   rM   rO   rR   rS   rT   rY   rZ   compute_bookmark_label)r,   r-   rc   r1   r6   r8   r9   r.   r)   r?   r'   rd   re   _counter_scopesrZ   rg   _quote_depthr   r   r   rU     s>    






rU   c              
   c   s  || d}g }|\}	}
}t | j d||| }|d dkr>dS |d \}}|d dvrr|t|||	|
||| n|d	kr|||d
 d}|durtj||}|| |s|d dkr|
ddgd }|d }|	|| }rtj
||}d|jd< || |sdS |d dkrtj||}d|jd< |d dkrXt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

    rj   ::markerr)   r*   Nlist_style_imager?   )rk   rl   urlimage_orientationru   orientationlist_style_typer+   rE   r   rH   zpre-wrapwhite_spacerJ   rK   absoluteposition	directionltri%d   	translate	transform)r@   rM   rT   rY   r
   InlineReplacedBoxrX   rP   getrender_markerrW   r.   BlockBoxr   	DimensionZERO_PIXELS	InlineBox)r,   rc   parent_styler1   r6   r8   r9   r.   rZ   rd   re   rq   r'   Z
image_typeimagecounter_valuecounter_typeZmarker_textZ
marker_boxZtranslate_xZtranslate_yr   r   r   rS   3  sN    







rS   c           .         s:  g  t   fdd}g }i }|duo0|du}|jo<| }jdu r\dd | D _| D ]\}}|dkr||| q`|dkr|dur|\}}|dkrq`||jd	 d
}|dur̈ tj| q`|dkrt	|}||
  q`|dkr*|stdd| q`||j|g|R   q`|dv r|d |d  }dkrRq`|rt|t|| vrt|| |dkr||dgd }|}n,|d }|fdd||dgD }|| q`|dv r|dd |d  \}}dkrq`||||}|jdkr& q|jj}|rh||vrht|} || g }||vrh|| |j }!|!| |dkr|!|dgd }|}nH|d }|d dkr q|d }"|"fdd|!|dgD }|| q`|dkrL|\}}#||||}|jdkrD|j}$t	|#|$}||
  n qq`|dkrd||	fvrd|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  < q`|d!kr|s,td"d| q`|j |g|R  }*|*du rJq`|*! }*d#|*jd$< t"|*tj#r|*$ D ]8}+|+jd% d&v rqrt%|+j|+||||||d'	|+_&qr |* q`|d(kr`|d sq`tj'|d },tj(|,f}-d)|-jd*< d)|,jd*< d+|-_) |- q`s  r6|*||||  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                    sN    d | rJ r6t d tjr6 d  j| 7  _n tj|  d S )NTrH   )addrL   r
   rW   rV   rP   rX   rV   )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>stringru   externalrv   rw   z	content()zstring()z,"string(%s)" is only allowed in page margins )	counter()z
counters()r   rH   r+   r   r	   c                 3   s   | ]}  |V  qd S Nrender_valuer   r   r9   r   r   r   	<genexpr>  s   z'compute_content_list.<locals>.<genexpr>)target-counter()ztarget-counters()r   z
up-to-dater   c                 3   s   | ]}  |V  qd S r   r   r   r   r   r   r     s   ztarget-text()quoteopenzno-autoz	element()z-"element(%s)" is only allowed in page marginsstaticr|   r?   )rk   r+   )contextpagezleader()prerz   T)+rQ   Z
collectingcached_counter_valuesitemsr.   rP   r
   r   rX   extract_textstripr   warningjoinget_string_set_forrR   r   r   lookup_targetrc   
target_boxr   Zanchor_name_from_token
setdefaultZcached_page_counter_valuesr   update
startswithmaxr   minr`   get_running_element_fordeepcopyrL   	ParentBoxdescendantsrY   rZ   rW   r   	is_leaderZcollect_missing_counters).content_listr   re   	css_tokenparse_againr8   r9   r6   rd   Zquote_stylelangr   r   r,   r   Zmissing_countersZmissing_target_countersZin_page_contextZneed_collect_missingtype_r   originurir   Z
added_textcounter_namer   rV   	separatoranchor_tokenr   Ztarget_valuesanchor_namelocal_countersZseparator_stringZ
text_styler   Zis_openra   Zopen_quotesZclose_quotesquotesnew_boxchildrh   Z
leader_boxr   )r   r9   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 ||}|pjg S )	z:Take the value of a ``content`` property and return boxes.Nc              
      sx   | du ri }n|   }|j g }|t|  tjdkrntjd tj	rn|jd _n|_dS )z9Closure to parse the ``parent_boxes`` children all again.Nr	   r   )
r   r   r   rT   rY   r`   rZ   rL   r
   LineBox)mixin_pagebased_countersr   Zlocal_childrenr9   r6   Zorig_quote_depthr   r.   r8   r   r   r   5  s    z%content_to_boxes.<locals>.parse_againr?   rl   r   r   )N)r   )r.   r   rd   re   r6   r8   r9   r   r   r   r   r;   r   r   r   rY   1  s    rY   c              
      s   d
 fdd	}d }t  |||d}	|	durddd |	D }
 jD ] }|d	 kr\ j|  q~q\ j|
f 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   r9   r,   string_namer8   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 r   rL   r
   rW   rV   r   r'   r   r   r   r   r  s   z%compute_string_set.<locals>.<genexpr>r   )N)r   r   
string_setremoverP   )r,   r'   r   r   re   r8   r9   r   r   r;   r   Zstring_set_tupler   r   r   r   [  s    



r   c           	   
      sR   i f fdd	}d}t  |||d}|rNddd |D  _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   rp   r   r'   r   r9   r,   r8   r   r   r     s    
z+compute_bookmark_label.<locals>.parse_againzbookmark-labelr   r   c                 s   s   | ]}t |V  qd S r   )box_textr   r   r   r   r     r   z)compute_bookmark_label.<locals>.<genexpr>N)r   r   ro   )	r,   r'   r   re   r8   r9   r   r   r;   r   r   r   rp   }  s    
rp   c           	   	   C   sf   g |_ |d dkr@t|d D ] \}\}}t| |||||| q|d dkrbt| ||d ||| dS )zSet the content-lists values.

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

    r   r+   rn   ro   N)r   	enumerater   rp   )	r,   r'   r.   re   r8   r9   r   r   Zstring_valuesr   r   r   r^     s    
r^   c           
      C   s  | \}}}|d }|d D ]:\}}||v r8||    n
|| ||g | q|d D ]@\}}||g }|s||vsJ || |d ||d< q^|d }	|	dkrd|d v rd	g}	ng }	|	D ]J\}}||g }|s||vsJ || |d |d  |7  < qd
S )z$Handle the ``counter-*`` properties.rH   counter_resetcounter_setr   counter_incrementr   rE   r)   )rE   r	   N)r\   r   r   rP   )
rc   r.   rr   re   rf   Zsibling_scopesri   r   valuesr   r   r   r   rO     s4    






rO   z\Sc                 C   s   t | tjo|| j S )z9Return True if ``box`` is a TextBox with only whitespace.r   )r'   Z_has_non_whitespacer   r   r   is_whitespace  s    r   c                 #   s   |du r fdd}g }|D ]@}||rR|rJ j | g d}t||V  g }|V  q|| q|r| j | g d}t||V  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 r   )rL   r   wrapper_typer   r   test  s    zwrap_improper.<locals>.test)rZ   )rX   table_boxes_childrenrP   )r'   rZ   r   r   Z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   s   g | ]}t |qS r   )r!   r   r   r   r   r   
<listcomp>  r   z)anonymous_table_boxes.<locals>.<listcomp>)rL   r
   r   
is_runningrZ   r   r'   rZ   r   r   r   r!     s    r!   c                    s  t  tjrg }nTt  tjrfdd |D }|sf jdu sD jdk rJd}n j} fddt|D } jrt|dkr|dd \}}|jrt	|r|
  t|dkr|dd \}}|jrt	|r|
d d	d tdg|dd
  ||dd dg D }t  tjr(t |tjdd }nt  tjrDt |tj}t  tjrbt |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 dS )z3Internal implementation of anonymous_table_boxes().c                 S   s   g | ]}t |tjr|qS r   )rL   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   rX   )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   Z
prev_childr   Z
next_childr   r   r   r   *  s
   

rH   c                 S   s   | j S r   proper_table_childr   r   r   r   <lambda>=  r   z&table_boxes_children.<locals>.<lambda>c                 S   s   t | tj S r   )rL   r
   TableCellBoxr   r   r   r   r   I  r   c                 S   s   | j  S r   r   r   r   r   r   r   O  r   c                    s   | j  p | jv S r   )r   proper_parentsr   )parent_typer   r   r   T  s   )rL   r
   r   TableColumnGroupBoxspanrangetabular_containerr`   r   r   r\   zipTableBoxr   TableRowBoxTableRowGroupBoxr   r   InlineTableBoxtype
wrap_tablerR   rZ   )r'   rZ   r   internalrV   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| | q2g g d}|D ]}||jd  | qXt	t
| |t j}	d}
|	D ]6}|
|_|jr|jD ]}|
|_|
d7 }
qq|
|j7 }
q|
}t
| |t j}g }d}d}|D ]X}|jd }|dkr|du rd|_|}q|d	kr4|du r4d|_|}q|| q|durP|gng | |durf|gng  }d}|D ]}d
d |jD }|jD ]}|d}d}
|jD ]}|
|v r|
d7 }
q|
|_|
|j }|jdkr@t|d }|jdkr |}||_n t|j||_|d|jd  }t|
|}|D ]}|| q.|}
t||
}qq|t|j7 }qt| |}|j |_t|	|_|jd dkrt||||_t| t jrt j }nt j!}|"| |d |g |d  }|j |_d|_#t$j%D ]&} |j|  |j| < t$j&|  |j| < q|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   )rQ   )r   rowr   r   r   r     r   zwrap_table.<locals>.<listcomp>border_collapsecollapser  r  )'r
   r   r   r   r   TableCaptionBoxr   rP   r.   rR   r   grid_xrZ   r   	is_header	is_footerr\   colspanrowspanr`   r   r   r   r   copy_with_childrenr   tuplecolumn_groupsr   Zcollapsed_border_gridrL   r   InlineBlockBoxr   rX   is_table_wrapperr   TABLE_WRAPPER_BOX_PROPERTIESINITIAL_VALUES)!r'   rZ   columnsrowsZall_captionsZby_typer   Zcaptionscaptionr  r	  groupcolumnZ
grid_widthZ
row_groupsZbody_row_groupsheaderfooterr)   Zgrid_heightZoccupied_cells_by_rowr  Zoccupied_cells_in_this_rowcellZ
new_grid_xZmax_rowspanZspanned_rowsZspanned_columnsZoccupied_cellsr   r   r   ri   r   r   r   r   ^  s    











r   c                 C   s8   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   s   g | ]}t |qS r   )r"   r   r   r   r   r     r   zflex_boxes.<locals>.<listcomp>)rL   r
   r   r   rZ   flex_childrenr   r   r   r   r"     s
    r"   c                 C   s   t | tjrg }|D ]}dd |_| r0d|_t |tjrJ|jdsJqt |tj	rtj
||j}|j|_d|_|| qt |tjrtj
||g}|j|_d|_|| q|| q|S |S d S )Nc                   S   s   dS )NFr   r   r   r   r   r     r   zflex_children.<locals>.<lambda>Tr   )rL   r
   FlexContainerBox
is_floatedis_in_normal_flowis_flex_itemrW   rV   r   r  r   rX   rZ   r.   rP   InlineLevelBox)r'   rZ   r  r   	anonymousr   r   r   r    s*    
r  c                 C   s8   t | tjr|  r| S dd | jD }t| || _| S )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   s   g | ]}t |qS r   )r#   r   r   r   r   r     r   zgrid_boxes.<locals>.<listcomp>)rL   r
   r   r   rZ   grid_childrenr   r   r   r   r#     s
    r#   c                 C   s   t | tjrg }|D ]}| r&d|_t |tjr@|jds@qt |tjrvtj	
||j}|j|_d|_|| qt |tjrtj	
||g}|j|_d|_d|_|| q|| q|S |S d S )NTr   F)rL   r
   GridContainerBoxr   is_grid_itemrW   rV   r   r  r   rX   rZ   r.   rP   r"  )r'   rZ   r$  r   r#  r   r   r   r$     s*    r$  Fc                 C   s  t | tjr| j}|s|S td|}| jd dv }| jd dv }|rRtd|}|rb|dd}|rt	d| }}|r|
dr|dd }d| _|d}nd	}|| _nJ| jD ]B}t |tjtjfrt||}|  r| r|}q| rd	}q|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

    
rz   )rk   nowraprk   r(  zpre-liner   r	   NTF)rL   r
   rW   rV   LINE_FEED_REsubr.   TAB_REreplaceSPACE_REr   leading_collapsible_spaceendswithrZ   r   r]   r   r   )r'   Zfollowing_collapsible_spacerV   Znew_line_collapsespace_collapseZprevious_textr   Zchild_collapsible_spacer   r   r   r]   =  s:    
r]   c                 C   s   t | tjrd| jd }|dkrDdd dd tdd d| | j| _| jd dkr| jd	d
| _n.|  s| jD ]}t |tjtj	frrt
| qrd S )Ntext_transformr+   c                 S   s   |   S r   )upperr   r   r   r   r   x  r   z(process_text_transform.<locals>.<lambda>c                 S   s   |   S r   )lowerr   r   r   r   r   y  r   c                 S   s
   |  tS r   )r   ASCII_TO_WIDEr   r   r   r   r   {  r   )	uppercase	lowercase
capitalizez
full-widthhyphens   ­r   )rL   r
   rW   r.   r8  rV   r-  r   rZ   r   r_   )r'   r2  r   r   r   r   r_   s  s$    

r_   c                 C   sR   d}d}| D ]@}t |d }|s8|dv r8d}| }n|dkrDd}||7 }q|S )uC   Capitalize words according to CSS’s "text-transform: capitalize".Fr   r   )LNTZ)unicodedatacategoryr3  )rV   Zletter_foundoutputletterr?  r   r   r   r8    s    

r8  c           
      C   s  | j r|  r| S t| j }|r6| jdu r6|d j| _g }d}|D ]:}|rPd|_t|tjrj|jsj|j}qBd}|t	| qB| j
du r|| _
t| tjs|| _ | S g }g }|D ]}t|tjrJ |r| r|| qt|tjs|r4| s4|s(t|tjr(|jdkr(|jd dv sp|| q|rftj| |}tj| |g}	||	 g }|| q|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   rz   r)  )rZ   r   rR   r/  rL   r
   rW   rV   rP   r$   trailing_collapsible_spaceBlockContainerBoxr   is_absolutely_positionedr"  r   r.   rX   r   )
r'   Zbox_childrenrZ   rB  r   Znew_line_childrennew_childrenZ	child_boxZline_boxr#  r   r   r   r$     sj    &




r$   c           	      C   s   | j r|  r| S g }d}| j D ]}t|tjrt| j dksLJ d| j  d}t||d\}}}|du rlqtj| |g}|	| |	t
| qP|rtj| |g}q|}nt
|}||urd}|	| q |r|| _ | 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.N)
skip_stackT)rZ   r   rL   r
   r   r`   _inner_block_in_inliner   rX   rP   r%   )	r'   rE  changedr   stackZnew_liner   Zanon	new_childr   r   r   r%     s<    =

r%   c                 C   s  g }d}d}d}|du }|r"d}n|  \\}}t| j|d D ]\}}	|| }
t|	tjr|	 r|du srJ |	}|
d7 }
nPt|	tjrt|	|}d}|\}}}n|du sJ t	|	}||	urd}|
| |durB|
|i}| |}  qqB|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   rZ   rL   r
   BlockLevelBoxr   r   rG  r%   rP   r  )r'   rF  rE  Zblock_level_box	resume_atrH  Zis_startskipr   r   indexZ	recursionrJ  r   r   r   rG  k  s@    





rG  c                 C   s\   | }| j  dkrB| jd dkrB| jD ]}|j  dkr&|} qBq&|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>   r4  r.   rZ   Zviewport_overflow)root_boxZ
chosen_boxr   r   r   r   r5     s    	

r5   c                 C   s:   t | tjr| jS t | tjr6ddd |  D S dS )Nr   c                 s   sD   | ]<}|j d s|j ds|j dst|tjr|jV  qdS )z::beforez::afterrs   N)r>   r0  rL   r
   rW   rV   r   r   r   r   r     s   zbox_text.<locals>.<genexpr>)rL   r
   rW   rV   r   r   r   r&   r   r   r   r     s    
r   c                    s    dv rt |S  dv rDt|tjr@d fdd| D S dS  dkrd}d}t |}|D ]*}t|}|dvr|r~ qd	}||7 }q`|S d S )
N)rV   r?   )rF   rI   r   c                 3   s4   | ],}|j d   rt|tjst|V  qdS )rm   N)r>   r0  rL   r
   r   r   r   	text_partr   r   r     s   zextract_text.<locals>.<genexpr>rD   F)ZPsZPePiZPfZPoT)r   rL   r
   r   r   r   r>  r?  )rT  r'   Zcharacter_foundZfirst_letterrV   rA  r?  r   rS  r   r     s(    

r   )N)NNNNNNN)NN)N)F)N)E__doc__rer>  r   r   cssr   r   Zlayout.tabler   loggerr   Ztext.constantsr   r
   r   r   r  r   r   FlexBoxInlineFlexBoxGridBoxInlineGridBoxr   r   r   r   r   r  r=   r   r5  r   compiler*  r,  r.  r(   r<   r@   r3   rU   rS   r   rY   r   rp   r^   rO   searchr   r   r!   r   r   r"   r  r#   r$  r]   r_   r8  r$   r%   rG  r5   r   r   r   r   r   r   <module>   s   



  
 ".D   
 ? 
*"'
^ 
6pf
5