3
`Wj                 @   s  d Z ddlmZm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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dZdd Zdd Zd>ddZ dd Z!d?ddZ"dd Z#dd Z$dd Z%dd Z&ej'dj(fd d!Z)d@d"d#Z*d$d% Z+d&d' Z,d(d) Z-d*d+ Z.dAd-d.Z/d/d0 Z0d1d2 Z1dBd3d4Z2d5d6 Z3d7d8 Z4d9d: Z5d;d< Z6e4e5e6d=Z7dS )Ca  
    weasyprint.formatting_structure.build
    -------------------------------------

    Turn an element tree with associated CSS style (computed values)
    into a "before layout" formatting structure / box tree.

    This includes creating anonymous boxes and processing whitespace
    as necessary.

    :copyright: Copyright 2011-2014 Simon Sapin and contributors, see AUTHORS.
    :license: BSD, see LICENSE for details.

    )divisionunicode_literalsN)COLOR_KEYWORDS   )boxescounters   )html)
properties)ZERO_PIXELS)
basestringxrange)blockz	list-iteminlinezinline-blocktablezinline-tablez	table-rowztable-row-groupztable-header-groupztable-footer-groupztable-columnztable-column-groupz
table-cellztable-captionc                sf   t |  |}|r|\}nd fdd	}t | ||\}d|_t| t|}t|}t|}t|}|S )z=Build a formatting structure (box tree) from an element tree.Nc                s,    | |}|r(| j  d kr"d|_nd|_|S )Nr   none)Z	getparentdisplay)elementpseudo_typestyle)	style_for e/var/www/html/enquirykeeper_venv/lib/python3.6/site-packages/weasyprint/formatting_structure/build.pyroot_style_for8   s    
z2build_formatting_structure.<locals>.root_style_forT)N)element_to_boxZis_for_root_elementprocess_whitespaceanonymous_table_boxesinline_in_blockblock_in_inlineset_viewport_overflow)Zelement_treer   get_image_from_uriZbox_listboxr   r   )r   r   build_formatting_structure1   s    r"   c             C   sr   |j dkr.|jdkr.xdD ]}t|d| < qW |j jd	r^|j d
kr^xdD ]}t|d| < qJW t|j  | |||S )Nr   inline-tablecollapsetopbottomleftrightZpadding_ztable-ztable-captionmargin_)r   r#   )r%   r&   r'   r(   )r%   r&   r'   r(   )r   border_collapser   
startswithBOX_TYPE_FROM_DISPLAY)element_tag
sourceliner   contentr    sider   r   r   make_boxK   s    



r1   c             C   s  t | jtsg S || }|j}|dkr*g S t| j| j|g |}|dkrVdgi t gf}|\}}}	t|| g }
|dkr|
jt	||| |	j
t  |
jt| d||| | j}|r|
j
tjj|| xp| D ]h}|
jt|||| |j}|rtjj||}|
r,t |
d tjr,|
d	  j|j7  _q|
j
| qW |
jt| d||| x2|	j D ]&}|| j  || sZ|j| qZW |j|
}t| ||| tj| ||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 http://www.w3.org/TR/CSS21/visuren.html#anonymous

    r   Nr   z	list-itembeforer   afterr4   )
isinstancetagr   r   r1   r.   setupdate_countersextendadd_box_markerappendpseudo_to_boxtextr   TextBoxanonymous_fromr   tailpopcopy_with_childrenreplace_content_listsr	   Zhandle_element)r   r   r    stater   r   r!   _quote_depthcounter_valuescounter_scopeschildrenr=   Zchild_elementZtext_boxnamer   r   r   r   Z   sT    





r   c             c   s   || |}|r|dkrdS |j }|j}d||fks:|dkr>dS td| j|f | j|g |}|\}	}
}t|| g }|dkr|jt||
| |jt|||	|
| |j	|V  dS )zEYield the box for a :before or :after pseudo-element if there is one.Nr   normalz%s:%sz	list-item)
r   r/   r1   r6   r.   r8   r9   r:   content_to_boxesrB   )r   r   rD   r   r    r   r   r/   r!   quote_depthrF   Z_counter_scopesrH   r   r   r   r<      s&    


r<   c             #   s  g }x| j D ]\}}|dkr,|j| q|dkrx||}	|	dk	rvdj|}
|
rbtjj||
V  g }tjj||	V  q|dkr|\} |j|dgd }|jtj	|  q|dkr|\}} |j|j fd	d
|j|dgD  q|dko|dk	r|j
| }
|j|
 q|dks t|\}}|sDtd|d d |d< |r| j\}}|r^|n|}|j|t|d t|d   |r|d  d7  < qW dj|}
|
rtjj||
V  dS )z:Takes the value of a ``content`` property and yield boxes.STRINGURIN counterr   r   r   c             3   s   | ]}t j| V  qd S )N)r   format).0counter_value)counter_styler   r   	<genexpr>   s   z#content_to_boxes.<locals>.<genexpr>stringZQUOTEr4   )r/   r;   joinr   r>   r?   InlineReplacedBoxgetr   rQ   Zget_string_set_forAssertionErrormaxquotesminlen)r   Z
parent_boxrL   rF   r    contextZtextstype_valueimager=   counter_namerS   	separatorZis_openinsertZopen_quotesZclose_quotesr\   r   )rT   r   rK      sJ    




 
rK   c                s   d}x|D ]\}}|dkr$||7 }q
|dkrJt | |}|j }||7 }q
|dkr~|\} |j|dgd }	|tj|	 7 }q
|dkr|\}}
 ||
j fdd	|j|dgD 7 }q
|d
kr
|| j|d7 }q
W |S )z5Compute the string corresponding to the content-list.rO   rM   r/   rP   r   r   r   c             3   s   | ]}t j| V  qd S )N)r   rQ   )rR   rS   )rT   r   r   rU     s   z.compute_content_list_string.<locals>.<genexpr>attrr4   )TEXT_CONTENT_EXTRACTORSstriprY   r   rQ   rW   )r   r!   rF   Zcontent_listrV   r`   ra   Z
added_textrc   rS   rd   r   )rT   r   compute_content_list_string  s(    



ri   c             C   sp   g }|j dkrBx2t|j D ]$\}\}}|j|t| |||f qW ||_ |jdkrZd|_nt| |||j|_dS )zReplace the content-lists by strings.

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

    r   rO   N)
string_set	enumerater;   ri   Zbookmark_label)r   r!   r   rF   rj   iZstring_nameZstring_valuesr   r   r   rC     s    

rC   c       
      C   s   | \}}}|d }xD|j D ]:\}}||kr8|| j  n
|j| |j|g j| qW |j}|dkr||jdkrxdg}ng }xP|D ]H\}}|j|g }	|	s||kst|j| |	jd |	d  |7  < qW dS )	z$Handle the ``counter-*`` properties.r   auto	list-itemr   Nr4   )rn   r   r4   )Zcounter_resetrA   add
setdefaultr;   counter_incrementr   rZ   )
rD   r   rE   rF   rG   Zsibling_scopesrI   ra   rq   valuesr   r   r   r8   2  s&    




r8   c             c   s   | j }|j\}}|dkr ||}|dkrh|j}|dkr:dS |jddgd }tj||}tjj| |}	ntj	j| |}	d|	_
|	 jd7  _|j}
|
d	kr|jd
krdnd}|jd }tj|d|	j d| < |	V  n|
dkr|	| _dS )zAdd a list marker to boxes for elements with ``display: list-item``,
    and yield children to add a the start of the box.

    See http://www.w3.org/TR/CSS21/generate.html#lists

    urlNr   z	list-itemr   r   Tz::markerZinsideZltrr(   r'   g      ?Zpxr)   Zoutsider4   )r   Zlist_style_imageZlist_style_typerY   r   Zformat_list_markerr   r>   r?   rX   Zis_list_markerr-   Zlist_style_position	directionZ	font_sizer
   Z	DimensionZoutside_list_marker)r!   rF   r    r   Z
image_typerb   r`   rS   Zmarker_textZ
marker_boxpositionr0   marginr   r   r   r:   Z  s,    

r:   z\Sc             C   s   t | tjo|| j S )z9Return True if ``box`` is a TextBox with only whitespace.)r5   r   r>   r=   )r!   Z_has_non_whitespacer   r   r   is_whitespace}  s    rw   c             #   s   |dkr fdd}g }xH|D ]@}||rT|rL j | g d}t||V  g }|V  q|j| qW |r j | g d}t||V  dS )z
    Wrap consecutive children that do not pass ``test`` in a box of type
    ``wrapper_type``.

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

    Nc                s
   t |  S )N)r5   )child)wrapper_typer   r   test  s    zwrap_improper.<locals>.test)rH   )r?   table_boxes_childrenr;   )r!   rH   ry   rz   Zimproperrx   wrapperr   )ry   r   wrap_improper  s    
r}   c             C   s*   t | tjs| S dd | jD }t| |S )zRemove and add boxes according to the table model.

    Take and return a ``Box`` object.

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

    c             S   s   g | ]}t |qS r   )r   )rR   rx   r   r   r   
<listcomp>  s    z)anonymous_table_boxes.<locals>.<listcomp>)r5   r   	ParentBoxrH   r{   )r!   rH   r   r   r   r     s    r   c                s  t  tjrg }n6t  tjrHdd |D }|sH fddt jD } jrt|dkr|dd \}}|jrt	|r|j
  t|dkr|dd \}}|jrt	|r|j
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r&t |tj}t  tjrDt |tj}nt |tjdd
 }t  tjr|t |tjdd
 }n t t |tjfdd
}t  tjrt |S  j|S dS )z3Internal implementation of anonymous_table_boxes().c             S   s   g | ]}t |tjr|qS r   )r5   r   TableColumnBox)rR   rx   r   r   r   r~     s    z(table_boxes_children.<locals>.<listcomp>c                s   g | ]}t jj g qS r   )r   r   r?   )rR   Z_i)r!   r   r   r~     s   r   Nr   c             S   s2   g | ]*\}}}|o(|j o(|o(|j o(t|s|qS r   )internal_table_or_captionrw   )rR   Z
prev_childrx   Z
next_childr   r   r   r~     s   

r   c             S   s   | j S )N)proper_table_child)rx   r   r   r   <lambda>  s    z&table_boxes_children.<locals>.<lambda>c             S   s   t | tj S )N)r5   r   TableCellBox)rx   r   r   r   r     s    c             S   s   | j  S )N)r   )rx   r   r   r   r     s    c                s   | j  p | jkS )N)r   Zproper_parents)rx   )parent_typer   r   r     s   r4   )r5   r   r   TableColumnGroupBoxr   spanZtabular_containerr^   r   rw   rA   zipTableBoxr}   TableRowBoxTableRowGroupBoxr   	InlineBoxInlineTableBoxtype
wrap_tablerB   )r!   rH   Zinternalr=   r   )r!   r   r   r{     sT    




r{   c       !   
   C   sN  g }g }g }t j|t j|t j|t j|t j|i}x|D ]}|t| j| q4W g g d}x|D ]}||jj	 j| q^W t
t| |t j}	d}
xN|	D ]F}|
|_|jrx|jD ]}|
|_|
d7 }
qW t|j|_q|
|j7 }
qW |
}t| |t j}g }d}d}x`|D ]X}|jj}|dkr.|dkr.d|_|}n*|dkrN|dkrNd|_|}n
|j| qW |dk	rn|gng | |dk	r|gng  }d}x|D ]}dd	 |jD }x|jD ]}|jd}d}
x|jD ]}x|
|kr|
d7 }
qW |
|_|
|j }|jdkrpt|d }|jdkr,|}||_n t|j||_|d|jd  }t|
|}x|D ]}|j| q\W |}
t||
}qW qW |t|j7 }qW | j|}t|	|_|jjd
krt||||_t | t j!rt j"}nt j#}|j$| |d |g |d  }d|_%|jj&sJx0t'j(D ]&} |j|  |j| < t'j)|  |j| < q W |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.

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

    )r%   r&   r   r   Nztable-header-groupTztable-footer-groupc             S   s   g | ]
}t  qS r   )r7   )rR   rowr   r   r   r~   X  s    zwrap_table.<locals>.<listcomp>r$   r%   r&   )*r   r   r   r   r   TableCaptionBoxr   r;   r   Zcaption_sidelistr}   grid_xrH   r^   r   r   Z	is_headerZ	is_footerrA   colspanrowspanr]   rangeupdater[   rB   tuplecolumn_groupsr*   collapse_table_bordersZcollapsed_border_gridr5   r   InlineBlockBoxBlockBoxr?   Zis_table_wrapper	anonymousr
   ZTABLE_WRAPPER_BOX_PROPERTIESZINITIAL_VALUES)!r!   rH   columnsZrowsZall_captionsZby_typerx   ZcaptionsZcaptionr   r   groupcolumn
grid_widthZ
row_groupsZbody_row_groupsheaderZfooterr   grid_heightZoccupied_cells_by_rowr   Zoccupied_cells_in_this_rowcellZ
new_grid_xZmax_rowspanZspanned_rowsZspanned_columnsZoccupied_cellsr   ry   r|   rI   r   r   r   r   
  s    












r   c                s6   o|sg g fS t dd ttddddddd	d
ddg
D dd
dtd ddd fddff fddt|D  fddt|d D fddfdd}ddd fddff}d}x| jD ]}x|jD ]}x|jD ]}xJt|jd |j|j D ].}	x&t|||j D ]}
||
 |	< q*W qW xJt|j|j|j D ]2}	x*t|d ||j D ]}
||
 |	< qvW q\W |||j||j|jd qW |d7 }qW qW d}x<| jD ]2}x*|jD ] }||d| dd |d7 }qW qW d}x4| jD ]*}t	|j}||d| |d ||7 }qW x6| j
D ],}x$|jD ]}|||jdd|d qNW qBW x&| j
D ]}|||jd|j|d qzW || dd |d fddfdd}fdd}fdd }d}x| jD ]}|| x|jD ]}|| x|jD ]z}|d!||j||jd" |d#||j||j |jd" |d$||j||jd% |d&||j|j ||jd% qW |d7 }qW qW x2| j
D ](}|| x|jD ]}|| qW qW | d!|dd d" | d#|d| d" | d$|dddd% | d&| ddd% fS )'a  Resolve border conflicts for a table in the collapsing border model.

    Take a :class:`TableBox`; set appropriate border widths on the table,
    column group, column, row group, row, and cell boxes; and return
    a data structure for the resolved collapsed border grid.

    c             s   s   | ]\}}||fV  qd S )Nr   )rR   rl   vr   r   r   rU     s    z)collapse_table_borders.<locals>.<genexpr>hiddenZdoublesolidZdashedZdottedZridgeoutsetZgrooveinsetr   )r   r   transparentr   c                s&   g | ]}fd dt  d D qS )c                s   g | ]} qS r   r   )rR   x)weak_null_borderr   r   r~     s    z5collapse_table_borders.<locals>.<listcomp>.<listcomp>r   )r   )rR   y)r   r   r   r   r~     s   z*collapse_table_borders.<locals>.<listcomp>c                s"   g | ]}fd dt  D qS )c                s   g | ]} qS r   r   )rR   r   )r   r   r   r~     s    z5collapse_table_borders.<locals>.<listcomp>.<listcomp>)r   )rR   r   )r   r   r   r   r~     s   r   c                s~   |d|  }|d|  }|j d| }|dkr2dnd|| f} j||}| | | \}	}
|	|k rz||||ff| | |< d S )Nzborder_%s_stylezborder_%s_widthzborder_%s_colorr   r   r   )Z	get_colorrY   )Zborder_gridZ	box_styler0   r   grid_yr   widthZcolorZscoreZprevious_score_)	style_mapstyle_scoresr   r   set_one_border  s    z.collapse_table_borders.<locals>.set_one_borderc                s   | j }x:t||| D ](}|d|| |d|| | qW x:t||| D ](} |d||  |d|||  qRW d S )Nr'   r(   r%   r&   )r   r   )r!   r   r   whr   yyxx)horizontal_bordersr   vertical_bordersr   r   set_borders  s    z+collapse_table_borders.<locals>.set_borders)r   r   r   r   c                s2   | j }d|d| < |d |d| <  |d| < d S )Nr   zborder_%s_styler   zborder_%s_widthzborder_%s_color)r   )r!   r0   Ztwice_widthr   )r   r   r   set_transparent_border  s    z6collapse_table_borders.<locals>.set_transparent_borderc                s4    | dd  | dd  | dd  | dd d S )Nr%   r   r(   r&   r'   r   )r!   )r   r   r   remove_borders  s    z.collapse_table_borders.<locals>.remove_bordersc                s"   t  fdd|||  D S )Nc             3   s,   | ]$}|  gD ]\}\}}}|V  qqd S )Nr   )rR   Zgrid_rowr   r   )r   r   r   rU     s    zEcollapse_table_borders.<locals>.max_vertical_width.<locals>.<genexpr>)r[   )r   r   r   )r   )r   r   max_vertical_width  s    z2collapse_table_borders.<locals>.max_vertical_widthc                s"   t dd  | | | |  D S )Nc             s   s   | ]\}\}}}|V  qd S )Nr   )rR   r   r   r   r   r   rU     s    zGcollapse_table_borders.<locals>.max_horizontal_width.<locals>.<genexpr>)r[   )r   r   r   )r   r   r   max_horizontal_width  s    z4collapse_table_borders.<locals>.max_horizontal_widthr%   )r   r   r   r&   r'   )r   r   r   r(   )dictrk   reversedr   r   rH   r   r   r   r^   r   r   )r   r   r   r   Zstrong_null_borderr   Z	row_groupr   r   r   r   r   Zcolumn_groupr   r   r   r   r   )	r   r   r   r   r   r   r   r   r   r   r     s    


 
r   Fc             C   s  t | tjr| j}|s|S tjdd|}| jjdk}| jjdk}|rRtjdd|}|rb|jdd}|r|jdd}tjd	d|}|}|r|j	dr|d
d }|j
d}nd}|| _|S t | tjrx@| jD ]6}t |tjtjfrt||}qt| |j rd}qW |S )zFirst part of "The 'white-space' processing model".

    See http://www.w3.org/TR/CSS21/text.html#white-space-model
    http://dev.w3.org/csswg/css3-text/#white-space-rules

    z
?
rJ   nowrappre-linez[	 ]*
[	 ]* 	z +r   NF)rJ   r   )rJ   r   r   )r5   r   r>   r=   resubr   white_spacereplacer+   endswithr   rH   r   r   is_in_normal_flow)r!   Zfollowing_collapsible_spacer=   Znew_line_collapseZspace_collapseZprevious_textrx   r   r   r   r   $  s>    
r   c             C   sF  t | tjs| S dd | jD }t | tjs6| j|S g }g }x|D ]}t |tj sZt|rr|j rr|j	| qDt |tj
s|r|j r|st |tjo|jdko|jjdk r|j	| qD|rtjj| |}tjj| |g}|j	| g }|j	| qDW |r<tjj| |}|r2tjj| |g}|j	| n
|j	| | j|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
    http://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'],
                ]
            ]
        ]

    c             S   s(   g | ] }t |tjo|j st|qS r   )r5   r   r>   r=   r   )rR   rx   r   r   r   r~     s    z#inline_in_block.<locals>.<listcomp>r   rJ   r   pre-line)rJ   r   r   )r5   r   r   rH   ZBlockContainerBoxrB   LineBoxrZ   Zis_absolutely_positionedr;   ZInlineLevelBoxZ
is_floatedr>   r=   r   r   r?   r   )r!   rH   Znew_line_childrennew_childrenZ	child_boxZline_boxr   r   r   r   r   \  s@    &




r   c       	      C   s   t | tjs| S g }d}x| jD ]}t |tjrt| jdksLtd| j d}xHt||d\}}}|dkrnP tjj	| |g}|j
| |j
t| qRW |rtjj	| |g}q|}nt|}||k	rd}|j
| q W |r| j|S | S d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
    http://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)r5   r   r   rH   r   r^   rZ   _inner_block_in_inliner   r?   r;   r   rB   )	r!   r   changedrx   stackZnew_liner   Zanon	new_childr   r   r   r     s8    =


r   c             C   s  g }d}d}d}|dk}|r"d}n|\}}x| j |D ]\}}	t|	tjrl|	j rl|dks^t|	}|d7 }nPt|	tjrt|	|}
d}|
\}}}n|dkstt|	}||	k	rd}|j	| |dk	r6||f}| j
||dd} P q6W |s|r| j
||dd} | ||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)is_startZis_end)Zenumerate_skipr5   r   ZBlockLevelBoxr   rZ   r   r   r   r;   rB   )r!   r   r   Zblock_level_boxZ	resume_atr   r   skipindexrx   Z	recursionr   r   r   r   r     s@    


r   c             C   sb   | }| j j dkrB| jjdkrBx"| jD ]}|j j dkr&|}P q&W |jj| _|jjddi|_| 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 http://www.w3.org/TR/CSS21/visufx.html#overflow
    r	   Zvisiblebodyoverflow)r-   lowerr   r   rH   Zviewport_overflowZupdated_copy)Zroot_boxZ
chosen_boxrx   r   r   r   r   R  s    	
r   c             C   s>   t | tjr| jS t | tjr6djdd | j D S dS d S )NrO   c             s   s<   | ]4}|j jd  r|j jd rt|tjr|jV  qdS )z:beforez:afterN)r-   r   r5   r   r>   r=   )rR   rx   r   r   r   rU   m  s    zbox_text.<locals>.<genexpr>)r5   r   r>   r=   r   rW   descendants)r!   r   r   r   box_texth  s    r   c             C   s,   t | tjr$djdd | j D S dS d S )NrO   c             s   s0   | ](}|j jd rt|tj rt|V  qdS )z:beforeN)r-   r   r5   r   r   r   )rR   rx   r   r   r   rU   x  s    z"box_text_before.<locals>.<genexpr>)r5   r   r   rW   r   )r!   r   r   r   box_text_beforeu  s    r   c             C   s,   t | tjr$djdd | j D S dS d S )NrO   c             s   s0   | ](}|j jd rt|tj rt|V  qdS )z:afterN)r-   r   r5   r   r   r   )rR   rx   r   r   r   rU     s    z!box_text_after.<locals>.<genexpr>)r5   r   r   rW   r   )r!   r   r   r   box_text_after  s    r   )r=   r2   r3   )N)N)N)F)N)8__doc__
__future__r   r   r   Ztinycss.color3r   rO   r   r   r	   cssr
   Zcss.computed_valuesr   compatr   r   r   r   r   r   r   r   r   r   r   r   r   r,   r"   r1   r   r<   rK   ri   rC   r8   r:   compilesearchrw   r}   r   r{   r   r   r   r   r   r   r   r   r   r   rg   r   r   r   r   <module>   sd   

] 
+(#
Y  
8Yg
6
