#!/usr/bin/env python3 """ Table Text Wrapping Example This example demonstrates the line wrapping functionality in table cells: - Tables with long text that wraps across multiple lines - Automatic word wrapping within cell boundaries - Hyphenation support for long words - Multiple paragraphs per cell - Comparison of narrow vs. wide columns Shows how the Line-based text layout system handles text overflow in tables. """ from pyWebLayout.io.readers.html_extraction import parse_html_string from pyWebLayout.layout.document_layouter import DocumentLayouter from pyWebLayout.style.page_style import PageStyle from pyWebLayout.concrete.table import TableStyle from pyWebLayout.concrete.page import Page import sys from pathlib import Path from PIL import Image # Add pyWebLayout to path sys.path.insert(0, str(Path(__file__).parent.parent)) def create_narrow_columns_example(): """Create a table with narrow columns to show aggressive wrapping.""" print(" - Narrow columns with text wrapping") html = """
Feature Description Benefits
Automatic Line Wrapping Text automatically wraps to fit within the available cell width, creating multiple lines as needed. Improves readability and prevents horizontal overflow in tables.
Hyphenation Support Long words are intelligently hyphenated using pyphen library or brute-force splitting when necessary. Handles extraordinarily long words that wouldn't fit on a single line.
Multi-paragraph Cells Each cell can contain multiple paragraphs or headings, all properly wrapped. Allows rich content within table cells.
""" return html, "Text Wrapping in Narrow Columns" def create_mixed_content_example(): """Create a table with both short and long content.""" print(" - Mixed content lengths") html = """
Product Comparison
Product Short Description Detailed Features
Widget Pro Premium Advanced functionality with enterprise-grade reliability, comprehensive warranty coverage, and dedicated customer support available around the clock.
Widget Lite Basic Essential features for everyday use with straightforward operation and minimal learning curve.
Widget Max Ultimate Everything from Widget Pro plus additional customization options, API integration capabilities, and advanced analytics dashboard.
""" return html, "Mixed Short and Long Content" def create_technical_documentation_example(): """Create a table like technical documentation.""" print(" - Technical documentation style") html = """
API Method Parameters Description Return Value
render_table() table, origin, width, draw, style Renders a table with automatic text wrapping in cells. Uses the Line class for intelligent word placement and hyphenation. Rendered table with calculated height and width properties.
add_word() word, pretext Attempts to add a word to the current line. If it doesn't fit, tries hyphenation strategies including pyphen and brute-force splitting. Tuple of (success, overflow_text) indicating whether word was added and any remaining text.
calculate_spacing() text_objects, width, min_spacing, max_spacing Determines optimal spacing between words to achieve proper justification within the specified constraints. Calculated spacing value and position offset for alignment.
""" return html, "Technical Documentation Table" def create_news_article_example(): """Create a table with article-style content.""" print(" - News article layout") html = """
Date Headline Summary
2024-01-15 New Text Wrapping Feature PyWebLayout now supports automatic line wrapping in table cells, bringing sophisticated text layout capabilities to table rendering. The implementation leverages the existing Line class infrastructure.
2024-01-10 Hyphenation Improvements Enhanced hyphenation algorithms now include both dictionary-based pyphen hyphenation and intelligent brute-force splitting for edge cases.
2024-01-05 Performance Optimization Table rendering performance improved through better caching and reduced font object creation overhead.
""" return html, "News Article Layout" def render_table_example(html, title, style_variant=0): """Render a single table example.""" from pyWebLayout.style import Font from pyWebLayout.abstract.block import Table # Parse HTML base_font = Font(font_size=12) blocks = parse_html_string(html, base_font=base_font) # Find the table block table = None for block in blocks: if isinstance(block, Table): table = block break if not table: print(f" Warning: No table found in {title}") return None # Create page style page_style = PageStyle( padding=(20, 20, 20, 20), background_color=(255, 255, 255) ) # Create page page_size = (900, 600) page = Page(size=page_size, style=page_style) # Create table style variants table_styles = [ # Default style TableStyle( border_width=1, border_color=(0, 0, 0), cell_padding=(8, 8, 8, 8), header_bg_color=(240, 240, 240), cell_bg_color=(255, 255, 255) ), # Blue header style TableStyle( border_width=2, border_color=(70, 130, 180), cell_padding=(10, 10, 10, 10), header_bg_color=(176, 196, 222), cell_bg_color=(245, 250, 255) ), # Minimal style TableStyle( border_width=1, border_color=(200, 200, 200), cell_padding=(6, 6, 6, 6), header_bg_color=(250, 250, 250), cell_bg_color=(255, 255, 255) ), ] table_style = table_styles[style_variant % len(table_styles)] # Create layouter and render table layouter = DocumentLayouter(page) layouter.layout_table(table, style=table_style) # Get the rendered canvas _ = page.draw # Ensure canvas exists img = page._canvas return img def combine_examples(examples): """Combine multiple example images into one.""" images = [] titles = [] for html, title in examples: img = render_table_example(html, title) if img: images.append(img) titles.append(title) if not images: return None # Calculate combined image size max_width = max(img.width for img in images) total_height = sum(img.height for img in images) + 40 * len(images) # Extra space between images # Create combined image combined = Image.new('RGB', (max_width, total_height), color=(255, 255, 255)) # Paste images y_offset = 20 for img in images: combined.paste(img, (0, y_offset)) y_offset += img.height + 40 return combined def main(): """Run the table text wrapping example.""" print("\nTable Text Wrapping Example") print("=" * 50) # Create examples print("\n Creating table examples...") examples = [ create_narrow_columns_example(), create_mixed_content_example(), create_technical_documentation_example(), create_news_article_example(), ] print("\n Rendering table examples...") combined_image = combine_examples(examples) if combined_image: # Save the output output_dir = Path(__file__).parent.parent / 'docs' / 'images' output_dir.mkdir(parents=True, exist_ok=True) output_path = output_dir / 'example_11_table_text_wrapping.png' combined_image.save(str(output_path)) print("\n✓ Example completed!") print(f" Output saved to: {output_path}") print(f" Image size: {combined_image.width}x{combined_image.height} pixels") print(f" Created {len(examples)} table examples with text wrapping") else: print("\n✗ Failed to generate examples") if __name__ == '__main__': main()