#!/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)