[{"data":1,"prerenderedAt":56},["Reactive",2],{"blog-post-markdown-automated-testing-validation-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":31,"related":32},"markdown-automated-testing-validation-complete-guide","Markdown Automated Testing and Validation: Complete Guide for Quality Assurance and Continuous Integration","Master comprehensive Markdown testing strategies, automated validation systems, and CI/CD integration for maintaining high-quality documentation and content integrity across large-scale projects.","Automated testing and validation for Markdown content ensures consistency, quality, and reliability across documentation projects through comprehensive testing frameworks that verify syntax…","2025-10-17","Tutorial","Matthew Rathbone","markdown testing, markdown validation, automated testing markdown, CI/CD markdown, markdown quality assurance, content testing, documentation testing, markdown linting",22,"\u003Cp>Automated testing and validation for Markdown content ensures consistency, quality, and reliability across documentation projects through comprehensive testing frameworks that verify syntax correctness, link integrity, content structure, and formatting compliance. By implementing sophisticated validation systems integrated with continuous integration pipelines, development teams can catch errors early, maintain documentation standards, and ensure that content changes don&#39;t introduce regressions or break existing functionality.\u003C/p>\n\u003Ch2 id=\"why-master-markdown-testing-and-validation\">Why Master Markdown Testing and Validation?\u003C/h2>\n\u003Cp>Professional automated testing provides essential benefits for content management:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Error Prevention\u003C/strong>: Catch syntax errors, broken links, and formatting issues before they reach production\u003C/li>\n\u003Cli>\u003Cstrong>Consistency Enforcement\u003C/strong>: Maintain uniform structure, style, and formatting across all documentation\u003C/li>\n\u003Cli>\u003Cstrong>Quality Assurance\u003C/strong>: Implement automated checks for readability, accessibility, and SEO optimization\u003C/li>\n\u003Cli>\u003Cstrong>Regression Detection\u003C/strong>: Prevent content changes from breaking existing functionality or links\u003C/li>\n\u003Cli>\u003Cstrong>Scalability\u003C/strong>: Handle large documentation projects with automated quality control systems\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"foundation-testing-framework\">Foundation Testing Framework\u003C/h2>\n\u003Ch3 id=\"core-validation-architecture\">Core Validation Architecture\u003C/h3>\n\u003Cp>Building comprehensive testing systems for Markdown content validation:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-javascript\">\u003Cspan class=\"hljs-comment\">// markdown-testing-framework.js - Comprehensive testing and validation system\u003C/span>\n\u003Cspan class=\"hljs-keyword\">const\u003C/span> fs = \u003Cspan class=\"hljs-built_in\">require\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;fs&#x27;\u003C/span>).\u003Cspan class=\"hljs-property\">promises\u003C/span>;\n\u003Cspan class=\"hljs-keyword\">const\u003C/span> path = \u003Cspan class=\"hljs-built_in\">require\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;path&#x27;\u003C/span>);\n\u003Cspan class=\"hljs-keyword\">const\u003C/span> matter = \u003Cspan class=\"hljs-built_in\">require\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;gray-matter&#x27;\u003C/span>);\n\u003Cspan class=\"hljs-keyword\">const\u003C/span> markdownIt = \u003Cspan class=\"hljs-built_in\">require\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;markdown-it&#x27;\u003C/span>);\n\u003Cspan class=\"hljs-keyword\">const\u003C/span> { \u003Cspan class=\"hljs-variable constant_\">JSDOM\u003C/span> } = \u003Cspan class=\"hljs-built_in\">require\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;jsdom&#x27;\u003C/span>);\n\u003Cspan class=\"hljs-keyword\">const\u003C/span> axios = \u003Cspan class=\"hljs-built_in\">require\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;axios&#x27;\u003C/span>);\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">MarkdownTestingFramework\u003C/span> {\n    \u003Cspan class=\"hljs-title function_\">constructor\u003C/span>(\u003Cspan class=\"hljs-params\">options = {}\u003C/span>) {\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">config\u003C/span> = {\n            \u003Cspan class=\"hljs-attr\">contentDirectory\u003C/span>: options.\u003Cspan class=\"hljs-property\">contentDirectory\u003C/span> || \u003Cspan class=\"hljs-string\">&#x27;./content&#x27;\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">testOutputDirectory\u003C/span>: options.\u003Cspan class=\"hljs-property\">testOutputDirectory\u003C/span> || \u003Cspan class=\"hljs-string\">&#x27;./test-results&#x27;\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">parallelTests\u003C/span>: options.\u003Cspan class=\"hljs-property\">parallelTests\u003C/span> || \u003Cspan class=\"hljs-number\">10\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">timeoutMs\u003C/span>: options.\u003Cspan class=\"hljs-property\">timeoutMs\u003C/span> || \u003Cspan class=\"hljs-number\">30000\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">enableLinkValidation\u003C/span>: options.\u003Cspan class=\"hljs-property\">enableLinkValidation\u003C/span> !== \u003Cspan class=\"hljs-literal\">false\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">enableAccessibilityTests\u003C/span>: options.\u003Cspan class=\"hljs-property\">enableAccessibilityTests\u003C/span> !== \u003Cspan class=\"hljs-literal\">false\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">enablePerformanceTests\u003C/span>: options.\u003Cspan class=\"hljs-property\">enablePerformanceTests\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\">md\u003C/span> = \u003Cspan class=\"hljs-title function_\">markdownIt\u003C/span>({\n            \u003Cspan class=\"hljs-attr\">html\u003C/span>: \u003Cspan class=\"hljs-literal\">true\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">linkify\u003C/span>: \u003Cspan class=\"hljs-literal\">true\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">typographer\u003C/span>: \u003Cspan class=\"hljs-literal\">true\u003C/span>\n        });\n        \n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">testResults\u003C/span> = {\n            \u003Cspan class=\"hljs-attr\">passed\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">failed\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">warnings\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">errors\u003C/span>: [],\n            \u003Cspan class=\"hljs-attr\">performance\u003C/span>: {},\n            \u003Cspan class=\"hljs-attr\">coverage\u003C/span>: {}\n        };\n        \n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">validators\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\">linkCache\u003C/span> = \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">Map\u003C/span>();\n        \n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">initializeValidators\u003C/span>();\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">initializeValidators\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n        \u003Cspan class=\"hljs-comment\">// Syntax validation\u003C/span>\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">validators\u003C/span>.\u003Cspan class=\"hljs-title function_\">set\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;syntax&#x27;\u003C/span>, {\n            \u003Cspan class=\"hljs-attr\">name\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Markdown Syntax Validation&#x27;\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">test\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">validateSyntax\u003C/span>.\u003Cspan class=\"hljs-title function_\">bind\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>),\n            \u003Cspan class=\"hljs-attr\">critical\u003C/span>: \u003Cspan class=\"hljs-literal\">true\u003C/span>\n        });\n        \n        \u003Cspan class=\"hljs-comment\">// Frontmatter validation\u003C/span>\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">validators\u003C/span>.\u003Cspan class=\"hljs-title function_\">set\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;frontmatter&#x27;\u003C/span>, {\n            \u003Cspan class=\"hljs-attr\">name\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Frontmatter Validation&#x27;\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">test\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">validateFrontmatter\u003C/span>.\u003Cspan class=\"hljs-title function_\">bind\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>),\n            \u003Cspan class=\"hljs-attr\">critical\u003C/span>: \u003Cspan class=\"hljs-literal\">true\u003C/span>\n        });\n        \n        \u003Cspan class=\"hljs-comment\">// Link validation\u003C/span>\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">validators\u003C/span>.\u003Cspan class=\"hljs-title function_\">set\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;links&#x27;\u003C/span>, {\n            \u003Cspan class=\"hljs-attr\">name\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Link Integrity Validation&#x27;\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">test\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">validateLinks\u003C/span>.\u003Cspan class=\"hljs-title function_\">bind\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>),\n            \u003Cspan class=\"hljs-attr\">critical\u003C/span>: \u003Cspan class=\"hljs-literal\">false\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">enabled\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">config\u003C/span>.\u003Cspan class=\"hljs-property\">enableLinkValidation\u003C/span>\n        });\n        \n        \u003Cspan class=\"hljs-comment\">// Content structure validation\u003C/span>\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">validators\u003C/span>.\u003Cspan class=\"hljs-title function_\">set\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;structure&#x27;\u003C/span>, {\n            \u003Cspan class=\"hljs-attr\">name\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Content Structure Validation&#x27;\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">test\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">validateStructure\u003C/span>.\u003Cspan class=\"hljs-title function_\">bind\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>),\n            \u003Cspan class=\"hljs-attr\">critical\u003C/span>: \u003Cspan class=\"hljs-literal\">false\u003C/span>\n        });\n        \n        \u003Cspan class=\"hljs-comment\">// Accessibility validation\u003C/span>\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">validators\u003C/span>.\u003Cspan class=\"hljs-title function_\">set\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;accessibility&#x27;\u003C/span>, {\n            \u003Cspan class=\"hljs-attr\">name\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Accessibility Validation&#x27;\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">test\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">validateAccessibility\u003C/span>.\u003Cspan class=\"hljs-title function_\">bind\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>),\n            \u003Cspan class=\"hljs-attr\">critical\u003C/span>: \u003Cspan class=\"hljs-literal\">false\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">enabled\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">config\u003C/span>.\u003Cspan class=\"hljs-property\">enableAccessibilityTests\u003C/span>\n        });\n        \n        \u003Cspan class=\"hljs-comment\">// SEO validation\u003C/span>\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">validators\u003C/span>.\u003Cspan class=\"hljs-title function_\">set\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;seo&#x27;\u003C/span>, {\n            \u003Cspan class=\"hljs-attr\">name\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;SEO Optimization Validation&#x27;\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">test\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">validateSEO\u003C/span>.\u003Cspan class=\"hljs-title function_\">bind\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>),\n            \u003Cspan class=\"hljs-attr\">critical\u003C/span>: \u003Cspan class=\"hljs-literal\">false\u003C/span>\n        });\n        \n        \u003Cspan class=\"hljs-comment\">// Performance validation\u003C/span>\n        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">validators\u003C/span>.\u003Cspan class=\"hljs-title function_\">set\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;performance&#x27;\u003C/span>, {\n            \u003Cspan class=\"hljs-attr\">name\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Performance Validation&#x27;\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">test\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">validatePerformance\u003C/span>.\u003Cspan class=\"hljs-title function_\">bind\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>),\n            \u003Cspan class=\"hljs-attr\">critical\u003C/span>: \u003Cspan class=\"hljs-literal\">false\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">enabled\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">config\u003C/span>.\u003Cspan class=\"hljs-property\">enablePerformanceTests\u003C/span>\n        });\n    }\n    \n    \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">runAllTests\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n        \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;🧪 Starting comprehensive Markdown testing...&#x27;\u003C/span>);\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> startTime = \u003Cspan class=\"hljs-title class_\">Date\u003C/span>.\u003Cspan class=\"hljs-title function_\">now\u003C/span>();\n        \n        \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n            \u003Cspan class=\"hljs-comment\">// Discover test files\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> markdownFiles = \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">discoverMarkdownFiles\u003C/span>();\n            \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(\u003Cspan class=\"hljs-string\">`📁 Found \u003Cspan class=\"hljs-subst\">${markdownFiles.length}\u003C/span> Markdown files to test`\u003C/span>);\n            \n            \u003Cspan class=\"hljs-comment\">// Run tests in parallel batches\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> testPromises = [];\n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> (\u003Cspan class=\"hljs-keyword\">let\u003C/span> i = \u003Cspan class=\"hljs-number\">0\u003C/span>; i &lt; markdownFiles.\u003Cspan class=\"hljs-property\">length\u003C/span>; i += \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">config\u003C/span>.\u003Cspan class=\"hljs-property\">parallelTests\u003C/span>) {\n                \u003Cspan class=\"hljs-keyword\">const\u003C/span> batch = markdownFiles.\u003Cspan class=\"hljs-title function_\">slice\u003C/span>(i, i + \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">config\u003C/span>.\u003Cspan class=\"hljs-property\">parallelTests\u003C/span>);\n                testPromises.\u003Cspan class=\"hljs-title function_\">push\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">runBatchTests\u003C/span>(batch));\n            }\n            \n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> batchResults = \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-title class_\">Promise\u003C/span>.\u003Cspan class=\"hljs-title function_\">all\u003C/span>(testPromises);\n            \n            \u003Cspan class=\"hljs-comment\">// Aggregate results\u003C/span>\n            \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">aggregateResults\u003C/span>(batchResults);\n            \n            \u003Cspan class=\"hljs-comment\">// Generate report\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> report = \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">generateTestReport\u003C/span>();\n            \n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> endTime = \u003Cspan class=\"hljs-title class_\">Date\u003C/span>.\u003Cspan class=\"hljs-title function_\">now\u003C/span>();\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> duration = (endTime - startTime) / \u003Cspan class=\"hljs-number\">1000\u003C/span>;\n            \n            \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(\u003Cspan class=\"hljs-string\">`✅ Testing completed in \u003Cspan class=\"hljs-subst\">${duration.toFixed(\u003Cspan class=\"hljs-number\">2\u003C/span>)}\u003C/span>s`\u003C/span>);\n            \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(\u003Cspan class=\"hljs-string\">`📊 Results: \u003Cspan class=\"hljs-subst\">${\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.testResults.passed}\u003C/span> passed, \u003Cspan class=\"hljs-subst\">${\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.testResults.failed}\u003C/span> failed, \u003Cspan class=\"hljs-subst\">${\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.testResults.warnings}\u003C/span> warnings`\u003C/span>);\n            \n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> report;\n            \n        } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n            \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">error\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;❌ Testing framework error:&#x27;\u003C/span>, error);\n            \u003Cspan class=\"hljs-keyword\">throw\u003C/span> error;\n        }\n    }\n    \n    \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">discoverMarkdownFiles\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> files = [];\n        \n        \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-keyword\">function\u003C/span> \u003Cspan class=\"hljs-title function_\">scanDirectory\u003C/span>(\u003Cspan class=\"hljs-params\">dir\u003C/span>) {\n            \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n                \u003Cspan class=\"hljs-keyword\">const\u003C/span> entries = \u003Cspan class=\"hljs-keyword\">await\u003C/span> fs.\u003Cspan class=\"hljs-title function_\">readdir\u003C/span>(dir, { \u003Cspan class=\"hljs-attr\">withFileTypes\u003C/span>: \u003Cspan class=\"hljs-literal\">true\u003C/span> });\n                \n                \u003Cspan class=\"hljs-keyword\">for\u003C/span> (\u003Cspan class=\"hljs-keyword\">const\u003C/span> entry \u003Cspan class=\"hljs-keyword\">of\u003C/span> entries) {\n                    \u003Cspan class=\"hljs-keyword\">const\u003C/span> fullPath = path.\u003Cspan class=\"hljs-title function_\">join\u003C/span>(dir, entry.\u003Cspan class=\"hljs-property\">name\u003C/span>);\n                    \n                    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (entry.\u003Cspan class=\"hljs-title function_\">isDirectory\u003C/span>() &amp;&amp; !entry.\u003Cspan class=\"hljs-property\">name\u003C/span>.\u003Cspan class=\"hljs-title function_\">startsWith\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;.&#x27;\u003C/span>)) {\n                        \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-title function_\">scanDirectory\u003C/span>(fullPath);\n                    } \u003Cspan class=\"hljs-keyword\">else\u003C/span> \u003Cspan class=\"hljs-keyword\">if\u003C/span> (entry.\u003Cspan class=\"hljs-title function_\">isFile\u003C/span>() &amp;&amp; entry.\u003Cspan class=\"hljs-property\">name\u003C/span>.\u003Cspan class=\"hljs-title function_\">endsWith\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;.md&#x27;\u003C/span>)) {\n                        files.\u003Cspan class=\"hljs-title function_\">push\u003C/span>(fullPath);\n                    }\n                }\n            } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n                \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">warn\u003C/span>(\u003Cspan class=\"hljs-string\">`⚠️  Cannot access directory \u003Cspan class=\"hljs-subst\">${dir}\u003C/span>: \u003Cspan class=\"hljs-subst\">${error.message}\u003C/span>`\u003C/span>);\n            }\n        }\n        \n        \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-title function_\">scanDirectory\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">config\u003C/span>.\u003Cspan class=\"hljs-property\">contentDirectory\u003C/span>);\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> files;\n    }\n    \n    \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">runBatchTests\u003C/span>(\u003Cspan class=\"hljs-params\">filePaths\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> results = [];\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> (\u003Cspan class=\"hljs-keyword\">const\u003C/span> filePath \u003Cspan class=\"hljs-keyword\">of\u003C/span> filePaths) {\n            \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n                \u003Cspan class=\"hljs-keyword\">const\u003C/span> fileResult = \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">testFile\u003C/span>(filePath);\n                results.\u003Cspan class=\"hljs-title function_\">push\u003C/span>(fileResult);\n            } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n                results.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                    \u003Cspan class=\"hljs-attr\">file\u003C/span>: filePath,\n                    \u003Cspan class=\"hljs-attr\">error\u003C/span>: error.\u003Cspan class=\"hljs-property\">message\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">passed\u003C/span>: \u003Cspan class=\"hljs-literal\">false\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">tests\u003C/span>: []\n                });\n            }\n        }\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> results;\n    }\n    \n    \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">testFile\u003C/span>(\u003Cspan class=\"hljs-params\">filePath\u003C/span>) {\n        \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(\u003Cspan class=\"hljs-string\">`🔍 Testing: \u003Cspan class=\"hljs-subst\">${path.relative(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.config.contentDirectory, filePath)}\u003C/span>`\u003C/span>);\n        \n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> fileContent = \u003Cspan class=\"hljs-keyword\">await\u003C/span> fs.\u003Cspan class=\"hljs-title function_\">readFile\u003C/span>(filePath, \u003Cspan class=\"hljs-string\">&#x27;utf8&#x27;\u003C/span>);\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> { \u003Cspan class=\"hljs-attr\">data\u003C/span>: frontmatter, content } = \u003Cspan class=\"hljs-title function_\">matter\u003C/span>(fileContent);\n        \n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> \u003Cspan class=\"hljs-variable language_\">document\u003C/span> = {\n            \u003Cspan class=\"hljs-attr\">path\u003C/span>: filePath,\n            frontmatter,\n            content,\n            \u003Cspan class=\"hljs-attr\">fullContent\u003C/span>: fileContent\n        };\n        \n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> testResults = {\n            \u003Cspan class=\"hljs-attr\">file\u003C/span>: filePath,\n            \u003Cspan class=\"hljs-attr\">passed\u003C/span>: \u003Cspan class=\"hljs-literal\">true\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">tests\u003C/span>: [],\n            \u003Cspan class=\"hljs-attr\">warnings\u003C/span>: [],\n            \u003Cspan class=\"hljs-attr\">performance\u003C/span>: {}\n        };\n        \n        \u003Cspan class=\"hljs-comment\">// Run all validators\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> (\u003Cspan class=\"hljs-keyword\">const\u003C/span> [validatorName, validator] \u003Cspan class=\"hljs-keyword\">of\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">validators\u003C/span>) {\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (validator.\u003Cspan class=\"hljs-property\">enabled\u003C/span> === \u003Cspan class=\"hljs-literal\">false\u003C/span>) \u003Cspan class=\"hljs-keyword\">continue\u003C/span>;\n            \n            \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n                \u003Cspan class=\"hljs-keyword\">const\u003C/span> testStart = \u003Cspan class=\"hljs-title class_\">Date\u003C/span>.\u003Cspan class=\"hljs-title function_\">now\u003C/span>();\n                \u003Cspan class=\"hljs-keyword\">const\u003C/span> result = \u003Cspan class=\"hljs-keyword\">await\u003C/span> validator.\u003Cspan class=\"hljs-title function_\">test\u003C/span>(\u003Cspan class=\"hljs-variable language_\">document\u003C/span>);\n                \u003Cspan class=\"hljs-keyword\">const\u003C/span> testDuration = \u003Cspan class=\"hljs-title class_\">Date\u003C/span>.\u003Cspan class=\"hljs-title function_\">now\u003C/span>() - testStart;\n                \n                \u003Cspan class=\"hljs-keyword\">const\u003C/span> testResult = {\n                    \u003Cspan class=\"hljs-attr\">name\u003C/span>: validator.\u003Cspan class=\"hljs-property\">name\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">type\u003C/span>: validatorName,\n                    \u003Cspan class=\"hljs-attr\">passed\u003C/span>: result.\u003Cspan class=\"hljs-property\">passed\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">critical\u003C/span>: validator.\u003Cspan class=\"hljs-property\">critical\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">duration\u003C/span>: testDuration,\n                    \u003Cspan class=\"hljs-attr\">issues\u003C/span>: result.\u003Cspan class=\"hljs-property\">issues\u003C/span> || [],\n                    \u003Cspan class=\"hljs-attr\">warnings\u003C/span>: result.\u003Cspan class=\"hljs-property\">warnings\u003C/span> || [],\n                    \u003Cspan class=\"hljs-attr\">metrics\u003C/span>: result.\u003Cspan class=\"hljs-property\">metrics\u003C/span> || {}\n                };\n                \n                testResults.\u003Cspan class=\"hljs-property\">tests\u003C/span>.\u003Cspan class=\"hljs-title function_\">push\u003C/span>(testResult);\n                testResults.\u003Cspan class=\"hljs-property\">warnings\u003C/span>.\u003Cspan class=\"hljs-title function_\">push\u003C/span>(...result.\u003Cspan class=\"hljs-property\">warnings\u003C/span> || []);\n                \n                \u003Cspan class=\"hljs-comment\">// Mark file as failed if critical test fails\u003C/span>\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!result.\u003Cspan class=\"hljs-property\">passed\u003C/span> &amp;&amp; validator.\u003Cspan class=\"hljs-property\">critical\u003C/span>) {\n                    testResults.\u003Cspan class=\"hljs-property\">passed\u003C/span> = \u003Cspan class=\"hljs-literal\">false\u003C/span>;\n                }\n                \n                \u003Cspan class=\"hljs-comment\">// Collect performance metrics\u003C/span>\n                testResults.\u003Cspan class=\"hljs-property\">performance\u003C/span>[validatorName] = testDuration;\n                \n            } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n                testResults.\u003Cspan class=\"hljs-property\">tests\u003C/span>.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                    \u003Cspan class=\"hljs-attr\">name\u003C/span>: validator.\u003Cspan class=\"hljs-property\">name\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">type\u003C/span>: validatorName,\n                    \u003Cspan class=\"hljs-attr\">passed\u003C/span>: \u003Cspan class=\"hljs-literal\">false\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">critical\u003C/span>: validator.\u003Cspan class=\"hljs-property\">critical\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">error\u003C/span>: error.\u003Cspan class=\"hljs-property\">message\u003C/span>\n                });\n                \n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> (validator.\u003Cspan class=\"hljs-property\">critical\u003C/span>) {\n                    testResults.\u003Cspan class=\"hljs-property\">passed\u003C/span> = \u003Cspan class=\"hljs-literal\">false\u003C/span>;\n                }\n            }\n        }\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> testResults;\n    }\n    \n    \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">validateSyntax\u003C/span>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-variable language_\">document\u003C/span>\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> issues = [];\n        \n        \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n            \u003Cspan class=\"hljs-comment\">// Parse markdown to check for syntax errors\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> tokens = \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">md\u003C/span>.\u003Cspan class=\"hljs-title function_\">parse\u003C/span>(\u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">content\u003C/span>, {});\n            \n            \u003Cspan class=\"hljs-comment\">// Check for unmatched code blocks\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> codeBlockPattern = \u003Cspan class=\"hljs-regexp\">/```/g\u003C/span>;\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> codeBlockMatches = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">content\u003C/span>.\u003Cspan class=\"hljs-title function_\">match\u003C/span>(codeBlockPattern) || [];\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (codeBlockMatches.\u003Cspan class=\"hljs-property\">length\u003C/span> % \u003Cspan class=\"hljs-number\">2\u003C/span> !== \u003Cspan class=\"hljs-number\">0\u003C/span>) {\n                issues.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                    \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;syntax&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">severity\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;high&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Unmatched code block delimiters (```)&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">line\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">findUnmatchedCodeBlockLine\u003C/span>(\u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">content\u003C/span>)\n                });\n            }\n            \n            \u003Cspan class=\"hljs-comment\">// Check for malformed links\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> malformedLinks = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">content\u003C/span>.\u003Cspan class=\"hljs-title function_\">match\u003C/span>(\u003Cspan class=\"hljs-regexp\">/\\[([^\\]]*)\\]\\([^)]*$/gm\u003C/span>);\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (malformedLinks) {\n                issues.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                    \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;syntax&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">severity\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;high&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">`\u003Cspan class=\"hljs-subst\">${malformedLinks.length}\u003C/span> malformed links detected`\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">examples\u003C/span>: malformedLinks.\u003Cspan class=\"hljs-title function_\">slice\u003C/span>(\u003Cspan class=\"hljs-number\">0\u003C/span>, \u003Cspan class=\"hljs-number\">3\u003C/span>)\n                });\n            }\n            \n            \u003Cspan class=\"hljs-comment\">// Check for unmatched brackets in links\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> unmatchedBrackets = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">content\u003C/span>.\u003Cspan class=\"hljs-title function_\">match\u003C/span>(\u003Cspan class=\"hljs-regexp\">/\\[[^\\]]*$/gm\u003C/span>) || [];\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (unmatchedBrackets.\u003Cspan class=\"hljs-property\">length\u003C/span> &gt; \u003Cspan class=\"hljs-number\">0\u003C/span>) {\n                issues.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                    \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;syntax&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">severity\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;medium&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Unmatched square brackets detected&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">count\u003C/span>: unmatchedBrackets.\u003Cspan class=\"hljs-property\">length\u003C/span>\n                });\n            }\n            \n        } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n            issues.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;syntax&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">severity\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;critical&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">`Markdown parsing failed: \u003Cspan class=\"hljs-subst\">${error.message}\u003C/span>`\u003C/span>\n            });\n        }\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> {\n            \u003Cspan class=\"hljs-attr\">passed\u003C/span>: issues.\u003Cspan class=\"hljs-title function_\">filter\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">i\u003C/span> =&gt;\u003C/span> i.\u003Cspan class=\"hljs-property\">severity\u003C/span> === \u003Cspan class=\"hljs-string\">&#x27;high&#x27;\u003C/span> || i.\u003Cspan class=\"hljs-property\">severity\u003C/span> === \u003Cspan class=\"hljs-string\">&#x27;critical&#x27;\u003C/span>).\u003Cspan class=\"hljs-property\">length\u003C/span> === \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            issues,\n            \u003Cspan class=\"hljs-attr\">warnings\u003C/span>: issues.\u003Cspan class=\"hljs-title function_\">filter\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">i\u003C/span> =&gt;\u003C/span> i.\u003Cspan class=\"hljs-property\">severity\u003C/span> === \u003Cspan class=\"hljs-string\">&#x27;medium&#x27;\u003C/span> || i.\u003Cspan class=\"hljs-property\">severity\u003C/span> === \u003Cspan class=\"hljs-string\">&#x27;low&#x27;\u003C/span>)\n        };\n    }\n    \n    \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">validateFrontmatter\u003C/span>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-variable language_\">document\u003C/span>\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> issues = [];\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> warnings = [];\n        \n        \u003Cspan class=\"hljs-comment\">// Required fields check\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> requiredFields = [\u003Cspan class=\"hljs-string\">&#x27;title&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;description&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;date&#x27;\u003C/span>];\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> (\u003Cspan class=\"hljs-keyword\">const\u003C/span> field \u003Cspan class=\"hljs-keyword\">of\u003C/span> requiredFields) {\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!\u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">frontmatter\u003C/span>[field]) {\n                issues.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                    \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;frontmatter&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">severity\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;high&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">`Missing required frontmatter field: \u003Cspan class=\"hljs-subst\">${field}\u003C/span>`\u003C/span>\n                });\n            }\n        }\n        \n        \u003Cspan class=\"hljs-comment\">// Title validation\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">frontmatter\u003C/span>.\u003Cspan class=\"hljs-property\">title\u003C/span>) {\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> titleLength = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">frontmatter\u003C/span>.\u003Cspan class=\"hljs-property\">title\u003C/span>.\u003Cspan class=\"hljs-property\">length\u003C/span>;\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (titleLength &lt; \u003Cspan class=\"hljs-number\">10\u003C/span>) {\n                issues.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                    \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;frontmatter&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">severity\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;medium&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">`Title too short: \u003Cspan class=\"hljs-subst\">${titleLength}\u003C/span> characters (minimum: 10)`\u003C/span>\n                });\n            } \u003Cspan class=\"hljs-keyword\">else\u003C/span> \u003Cspan class=\"hljs-keyword\">if\u003C/span> (titleLength &gt; \u003Cspan class=\"hljs-number\">100\u003C/span>) {\n                warnings.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                    \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;frontmatter&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">`Title may be too long: \u003Cspan class=\"hljs-subst\">${titleLength}\u003C/span> characters (recommended: &lt;100)`\u003C/span>\n                });\n            }\n        }\n        \n        \u003Cspan class=\"hljs-comment\">// Description validation\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">frontmatter\u003C/span>.\u003Cspan class=\"hljs-property\">description\u003C/span>) {\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> descLength = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">frontmatter\u003C/span>.\u003Cspan class=\"hljs-property\">description\u003C/span>.\u003Cspan class=\"hljs-property\">length\u003C/span>;\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (descLength &lt; \u003Cspan class=\"hljs-number\">50\u003C/span>) {\n                warnings.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                    \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;frontmatter&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">`Description may be too short: \u003Cspan class=\"hljs-subst\">${descLength}\u003C/span> characters (recommended: 120-160)`\u003C/span>\n                });\n            } \u003Cspan class=\"hljs-keyword\">else\u003C/span> \u003Cspan class=\"hljs-keyword\">if\u003C/span> (descLength &gt; \u003Cspan class=\"hljs-number\">200\u003C/span>) {\n                warnings.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                    \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;frontmatter&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">`Description may be too long: \u003Cspan class=\"hljs-subst\">${descLength}\u003C/span> characters (recommended: 120-160)`\u003C/span>\n                });\n            }\n        }\n        \n        \u003Cspan class=\"hljs-comment\">// Date validation\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">frontmatter\u003C/span>.\u003Cspan class=\"hljs-property\">date\u003C/span>) {\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> date = \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">Date\u003C/span>(\u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">frontmatter\u003C/span>.\u003Cspan class=\"hljs-property\">date\u003C/span>);\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-built_in\">isNaN\u003C/span>(date.\u003Cspan class=\"hljs-title function_\">getTime\u003C/span>())) {\n                issues.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                    \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;frontmatter&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">severity\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;medium&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Invalid date format in frontmatter&#x27;\u003C/span>\n                });\n            } \u003Cspan class=\"hljs-keyword\">else\u003C/span> \u003Cspan class=\"hljs-keyword\">if\u003C/span> (date &gt; \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">Date\u003C/span>()) {\n                warnings.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                    \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;frontmatter&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Date is in the future&#x27;\u003C/span>\n                });\n            }\n        }\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> {\n            \u003Cspan class=\"hljs-attr\">passed\u003C/span>: issues.\u003Cspan class=\"hljs-title function_\">filter\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">i\u003C/span> =&gt;\u003C/span> i.\u003Cspan class=\"hljs-property\">severity\u003C/span> === \u003Cspan class=\"hljs-string\">&#x27;high&#x27;\u003C/span>).\u003Cspan class=\"hljs-property\">length\u003C/span> === \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            issues,\n            warnings\n        };\n    }\n    \n    \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">validateLinks\u003C/span>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-variable language_\">document\u003C/span>\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> issues = [];\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> warnings = [];\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> metrics = {\n            \u003Cspan class=\"hljs-attr\">totalLinks\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">internalLinks\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">externalLinks\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">brokenLinks\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">checkDuration\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>\n        };\n        \n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> startTime = \u003Cspan class=\"hljs-title class_\">Date\u003C/span>.\u003Cspan class=\"hljs-title function_\">now\u003C/span>();\n        \n        \u003Cspan class=\"hljs-comment\">// Extract all links\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> linkPattern = \u003Cspan class=\"hljs-regexp\">/\\[([^\\]]+)\\]\\(([^)]+)\\)/g\u003C/span>;\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> links = [];\n        \u003Cspan class=\"hljs-keyword\">let\u003C/span> match;\n        \n        \u003Cspan class=\"hljs-keyword\">while\u003C/span> ((match = linkPattern.\u003Cspan class=\"hljs-title function_\">exec\u003C/span>(\u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">content\u003C/span>)) !== \u003Cspan class=\"hljs-literal\">null\u003C/span>) {\n            links.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                \u003Cspan class=\"hljs-attr\">text\u003C/span>: match[\u003Cspan class=\"hljs-number\">1\u003C/span>],\n                \u003Cspan class=\"hljs-attr\">url\u003C/span>: match[\u003Cspan class=\"hljs-number\">2\u003C/span>],\n                \u003Cspan class=\"hljs-attr\">fullMatch\u003C/span>: match[\u003Cspan class=\"hljs-number\">0\u003C/span>],\n                \u003Cspan class=\"hljs-attr\">index\u003C/span>: match.\u003Cspan class=\"hljs-property\">index\u003C/span>\n            });\n        }\n        \n        metrics.\u003Cspan class=\"hljs-property\">totalLinks\u003C/span> = links.\u003Cspan class=\"hljs-property\">length\u003C/span>;\n        \n        \u003Cspan class=\"hljs-comment\">// Validate each link\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> (\u003Cspan class=\"hljs-keyword\">const\u003C/span> link \u003Cspan class=\"hljs-keyword\">of\u003C/span> links) {\n            \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> (link.\u003Cspan class=\"hljs-property\">url\u003C/span>.\u003Cspan class=\"hljs-title function_\">startsWith\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;http://&#x27;\u003C/span>) || link.\u003Cspan class=\"hljs-property\">url\u003C/span>.\u003Cspan class=\"hljs-title function_\">startsWith\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;https://&#x27;\u003C/span>)) {\n                    \u003Cspan class=\"hljs-comment\">// External link\u003C/span>\n                    metrics.\u003Cspan class=\"hljs-property\">externalLinks\u003C/span>++;\n                    \n                    \u003Cspan class=\"hljs-comment\">// Check if we&#x27;ve already validated this URL\u003C/span>\n                    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">linkCache\u003C/span>.\u003Cspan class=\"hljs-title function_\">has\u003C/span>(link.\u003Cspan class=\"hljs-property\">url\u003C/span>)) {\n                        \u003Cspan class=\"hljs-keyword\">const\u003C/span> isValid = \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">checkExternalLink\u003C/span>(link.\u003Cspan class=\"hljs-property\">url\u003C/span>);\n                        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">linkCache\u003C/span>.\u003Cspan class=\"hljs-title function_\">set\u003C/span>(link.\u003Cspan class=\"hljs-property\">url\u003C/span>, isValid);\n                    }\n                    \n                    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">linkCache\u003C/span>.\u003Cspan class=\"hljs-title function_\">get\u003C/span>(link.\u003Cspan class=\"hljs-property\">url\u003C/span>)) {\n                        issues.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                            \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;links&#x27;\u003C/span>,\n                            \u003Cspan class=\"hljs-attr\">severity\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;medium&#x27;\u003C/span>,\n                            \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">`Broken external link: \u003Cspan class=\"hljs-subst\">${link.url}\u003C/span>`\u003C/span>,\n                            \u003Cspan class=\"hljs-attr\">linkText\u003C/span>: link.\u003Cspan class=\"hljs-property\">text\u003C/span>\n                        });\n                        metrics.\u003Cspan class=\"hljs-property\">brokenLinks\u003C/span>++;\n                    }\n                    \n                } \u003Cspan class=\"hljs-keyword\">else\u003C/span> \u003Cspan class=\"hljs-keyword\">if\u003C/span> (link.\u003Cspan class=\"hljs-property\">url\u003C/span>.\u003Cspan class=\"hljs-title function_\">startsWith\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;#&#x27;\u003C/span>)) {\n                    \u003Cspan class=\"hljs-comment\">// Internal anchor link\u003C/span>\n                    \u003Cspan class=\"hljs-keyword\">const\u003C/span> anchor = link.\u003Cspan class=\"hljs-property\">url\u003C/span>.\u003Cspan class=\"hljs-title function_\">substring\u003C/span>(\u003Cspan class=\"hljs-number\">1\u003C/span>);\n                    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">findAnchorInContent\u003C/span>(\u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">content\u003C/span>, anchor)) {\n                        issues.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                            \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;links&#x27;\u003C/span>,\n                            \u003Cspan class=\"hljs-attr\">severity\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;medium&#x27;\u003C/span>,\n                            \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">`Broken internal anchor: \u003Cspan class=\"hljs-subst\">${link.url}\u003C/span>`\u003C/span>,\n                            \u003Cspan class=\"hljs-attr\">linkText\u003C/span>: link.\u003Cspan class=\"hljs-property\">text\u003C/span>\n                        });\n                    }\n                    \n                } \u003Cspan class=\"hljs-keyword\">else\u003C/span> \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!link.\u003Cspan class=\"hljs-property\">url\u003C/span>.\u003Cspan class=\"hljs-title function_\">startsWith\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;mailto:&#x27;\u003C/span>)) {\n                    \u003Cspan class=\"hljs-comment\">// Relative link\u003C/span>\n                    metrics.\u003Cspan class=\"hljs-property\">internalLinks\u003C/span>++;\n                    \n                    \u003Cspan class=\"hljs-keyword\">const\u003C/span> basePath = path.\u003Cspan class=\"hljs-title function_\">dirname\u003C/span>(\u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">path\u003C/span>);\n                    \u003Cspan class=\"hljs-keyword\">const\u003C/span> targetPath = path.\u003Cspan class=\"hljs-title function_\">resolve\u003C/span>(basePath, link.\u003Cspan class=\"hljs-property\">url\u003C/span>);\n                    \n                    \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n                        \u003Cspan class=\"hljs-keyword\">await\u003C/span> fs.\u003Cspan class=\"hljs-title function_\">access\u003C/span>(targetPath);\n                    } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> {\n                        issues.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                            \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;links&#x27;\u003C/span>,\n                            \u003Cspan class=\"hljs-attr\">severity\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;high&#x27;\u003C/span>,\n                            \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">`Broken internal link: \u003Cspan class=\"hljs-subst\">${link.url}\u003C/span>`\u003C/span>,\n                            \u003Cspan class=\"hljs-attr\">linkText\u003C/span>: link.\u003Cspan class=\"hljs-property\">text\u003C/span>,\n                            \u003Cspan class=\"hljs-attr\">resolvedPath\u003C/span>: targetPath\n                        });\n                        metrics.\u003Cspan class=\"hljs-property\">brokenLinks\u003C/span>++;\n                    }\n                }\n                \n            } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n                warnings.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                    \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;links&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">`Error validating link \u003Cspan class=\"hljs-subst\">${link.url}\u003C/span>: \u003Cspan class=\"hljs-subst\">${error.message}\u003C/span>`\u003C/span>\n                });\n            }\n        }\n        \n        metrics.\u003Cspan class=\"hljs-property\">checkDuration\u003C/span> = \u003Cspan class=\"hljs-title class_\">Date\u003C/span>.\u003Cspan class=\"hljs-title function_\">now\u003C/span>() - startTime;\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> {\n            \u003Cspan class=\"hljs-attr\">passed\u003C/span>: issues.\u003Cspan class=\"hljs-title function_\">filter\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">i\u003C/span> =&gt;\u003C/span> i.\u003Cspan class=\"hljs-property\">severity\u003C/span> === \u003Cspan class=\"hljs-string\">&#x27;high&#x27;\u003C/span>).\u003Cspan class=\"hljs-property\">length\u003C/span> === \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            issues,\n            warnings,\n            metrics\n        };\n    }\n    \n    \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">checkExternalLink\u003C/span>(\u003Cspan class=\"hljs-params\">url\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> response = \u003Cspan class=\"hljs-keyword\">await\u003C/span> axios.\u003Cspan class=\"hljs-title function_\">head\u003C/span>(url, {\n                \u003Cspan class=\"hljs-attr\">timeout\u003C/span>: \u003Cspan class=\"hljs-number\">10000\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">maxRedirects\u003C/span>: \u003Cspan class=\"hljs-number\">5\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">validateStatus\u003C/span>: \u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">status\u003C/span>) =&gt;\u003C/span> status &lt; \u003Cspan class=\"hljs-number\">400\u003C/span>\n            });\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-literal\">true\u003C/span>;\n        } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n            \u003Cspan class=\"hljs-comment\">// Try GET request if HEAD fails\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n                \u003Cspan class=\"hljs-keyword\">const\u003C/span> response = \u003Cspan class=\"hljs-keyword\">await\u003C/span> axios.\u003Cspan class=\"hljs-title function_\">get\u003C/span>(url, {\n                    \u003Cspan class=\"hljs-attr\">timeout\u003C/span>: \u003Cspan class=\"hljs-number\">10000\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">maxRedirects\u003C/span>: \u003Cspan class=\"hljs-number\">5\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">validateStatus\u003C/span>: \u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">status\u003C/span>) =&gt;\u003C/span> status &lt; \u003Cspan class=\"hljs-number\">400\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">maxContentLength\u003C/span>: \u003Cspan class=\"hljs-number\">1024\u003C/span> \u003Cspan class=\"hljs-comment\">// Only download first 1KB\u003C/span>\n                });\n                \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-literal\">true\u003C/span>;\n            } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> {\n                \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-literal\">false\u003C/span>;\n            }\n        }\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">findAnchorInContent\u003C/span>(\u003Cspan class=\"hljs-params\">content, anchor\u003C/span>) {\n        \u003Cspan class=\"hljs-comment\">// Check for heading that would generate this anchor\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> headingPattern = \u003Cspan class=\"hljs-keyword\">new\u003C/span> \u003Cspan class=\"hljs-title class_\">RegExp\u003C/span>(\u003Cspan class=\"hljs-string\">`^#+\\\\s+(.*)$`\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;gm&#x27;\u003C/span>);\n        \u003Cspan class=\"hljs-keyword\">let\u003C/span> match;\n        \n        \u003Cspan class=\"hljs-keyword\">while\u003C/span> ((match = headingPattern.\u003Cspan class=\"hljs-title function_\">exec\u003C/span>(content)) !== \u003Cspan class=\"hljs-literal\">null\u003C/span>) {\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> headingText = match[\u003Cspan class=\"hljs-number\">1\u003C/span>];\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> generatedAnchor = headingText\n                .\u003Cspan class=\"hljs-title function_\">toLowerCase\u003C/span>()\n                .\u003Cspan class=\"hljs-title function_\">replace\u003C/span>(\u003Cspan class=\"hljs-regexp\">/[^a-z0-9\\s-]/g\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>)\n                .\u003Cspan class=\"hljs-title function_\">replace\u003C/span>(\u003Cspan class=\"hljs-regexp\">/\\s+/g\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;-&#x27;\u003C/span>)\n                .\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-title function_\">replace\u003C/span>(\u003Cspan class=\"hljs-regexp\">/^-|-$/g\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>);\n            \n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (generatedAnchor === anchor) {\n                \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-literal\">true\u003C/span>;\n            }\n        }\n        \n        \u003Cspan class=\"hljs-comment\">// Check for explicit anchor tags\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> content.\u003Cspan class=\"hljs-title function_\">includes\u003C/span>(\u003Cspan class=\"hljs-string\">`&lt;a id=&quot;\u003Cspan class=\"hljs-subst\">${anchor}\u003C/span>&quot;`\u003C/span>) || content.\u003Cspan class=\"hljs-title function_\">includes\u003C/span>(\u003Cspan class=\"hljs-string\">`&lt;a name=&quot;\u003Cspan class=\"hljs-subst\">${anchor}\u003C/span>&quot;`\u003C/span>);\n    }\n    \n    \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">validateStructure\u003C/span>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-variable language_\">document\u003C/span>\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> issues = [];\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> warnings = [];\n        \n        \u003Cspan class=\"hljs-comment\">// Check heading hierarchy\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> headings = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">content\u003C/span>.\u003Cspan class=\"hljs-title function_\">match\u003C/span>(\u003Cspan class=\"hljs-regexp\">/^(#+)\\s+(.+)$/gm\u003C/span>) || [];\n        \u003Cspan class=\"hljs-keyword\">let\u003C/span> lastLevel = \u003Cspan class=\"hljs-number\">0\u003C/span>;\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> (\u003Cspan class=\"hljs-keyword\">const\u003C/span> heading \u003Cspan class=\"hljs-keyword\">of\u003C/span> headings) {\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> level = heading.\u003Cspan class=\"hljs-title function_\">match\u003C/span>(\u003Cspan class=\"hljs-regexp\">/^#+/\u003C/span>)[\u003Cspan class=\"hljs-number\">0\u003C/span>].\u003Cspan class=\"hljs-property\">length\u003C/span>;\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> text = heading.\u003Cspan class=\"hljs-title function_\">replace\u003C/span>(\u003Cspan class=\"hljs-regexp\">/^#+\\s/\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>);\n            \n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (level &gt; lastLevel + \u003Cspan class=\"hljs-number\">1\u003C/span>) {\n                issues.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                    \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;structure&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">severity\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;medium&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">`Heading level skip: \u003Cspan class=\"hljs-subst\">${heading}\u003C/span> (from h\u003Cspan class=\"hljs-subst\">${lastLevel}\u003C/span> to h\u003Cspan class=\"hljs-subst\">${level}\u003C/span>)`\u003C/span>\n                });\n            }\n            \n            \u003Cspan class=\"hljs-comment\">// Check for empty headings\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!text.\u003Cspan class=\"hljs-title function_\">trim\u003C/span>()) {\n                issues.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                    \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;structure&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">severity\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;high&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Empty heading detected&#x27;\u003C/span>\n                });\n            }\n            \n            lastLevel = level;\n        }\n        \n        \u003Cspan class=\"hljs-comment\">// Check for minimum content structure\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (headings.\u003Cspan class=\"hljs-property\">length\u003C/span> === \u003Cspan class=\"hljs-number\">0\u003C/span>) {\n            warnings.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;structure&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Document has no headings - consider adding structure&#x27;\u003C/span>\n            });\n        }\n        \n        \u003Cspan class=\"hljs-comment\">// Check paragraph structure\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> paragraphs = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">content\u003C/span>.\u003Cspan class=\"hljs-title function_\">split\u003C/span>(\u003Cspan class=\"hljs-regexp\">/\\n\\s*\\n/\u003C/span>).\u003Cspan class=\"hljs-title function_\">filter\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">p\u003C/span> =&gt;\u003C/span> p.\u003Cspan class=\"hljs-title function_\">trim\u003C/span>());\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> shortParagraphs = paragraphs.\u003Cspan class=\"hljs-title function_\">filter\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">p\u003C/span> =&gt;\u003C/span> p.\u003Cspan class=\"hljs-title function_\">trim\u003C/span>().\u003Cspan class=\"hljs-property\">length\u003C/span> &lt; \u003Cspan class=\"hljs-number\">50\u003C/span> &amp;&amp; !p.\u003Cspan class=\"hljs-title function_\">trim\u003C/span>().\u003Cspan class=\"hljs-title function_\">startsWith\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;#&#x27;\u003C/span>));\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (shortParagraphs.\u003Cspan class=\"hljs-property\">length\u003C/span> &gt; paragraphs.\u003Cspan class=\"hljs-property\">length\u003C/span> * \u003Cspan class=\"hljs-number\">0.3\u003C/span>) {\n            warnings.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;structure&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">`Many short paragraphs detected (\u003Cspan class=\"hljs-subst\">${shortParagraphs.length}\u003C/span>/\u003Cspan class=\"hljs-subst\">${paragraphs.length}\u003C/span>)`\u003C/span>\n            });\n        }\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> {\n            \u003Cspan class=\"hljs-attr\">passed\u003C/span>: issues.\u003Cspan class=\"hljs-title function_\">filter\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">i\u003C/span> =&gt;\u003C/span> i.\u003Cspan class=\"hljs-property\">severity\u003C/span> === \u003Cspan class=\"hljs-string\">&#x27;high&#x27;\u003C/span>).\u003Cspan class=\"hljs-property\">length\u003C/span> === \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            issues,\n            warnings\n        };\n    }\n    \n    \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">validateAccessibility\u003C/span>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-variable language_\">document\u003C/span>\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> issues = [];\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> warnings = [];\n        \n        \u003Cspan class=\"hljs-comment\">// Check images have alt text\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> images = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">content\u003C/span>.\u003Cspan class=\"hljs-title function_\">match\u003C/span>(\u003Cspan class=\"hljs-regexp\">/!\\[([^\\]]*)\\]\\([^)]+\\)/g\u003C/span>) || [];\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> imagesWithoutAlt = images.\u003Cspan class=\"hljs-title function_\">filter\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">img\u003C/span> =&gt;\u003C/span> {\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> altMatch = img.\u003Cspan class=\"hljs-title function_\">match\u003C/span>(\u003Cspan class=\"hljs-regexp\">/!\\[([^\\]]*)\\]/\u003C/span>);\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> !altMatch || !altMatch[\u003Cspan class=\"hljs-number\">1\u003C/span>].\u003Cspan class=\"hljs-title function_\">trim\u003C/span>();\n        });\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (imagesWithoutAlt.\u003Cspan class=\"hljs-property\">length\u003C/span> &gt; \u003Cspan class=\"hljs-number\">0\u003C/span>) {\n            issues.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;accessibility&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">severity\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;high&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">`\u003Cspan class=\"hljs-subst\">${imagesWithoutAlt.length}\u003C/span> images missing alt text`\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">examples\u003C/span>: imagesWithoutAlt.\u003Cspan class=\"hljs-title function_\">slice\u003C/span>(\u003Cspan class=\"hljs-number\">0\u003C/span>, \u003Cspan class=\"hljs-number\">3\u003C/span>)\n            });\n        }\n        \n        \u003Cspan class=\"hljs-comment\">// Check for descriptive link text\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> linkPattern = \u003Cspan class=\"hljs-regexp\">/\\[([^\\]]+)\\]\\([^)]+\\)/g\u003C/span>;\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> vagueLinkTexts = [\u003Cspan class=\"hljs-string\">&#x27;click here&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;read more&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;here&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;this&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;link&#x27;\u003C/span>];\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> vagueLinks = [];\n        \u003Cspan class=\"hljs-keyword\">let\u003C/span> match;\n        \n        \u003Cspan class=\"hljs-keyword\">while\u003C/span> ((match = linkPattern.\u003Cspan class=\"hljs-title function_\">exec\u003C/span>(\u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">content\u003C/span>)) !== \u003Cspan class=\"hljs-literal\">null\u003C/span>) {\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> linkText = match[\u003Cspan class=\"hljs-number\">1\u003C/span>].\u003Cspan class=\"hljs-title function_\">toLowerCase\u003C/span>();\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (vagueLinkTexts.\u003Cspan class=\"hljs-title function_\">some\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">vague\u003C/span> =&gt;\u003C/span> linkText.\u003Cspan class=\"hljs-title function_\">includes\u003C/span>(vague))) {\n                vagueLinks.\u003Cspan class=\"hljs-title function_\">push\u003C/span>(match[\u003Cspan class=\"hljs-number\">0\u003C/span>]);\n            }\n        }\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (vagueLinks.\u003Cspan class=\"hljs-property\">length\u003C/span> &gt; \u003Cspan class=\"hljs-number\">0\u003C/span>) {\n            warnings.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;accessibility&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">`\u003Cspan class=\"hljs-subst\">${vagueLinks.length}\u003C/span> links with vague text found`\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">examples\u003C/span>: vagueLinks.\u003Cspan class=\"hljs-title function_\">slice\u003C/span>(\u003Cspan class=\"hljs-number\">0\u003C/span>, \u003Cspan class=\"hljs-number\">3\u003C/span>)\n            });\n        }\n        \n        \u003Cspan class=\"hljs-comment\">// Check heading structure for screen readers\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> headings = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">content\u003C/span>.\u003Cspan class=\"hljs-title function_\">match\u003C/span>(\u003Cspan class=\"hljs-regexp\">/^(#+)\\s+(.+)$/gm\u003C/span>) || [];\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (headings.\u003Cspan class=\"hljs-property\">length\u003C/span> &gt; \u003Cspan class=\"hljs-number\">0\u003C/span>) {\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> firstHeading = headings[\u003Cspan class=\"hljs-number\">0\u003C/span>];\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> firstLevel = firstHeading.\u003Cspan class=\"hljs-title function_\">match\u003C/span>(\u003Cspan class=\"hljs-regexp\">/^#+/\u003C/span>)[\u003Cspan class=\"hljs-number\">0\u003C/span>].\u003Cspan class=\"hljs-property\">length\u003C/span>;\n            \n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (firstLevel !== \u003Cspan class=\"hljs-number\">1\u003C/span>) {\n                warnings.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                    \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;accessibility&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">`First heading is h\u003Cspan class=\"hljs-subst\">${firstLevel}\u003C/span>, consider starting with h1`\u003C/span>\n                });\n            }\n        }\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> {\n            \u003Cspan class=\"hljs-attr\">passed\u003C/span>: issues.\u003Cspan class=\"hljs-title function_\">filter\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">i\u003C/span> =&gt;\u003C/span> i.\u003Cspan class=\"hljs-property\">severity\u003C/span> === \u003Cspan class=\"hljs-string\">&#x27;high&#x27;\u003C/span>).\u003Cspan class=\"hljs-property\">length\u003C/span> === \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            issues,\n            warnings\n        };\n    }\n    \n    \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">validateSEO\u003C/span>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-variable language_\">document\u003C/span>\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> issues = [];\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> warnings = [];\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> metrics = {\n            \u003Cspan class=\"hljs-attr\">wordCount\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">headingCount\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">linkCount\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">imageCount\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>\n        };\n        \n        \u003Cspan class=\"hljs-comment\">// Word count\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> words = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">content\u003C/span>.\u003Cspan class=\"hljs-title function_\">split\u003C/span>(\u003Cspan class=\"hljs-regexp\">/\\s+/\u003C/span>).\u003Cspan class=\"hljs-title function_\">filter\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">word\u003C/span> =&gt;\u003C/span> word.\u003Cspan class=\"hljs-property\">length\u003C/span> &gt; \u003Cspan class=\"hljs-number\">0\u003C/span>);\n        metrics.\u003Cspan class=\"hljs-property\">wordCount\u003C/span> = words.\u003Cspan class=\"hljs-property\">length\u003C/span>;\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (metrics.\u003Cspan class=\"hljs-property\">wordCount\u003C/span> &lt; \u003Cspan class=\"hljs-number\">300\u003C/span>) {\n            warnings.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;seo&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">`Low word count: \u003Cspan class=\"hljs-subst\">${metrics.wordCount}\u003C/span> (recommended: 300+)`\u003C/span>\n            });\n        }\n        \n        \u003Cspan class=\"hljs-comment\">// Heading distribution\u003C/span>\n        metrics.\u003Cspan class=\"hljs-property\">headingCount\u003C/span> = (\u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">content\u003C/span>.\u003Cspan class=\"hljs-title function_\">match\u003C/span>(\u003Cspan class=\"hljs-regexp\">/^#+\\s/gm\u003C/span>) || []).\u003Cspan class=\"hljs-property\">length\u003C/span>;\n        \n        \u003Cspan class=\"hljs-comment\">// Link count\u003C/span>\n        metrics.\u003Cspan class=\"hljs-property\">linkCount\u003C/span> = (\u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">content\u003C/span>.\u003Cspan class=\"hljs-title function_\">match\u003C/span>(\u003Cspan class=\"hljs-regexp\">/\\[([^\\]]+)\\]\\([^)]+\\)/g\u003C/span>) || []).\u003Cspan class=\"hljs-property\">length\u003C/span>;\n        \n        \u003Cspan class=\"hljs-comment\">// Image count\u003C/span>\n        metrics.\u003Cspan class=\"hljs-property\">imageCount\u003C/span> = (\u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">content\u003C/span>.\u003Cspan class=\"hljs-title function_\">match\u003C/span>(\u003Cspan class=\"hljs-regexp\">/!\\[([^\\]]*)\\]\\([^)]+\\)/g\u003C/span>) || []).\u003Cspan class=\"hljs-property\">length\u003C/span>;\n        \n        \u003Cspan class=\"hljs-comment\">// Check meta description length\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">frontmatter\u003C/span>.\u003Cspan class=\"hljs-property\">description\u003C/span>) {\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> descLength = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">frontmatter\u003C/span>.\u003Cspan class=\"hljs-property\">description\u003C/span>.\u003Cspan class=\"hljs-property\">length\u003C/span>;\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (descLength &lt; \u003Cspan class=\"hljs-number\">120\u003C/span> || descLength &gt; \u003Cspan class=\"hljs-number\">160\u003C/span>) {\n                warnings.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                    \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;seo&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">`Description length \u003Cspan class=\"hljs-subst\">${descLength}\u003C/span> not optimal (recommended: 120-160)`\u003C/span>\n                });\n            }\n        }\n        \n        \u003Cspan class=\"hljs-comment\">// Check title length\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">frontmatter\u003C/span>.\u003Cspan class=\"hljs-property\">title\u003C/span>) {\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> titleLength = \u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">frontmatter\u003C/span>.\u003Cspan class=\"hljs-property\">title\u003C/span>.\u003Cspan class=\"hljs-property\">length\u003C/span>;\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (titleLength &gt; \u003Cspan class=\"hljs-number\">60\u003C/span>) {\n                warnings.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                    \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;seo&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">`Title may be too long: \u003Cspan class=\"hljs-subst\">${titleLength}\u003C/span> characters (recommended: &lt;60)`\u003C/span>\n                });\n            }\n        }\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> {\n            \u003Cspan class=\"hljs-attr\">passed\u003C/span>: \u003Cspan class=\"hljs-literal\">true\u003C/span>, \u003Cspan class=\"hljs-comment\">// SEO issues are typically warnings\u003C/span>\n            issues,\n            warnings,\n            metrics\n        };\n    }\n    \n    \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">validatePerformance\u003C/span>(\u003Cspan class=\"hljs-params\">\u003Cspan class=\"hljs-variable language_\">document\u003C/span>\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> issues = [];\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> warnings = [];\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> metrics = {\n            \u003Cspan class=\"hljs-attr\">fileSize\u003C/span>: \u003Cspan class=\"hljs-title class_\">Buffer\u003C/span>.\u003Cspan class=\"hljs-title function_\">byteLength\u003C/span>(\u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">fullContent\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;utf8&#x27;\u003C/span>),\n            \u003Cspan class=\"hljs-attr\">renderTime\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">complexity\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>\n        };\n        \n        \u003Cspan class=\"hljs-comment\">// File size check\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> maxSize = \u003Cspan class=\"hljs-number\">1024\u003C/span> * \u003Cspan class=\"hljs-number\">1024\u003C/span>; \u003Cspan class=\"hljs-comment\">// 1MB\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (metrics.\u003Cspan class=\"hljs-property\">fileSize\u003C/span> &gt; maxSize) {\n            warnings.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;performance&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">`Large file size: \u003Cspan class=\"hljs-subst\">${(metrics.fileSize / \u003Cspan class=\"hljs-number\">1024\u003C/span>).toFixed(\u003Cspan class=\"hljs-number\">1\u003C/span>)}\u003C/span>KB (consider splitting)`\u003C/span>\n            });\n        }\n        \n        \u003Cspan class=\"hljs-comment\">// Rendering performance test\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> renderStart = \u003Cspan class=\"hljs-title class_\">Date\u003C/span>.\u003Cspan class=\"hljs-title function_\">now\u003C/span>();\n        \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> html = \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">md\u003C/span>.\u003Cspan class=\"hljs-title function_\">render\u003C/span>(\u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">content\u003C/span>);\n            metrics.\u003Cspan class=\"hljs-property\">renderTime\u003C/span> = \u003Cspan class=\"hljs-title class_\">Date\u003C/span>.\u003Cspan class=\"hljs-title function_\">now\u003C/span>() - renderStart;\n            \n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (metrics.\u003Cspan class=\"hljs-property\">renderTime\u003C/span> &gt; \u003Cspan class=\"hljs-number\">1000\u003C/span>) {\n                warnings.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                    \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;performance&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">`Slow rendering: \u003Cspan class=\"hljs-subst\">${metrics.renderTime}\u003C/span>ms (consider optimizing content)`\u003C/span>\n                });\n            }\n        } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n            issues.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;performance&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">severity\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;medium&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">`Rendering failed: \u003Cspan class=\"hljs-subst\">${error.message}\u003C/span>`\u003C/span>\n            });\n        }\n        \n        \u003Cspan class=\"hljs-comment\">// Complexity analysis\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> codeBlocks = (\u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">content\u003C/span>.\u003Cspan class=\"hljs-title function_\">match\u003C/span>(\u003Cspan class=\"hljs-regexp\">/```/g\u003C/span>) || []).\u003Cspan class=\"hljs-property\">length\u003C/span> / \u003Cspan class=\"hljs-number\">2\u003C/span>;\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> tables = (\u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">content\u003C/span>.\u003Cspan class=\"hljs-title function_\">match\u003C/span>(\u003Cspan class=\"hljs-regexp\">/\\|/g\u003C/span>) || []).\u003Cspan class=\"hljs-property\">length\u003C/span>;\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> links = (\u003Cspan class=\"hljs-variable language_\">document\u003C/span>.\u003Cspan class=\"hljs-property\">content\u003C/span>.\u003Cspan class=\"hljs-title function_\">match\u003C/span>(\u003Cspan class=\"hljs-regexp\">/\\]/g\u003C/span>) || []).\u003Cspan class=\"hljs-property\">length\u003C/span>;\n        \n        metrics.\u003Cspan class=\"hljs-property\">complexity\u003C/span> = codeBlocks * \u003Cspan class=\"hljs-number\">2\u003C/span> + tables * \u003Cspan class=\"hljs-number\">0.5\u003C/span> + links * \u003Cspan class=\"hljs-number\">0.1\u003C/span>;\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (metrics.\u003Cspan class=\"hljs-property\">complexity\u003C/span> &gt; \u003Cspan class=\"hljs-number\">50\u003C/span>) {\n            warnings.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                \u003Cspan class=\"hljs-attr\">type\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;performance&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">`High complexity score: \u003Cspan class=\"hljs-subst\">${metrics.complexity.toFixed(\u003Cspan class=\"hljs-number\">1\u003C/span>)}\u003C/span> (consider simplifying)`\u003C/span>\n            });\n        }\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> {\n            \u003Cspan class=\"hljs-attr\">passed\u003C/span>: issues.\u003Cspan class=\"hljs-title function_\">filter\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">i\u003C/span> =&gt;\u003C/span> i.\u003Cspan class=\"hljs-property\">severity\u003C/span> === \u003Cspan class=\"hljs-string\">&#x27;high&#x27;\u003C/span>).\u003Cspan class=\"hljs-property\">length\u003C/span> === \u003Cspan class=\"hljs-number\">0\u003C/span>,\n            issues,\n            warnings,\n            metrics\n        };\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">findUnmatchedCodeBlockLine\u003C/span>(\u003Cspan class=\"hljs-params\">content\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> lines = content.\u003Cspan class=\"hljs-title function_\">split\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;\\n&#x27;\u003C/span>);\n        \u003Cspan class=\"hljs-keyword\">let\u003C/span> codeBlockCount = \u003Cspan class=\"hljs-number\">0\u003C/span>;\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> (\u003Cspan class=\"hljs-keyword\">let\u003C/span> i = \u003Cspan class=\"hljs-number\">0\u003C/span>; i &lt; lines.\u003Cspan class=\"hljs-property\">length\u003C/span>; i++) {\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> (lines[i].\u003Cspan class=\"hljs-title function_\">includes\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;```&#x27;\u003C/span>)) {\n                codeBlockCount++;\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> (codeBlockCount % \u003Cspan class=\"hljs-number\">2\u003C/span> !== \u003Cspan class=\"hljs-number\">0\u003C/span>) {\n                    \u003Cspan class=\"hljs-comment\">// Return line number of last unmatched opening\u003C/span>\n                    \u003Cspan class=\"hljs-keyword\">return\u003C/span> i + \u003Cspan class=\"hljs-number\">1\u003C/span>;\n                }\n            }\n        }\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-literal\">null\u003C/span>;\n    }\n    \n    \u003Cspan class=\"hljs-title function_\">aggregateResults\u003C/span>(\u003Cspan class=\"hljs-params\">batchResults\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> (\u003Cspan class=\"hljs-keyword\">const\u003C/span> batch \u003Cspan class=\"hljs-keyword\">of\u003C/span> batchResults) {\n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> (\u003Cspan class=\"hljs-keyword\">const\u003C/span> fileResult \u003Cspan class=\"hljs-keyword\">of\u003C/span> batch) {\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> (fileResult.\u003Cspan class=\"hljs-property\">passed\u003C/span>) {\n                    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">testResults\u003C/span>.\u003Cspan class=\"hljs-property\">passed\u003C/span>++;\n                } \u003Cspan class=\"hljs-keyword\">else\u003C/span> {\n                    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">testResults\u003C/span>.\u003Cspan class=\"hljs-property\">failed\u003C/span>++;\n                    \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">testResults\u003C/span>.\u003Cspan class=\"hljs-property\">errors\u003C/span>.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                        \u003Cspan class=\"hljs-attr\">file\u003C/span>: fileResult.\u003Cspan class=\"hljs-property\">file\u003C/span>,\n                        \u003Cspan class=\"hljs-attr\">issues\u003C/span>: fileResult.\u003Cspan class=\"hljs-property\">tests\u003C/span>.\u003Cspan class=\"hljs-title function_\">filter\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">t\u003C/span> =&gt;\u003C/span> !t.\u003Cspan class=\"hljs-property\">passed\u003C/span>)\n                    });\n                }\n                \n                \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">testResults\u003C/span>.\u003Cspan class=\"hljs-property\">warnings\u003C/span> += fileResult.\u003Cspan class=\"hljs-property\">warnings\u003C/span>.\u003Cspan class=\"hljs-property\">length\u003C/span>;\n                \n                \u003Cspan class=\"hljs-comment\">// Collect performance data\u003C/span>\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> (fileResult.\u003Cspan class=\"hljs-property\">performance\u003C/span>) {\n                    \u003Cspan class=\"hljs-keyword\">for\u003C/span> (\u003Cspan class=\"hljs-keyword\">const\u003C/span> [testType, duration] \u003Cspan class=\"hljs-keyword\">of\u003C/span> \u003Cspan class=\"hljs-title class_\">Object\u003C/span>.\u003Cspan class=\"hljs-title function_\">entries\u003C/span>(fileResult.\u003Cspan class=\"hljs-property\">performance\u003C/span>)) {\n                        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (!\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">testResults\u003C/span>.\u003Cspan class=\"hljs-property\">performance\u003C/span>[testType]) {\n                            \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">testResults\u003C/span>.\u003Cspan class=\"hljs-property\">performance\u003C/span>[testType] = [];\n                        }\n                        \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">testResults\u003C/span>.\u003Cspan class=\"hljs-property\">performance\u003C/span>[testType].\u003Cspan class=\"hljs-title function_\">push\u003C/span>(duration);\n                    }\n                }\n            }\n        }\n    }\n    \n    \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">generateTestReport\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> report = {\n            \u003Cspan class=\"hljs-attr\">summary\u003C/span>: {\n                \u003Cspan class=\"hljs-attr\">totalFiles\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">testResults\u003C/span>.\u003Cspan class=\"hljs-property\">passed\u003C/span> + \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">testResults\u003C/span>.\u003Cspan class=\"hljs-property\">failed\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">passed\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">testResults\u003C/span>.\u003Cspan class=\"hljs-property\">passed\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">failed\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">testResults\u003C/span>.\u003Cspan class=\"hljs-property\">failed\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">warnings\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">testResults\u003C/span>.\u003Cspan class=\"hljs-property\">warnings\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">passRate\u003C/span>: ((\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">testResults\u003C/span>.\u003Cspan class=\"hljs-property\">passed\u003C/span> / (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">testResults\u003C/span>.\u003Cspan class=\"hljs-property\">passed\u003C/span> + \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">testResults\u003C/span>.\u003Cspan class=\"hljs-property\">failed\u003C/span>)) * \u003Cspan class=\"hljs-number\">100\u003C/span>).\u003Cspan class=\"hljs-title function_\">toFixed\u003C/span>(\u003Cspan class=\"hljs-number\">1\u003C/span>)\n            },\n            \u003Cspan class=\"hljs-attr\">errors\u003C/span>: \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">testResults\u003C/span>.\u003Cspan class=\"hljs-property\">errors\u003C/span>,\n            \u003Cspan class=\"hljs-attr\">performance\u003C/span>: {},\n            \u003Cspan class=\"hljs-attr\">recommendations\u003C/span>: []\n        };\n        \n        \u003Cspan class=\"hljs-comment\">// Calculate performance statistics\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> (\u003Cspan class=\"hljs-keyword\">const\u003C/span> [testType, durations] \u003Cspan class=\"hljs-keyword\">of\u003C/span> \u003Cspan class=\"hljs-title class_\">Object\u003C/span>.\u003Cspan class=\"hljs-title function_\">entries\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">testResults\u003C/span>.\u003Cspan class=\"hljs-property\">performance\u003C/span>)) {\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> avg = durations.\u003Cspan class=\"hljs-title function_\">reduce\u003C/span>(\u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">a, b\u003C/span>) =&gt;\u003C/span> a + b, \u003Cspan class=\"hljs-number\">0\u003C/span>) / durations.\u003Cspan class=\"hljs-property\">length\u003C/span>;\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> max = \u003Cspan class=\"hljs-title class_\">Math\u003C/span>.\u003Cspan class=\"hljs-title function_\">max\u003C/span>(...durations);\n            \u003Cspan class=\"hljs-keyword\">const\u003C/span> min = \u003Cspan class=\"hljs-title class_\">Math\u003C/span>.\u003Cspan class=\"hljs-title function_\">min\u003C/span>(...durations);\n            \n            report.\u003Cspan class=\"hljs-property\">performance\u003C/span>[testType] = {\n                \u003Cspan class=\"hljs-attr\">average\u003C/span>: \u003Cspan class=\"hljs-title class_\">Math\u003C/span>.\u003Cspan class=\"hljs-title function_\">round\u003C/span>(avg),\n                \u003Cspan class=\"hljs-attr\">maximum\u003C/span>: max,\n                \u003Cspan class=\"hljs-attr\">minimum\u003C/span>: min,\n                \u003Cspan class=\"hljs-attr\">total\u003C/span>: durations.\u003Cspan class=\"hljs-title function_\">reduce\u003C/span>(\u003Cspan class=\"hljs-function\">(\u003Cspan class=\"hljs-params\">a, b\u003C/span>) =&gt;\u003C/span> a + b, \u003Cspan class=\"hljs-number\">0\u003C/span>)\n            };\n        }\n        \n        \u003Cspan class=\"hljs-comment\">// Generate recommendations\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (report.\u003Cspan class=\"hljs-property\">summary\u003C/span>.\u003Cspan class=\"hljs-property\">passRate\u003C/span> &lt; \u003Cspan class=\"hljs-number\">80\u003C/span>) {\n            report.\u003Cspan class=\"hljs-property\">recommendations\u003C/span>.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                \u003Cspan class=\"hljs-attr\">priority\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;high&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Pass rate is below 80%. Focus on fixing critical syntax and link issues.&#x27;\u003C/span>\n            });\n        }\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> (\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">testResults\u003C/span>.\u003Cspan class=\"hljs-property\">warnings\u003C/span> &gt; \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">testResults\u003C/span>.\u003Cspan class=\"hljs-property\">passed\u003C/span> * \u003Cspan class=\"hljs-number\">2\u003C/span>) {\n            report.\u003Cspan class=\"hljs-property\">recommendations\u003C/span>.\u003Cspan class=\"hljs-title function_\">push\u003C/span>({\n                \u003Cspan class=\"hljs-attr\">priority\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;medium&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">message\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;High warning count suggests content quality improvements needed.&#x27;\u003C/span>\n            });\n        }\n        \n        \u003Cspan class=\"hljs-comment\">// Save report to file\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> reportPath = path.\u003Cspan class=\"hljs-title function_\">join\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">config\u003C/span>.\u003Cspan class=\"hljs-property\">testOutputDirectory\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;test-report.json&#x27;\u003C/span>);\n        \u003Cspan class=\"hljs-keyword\">await\u003C/span> fs.\u003Cspan class=\"hljs-title function_\">mkdir\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">config\u003C/span>.\u003Cspan class=\"hljs-property\">testOutputDirectory\u003C/span>, { \u003Cspan class=\"hljs-attr\">recursive\u003C/span>: \u003Cspan class=\"hljs-literal\">true\u003C/span> });\n        \u003Cspan class=\"hljs-keyword\">await\u003C/span> fs.\u003Cspan class=\"hljs-title function_\">writeFile\u003C/span>(reportPath, \u003Cspan class=\"hljs-title class_\">JSON\u003C/span>.\u003Cspan class=\"hljs-title function_\">stringify\u003C/span>(report, \u003Cspan class=\"hljs-literal\">null\u003C/span>, \u003Cspan class=\"hljs-number\">2\u003C/span>));\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> report;\n    }\n    \n    \u003Cspan class=\"hljs-keyword\">async\u003C/span> \u003Cspan class=\"hljs-title function_\">runContinuousTests\u003C/span>(\u003Cspan class=\"hljs-params\">\u003C/span>) {\n        \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;🔄 Starting continuous testing mode...&#x27;\u003C/span>);\n        \n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> chokidar = \u003Cspan class=\"hljs-built_in\">require\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;chokidar&#x27;\u003C/span>);\n        \u003Cspan class=\"hljs-keyword\">const\u003C/span> watcher = chokidar.\u003Cspan class=\"hljs-title function_\">watch\u003C/span>(\n            path.\u003Cspan class=\"hljs-title function_\">join\u003C/span>(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-property\">config\u003C/span>.\u003Cspan class=\"hljs-property\">contentDirectory\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;**/*.md&#x27;\u003C/span>),\n            { \u003Cspan class=\"hljs-attr\">ignoreInitial\u003C/span>: \u003Cspan class=\"hljs-literal\">true\u003C/span> }\n        );\n        \n        watcher.\u003Cspan class=\"hljs-title function_\">on\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;change&#x27;\u003C/span>, \u003Cspan class=\"hljs-keyword\">async\u003C/span> (filePath) =&gt; {\n            \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(\u003Cspan class=\"hljs-string\">`📝 File changed: \u003Cspan class=\"hljs-subst\">${path.relative(\u003Cspan class=\"hljs-variable language_\">this\u003C/span>.config.contentDirectory, filePath)}\u003C/span>`\u003C/span>);\n            \n            \u003Cspan class=\"hljs-keyword\">try\u003C/span> {\n                \u003Cspan class=\"hljs-keyword\">const\u003C/span> result = \u003Cspan class=\"hljs-keyword\">await\u003C/span> \u003Cspan class=\"hljs-variable language_\">this\u003C/span>.\u003Cspan class=\"hljs-title function_\">testFile\u003C/span>(filePath);\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> (result.\u003Cspan class=\"hljs-property\">passed\u003C/span>) {\n                    \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;✅ Tests passed&#x27;\u003C/span>);\n                } \u003Cspan class=\"hljs-keyword\">else\u003C/span> {\n                    \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;❌ Tests failed&#x27;\u003C/span>);\n                    \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">log\u003C/span>(result.\u003Cspan class=\"hljs-property\">tests\u003C/span>.\u003Cspan class=\"hljs-title function_\">filter\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">t\u003C/span> =&gt;\u003C/span> !t.\u003Cspan class=\"hljs-property\">passed\u003C/span>).\u003Cspan class=\"hljs-title function_\">map\u003C/span>(\u003Cspan class=\"hljs-function\">\u003Cspan class=\"hljs-params\">t\u003C/span> =&gt;\u003C/span> \u003Cspan class=\"hljs-string\">`  - \u003Cspan class=\"hljs-subst\">${t.name}\u003C/span>: \u003Cspan class=\"hljs-subst\">${t.error || \u003Cspan class=\"hljs-string\">&#x27;failed&#x27;\u003C/span>}\u003C/span>`\u003C/span>).\u003Cspan class=\"hljs-title function_\">join\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;\\n&#x27;\u003C/span>));\n                }\n            } \u003Cspan class=\"hljs-keyword\">catch\u003C/span> (error) {\n                \u003Cspan class=\"hljs-variable language_\">console\u003C/span>.\u003Cspan class=\"hljs-title function_\">error\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;❌ Test error:&#x27;\u003C/span>, error.\u003Cspan class=\"hljs-property\">message\u003C/span>);\n            }\n        });\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> watcher;\n    }\n}\n\n\u003Cspan class=\"hljs-variable language_\">module\u003C/span>.\u003Cspan class=\"hljs-property\">exports\u003C/span> = \u003Cspan class=\"hljs-title class_\">MarkdownTestingFramework\u003C/span>;\n\u003C/code>\u003C/pre>\u003Ch3 id=\"cicd-integration-pipeline\">CI/CD Integration Pipeline\u003C/h3>\n\u003Cp>Advanced continuous integration setup for automated testing:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-yaml\">\u003Cspan class=\"hljs-comment\"># .github/workflows/markdown-testing.yml - Comprehensive CI/CD pipeline\u003C/span>\n\u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Markdown\u003C/span> \u003Cspan class=\"hljs-string\">Testing\u003C/span> \u003Cspan class=\"hljs-string\">and\u003C/span> \u003Cspan class=\"hljs-string\">Validation\u003C/span>\n\n\u003Cspan class=\"hljs-attr\">on:\u003C/span>\n  \u003Cspan class=\"hljs-attr\">push:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">branches:\u003C/span> [ \u003Cspan class=\"hljs-string\">main\u003C/span>, \u003Cspan class=\"hljs-string\">develop\u003C/span> ]\n    \u003Cspan class=\"hljs-attr\">paths:\u003C/span> [\u003Cspan class=\"hljs-string\">&#x27;**/*.md&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;content/**/*&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;docs/**/*&#x27;\u003C/span>]\n  \u003Cspan class=\"hljs-attr\">pull_request:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">branches:\u003C/span> [ \u003Cspan class=\"hljs-string\">main\u003C/span> ]\n    \u003Cspan class=\"hljs-attr\">paths:\u003C/span> [\u003Cspan class=\"hljs-string\">&#x27;**/*.md&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;content/**/*&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;docs/**/*&#x27;\u003C/span>]\n  \u003Cspan class=\"hljs-attr\">schedule:\u003C/span>\n    \u003Cspan class=\"hljs-comment\"># Run full validation daily at 6 AM UTC\u003C/span>\n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">cron:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;0 6 * * *&#x27;\u003C/span>\n\n\u003Cspan class=\"hljs-attr\">env:\u003C/span>\n  \u003Cspan class=\"hljs-attr\">NODE_VERSION:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;18&#x27;\u003C/span>\n  \u003Cspan class=\"hljs-attr\">PYTHON_VERSION:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;3.11&#x27;\u003C/span>\n\n\u003Cspan class=\"hljs-attr\">jobs:\u003C/span>\n  \u003Cspan class=\"hljs-attr\">markdown-validation:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Markdown\u003C/span> \u003Cspan class=\"hljs-string\">Syntax\u003C/span> \u003Cspan class=\"hljs-string\">and\u003C/span> \u003Cspan class=\"hljs-string\">Structure\u003C/span> \u003Cspan class=\"hljs-string\">Validation\u003C/span>\n    \u003Cspan class=\"hljs-attr\">runs-on:\u003C/span> \u003Cspan class=\"hljs-string\">ubuntu-latest\u003C/span>\n    \n    \u003Cspan class=\"hljs-attr\">steps:\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Checkout\u003C/span> \u003Cspan class=\"hljs-string\">repository\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/checkout@v4\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">fetch-depth:\u003C/span> \u003Cspan class=\"hljs-number\">0\u003C/span>\n      \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Setup\u003C/span> \u003Cspan class=\"hljs-string\">Node.js\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/setup-node@v4\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">node-version:\u003C/span> \u003Cspan class=\"hljs-string\">${{\u003C/span> \u003Cspan class=\"hljs-string\">env.NODE_VERSION\u003C/span> \u003Cspan class=\"hljs-string\">}}\u003C/span>\n          \u003Cspan class=\"hljs-attr\">cache:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;npm&#x27;\u003C/span>\n      \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Install\u003C/span> \u003Cspan class=\"hljs-string\">dependencies\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          npm install -g markdownlint-cli2\n          npm install markdown-it jsdom axios gray-matter chokidar\n\u003C/span>      \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Run\u003C/span> \u003Cspan class=\"hljs-string\">markdown\u003C/span> \u003Cspan class=\"hljs-string\">linting\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          markdownlint-cli2 &quot;**/*.md&quot; --config .markdownlint.json --fix\n\u003C/span>          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Run\u003C/span> \u003Cspan class=\"hljs-string\">comprehensive\u003C/span> \u003Cspan class=\"hljs-string\">validation\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          node scripts/test-markdown.js --config .markdown-test-config.json\n\u003C/span>      \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Upload\u003C/span> \u003Cspan class=\"hljs-string\">validation\u003C/span> \u003Cspan class=\"hljs-string\">results\u003C/span>\n        \u003Cspan class=\"hljs-attr\">if:\u003C/span> \u003Cspan class=\"hljs-string\">always()\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/upload-artifact@v4\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">markdown-validation-results\u003C/span>\n          \u003Cspan class=\"hljs-attr\">path:\u003C/span> \u003Cspan class=\"hljs-string\">test-results/\u003C/span>\n          \u003Cspan class=\"hljs-attr\">retention-days:\u003C/span> \u003Cspan class=\"hljs-number\">30\u003C/span>\n  \n  \u003Cspan class=\"hljs-attr\">link-validation:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Link\u003C/span> \u003Cspan class=\"hljs-string\">Integrity\u003C/span> \u003Cspan class=\"hljs-string\">Check\u003C/span>\n    \u003Cspan class=\"hljs-attr\">runs-on:\u003C/span> \u003Cspan class=\"hljs-string\">ubuntu-latest\u003C/span>\n    \u003Cspan class=\"hljs-attr\">if:\u003C/span> \u003Cspan class=\"hljs-string\">github.event_name\u003C/span> \u003Cspan class=\"hljs-type\">!=\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;schedule&#x27;\u003C/span> \u003Cspan class=\"hljs-comment\"># Skip for scheduled runs to avoid rate limits\u003C/span>\n    \n    \u003Cspan class=\"hljs-attr\">steps:\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Checkout\u003C/span> \u003Cspan class=\"hljs-string\">repository\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/checkout@v4\u003C/span>\n      \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Setup\u003C/span> \u003Cspan class=\"hljs-string\">Node.js\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/setup-node@v4\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">node-version:\u003C/span> \u003Cspan class=\"hljs-string\">${{\u003C/span> \u003Cspan class=\"hljs-string\">env.NODE_VERSION\u003C/span> \u003Cspan class=\"hljs-string\">}}\u003C/span>\n      \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Install\u003C/span> \u003Cspan class=\"hljs-string\">link\u003C/span> \u003Cspan class=\"hljs-string\">checker\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">npm\u003C/span> \u003Cspan class=\"hljs-string\">install\u003C/span> \u003Cspan class=\"hljs-string\">-g\u003C/span> \u003Cspan class=\"hljs-string\">markdown-link-check\u003C/span>\n      \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Check\u003C/span> \u003Cspan class=\"hljs-string\">internal\u003C/span> \u003Cspan class=\"hljs-string\">links\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          find . -name &quot;*.md&quot; -not -path &quot;./node_modules/*&quot; -not -path &quot;./.git/*&quot; | \\\n          xargs -I {} markdown-link-check {} --config .markdown-link-check.json\n\u003C/span>      \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Check\u003C/span> \u003Cspan class=\"hljs-string\">external\u003C/span> \u003Cspan class=\"hljs-string\">links\u003C/span> \u003Cspan class=\"hljs-string\">(rate\u003C/span> \u003Cspan class=\"hljs-string\">limited)\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          # Rate-limited external link checking\n          find . -name &quot;*.md&quot; -not -path &quot;./node_modules/*&quot; | \\\n          head -20 | \\\n          xargs -I {} markdown-link-check {} --config .markdown-link-check-external.json\n\u003C/span>\n  \u003Cspan class=\"hljs-attr\">accessibility-testing:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Accessibility\u003C/span> \u003Cspan class=\"hljs-string\">Validation\u003C/span>\n    \u003Cspan class=\"hljs-attr\">runs-on:\u003C/span> \u003Cspan class=\"hljs-string\">ubuntu-latest\u003C/span>\n    \n    \u003Cspan class=\"hljs-attr\">steps:\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Checkout\u003C/span> \u003Cspan class=\"hljs-string\">repository\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/checkout@v4\u003C/span>\n      \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Setup\u003C/span> \u003Cspan class=\"hljs-string\">Python\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/setup-python@v4\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">python-version:\u003C/span> \u003Cspan class=\"hljs-string\">${{\u003C/span> \u003Cspan class=\"hljs-string\">env.PYTHON_VERSION\u003C/span> \u003Cspan class=\"hljs-string\">}}\u003C/span>\n      \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Install\u003C/span> \u003Cspan class=\"hljs-string\">accessibility\u003C/span> \u003Cspan class=\"hljs-string\">tools\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          pip install beautifulsoup4 requests markdown\n          npm install -g @axe-core/cli\n\u003C/span>      \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Run\u003C/span> \u003Cspan class=\"hljs-string\">accessibility\u003C/span> \u003Cspan class=\"hljs-string\">tests\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          python scripts/accessibility-test.py --input-dir content/ --output-dir test-results/accessibility/\n\u003C/span>      \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Upload\u003C/span> \u003Cspan class=\"hljs-string\">accessibility\u003C/span> \u003Cspan class=\"hljs-string\">results\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/upload-artifact@v4\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">accessibility-test-results\u003C/span>\n          \u003Cspan class=\"hljs-attr\">path:\u003C/span> \u003Cspan class=\"hljs-string\">test-results/accessibility/\u003C/span>\n\n  \u003Cspan class=\"hljs-attr\">performance-testing:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Content\u003C/span> \u003Cspan class=\"hljs-string\">Performance\u003C/span> \u003Cspan class=\"hljs-string\">Analysis\u003C/span>\n    \u003Cspan class=\"hljs-attr\">runs-on:\u003C/span> \u003Cspan class=\"hljs-string\">ubuntu-latest\u003C/span>\n    \n    \u003Cspan class=\"hljs-attr\">steps:\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Checkout\u003C/span> \u003Cspan class=\"hljs-string\">repository\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/checkout@v4\u003C/span>\n      \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Setup\u003C/span> \u003Cspan class=\"hljs-string\">Node.js\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/setup-node@v4\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">node-version:\u003C/span> \u003Cspan class=\"hljs-string\">${{\u003C/span> \u003Cspan class=\"hljs-string\">env.NODE_VERSION\u003C/span> \u003Cspan class=\"hljs-string\">}}\u003C/span>\n      \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Install\u003C/span> \u003Cspan class=\"hljs-string\">performance\u003C/span> \u003Cspan class=\"hljs-string\">testing\u003C/span> \u003Cspan class=\"hljs-string\">tools\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          npm install -g lighthouse-ci puppeteer\n          npm install markdown-it benchmark\n\u003C/span>      \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Build\u003C/span> \u003Cspan class=\"hljs-string\">site\u003C/span> \u003Cspan class=\"hljs-string\">for\u003C/span> \u003Cspan class=\"hljs-string\">testing\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          # Build your static site (adjust for your generator)\n          npm run build || bundle exec jekyll build || hugo build\n\u003C/span>      \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Run\u003C/span> \u003Cspan class=\"hljs-string\">performance\u003C/span> \u003Cspan class=\"hljs-string\">analysis\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          node scripts/performance-test.js --site-dir _site/ --output test-results/performance/\n\u003C/span>      \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Upload\u003C/span> \u003Cspan class=\"hljs-string\">performance\u003C/span> \u003Cspan class=\"hljs-string\">results\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/upload-artifact@v4\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">performance-test-results\u003C/span>\n          \u003Cspan class=\"hljs-attr\">path:\u003C/span> \u003Cspan class=\"hljs-string\">test-results/performance/\u003C/span>\n\n  \u003Cspan class=\"hljs-attr\">content-quality:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Content\u003C/span> \u003Cspan class=\"hljs-string\">Quality\u003C/span> \u003Cspan class=\"hljs-string\">Assessment\u003C/span>\n    \u003Cspan class=\"hljs-attr\">runs-on:\u003C/span> \u003Cspan class=\"hljs-string\">ubuntu-latest\u003C/span>\n    \n    \u003Cspan class=\"hljs-attr\">steps:\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Checkout\u003C/span> \u003Cspan class=\"hljs-string\">repository\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/checkout@v4\u003C/span>\n      \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Setup\u003C/span> \u003Cspan class=\"hljs-string\">Python\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/setup-python@v4\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">python-version:\u003C/span> \u003Cspan class=\"hljs-string\">${{\u003C/span> \u003Cspan class=\"hljs-string\">env.PYTHON_VERSION\u003C/span> \u003Cspan class=\"hljs-string\">}}\u003C/span>\n      \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Install\u003C/span> \u003Cspan class=\"hljs-string\">quality\u003C/span> \u003Cspan class=\"hljs-string\">analysis\u003C/span> \u003Cspan class=\"hljs-string\">tools\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          pip install textstat nltk spacy\n          python -m spacy download en_core_web_sm\n\u003C/span>      \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Run\u003C/span> \u003Cspan class=\"hljs-string\">content\u003C/span> \u003Cspan class=\"hljs-string\">quality\u003C/span> \u003Cspan class=\"hljs-string\">analysis\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          python scripts/content-quality.py --input content/ --output test-results/quality/\n\u003C/span>          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Generate\u003C/span> \u003Cspan class=\"hljs-string\">quality\u003C/span> \u003Cspan class=\"hljs-string\">report\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          python scripts/generate-quality-report.py --results test-results/ --output test-results/final-report.html\n\u003C/span>\n  \u003Cspan class=\"hljs-attr\">security-scanning:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Content\u003C/span> \u003Cspan class=\"hljs-string\">Security\u003C/span> \u003Cspan class=\"hljs-string\">Scanning\u003C/span>\n    \u003Cspan class=\"hljs-attr\">runs-on:\u003C/span> \u003Cspan class=\"hljs-string\">ubuntu-latest\u003C/span>\n    \n    \u003Cspan class=\"hljs-attr\">steps:\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Checkout\u003C/span> \u003Cspan class=\"hljs-string\">repository\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/checkout@v4\u003C/span>\n      \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Scan\u003C/span> \u003Cspan class=\"hljs-string\">for\u003C/span> \u003Cspan class=\"hljs-string\">sensitive\u003C/span> \u003Cspan class=\"hljs-string\">information\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          # Check for accidentally committed secrets, API keys, etc.\n          grep -r -i -E &quot;(api[_-]?key|password|secret|token)&quot; --include=&quot;*.md&quot; . || true\n\u003C/span>          \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Check\u003C/span> \u003Cspan class=\"hljs-string\">for\u003C/span> \u003Cspan class=\"hljs-string\">malicious\u003C/span> \u003Cspan class=\"hljs-string\">links\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          # Basic malicious domain checking\n          python scripts/security-scan.py --input content/ --output test-results/security/\n\u003C/span>\n  \u003Cspan class=\"hljs-attr\">test-reporting:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Aggregate\u003C/span> \u003Cspan class=\"hljs-string\">Test\u003C/span> \u003Cspan class=\"hljs-string\">Results\u003C/span>\n    \u003Cspan class=\"hljs-attr\">runs-on:\u003C/span> \u003Cspan class=\"hljs-string\">ubuntu-latest\u003C/span>\n    \u003Cspan class=\"hljs-attr\">needs:\u003C/span> [\u003Cspan class=\"hljs-string\">markdown-validation\u003C/span>, \u003Cspan class=\"hljs-string\">link-validation\u003C/span>, \u003Cspan class=\"hljs-string\">accessibility-testing\u003C/span>, \u003Cspan class=\"hljs-string\">performance-testing\u003C/span>, \u003Cspan class=\"hljs-string\">content-quality\u003C/span>]\n    \u003Cspan class=\"hljs-attr\">if:\u003C/span> \u003Cspan class=\"hljs-string\">always()\u003C/span>\n    \n    \u003Cspan class=\"hljs-attr\">steps:\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Checkout\u003C/span> \u003Cspan class=\"hljs-string\">repository\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/checkout@v4\u003C/span>\n      \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Download\u003C/span> \u003Cspan class=\"hljs-string\">all\u003C/span> \u003Cspan class=\"hljs-string\">test\u003C/span> \u003Cspan class=\"hljs-string\">results\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/download-artifact@v4\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">path:\u003C/span> \u003Cspan class=\"hljs-string\">all-test-results/\u003C/span>\n      \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Setup\u003C/span> \u003Cspan class=\"hljs-string\">Python\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/setup-python@v4\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">python-version:\u003C/span> \u003Cspan class=\"hljs-string\">${{\u003C/span> \u003Cspan class=\"hljs-string\">env.PYTHON_VERSION\u003C/span> \u003Cspan class=\"hljs-string\">}}\u003C/span>\n      \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Install\u003C/span> \u003Cspan class=\"hljs-string\">reporting\u003C/span> \u003Cspan class=\"hljs-string\">tools\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          pip install jinja2 markdown\n\u003C/span>      \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Generate\u003C/span> \u003Cspan class=\"hljs-string\">comprehensive\u003C/span> \u003Cspan class=\"hljs-string\">report\u003C/span>\n        \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          python scripts/generate-test-report.py --input all-test-results/ --output final-test-report/\n\u003C/span>      \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Upload\u003C/span> \u003Cspan class=\"hljs-string\">final\u003C/span> \u003Cspan class=\"hljs-string\">report\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/upload-artifact@v4\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">comprehensive-test-report\u003C/span>\n          \u003Cspan class=\"hljs-attr\">path:\u003C/span> \u003Cspan class=\"hljs-string\">final-test-report/\u003C/span>\n          \u003Cspan class=\"hljs-attr\">retention-days:\u003C/span> \u003Cspan class=\"hljs-number\">90\u003C/span>\n      \n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Comment\u003C/span> \u003Cspan class=\"hljs-string\">PR\u003C/span> \u003Cspan class=\"hljs-string\">with\u003C/span> \u003Cspan class=\"hljs-string\">results\u003C/span>\n        \u003Cspan class=\"hljs-attr\">if:\u003C/span> \u003Cspan class=\"hljs-string\">github.event_name\u003C/span> \u003Cspan class=\"hljs-string\">==\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;pull_request&#x27;\u003C/span>\n        \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/github-script@v7\u003C/span>\n        \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n          \u003Cspan class=\"hljs-attr\">script:\u003C/span> \u003Cspan class=\"hljs-string\">|\n            const fs = require(&#x27;fs&#x27;);\n            const path = &#x27;final-test-report/summary.json&#x27;;\n\u003C/span>            \n            \u003Cspan class=\"hljs-string\">if\u003C/span> \u003Cspan class=\"hljs-string\">(fs.existsSync(path))\u003C/span> {\n              \u003Cspan class=\"hljs-string\">const\u003C/span> \u003Cspan class=\"hljs-string\">summary\u003C/span> \u003Cspan class=\"hljs-string\">=\u003C/span> \u003Cspan class=\"hljs-string\">JSON.parse(fs.readFileSync(path\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;utf8&#x27;\u003C/span>\u003Cspan class=\"hljs-string\">));\u003C/span>\n              \n              \u003Cspan class=\"hljs-string\">const\u003C/span> \u003Cspan class=\"hljs-string\">comment\u003C/span> \u003Cspan class=\"hljs-string\">=\u003C/span> \u003Cspan class=\"hljs-string\">`##\u003C/span> \u003Cspan class=\"hljs-string\">📊\u003C/span> \u003Cspan class=\"hljs-string\">Markdown\u003C/span> \u003Cspan class=\"hljs-string\">Testing\u003C/span> \u003Cspan class=\"hljs-string\">Results\u003C/span>\n              \n              \u003Cspan class=\"hljs-string\">|\u003C/span> \u003Cspan class=\"hljs-string\">Test\u003C/span> \u003Cspan class=\"hljs-string\">Category\u003C/span> \u003Cspan class=\"hljs-string\">|\u003C/span> \u003Cspan class=\"hljs-string\">Status\u003C/span> \u003Cspan class=\"hljs-string\">|\u003C/span> \u003Cspan class=\"hljs-string\">Details\u003C/span> \u003Cspan class=\"hljs-string\">|\n              |---------------|---------|---------|\n              | Syntax &amp; Structure | ${summary.syntax.passed ? &#x27;✅&#x27; : &#x27;❌&#x27;} | ${summary.syntax.passed}/${summary.syntax.total} files passed |\n              | Link Integrity | ${summary.links.passed ? &#x27;✅&#x27; : &#x27;❌&#x27;} | ${summary.links.broken} broken links found |\n              | Accessibility | ${summary.accessibility.passed ? &#x27;✅&#x27; : &#x27;⚠️&#x27;} | ${summary.accessibility.issues} issues found |\n              | Performance | ${summary.performance.passed ? &#x27;✅&#x27; : &#x27;⚠️&#x27;} | Avg render time: ${summary.performance.avgRenderTime}ms |\n              | Content Quality | ${summary.quality.score &gt;= 80 ? &#x27;✅&#x27; : &#x27;⚠️&#x27;} | Quality score: ${summary.quality.score}/100 |\n\u003C/span>              \n              \u003Cspan class=\"hljs-string\">**Overall\u003C/span> \u003Cspan class=\"hljs-string\">Status:**\u003C/span> \u003Cspan class=\"hljs-string\">$\u003C/span>{\u003Cspan class=\"hljs-string\">summary.overall.passed\u003C/span> \u003Cspan class=\"hljs-string\">?\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;✅ PASSED&#x27;\u003C/span> \u003Cspan class=\"hljs-string\">:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;❌ FAILED&#x27;\u003C/span>}\n              \n              \u003Cspan class=\"hljs-string\">View\u003C/span> \u003Cspan class=\"hljs-string\">detailed\u003C/span> \u003Cspan class=\"hljs-string\">results\u003C/span> \u003Cspan class=\"hljs-string\">in\u003C/span> \u003Cspan class=\"hljs-string\">the\u003C/span> [\u003Cspan class=\"hljs-string\">test\u003C/span> \u003Cspan class=\"hljs-string\">artifacts\u003C/span>]\u003Cspan class=\"hljs-string\">($\u003C/span>{\u003Cspan class=\"hljs-string\">context.payload.pull_request.html_url\u003C/span>}\u003Cspan class=\"hljs-string\">/checks).`;\u003C/span>\n              \n              \u003Cspan class=\"hljs-string\">github.rest.issues.createComment(\u003C/span>{\n                \u003Cspan class=\"hljs-attr\">issue_number:\u003C/span> \u003Cspan class=\"hljs-string\">context.issue.number\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">owner:\u003C/span> \u003Cspan class=\"hljs-string\">context.repo.owner\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">repo:\u003C/span> \u003Cspan class=\"hljs-string\">context.repo.repo\u003C/span>,\n                \u003Cspan class=\"hljs-attr\">body:\u003C/span> \u003Cspan class=\"hljs-string\">comment\u003C/span>\n              }\u003Cspan class=\"hljs-string\">);\u003C/span>\n            }\n\u003C/code>\u003C/pre>\u003Ch2 id=\"integration-with-modern-development-workflows\">Integration with Modern Development Workflows\u003C/h2>\n\u003Cp>Advanced Markdown testing integrates seamlessly with comprehensive development ecosystems. When combined with \u003Ca href=\"/blog/markdown-workflow-automation-and-productivity-complete-guide\">workflow automation and productivity systems\u003C/a>, automated testing ensures that productivity improvements don&#39;t compromise content quality, providing continuous validation that maintains standards while enabling efficient content creation and management.\u003C/p>\n\u003Cp>For sophisticated content management, testing frameworks complement \u003Ca href=\"/blog/markdown-collaborative-editing-real-time-synchronization-complete-guide\">collaborative editing and real-time synchronization systems\u003C/a> by providing quality assurance that validates collaborative changes, ensures content integrity across multiple authors, and maintains documentation standards in multi-user environments.\u003C/p>\n\u003Cp>When building scalable documentation platforms, automated testing works effectively with \u003Ca href=\"/blog/markdown-dynamic-content-generation-complete-guide\">dynamic content generation systems\u003C/a> by validating generated content, ensuring template integrity, and maintaining quality standards across automatically generated documentation while providing feedback for continuous improvement of generation algorithms.\u003C/p>\n\u003Ch2 id=\"advanced-testing-strategies\">Advanced Testing Strategies\u003C/h2>\n\u003Ch3 id=\"custom-validation-rules-engine\">Custom Validation Rules Engine\u003C/h3>\n\u003Cpre>\u003Ccode class=\"hljs language-python\">\u003Cspan class=\"hljs-comment\"># custom_validation_engine.py - Extensible validation system\u003C/span>\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> re\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> json\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> yaml\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>, \u003Cspan class=\"hljs-type\">Any\u003C/span>, \u003Cspan class=\"hljs-type\">Optional\u003C/span>\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> dataclasses \u003Cspan class=\"hljs-keyword\">import\u003C/span> dataclass\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> abc \u003Cspan class=\"hljs-keyword\">import\u003C/span> ABC, abstractmethod\n\n\u003Cspan class=\"hljs-meta\">@dataclass\u003C/span>\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">ValidationRule\u003C/span>:\n    name: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\n    description: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\n    severity: \u003Cspan class=\"hljs-built_in\">str\u003C/span>  \u003Cspan class=\"hljs-comment\"># &#x27;error&#x27;, &#x27;warning&#x27;, &#x27;info&#x27;\u003C/span>\n    category: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\n    enabled: \u003Cspan class=\"hljs-built_in\">bool\u003C/span> = \u003Cspan class=\"hljs-literal\">True\u003C/span>\n    config: \u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>] = \u003Cspan class=\"hljs-literal\">None\u003C/span>\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">BaseValidator\u003C/span>(\u003Cspan class=\"hljs-title class_ inherited__\">ABC\u003C/span>):\n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">__init__\u003C/span>(\u003Cspan class=\"hljs-params\">self, rule: ValidationRule\u003C/span>):\n        self.rule = rule\n    \n\u003Cspan class=\"hljs-meta\">    @abstractmethod\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate\u003C/span>(\u003Cspan class=\"hljs-params\">self, content: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, metadata: \u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>]\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">List\u003C/span>[\u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>]]:\n        \u003Cspan class=\"hljs-keyword\">pass\u003C/span>\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">CustomValidationEngine\u003C/span>:\n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">__init__\u003C/span>(\u003Cspan class=\"hljs-params\">self, config_file: \u003Cspan class=\"hljs-built_in\">str\u003C/span> = \u003Cspan class=\"hljs-literal\">None\u003C/span>\u003C/span>):\n        self.validators = {}\n        self.rules = []\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> config_file:\n            self.load_config(config_file)\n        \n        self.register_built_in_validators()\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">load_config\u003C/span>(\u003Cspan class=\"hljs-params\">self, config_file: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Load validation configuration from YAML or JSON file&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">with\u003C/span> \u003Cspan class=\"hljs-built_in\">open\u003C/span>(config_file, \u003Cspan class=\"hljs-string\">&#x27;r&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">as\u003C/span> f:\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> config_file.endswith(\u003Cspan class=\"hljs-string\">&#x27;.yaml&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">or\u003C/span> config_file.endswith(\u003Cspan class=\"hljs-string\">&#x27;.yml&#x27;\u003C/span>):\n                config = yaml.safe_load(f)\n            \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n                config = json.load(f)\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> rule_config \u003Cspan class=\"hljs-keyword\">in\u003C/span> config.get(\u003Cspan class=\"hljs-string\">&#x27;rules&#x27;\u003C/span>, []):\n            rule = ValidationRule(**rule_config)\n            self.rules.append(rule)\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">register_validator\u003C/span>(\u003Cspan class=\"hljs-params\">self, validator_class: \u003Cspan class=\"hljs-built_in\">type\u003C/span>, rule_name: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Register a custom validator class&quot;&quot;&quot;\u003C/span>\n        self.validators[rule_name] = validator_class\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">register_built_in_validators\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Register built-in validators&quot;&quot;&quot;\u003C/span>\n        self.register_validator(HeadingStructureValidator, \u003Cspan class=\"hljs-string\">&#x27;heading_structure&#x27;\u003C/span>)\n        self.register_validator(CodeBlockValidator, \u003Cspan class=\"hljs-string\">&#x27;code_blocks&#x27;\u003C/span>)\n        self.register_validator(LinkConsistencyValidator, \u003Cspan class=\"hljs-string\">&#x27;link_consistency&#x27;\u003C/span>)\n        self.register_validator(ContentLengthValidator, \u003Cspan class=\"hljs-string\">&#x27;content_length&#x27;\u003C/span>)\n        self.register_validator(TerminologyValidator, \u003Cspan class=\"hljs-string\">&#x27;terminology&#x27;\u003C/span>)\n        self.register_validator(ReadabilityValidator, \u003Cspan class=\"hljs-string\">&#x27;readability&#x27;\u003C/span>)\n        self.register_validator(SEOValidator, \u003Cspan class=\"hljs-string\">&#x27;seo_optimization&#x27;\u003C/span>)\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate_document\u003C/span>(\u003Cspan class=\"hljs-params\">self, content: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, metadata: \u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>] = \u003Cspan class=\"hljs-literal\">None\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>]:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate a document against all configured rules&quot;&quot;&quot;\u003C/span>\n        results = {\n            \u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&#x27;errors&#x27;\u003C/span>: [],\n            \u003Cspan class=\"hljs-string\">&#x27;warnings&#x27;\u003C/span>: [],\n            \u003Cspan class=\"hljs-string\">&#x27;info&#x27;\u003C/span>: [],\n            \u003Cspan class=\"hljs-string\">&#x27;metrics&#x27;\u003C/span>: {}\n        }\n        \n        metadata = metadata \u003Cspan class=\"hljs-keyword\">or\u003C/span> {}\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> rule \u003Cspan class=\"hljs-keyword\">in\u003C/span> self.rules:\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> rule.enabled:\n                \u003Cspan class=\"hljs-keyword\">continue\u003C/span>\n            \n            validator_class = self.validators.get(rule.category)\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> validator_class:\n                \u003Cspan class=\"hljs-keyword\">continue\u003C/span>\n            \n            \u003Cspan class=\"hljs-keyword\">try\u003C/span>:\n                validator = validator_class(rule)\n                issues = validator.validate(content, metadata)\n                \n                \u003Cspan class=\"hljs-keyword\">for\u003C/span> issue \u003Cspan class=\"hljs-keyword\">in\u003C/span> issues:\n                    issue[\u003Cspan class=\"hljs-string\">&#x27;rule&#x27;\u003C/span>] = rule.name\n                    issue[\u003Cspan class=\"hljs-string\">&#x27;category&#x27;\u003C/span>] = rule.category\n                    \n                    \u003Cspan class=\"hljs-keyword\">if\u003C/span> issue[\u003Cspan class=\"hljs-string\">&#x27;severity&#x27;\u003C/span>] == \u003Cspan class=\"hljs-string\">&#x27;error&#x27;\u003C/span>:\n                        results[\u003Cspan class=\"hljs-string\">&#x27;errors&#x27;\u003C/span>].append(issue)\n                        results[\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>] = \u003Cspan class=\"hljs-literal\">False\u003C/span>\n                    \u003Cspan class=\"hljs-keyword\">elif\u003C/span> issue[\u003Cspan class=\"hljs-string\">&#x27;severity&#x27;\u003C/span>] == \u003Cspan class=\"hljs-string\">&#x27;warning&#x27;\u003C/span>:\n                        results[\u003Cspan class=\"hljs-string\">&#x27;warnings&#x27;\u003C/span>].append(issue)\n                    \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n                        results[\u003Cspan class=\"hljs-string\">&#x27;info&#x27;\u003C/span>].append(issue)\n                \n            \u003Cspan class=\"hljs-keyword\">except\u003C/span> Exception \u003Cspan class=\"hljs-keyword\">as\u003C/span> e:\n                results[\u003Cspan class=\"hljs-string\">&#x27;errors&#x27;\u003C/span>].append({\n                    \u003Cspan class=\"hljs-string\">&#x27;rule&#x27;\u003C/span>: rule.name,\n                    \u003Cspan class=\"hljs-string\">&#x27;category&#x27;\u003C/span>: rule.category,\n                    \u003Cspan class=\"hljs-string\">&#x27;severity&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;error&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;message&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">f&#x27;Validator error: \u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-built_in\">str\u003C/span>(e)}\u003C/span>&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;line&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>\n                })\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\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">HeadingStructureValidator\u003C/span>(\u003Cspan class=\"hljs-title class_ inherited__\">BaseValidator\u003C/span>):\n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate\u003C/span>(\u003Cspan class=\"hljs-params\">self, content: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, metadata: \u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>]\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">List\u003C/span>[\u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>]]:\n        issues = []\n        lines = content.split(\u003Cspan class=\"hljs-string\">&#x27;\\n&#x27;\u003C/span>)\n        \n        heading_pattern = re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^(#{1,6})\\s+(.+)$&#x27;\u003C/span>)\n        last_level = \u003Cspan class=\"hljs-number\">0\u003C/span>\n        heading_count = \u003Cspan class=\"hljs-number\">0\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> line_num, line \u003Cspan class=\"hljs-keyword\">in\u003C/span> \u003Cspan class=\"hljs-built_in\">enumerate\u003C/span>(lines, \u003Cspan class=\"hljs-number\">1\u003C/span>):\n            \u003Cspan class=\"hljs-keyword\">match\u003C/span> = heading_pattern.\u003Cspan class=\"hljs-keyword\">match\u003C/span>(line)\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">match\u003C/span>:\n                level = \u003Cspan class=\"hljs-built_in\">len\u003C/span>(\u003Cspan class=\"hljs-keyword\">match\u003C/span>.group(\u003Cspan class=\"hljs-number\">1\u003C/span>))\n                text = \u003Cspan class=\"hljs-keyword\">match\u003C/span>.group(\u003Cspan class=\"hljs-number\">2\u003C/span>).strip()\n                heading_count += \u003Cspan class=\"hljs-number\">1\u003C/span>\n                \n                \u003Cspan class=\"hljs-comment\"># Check for level skipping\u003C/span>\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> level &gt; last_level + \u003Cspan class=\"hljs-number\">1\u003C/span>:\n                    issues.append({\n                        \u003Cspan class=\"hljs-string\">&#x27;severity&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;warning&#x27;\u003C/span>,\n                        \u003Cspan class=\"hljs-string\">&#x27;message&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">f&#x27;Heading level skip from h\u003Cspan class=\"hljs-subst\">{last_level}\u003C/span> to h\u003Cspan class=\"hljs-subst\">{level}\u003C/span>&#x27;\u003C/span>,\n                        \u003Cspan class=\"hljs-string\">&#x27;line&#x27;\u003C/span>: line_num,\n                        \u003Cspan class=\"hljs-string\">&#x27;text&#x27;\u003C/span>: line\n                    })\n                \n                \u003Cspan class=\"hljs-comment\"># Check for empty headings\u003C/span>\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> text:\n                    issues.append({\n                        \u003Cspan class=\"hljs-string\">&#x27;severity&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;error&#x27;\u003C/span>,\n                        \u003Cspan class=\"hljs-string\">&#x27;message&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Empty heading found&#x27;\u003C/span>,\n                        \u003Cspan class=\"hljs-string\">&#x27;line&#x27;\u003C/span>: line_num,\n                        \u003Cspan class=\"hljs-string\">&#x27;text&#x27;\u003C/span>: line\n                    })\n                \n                \u003Cspan class=\"hljs-comment\"># Check for duplicate headings at same level\u003C/span>\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">hasattr\u003C/span>(self, \u003Cspan class=\"hljs-string\">&#x27;seen_headings&#x27;\u003C/span>):\n                    \u003Cspan class=\"hljs-keyword\">if\u003C/span> (level, text) \u003Cspan class=\"hljs-keyword\">in\u003C/span> self.seen_headings:\n                        issues.append({\n                            \u003Cspan class=\"hljs-string\">&#x27;severity&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;warning&#x27;\u003C/span>,\n                            \u003Cspan class=\"hljs-string\">&#x27;message&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">f&#x27;Duplicate heading at same level: &quot;\u003Cspan class=\"hljs-subst\">{text}\u003C/span>&quot;&#x27;\u003C/span>,\n                            \u003Cspan class=\"hljs-string\">&#x27;line&#x27;\u003C/span>: line_num,\n                            \u003Cspan class=\"hljs-string\">&#x27;text&#x27;\u003C/span>: line\n                        })\n                \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n                    self.seen_headings = \u003Cspan class=\"hljs-built_in\">set\u003C/span>()\n                \n                self.seen_headings.add((level, text))\n                last_level = level\n        \n        \u003Cspan class=\"hljs-comment\"># Check minimum heading requirement\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> heading_count == \u003Cspan class=\"hljs-number\">0\u003C/span>:\n            issues.append({\n                \u003Cspan class=\"hljs-string\">&#x27;severity&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;warning&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;message&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Document has no headings - consider adding structure&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;line&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;text&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>\n            })\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> issues\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">CodeBlockValidator\u003C/span>(\u003Cspan class=\"hljs-title class_ inherited__\">BaseValidator\u003C/span>):\n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate\u003C/span>(\u003Cspan class=\"hljs-params\">self, content: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, metadata: \u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>]\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">List\u003C/span>[\u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>]]:\n        issues = []\n        lines = content.split(\u003Cspan class=\"hljs-string\">&#x27;\\n&#x27;\u003C/span>)\n        \n        in_code_block = \u003Cspan class=\"hljs-literal\">False\u003C/span>\n        code_block_start = \u003Cspan class=\"hljs-number\">0\u003C/span>\n        fence_count = \u003Cspan class=\"hljs-number\">0\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> line_num, line \u003Cspan class=\"hljs-keyword\">in\u003C/span> \u003Cspan class=\"hljs-built_in\">enumerate\u003C/span>(lines, \u003Cspan class=\"hljs-number\">1\u003C/span>):\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> line.strip().startswith(\u003Cspan class=\"hljs-string\">&#x27;```&#x27;\u003C/span>):\n                fence_count += \u003Cspan class=\"hljs-number\">1\u003C/span>\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> in_code_block:\n                    in_code_block = \u003Cspan class=\"hljs-literal\">True\u003C/span>\n                    code_block_start = line_num\n                    \n                    \u003Cspan class=\"hljs-comment\"># Check for language specification\u003C/span>\n                    language = line.strip()[\u003Cspan class=\"hljs-number\">3\u003C/span>:].strip()\n                    \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> language \u003Cspan class=\"hljs-keyword\">and\u003C/span> self.rule.config \u003Cspan class=\"hljs-keyword\">and\u003C/span> self.rule.config.get(\u003Cspan class=\"hljs-string\">&#x27;require_language&#x27;\u003C/span>, \u003Cspan class=\"hljs-literal\">False\u003C/span>):\n                        issues.append({\n                            \u003Cspan class=\"hljs-string\">&#x27;severity&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;warning&#x27;\u003C/span>,\n                            \u003Cspan class=\"hljs-string\">&#x27;message&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Code block missing language specification&#x27;\u003C/span>,\n                            \u003Cspan class=\"hljs-string\">&#x27;line&#x27;\u003C/span>: line_num,\n                            \u003Cspan class=\"hljs-string\">&#x27;text&#x27;\u003C/span>: line\n                        })\n                \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n                    in_code_block = \u003Cspan class=\"hljs-literal\">False\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Check for unmatched code fences\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> fence_count % \u003Cspan class=\"hljs-number\">2\u003C/span> != \u003Cspan class=\"hljs-number\">0\u003C/span>:\n            issues.append({\n                \u003Cspan class=\"hljs-string\">&#x27;severity&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;error&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;message&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Unmatched code block fences&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;line&#x27;\u003C/span>: code_block_start,\n                \u003Cspan class=\"hljs-string\">&#x27;text&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">f&#x27;Unclosed code block starting at line \u003Cspan class=\"hljs-subst\">{code_block_start}\u003C/span>&#x27;\u003C/span>\n            })\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> issues\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">LinkConsistencyValidator\u003C/span>(\u003Cspan class=\"hljs-title class_ inherited__\">BaseValidator\u003C/span>):\n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate\u003C/span>(\u003Cspan class=\"hljs-params\">self, content: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, metadata: \u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>]\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">List\u003C/span>[\u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>]]:\n        issues = []\n        \n        \u003Cspan class=\"hljs-comment\"># Extract all links\u003C/span>\n        link_pattern = re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;\\[([^\\]]+)\\]\\(([^)]+)\\)&#x27;\u003C/span>)\n        links = []\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> \u003Cspan class=\"hljs-keyword\">match\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> link_pattern.finditer(content):\n            links.append({\n                \u003Cspan class=\"hljs-string\">&#x27;text&#x27;\u003C/span>: \u003Cspan class=\"hljs-keyword\">match\u003C/span>.group(\u003Cspan class=\"hljs-number\">1\u003C/span>),\n                \u003Cspan class=\"hljs-string\">&#x27;url&#x27;\u003C/span>: \u003Cspan class=\"hljs-keyword\">match\u003C/span>.group(\u003Cspan class=\"hljs-number\">2\u003C/span>),\n                \u003Cspan class=\"hljs-string\">&#x27;start&#x27;\u003C/span>: \u003Cspan class=\"hljs-keyword\">match\u003C/span>.start(),\n                \u003Cspan class=\"hljs-string\">&#x27;end&#x27;\u003C/span>: \u003Cspan class=\"hljs-keyword\">match\u003C/span>.end(),\n                \u003Cspan class=\"hljs-string\">&#x27;line&#x27;\u003C/span>: content[:\u003Cspan class=\"hljs-keyword\">match\u003C/span>.start()].count(\u003Cspan class=\"hljs-string\">&#x27;\\n&#x27;\u003C/span>) + \u003Cspan class=\"hljs-number\">1\u003C/span>\n            })\n        \n        \u003Cspan class=\"hljs-comment\"># Check for duplicate URLs with different text\u003C/span>\n        url_texts = {}\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> link \u003Cspan class=\"hljs-keyword\">in\u003C/span> links:\n            url = link[\u003Cspan class=\"hljs-string\">&#x27;url&#x27;\u003C/span>]\n            text = link[\u003Cspan class=\"hljs-string\">&#x27;text&#x27;\u003C/span>]\n            \n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> url \u003Cspan class=\"hljs-keyword\">in\u003C/span> url_texts:\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> text != url_texts[url]:\n                    issues.append({\n                        \u003Cspan class=\"hljs-string\">&#x27;severity&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;warning&#x27;\u003C/span>,\n                        \u003Cspan class=\"hljs-string\">&#x27;message&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">f&#x27;Inconsistent link text for URL: \u003Cspan class=\"hljs-subst\">{url}\u003C/span>&#x27;\u003C/span>,\n                        \u003Cspan class=\"hljs-string\">&#x27;line&#x27;\u003C/span>: link[\u003Cspan class=\"hljs-string\">&#x27;line&#x27;\u003C/span>],\n                        \u003Cspan class=\"hljs-string\">&#x27;text&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">f&#x27;Found: &quot;\u003Cspan class=\"hljs-subst\">{text}\u003C/span>&quot;, Previous: &quot;\u003Cspan class=\"hljs-subst\">{url_texts[url]}\u003C/span>&quot;&#x27;\u003C/span>\n                    })\n            \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n                url_texts[url] = text\n        \n        \u003Cspan class=\"hljs-comment\"># Check for broken reference-style links\u003C/span>\n        ref_link_pattern = re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;\\[([^\\]]+)\\]\\[([^\\]]*)\\]&#x27;\u003C/span>)\n        ref_def_pattern = re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^\\s*\\[([^\\]]+)\\]:\\s*(.+)$&#x27;\u003C/span>, re.MULTILINE)\n        \n        \u003Cspan class=\"hljs-comment\"># Find all reference definitions\u003C/span>\n        ref_defs = \u003Cspan class=\"hljs-built_in\">set\u003C/span>()\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> \u003Cspan class=\"hljs-keyword\">match\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> ref_def_pattern.finditer(content):\n            ref_defs.add(\u003Cspan class=\"hljs-keyword\">match\u003C/span>.group(\u003Cspan class=\"hljs-number\">1\u003C/span>).lower())\n        \n        \u003Cspan class=\"hljs-comment\"># Check reference links\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> \u003Cspan class=\"hljs-keyword\">match\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> ref_link_pattern.finditer(content):\n            ref_id = \u003Cspan class=\"hljs-keyword\">match\u003C/span>.group(\u003Cspan class=\"hljs-number\">2\u003C/span>) \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">match\u003C/span>.group(\u003Cspan class=\"hljs-number\">2\u003C/span>) \u003Cspan class=\"hljs-keyword\">else\u003C/span> \u003Cspan class=\"hljs-keyword\">match\u003C/span>.group(\u003Cspan class=\"hljs-number\">1\u003C/span>)\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> ref_id.lower() \u003Cspan class=\"hljs-keyword\">not\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> ref_defs:\n                line_num = content[:\u003Cspan class=\"hljs-keyword\">match\u003C/span>.start()].count(\u003Cspan class=\"hljs-string\">&#x27;\\n&#x27;\u003C/span>) + \u003Cspan class=\"hljs-number\">1\u003C/span>\n                issues.append({\n                    \u003Cspan class=\"hljs-string\">&#x27;severity&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;error&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;message&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">f&#x27;Undefined reference link: \u003Cspan class=\"hljs-subst\">{ref_id}\u003C/span>&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;line&#x27;\u003C/span>: line_num,\n                    \u003Cspan class=\"hljs-string\">&#x27;text&#x27;\u003C/span>: \u003Cspan class=\"hljs-keyword\">match\u003C/span>.group(\u003Cspan class=\"hljs-number\">0\u003C/span>)\n                })\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> issues\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">TerminologyValidator\u003C/span>(\u003Cspan class=\"hljs-title class_ inherited__\">BaseValidator\u003C/span>):\n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate\u003C/span>(\u003Cspan class=\"hljs-params\">self, content: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, metadata: \u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>]\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">List\u003C/span>[\u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>]]:\n        issues = []\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> self.rule.config \u003Cspan class=\"hljs-keyword\">or\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;terminology&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> self.rule.config:\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> issues\n        \n        terminology = self.rule.config[\u003Cspan class=\"hljs-string\">&#x27;terminology&#x27;\u003C/span>]\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> term_config \u003Cspan class=\"hljs-keyword\">in\u003C/span> terminology:\n            preferred = term_config[\u003Cspan class=\"hljs-string\">&#x27;preferred&#x27;\u003C/span>]\n            alternatives = term_config.get(\u003Cspan class=\"hljs-string\">&#x27;alternatives&#x27;\u003C/span>, [])\n            case_sensitive = term_config.get(\u003Cspan class=\"hljs-string\">&#x27;case_sensitive&#x27;\u003C/span>, \u003Cspan class=\"hljs-literal\">False\u003C/span>)\n            \n            flags = \u003Cspan class=\"hljs-number\">0\u003C/span> \u003Cspan class=\"hljs-keyword\">if\u003C/span> case_sensitive \u003Cspan class=\"hljs-keyword\">else\u003C/span> re.IGNORECASE\n            \n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> alt \u003Cspan class=\"hljs-keyword\">in\u003C/span> alternatives:\n                pattern = re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;\\b&#x27;\u003C/span> + re.escape(alt) + \u003Cspan class=\"hljs-string\">r&#x27;\\b&#x27;\u003C/span>, flags)\n                \n                \u003Cspan class=\"hljs-keyword\">for\u003C/span> \u003Cspan class=\"hljs-keyword\">match\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> pattern.finditer(content):\n                    line_num = content[:\u003Cspan class=\"hljs-keyword\">match\u003C/span>.start()].count(\u003Cspan class=\"hljs-string\">&#x27;\\n&#x27;\u003C/span>) + \u003Cspan class=\"hljs-number\">1\u003C/span>\n                    issues.append({\n                        \u003Cspan class=\"hljs-string\">&#x27;severity&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;warning&#x27;\u003C/span>,\n                        \u003Cspan class=\"hljs-string\">&#x27;message&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">f&#x27;Consider using &quot;\u003Cspan class=\"hljs-subst\">{preferred}\u003C/span>&quot; instead of &quot;\u003Cspan class=\"hljs-subst\">{alt}\u003C/span>&quot;&#x27;\u003C/span>,\n                        \u003Cspan class=\"hljs-string\">&#x27;line&#x27;\u003C/span>: line_num,\n                        \u003Cspan class=\"hljs-string\">&#x27;text&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">f&#x27;Found: \u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-keyword\">match\u003C/span>.group(\u003Cspan class=\"hljs-number\">0\u003C/span>)}\u003C/span>&#x27;\u003C/span>\n                    })\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> issues\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">ReadabilityValidator\u003C/span>(\u003Cspan class=\"hljs-title class_ inherited__\">BaseValidator\u003C/span>):\n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate\u003C/span>(\u003Cspan class=\"hljs-params\">self, content: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, metadata: \u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>]\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">List\u003C/span>[\u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>]]:\n        issues = []\n        \n        \u003Cspan class=\"hljs-comment\"># Remove markdown formatting for analysis\u003C/span>\n        text = self.clean_markdown(content)\n        \n        \u003Cspan class=\"hljs-comment\"># Calculate basic readability metrics\u003C/span>\n        sentences = self.count_sentences(text)\n        words = self.count_words(text)\n        syllables = self.count_syllables(text)\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> sentences == \u003Cspan class=\"hljs-number\">0\u003C/span> \u003Cspan class=\"hljs-keyword\">or\u003C/span> words == \u003Cspan class=\"hljs-number\">0\u003C/span>:\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> issues\n        \n        \u003Cspan class=\"hljs-comment\"># Flesch Reading Ease Score\u003C/span>\n        flesch_score = \u003Cspan class=\"hljs-number\">206.835\u003C/span> - (\u003Cspan class=\"hljs-number\">1.015\u003C/span> * (words / sentences)) - (\u003Cspan class=\"hljs-number\">84.6\u003C/span> * (syllables / words))\n        \n        thresholds = self.rule.config.get(\u003Cspan class=\"hljs-string\">&#x27;thresholds&#x27;\u003C/span>, {}) \u003Cspan class=\"hljs-keyword\">if\u003C/span> self.rule.config \u003Cspan class=\"hljs-keyword\">else\u003C/span> {}\n        min_score = thresholds.get(\u003Cspan class=\"hljs-string\">&#x27;min_flesch_score&#x27;\u003C/span>, \u003Cspan class=\"hljs-number\">30\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> flesch_score &lt; min_score:\n            issues.append({\n                \u003Cspan class=\"hljs-string\">&#x27;severity&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;warning&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;message&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">f&#x27;Low readability score: \u003Cspan class=\"hljs-subst\">{flesch_score:\u003Cspan class=\"hljs-number\">.1\u003C/span>f}\u003C/span> (target: \u003Cspan class=\"hljs-subst\">{min_score}\u003C/span>+)&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;line&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;text&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">f&#x27;Consider shorter sentences and simpler words&#x27;\u003C/span>\n            })\n        \n        \u003Cspan class=\"hljs-comment\"># Check average sentence length\u003C/span>\n        avg_sentence_length = words / sentences\n        max_sentence_length = thresholds.get(\u003Cspan class=\"hljs-string\">&#x27;max_sentence_length&#x27;\u003C/span>, \u003Cspan class=\"hljs-number\">25\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> avg_sentence_length &gt; max_sentence_length:\n            issues.append({\n                \u003Cspan class=\"hljs-string\">&#x27;severity&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;info&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;message&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">f&#x27;Average sentence length: \u003Cspan class=\"hljs-subst\">{avg_sentence_length:\u003Cspan class=\"hljs-number\">.1\u003C/span>f}\u003C/span> words (target: &lt;\u003Cspan class=\"hljs-subst\">{max_sentence_length}\u003C/span>)&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;line&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">0\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;text&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Consider breaking up long sentences&#x27;\u003C/span>\n            })\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> issues\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">clean_markdown\u003C/span>(\u003Cspan class=\"hljs-params\">self, content: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">str\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Remove markdown formatting for readability analysis&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-comment\"># Remove code blocks\u003C/span>\n        content = re.sub(\u003Cspan class=\"hljs-string\">r&#x27;```.*?```&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>, content, flags=re.DOTALL)\n        \u003Cspan class=\"hljs-comment\"># Remove inline code\u003C/span>\n        content = re.sub(\u003Cspan class=\"hljs-string\">r&#x27;`[^`]+`&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>, content)\n        \u003Cspan class=\"hljs-comment\"># Remove links but keep text\u003C/span>\n        content = re.sub(\u003Cspan class=\"hljs-string\">r&#x27;\\[([^\\]]+)\\]\\([^)]+\\)&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">r&#x27;\\1&#x27;\u003C/span>, content)\n        \u003Cspan class=\"hljs-comment\"># Remove headers\u003C/span>\n        content = re.sub(\u003Cspan class=\"hljs-string\">r&#x27;^#+\\s*&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>, content, flags=re.MULTILINE)\n        \u003Cspan class=\"hljs-comment\"># Remove emphasis\u003C/span>\n        content = re.sub(\u003Cspan class=\"hljs-string\">r&#x27;[*_]+([^*_]+)[*_]+&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">r&#x27;\\1&#x27;\u003C/span>, content)\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> content\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">count_sentences\u003C/span>(\u003Cspan class=\"hljs-params\">self, text: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">int\u003C/span>:\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(re.findall(\u003Cspan class=\"hljs-string\">r&#x27;[.!?]+&#x27;\u003C/span>, text))\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">count_words\u003C/span>(\u003Cspan class=\"hljs-params\">self, text: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">int\u003C/span>:\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(re.findall(\u003Cspan class=\"hljs-string\">r&#x27;\\b\\w+\\b&#x27;\u003C/span>, text))\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">count_syllables\u003C/span>(\u003Cspan class=\"hljs-params\">self, text: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">int\u003C/span>:\n        words = re.findall(\u003Cspan class=\"hljs-string\">r&#x27;\\b[a-zA-Z]+\\b&#x27;\u003C/span>, text.lower())\n        total_syllables = \u003Cspan class=\"hljs-number\">0\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> word \u003Cspan class=\"hljs-keyword\">in\u003C/span> words:\n            syllables = self.syllables_in_word(word)\n            total_syllables += syllables\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> total_syllables\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">syllables_in_word\u003C/span>(\u003Cspan class=\"hljs-params\">self, word: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">int\u003C/span>:\n        vowels = \u003Cspan class=\"hljs-string\">&#x27;aeiouy&#x27;\u003C/span>\n        count = \u003Cspan class=\"hljs-number\">0\u003C/span>\n        prev_was_vowel = \u003Cspan class=\"hljs-literal\">False\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> char \u003Cspan class=\"hljs-keyword\">in\u003C/span> word:\n            is_vowel = char \u003Cspan class=\"hljs-keyword\">in\u003C/span> vowels\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> is_vowel \u003Cspan class=\"hljs-keyword\">and\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> prev_was_vowel:\n                count += \u003Cspan class=\"hljs-number\">1\u003C/span>\n            prev_was_vowel = is_vowel\n        \n        \u003Cspan class=\"hljs-comment\"># Handle silent &#x27;e&#x27;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> word.endswith(\u003Cspan class=\"hljs-string\">&#x27;e&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">and\u003C/span> count &gt; \u003Cspan class=\"hljs-number\">1\u003C/span>:\n            count -= \u003Cspan class=\"hljs-number\">1\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-built_in\">max\u003C/span>(\u003Cspan class=\"hljs-number\">1\u003C/span>, count)\n\n\u003Cspan class=\"hljs-comment\"># Example configuration file (.validation-config.yaml)\u003C/span>\nvalidation_config_example = \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;\nrules:\n  - name: heading_structure\n    description: Validate heading hierarchy and structure\n    severity: warning\n    category: heading_structure\n    enabled: true\n    \n  - name: code_blocks\n    description: Validate code block syntax and formatting\n    severity: error\n    category: code_blocks\n    enabled: true\n    config:\n      require_language: true\n      \n  - name: terminology_consistency\n    description: Enforce consistent terminology usage\n    severity: warning\n    category: terminology\n    enabled: true\n    config:\n      terminology:\n        - preferred: &quot;JavaScript&quot;\n          alternatives: [&quot;Javascript&quot;, &quot;javascript&quot;, &quot;JS&quot;]\n          case_sensitive: false\n        - preferred: &quot;API&quot;\n          alternatives: [&quot;api&quot;]\n          case_sensitive: true\n          \n  - name: readability_check\n    description: Analyze content readability\n    severity: info\n    category: readability\n    enabled: true\n    config:\n      thresholds:\n        min_flesch_score: 40\n        max_sentence_length: 25\n&quot;&quot;&quot;\u003C/span>\n\n\u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">main\u003C/span>():\n    \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;CLI interface for the validation engine&quot;&quot;&quot;\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">import\u003C/span> argparse\n    \n    parser = argparse.ArgumentParser(description=\u003Cspan class=\"hljs-string\">&#x27;Custom Markdown Validation Engine&#x27;\u003C/span>)\n    parser.add_argument(\u003Cspan class=\"hljs-string\">&#x27;files&#x27;\u003C/span>, nargs=\u003Cspan class=\"hljs-string\">&#x27;+&#x27;\u003C/span>, \u003Cspan class=\"hljs-built_in\">help\u003C/span>=\u003Cspan class=\"hljs-string\">&#x27;Markdown files to validate&#x27;\u003C/span>)\n    parser.add_argument(\u003Cspan class=\"hljs-string\">&#x27;--config&#x27;\u003C/span>, \u003Cspan class=\"hljs-built_in\">help\u003C/span>=\u003Cspan class=\"hljs-string\">&#x27;Validation configuration file&#x27;\u003C/span>)\n    parser.add_argument(\u003Cspan class=\"hljs-string\">&#x27;--output&#x27;\u003C/span>, \u003Cspan class=\"hljs-built_in\">help\u003C/span>=\u003Cspan class=\"hljs-string\">&#x27;Output file for results (JSON)&#x27;\u003C/span>)\n    parser.add_argument(\u003Cspan class=\"hljs-string\">&#x27;--verbose&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;-v&#x27;\u003C/span>, action=\u003Cspan class=\"hljs-string\">&#x27;store_true&#x27;\u003C/span>, \u003Cspan class=\"hljs-built_in\">help\u003C/span>=\u003Cspan class=\"hljs-string\">&#x27;Verbose output&#x27;\u003C/span>)\n    \n    args = parser.parse_args()\n    \n    \u003Cspan class=\"hljs-comment\"># Initialize validation engine\u003C/span>\n    engine = CustomValidationEngine(args.config)\n    \n    all_results = {}\n    \n    \u003Cspan class=\"hljs-keyword\">for\u003C/span> file_path \u003Cspan class=\"hljs-keyword\">in\u003C/span> args.files:\n        \u003Cspan class=\"hljs-keyword\">try\u003C/span>:\n            \u003Cspan class=\"hljs-keyword\">with\u003C/span> \u003Cspan class=\"hljs-built_in\">open\u003C/span>(file_path, \u003Cspan class=\"hljs-string\">&#x27;r&#x27;\u003C/span>, encoding=\u003Cspan class=\"hljs-string\">&#x27;utf-8&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">as\u003C/span> f:\n                content = f.read()\n            \n            \u003Cspan class=\"hljs-comment\"># Extract frontmatter if present\u003C/span>\n            metadata = {}\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> content.startswith(\u003Cspan class=\"hljs-string\">&#x27;---&#x27;\u003C/span>):\n                \u003Cspan class=\"hljs-keyword\">try\u003C/span>:\n                    \u003Cspan class=\"hljs-keyword\">import\u003C/span> frontmatter\n                    post = frontmatter.loads(content)\n                    metadata = post.metadata\n                    content = post.content\n                \u003Cspan class=\"hljs-keyword\">except\u003C/span> ImportError:\n                    \u003Cspan class=\"hljs-keyword\">pass\u003C/span>\n            \n            results = engine.validate_document(content, metadata)\n            all_results[file_path] = results\n            \n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> args.verbose \u003Cspan class=\"hljs-keyword\">or\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> results[\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>]:\n                \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;\\n📄 \u003Cspan class=\"hljs-subst\">{file_path}\u003C/span>&quot;\u003C/span>)\n                \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;Status: \u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-string\">&#x27;✅ PASSED&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">if\u003C/span> results[\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                \u003Cspan class=\"hljs-keyword\">if\u003C/span> results[\u003Cspan class=\"hljs-string\">&#x27;errors&#x27;\u003C/span>]:\n                    \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;Errors (\u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-built_in\">len\u003C/span>(results[\u003Cspan class=\"hljs-string\">&#x27;errors&#x27;\u003C/span>])}\u003C/span>):&quot;\u003C/span>)\n                    \u003Cspan class=\"hljs-keyword\">for\u003C/span> error \u003Cspan class=\"hljs-keyword\">in\u003C/span> results[\u003Cspan class=\"hljs-string\">&#x27;errors&#x27;\u003C/span>]:\n                        \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;  ❌ Line \u003Cspan class=\"hljs-subst\">{error[\u003Cspan class=\"hljs-string\">&#x27;line&#x27;\u003C/span>]}\u003C/span>: \u003Cspan class=\"hljs-subst\">{error[\u003Cspan class=\"hljs-string\">&#x27;message&#x27;\u003C/span>]}\u003C/span>&quot;\u003C/span>)\n                \n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> results[\u003Cspan class=\"hljs-string\">&#x27;warnings&#x27;\u003C/span>]:\n                    \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;Warnings (\u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-built_in\">len\u003C/span>(results[\u003Cspan class=\"hljs-string\">&#x27;warnings&#x27;\u003C/span>])}\u003C/span>):&quot;\u003C/span>)\n                    \u003Cspan class=\"hljs-keyword\">for\u003C/span> warning \u003Cspan class=\"hljs-keyword\">in\u003C/span> results[\u003Cspan class=\"hljs-string\">&#x27;warnings&#x27;\u003C/span>]:\n                        \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;  ⚠️  Line \u003Cspan class=\"hljs-subst\">{warning[\u003Cspan class=\"hljs-string\">&#x27;line&#x27;\u003C/span>]}\u003C/span>: \u003Cspan class=\"hljs-subst\">{warning[\u003Cspan class=\"hljs-string\">&#x27;message&#x27;\u003C/span>]}\u003C/span>&quot;\u003C/span>)\n                \n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> results[\u003Cspan class=\"hljs-string\">&#x27;info&#x27;\u003C/span>]:\n                    \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;Info (\u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-built_in\">len\u003C/span>(results[\u003Cspan class=\"hljs-string\">&#x27;info&#x27;\u003C/span>])}\u003C/span>):&quot;\u003C/span>)\n                    \u003Cspan class=\"hljs-keyword\">for\u003C/span> info \u003Cspan class=\"hljs-keyword\">in\u003C/span> results[\u003Cspan class=\"hljs-string\">&#x27;info&#x27;\u003C/span>]:\n                        \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;  ℹ️  Line \u003Cspan class=\"hljs-subst\">{info[\u003Cspan class=\"hljs-string\">&#x27;line&#x27;\u003C/span>]}\u003C/span>: \u003Cspan class=\"hljs-subst\">{info[\u003Cspan class=\"hljs-string\">&#x27;message&#x27;\u003C/span>]}\u003C/span>&quot;\u003C/span>)\n            \n        \u003Cspan class=\"hljs-keyword\">except\u003C/span> Exception \u003Cspan class=\"hljs-keyword\">as\u003C/span> e:\n            \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;❌ Error processing \u003Cspan class=\"hljs-subst\">{file_path}\u003C/span>: \u003Cspan class=\"hljs-subst\">{e}\u003C/span>&quot;\u003C/span>)\n            all_results[file_path] = {\u003Cspan class=\"hljs-string\">&#x27;error&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">str\u003C/span>(e), \u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">False\u003C/span>}\n    \n    \u003Cspan class=\"hljs-comment\"># Output results\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> args.output:\n        \u003Cspan class=\"hljs-keyword\">with\u003C/span> \u003Cspan class=\"hljs-built_in\">open\u003C/span>(args.output, \u003Cspan class=\"hljs-string\">&#x27;w&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">as\u003C/span> f:\n            json.dump(all_results, f, indent=\u003Cspan class=\"hljs-number\">2\u003C/span>)\n        \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;\\n📊 Results saved to \u003Cspan class=\"hljs-subst\">{args.output}\u003C/span>&quot;\u003C/span>)\n    \n    \u003Cspan class=\"hljs-comment\"># Summary\u003C/span>\n    total_files = \u003Cspan class=\"hljs-built_in\">len\u003C/span>(all_results)\n    passed_files = \u003Cspan class=\"hljs-built_in\">sum\u003C/span>(\u003Cspan class=\"hljs-number\">1\u003C/span> \u003Cspan class=\"hljs-keyword\">for\u003C/span> r \u003Cspan class=\"hljs-keyword\">in\u003C/span> all_results.values() \u003Cspan class=\"hljs-keyword\">if\u003C/span> r.get(\u003Cspan class=\"hljs-string\">&#x27;passed&#x27;\u003C/span>, \u003Cspan class=\"hljs-literal\">False\u003C/span>))\n    \n    \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;\\n📈 Summary: \u003Cspan class=\"hljs-subst\">{passed_files}\u003C/span>/\u003Cspan class=\"hljs-subst\">{total_files}\u003C/span> files passed validation&quot;\u003C/span>)\n    \n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> passed_files &lt; total_files:\n        exit(\u003Cspan class=\"hljs-number\">1\u003C/span>)\n\n\u003Cspan class=\"hljs-keyword\">if\u003C/span> __name__ == \u003Cspan class=\"hljs-string\">&quot;__main__&quot;\u003C/span>:\n    main()\n\u003C/code>\u003C/pre>\u003Ch2 id=\"conclusion\">Conclusion\u003C/h2>\n\u003Cp>Advanced Markdown testing and validation represents a fundamental shift toward quality-driven content management that ensures consistency, reliability, and professional standards across documentation projects. By implementing comprehensive testing frameworks, automated validation systems, and continuous integration pipelines, development teams can catch errors early, maintain high-quality standards, and scale their documentation efforts without compromising quality or introducing technical debt.\u003C/p>\n\u003Cp>The key to successful automated testing lies in balancing thoroughness with performance, ensuring that validation processes enhance rather than hinder productivity. Whether you&#39;re managing individual blog posts or coordinating enterprise-scale documentation projects, the testing strategies covered in this guide provide the foundation for building robust, reliable, and maintainable content workflows that grow with your organization&#39;s needs.\u003C/p>\n\u003Cp>Remember to start with essential validation rules and gradually expand testing coverage based on your specific requirements, regularly review and update validation criteria to match evolving content standards, and continuously monitor testing performance to ensure that quality assurance remains efficient and effective. With proper implementation of advanced testing and validation techniques, your Markdown content can achieve unprecedented levels of quality and reliability while maintaining the simplicity and flexibility that makes Markdown such an effective documentation format.\u003C/p>\n",[15,19,22,25,28],{"id":16,"text":17,"level":18},"why-master-markdown-testing-and-validation","Why Master Markdown Testing and Validation?",2,{"id":20,"text":21,"level":18},"foundation-testing-framework","Foundation Testing Framework",{"id":23,"text":24,"level":18},"integration-with-modern-development-workflows","Integration with Modern Development Workflows",{"id":26,"text":27,"level":18},"advanced-testing-strategies","Advanced Testing Strategies",{"id":29,"text":30,"level":18},"conclusion","Conclusion",[],[33,41,49],{"slug":34,"title":35,"description":36,"excerpt":37,"date":38,"category":9,"author":10,"keywords":39,"readingMinutes":40},"markdown-table-data-validation-and-quality-assurance-complete-guide","Markdown Table Data Validation and Quality Assurance: Complete Guide for Automated Testing and Error Detection in Tabular Content","Master comprehensive data validation techniques for Markdown tables, implementing automated quality assurance, error detection systems, and data integrity checks for reliable tabular content management.","Advanced Markdown table data validation and quality assurance techniques enable systematic verification of tabular content accuracy, structural integrity, and formatting consistency across…","2025-12-18","markdown table validation, table data quality, automated table testing, markdown table errors, data validation markdown, table quality assurance, markdown table integrity, tabular data validation",26,{"slug":42,"title":43,"description":44,"excerpt":45,"date":46,"category":9,"author":10,"keywords":47,"readingMinutes":48},"markdown-error-handling-validation-complete-guide","Markdown Error Handling and Validation: Complete Guide for Content Quality Assurance and Automated Checking","Master Markdown error handling, validation techniques, and automated quality assurance. Learn syntax checking, link validation, content linting, and comprehensive testing strategies for robust Markdown workflows.","Markdown error handling and validation techniques enable content teams to maintain high-quality documentation through automated quality assurance processes that catch syntax errors, validate…","2025-12-04","markdown validation, markdown error handling, markdown linting, content quality assurance, markdown syntax checking, automated markdown testing, markdown workflow validation",28,{"slug":50,"title":51,"description":52,"excerpt":53,"date":54,"category":9,"author":10,"keywords":55,"readingMinutes":12},"markdown-table-data-validation-quality-assurance-complete-guide","Markdown Table Data Validation and Quality Assurance: Complete Guide for Automated Table Content Verification","Master comprehensive table data validation techniques in Markdown for automated quality assurance, content verification, and structural integrity checking. Learn advanced validation patterns and automated testing workflows.","Markdown table data validation and quality assurance ensure accurate, consistent, and reliable table content across documentation systems through automated verification, structural integrity…","2025-11-09","markdown table validation, data quality assurance, table content verification, automated markdown testing, table structure validation, data integrity checking, markdown quality control, table validation tools",1792184943321]