[{"data":1,"prerenderedAt":60},["Reactive",2],{"blog-post-markdown-table-accessibility-aria-complete-guide":3},{"slug":4,"title":5,"description":6,"excerpt":7,"date":8,"category":9,"author":10,"keywords":11,"readingMinutes":12,"html":13,"headings":14,"tools":34,"related":35},"markdown-table-accessibility-aria-complete-guide","Markdown Table Accessibility and ARIA Attributes: Complete Guide for Inclusive Technical Documentation","Master accessible Markdown table creation with ARIA attributes, semantic markup, and screen reader optimization. Learn responsive table design, accessibility testing, and inclusive documentation practices for all users.","Advanced Markdown table accessibility ensures that tabular data remains usable and comprehensible for all users, including those who rely on screen readers, keyboard navigation, and assistive…","2025-10-02","Tutorial","Matthew Rathbone","markdown table accessibility, ARIA attributes markdown, accessible tables, screen reader tables, markdown table headers, table semantics, inclusive documentation, WCAG compliance markdown, responsive accessible tables",22,"\u003Cp>Advanced Markdown table accessibility ensures that tabular data remains usable and comprehensible for all users, including those who rely on screen readers, keyboard navigation, and assistive technologies. By implementing proper semantic markup, ARIA attributes, and responsive design patterns, technical writers can create inclusive documentation that meets WCAG guidelines while maintaining the simplicity and flexibility that makes Markdown an effective format for structured content presentation.\u003C/p>\n\u003Ch2 id=\"why-prioritize-table-accessibility\">Why Prioritize Table Accessibility?\u003C/h2>\n\u003Cp>Professional table accessibility provides essential benefits for inclusive documentation:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Universal Usability\u003C/strong>: Ensure tabular data is accessible to users with visual, motor, and cognitive disabilities\u003C/li>\n\u003Cli>\u003Cstrong>Legal Compliance\u003C/strong>: Meet WCAG 2.1 AA standards and accessibility legislation requirements\u003C/li>\n\u003Cli>\u003Cstrong>Enhanced User Experience\u003C/strong>: Improve navigation and comprehension for all users, not just those with disabilities\u003C/li>\n\u003Cli>\u003Cstrong>SEO Benefits\u003C/strong>: Semantic table markup improves search engine understanding of content structure\u003C/li>\n\u003Cli>\u003Cstrong>Future-Proofing\u003C/strong>: Build documentation that works with emerging assistive technologies\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"foundation-accessibility-principles\">Foundation Accessibility Principles\u003C/h2>\n\u003Ch3 id=\"semantic-table-structure\">Semantic Table Structure\u003C/h3>\n\u003Cp>Understanding how to create properly structured accessible tables in Markdown:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-markdown\">\u003Cspan class=\"hljs-section\"># Basic Accessible Table Structure\u003C/span>\n\n\u003Cspan class=\"hljs-section\">## Simple Data Table with Headers\u003C/span>\n\n| Product Name | Price | Stock Status | Category |\n|--------------|-------|--------------|----------|\n| Wireless Mouse | $29.99 | In Stock | Electronics |\n| Bluetooth Keyboard | $79.99 | Low Stock | Electronics |\n| USB-C Cable | $12.99 | Out of Stock | Accessories |\n| Laptop Stand | $45.00 | In Stock | Furniture |\n\n\u003Cspan class=\"hljs-section\">## Table with Enhanced Semantic Meaning\u003C/span>\n\nThe following table shows quarterly sales data by region:\n\n| Region | Q1 Sales | Q2 Sales | Q3 Sales | Q4 Sales | Total |\n|--------|----------|----------|----------|----------|-------|\n| North America | $125,000 | $134,500 | $142,300 | $156,800 | $558,600 |\n| Europe | $98,400 | $103,200 | $115,600 | $128,900 | $446,100 |\n| Asia Pacific | $87,300 | $92,100 | $98,700 | $105,400 | $383,500 |\n| \u003Cspan class=\"hljs-strong\">**Total**\u003C/span> | \u003Cspan class=\"hljs-strong\">**$310,700**\u003C/span> | \u003Cspan class=\"hljs-strong\">**$329,800**\u003C/span> | \u003Cspan class=\"hljs-strong\">**$356,600**\u003C/span> | \u003Cspan class=\"hljs-strong\">**$391,100**\u003C/span> | \u003Cspan class=\"hljs-strong\">**$1,388,200**\u003C/span> |\n\n\u003Cspan class=\"hljs-emphasis\">*Note: All figures shown in USD. Data reflects gross sales before taxes and fees.*\u003C/span>\n\u003C/code>\u003C/pre>\u003Ch3 id=\"advanced-table-accessibility-patterns\">Advanced Table Accessibility Patterns\u003C/h3>\n\u003Cp>Implementing comprehensive accessibility features for complex tables:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-html\">\u003Cspan class=\"hljs-comment\">&lt;!-- Enhanced HTML output for accessible Markdown tables --&gt;\u003C/span>\n\u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">div\u003C/span> \u003Cspan class=\"hljs-attr\">class\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;table-container&quot;\u003C/span> \u003Cspan class=\"hljs-attr\">role\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;region&quot;\u003C/span> \u003Cspan class=\"hljs-attr\">aria-labelledby\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;sales-table-caption&quot;\u003C/span>&gt;\u003C/span>\n  \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">table\u003C/span> \u003Cspan class=\"hljs-attr\">class\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;accessible-table&quot;\u003C/span> \u003Cspan class=\"hljs-attr\">id\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;quarterly-sales&quot;\u003C/span>&gt;\u003C/span>\n    \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">caption\u003C/span> \u003Cspan class=\"hljs-attr\">id\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;sales-table-caption&quot;\u003C/span>&gt;\u003C/span>\n      Quarterly Sales Performance by Region (2025)\n      \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">details\u003C/span> \u003Cspan class=\"hljs-attr\">class\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;table-description&quot;\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">summary\u003C/span>&gt;\u003C/span>Table Description\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">summary\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">p\u003C/span>&gt;\u003C/span>This table displays quarterly sales figures for four regions: North America, Europe, and Asia Pacific. Each row represents a region, with columns showing sales data for each quarter (Q1-Q4) and a total column. The final row shows aggregate totals across all regions.\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">p\u003C/span>&gt;\u003C/span>\n      \u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">details\u003C/span>&gt;\u003C/span>\n    \u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">caption\u003C/span>&gt;\u003C/span>\n    \n    \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">thead\u003C/span>&gt;\u003C/span>\n      \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">tr\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">th\u003C/span> \u003Cspan class=\"hljs-attr\">scope\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;col&quot;\u003C/span> \u003Cspan class=\"hljs-attr\">id\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;region-header&quot;\u003C/span>&gt;\u003C/span>Region\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">th\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">th\u003C/span> \u003Cspan class=\"hljs-attr\">scope\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;col&quot;\u003C/span> \u003Cspan class=\"hljs-attr\">id\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;q1-header&quot;\u003C/span>&gt;\u003C/span>Q1 Sales\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">th\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">th\u003C/span> \u003Cspan class=\"hljs-attr\">scope\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;col&quot;\u003C/span> \u003Cspan class=\"hljs-attr\">id\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;q2-header&quot;\u003C/span>&gt;\u003C/span>Q2 Sales\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">th\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">th\u003C/span> \u003Cspan class=\"hljs-attr\">scope\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;col&quot;\u003C/span> \u003Cspan class=\"hljs-attr\">id\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;q3-header&quot;\u003C/span>&gt;\u003C/span>Q3 Sales\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">th\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">th\u003C/span> \u003Cspan class=\"hljs-attr\">scope\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;col&quot;\u003C/span> \u003Cspan class=\"hljs-attr\">id\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;q4-header&quot;\u003C/span>&gt;\u003C/span>Q4 Sales\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">th\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">th\u003C/span> \u003Cspan class=\"hljs-attr\">scope\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;col&quot;\u003C/span> \u003Cspan class=\"hljs-attr\">id\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;total-header&quot;\u003C/span>&gt;\u003C/span>Annual Total\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">th\u003C/span>&gt;\u003C/span>\n      \u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">tr\u003C/span>&gt;\u003C/span>\n    \u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">thead\u003C/span>&gt;\u003C/span>\n    \n    \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">tbody\u003C/span>&gt;\u003C/span>\n      \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">tr\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">th\u003C/span> \u003Cspan class=\"hljs-attr\">scope\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;row&quot;\u003C/span> \u003Cspan class=\"hljs-attr\">headers\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;region-header&quot;\u003C/span>&gt;\u003C/span>North America\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">th\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">td\u003C/span> \u003Cspan class=\"hljs-attr\">headers\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;q1-header region-header&quot;\u003C/span>&gt;\u003C/span>$125,000\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">td\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">td\u003C/span> \u003Cspan class=\"hljs-attr\">headers\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;q2-header region-header&quot;\u003C/span>&gt;\u003C/span>$134,500\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">td\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">td\u003C/span> \u003Cspan class=\"hljs-attr\">headers\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;q3-header region-header&quot;\u003C/span>&gt;\u003C/span>$142,300\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">td\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">td\u003C/span> \u003Cspan class=\"hljs-attr\">headers\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;q4-header region-header&quot;\u003C/span>&gt;\u003C/span>$156,800\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">td\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">td\u003C/span> \u003Cspan class=\"hljs-attr\">headers\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;total-header region-header&quot;\u003C/span>&gt;\u003C/span>\u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">strong\u003C/span>&gt;\u003C/span>$558,600\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">strong\u003C/span>&gt;\u003C/span>\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">td\u003C/span>&gt;\u003C/span>\n      \u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">tr\u003C/span>&gt;\u003C/span>\n      \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">tr\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">th\u003C/span> \u003Cspan class=\"hljs-attr\">scope\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;row&quot;\u003C/span> \u003Cspan class=\"hljs-attr\">headers\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;region-header&quot;\u003C/span>&gt;\u003C/span>Europe\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">th\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">td\u003C/span> \u003Cspan class=\"hljs-attr\">headers\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;q1-header region-header&quot;\u003C/span>&gt;\u003C/span>$98,400\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">td\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">td\u003C/span> \u003Cspan class=\"hljs-attr\">headers\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;q2-header region-header&quot;\u003C/span>&gt;\u003C/span>$103,200\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">td\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">td\u003C/span> \u003Cspan class=\"hljs-attr\">headers\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;q3-header region-header&quot;\u003C/span>&gt;\u003C/span>$115,600\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">td\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">td\u003C/span> \u003Cspan class=\"hljs-attr\">headers\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;q4-header region-header&quot;\u003C/span>&gt;\u003C/span>$128,900\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">td\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">td\u003C/span> \u003Cspan class=\"hljs-attr\">headers\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;total-header region-header&quot;\u003C/span>&gt;\u003C/span>\u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">strong\u003C/span>&gt;\u003C/span>$446,100\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">strong\u003C/span>&gt;\u003C/span>\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">td\u003C/span>&gt;\u003C/span>\n      \u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">tr\u003C/span>&gt;\u003C/span>\n      \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">tr\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">th\u003C/span> \u003Cspan class=\"hljs-attr\">scope\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;row&quot;\u003C/span> \u003Cspan class=\"hljs-attr\">headers\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;region-header&quot;\u003C/span>&gt;\u003C/span>Asia Pacific\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">th\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">td\u003C/span> \u003Cspan class=\"hljs-attr\">headers\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;q1-header region-header&quot;\u003C/span>&gt;\u003C/span>$87,300\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">td\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">td\u003C/span> \u003Cspan class=\"hljs-attr\">headers\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;q2-header region-header&quot;\u003C/span>&gt;\u003C/span>$92,100\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">td\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">td\u003C/span> \u003Cspan class=\"hljs-attr\">headers\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;q3-header region-header&quot;\u003C/span>&gt;\u003C/span>$98,700\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">td\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">td\u003C/span> \u003Cspan class=\"hljs-attr\">headers\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;q4-header region-header&quot;\u003C/span>&gt;\u003C/span>$105,400\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">td\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">td\u003C/span> \u003Cspan class=\"hljs-attr\">headers\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;total-header region-header&quot;\u003C/span>&gt;\u003C/span>\u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">strong\u003C/span>&gt;\u003C/span>$383,500\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">strong\u003C/span>&gt;\u003C/span>\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">td\u003C/span>&gt;\u003C/span>\n      \u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">tr\u003C/span>&gt;\u003C/span>\n    \u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">tbody\u003C/span>&gt;\u003C/span>\n    \n    \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">tfoot\u003C/span>&gt;\u003C/span>\n      \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">tr\u003C/span> \u003Cspan class=\"hljs-attr\">class\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;total-row&quot;\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">th\u003C/span> \u003Cspan class=\"hljs-attr\">scope\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;row&quot;\u003C/span> \u003Cspan class=\"hljs-attr\">headers\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;region-header&quot;\u003C/span>&gt;\u003C/span>Grand Total\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">th\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">td\u003C/span> \u003Cspan class=\"hljs-attr\">headers\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;q1-header&quot;\u003C/span>&gt;\u003C/span>\u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">strong\u003C/span>&gt;\u003C/span>$310,700\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">strong\u003C/span>&gt;\u003C/span>\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">td\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">td\u003C/span> \u003Cspan class=\"hljs-attr\">headers\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;q2-header&quot;\u003C/span>&gt;\u003C/span>\u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">strong\u003C/span>&gt;\u003C/span>$329,800\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">strong\u003C/span>&gt;\u003C/span>\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">td\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">td\u003C/span> \u003Cspan class=\"hljs-attr\">headers\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;q3-header&quot;\u003C/span>&gt;\u003C/span>\u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">strong\u003C/span>&gt;\u003C/span>$356,600\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">strong\u003C/span>&gt;\u003C/span>\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">td\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">td\u003C/span> \u003Cspan class=\"hljs-attr\">headers\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;q4-header&quot;\u003C/span>&gt;\u003C/span>\u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">strong\u003C/span>&gt;\u003C/span>$391,100\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">strong\u003C/span>&gt;\u003C/span>\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">td\u003C/span>&gt;\u003C/span>\n        \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">td\u003C/span> \u003Cspan class=\"hljs-attr\">headers\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;total-header&quot;\u003C/span>&gt;\u003C/span>\u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">strong\u003C/span>&gt;\u003C/span>$1,388,200\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">strong\u003C/span>&gt;\u003C/span>\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">td\u003C/span>&gt;\u003C/span>\n      \u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">tr\u003C/span>&gt;\u003C/span>\n    \u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">tfoot\u003C/span>&gt;\u003C/span>\n  \u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">table\u003C/span>&gt;\u003C/span>\n  \n  \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">div\u003C/span> \u003Cspan class=\"hljs-attr\">class\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;table-controls&quot;\u003C/span> \u003Cspan class=\"hljs-attr\">role\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;toolbar&quot;\u003C/span> \u003Cspan class=\"hljs-attr\">aria-label\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;Table interaction controls&quot;\u003C/span>&gt;\u003C/span>\n    \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">button\u003C/span> \u003Cspan class=\"hljs-attr\">type\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;button&quot;\u003C/span> \u003Cspan class=\"hljs-attr\">aria-controls\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;quarterly-sales&quot;\u003C/span> \u003Cspan class=\"hljs-attr\">id\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;sort-toggle&quot;\u003C/span>&gt;\u003C/span>\n      \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">span\u003C/span> \u003Cspan class=\"hljs-attr\">aria-hidden\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;true&quot;\u003C/span>&gt;\u003C/span>⇅\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">span\u003C/span>&gt;\u003C/span>\n      Toggle Sort\n    \u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">button\u003C/span>&gt;\u003C/span>\n    \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">button\u003C/span> \u003Cspan class=\"hljs-attr\">type\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;button&quot;\u003C/span> \u003Cspan class=\"hljs-attr\">aria-controls\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;quarterly-sales&quot;\u003C/span> \u003Cspan class=\"hljs-attr\">id\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;filter-toggle&quot;\u003C/span>&gt;\u003C/span>\n      \u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">span\u003C/span> \u003Cspan class=\"hljs-attr\">aria-hidden\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;true&quot;\u003C/span>&gt;\u003C/span>🔍\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">span\u003C/span>&gt;\u003C/span>\n      Filter Data\n    \u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">button\u003C/span>&gt;\u003C/span>\n  \u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">div\u003C/span>&gt;\u003C/span>\n\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">div\u003C/span>&gt;\u003C/span>\n\u003C/code>\u003C/pre>\u003Ch3 id=\"markdown-processing-for-accessibility\">Markdown Processing for Accessibility\u003C/h3>\n\u003Cp>Creating tools to enhance Markdown table accessibility automatically:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-python\">\u003Cspan class=\"hljs-comment\"># markdown_table_accessibility.py - Accessibility enhancement for Markdown tables\u003C/span>\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> re\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> typing \u003Cspan class=\"hljs-keyword\">import\u003C/span> \u003Cspan class=\"hljs-type\">List\u003C/span>, \u003Cspan class=\"hljs-type\">Dict\u003C/span>, \u003Cspan class=\"hljs-type\">Optional\u003C/span>, \u003Cspan class=\"hljs-type\">Tuple\u003C/span>\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> markdown \u003Cspan class=\"hljs-keyword\">import\u003C/span> Markdown\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> markdown.extensions \u003Cspan class=\"hljs-keyword\">import\u003C/span> Extension\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> markdown.preprocessors \u003Cspan class=\"hljs-keyword\">import\u003C/span> Preprocessor\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> markdown.postprocessors \u003Cspan class=\"hljs-keyword\">import\u003C/span> Postprocessor\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">AccessibleTableExtension\u003C/span>(\u003Cspan class=\"hljs-title class_ inherited__\">Extension\u003C/span>):\n    \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Markdown extension to enhance table accessibility&quot;&quot;&quot;\u003C/span>\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">__init__\u003C/span>(\u003Cspan class=\"hljs-params\">self, **kwargs\u003C/span>):\n        self.config = {\n            \u003Cspan class=\"hljs-string\">&#x27;add_captions&#x27;\u003C/span>: [\u003Cspan class=\"hljs-literal\">True\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;Add table captions from preceding text&#x27;\u003C/span>],\n            \u003Cspan class=\"hljs-string\">&#x27;add_descriptions&#x27;\u003C/span>: [\u003Cspan class=\"hljs-literal\">True\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;Add detailed table descriptions&#x27;\u003C/span>],\n            \u003Cspan class=\"hljs-string\">&#x27;enhance_headers&#x27;\u003C/span>: [\u003Cspan class=\"hljs-literal\">True\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;Add proper header scope attributes&#x27;\u003C/span>],\n            \u003Cspan class=\"hljs-string\">&#x27;add_navigation&#x27;\u003C/span>: [\u003Cspan class=\"hljs-literal\">False\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;Add table navigation controls&#x27;\u003C/span>],\n            \u003Cspan class=\"hljs-string\">&#x27;responsive_design&#x27;\u003C/span>: [\u003Cspan class=\"hljs-literal\">True\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;Add responsive table wrapper&#x27;\u003C/span>]\n        }\n        \u003Cspan class=\"hljs-built_in\">super\u003C/span>().__init__(**kwargs)\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">extendMarkdown\u003C/span>(\u003Cspan class=\"hljs-params\">self, md\u003C/span>):\n        md.preprocessors.register(\n            AccessibleTablePreprocessor(md, self.getConfigs()), \n            \u003Cspan class=\"hljs-string\">&#x27;accessible_table_pre&#x27;\u003C/span>, \n            \u003Cspan class=\"hljs-number\">30\u003C/span>\n        )\n        md.postprocessors.register(\n            AccessibleTablePostprocessor(md, self.getConfigs()), \n            \u003Cspan class=\"hljs-string\">&#x27;accessible_table_post&#x27;\u003C/span>, \n            \u003Cspan class=\"hljs-number\">10\u003C/span>\n        )\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">AccessibleTablePreprocessor\u003C/span>(\u003Cspan class=\"hljs-title class_ inherited__\">Preprocessor\u003C/span>):\n    \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Preprocessor to prepare tables for accessibility enhancement&quot;&quot;&quot;\u003C/span>\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">__init__\u003C/span>(\u003Cspan class=\"hljs-params\">self, md, config\u003C/span>):\n        \u003Cspan class=\"hljs-built_in\">super\u003C/span>().__init__(md)\n        self.config = config\n        self.table_counter = \u003Cspan class=\"hljs-number\">0\u003C/span>\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">run\u003C/span>(\u003Cspan class=\"hljs-params\">self, lines\u003C/span>):\n        new_lines = []\n        i = \u003Cspan class=\"hljs-number\">0\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">while\u003C/span> i &lt; \u003Cspan class=\"hljs-built_in\">len\u003C/span>(lines):\n            line = lines[i]\n            \n            \u003Cspan class=\"hljs-comment\"># Detect table start\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> self.is_table_header(line):\n                table_info = self.extract_table_info(lines, i)\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> table_info:\n                    \u003Cspan class=\"hljs-comment\"># Add accessibility metadata\u003C/span>\n                    enhanced_table = self.enhance_table_accessibility(\n                        lines[i:i + table_info[\u003Cspan class=\"hljs-string\">&#x27;line_count&#x27;\u003C/span>]], \n                        table_info\n                    )\n                    new_lines.extend(enhanced_table)\n                    i += table_info[\u003Cspan class=\"hljs-string\">&#x27;line_count&#x27;\u003C/span>]\n                    \u003Cspan class=\"hljs-keyword\">continue\u003C/span>\n            \n            new_lines.append(line)\n            i += \u003Cspan class=\"hljs-number\">1\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> new_lines\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">is_table_header\u003C/span>(\u003Cspan class=\"hljs-params\">self, line: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">bool\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Check if line is a table header row&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;|&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> line \u003Cspan class=\"hljs-keyword\">and\u003C/span> line.strip().startswith(\u003Cspan class=\"hljs-string\">&#x27;|&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">or\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> line.strip().startswith(\u003Cspan class=\"hljs-string\">&#x27;|&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">and\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;|&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> line\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">extract_table_info\u003C/span>(\u003Cspan class=\"hljs-params\">self, lines: \u003Cspan class=\"hljs-type\">List\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>], start_idx: \u003Cspan class=\"hljs-built_in\">int\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Optional\u003C/span>[\u003Cspan class=\"hljs-type\">Dict\u003C/span>]:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Extract information about a table structure&quot;&quot;&quot;\u003C/span>\n        table_lines = []\n        i = start_idx\n        \n        \u003Cspan class=\"hljs-comment\"># Look for table caption in preceding lines\u003C/span>\n        caption_candidates = []\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> j \u003Cspan class=\"hljs-keyword\">in\u003C/span> \u003Cspan class=\"hljs-built_in\">range\u003C/span>(\u003Cspan class=\"hljs-built_in\">max\u003C/span>(\u003Cspan class=\"hljs-number\">0\u003C/span>, start_idx - \u003Cspan class=\"hljs-number\">3\u003C/span>), start_idx):\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> lines[j].strip() \u003Cspan class=\"hljs-keyword\">and\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> lines[j].startswith(\u003Cspan class=\"hljs-string\">&#x27;#&#x27;\u003C/span>):\n                caption_candidates.append(lines[j].strip())\n        \n        \u003Cspan class=\"hljs-comment\"># Extract table rows\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">while\u003C/span> i &lt; \u003Cspan class=\"hljs-built_in\">len\u003C/span>(lines) \u003Cspan class=\"hljs-keyword\">and\u003C/span> (self.is_table_row(lines[i]) \u003Cspan class=\"hljs-keyword\">or\u003C/span> self.is_table_separator(lines[i])):\n            table_lines.append(lines[i])\n            i += \u003Cspan class=\"hljs-number\">1\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(table_lines) &lt; \u003Cspan class=\"hljs-number\">2\u003C/span>:  \u003Cspan class=\"hljs-comment\"># Need at least header + separator\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-literal\">None\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Analyze table structure\u003C/span>\n        header_row = table_lines[\u003Cspan class=\"hljs-number\">0\u003C/span>]\n        columns = [col.strip() \u003Cspan class=\"hljs-keyword\">for\u003C/span> col \u003Cspan class=\"hljs-keyword\">in\u003C/span> header_row.split(\u003Cspan class=\"hljs-string\">&#x27;|&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">if\u003C/span> col.strip()]\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> {\n            \u003Cspan class=\"hljs-string\">&#x27;line_count&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">len\u003C/span>(table_lines),\n            \u003Cspan class=\"hljs-string\">&#x27;columns&#x27;\u003C/span>: columns,\n            \u003Cspan class=\"hljs-string\">&#x27;column_count&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">len\u003C/span>(columns),\n            \u003Cspan class=\"hljs-string\">&#x27;caption_candidates&#x27;\u003C/span>: caption_candidates,\n            \u003Cspan class=\"hljs-string\">&#x27;table_id&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">f&#x27;accessible-table-\u003Cspan class=\"hljs-subst\">{self.table_counter + \u003Cspan class=\"hljs-number\">1\u003C/span>}\u003C/span>&#x27;\u003C/span>\n        }\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">is_table_row\u003C/span>(\u003Cspan class=\"hljs-params\">self, line: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">bool\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Check if line is a table data row&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;|&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> line \u003Cspan class=\"hljs-keyword\">and\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> self.is_table_separator(line)\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">is_table_separator\u003C/span>(\u003Cspan class=\"hljs-params\">self, line: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">bool\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Check if line is a table separator (---|---|---)&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> re.\u003Cspan class=\"hljs-keyword\">match\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^[\\s\\|:\\-]+$&#x27;\u003C/span>, line.strip())\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">enhance_table_accessibility\u003C/span>(\u003Cspan class=\"hljs-params\">self, table_lines: \u003Cspan class=\"hljs-type\">List\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>], table_info: \u003Cspan class=\"hljs-type\">Dict\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">List\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>]:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Add accessibility metadata to table&quot;&quot;&quot;\u003C/span>\n        enhanced_lines = []\n        \n        \u003Cspan class=\"hljs-comment\"># Add table container with accessibility attributes\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> self.config[\u003Cspan class=\"hljs-string\">&#x27;responsive_design&#x27;\u003C/span>]:\n            enhanced_lines.append(\u003Cspan class=\"hljs-string\">f&#x27;&lt;div class=&quot;table-container&quot; role=&quot;region&quot; aria-labelledby=&quot;\u003Cspan class=\"hljs-subst\">{table_info[\u003Cspan class=\"hljs-string\">&quot;table_id&quot;\u003C/span>]}\u003C/span>-caption&quot;&gt;&#x27;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-comment\"># Add table caption if available\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> self.config[\u003Cspan class=\"hljs-string\">&#x27;add_captions&#x27;\u003C/span>] \u003Cspan class=\"hljs-keyword\">and\u003C/span> table_info[\u003Cspan class=\"hljs-string\">&#x27;caption_candidates&#x27;\u003C/span>]:\n            best_caption = table_info[\u003Cspan class=\"hljs-string\">&#x27;caption_candidates&#x27;\u003C/span>][-\u003Cspan class=\"hljs-number\">1\u003C/span>]  \u003Cspan class=\"hljs-comment\"># Use the closest preceding line\u003C/span>\n            enhanced_lines.append(\u003Cspan class=\"hljs-string\">f&#x27;&lt;caption id=&quot;\u003Cspan class=\"hljs-subst\">{table_info[\u003Cspan class=\"hljs-string\">&quot;table_id&quot;\u003C/span>]}\u003C/span>-caption&quot;&gt;\u003Cspan class=\"hljs-subst\">{best_caption}\u003C/span>&lt;/caption&gt;&#x27;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-comment\"># Add table with accessibility attributes\u003C/span>\n        enhanced_lines.append(\u003Cspan class=\"hljs-string\">f&#x27;&lt;table id=&quot;\u003Cspan class=\"hljs-subst\">{table_info[\u003Cspan class=\"hljs-string\">&quot;table_id&quot;\u003C/span>]}\u003C/span>&quot; class=&quot;accessible-table&quot;&gt;&#x27;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-comment\"># Process table content\u003C/span>\n        enhanced_lines.extend(table_lines)\n        \n        enhanced_lines.append(\u003Cspan class=\"hljs-string\">&#x27;&lt;/table&gt;&#x27;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> self.config[\u003Cspan class=\"hljs-string\">&#x27;responsive_design&#x27;\u003C/span>]:\n            enhanced_lines.append(\u003Cspan class=\"hljs-string\">&#x27;&lt;/div&gt;&#x27;\u003C/span>)\n        \n        self.table_counter += \u003Cspan class=\"hljs-number\">1\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> enhanced_lines\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">AccessibleTablePostprocessor\u003C/span>(\u003Cspan class=\"hljs-title class_ inherited__\">Postprocessor\u003C/span>):\n    \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Postprocessor to enhance rendered table HTML&quot;&quot;&quot;\u003C/span>\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">__init__\u003C/span>(\u003Cspan class=\"hljs-params\">self, md, config\u003C/span>):\n        \u003Cspan class=\"hljs-built_in\">super\u003C/span>().__init__(md)\n        self.config = config\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">run\u003C/span>(\u003Cspan class=\"hljs-params\">self, text\u003C/span>):\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> self.config[\u003Cspan class=\"hljs-string\">&#x27;enhance_headers&#x27;\u003C/span>]:\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> text\n        \n        \u003Cspan class=\"hljs-comment\"># Add scope attributes to table headers\u003C/span>\n        text = re.sub(\n            \u003Cspan class=\"hljs-string\">r&#x27;&lt;th&gt;([^&lt;]+)&lt;/th&gt;&#x27;\u003C/span>,\n            \u003Cspan class=\"hljs-keyword\">lambda\u003C/span> m: \u003Cspan class=\"hljs-string\">f&#x27;&lt;th scope=&quot;col&quot;&gt;\u003Cspan class=\"hljs-subst\">{m.group(\u003Cspan class=\"hljs-number\">1\u003C/span>)}\u003C/span>&lt;/th&gt;&#x27;\u003C/span>,\n            text\n        )\n        \n        \u003Cspan class=\"hljs-comment\"># Add scope attributes to row headers (first column)\u003C/span>\n        text = re.sub(\n            \u003Cspan class=\"hljs-string\">r&#x27;&lt;tr&gt;\\s*&lt;td&gt;([^&lt;]+)&lt;/td&gt;&#x27;\u003C/span>,\n            \u003Cspan class=\"hljs-keyword\">lambda\u003C/span> m: \u003Cspan class=\"hljs-string\">f&#x27;&lt;tr&gt;\\n&lt;th scope=&quot;row&quot;&gt;\u003Cspan class=\"hljs-subst\">{m.group(\u003Cspan class=\"hljs-number\">1\u003C/span>)}\u003C/span>&lt;/th&gt;&#x27;\u003C/span>,\n            text\n        )\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> text\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">MarkdownTableAccessibilityAnalyzer\u003C/span>:\n    \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Analyze and improve Markdown table accessibility&quot;&quot;&quot;\u003C/span>\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">__init__\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>):\n        self.accessibility_checks = [\n            self.check_table_structure,\n            self.check_header_presence,\n            self.check_caption_availability,\n            self.check_complex_table_features,\n            self.check_responsive_design\n        ]\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">analyze_table_accessibility\u003C/span>(\u003Cspan class=\"hljs-params\">self, markdown_content: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Dict\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Comprehensive accessibility analysis of tables in Markdown content&quot;&quot;&quot;\u003C/span>\n        results = {\n            \u003Cspan class=\"hljs-string\">&#x27;tables_found&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&#x27;accessibility_score&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>: [],\n            \u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>: [],\n            \u003Cspan class=\"hljs-string\">&#x27;enhanced_markdown&#x27;\u003C/span>: markdown_content\n        }\n        \n        tables = self.extract_tables(markdown_content)\n        results[\u003Cspan class=\"hljs-string\">&#x27;tables_found&#x27;\u003C/span>] = \u003Cspan class=\"hljs-built_in\">len\u003C/span>(tables)\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> tables:\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> results\n        \n        total_score = \u003Cspan class=\"hljs-number\">0\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> i, table \u003Cspan class=\"hljs-keyword\">in\u003C/span> \u003Cspan class=\"hljs-built_in\">enumerate\u003C/span>(tables):\n            table_analysis = self.analyze_single_table(table, i + \u003Cspan class=\"hljs-number\">1\u003C/span>)\n            total_score += table_analysis[\u003Cspan class=\"hljs-string\">&#x27;score&#x27;\u003C/span>]\n            results[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>].extend(table_analysis[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>])\n            results[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>].extend(table_analysis[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>])\n        \n        results[\u003Cspan class=\"hljs-string\">&#x27;accessibility_score&#x27;\u003C/span>] = total_score / \u003Cspan class=\"hljs-built_in\">len\u003C/span>(tables)\n        results[\u003Cspan class=\"hljs-string\">&#x27;enhanced_markdown&#x27;\u003C/span>] = self.enhance_markdown_accessibility(markdown_content, tables)\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> results\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">extract_tables\u003C/span>(\u003Cspan class=\"hljs-params\">self, markdown_content: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">List\u003C/span>[\u003Cspan class=\"hljs-type\">Dict\u003C/span>]:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Extract all tables from Markdown content&quot;&quot;&quot;\u003C/span>\n        tables = []\n        lines = markdown_content.split(\u003Cspan class=\"hljs-string\">&#x27;\\n&#x27;\u003C/span>)\n        i = \u003Cspan class=\"hljs-number\">0\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">while\u003C/span> i &lt; \u003Cspan class=\"hljs-built_in\">len\u003C/span>(lines):\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> self.is_table_start(lines[i]):\n                table_data = self.extract_single_table(lines, i)\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> table_data:\n                    tables.append(table_data)\n                    i = table_data[\u003Cspan class=\"hljs-string\">&#x27;end_line&#x27;\u003C/span>]\n                \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n                    i += \u003Cspan class=\"hljs-number\">1\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n                i += \u003Cspan class=\"hljs-number\">1\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> tables\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">is_table_start\u003C/span>(\u003Cspan class=\"hljs-params\">self, line: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">bool\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Check if line starts a table&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;|&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> line \u003Cspan class=\"hljs-keyword\">and\u003C/span> line.count(\u003Cspan class=\"hljs-string\">&#x27;|&#x27;\u003C/span>) &gt;= \u003Cspan class=\"hljs-number\">2\u003C/span>\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">extract_single_table\u003C/span>(\u003Cspan class=\"hljs-params\">self, lines: \u003Cspan class=\"hljs-type\">List\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>], start_idx: \u003Cspan class=\"hljs-built_in\">int\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Optional\u003C/span>[\u003Cspan class=\"hljs-type\">Dict\u003C/span>]:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Extract a single table with its metadata&quot;&quot;&quot;\u003C/span>\n        table_lines = []\n        i = start_idx\n        \n        \u003Cspan class=\"hljs-comment\"># Find table boundaries\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">while\u003C/span> i &lt; \u003Cspan class=\"hljs-built_in\">len\u003C/span>(lines) \u003Cspan class=\"hljs-keyword\">and\u003C/span> (\u003Cspan class=\"hljs-string\">&#x27;|&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> lines[i] \u003Cspan class=\"hljs-keyword\">or\u003C/span> re.\u003Cspan class=\"hljs-keyword\">match\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^[\\s\\|:\\-]+$&#x27;\u003C/span>, lines[i].strip())):\n            table_lines.append(lines[i])\n            i += \u003Cspan class=\"hljs-number\">1\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(table_lines) &lt; \u003Cspan class=\"hljs-number\">2\u003C/span>:\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-literal\">None\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Look for preceding context (potential caption)\u003C/span>\n        context_lines = []\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> j \u003Cspan class=\"hljs-keyword\">in\u003C/span> \u003Cspan class=\"hljs-built_in\">range\u003C/span>(\u003Cspan class=\"hljs-built_in\">max\u003C/span>(\u003Cspan class=\"hljs-number\">0\u003C/span>, start_idx - \u003Cspan class=\"hljs-number\">3\u003C/span>), start_idx):\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> lines[j].strip():\n                context_lines.append(lines[j].strip())\n        \n        \u003Cspan class=\"hljs-comment\"># Analyze table structure\u003C/span>\n        header_row = table_lines[\u003Cspan class=\"hljs-number\">0\u003C/span>]\n        columns = [col.strip() \u003Cspan class=\"hljs-keyword\">for\u003C/span> col \u003Cspan class=\"hljs-keyword\">in\u003C/span> header_row.split(\u003Cspan class=\"hljs-string\">&#x27;|&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">if\u003C/span> col.strip()]\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> {\n            \u003Cspan class=\"hljs-string\">&#x27;start_line&#x27;\u003C/span>: start_idx,\n            \u003Cspan class=\"hljs-string\">&#x27;end_line&#x27;\u003C/span>: i,\n            \u003Cspan class=\"hljs-string\">&#x27;content&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;\\n&#x27;\u003C/span>.join(table_lines),\n            \u003Cspan class=\"hljs-string\">&#x27;columns&#x27;\u003C/span>: columns,\n            \u003Cspan class=\"hljs-string\">&#x27;column_count&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">len\u003C/span>(columns),\n            \u003Cspan class=\"hljs-string\">&#x27;row_count&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">len\u003C/span>([line \u003Cspan class=\"hljs-keyword\">for\u003C/span> line \u003Cspan class=\"hljs-keyword\">in\u003C/span> table_lines \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;|&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> line \u003Cspan class=\"hljs-keyword\">and\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> re.\u003Cspan class=\"hljs-keyword\">match\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^[\\s\\|:\\-]+$&#x27;\u003C/span>, line.strip())]),\n            \u003Cspan class=\"hljs-string\">&#x27;context_lines&#x27;\u003C/span>: context_lines,\n            \u003Cspan class=\"hljs-string\">&#x27;has_separator&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">any\u003C/span>(re.\u003Cspan class=\"hljs-keyword\">match\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^[\\s\\|:\\-]+$&#x27;\u003C/span>, line.strip()) \u003Cspan class=\"hljs-keyword\">for\u003C/span> line \u003Cspan class=\"hljs-keyword\">in\u003C/span> table_lines)\n        }\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">analyze_single_table\u003C/span>(\u003Cspan class=\"hljs-params\">self, table: \u003Cspan class=\"hljs-type\">Dict\u003C/span>, table_number: \u003Cspan class=\"hljs-built_in\">int\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Dict\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Analyze accessibility of a single table&quot;&quot;&quot;\u003C/span>\n        analysis = {\n            \u003Cspan class=\"hljs-string\">&#x27;table_number&#x27;\u003C/span>: table_number,\n            \u003Cspan class=\"hljs-string\">&#x27;score&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>: [],\n            \u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>: []\n        }\n        \n        \u003Cspan class=\"hljs-comment\"># Run all accessibility checks\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> check \u003Cspan class=\"hljs-keyword\">in\u003C/span> self.accessibility_checks:\n            check_result = check(table, table_number)\n            analysis[\u003Cspan class=\"hljs-string\">&#x27;score&#x27;\u003C/span>] += check_result.get(\u003Cspan class=\"hljs-string\">&#x27;score&#x27;\u003C/span>, \u003Cspan class=\"hljs-number\">0\u003C/span>)\n            analysis[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>].extend(check_result.get(\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>, []))\n            analysis[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>].extend(check_result.get(\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>, []))\n        \n        \u003Cspan class=\"hljs-comment\"># Normalize score to 0-100 range\u003C/span>\n        max_possible_score = \u003Cspan class=\"hljs-built_in\">len\u003C/span>(self.accessibility_checks) * \u003Cspan class=\"hljs-number\">20\u003C/span>  \u003Cspan class=\"hljs-comment\"># Assuming max 20 points per check\u003C/span>\n        analysis[\u003Cspan class=\"hljs-string\">&#x27;score&#x27;\u003C/span>] = \u003Cspan class=\"hljs-built_in\">min\u003C/span>(\u003Cspan class=\"hljs-number\">100\u003C/span>, (analysis[\u003Cspan class=\"hljs-string\">&#x27;score&#x27;\u003C/span>] / max_possible_score) * \u003Cspan class=\"hljs-number\">100\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> analysis\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">check_table_structure\u003C/span>(\u003Cspan class=\"hljs-params\">self, table: \u003Cspan class=\"hljs-type\">Dict\u003C/span>, table_number: \u003Cspan class=\"hljs-built_in\">int\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Dict\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Check basic table structure accessibility&quot;&quot;&quot;\u003C/span>\n        result = {\u003Cspan class=\"hljs-string\">&#x27;score&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>: [], \u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>: []}\n        \n        \u003Cspan class=\"hljs-comment\"># Check if table has proper structure\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> table[\u003Cspan class=\"hljs-string\">&#x27;has_separator&#x27;\u003C/span>]:\n            result[\u003Cspan class=\"hljs-string\">&#x27;score&#x27;\u003C/span>] += \u003Cspan class=\"hljs-number\">15\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n            result[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">f&quot;Table \u003Cspan class=\"hljs-subst\">{table_number}\u003C/span>: Missing header separator row&quot;\u003C/span>)\n            result[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">f&quot;Add a separator row (e.g., |---|---|) after the header in table \u003Cspan class=\"hljs-subst\">{table_number}\u003C/span>&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-comment\"># Check column consistency\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> table[\u003Cspan class=\"hljs-string\">&#x27;column_count&#x27;\u003C/span>] &gt;= \u003Cspan class=\"hljs-number\">2\u003C/span>:\n            result[\u003Cspan class=\"hljs-string\">&#x27;score&#x27;\u003C/span>] += \u003Cspan class=\"hljs-number\">5\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n            result[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">f&quot;Table \u003Cspan class=\"hljs-subst\">{table_number}\u003C/span>: Table has only \u003Cspan class=\"hljs-subst\">{table[\u003Cspan class=\"hljs-string\">&#x27;column_count&#x27;\u003C/span>]}\u003C/span> column(s)&quot;\u003C/span>)\n            result[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">f&quot;Consider if table \u003Cspan class=\"hljs-subst\">{table_number}\u003C/span> would be better as a list or definition list&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> result\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">check_header_presence\u003C/span>(\u003Cspan class=\"hljs-params\">self, table: \u003Cspan class=\"hljs-type\">Dict\u003C/span>, table_number: \u003Cspan class=\"hljs-built_in\">int\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Dict\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Check if table has appropriate headers&quot;&quot;&quot;\u003C/span>\n        result = {\u003Cspan class=\"hljs-string\">&#x27;score&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>: [], \u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>: []}\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> table[\u003Cspan class=\"hljs-string\">&#x27;columns&#x27;\u003C/span>]:\n            result[\u003Cspan class=\"hljs-string\">&#x27;score&#x27;\u003C/span>] += \u003Cspan class=\"hljs-number\">15\u003C/span>\n            \n            \u003Cspan class=\"hljs-comment\"># Check for meaningful header text\u003C/span>\n            meaningful_headers = [col \u003Cspan class=\"hljs-keyword\">for\u003C/span> col \u003Cspan class=\"hljs-keyword\">in\u003C/span> table[\u003Cspan class=\"hljs-string\">&#x27;columns&#x27;\u003C/span>] \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(col.strip()) &gt; \u003Cspan class=\"hljs-number\">0\u003C/span> \u003Cspan class=\"hljs-keyword\">and\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> col.strip().isspace()]\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(meaningful_headers) == \u003Cspan class=\"hljs-built_in\">len\u003C/span>(table[\u003Cspan class=\"hljs-string\">&#x27;columns&#x27;\u003C/span>]):\n                result[\u003Cspan class=\"hljs-string\">&#x27;score&#x27;\u003C/span>] += \u003Cspan class=\"hljs-number\">5\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n                result[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">f&quot;Table \u003Cspan class=\"hljs-subst\">{table_number}\u003C/span>: Some headers are empty or contain only whitespace&quot;\u003C/span>)\n                result[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">f&quot;Provide meaningful header text for all columns in table \u003Cspan class=\"hljs-subst\">{table_number}\u003C/span>&quot;\u003C/span>)\n        \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n            result[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">f&quot;Table \u003Cspan class=\"hljs-subst\">{table_number}\u003C/span>: No header row detected&quot;\u003C/span>)\n            result[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">f&quot;Add a header row to table \u003Cspan class=\"hljs-subst\">{table_number}\u003C/span> to describe the column content&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> result\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">check_caption_availability\u003C/span>(\u003Cspan class=\"hljs-params\">self, table: \u003Cspan class=\"hljs-type\">Dict\u003C/span>, table_number: \u003Cspan class=\"hljs-built_in\">int\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Dict\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Check if table has an accessible caption or description&quot;&quot;&quot;\u003C/span>\n        result = {\u003Cspan class=\"hljs-string\">&#x27;score&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>: [], \u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>: []}\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> table[\u003Cspan class=\"hljs-string\">&#x27;context_lines&#x27;\u003C/span>]:\n            \u003Cspan class=\"hljs-comment\"># Look for caption-like content\u003C/span>\n            potential_captions = [line \u003Cspan class=\"hljs-keyword\">for\u003C/span> line \u003Cspan class=\"hljs-keyword\">in\u003C/span> table[\u003Cspan class=\"hljs-string\">&#x27;context_lines&#x27;\u003C/span>] \n                                \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> line.startswith(\u003Cspan class=\"hljs-string\">&#x27;#&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">and\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(line) &gt; \u003Cspan class=\"hljs-number\">10\u003C/span>]\n            \n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> potential_captions:\n                result[\u003Cspan class=\"hljs-string\">&#x27;score&#x27;\u003C/span>] += \u003Cspan class=\"hljs-number\">10\u003C/span>\n                result[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">f&quot;Consider converting the preceding text to a formal table caption for table \u003Cspan class=\"hljs-subst\">{table_number}\u003C/span>&quot;\u003C/span>)\n            \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n                result[\u003Cspan class=\"hljs-string\">&#x27;score&#x27;\u003C/span>] += \u003Cspan class=\"hljs-number\">5\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n            result[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">f&quot;Table \u003Cspan class=\"hljs-subst\">{table_number}\u003C/span>: No caption or descriptive text found&quot;\u003C/span>)\n            result[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">f&quot;Add a caption or description before table \u003Cspan class=\"hljs-subst\">{table_number}\u003C/span> to explain its purpose and content&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> result\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">check_complex_table_features\u003C/span>(\u003Cspan class=\"hljs-params\">self, table: \u003Cspan class=\"hljs-type\">Dict\u003C/span>, table_number: \u003Cspan class=\"hljs-built_in\">int\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Dict\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Check for complex table features that need special accessibility treatment&quot;&quot;&quot;\u003C/span>\n        result = {\u003Cspan class=\"hljs-string\">&#x27;score&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">10\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>: [], \u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>: []}  \u003Cspan class=\"hljs-comment\"># Default good score for simple tables\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Check table size - larger tables need more accessibility features\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> table[\u003Cspan class=\"hljs-string\">&#x27;row_count&#x27;\u003C/span>] &gt; \u003Cspan class=\"hljs-number\">10\u003C/span> \u003Cspan class=\"hljs-keyword\">or\u003C/span> table[\u003Cspan class=\"hljs-string\">&#x27;column_count&#x27;\u003C/span>] &gt; \u003Cspan class=\"hljs-number\">6\u003C/span>:\n            result[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">f&quot;Table \u003Cspan class=\"hljs-subst\">{table_number}\u003C/span>: Large table (\u003Cspan class=\"hljs-subst\">{table[\u003Cspan class=\"hljs-string\">&#x27;row_count&#x27;\u003C/span>]}\u003C/span> rows, \u003Cspan class=\"hljs-subst\">{table[\u003Cspan class=\"hljs-string\">&#x27;column_count&#x27;\u003C/span>]}\u003C/span> columns) may be difficult to navigate&quot;\u003C/span>)\n            result[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">f&quot;Consider breaking table \u003Cspan class=\"hljs-subst\">{table_number}\u003C/span> into smaller tables or provide navigation aids&quot;\u003C/span>)\n            result[\u003Cspan class=\"hljs-string\">&#x27;score&#x27;\u003C/span>] -= \u003Cspan class=\"hljs-number\">5\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Check for data that might need special formatting (numbers, dates, etc.)\u003C/span>\n        content_lower = table[\u003Cspan class=\"hljs-string\">&#x27;content&#x27;\u003C/span>].lower()\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">any\u003C/span>(indicator \u003Cspan class=\"hljs-keyword\">in\u003C/span> content_lower \u003Cspan class=\"hljs-keyword\">for\u003C/span> indicator \u003Cspan class=\"hljs-keyword\">in\u003C/span> [\u003Cspan class=\"hljs-string\">&#x27;$&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;%&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;total&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;sum&#x27;\u003C/span>]):\n            result[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">f&quot;Table \u003Cspan class=\"hljs-subst\">{table_number}\u003C/span> appears to contain financial or numerical data - ensure proper formatting and units are clear&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> result\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">check_responsive_design\u003C/span>(\u003Cspan class=\"hljs-params\">self, table: \u003Cspan class=\"hljs-type\">Dict\u003C/span>, table_number: \u003Cspan class=\"hljs-built_in\">int\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Dict\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Check if table considers responsive design needs&quot;&quot;&quot;\u003C/span>\n        result = {\u003Cspan class=\"hljs-string\">&#x27;score&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">5\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>: [], \u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>: []}\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> table[\u003Cspan class=\"hljs-string\">&#x27;column_count&#x27;\u003C/span>] &gt; \u003Cspan class=\"hljs-number\">4\u003C/span>:\n            result[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">f&quot;Table \u003Cspan class=\"hljs-subst\">{table_number}\u003C/span> has \u003Cspan class=\"hljs-subst\">{table[\u003Cspan class=\"hljs-string\">&#x27;column_count&#x27;\u003C/span>]}\u003C/span> columns - consider responsive design for mobile devices&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> result\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">enhance_markdown_accessibility\u003C/span>(\u003Cspan class=\"hljs-params\">self, markdown_content: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, tables: \u003Cspan class=\"hljs-type\">List\u003C/span>[\u003Cspan class=\"hljs-type\">Dict\u003C/span>]\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">str\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Enhance Markdown content with accessibility improvements&quot;&quot;&quot;\u003C/span>\n        lines = markdown_content.split(\u003Cspan class=\"hljs-string\">&#x27;\\n&#x27;\u003C/span>)\n        enhanced_lines = []\n        i = \u003Cspan class=\"hljs-number\">0\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">while\u003C/span> i &lt; \u003Cspan class=\"hljs-built_in\">len\u003C/span>(lines):\n            \u003Cspan class=\"hljs-comment\"># Check if current line starts a table\u003C/span>\n            table_found = \u003Cspan class=\"hljs-literal\">None\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> table \u003Cspan class=\"hljs-keyword\">in\u003C/span> tables:\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> table[\u003Cspan class=\"hljs-string\">&#x27;start_line&#x27;\u003C/span>] &lt;= i &lt; table[\u003Cspan class=\"hljs-string\">&#x27;end_line&#x27;\u003C/span>]:\n                    table_found = table\n                    \u003Cspan class=\"hljs-keyword\">break\u003C/span>\n            \n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> table_found \u003Cspan class=\"hljs-keyword\">and\u003C/span> i == table_found[\u003Cspan class=\"hljs-string\">&#x27;start_line&#x27;\u003C/span>]:\n                \u003Cspan class=\"hljs-comment\"># Add enhanced table\u003C/span>\n                enhanced_table = self.generate_enhanced_table(table_found)\n                enhanced_lines.extend(enhanced_table.split(\u003Cspan class=\"hljs-string\">&#x27;\\n&#x27;\u003C/span>))\n                i = table_found[\u003Cspan class=\"hljs-string\">&#x27;end_line&#x27;\u003C/span>]\n            \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n                enhanced_lines.append(lines[i])\n                i += \u003Cspan class=\"hljs-number\">1\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;\\n&#x27;\u003C/span>.join(enhanced_lines)\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">generate_enhanced_table\u003C/span>(\u003Cspan class=\"hljs-params\">self, table: \u003Cspan class=\"hljs-type\">Dict\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">str\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Generate accessibility-enhanced version of a table&quot;&quot;&quot;\u003C/span>\n        enhanced_content = []\n        \n        \u003Cspan class=\"hljs-comment\"># Add caption if context is available\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> table[\u003Cspan class=\"hljs-string\">&#x27;context_lines&#x27;\u003C/span>]:\n            best_caption = table[\u003Cspan class=\"hljs-string\">&#x27;context_lines&#x27;\u003C/span>][-\u003Cspan class=\"hljs-number\">1\u003C/span>]\n            enhanced_content.append(\u003Cspan class=\"hljs-string\">f&quot;*Table: \u003Cspan class=\"hljs-subst\">{best_caption}\u003C/span>*&quot;\u003C/span>)\n            enhanced_content.append(\u003Cspan class=\"hljs-string\">&quot;&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-comment\"># Add the table content\u003C/span>\n        enhanced_content.append(table[\u003Cspan class=\"hljs-string\">&#x27;content&#x27;\u003C/span>])\n        \n        \u003Cspan class=\"hljs-comment\"># Add table summary for complex tables\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> table[\u003Cspan class=\"hljs-string\">&#x27;row_count&#x27;\u003C/span>] &gt; \u003Cspan class=\"hljs-number\">5\u003C/span> \u003Cspan class=\"hljs-keyword\">or\u003C/span> table[\u003Cspan class=\"hljs-string\">&#x27;column_count&#x27;\u003C/span>] &gt; \u003Cspan class=\"hljs-number\">4\u003C/span>:\n            summary = \u003Cspan class=\"hljs-string\">f&quot;*This table contains \u003Cspan class=\"hljs-subst\">{table[\u003Cspan class=\"hljs-string\">&#x27;row_count&#x27;\u003C/span>]}\u003C/span> rows and \u003Cspan class=\"hljs-subst\">{table[\u003Cspan class=\"hljs-string\">&#x27;column_count&#x27;\u003C/span>]}\u003C/span> columns showing \u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-string\">&#x27;, &#x27;\u003C/span>.join(table[\u003Cspan class=\"hljs-string\">&#x27;columns&#x27;\u003C/span>][:\u003Cspan class=\"hljs-number\">3\u003C/span>])}\u003C/span>\u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-string\">&#x27;...&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(table[\u003Cspan class=\"hljs-string\">&#x27;columns&#x27;\u003C/span>]) &gt; \u003Cspan class=\"hljs-number\">3\u003C/span> \u003Cspan class=\"hljs-keyword\">else\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>}\u003C/span>.*&quot;\u003C/span>\n            enhanced_content.append(\u003Cspan class=\"hljs-string\">&quot;&quot;\u003C/span>)\n            enhanced_content.append(summary)\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;\\n&#x27;\u003C/span>.join(enhanced_content)\n\n\u003Cspan class=\"hljs-comment\"># CSS for accessible table styling\u003C/span>\naccessible_table_css = \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;\n/* Accessible Table Styles */\n.table-container {\n  overflow-x: auto;\n  margin: 1rem 0;\n  border: 1px solid #ddd;\n  border-radius: 4px;\n}\n\n.accessible-table {\n  width: 100%;\n  border-collapse: collapse;\n  font-family: system-ui, sans-serif;\n}\n\n.accessible-table caption {\n  padding: 0.75rem;\n  font-weight: bold;\n  text-align: left;\n  background-color: #f8f9fa;\n  border-bottom: 2px solid #dee2e6;\n}\n\n.accessible-table th,\n.accessible-table td {\n  padding: 0.75rem;\n  text-align: left;\n  border-bottom: 1px solid #dee2e6;\n  vertical-align: top;\n}\n\n.accessible-table th {\n  background-color: #f8f9fa;\n  font-weight: 600;\n  color: #495057;\n}\n\n.accessible-table tbody tr:nth-child(even) {\n  background-color: #f8f9fa;\n}\n\n.accessible-table tbody tr:hover {\n  background-color: #e9ecef;\n}\n\n/* Focus styles for keyboard navigation */\n.accessible-table th:focus,\n.accessible-table td:focus {\n  outline: 2px solid #0066cc;\n  outline-offset: -1px;\n  background-color: #fff3cd;\n}\n\n/* Responsive design */\n@media (max-width: 768px) {\n  .table-container {\n    font-size: 0.875rem;\n  }\n  \n  .accessible-table th,\n  .accessible-table td {\n    padding: 0.5rem;\n  }\n  \n  /* Stack table cells vertically on very small screens */\n  @media (max-width: 480px) {\n    .accessible-table,\n    .accessible-table thead,\n    .accessible-table tbody,\n    .accessible-table th,\n    .accessible-table td,\n    .accessible-table tr {\n      display: block;\n    }\n    \n    .accessible-table thead tr {\n      position: absolute;\n      top: -9999px;\n      left: -9999px;\n    }\n    \n    .accessible-table tr {\n      border: 1px solid #ccc;\n      margin-bottom: 0.5rem;\n    }\n    \n    .accessible-table td {\n      border: none;\n      position: relative;\n      padding-left: 50% !important;\n    }\n    \n    .accessible-table td:before {\n      content: attr(data-label) &quot;: &quot;;\n      position: absolute;\n      left: 6px;\n      width: 45%;\n      padding-right: 10px;\n      white-space: nowrap;\n      font-weight: bold;\n    }\n  }\n}\n\n/* High contrast mode support */\n@media (prefers-contrast: high) {\n  .accessible-table {\n    border: 2px solid;\n  }\n  \n  .accessible-table th,\n  .accessible-table td {\n    border: 1px solid;\n  }\n}\n\n/* Reduced motion support */\n@media (prefers-reduced-motion: reduce) {\n  .accessible-table tbody tr {\n    transition: none;\n  }\n}\n\n/* Print styles */\n@media print {\n  .table-container {\n    overflow: visible;\n    border: none;\n  }\n  \n  .accessible-table {\n    font-size: 10pt;\n  }\n  \n  .accessible-table th,\n  .accessible-table td {\n    padding: 0.25rem;\n  }\n}\n&quot;&quot;&quot;\u003C/span>\n\n\u003Cspan class=\"hljs-comment\"># Usage example\u003C/span>\n\u003Cspan class=\"hljs-keyword\">if\u003C/span> __name__ == \u003Cspan class=\"hljs-string\">&quot;__main__&quot;\u003C/span>:\n    \u003Cspan class=\"hljs-comment\"># Example Markdown content with tables\u003C/span>\n    sample_markdown = \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;\n# Sales Report Q3 2025\n\nThis report shows quarterly performance across our key markets.\n\n## Regional Performance\n\n| Region | Q1 Sales | Q2 Sales | Q3 Sales | Growth |\n|--------|----------|----------|----------|---------|\n| North America | $125,000 | $134,500 | $142,300 | 5.8% |\n| Europe | $98,400 | $103,200 | $115,600 | 12.0% |\n| Asia Pacific | $87,300 | $92,100 | $98,700 | 7.2% |\n\n## Product Categories\n\nPerformance by product category for Q3.\n\n| Category | Units Sold | Revenue | Profit Margin |\n|----------|------------|---------|---------------|\n| Electronics | 1,250 | $89,400 | 22% |\n| Accessories | 2,100 | $45,600 | 35% |\n| Software | 850 | $78,200 | 68% |\n&quot;&quot;&quot;\u003C/span>\n    \n    \u003Cspan class=\"hljs-comment\"># Analyze table accessibility\u003C/span>\n    analyzer = MarkdownTableAccessibilityAnalyzer()\n    results = analyzer.analyze_table_accessibility(sample_markdown)\n    \n    \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">&quot;Table Accessibility Analysis Results:&quot;\u003C/span>)\n    \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;Tables found: \u003Cspan class=\"hljs-subst\">{results[\u003Cspan class=\"hljs-string\">&#x27;tables_found&#x27;\u003C/span>]}\u003C/span>&quot;\u003C/span>)\n    \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;Overall accessibility score: \u003Cspan class=\"hljs-subst\">{results[\u003Cspan class=\"hljs-string\">&#x27;accessibility_score&#x27;\u003C/span>]:\u003Cspan class=\"hljs-number\">.1\u003C/span>f}\u003C/span>/100&quot;\u003C/span>)\n    \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">&quot;\\nIssues found:&quot;\u003C/span>)\n    \u003Cspan class=\"hljs-keyword\">for\u003C/span> issue \u003Cspan class=\"hljs-keyword\">in\u003C/span> results[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>]:\n        \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;  - \u003Cspan class=\"hljs-subst\">{issue}\u003C/span>&quot;\u003C/span>)\n    \n    \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">&quot;\\nRecommendations:&quot;\u003C/span>)\n    \u003Cspan class=\"hljs-keyword\">for\u003C/span> rec \u003Cspan class=\"hljs-keyword\">in\u003C/span> results[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>]:\n        \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;  - \u003Cspan class=\"hljs-subst\">{rec}\u003C/span>&quot;\u003C/span>)\n\u003C/code>\u003C/pre>\u003Ch2 id=\"complex-table-accessibility-patterns\">Complex Table Accessibility Patterns\u003C/h2>\n\u003Ch3 id=\"multi-header-table-structures\">Multi-Header Table Structures\u003C/h3>\n\u003Cp>Handling complex table layouts with multiple header levels:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-markdown\">\u003Cspan class=\"hljs-section\"># Complex Multi-Header Table Example\u003C/span>\n\n\u003Cspan class=\"hljs-section\">## Budget Allocation by Department and Quarter\u003C/span>\n\nThe following table shows detailed budget allocation across departments and fiscal quarters:\n\n\u003Cspan class=\"language-xml\">\u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">div\u003C/span> \u003Cspan class=\"hljs-attr\">class\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;table-container&quot;\u003C/span> \u003Cspan class=\"hljs-attr\">role\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;region&quot;\u003C/span> \u003Cspan class=\"hljs-attr\">aria-labelledby\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;budget-table-caption&quot;\u003C/span>&gt;\u003C/span>\u003C/span>\n\u003Cspan class=\"language-xml\">\u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">table\u003C/span> \u003Cspan class=\"hljs-attr\">class\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;accessible-table&quot;\u003C/span> \u003Cspan class=\"hljs-attr\">id\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;budget-allocation&quot;\u003C/span>&gt;\u003C/span>\u003C/span>\n\u003Cspan class=\"language-xml\">\u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">caption\u003C/span> \u003Cspan class=\"hljs-attr\">id\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;budget-table-caption&quot;\u003C/span>&gt;\u003C/span>\u003C/span>\n  Annual Budget Allocation by Department and Quarter (FY 2025)\n  \u003Cspan class=\"language-xml\">\u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">details\u003C/span> \u003Cspan class=\"hljs-attr\">class\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;table-description&quot;\u003C/span>&gt;\u003C/span>\u003C/span>\n\u003Cspan class=\"hljs-code\">    &lt;summary&gt;Detailed table description&lt;/summary&gt;\n    &lt;p&gt;This table shows budget allocation for four departments (Engineering, Marketing, Sales, Operations) across four fiscal quarters. The table includes planned budget, actual spending, and variance for each department and quarter. Row headers identify departments, and column headers are grouped by quarter with sub-headers for planned, actual, and variance amounts.&lt;/p&gt;\n  &lt;/details&gt;\n&lt;/caption&gt;\n\u003C/span>\n\u003Cspan class=\"language-xml\">\u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">thead\u003C/span>&gt;\u003C/span>\u003C/span>\n  \u003Cspan class=\"language-xml\">\u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">tr\u003C/span>&gt;\u003C/span>\u003C/span>\n\u003Cspan class=\"hljs-code\">    &lt;th scope=&quot;col&quot; rowspan=&quot;2&quot; id=&quot;dept-header&quot;&gt;Department&lt;/th&gt;\n    &lt;th scope=&quot;colgroup&quot; colspan=&quot;3&quot; id=&quot;q1-header&quot;&gt;Q1 FY2025&lt;/th&gt;\n    &lt;th scope=&quot;colgroup&quot; colspan=&quot;3&quot; id=&quot;q2-header&quot;&gt;Q2 FY2025&lt;/th&gt;\n    &lt;th scope=&quot;colgroup&quot; colspan=&quot;3&quot; id=&quot;q3-header&quot;&gt;Q3 FY2025&lt;/th&gt;\n    &lt;th scope=&quot;colgroup&quot; colspan=&quot;3&quot; id=&quot;q4-header&quot;&gt;Q4 FY2025&lt;/th&gt;\n  &lt;/tr&gt;\n  &lt;tr&gt;\n    &lt;th scope=&quot;col&quot; id=&quot;q1-planned&quot; headers=&quot;q1-header&quot;&gt;Planned&lt;/th&gt;\n    &lt;th scope=&quot;col&quot; id=&quot;q1-actual&quot; headers=&quot;q1-header&quot;&gt;Actual&lt;/th&gt;\n    &lt;th scope=&quot;col&quot; id=&quot;q1-variance&quot; headers=&quot;q1-header&quot;&gt;Variance&lt;/th&gt;\n    &lt;th scope=&quot;col&quot; id=&quot;q2-planned&quot; headers=&quot;q2-header&quot;&gt;Planned&lt;/th&gt;\n    &lt;th scope=&quot;col&quot; id=&quot;q2-actual&quot; headers=&quot;q2-header&quot;&gt;Actual&lt;/th&gt;\n    &lt;th scope=&quot;col&quot; id=&quot;q2-variance&quot; headers=&quot;q2-header&quot;&gt;Variance&lt;/th&gt;\n    &lt;th scope=&quot;col&quot; id=&quot;q3-planned&quot; headers=&quot;q3-header&quot;&gt;Planned&lt;/th&gt;\n    &lt;th scope=&quot;col&quot; id=&quot;q3-actual&quot; headers=&quot;q3-header&quot;&gt;Actual&lt;/th&gt;\n    &lt;th scope=&quot;col&quot; id=&quot;q3-variance&quot; headers=&quot;q3-header&quot;&gt;Variance&lt;/th&gt;\n    &lt;th scope=&quot;col&quot; id=&quot;q4-planned&quot; headers=&quot;q4-header&quot;&gt;Planned&lt;/th&gt;\n    &lt;th scope=&quot;col&quot; id=&quot;q4-actual&quot; headers=&quot;q4-header&quot;&gt;Actual&lt;/th&gt;\n    &lt;th scope=&quot;col&quot; id=&quot;q4-variance&quot; headers=&quot;q4-header&quot;&gt;Variance&lt;/th&gt;\n  &lt;/tr&gt;\n&lt;/thead&gt;\n\u003C/span>\n\u003Cspan class=\"language-xml\">\u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">tbody\u003C/span>&gt;\u003C/span>\u003C/span>\n  \u003Cspan class=\"language-xml\">\u003Cspan class=\"hljs-tag\">&lt;\u003Cspan class=\"hljs-name\">tr\u003C/span>&gt;\u003C/span>\u003C/span>\n\u003Cspan class=\"hljs-code\">    &lt;th scope=&quot;row&quot; id=&quot;engineering&quot; headers=&quot;dept-header&quot;&gt;Engineering&lt;/th&gt;\n    &lt;td headers=&quot;q1-planned engineering&quot;&gt;$450,000&lt;/td&gt;\n    &lt;td headers=&quot;q1-actual engineering&quot;&gt;$442,100&lt;/td&gt;\n    &lt;td headers=&quot;q1-variance engineering&quot; class=&quot;positive&quot;&gt;-$7,900&lt;/td&gt;\n    &lt;td headers=&quot;q2-planned engineering&quot;&gt;$470,000&lt;/td&gt;\n    &lt;td headers=&quot;q2-actual engineering&quot;&gt;$481,200&lt;/td&gt;\n    &lt;td headers=&quot;q2-variance engineering&quot; class=&quot;negative&quot;&gt;+$11,200&lt;/td&gt;\n    &lt;td headers=&quot;q3-planned engineering&quot;&gt;$485,000&lt;/td&gt;\n    &lt;td headers=&quot;q3-actual engineering&quot;&gt;$479,800&lt;/td&gt;\n    &lt;td headers=&quot;q3-variance engineering&quot; class=&quot;positive&quot;&gt;-$5,200&lt;/td&gt;\n    &lt;td headers=&quot;q4-planned engineering&quot;&gt;$520,000&lt;/td&gt;\n    &lt;td headers=&quot;q4-actual engineering&quot;&gt;$518,900&lt;/td&gt;\n    &lt;td headers=&quot;q4-variance engineering&quot; class=&quot;positive&quot;&gt;-$1,100&lt;/td&gt;\n  &lt;/tr&gt;\n  \n  &lt;tr&gt;\n    &lt;th scope=&quot;row&quot; id=&quot;marketing&quot; headers=&quot;dept-header&quot;&gt;Marketing&lt;/th&gt;\n    &lt;td headers=&quot;q1-planned marketing&quot;&gt;$125,000&lt;/td&gt;\n    &lt;td headers=&quot;q1-actual marketing&quot;&gt;$132,400&lt;/td&gt;\n    &lt;td headers=&quot;q1-variance marketing&quot; class=&quot;negative&quot;&gt;+$7,400&lt;/td&gt;\n    &lt;td headers=&quot;q2-planned marketing&quot;&gt;$140,000&lt;/td&gt;\n    &lt;td headers=&quot;q2-actual marketing&quot;&gt;$138,700&lt;/td&gt;\n    &lt;td headers=&quot;q2-variance marketing&quot; class=&quot;positive&quot;&gt;-$1,300&lt;/td&gt;\n    &lt;td headers=&quot;q3-planned marketing&quot;&gt;$155,000&lt;/td&gt;\n    &lt;td headers=&quot;q3-actual marketing&quot;&gt;$159,200&lt;/td&gt;\n    &lt;td headers=&quot;q3-variance marketing&quot; class=&quot;negative&quot;&gt;+$4,200&lt;/td&gt;\n    &lt;td headers=&quot;q4-planned marketing&quot;&gt;$180,000&lt;/td&gt;\n    &lt;td headers=&quot;q4-actual marketing&quot;&gt;$177,100&lt;/td&gt;\n    &lt;td headers=&quot;q4-variance marketing&quot; class=&quot;positive&quot;&gt;-$2,900&lt;/td&gt;\n  &lt;/tr&gt;\n&lt;/tbody&gt;\n&lt;/table&gt;\n&lt;/div&gt;\n\u003C/span>\n\u003Cspan class=\"hljs-emphasis\">*Note: Variance shown as positive (+) for over-budget, negative (-) for under-budget.*\u003C/span>\n\u003C/code>\u003C/pre>\u003Ch3 id=\"data-table-navigation-and-interaction\">Data Table Navigation and Interaction\u003C/h3>\n\u003Cp>Creating accessible interactive table features:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-javascript\">\u003Cspan class=\"hljs-comment\">// accessible-table-controls.js - Interactive table accessibility features\u003C/span>\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">AccessibleTableController\u003C/span> {\n    \u003Cspan class=\"hljs-title function_\">constructor\u003C/span>(\u003Cspan class=\"hljs-params\">tableElement, options = {}\u003C/span>) {\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">table\u003C/span> = tableElement;\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">options\u003C/span> = {\n            \u003Cspan class=\"hljs-attr\">sortable\u003C/span>: \u003Cspan class=\"hljs-literal\">true\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">filterable\u003C/span>: \u003Cspan class=\"hljs-literal\">true\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">searchable\u003C/span>: \u003Cspan class=\"hljs-literal\">true\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">exportable\u003C/span>: \u003Cspan class=\"hljs-literal\">false\u003C/span>,\n            ...options\n        };\n        \n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">currentSort\u003C/span> = { \u003Cspan class=\"hljs-attr\">column\u003C/span>: -\u003Cspan class=\"hljs-number\">1\u003C/span>, \u003Cspan class=\"hljs-attr\">direction\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;none&#x27;\u003C/span> };\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">filters\u003C/span> = \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">Map\u003C/span>();\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">searchTerm\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>;\n        \n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">init\u003C/span>();\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">init\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">addAccessibilityFeatures\u003C/span>();\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">createControls\u003C/span>();\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">setupKeyboardNavigation\u003C/span>();\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">announceTableInfo\u003C/span>();\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">addAccessibilityFeatures\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n        \u003Cspan class=\"hljs-comment\">// Add ARIA attributes if missing\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">table\u003C/span>.\u003Cspan class=\"hljs-title function_\">getAttribute\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;role&#x27;\u003C/span>)) {\n            \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">table\u003C/span>.\u003Cspan class=\"hljs-title function_\">setAttribute\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;role&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;table&#x27;\u003C/span>);\n        }\n        \n        \u003Cspan class=\"hljs-comment\">// Add table summary\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">table\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelector\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;caption&#x27;\u003C/span>)) {\n            \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">addTableSummary\u003C/span>();\n        }\n        \n        \u003Cspan class=\"hljs-comment\">// Enhance headers with proper scope\u003C/span>\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">enhanceHeaders\u003C/span>();\n        \n        \u003Cspan class=\"hljs-comment\">// Add keyboard navigation support\u003C/span>\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">table\u003C/span>.\u003Cspan class=\"hljs-title function_\">setAttribute\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;tabindex&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;0&#x27;\u003C/span>);\n        \n        \u003Cspan class=\"hljs-comment\">// Add live region for announcements\u003C/span>\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">createLiveRegion\u003C/span>();\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">addTableSummary\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> rows = \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">table\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelectorAll\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;tbody tr&#x27;\u003C/span>).\u003Cspan class=\"hljs-property\">length\u003C/span>;\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> cols = \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">table\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelectorAll\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;thead th&#x27;\u003C/span>).\u003Cspan class=\"hljs-property\">length\u003C/span>;\n        \n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> caption = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">createElement\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;caption&#x27;\u003C/span>);\n        caption.\u003Cspan class=\"hljs-property\">innerHTML\u003C/span> = \u003Cspan class=\"hljs-string\">`\n            &lt;div class=&quot;table-summary&quot;&gt;\n                &lt;span class=&quot;sr-only&quot;&gt;Data table with \u003Cspan class=\"hljs-subst\">${rows}\u003C/span> rows and \u003Cspan class=\"hljs-subst\">${cols}\u003C/span> columns.&lt;/span&gt;\n                \u003Cspan class=\"hljs-subst\">${\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.generateTableDescription()}\u003C/span>\n            &lt;/div&gt;\n        `\u003C/span>;\n        \n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">table\u003C/span>.\u003Cspan class=\"hljs-title function_\">insertBefore\u003C/span>(caption, \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">table\u003C/span>.\u003Cspan class=\"hljs-property\">firstChild\u003C/span>);\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">generateTableDescription\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> headers = \u003Cspan class=\"hljs-title class_\">Array\u003C/span>.\u003Cspan class=\"hljs-title function_\">from\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">table\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelectorAll\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;thead th&#x27;\u003C/span>))\n                           .\u003Cspan class=\"hljs-title function_\">map\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">th\u003C/span> =&gt;\u003C/span> th.\u003Cspan class=\"hljs-property\">textContent\u003C/span>.\u003Cspan class=\"hljs-title function_\">trim\u003C/span>());\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-string\">`Column headers: \u003Cspan class=\"hljs-subst\">${headers.join(\u003Cspan class=\"hljs-string\">&#x27;, &#x27;\u003C/span>)}\u003C/span>.`\u003C/span>;\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">enhanceHeaders\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n        \u003Cspan class=\"hljs-comment\">// Add scope attributes to headers\u003C/span>\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">table\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelectorAll\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;thead th&#x27;\u003C/span>).\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">th, index\u003C/span>) =&gt;\u003C/span> {\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!th.\u003Cspan class=\"hljs-title function_\">getAttribute\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;scope&#x27;\u003C/span>)) {\n                th.\u003Cspan class=\"hljs-title function_\">setAttribute\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;scope&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;col&#x27;\u003C/span>);\n            }\n            \n            \u003Cspan class=\"hljs-comment\">// Add unique IDs for complex tables\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!th.\u003Cspan class=\"hljs-property\">id\u003C/span>) {\n                th.\u003Cspan class=\"hljs-property\">id\u003C/span> = \u003Cspan class=\"hljs-string\">`col-header-\u003Cspan class=\"hljs-subst\">${index}\u003C/span>`\u003C/span>;\n            }\n        });\n        \n        \u003Cspan class=\"hljs-comment\">// Add scope to row headers (first column cells)\u003C/span>\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">table\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelectorAll\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;tbody tr&#x27;\u003C/span>).\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">tr\u003C/span> =&gt;\u003C/span> {\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> firstCell = tr.\u003Cspan class=\"hljs-title function_\">querySelector\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;td&#x27;\u003C/span>);\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (firstCell &amp;&amp; \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">isRowHeader\u003C/span>(firstCell)) {\n                firstCell.\u003Cspan class=\"hljs-property\">tagName\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;TH&#x27;\u003C/span>;\n                firstCell.\u003Cspan class=\"hljs-title function_\">setAttribute\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;scope&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;row&#x27;\u003C/span>);\n            }\n        });\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">isRowHeader\u003C/span>(\u003Cspan class=\"hljs-params\">cell\u003C/span>) {\n        \u003Cspan class=\"hljs-comment\">// Heuristic to determine if a cell should be a row header\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> text = cell.\u003Cspan class=\"hljs-property\">textContent\u003C/span>.\u003Cspan class=\"hljs-title function_\">trim\u003C/span>();\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> isNumeric = \u003Cspan class=\"hljs-regexp\">/^\\d+\\.?\\d*$/\u003C/span>.\u003Cspan class=\"hljs-title function_\">test\u003C/span>(text);\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> isShort = text.\u003Cspan class=\"hljs-property\">length\u003C/span> &lt; \u003Cspan class=\"hljs-number\">50\u003C/span>;\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> !isNumeric &amp;&amp; isShort;\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">createControls\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> controlsContainer = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">createElement\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;div&#x27;\u003C/span>);\n        controlsContainer.\u003Cspan class=\"hljs-property\">className\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;table-controls&#x27;\u003C/span>;\n        controlsContainer.\u003Cspan class=\"hljs-title function_\">setAttribute\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;role&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;toolbar&#x27;\u003C/span>);\n        controlsContainer.\u003Cspan class=\"hljs-title function_\">setAttribute\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;aria-label&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;Table interaction controls&#x27;\u003C/span>);\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">options\u003C/span>.\u003Cspan class=\"hljs-property\">sortable\u003C/span>) {\n            \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">addSortControls\u003C/span>(controlsContainer);\n        }\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">options\u003C/span>.\u003Cspan class=\"hljs-property\">searchable\u003C/span>) {\n            \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">addSearchControl\u003C/span>(controlsContainer);\n        }\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">options\u003C/span>.\u003Cspan class=\"hljs-property\">filterable\u003C/span>) {\n            \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">addFilterControls\u003C/span>(controlsContainer);\n        }\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">options\u003C/span>.\u003Cspan class=\"hljs-property\">exportable\u003C/span>) {\n            \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">addExportControl\u003C/span>(controlsContainer);\n        }\n        \n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">table\u003C/span>.\u003Cspan class=\"hljs-property\">parentNode\u003C/span>.\u003Cspan class=\"hljs-title function_\">insertBefore\u003C/span>(controlsContainer, \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">table\u003C/span>);\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">addSortControls\u003C/span>(\u003Cspan class=\"hljs-params\">container\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> sortGroup = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">createElement\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;div&#x27;\u003C/span>);\n        sortGroup.\u003Cspan class=\"hljs-property\">className\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;control-group&#x27;\u003C/span>;\n        sortGroup.\u003Cspan class=\"hljs-title function_\">setAttribute\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;role&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;group&#x27;\u003C/span>);\n        sortGroup.\u003Cspan class=\"hljs-title function_\">setAttribute\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;aria-label&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;Sort controls&#x27;\u003C/span>);\n        \n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> sortLabel = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">createElement\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;label&#x27;\u003C/span>);\n        sortLabel.\u003Cspan class=\"hljs-property\">textContent\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;Sort by:&#x27;\u003C/span>;\n        sortLabel.\u003Cspan class=\"hljs-property\">className\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;control-label&#x27;\u003C/span>;\n        \n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> sortSelect = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">createElement\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;select&#x27;\u003C/span>);\n        sortSelect.\u003Cspan class=\"hljs-property\">id\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;table-sort-select&#x27;\u003C/span>;\n        sortSelect.\u003Cspan class=\"hljs-title function_\">setAttribute\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;aria-describedby&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;sort-help&#x27;\u003C/span>);\n        \n        \u003Cspan class=\"hljs-comment\">// Add column options\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> defaultOption = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">createElement\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;option&#x27;\u003C/span>);\n        defaultOption.\u003Cspan class=\"hljs-property\">value\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>;\n        defaultOption.\u003Cspan class=\"hljs-property\">textContent\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;Default order&#x27;\u003C/span>;\n        sortSelect.\u003Cspan class=\"hljs-title function_\">appendChild\u003C/span>(defaultOption);\n        \n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">table\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelectorAll\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;thead th&#x27;\u003C/span>).\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">th, index\u003C/span>) =&gt;\u003C/span> {\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> option = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">createElement\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;option&#x27;\u003C/span>);\n            option.\u003Cspan class=\"hljs-property\">value\u003C/span> = index;\n            option.\u003Cspan class=\"hljs-property\">textContent\u003C/span> = th.\u003Cspan class=\"hljs-property\">textContent\u003C/span>.\u003Cspan class=\"hljs-title function_\">trim\u003C/span>();\n            sortSelect.\u003Cspan class=\"hljs-title function_\">appendChild\u003C/span>(option);\n        });\n        \n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> sortDirection = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">createElement\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;button&#x27;\u003C/span>);\n        sortDirection.\u003Cspan class=\"hljs-property\">type\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;button&#x27;\u003C/span>;\n        sortDirection.\u003Cspan class=\"hljs-property\">className\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;sort-direction&#x27;\u003C/span>;\n        sortDirection.\u003Cspan class=\"hljs-property\">innerHTML\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;&lt;span aria-hidden=&quot;true&quot;&gt;⇅&lt;/span&gt; Sort direction&#x27;\u003C/span>;\n        sortDirection.\u003Cspan class=\"hljs-title function_\">setAttribute\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;aria-pressed&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;false&#x27;\u003C/span>);\n        \n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> helpText = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">createElement\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;div&#x27;\u003C/span>);\n        helpText.\u003Cspan class=\"hljs-property\">id\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;sort-help&#x27;\u003C/span>;\n        helpText.\u003Cspan class=\"hljs-property\">className\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;help-text&#x27;\u003C/span>;\n        helpText.\u003Cspan class=\"hljs-property\">textContent\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;Select a column to sort by, then choose ascending or descending order.&#x27;\u003C/span>;\n        \n        sortLabel.\u003Cspan class=\"hljs-title function_\">setAttribute\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;for&#x27;\u003C/span>, sortSelect.\u003Cspan class=\"hljs-property\">id\u003C/span>);\n        \n        sortSelect.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;change&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">e\u003C/span>) =&gt;\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">handleSort\u003C/span>(e.\u003Cspan class=\"hljs-property\">target\u003C/span>.\u003Cspan class=\"hljs-property\">value\u003C/span>));\n        sortDirection.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;click&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">toggleSortDirection\u003C/span>());\n        \n        sortGroup.\u003Cspan class=\"hljs-title function_\">appendChild\u003C/span>(sortLabel);\n        sortGroup.\u003Cspan class=\"hljs-title function_\">appendChild\u003C/span>(sortSelect);\n        sortGroup.\u003Cspan class=\"hljs-title function_\">appendChild\u003C/span>(sortDirection);\n        sortGroup.\u003Cspan class=\"hljs-title function_\">appendChild\u003C/span>(helpText);\n        \n        container.\u003Cspan class=\"hljs-title function_\">appendChild\u003C/span>(sortGroup);\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">addSearchControl\u003C/span>(\u003Cspan class=\"hljs-params\">container\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> searchGroup = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">createElement\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;div&#x27;\u003C/span>);\n        searchGroup.\u003Cspan class=\"hljs-property\">className\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;control-group&#x27;\u003C/span>;\n        searchGroup.\u003Cspan class=\"hljs-title function_\">setAttribute\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;role&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;search&#x27;\u003C/span>);\n        \n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> searchLabel = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">createElement\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;label&#x27;\u003C/span>);\n        searchLabel.\u003Cspan class=\"hljs-property\">textContent\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;Search table:&#x27;\u003C/span>;\n        searchLabel.\u003Cspan class=\"hljs-property\">className\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;control-label&#x27;\u003C/span>;\n        \n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> searchInput = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">createElement\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;input&#x27;\u003C/span>);\n        searchInput.\u003Cspan class=\"hljs-property\">type\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;search&#x27;\u003C/span>;\n        searchInput.\u003Cspan class=\"hljs-property\">id\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;table-search&#x27;\u003C/span>;\n        searchInput.\u003Cspan class=\"hljs-title function_\">setAttribute\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;aria-describedby&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;search-help&#x27;\u003C/span>);\n        searchInput.\u003Cspan class=\"hljs-property\">placeholder\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;Enter search terms...&#x27;\u003C/span>;\n        \n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> searchHelp = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">createElement\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;div&#x27;\u003C/span>);\n        searchHelp.\u003Cspan class=\"hljs-property\">id\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;search-help&#x27;\u003C/span>;\n        searchHelp.\u003Cspan class=\"hljs-property\">className\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;help-text&#x27;\u003C/span>;\n        searchHelp.\u003Cspan class=\"hljs-property\">textContent\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;Search will filter table rows based on content matches.&#x27;\u003C/span>;\n        \n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> clearButton = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">createElement\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;button&#x27;\u003C/span>);\n        clearButton.\u003Cspan class=\"hljs-property\">type\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;button&#x27;\u003C/span>;\n        clearButton.\u003Cspan class=\"hljs-property\">className\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;clear-search&#x27;\u003C/span>;\n        clearButton.\u003Cspan class=\"hljs-property\">textContent\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;Clear&#x27;\u003C/span>;\n        clearButton.\u003Cspan class=\"hljs-title function_\">setAttribute\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;aria-label&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;Clear search&#x27;\u003C/span>);\n        \n        searchLabel.\u003Cspan class=\"hljs-title function_\">setAttribute\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;for&#x27;\u003C/span>, searchInput.\u003Cspan class=\"hljs-property\">id\u003C/span>);\n        \n        searchInput.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;input&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">e\u003C/span>) =&gt;\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">handleSearch\u003C/span>(e.\u003Cspan class=\"hljs-property\">target\u003C/span>.\u003Cspan class=\"hljs-property\">value\u003C/span>));\n        clearButton.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;click&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">clearSearch\u003C/span>());\n        \n        searchGroup.\u003Cspan class=\"hljs-title function_\">appendChild\u003C/span>(searchLabel);\n        searchGroup.\u003Cspan class=\"hljs-title function_\">appendChild\u003C/span>(searchInput);\n        searchGroup.\u003Cspan class=\"hljs-title function_\">appendChild\u003C/span>(clearButton);\n        searchGroup.\u003Cspan class=\"hljs-title function_\">appendChild\u003C/span>(searchHelp);\n        \n        container.\u003Cspan class=\"hljs-title function_\">appendChild\u003C/span>(searchGroup);\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">setupKeyboardNavigation\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">table\u003C/span>.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;keydown&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">e\u003C/span>) =&gt;\u003C/span> {\n            \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">handleTableKeyNavigation\u003C/span>(e);\n        });\n        \n        \u003Cspan class=\"hljs-comment\">// Make table cells focusable for keyboard navigation\u003C/span>\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">table\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelectorAll\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;th, td&#x27;\u003C/span>).\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">cell\u003C/span> =&gt;\u003C/span> {\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!cell.\u003Cspan class=\"hljs-title function_\">getAttribute\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;tabindex&#x27;\u003C/span>)) {\n                cell.\u003Cspan class=\"hljs-title function_\">setAttribute\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;tabindex&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;-1&#x27;\u003C/span>);\n            }\n        });\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">handleTableKeyNavigation\u003C/span>(\u003Cspan class=\"hljs-params\">event\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> currentCell = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">activeElement\u003C/span>;\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!currentCell.\u003Cspan class=\"hljs-title function_\">matches\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;th, td&#x27;\u003C/span>)) {\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span>;\n        }\n        \n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> currentRow = currentCell.\u003Cspan class=\"hljs-property\">parentElement\u003C/span>;\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> allRows = \u003Cspan class=\"hljs-title class_\">Array\u003C/span>.\u003Cspan class=\"hljs-title function_\">from\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">table\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelectorAll\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;tr&#x27;\u003C/span>));\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> currentRowIndex = allRows.\u003Cspan class=\"hljs-title function_\">indexOf\u003C/span>(currentRow);\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> currentCellIndex = \u003Cspan class=\"hljs-title class_\">Array\u003C/span>.\u003Cspan class=\"hljs-title function_\">from\u003C/span>(currentRow.\u003Cspan class=\"hljs-property\">children\u003C/span>).\u003Cspan class=\"hljs-title function_\">indexOf\u003C/span>(currentCell);\n        \n        \u003Cspan class=\"hljs-keyword\">let\u003C/span> targetCell = \u003Cspan class=\"hljs-literal\">null\u003C/span>;\n        \n        \u003Cspan class=\"hljs-keyword\">switch\u003C/span> (event.\u003Cspan class=\"hljs-property\">key\u003C/span>) {\n            \u003Cspan class=\"hljs-keyword\">case\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;ArrowUp&#x27;\u003C/span>:\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> (currentRowIndex &gt; \u003Cspan class=\"hljs-number\">0\u003C/span>) {\n                    \u003Cspan class=\"hljs-keyword\">const\u003C/span> targetRow = allRows[currentRowIndex - \u003Cspan class=\"hljs-number\">1\u003C/span>];\n                    targetCell = targetRow.\u003Cspan class=\"hljs-property\">children\u003C/span>[currentCellIndex];\n                }\n                \u003Cspan class=\"hljs-keyword\">break\u003C/span>;\n                \n            \u003Cspan class=\"hljs-keyword\">case\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;ArrowDown&#x27;\u003C/span>:\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> (currentRowIndex &lt; allRows.\u003Cspan class=\"hljs-property\">length\u003C/span> - \u003Cspan class=\"hljs-number\">1\u003C/span>) {\n                    \u003Cspan class=\"hljs-keyword\">const\u003C/span> targetRow = allRows[currentRowIndex + \u003Cspan class=\"hljs-number\">1\u003C/span>];\n                    targetCell = targetRow.\u003Cspan class=\"hljs-property\">children\u003C/span>[currentCellIndex];\n                }\n                \u003Cspan class=\"hljs-keyword\">break\u003C/span>;\n                \n            \u003Cspan class=\"hljs-keyword\">case\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;ArrowLeft&#x27;\u003C/span>:\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> (currentCellIndex &gt; \u003Cspan class=\"hljs-number\">0\u003C/span>) {\n                    targetCell = currentRow.\u003Cspan class=\"hljs-property\">children\u003C/span>[currentCellIndex - \u003Cspan class=\"hljs-number\">1\u003C/span>];\n                }\n                \u003Cspan class=\"hljs-keyword\">break\u003C/span>;\n                \n            \u003Cspan class=\"hljs-keyword\">case\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;ArrowRight&#x27;\u003C/span>:\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> (currentCellIndex &lt; currentRow.\u003Cspan class=\"hljs-property\">children\u003C/span>.\u003Cspan class=\"hljs-property\">length\u003C/span> - \u003Cspan class=\"hljs-number\">1\u003C/span>) {\n                    targetCell = currentRow.\u003Cspan class=\"hljs-property\">children\u003C/span>[currentCellIndex + \u003Cspan class=\"hljs-number\">1\u003C/span>];\n                }\n                \u003Cspan class=\"hljs-keyword\">break\u003C/span>;\n                \n            \u003Cspan class=\"hljs-keyword\">case\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;Home&#x27;\u003C/span>:\n                targetCell = currentRow.\u003Cspan class=\"hljs-property\">children\u003C/span>[\u003Cspan class=\"hljs-number\">0\u003C/span>];\n                \u003Cspan class=\"hljs-keyword\">break\u003C/span>;\n                \n            \u003Cspan class=\"hljs-keyword\">case\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;End&#x27;\u003C/span>:\n                targetCell = currentRow.\u003Cspan class=\"hljs-property\">children\u003C/span>[currentRow.\u003Cspan class=\"hljs-property\">children\u003C/span>.\u003Cspan class=\"hljs-property\">length\u003C/span> - \u003Cspan class=\"hljs-number\">1\u003C/span>];\n                \u003Cspan class=\"hljs-keyword\">break\u003C/span>;\n        }\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (targetCell) {\n            event.\u003Cspan class=\"hljs-title function_\">preventDefault\u003C/span>();\n            targetCell.\u003Cspan class=\"hljs-title function_\">focus\u003C/span>();\n            \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">announceNavigation\u003C/span>(targetCell);\n        }\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">createLiveRegion\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">liveRegion\u003C/span> = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">createElement\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;div&#x27;\u003C/span>);\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">liveRegion\u003C/span>.\u003Cspan class=\"hljs-property\">className\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;sr-only&#x27;\u003C/span>;\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">liveRegion\u003C/span>.\u003Cspan class=\"hljs-title function_\">setAttribute\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;aria-live&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;polite&#x27;\u003C/span>);\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">liveRegion\u003C/span>.\u003Cspan class=\"hljs-title function_\">setAttribute\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;aria-atomic&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;true&#x27;\u003C/span>);\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">liveRegion\u003C/span>.\u003Cspan class=\"hljs-property\">id\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;table-announcements&#x27;\u003C/span>;\n        \n        \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">body\u003C/span>.\u003Cspan class=\"hljs-title function_\">appendChild\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">liveRegion\u003C/span>);\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">announce\u003C/span>(\u003Cspan class=\"hljs-params\">message\u003C/span>) {\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">liveRegion\u003C/span>.\u003Cspan class=\"hljs-property\">textContent\u003C/span> = message;\n        \n        \u003Cspan class=\"hljs-comment\">// Clear after a delay to avoid repeated announcements\u003C/span>\n        \u003Cspan class=\"hljs-built_in\">setTimeout\u003C/span>(\u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> {\n            \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">liveRegion\u003C/span>.\u003Cspan class=\"hljs-property\">textContent\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>;\n        }, \u003Cspan class=\"hljs-number\">1000\u003C/span>);\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">announceTableInfo\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> rows = \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">table\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelectorAll\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;tbody tr&#x27;\u003C/span>).\u003Cspan class=\"hljs-property\">length\u003C/span>;\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> cols = \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">table\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelectorAll\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;thead th&#x27;\u003C/span>).\u003Cspan class=\"hljs-property\">length\u003C/span>;\n        \n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">announce\u003C/span>(\u003Cspan class=\"hljs-string\">`Table loaded with \u003Cspan class=\"hljs-subst\">${rows}\u003C/span> data rows and \u003Cspan class=\"hljs-subst\">${cols}\u003C/span> columns. Use arrow keys to navigate cells.`\u003C/span>);\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">announceNavigation\u003C/span>(\u003Cspan class=\"hljs-params\">cell\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> cellContent = cell.\u003Cspan class=\"hljs-property\">textContent\u003C/span>.\u003Cspan class=\"hljs-title function_\">trim\u003C/span>();\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> rowHeader = cell.\u003Cspan class=\"hljs-title function_\">closest\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;tr&#x27;\u003C/span>).\u003Cspan class=\"hljs-title function_\">querySelector\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;th[scope=&quot;row&quot;]&#x27;\u003C/span>);\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> colHeader = \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">table\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelector\u003C/span>(\u003Cspan class=\"hljs-string\">`thead th:nth-child(\u003Cspan class=\"hljs-subst\">${\u003Cspan class=\"hljs-built_in\">Array\u003C/span>.\u003Cspan class=\"hljs-keyword\">from\u003C/span>(cell.parentElement.children).indexOf(cell) + \u003Cspan class=\"hljs-number\">1\u003C/span>}\u003C/span>)`\u003C/span>);\n        \n        \u003Cspan class=\"hljs-keyword\">let\u003C/span> announcement = cellContent;\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (rowHeader &amp;&amp; colHeader) {\n            announcement = \u003Cspan class=\"hljs-string\">`\u003Cspan class=\"hljs-subst\">${colHeader.textContent.trim()}\u003C/span>, \u003Cspan class=\"hljs-subst\">${rowHeader.textContent.trim()}\u003C/span>: \u003Cspan class=\"hljs-subst\">${cellContent}\u003C/span>`\u003C/span>;\n        } \u003Cspan class=\"hljs-keyword\">else\u003C/span> \u003Cspan class=\"hljs-keyword\">if\u003C/span> (colHeader) {\n            announcement = \u003Cspan class=\"hljs-string\">`\u003Cspan class=\"hljs-subst\">${colHeader.textContent.trim()}\u003C/span>: \u003Cspan class=\"hljs-subst\">${cellContent}\u003C/span>`\u003C/span>;\n        }\n        \n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">announce\u003C/span>(announcement);\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">handleSort\u003C/span>(\u003Cspan class=\"hljs-params\">columnIndex\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (columnIndex === \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>) {\n            \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">resetSort\u003C/span>();\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span>;\n        }\n        \n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> column = \u003Cspan class=\"hljs-built_in\">parseInt\u003C/span>(columnIndex);\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">currentSort\u003C/span> = {\n            \u003Cspan class=\"hljs-attr\">column\u003C/span>: column,\n            \u003Cspan class=\"hljs-attr\">direction\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">currentSort\u003C/span>.\u003Cspan class=\"hljs-property\">column\u003C/span> === column ? \n                (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">currentSort\u003C/span>.\u003Cspan class=\"hljs-property\">direction\u003C/span> === \u003Cspan class=\"hljs-string\">&#x27;asc&#x27;\u003C/span> ? \u003Cspan class=\"hljs-string\">&#x27;desc&#x27;\u003C/span> : \u003Cspan class=\"hljs-string\">&#x27;asc&#x27;\u003C/span>) : \u003Cspan class=\"hljs-string\">&#x27;asc&#x27;\u003C/span>\n        };\n        \n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">sortTable\u003C/span>(column, \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">currentSort\u003C/span>.\u003Cspan class=\"hljs-property\">direction\u003C/span>);\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">announce\u003C/span>(\u003Cspan class=\"hljs-string\">`Table sorted by \u003Cspan class=\"hljs-subst\">${\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.getColumnHeader(column)}\u003C/span> in \u003Cspan class=\"hljs-subst\">${\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.currentSort.direction}\u003C/span>ending order.`\u003C/span>);\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">sortTable\u003C/span>(\u003Cspan class=\"hljs-params\">columnIndex, direction\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> tbody = \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">table\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelector\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;tbody&#x27;\u003C/span>);\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> rows = \u003Cspan class=\"hljs-title class_\">Array\u003C/span>.\u003Cspan class=\"hljs-title function_\">from\u003C/span>(tbody.\u003Cspan class=\"hljs-title function_\">querySelectorAll\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;tr&#x27;\u003C/span>));\n        \n        rows.\u003Cspan class=\"hljs-title function_\">sort\u003C/span>(\u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">a, b\u003C/span>) =&gt;\u003C/span> {\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> aCell = a.\u003Cspan class=\"hljs-property\">children\u003C/span>[columnIndex];\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> bCell = b.\u003Cspan class=\"hljs-property\">children\u003C/span>[columnIndex];\n            \n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> aValue = \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">getCellSortValue\u003C/span>(aCell);\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> bValue = \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">getCellSortValue\u003C/span>(bCell);\n            \n            \u003Cspan class=\"hljs-keyword\">let\u003C/span> result = \u003Cspan class=\"hljs-number\">0\u003C/span>;\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (aValue &lt; bValue) result = -\u003Cspan class=\"hljs-number\">1\u003C/span>;\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (aValue &gt; bValue) result = \u003Cspan class=\"hljs-number\">1\u003C/span>;\n            \n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> direction === \u003Cspan class=\"hljs-string\">&#x27;desc&#x27;\u003C/span> ? -result : result;\n        });\n        \n        \u003Cspan class=\"hljs-comment\">// Reorder rows in DOM\u003C/span>\n        rows.\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">row\u003C/span> =&gt;\u003C/span> tbody.\u003Cspan class=\"hljs-title function_\">appendChild\u003C/span>(row));\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">getCellSortValue\u003C/span>(\u003Cspan class=\"hljs-params\">cell\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> text = cell.\u003Cspan class=\"hljs-property\">textContent\u003C/span>.\u003Cspan class=\"hljs-title function_\">trim\u003C/span>();\n        \n        \u003Cspan class=\"hljs-comment\">// Try to parse as number\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> numericValue = \u003Cspan class=\"hljs-built_in\">parseFloat\u003C/span>(text.\u003Cspan class=\"hljs-title function_\">replace\u003C/span>(\u003Cspan class=\"hljs-regexp\">/[$,%]/g\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>));\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!\u003Cspan class=\"hljs-built_in\">isNaN\u003C/span>(numericValue)) {\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> numericValue;\n        }\n        \n        \u003Cspan class=\"hljs-comment\">// Try to parse as date\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> dateValue = \u003Cspan class=\"hljs-title class_\">Date\u003C/span>.\u003Cspan class=\"hljs-title function_\">parse\u003C/span>(text);\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!\u003Cspan class=\"hljs-built_in\">isNaN\u003C/span>(dateValue)) {\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> dateValue;\n        }\n        \n        \u003Cspan class=\"hljs-comment\">// Return as lowercase string\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> text.\u003Cspan class=\"hljs-title function_\">toLowerCase\u003C/span>();\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">getColumnHeader\u003C/span>(\u003Cspan class=\"hljs-params\">columnIndex\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> headers = \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">table\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelectorAll\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;thead th&#x27;\u003C/span>);\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> headers[columnIndex] ? headers[columnIndex].\u003Cspan class=\"hljs-property\">textContent\u003C/span>.\u003Cspan class=\"hljs-title function_\">trim\u003C/span>() : \u003Cspan class=\"hljs-string\">`Column \u003Cspan class=\"hljs-subst\">${columnIndex + \u003Cspan class=\"hljs-number\">1\u003C/span>}\u003C/span>`\u003C/span>;\n    }\n}\n\n\u003Cspan class=\"hljs-comment\">// Initialize accessible tables on page load\u003C/span>\n\u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">addEventListener\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;DOMContentLoaded&#x27;\u003C/span>, \u003Cspan class=\"hljs-function\">() =&gt;\u003C/span> {\n    \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-title function_\">querySelectorAll\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;.accessible-table&#x27;\u003C/span>).\u003Cspan class=\"hljs-title function_\">forEach\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">table\u003C/span> =&gt;\u003C/span> {\n        \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">AccessibleTableController\u003C/span>(table, {\n            \u003Cspan class=\"hljs-attr\">sortable\u003C/span>: table.\u003Cspan class=\"hljs-property\">classList\u003C/span>.\u003Cspan class=\"hljs-title function_\">contains\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;sortable&#x27;\u003C/span>),\n            \u003Cspan class=\"hljs-attr\">filterable\u003C/span>: table.\u003Cspan class=\"hljs-property\">classList\u003C/span>.\u003Cspan class=\"hljs-title function_\">contains\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;filterable&#x27;\u003C/span>),\n            \u003Cspan class=\"hljs-attr\">searchable\u003C/span>: table.\u003Cspan class=\"hljs-property\">classList\u003C/span>.\u003Cspan class=\"hljs-title function_\">contains\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;searchable&#x27;\u003C/span>),\n            \u003Cspan class=\"hljs-attr\">exportable\u003C/span>: table.\u003Cspan class=\"hljs-property\">classList\u003C/span>.\u003Cspan class=\"hljs-title function_\">contains\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;exportable&#x27;\u003C/span>)\n        });\n    });\n});\n\u003C/code>\u003C/pre>\u003Ch2 id=\"integration-with-documentation-systems\">Integration with Documentation Systems\u003C/h2>\n\u003Cp>Table accessibility integrates seamlessly with comprehensive documentation workflows. When combined with \u003Ca href=\"/blog/markdown-performance-optimization-rendering-speed-guide\">performance optimization and rendering systems\u003C/a>, accessible tables maintain fast loading times while providing enhanced functionality for screen readers and assistive technologies, ensuring optimal user experience across all access methods.\u003C/p>\n\u003Cp>For sophisticated content management, accessible tables work effectively with \u003Ca href=\"/blog/markdown-version-control-git-integration-complete-guide\">version control and collaborative workflows\u003C/a> to ensure that accessibility improvements are preserved through content updates, reviews, and collaborative editing processes while maintaining consistent accessibility standards across documentation teams.\u003C/p>\n\u003Cp>When building comprehensive documentation systems, table accessibility complements \u003Ca href=\"/blog/markdown-progressive-web-app-documentation-complete-guide\">Progressive Web App documentation\u003C/a> by ensuring that offline functionality, caching, and interactive features preserve accessibility attributes and maintain compatibility with assistive technologies in offline environments.\u003C/p>\n\u003Ch2 id=\"testing-and-validation\">Testing and Validation\u003C/h2>\n\u003Ch3 id=\"automated-accessibility-testing\">Automated Accessibility Testing\u003C/h3>\n\u003Cp>Implementing comprehensive accessibility testing for Markdown tables:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-python\">\u003Cspan class=\"hljs-comment\"># accessibility_tester.py - Automated accessibility testing for tables\u003C/span>\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> requests\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> selenium \u003Cspan class=\"hljs-keyword\">import\u003C/span> webdriver\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> selenium.webdriver.common.by \u003Cspan class=\"hljs-keyword\">import\u003C/span> By\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> selenium.webdriver.chrome.options \u003Cspan class=\"hljs-keyword\">import\u003C/span> Options\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> json\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> typing \u003Cspan class=\"hljs-keyword\">import\u003C/span> \u003Cspan class=\"hljs-type\">Dict\u003C/span>, \u003Cspan class=\"hljs-type\">List\u003C/span>\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> time\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">TableAccessibilityTester\u003C/span>:\n    \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Automated testing for table accessibility compliance&quot;&quot;&quot;\u003C/span>\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">__init__\u003C/span>(\u003Cspan class=\"hljs-params\">self, headless=\u003Cspan class=\"hljs-literal\">True\u003C/span>\u003C/span>):\n        self.setup_browser(headless)\n        self.accessibility_criteria = {\n            \u003Cspan class=\"hljs-string\">&#x27;wcag_aa&#x27;\u003C/span>: {\n                \u003Cspan class=\"hljs-string\">&#x27;required_attributes&#x27;\u003C/span>: [\u003Cspan class=\"hljs-string\">&#x27;scope&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;headers&#x27;\u003C/span>],\n                \u003Cspan class=\"hljs-string\">&#x27;required_elements&#x27;\u003C/span>: [\u003Cspan class=\"hljs-string\">&#x27;caption&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;thead&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;tbody&#x27;\u003C/span>],\n                \u003Cspan class=\"hljs-string\">&#x27;contrast_ratio&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">4.5\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;focus_indicators&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>\n            },\n            \u003Cspan class=\"hljs-string\">&#x27;wcag_aaa&#x27;\u003C/span>: {\n                \u003Cspan class=\"hljs-string\">&#x27;required_attributes&#x27;\u003C/span>: [\u003Cspan class=\"hljs-string\">&#x27;scope&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;headers&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;aria-label&#x27;\u003C/span>],\n                \u003Cspan class=\"hljs-string\">&#x27;required_elements&#x27;\u003C/span>: [\u003Cspan class=\"hljs-string\">&#x27;caption&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;thead&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;tbody&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;summary&#x27;\u003C/span>],\n                \u003Cspan class=\"hljs-string\">&#x27;contrast_ratio&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">7.0\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;focus_indicators&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>\n            }\n        }\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">setup_browser\u003C/span>(\u003Cspan class=\"hljs-params\">self, headless\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Setup Chrome browser with accessibility testing extensions&quot;&quot;&quot;\u003C/span>\n        chrome_options = Options()\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> headless:\n            chrome_options.add_argument(\u003Cspan class=\"hljs-string\">&#x27;--headless&#x27;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-comment\"># Add accessibility testing capabilities\u003C/span>\n        chrome_options.add_argument(\u003Cspan class=\"hljs-string\">&#x27;--enable-automation&#x27;\u003C/span>)\n        chrome_options.add_argument(\u003Cspan class=\"hljs-string\">&#x27;--no-sandbox&#x27;\u003C/span>)\n        chrome_options.add_argument(\u003Cspan class=\"hljs-string\">&#x27;--disable-dev-shm-usage&#x27;\u003C/span>)\n        \n        self.driver = webdriver.Chrome(options=chrome_options)\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">test_table_accessibility\u003C/span>(\u003Cspan class=\"hljs-params\">self, url: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, table_selector: \u003Cspan class=\"hljs-built_in\">str\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;.accessible-table&#x27;\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Dict\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Comprehensive accessibility test for tables on a webpage&quot;&quot;&quot;\u003C/span>\n        self.driver.get(url)\n        time.sleep(\u003Cspan class=\"hljs-number\">2\u003C/span>)  \u003Cspan class=\"hljs-comment\"># Allow page to load\u003C/span>\n        \n        results = {\n            \u003Cspan class=\"hljs-string\">&#x27;url&#x27;\u003C/span>: url,\n            \u003Cspan class=\"hljs-string\">&#x27;timestamp&#x27;\u003C/span>: time.time(),\n            \u003Cspan class=\"hljs-string\">&#x27;tables_tested&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&#x27;passed_tests&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&#x27;failed_tests&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>: [],\n            \u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>: [],\n            \u003Cspan class=\"hljs-string\">&#x27;detailed_results&#x27;\u003C/span>: []\n        }\n        \n        \u003Cspan class=\"hljs-comment\"># Find all tables\u003C/span>\n        tables = self.driver.find_elements(By.CSS_SELECTOR, table_selector)\n        results[\u003Cspan class=\"hljs-string\">&#x27;tables_tested&#x27;\u003C/span>] = \u003Cspan class=\"hljs-built_in\">len\u003C/span>(tables)\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> i, table \u003Cspan class=\"hljs-keyword\">in\u003C/span> \u003Cspan class=\"hljs-built_in\">enumerate\u003C/span>(tables):\n            table_results = self.test_single_table(table, \u003Cspan class=\"hljs-string\">f&quot;table-\u003Cspan class=\"hljs-subst\">{i+\u003Cspan class=\"hljs-number\">1\u003C/span>}\u003C/span>&quot;\u003C/span>)\n            results[\u003Cspan class=\"hljs-string\">&#x27;detailed_results&#x27;\u003C/span>].append(table_results)\n            \n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> table_results[\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>]:\n                results[\u003Cspan class=\"hljs-string\">&#x27;passed_tests&#x27;\u003C/span>] += \u003Cspan class=\"hljs-number\">1\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n                results[\u003Cspan class=\"hljs-string\">&#x27;failed_tests&#x27;\u003C/span>] += \u003Cspan class=\"hljs-number\">1\u003C/span>\n                results[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>].extend(table_results[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>])\n                results[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>].extend(table_results[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>])\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> results\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">test_single_table\u003C/span>(\u003Cspan class=\"hljs-params\">self, table_element, table_id: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Dict\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Test accessibility of a single table&quot;&quot;&quot;\u003C/span>\n        results = {\n            \u003Cspan class=\"hljs-string\">&#x27;table_id&#x27;\u003C/span>: table_id,\n            \u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>: [],\n            \u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>: [],\n            \u003Cspan class=\"hljs-string\">&#x27;tests&#x27;\u003C/span>: {\n                \u003Cspan class=\"hljs-string\">&#x27;semantic_structure&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">False\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;header_association&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">False\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;keyboard_navigation&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">False\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;screen_reader_support&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">False\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;responsive_design&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">False\u003C/span>\n            }\n        }\n        \n        \u003Cspan class=\"hljs-comment\"># Test semantic structure\u003C/span>\n        structure_result = self.test_semantic_structure(table_element)\n        results[\u003Cspan class=\"hljs-string\">&#x27;tests&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;semantic_structure&#x27;\u003C/span>] = structure_result[\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>]\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> structure_result[\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>]:\n            results[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>].extend(structure_result[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>])\n            results[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>].extend(structure_result[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>])\n            results[\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>] = \u003Cspan class=\"hljs-literal\">False\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Test header association\u003C/span>\n        header_result = self.test_header_association(table_element)\n        results[\u003Cspan class=\"hljs-string\">&#x27;tests&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;header_association&#x27;\u003C/span>] = header_result[\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>]\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> header_result[\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>]:\n            results[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>].extend(header_result[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>])\n            results[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>].extend(header_result[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>])\n            results[\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>] = \u003Cspan class=\"hljs-literal\">False\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Test keyboard navigation\u003C/span>\n        keyboard_result = self.test_keyboard_navigation(table_element)\n        results[\u003Cspan class=\"hljs-string\">&#x27;tests&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;keyboard_navigation&#x27;\u003C/span>] = keyboard_result[\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>]\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> keyboard_result[\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>]:\n            results[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>].extend(keyboard_result[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>])\n            results[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>].extend(keyboard_result[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>])\n            results[\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>] = \u003Cspan class=\"hljs-literal\">False\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Test screen reader support\u003C/span>\n        screenreader_result = self.test_screen_reader_support(table_element)\n        results[\u003Cspan class=\"hljs-string\">&#x27;tests&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;screen_reader_support&#x27;\u003C/span>] = screenreader_result[\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>]\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> screenreader_result[\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>]:\n            results[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>].extend(screenreader_result[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>])\n            results[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>].extend(screenreader_result[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>])\n            results[\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>] = \u003Cspan class=\"hljs-literal\">False\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> results\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">test_semantic_structure\u003C/span>(\u003Cspan class=\"hljs-params\">self, table_element\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Dict\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Test proper semantic HTML structure&quot;&quot;&quot;\u003C/span>\n        result = {\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>: [], \u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>: []}\n        \n        \u003Cspan class=\"hljs-comment\"># Check for caption\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">try\u003C/span>:\n            caption = table_element.find_element(By.TAG_NAME, \u003Cspan class=\"hljs-string\">&#x27;caption&#x27;\u003C/span>)\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> caption.text.strip():\n                result[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">&quot;Table caption is empty&quot;\u003C/span>)\n                result[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">&quot;Provide meaningful caption text&quot;\u003C/span>)\n                result[\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>] = \u003Cspan class=\"hljs-literal\">False\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">except\u003C/span>:\n            result[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">&quot;Missing table caption&quot;\u003C/span>)\n            result[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">&quot;Add a descriptive table caption&quot;\u003C/span>)\n            result[\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>] = \u003Cspan class=\"hljs-literal\">False\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Check for thead\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">try\u003C/span>:\n            thead = table_element.find_element(By.TAG_NAME, \u003Cspan class=\"hljs-string\">&#x27;thead&#x27;\u003C/span>)\n            headers = thead.find_elements(By.TAG_NAME, \u003Cspan class=\"hljs-string\">&#x27;th&#x27;\u003C/span>)\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(headers) == \u003Cspan class=\"hljs-number\">0\u003C/span>:\n                result[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">&quot;No header cells found in thead&quot;\u003C/span>)\n                result[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">&quot;Use &lt;th&gt; elements for column headers&quot;\u003C/span>)\n                result[\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>] = \u003Cspan class=\"hljs-literal\">False\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">except\u003C/span>:\n            result[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">&quot;Missing thead element&quot;\u003C/span>)\n            result[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">&quot;Wrap header row in &lt;thead&gt; element&quot;\u003C/span>)\n            result[\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>] = \u003Cspan class=\"hljs-literal\">False\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Check for tbody\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">try\u003C/span>:\n            tbody = table_element.find_element(By.TAG_NAME, \u003Cspan class=\"hljs-string\">&#x27;tbody&#x27;\u003C/span>)\n        \u003Cspan class=\"hljs-keyword\">except\u003C/span>:\n            result[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">&quot;Missing tbody element&quot;\u003C/span>)\n            result[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">&quot;Wrap data rows in &lt;tbody&gt; element&quot;\u003C/span>)\n            result[\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>] = \u003Cspan class=\"hljs-literal\">False\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> result\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">test_header_association\u003C/span>(\u003Cspan class=\"hljs-params\">self, table_element\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Dict\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Test proper header-data cell associations&quot;&quot;&quot;\u003C/span>\n        result = {\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>: [], \u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>: []}\n        \n        \u003Cspan class=\"hljs-comment\"># Check scope attributes on headers\u003C/span>\n        headers = table_element.find_elements(By.TAG_NAME, \u003Cspan class=\"hljs-string\">&#x27;th&#x27;\u003C/span>)\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> header \u003Cspan class=\"hljs-keyword\">in\u003C/span> headers:\n            scope = header.get_attribute(\u003Cspan class=\"hljs-string\">&#x27;scope&#x27;\u003C/span>)\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> scope:\n                result[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">f&quot;Header &#x27;\u003Cspan class=\"hljs-subst\">{header.text}\u003C/span>&#x27; missing scope attribute&quot;\u003C/span>)\n                result[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">&quot;Add scope=&#x27;col&#x27; or scope=&#x27;row&#x27; to header cells&quot;\u003C/span>)\n                result[\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>] = \u003Cspan class=\"hljs-literal\">False\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">elif\u003C/span> scope \u003Cspan class=\"hljs-keyword\">not\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> [\u003Cspan class=\"hljs-string\">&#x27;col&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;row&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;colgroup&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;rowgroup&#x27;\u003C/span>]:\n                result[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">f&quot;Invalid scope value &#x27;\u003Cspan class=\"hljs-subst\">{scope}\u003C/span>&#x27; on header &#x27;\u003Cspan class=\"hljs-subst\">{header.text}\u003C/span>&#x27;&quot;\u003C/span>)\n                result[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">&quot;Use valid scope values: col, row, colgroup, rowgroup&quot;\u003C/span>)\n                result[\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>] = \u003Cspan class=\"hljs-literal\">False\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Check for headers attribute on complex tables\u003C/span>\n        data_cells = table_element.find_elements(By.TAG_NAME, \u003Cspan class=\"hljs-string\">&#x27;td&#x27;\u003C/span>)\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(data_cells) &gt; \u003Cspan class=\"hljs-number\">20\u003C/span>:  \u003Cspan class=\"hljs-comment\"># Complex table heuristic\u003C/span>\n            cells_with_headers = [cell \u003Cspan class=\"hljs-keyword\">for\u003C/span> cell \u003Cspan class=\"hljs-keyword\">in\u003C/span> data_cells \u003Cspan class=\"hljs-keyword\">if\u003C/span> cell.get_attribute(\u003Cspan class=\"hljs-string\">&#x27;headers&#x27;\u003C/span>)]\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(cells_with_headers) == \u003Cspan class=\"hljs-number\">0\u003C/span>:\n                result[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">&quot;Complex table missing headers attributes on data cells&quot;\u003C/span>)\n                result[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">&quot;Add headers attributes to data cells referencing appropriate header IDs&quot;\u003C/span>)\n                result[\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>] = \u003Cspan class=\"hljs-literal\">False\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> result\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">test_keyboard_navigation\u003C/span>(\u003Cspan class=\"hljs-params\">self, table_element\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Dict\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Test keyboard navigation capabilities&quot;&quot;&quot;\u003C/span>\n        result = {\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>: [], \u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>: []}\n        \n        \u003Cspan class=\"hljs-comment\"># Check if table is keyboard accessible\u003C/span>\n        tabindex = table_element.get_attribute(\u003Cspan class=\"hljs-string\">&#x27;tabindex&#x27;\u003C/span>)\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> tabindex:\n            focusable_elements = table_element.find_elements(By.CSS_SELECTOR, \u003Cspan class=\"hljs-string\">&#x27;[tabindex]&#x27;\u003C/span>)\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(focusable_elements) == \u003Cspan class=\"hljs-number\">0\u003C/span>:\n                result[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">&quot;Table not keyboard accessible&quot;\u003C/span>)\n                result[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">&quot;Add tabindex=&#x27;0&#x27; to table or make cells focusable&quot;\u003C/span>)\n                result[\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>] = \u003Cspan class=\"hljs-literal\">False\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Test focus indicators (requires visual inspection in real tests)\u003C/span>\n        \u003Cspan class=\"hljs-comment\"># This is a simplified check\u003C/span>\n        computed_style = self.driver.execute_script(\u003Cspan class=\"hljs-string\">&quot;&quot;&quot;\n            var element = arguments[0];\n            return window.getComputedStyle(element, &#x27;:focus&#x27;);\n        &quot;&quot;&quot;\u003C/span>, table_element)\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> result\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">test_screen_reader_support\u003C/span>(\u003Cspan class=\"hljs-params\">self, table_element\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Dict\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Test screen reader compatibility&quot;&quot;&quot;\u003C/span>\n        result = {\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>: [], \u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>: []}\n        \n        \u003Cspan class=\"hljs-comment\"># Check for ARIA attributes\u003C/span>\n        aria_label = table_element.get_attribute(\u003Cspan class=\"hljs-string\">&#x27;aria-label&#x27;\u003C/span>)\n        aria_labelledby = table_element.get_attribute(\u003Cspan class=\"hljs-string\">&#x27;aria-labelledby&#x27;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> aria_label \u003Cspan class=\"hljs-keyword\">and\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> aria_labelledby:\n            result[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">&quot;Table lacks ARIA labeling&quot;\u003C/span>)\n            result[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">&quot;Add aria-label or aria-labelledby attribute&quot;\u003C/span>)\n            result[\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>] = \u003Cspan class=\"hljs-literal\">False\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Check for role attribute\u003C/span>\n        role = table_element.get_attribute(\u003Cspan class=\"hljs-string\">&#x27;role&#x27;\u003C/span>)\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> role \u003Cspan class=\"hljs-keyword\">and\u003C/span> role != \u003Cspan class=\"hljs-string\">&#x27;table&#x27;\u003C/span>:\n            result[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">f&quot;Incorrect role &#x27;\u003Cspan class=\"hljs-subst\">{role}\u003C/span>&#x27; on table&quot;\u003C/span>)\n            result[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>].append(\u003Cspan class=\"hljs-string\">&quot;Use role=&#x27;table&#x27; or remove role attribute&quot;\u003C/span>)\n            result[\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>] = \u003Cspan class=\"hljs-literal\">False\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> result\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">generate_accessibility_report\u003C/span>(\u003Cspan class=\"hljs-params\">self, results: \u003Cspan class=\"hljs-type\">Dict\u003C/span>, output_file: \u003Cspan class=\"hljs-built_in\">str\u003C/span> = \u003Cspan class=\"hljs-literal\">None\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">str\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Generate comprehensive accessibility report&quot;&quot;&quot;\u003C/span>\n        report_lines = []\n        \n        report_lines.append(\u003Cspan class=\"hljs-string\">&quot;# Table Accessibility Test Report&quot;\u003C/span>)\n        report_lines.append(\u003Cspan class=\"hljs-string\">f&quot;\\n**URL:** \u003Cspan class=\"hljs-subst\">{results[\u003Cspan class=\"hljs-string\">&#x27;url&#x27;\u003C/span>]}\u003C/span>&quot;\u003C/span>)\n        report_lines.append(\u003Cspan class=\"hljs-string\">f&quot;**Test Date:** \u003Cspan class=\"hljs-subst\">{time.strftime(\u003Cspan class=\"hljs-string\">&#x27;%Y-%m-%d %H:%M:%S&#x27;\u003C/span>, time.localtime(results[\u003Cspan class=\"hljs-string\">&#x27;timestamp&#x27;\u003C/span>]))}\u003C/span>&quot;\u003C/span>)\n        report_lines.append(\u003Cspan class=\"hljs-string\">f&quot;**Tables Tested:** \u003Cspan class=\"hljs-subst\">{results[\u003Cspan class=\"hljs-string\">&#x27;tables_tested&#x27;\u003C/span>]}\u003C/span>&quot;\u003C/span>)\n        report_lines.append(\u003Cspan class=\"hljs-string\">f&quot;**Passed:** \u003Cspan class=\"hljs-subst\">{results[\u003Cspan class=\"hljs-string\">&#x27;passed_tests&#x27;\u003C/span>]}\u003C/span>&quot;\u003C/span>)\n        report_lines.append(\u003Cspan class=\"hljs-string\">f&quot;**Failed:** \u003Cspan class=\"hljs-subst\">{results[\u003Cspan class=\"hljs-string\">&#x27;failed_tests&#x27;\u003C/span>]}\u003C/span>&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-comment\"># Overall score\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> results[\u003Cspan class=\"hljs-string\">&#x27;tables_tested&#x27;\u003C/span>] &gt; \u003Cspan class=\"hljs-number\">0\u003C/span>:\n            score = (results[\u003Cspan class=\"hljs-string\">&#x27;passed_tests&#x27;\u003C/span>] / results[\u003Cspan class=\"hljs-string\">&#x27;tables_tested&#x27;\u003C/span>]) * \u003Cspan class=\"hljs-number\">100\u003C/span>\n            report_lines.append(\u003Cspan class=\"hljs-string\">f&quot;**Overall Score:** \u003Cspan class=\"hljs-subst\">{score:\u003Cspan class=\"hljs-number\">.1\u003C/span>f}\u003C/span>%&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-comment\"># Summary of issues\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> results[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>]:\n            report_lines.append(\u003Cspan class=\"hljs-string\">&quot;\\n## Issues Found&quot;\u003C/span>)\n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> issue \u003Cspan class=\"hljs-keyword\">in\u003C/span> results[\u003Cspan class=\"hljs-string\">&#x27;issues&#x27;\u003C/span>]:\n                report_lines.append(\u003Cspan class=\"hljs-string\">f&quot;- \u003Cspan class=\"hljs-subst\">{issue}\u003C/span>&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-comment\"># Recommendations\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> results[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>]:\n            report_lines.append(\u003Cspan class=\"hljs-string\">&quot;\\n## Recommendations&quot;\u003C/span>)\n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> rec \u003Cspan class=\"hljs-keyword\">in\u003C/span> results[\u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>]:\n                report_lines.append(\u003Cspan class=\"hljs-string\">f&quot;- \u003Cspan class=\"hljs-subst\">{rec}\u003C/span>&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-comment\"># Detailed results per table\u003C/span>\n        report_lines.append(\u003Cspan class=\"hljs-string\">&quot;\\n## Detailed Results&quot;\u003C/span>)\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> table_result \u003Cspan class=\"hljs-keyword\">in\u003C/span> results[\u003Cspan class=\"hljs-string\">&#x27;detailed_results&#x27;\u003C/span>]:\n            report_lines.append(\u003Cspan class=\"hljs-string\">f&quot;\\n### \u003Cspan class=\"hljs-subst\">{table_result[\u003Cspan class=\"hljs-string\">&#x27;table_id&#x27;\u003C/span>]}\u003C/span>&quot;\u003C/span>)\n            report_lines.append(\u003Cspan class=\"hljs-string\">f&quot;**Overall:** \u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-string\">&#x27;✅ Passed&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">if\u003C/span> table_result[\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>] \u003Cspan class=\"hljs-keyword\">else\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;❌ Failed&#x27;\u003C/span>}\u003C/span>&quot;\u003C/span>)\n            \n            report_lines.append(\u003Cspan class=\"hljs-string\">&quot;\\n**Test Results:**&quot;\u003C/span>)\n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> test_name, passed \u003Cspan class=\"hljs-keyword\">in\u003C/span> table_result[\u003Cspan class=\"hljs-string\">&#x27;tests&#x27;\u003C/span>].items():\n                status = \u003Cspan class=\"hljs-string\">&quot;✅&quot;\u003C/span> \u003Cspan class=\"hljs-keyword\">if\u003C/span> passed \u003Cspan class=\"hljs-keyword\">else\u003C/span> \u003Cspan class=\"hljs-string\">&quot;❌&quot;\u003C/span>\n                readable_name = test_name.replace(\u003Cspan class=\"hljs-string\">&#x27;_&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27; &#x27;\u003C/span>).title()\n                report_lines.append(\u003Cspan class=\"hljs-string\">f&quot;- \u003Cspan class=\"hljs-subst\">{readable_name}\u003C/span>: \u003Cspan class=\"hljs-subst\">{status}\u003C/span>&quot;\u003C/span>)\n        \n        report_content = \u003Cspan class=\"hljs-string\">&#x27;\\n&#x27;\u003C/span>.join(report_lines)\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> output_file:\n            \u003Cspan class=\"hljs-keyword\">with\u003C/span> \u003Cspan class=\"hljs-built_in\">open\u003C/span>(output_file, \u003Cspan class=\"hljs-string\">&#x27;w&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">as\u003C/span> f:\n                f.write(report_content)\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> report_content\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">close\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Clean up browser resources&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> self.driver:\n            self.driver.quit()\n\n\u003Cspan class=\"hljs-comment\"># Usage example\u003C/span>\n\u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">test_website_table_accessibility\u003C/span>():\n    \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Test table accessibility on a website&quot;&quot;&quot;\u003C/span>\n    tester = TableAccessibilityTester(headless=\u003Cspan class=\"hljs-literal\">True\u003C/span>)\n    \n    \u003Cspan class=\"hljs-keyword\">try\u003C/span>:\n        \u003Cspan class=\"hljs-comment\"># Test multiple pages\u003C/span>\n        test_urls = [\n            \u003Cspan class=\"hljs-string\">&quot;https://example.com/data-tables&quot;\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&quot;https://example.com/reports&quot;\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&quot;https://example.com/dashboard&quot;\u003C/span>\n        ]\n        \n        all_results = []\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> url \u003Cspan class=\"hljs-keyword\">in\u003C/span> test_urls:\n            \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;Testing \u003Cspan class=\"hljs-subst\">{url}\u003C/span>...&quot;\u003C/span>)\n            results = tester.test_table_accessibility(url)\n            all_results.append(results)\n            \n            \u003Cspan class=\"hljs-comment\"># Generate individual report\u003C/span>\n            report = tester.generate_accessibility_report(\n                results, \n                \u003Cspan class=\"hljs-string\">f&quot;accessibility-report-\u003Cspan class=\"hljs-subst\">{url.split(\u003Cspan class=\"hljs-string\">&#x27;/&#x27;\u003C/span>)[-\u003Cspan class=\"hljs-number\">1\u003C/span>]}\u003C/span>.md&quot;\u003C/span>\n            )\n            \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;Report generated for \u003Cspan class=\"hljs-subst\">{url}\u003C/span>&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-comment\"># Generate summary report\u003C/span>\n        \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">&quot;\\nGenerating summary report...&quot;\u003C/span>)\n        generate_summary_report(all_results)\n        \n    \u003Cspan class=\"hljs-keyword\">finally\u003C/span>:\n        tester.close()\n\n\u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">generate_summary_report\u003C/span>(\u003Cspan class=\"hljs-params\">all_results: \u003Cspan class=\"hljs-type\">List\u003C/span>[\u003Cspan class=\"hljs-type\">Dict\u003C/span>]\u003C/span>):\n    \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Generate summary report across multiple pages&quot;&quot;&quot;\u003C/span>\n    summary = {\n        \u003Cspan class=\"hljs-string\">&#x27;total_tables&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">sum\u003C/span>(r[\u003Cspan class=\"hljs-string\">&#x27;tables_tested&#x27;\u003C/span>] \u003Cspan class=\"hljs-keyword\">for\u003C/span> r \u003Cspan class=\"hljs-keyword\">in\u003C/span> all_results),\n        \u003Cspan class=\"hljs-string\">&#x27;total_passed&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">sum\u003C/span>(r[\u003Cspan class=\"hljs-string\">&#x27;passed_tests&#x27;\u003C/span>] \u003Cspan class=\"hljs-keyword\">for\u003C/span> r \u003Cspan class=\"hljs-keyword\">in\u003C/span> all_results),\n        \u003Cspan class=\"hljs-string\">&#x27;total_failed&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">sum\u003C/span>(r[\u003Cspan class=\"hljs-string\">&#x27;failed_tests&#x27;\u003C/span>] \u003Cspan class=\"hljs-keyword\">for\u003C/span> r \u003Cspan class=\"hljs-keyword\">in\u003C/span> all_results),\n        \u003Cspan class=\"hljs-string\">&#x27;urls_tested&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">len\u003C/span>(all_results)\n    }\n    \n    \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;\\nSUMMARY REPORT&quot;\u003C/span>)\n    \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;URLs tested: \u003Cspan class=\"hljs-subst\">{summary[\u003Cspan class=\"hljs-string\">&#x27;urls_tested&#x27;\u003C/span>]}\u003C/span>&quot;\u003C/span>)\n    \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;Total tables: \u003Cspan class=\"hljs-subst\">{summary[\u003Cspan class=\"hljs-string\">&#x27;total_tables&#x27;\u003C/span>]}\u003C/span>&quot;\u003C/span>)\n    \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;Passed: \u003Cspan class=\"hljs-subst\">{summary[\u003Cspan class=\"hljs-string\">&#x27;total_passed&#x27;\u003C/span>]}\u003C/span>&quot;\u003C/span>)\n    \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;Failed: \u003Cspan class=\"hljs-subst\">{summary[\u003Cspan class=\"hljs-string\">&#x27;total_failed&#x27;\u003C/span>]}\u003C/span>&quot;\u003C/span>)\n    \n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> summary[\u003Cspan class=\"hljs-string\">&#x27;total_tables&#x27;\u003C/span>] &gt; \u003Cspan class=\"hljs-number\">0\u003C/span>:\n        success_rate = (summary[\u003Cspan class=\"hljs-string\">&#x27;total_passed&#x27;\u003C/span>] / summary[\u003Cspan class=\"hljs-string\">&#x27;total_tables&#x27;\u003C/span>]) * \u003Cspan class=\"hljs-number\">100\u003C/span>\n        \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;Success rate: \u003Cspan class=\"hljs-subst\">{success_rate:\u003Cspan class=\"hljs-number\">.1\u003C/span>f}\u003C/span>%&quot;\u003C/span>)\n\n\u003Cspan class=\"hljs-keyword\">if\u003C/span> __name__ == \u003Cspan class=\"hljs-string\">&quot;__main__&quot;\u003C/span>:\n    test_website_table_accessibility()\n\u003C/code>\u003C/pre>\u003Ch2 id=\"conclusion\">Conclusion\u003C/h2>\n\u003Cp>Advanced Markdown table accessibility represents a critical component of inclusive technical documentation that ensures all users can access, understand, and interact with tabular data regardless of their abilities or the assistive technologies they use. By implementing proper semantic markup, ARIA attributes, keyboard navigation, and responsive design patterns, technical writers can create documentation that meets WCAG guidelines while maintaining the efficiency and simplicity of Markdown workflows.\u003C/p>\n\u003Cp>The key to successful table accessibility lies in understanding that accessibility benefits all users, not just those with disabilities. Well-structured, semantically correct tables are easier to navigate, understand, and maintain for everyone. Whether you&#39;re creating simple data tables or complex multi-dimensional data presentations, the techniques covered in this guide provide the foundation for building inclusive documentation that serves your entire audience effectively.\u003C/p>\n\u003Cp>Remember to test your tables with actual assistive technologies, implement automated accessibility testing in your content workflows, and continuously educate your team about accessibility best practices. With proper attention to table accessibility, your Markdown documentation can achieve true inclusivity while maintaining the performance and maintainability that makes Markdown such an effective format for technical content creation.\u003C/p>\n",[15,19,22,25,28,31],{"id":16,"text":17,"level":18},"why-prioritize-table-accessibility","Why Prioritize Table Accessibility?",2,{"id":20,"text":21,"level":18},"foundation-accessibility-principles","Foundation Accessibility Principles",{"id":23,"text":24,"level":18},"complex-table-accessibility-patterns","Complex Table Accessibility Patterns",{"id":26,"text":27,"level":18},"integration-with-documentation-systems","Integration with Documentation Systems",{"id":29,"text":30,"level":18},"testing-and-validation","Testing and Validation",{"id":32,"text":33,"level":18},"conclusion","Conclusion",[],[36,44,52],{"slug":37,"title":38,"description":39,"excerpt":40,"date":41,"category":9,"author":10,"keywords":42,"readingMinutes":43},"markdown-table-accessibility-screen-readers-complete-guide","Markdown Table Accessibility and Screen Reader Support: Complete Guide for Inclusive Documentation and Web Content","Master Markdown table accessibility techniques for screen readers, ARIA labels, semantic markup, and inclusive design patterns. Learn to create accessible tables that work seamlessly with assistive technologies and meet WCAG compliance standards.","Advanced Markdown table accessibility and screen reader optimization enable inclusive documentation and web content that serves users with diverse accessibility needs. By implementing proper…","2025-11-21","markdown table accessibility, screen reader tables, accessible markdown, aria labels markdown, wcag compliance markdown, inclusive design tables, semantic table markup, assistive technology markdown",29,{"slug":45,"title":46,"description":47,"excerpt":48,"date":49,"category":9,"author":10,"keywords":50,"readingMinutes":51},"markdown-accessibility-screen-reader-support-complete-guide","Markdown Accessibility and Screen Reader Support: Complete Guide for Inclusive Documentation","Master Markdown accessibility techniques for screen readers, keyboard navigation, and inclusive documentation. Learn WCAG compliance, semantic HTML generation, and accessible formatting for all users.","Advanced Markdown accessibility and screen reader support techniques enable inclusive documentation that serves all users regardless of their abilities or assistive technologies. By implementing…","2025-11-23","markdown accessibility, screen reader markdown, accessible documentation, markdown WCAG, inclusive markdown, markdown semantic html, accessibility best practices, markdown for disabled users",13,{"slug":53,"title":54,"description":55,"excerpt":56,"date":57,"category":9,"author":10,"keywords":58,"readingMinutes":59},"markdown-accessibility-complete-guide","Markdown Accessibility and WCAG Compliance: Complete Guide for Inclusive Documentation and Content Creation","Master accessibility in Markdown documentation with comprehensive WCAG compliance techniques, semantic markup strategies, and assistive technology support. Learn to create inclusive content that works for all users.","Advanced Markdown accessibility and WCAG compliance enable the creation of inclusive documentation that serves users with diverse abilities and assistive technology requirements. By implementing…","2025-12-19","markdown accessibility, WCAG compliance markdown, accessible documentation, inclusive content markdown, assistive technology markdown, screen reader markdown, semantic markup markdown, accessibility testing markdown",32,1792184942561]