198 lines
6.3 KiB
Python
198 lines
6.3 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Test script for the new external pagination system.
|
|
|
|
This script tests the new BlockPaginator and handler architecture
|
|
to ensure it works correctly with different block types.
|
|
"""
|
|
|
|
from pyWebLayout.abstract.block import Paragraph, Heading, HeadingLevel
|
|
from pyWebLayout.abstract.inline import Word
|
|
from pyWebLayout.concrete.page import Page
|
|
from pyWebLayout.style.fonts import Font
|
|
from pyWebLayout.typesetting.block_pagination import BlockPaginator, PaginationResult
|
|
|
|
|
|
def create_test_paragraph(text: str, font: Font = None) -> Paragraph:
|
|
"""Create a test paragraph with the given text."""
|
|
if font is None:
|
|
font = Font(font_size=16)
|
|
|
|
paragraph = Paragraph(font)
|
|
words = text.split()
|
|
|
|
for word_text in words:
|
|
word = Word(word_text, font)
|
|
paragraph.add_word(word)
|
|
|
|
return paragraph
|
|
|
|
|
|
def create_test_heading(text: str, level: HeadingLevel = HeadingLevel.H1) -> Heading:
|
|
"""Create a test heading with the given text."""
|
|
font = Font(font_size=20)
|
|
heading = Heading(level, font)
|
|
|
|
words = text.split()
|
|
for word_text in words:
|
|
word = Word(word_text, font)
|
|
heading.add_word(word)
|
|
|
|
return heading
|
|
|
|
|
|
def test_paragraph_pagination():
|
|
"""Test paragraph pagination with line breaking."""
|
|
print("Testing paragraph pagination...")
|
|
|
|
# Create a long paragraph
|
|
long_text = " ".join(["This is a very long paragraph that should be broken across multiple lines."] * 10)
|
|
paragraph = create_test_paragraph(long_text)
|
|
|
|
# Create a page with limited height
|
|
page = Page(size=(400, 200)) # Small page
|
|
|
|
# Test the pagination handler
|
|
paginator = BlockPaginator()
|
|
result = paginator.paginate_block(paragraph, page, available_height=100)
|
|
|
|
print(f"Paragraph pagination result:")
|
|
print(f" Success: {result.success}")
|
|
print(f" Height used: {result.height_used}")
|
|
print(f" Has remainder: {result.remainder is not None}")
|
|
print(f" Can continue: {result.can_continue}")
|
|
|
|
return result.success
|
|
|
|
|
|
def test_page_filling():
|
|
"""Test filling a page with multiple blocks."""
|
|
print("\nTesting page filling with multiple blocks...")
|
|
|
|
# Create test blocks
|
|
blocks = [
|
|
create_test_heading("Chapter 1: Introduction"),
|
|
create_test_paragraph("This is the first paragraph of the chapter. It contains some introductory text."),
|
|
create_test_paragraph("This is the second paragraph. It has more content and should flow nicely."),
|
|
create_test_heading("Section 1.1: Overview", HeadingLevel.H2),
|
|
create_test_paragraph("This is a paragraph under the section. It has even more content that might not fit on the same page."),
|
|
create_test_paragraph("This is another long paragraph that definitely won't fit. " * 20),
|
|
]
|
|
|
|
# Create a page
|
|
page = Page(size=(600, 400))
|
|
|
|
# Fill the page
|
|
next_index, remainder_blocks = page.fill_with_blocks(blocks)
|
|
|
|
print(f"Page filling result:")
|
|
print(f" Blocks processed: {next_index} out of {len(blocks)}")
|
|
print(f" Remainder blocks: {len(remainder_blocks)}")
|
|
print(f" Page children: {len(page._children)}")
|
|
|
|
# Try to render the page
|
|
try:
|
|
page_image = page.render()
|
|
print(f" Page rendered successfully: {page_image.size}")
|
|
return True
|
|
except Exception as e:
|
|
print(f" Page rendering failed: {e}")
|
|
return False
|
|
|
|
|
|
def test_multi_page_creation():
|
|
"""Test creating multiple pages from a list of blocks."""
|
|
print("\nTesting multi-page creation...")
|
|
|
|
# Create many test blocks
|
|
blocks = []
|
|
for i in range(10):
|
|
blocks.append(create_test_heading(f"Chapter {i+1}"))
|
|
for j in range(3):
|
|
long_text = f"This is paragraph {j+1} of chapter {i+1}. " * 15
|
|
blocks.append(create_test_paragraph(long_text))
|
|
|
|
print(f"Created {len(blocks)} blocks total")
|
|
|
|
# Create pages until all blocks are processed
|
|
pages = []
|
|
remaining_blocks = blocks
|
|
page_count = 0
|
|
|
|
while remaining_blocks and page_count < 20: # Safety limit
|
|
page = Page(size=(600, 400))
|
|
next_index, remainder_blocks = page.fill_with_blocks(remaining_blocks)
|
|
|
|
if page._children:
|
|
pages.append(page)
|
|
page_count += 1
|
|
|
|
# Update remaining blocks
|
|
if remainder_blocks:
|
|
remaining_blocks = remainder_blocks
|
|
elif next_index < len(remaining_blocks):
|
|
remaining_blocks = remaining_blocks[next_index:]
|
|
else:
|
|
remaining_blocks = []
|
|
|
|
# Safety check
|
|
if not page._children and remaining_blocks:
|
|
print(f" Warning: Infinite loop detected, stopping")
|
|
break
|
|
|
|
print(f"Multi-page creation result:")
|
|
print(f" Pages created: {len(pages)}")
|
|
print(f" Remaining blocks: {len(remaining_blocks)}")
|
|
|
|
# Try to render a few pages
|
|
rendered_count = 0
|
|
for i, page in enumerate(pages[:3]): # Test first 3 pages
|
|
try:
|
|
page_image = page.render()
|
|
rendered_count += 1
|
|
print(f" Page {i+1} rendered: {page_image.size}")
|
|
except Exception as e:
|
|
print(f" Page {i+1} rendering failed: {e}")
|
|
|
|
return len(pages) > 0 and rendered_count > 0
|
|
|
|
|
|
def main():
|
|
"""Run all pagination tests."""
|
|
print("=== Testing New Pagination System ===")
|
|
|
|
results = []
|
|
|
|
try:
|
|
results.append(test_paragraph_pagination())
|
|
except Exception as e:
|
|
print(f"Paragraph pagination test failed: {e}")
|
|
results.append(False)
|
|
|
|
try:
|
|
results.append(test_page_filling())
|
|
except Exception as e:
|
|
print(f"Page filling test failed: {e}")
|
|
results.append(False)
|
|
|
|
try:
|
|
results.append(test_multi_page_creation())
|
|
except Exception as e:
|
|
print(f"Multi-page creation test failed: {e}")
|
|
results.append(False)
|
|
|
|
print(f"\n=== Test Results ===")
|
|
print(f"Paragraph pagination: {'PASS' if results[0] else 'FAIL'}")
|
|
print(f"Page filling: {'PASS' if results[1] else 'FAIL'}")
|
|
print(f"Multi-page creation: {'PASS' if results[2] else 'FAIL'}")
|
|
|
|
overall_result = all(results)
|
|
print(f"Overall: {'PASS' if overall_result else 'FAIL'}")
|
|
|
|
return overall_result
|
|
|
|
|
|
if __name__ == "__main__":
|
|
success = main()
|
|
exit(0 if success else 1)
|