""" HTML generation functions for dreader UI. Generates HTML strings programmatically for library view, reader view, and various overlays (settings, TOC, etc.) that can be passed to a HAL for rendering. """ from pathlib import Path from typing import List, Dict, Optional import base64 from io import BytesIO def generate_library_html(books: List[Dict[str, str]], save_covers_to_disk: bool = False) -> str: """ Generate HTML for the library view showing all books in a simple table. Args: books: List of book dictionaries with keys: - title: Book title - author: Book author - filename: EPUB filename - cover_data: Optional base64 encoded cover image - cover_path: Optional path to saved cover image (if save_covers_to_disk=True) save_covers_to_disk: If True, expect cover_path instead of cover_data Returns: Complete HTML string for library view """ # Build table rows rows = [] for book in books: # Add cover image cell if available if save_covers_to_disk and book.get('cover_path'): cover_cell = f'
{len(books)} books
Adjust reading preferences
Font Size: {font_percent}%
Line Spacing: {line_spacing}px
Paragraph Spacing: {inter_block_spacing}px
Word Spacing: {word_spacing}px
Changes apply in real-time • Tap outside to close
''' return html def generate_toc_overlay(chapters: List[Dict], page_size: tuple = (800, 1200)) -> str: """ Generate HTML for the table of contents overlay. Args: chapters: List of chapter dictionaries with keys: - index: Chapter index - title: Chapter title page_size: Page dimensions (width, height) for sizing the overlay Returns: HTML string for TOC overlay (60% popup with transparent background) """ # Build chapter list items with clickable links for pyWebLayout query chapter_items = [] for i, chapter in enumerate(chapters): title = chapter["title"] # Wrap each row in a paragraph with an inline link # For very short titles (I, II), pad the link text to ensure it's clickable link_text = f'{i+1}. {title}' if len(title) <= 2: # Add extra padding spaces inside the link to make it easier to click link_text = f'{i+1}. {title} ' # Extra spaces for padding chapter_items.append( f'' f'' f'{link_text}
' ) # Render simple white panel - compositing will be done by OverlayManager html = f'''{len(chapters)} chapters
Tap a chapter to navigate • Tap outside to close
''' return html def generate_bookmarks_overlay(bookmarks: List[Dict]) -> str: """ Generate HTML for the bookmarks overlay. Args: bookmarks: List of bookmark dictionaries with keys: - name: Bookmark name - position: Position info Returns: HTML string for bookmarks overlay """ bookmark_rows = [] for bookmark in bookmarks: bookmark_rows.append(f'''' f'' f'{link_text}
' ) # Build bookmark list items with clickable links bookmark_items = [] for bookmark in bookmarks: name = bookmark['name'] position_text = bookmark.get('position', 'Saved position') bookmark_items.append( f'' f'' f'{name}' f'{position_text}' f'
' ) # Determine which content to show contents_display = "block" if active_tab == "contents" else "none" bookmarks_display = "block" if active_tab == "bookmarks" else "none" # Style active tab contents_tab_style = "background-color: #000; color: #fff;" if active_tab == "contents" else "background-color: #f0f0f0; color: #000;" bookmarks_tab_style = "background-color: #000; color: #fff;" if active_tab == "bookmarks" else "background-color: #f0f0f0; color: #000;" chapters_html = ''.join(chapter_items) if chapter_items else 'No chapters available
' bookmarks_html = ''.join(bookmark_items) if bookmark_items else 'No bookmarks yet
' html = f'''{len(chapters)} chapters
{len(bookmarks)} saved