Skip to content

Commit ad5a5a6

Browse files
authored
Merge pull request #2431 from Kozea/page-names
Fix bugs about page names
2 parents 83da2fe + 6b1d32b commit ad5a5a6

File tree

2 files changed

+88
-14
lines changed

2 files changed

+88
-14
lines changed

tests/layout/test_page.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -969,6 +969,74 @@ def test_page_groups():
969969
assert section.element_tag == 'section'
970970

971971

972+
@assert_no_logs
973+
def test_page_groups_blank_inside():
974+
# Regression test for #1076.
975+
pages = render_pages('''
976+
<style>
977+
@page { size: 100px }
978+
@page div { size: 50px }
979+
div { page: div }
980+
p { break-before: right }
981+
</style>
982+
<div>
983+
<p>1</p>
984+
<p>2</p>
985+
</div>
986+
''')
987+
assert len(pages) == 3
988+
for page in pages:
989+
assert (page.width, page.height) == (50, 50)
990+
991+
992+
@assert_no_logs
993+
def test_page_groups_blank_outside():
994+
pages = render_pages('''
995+
<style>
996+
@page { size: 100px }
997+
@page p { size: 50px }
998+
p { page: p; break-before: right }
999+
</style>
1000+
<div>
1001+
<p>1</p>
1002+
<p>2</p>
1003+
</div>
1004+
''')
1005+
page1, page2, page3 = pages
1006+
for page in (page1, page3):
1007+
assert (page.width, page.height) == (50, 50)
1008+
assert (page2.width, page2.height) == (100, 100)
1009+
1010+
1011+
@assert_no_logs
1012+
def test_page_groups_first_nth():
1013+
# Regression test for #2429.
1014+
pages = render_pages('''
1015+
<style>
1016+
@page { size: 100px }
1017+
@page div { size: 50px }
1018+
@page :nth(2n+1 of div) { size: 30px }
1019+
div { page: div; break-before: right }
1020+
p { break-before: page }
1021+
</style>
1022+
<div>
1023+
<p>1</p>
1024+
<p>2</p>
1025+
<p>3</p>
1026+
</div>
1027+
<div>
1028+
<p>4</p>
1029+
<p>5</p>
1030+
</div>
1031+
''')
1032+
page1, page2, page3, page4, page5, page6 = pages
1033+
for page in (page1, page3, page5):
1034+
assert (page.width, page.height) == (30, 30)
1035+
for page in (page2, page6):
1036+
assert (page.width, page.height) == (50, 50)
1037+
assert (page4.width, page4.height) == (100, 100)
1038+
1039+
9721040
@assert_no_logs
9731041
@pytest.mark.parametrize('style, line_counts', (
9741042
('orphans: 2; widows: 2', [4, 3]),

weasyprint/layout/page.py

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,8 @@ def set_page_type_computed_styles(page_type, html, style_for):
799799

800800

801801
def _includes_resume_at(resume_at, page_group_resume_at):
802+
if not page_group_resume_at:
803+
return True
802804
(page_child_index, page_child_resume_at), = page_group_resume_at.items()
803805
if resume_at is None or page_child_index not in resume_at:
804806
return False
@@ -807,7 +809,7 @@ def _includes_resume_at(resume_at, page_group_resume_at):
807809
return _includes_resume_at(resume_at[page_child_index], page_child_resume_at)
808810

809811

810-
def _update_page_groups(page_groups, resume_at, next_page, root_box):
812+
def _update_page_groups(page_groups, resume_at, next_page, root_box, blank):
811813
# https://www.w3.org/TR/css-gcpm-3/#document-sequence-selectors
812814

813815
# Remove or increment page groups.
@@ -819,35 +821,40 @@ def _update_page_groups(page_groups, resume_at, next_page, root_box):
819821
page_groups.pop(i - page_groups_length)
820822

821823
# Add page groups.
822-
if next_page['break'] == 'any' or not next_page['page']:
823-
# We don’t have a forced page break or a named page.
824-
return
825-
if page_groups and page_groups[-1][0] == next_page['page']:
826-
# We’re already in an element whose page name is the next page name.
827-
return
824+
if not blank:
825+
if (resume_at and next_page['break'] == 'any') or not next_page['page']:
826+
# We don’t have a forced page break or a named page.
827+
return next_page['page']
828+
if page_groups and page_groups[-1][0] == next_page['page']:
829+
# We’re already in an element whose page name is the next page name.
830+
return next_page['page']
828831

829832
# Find the box that has the named page. It is a first in-flow child of the
830833
# element corresponding to resume_at.
831834

832835
# Find element corrensponding to resume_at.
833-
page_group_resume_at = copy.deepcopy(resume_at)
834-
current_resume_at = page_group_resume_at
836+
current_resume_at = page_group_resume_at = copy.deepcopy(resume_at) or {0: None}
835837
current_element = root_box
836838
while True:
837839
child_index, child_resume_at = tuple(current_resume_at.items())[-1]
840+
parent_element = current_element
838841
current_element = current_element.children[child_index]
839842
if child_resume_at is None:
840843
break
841844
current_resume_at = child_resume_at
842845

846+
if blank:
847+
# Page is blank, don’t create a new page group and return parent’s page name.
848+
return parent_element.style['page']
849+
843850
# Find the descendant with named page.
844851
while True:
845852
if current_element.style['page'] == next_page['page']:
846853
page_groups.append([next_page['page'], 0, page_group_resume_at])
847-
return
854+
return next_page['page']
848855
if not isinstance(current_element, boxes.ParentBox):
849856
# Shouldn’t happen.
850-
return
857+
return next_page['page']
851858
for i, child in enumerate(current_element.children):
852859
if not child.is_in_normal_flow():
853860
continue
@@ -858,7 +865,7 @@ def _update_page_groups(page_groups, resume_at, next_page, root_box):
858865
break
859866
else:
860867
# Shouldn’t happen.
861-
return
868+
return next_page['page']
862869

863870

864871
def remake_page(index, page_groups, context, root_box, html):
@@ -891,9 +898,8 @@ def remake_page(index, page_groups, context, root_box, html):
891898
(next_page_side == 'left' and right_page) or
892899
(next_page_side == 'right' and not right_page) or
893900
(context.reported_footnotes and resume_at is None))
894-
name = '' if blank else next_page['page']
895901
side = 'right' if right_page else 'left'
896-
_update_page_groups(page_groups, resume_at, next_page, root_box)
902+
name = _update_page_groups(page_groups, resume_at, next_page, root_box, blank)
897903
groups = tuple((name, index) for name, index, _ in page_groups)
898904
page_type = PageType(side, blank, name, index, groups)
899905
set_page_type_computed_styles(page_type, html, context.style_for)

0 commit comments

Comments
 (0)