Source code for sabbath_school_reproducer.utils.debug_tools

"""
Debug Tools for Sabbath School Lesson Downloader

This module provides tools to parse and debug the combined markdown file.
"""

import os
import re
import markdown
from bs4 import BeautifulSoup


[docs] class DebugTools: """Tools for debugging and inspecting markdown content."""
[docs] @staticmethod def parse_file_sections(markdown_path): """ Parse the combined markdown file into its component file sections Args: markdown_path (str): Path to the combined markdown file Returns: dict: Dictionary mapping file names to content """ try: with open(markdown_path, 'r', encoding='utf-8') as f: content = f.read() # Find all file sections file_sections = re.findall(r'# File: ([^\n]+)[\r\n]+#-+[\r\n]+(.*?)(?=# File:|$)', content, re.DOTALL) result = {} for filename, section_content in file_sections: filename = filename.strip() result[filename] = section_content.strip() return result except Exception as e: print(f"Error parsing file: {e}") return {}
[docs] @staticmethod def extract_section(markdown_path, section_name): """ Extract a specific section from the combined markdown file Args: markdown_path (str): Path to the combined markdown file section_name (str): Name of the section to extract (e.g., 'front-matter.md') Returns: str or None: Content of the specified section, or None if not found """ sections = DebugTools.parse_file_sections(markdown_path) # Try exact match first if section_name in sections: return sections[section_name] # Try partial match for filename in sections: if section_name in filename: return sections[filename] return None
[docs] @staticmethod def generate_debug_html(markdown_path, output_path=None): """ Generate a more sophisticated debug HTML from the combined markdown file Args: markdown_path (str): Path to the combined markdown file output_path (str, optional): Path to save the HTML file Returns: str: Path to the generated HTML file """ if not output_path: output_path = markdown_path.replace('.md', '_debug.html') sections = DebugTools.parse_file_sections(markdown_path) # Generate HTML with collapsible sections html_parts = [ '<!DOCTYPE html>', '<html>', '<head>', ' <meta charset="utf-8">', ' <title>Debug View - ' + os.path.basename(markdown_path) + '</title>', ' <style>', ' body { font-family: Georgia, serif; margin: 2em; line-height: 1.5; }', ' .section { border: 1px solid #ddd; margin: 1em 0; border-radius: 4px; overflow: hidden; }', ' .section-header { background-color: #f5f1e6; padding: 0.8em; font-weight: bold; cursor: pointer; user-select: none; }', ' .section-header:hover { background-color: #ebe5d6; }', ' .section-content { padding: 1em; display: none; border-top: 1px solid #ddd; overflow-x: auto; }', ' .section-content.open { display: block; }', ' .section-content pre { margin: 0; white-space: pre-wrap; }', ' .section-content.html-preview { background-color: #f9f9f9; }', ' .tabs { display: flex; background-color: #f5f5f5; border-bottom: 1px solid #ddd; }', ' .tab { padding: 0.5em 1em; cursor: pointer; border-right: 1px solid #ddd; }', ' .tab.active { background-color: #fff; border-bottom: 2px solid #7d2b2b; }', ' h1, h2, h3 { color: #7d2b2b; }', ' .summary { background-color: #f9f7f1; padding: 1em; border-left: 3px solid #7d2b2b; margin-bottom: 1em; }', ' </style>', '</head>', '<body>', ' <h1>Debug View for Sabbath School Lessons</h1>', ' <p>This page shows the content of each file section from the combined markdown file.</p>', ' <div class="summary">', f' <p><strong>Filename:</strong> {os.path.basename(markdown_path)}</p>', f' <p><strong>Total sections:</strong> {len(sections)}</p>', ' </div>' ] # Add collapsible sections for filename, content in sections.items(): # Convert markdown to HTML for preview html_preview = markdown.markdown(content) section_html = f""" <div class="section"> <div class="section-header" onclick="toggleSection(this.parentNode)"> {filename} </div> <div class="tabs"> <div class="tab active" onclick="switchTab(this, 'raw')">Raw Markdown</div> <div class="tab" onclick="switchTab(this, 'html')">HTML Preview</div> </div> <div class="section-content raw open"> <pre>{content}</pre> </div> <div class="section-content html-preview html"> {html_preview} </div> </div> """ html_parts.append(section_html) # Add JavaScript for interaction html_parts.extend([ ' <script>', ' function toggleSection(section) {', ' const content = section.querySelector(".section-content.open");', ' if (content) {', ' content.classList.toggle("open");', ' }', ' }', ' function switchTab(tab, type) {', ' const section = tab.closest(".section");', ' const tabs = section.querySelectorAll(".tab");', ' const contents = section.querySelectorAll(".section-content");', ' ', ' // Deactivate all tabs and hide all contents', ' tabs.forEach(t => t.classList.remove("active"));', ' contents.forEach(c => c.classList.remove("open"));', ' ', ' // Activate selected tab and show corresponding content', ' tab.classList.add("active");', ' section.querySelector(`.section-content.${type}`).classList.add("open");', ' }', ' </script>', '</body>', '</html>' ]) # Write HTML to file with open(output_path, 'w', encoding='utf-8') as f: f.write('\n'.join(html_parts)) return output_path