""" weasyprint.tests.layout.inline ------------------------------ Tests for inline layout. :copyright: Copyright 2011-2019 Simon Sapin and contributors, see AUTHORS. :license: BSD, see LICENSE for details. """ import pytest from ...formatting_structure import boxes from ..test_boxes import render_pages as parse from ..testing_utils import SANS_FONTS, assert_no_logs @assert_no_logs def test_empty_linebox(): page, = parse('
') html, = page.children body, = html.children paragraph, = body.children assert len(paragraph.children) == 0 assert paragraph.height == 0 @pytest.mark.xfail @assert_no_logs def test_empty_linebox_removed_space(): # Whitespace removed at the beginning of the line => empty line => no line page, = parse('''
') html, = page.children body, = html.children paragraph, = body.children # TODO: The second line should be removed assert len(paragraph.children) == 1 @assert_no_logs def test_breaking_linebox(): page, = parse('''
Lorem Ipsum is verysimply dummytext of the printing and. naaaa naaaa naaaa naaaa naaaa naaaa naaaa naaaa naaaa
''' % {'fonts': SANS_FONTS}) html, = page.children body, = html.children paragraph, = body.children assert len(list(paragraph.children)) == 3 lines = paragraph.children for line in lines: assert line.style['font_size'] == 13 assert line.element_tag == 'p' for child in line.children: assert child.element_tag in ('em', 'p') assert child.style['font_size'] == 13 if isinstance(child, boxes.ParentBox): for child_child in child.children: assert child.element_tag in ('em', 'strong', 'span') assert child.style['font_size'] == 13 @assert_no_logs def test_position_x_ltr(): page, = parse(''' aa\nb\rc\r\nd\u2029e') html, = page.children body, = html.children pre, = body.children lines = pre.children texts = [] for line in lines: text_box, = line.children texts.append(text_box.text) assert texts == ['a', 'b', 'c', 'd', 'e'] @assert_no_logs def test_breaking_linebox_regression_2(): html_sample = '''
ab c defg hi
''' for i in range(16): page, = parse(html_sample % i) html, = page.children body, = html.children p, = body.children lines = p.children if i in (0, 1, 2, 3): line_1, line_2, line_3, line_4 = lines textbox_1, = line_1.children assert textbox_1.text == 'ab' span_1, = line_2.children textbox_1, = span_1.children assert textbox_1.text == 'c' span_1, textbox_2 = line_3.children textbox_1, = span_1.children assert textbox_1.text == 'def' assert textbox_2.text == 'g' textbox_1, = line_4.children assert textbox_1.text == 'hi' elif i in (4, 5, 6, 7, 8): line_1, line_2, line_3 = lines textbox_1, span_1 = line_1.children assert textbox_1.text == 'ab ' textbox_2, = span_1.children assert textbox_2.text == 'c' span_1, textbox_2 = line_2.children textbox_1, = span_1.children assert textbox_1.text == 'def' assert textbox_2.text == 'g' textbox_1, = line_3.children assert textbox_1.text == 'hi' elif i in (9, 10): line_1, line_2 = lines textbox_1, span_1 = line_1.children assert textbox_1.text == 'ab ' textbox_2, = span_1.children assert textbox_2.text == 'c' span_1, textbox_2 = line_2.children textbox_1, = span_1.children assert textbox_1.text == 'def' assert textbox_2.text == 'g hi' elif i in (11, 12, 13): line_1, line_2 = lines textbox_1, span_1, textbox_3 = line_1.children assert textbox_1.text == 'ab ' textbox_2, = span_1.children assert textbox_2.text == 'c def' assert textbox_3.text == 'g' textbox_1, = line_2.children assert textbox_1.text == 'hi' else: line_1, = lines textbox_1, span_1, textbox_3 = line_1.children assert textbox_1.text == 'ab ' textbox_2, = span_1.children assert textbox_2.text == 'c def' assert textbox_3.text == 'g hi' @assert_no_logs def test_breaking_linebox_regression_3(): # Regression test #1 for https://github.com/Kozea/WeasyPrint/issues/560 page, = parse( '' '\n' 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n' 'bbbbbbbbbbb\n' 'ccccddd
') html, = page.children body, = html.children p, = body.children line1, line2 = p.children assert line1.children[0].children[0].text == ( 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbb') assert line2.children[0].children[0].children[0].text == 'cccc' assert line2.children[1].text == 'ddd' @pytest.mark.xfail @assert_no_logs def test_breaking_linebox_regression_9(): # Regression test for https://github.com/Kozea/WeasyPrint/issues/783 # TODO: inlines.can_break_inside return False for span but we can break # before the tag. can_break_inside should be fixed. page, = parse( '' '\n' 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbb\n' 'ccccddd
') html, = page.children body, = html.children p, = body.children line1, line2 = p.children assert line1.children[0].children[0].text == ( 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbb') assert line2.children[0].children[0].children[0].text == 'cccc' assert line2.children[1].text == 'ddd' @assert_no_logs def test_breaking_linebox_regression_10(): # Regression test for https://github.com/Kozea/WeasyPrint/issues/923 page, = parse( '' '' ' ' ' xxxxxx YYY yyyyyy yyy' ' ZZZZZZ zzzzz' ' )x ' '
') html, = page.children body, = html.children p, = body.children line1, line2, line3, line4 = p.children assert line1.children[0].children[0].children[0].text == 'xxxxxx YYY' assert line2.children[0].children[0].children[0].text == 'yyyyyy yyy' assert line3.children[0].children[0].text == 'ZZZZZZ zzzzz' assert line4.children[0].text == ')x' @assert_no_logs def test_breaking_linebox_regression_11(): # Regression test for https://github.com/Kozea/WeasyPrint/issues/953 page, = parse( '' ''
' line 1
123 567 90x'
'
'
'
123 567 90x'
'
' ' 123 567 90 123 567 90x' '
') html, = page.children body, = html.children p, = body.children line1, line2, line3 = p.children assert line1.children[0].text == '123 567 90' assert line2.children[0].children[0].text == '123 567' assert line3.children[0].children[0].text == '90' assert line3.children[1].text == 'x' @assert_no_logs def test_linebox_text(): page, = parse('''Lorem Ipsumis very coool
''' % {'fonts': SANS_FONTS}) html, = page.children body, = html.children paragraph, = body.children lines = list(paragraph.children) assert len(lines) == 2 text = ' '.join( (''.join(box.text for box in line.descendants() if isinstance(box, boxes.TextBox))) for line in lines) assert text == 'Lorem Ipsumis very coool' @assert_no_logs def test_linebox_positions(): for width, expected_lines in [(165, 2), (1, 5), (0, 5)]: page = '''this is test for Weasyprint
''' page, = parse(page % {'fonts': SANS_FONTS, 'width': width}) html, = page.children body, = html.children paragraph, = body.children lines = list(paragraph.children) assert len(lines) == expected_lines ref_position_y = lines[0].position_y ref_position_x = lines[0].position_x for line in lines: assert ref_position_y == line.position_y assert ref_position_x == line.position_x for box in line.children: assert ref_position_x == box.position_x ref_position_x += box.width assert ref_position_y == box.position_y assert ref_position_x - line.position_x <= line.width ref_position_x = line.position_x ref_position_y += line.height @assert_no_logs def test_forced_line_breaks_pre(): # These lines should be small enough to fit on the default A4 page # with the default 12pt font-size. page, = parse('''Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed sollicitudin nibh et turpis molestie tristique.''') html, = page.children body, = html.children pre, = body.children assert pre.element_tag == 'pre' lines = pre.children assert all(isinstance(line, boxes.LineBox) for line in lines) assert len(lines) == 7 assert [line.height for line in lines] == [42] * 7 @assert_no_logs def test_forced_line_breaks_paragraph(): page, = parse('''
Lorem ipsum dolor sit amet,
consectetur adipiscing elit.
Sed sollicitudin nibh
et turpis molestie tristique.
WeasyPrint is a frée softwäre ./ visual rendèring enginè for HTML !!! and CSS.
''' % {'fonts': SANS_FONTS, 'width': width}) html, = page.children body, = html.children paragraph, = body.children lines = paragraph.children if width == 10000: assert len(lines) == 1 else: assert len(lines) > 1 text_parts = [] for line in lines: strong, = line.children text, = strong.children text_parts.append(text.text) assert ' '.join(text_parts) == ( 'WeasyPrint is a frée softwäre ./ visual ' 'rendèring enginè for HTML !!! and CSS.') @assert_no_logs def test_whitespace_processing(): for source in ['a', ' a ', ' \n \ta', ' a\t ']: page, = parse('%s
' % source) html, = page.children body, = html.children p, = body.children line, = p.children em, = line.children text, = em.children assert text.text == 'a', 'source was %r' % (source,) page, = parse( '\n\n%s' % source.replace('\n', ' ')) html, = page.children body, = html.children p, = body.children _line1, _line2, line3 = p.children em, = line3.children text, = em.children assert text.text == 'a', 'source was %r' % (source,) @assert_no_logs def test_inline_replaced_auto_margins(): page, = parse('''
Hello, world!
Hello, world!
''' % SANS_FONTS) html, = page.children body, = html.children p_1, p_2 = body.children normal = p_1.width condensed = p_2.width assert condensed < normal @assert_no_logs @pytest.mark.parametrize('source, lines_count', ( ('hyphénation', 1), # Default: no hyphenation ('hyphénation', 1), # lang only: no hyphenation ('hyphénation', 1), # hyphens only: no hyph. ('hyphénation', 2), # both: hyph. ('hyphénation', 2), # Hyphenation with soft hyphens ('hyphénation', 1), # … unless disabled )) def line_count(source, lines_count): page, = parse( '' + '' + source) html, = page.children body, = html.children lines = body.children assert len(lines) == lines_count @assert_no_logs def test_vertical_align_1(): # +-------+ <- position_y = 0 # +-----+ | # 40px | | | 60px # | | | # +-----+-------+ <- baseline page, = parse('''