[{"data":1,"prerenderedAt":60},["Reactive",2],{"blog-post-markdown-data-validation-and-schema-checking-complete-guide":3},{"slug":4,"title":5,"description":6,"excerpt":7,"date":8,"category":9,"author":10,"keywords":11,"readingMinutes":12,"html":13,"headings":14,"tools":34,"related":35},"markdown-data-validation-and-schema-checking-complete-guide","Markdown Data Validation and Schema Checking: Complete Guide for Content Quality Assurance and Automated Verification","Master advanced Markdown data validation techniques using schema checking, frontmatter validation, content structure verification, and automated quality assurance systems. Learn to implement robust validation workflows for documentation teams.","Advanced Markdown data validation and schema checking enables sophisticated content quality assurance systems that automatically verify document structure, validate metadata consistency, and…","2025-10-27","Tutorial","Matthew Rathbone","markdown data validation, schema checking markdown, frontmatter validation, markdown content verification, automated markdown quality, documentation validation, markdown schema, content structure validation",19,"\u003Cp>Advanced Markdown data validation and schema checking enables sophisticated content quality assurance systems that automatically verify document structure, validate metadata consistency, and enforce editorial standards across large documentation repositories. By implementing comprehensive validation frameworks, automated schema checking, and intelligent content verification systems, technical teams can maintain high-quality documentation standards while scaling content production and ensuring consistency across distributed authoring workflows.\u003C/p>\n\u003Ch2 id=\"why-master-markdown-data-validation\">Why Master Markdown Data Validation?\u003C/h2>\n\u003Cp>Professional data validation provides essential benefits for content quality assurance:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Content Consistency\u003C/strong>: Enforce standardized document structures and metadata formats across all content\u003C/li>\n\u003Cli>\u003Cstrong>Quality Assurance\u003C/strong>: Automatically detect formatting errors, missing required fields, and structural inconsistencies\u003C/li>\n\u003Cli>\u003Cstrong>Editorial Standards\u003C/strong>: Maintain consistent writing quality through automated grammar, style, and terminology checking\u003C/li>\n\u003Cli>\u003Cstrong>Integration Compliance\u003C/strong>: Ensure content meets API requirements and system integration specifications\u003C/li>\n\u003Cli>\u003Cstrong>Team Collaboration\u003C/strong>: Provide immediate feedback to authors and editors through automated validation workflows\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"foundation-validation-concepts\">Foundation Validation Concepts\u003C/h2>\n\u003Ch3 id=\"understanding-markdown-schema-validation\">Understanding Markdown Schema Validation\u003C/h3>\n\u003Cp>Implementing structured validation approaches for Markdown content:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-yaml\">\u003Cspan class=\"hljs-comment\"># markdown-schema.yml - Comprehensive schema definition\u003C/span>\n\u003Cspan class=\"hljs-attr\">schema_version:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;1.0&quot;\u003C/span>\n\u003Cspan class=\"hljs-attr\">document_types:\u003C/span>\n  \u003Cspan class=\"hljs-attr\">blog_post:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">required_frontmatter:\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">title\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">description\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">keywords\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">layout\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">date\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">author\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">category\u003C/span>\n    \u003Cspan class=\"hljs-attr\">optional_frontmatter:\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">image\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">tags\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">excerpt\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">featured\u003C/span>\n    \n    \u003Cspan class=\"hljs-attr\">frontmatter_rules:\u003C/span>\n      \u003Cspan class=\"hljs-attr\">title:\u003C/span>\n        \u003Cspan class=\"hljs-attr\">type:\u003C/span> \u003Cspan class=\"hljs-string\">string\u003C/span>\n        \u003Cspan class=\"hljs-attr\">min_length:\u003C/span> \u003Cspan class=\"hljs-number\">10\u003C/span>\n        \u003Cspan class=\"hljs-attr\">max_length:\u003C/span> \u003Cspan class=\"hljs-number\">120\u003C/span>\n        \u003Cspan class=\"hljs-attr\">pattern:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;^[A-Za-z0-9\\\\s\\\\-:]+$&quot;\u003C/span>\n        \n      \u003Cspan class=\"hljs-attr\">description:\u003C/span>\n        \u003Cspan class=\"hljs-attr\">type:\u003C/span> \u003Cspan class=\"hljs-string\">string\u003C/span>\n        \u003Cspan class=\"hljs-attr\">min_length:\u003C/span> \u003Cspan class=\"hljs-number\">50\u003C/span>\n        \u003Cspan class=\"hljs-attr\">max_length:\u003C/span> \u003Cspan class=\"hljs-number\">300\u003C/span>\n        \u003Cspan class=\"hljs-attr\">must_end_with_period:\u003C/span> \u003Cspan class=\"hljs-literal\">true\u003C/span>\n        \n      \u003Cspan class=\"hljs-attr\">keywords:\u003C/span>\n        \u003Cspan class=\"hljs-attr\">type:\u003C/span> \u003Cspan class=\"hljs-string\">string\u003C/span>\n        \u003Cspan class=\"hljs-attr\">min_keywords:\u003C/span> \u003Cspan class=\"hljs-number\">3\u003C/span>\n        \u003Cspan class=\"hljs-attr\">max_keywords:\u003C/span> \u003Cspan class=\"hljs-number\">12\u003C/span>\n        \u003Cspan class=\"hljs-attr\">separator:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;, &quot;\u003C/span>\n        \n      \u003Cspan class=\"hljs-attr\">date:\u003C/span>\n        \u003Cspan class=\"hljs-attr\">type:\u003C/span> \u003Cspan class=\"hljs-string\">date\u003C/span>\n        \u003Cspan class=\"hljs-attr\">format:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;YYYY-MM-DD&quot;\u003C/span>\n        \u003Cspan class=\"hljs-attr\">not_future:\u003C/span> \u003Cspan class=\"hljs-literal\">true\u003C/span>\n        \n      \u003Cspan class=\"hljs-attr\">category:\u003C/span>\n        \u003Cspan class=\"hljs-attr\">type:\u003C/span> \u003Cspan class=\"hljs-string\">string\u003C/span>\n        \u003Cspan class=\"hljs-attr\">allowed_values:\u003C/span> [\u003Cspan class=\"hljs-string\">&quot;Tutorial&quot;\u003C/span>, \u003Cspan class=\"hljs-string\">&quot;Guide&quot;\u003C/span>, \u003Cspan class=\"hljs-string\">&quot;Reference&quot;\u003C/span>, \u003Cspan class=\"hljs-string\">&quot;News&quot;\u003C/span>]\n    \n    \u003Cspan class=\"hljs-attr\">content_rules:\u003C/span>\n      \u003Cspan class=\"hljs-attr\">min_word_count:\u003C/span> \u003Cspan class=\"hljs-number\">800\u003C/span>\n      \u003Cspan class=\"hljs-attr\">max_word_count:\u003C/span> \u003Cspan class=\"hljs-number\">5000\u003C/span>\n      \n      \u003Cspan class=\"hljs-attr\">required_sections:\u003C/span>\n        \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">introduction_paragraph\u003C/span>\n        \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">main_headings\u003C/span>\n        \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">conclusion_section\u003C/span>\n        \n      \u003Cspan class=\"hljs-attr\">heading_structure:\u003C/span>\n        \u003Cspan class=\"hljs-attr\">max_heading_level:\u003C/span> \u003Cspan class=\"hljs-number\">4\u003C/span>\n        \u003Cspan class=\"hljs-attr\">require_h1:\u003C/span> \u003Cspan class=\"hljs-literal\">true\u003C/span>\n        \u003Cspan class=\"hljs-attr\">sequential_levels:\u003C/span> \u003Cspan class=\"hljs-literal\">true\u003C/span>\n        \n      \u003Cspan class=\"hljs-attr\">code_blocks:\u003C/span>\n        \u003Cspan class=\"hljs-attr\">require_language_tags:\u003C/span> \u003Cspan class=\"hljs-literal\">true\u003C/span>\n        \u003Cspan class=\"hljs-attr\">max_line_length:\u003C/span> \u003Cspan class=\"hljs-number\">100\u003C/span>\n        \u003Cspan class=\"hljs-attr\">escape_liquid_syntax:\u003C/span> \u003Cspan class=\"hljs-literal\">true\u003C/span>\n        \n      \u003Cspan class=\"hljs-attr\">links:\u003C/span>\n        \u003Cspan class=\"hljs-attr\">validate_internal:\u003C/span> \u003Cspan class=\"hljs-literal\">true\u003C/span>\n        \u003Cspan class=\"hljs-attr\">check_external:\u003C/span> \u003Cspan class=\"hljs-literal\">false\u003C/span>\n        \u003Cspan class=\"hljs-attr\">require_descriptions:\u003C/span> \u003Cspan class=\"hljs-literal\">true\u003C/span>\n        \n      \u003Cspan class=\"hljs-attr\">images:\u003C/span>\n        \u003Cspan class=\"hljs-attr\">require_alt_text:\u003C/span> \u003Cspan class=\"hljs-literal\">true\u003C/span>\n        \u003Cspan class=\"hljs-attr\">validate_paths:\u003C/span> \u003Cspan class=\"hljs-literal\">true\u003C/span>\n        \u003Cspan class=\"hljs-attr\">max_file_size:\u003C/span> \u003Cspan class=\"hljs-string\">&quot;2MB&quot;\u003C/span>\n\n  \u003Cspan class=\"hljs-attr\">documentation_page:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">required_frontmatter:\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">title\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">description\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">layout\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">nav_order\u003C/span>\n      \n    \u003Cspan class=\"hljs-attr\">content_rules:\u003C/span>\n      \u003Cspan class=\"hljs-attr\">min_word_count:\u003C/span> \u003Cspan class=\"hljs-number\">200\u003C/span>\n      \u003Cspan class=\"hljs-attr\">require_table_of_contents:\u003C/span> \u003Cspan class=\"hljs-literal\">true\u003C/span>\n      \n  \u003Cspan class=\"hljs-attr\">api_reference:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">required_frontmatter:\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">title\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">api_version\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">endpoint\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">method\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">layout\u003C/span>\n      \n    \u003Cspan class=\"hljs-attr\">content_rules:\u003C/span>\n      \u003Cspan class=\"hljs-attr\">required_sections:\u003C/span>\n        \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">parameters_section\u003C/span>\n        \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">response_section\u003C/span>\n        \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">example_section\u003C/span>\n\u003C/code>\u003C/pre>\u003Ch3 id=\"comprehensive-validation-framework\">Comprehensive Validation Framework\u003C/h3>\n\u003Cp>Building robust validation systems for Markdown content:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-python\">\u003Cspan class=\"hljs-comment\"># markdown_validator.py - Advanced validation framework\u003C/span>\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> yaml\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> re\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> os\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> requests\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> datetime \u003Cspan class=\"hljs-keyword\">import\u003C/span> datetime, date\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> pathlib \u003Cspan class=\"hljs-keyword\">import\u003C/span> Path\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>, \u003Cspan class=\"hljs-type\">Tuple\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> enum \u003Cspan class=\"hljs-keyword\">import\u003C/span> Enum\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">ValidationLevel\u003C/span>(\u003Cspan class=\"hljs-title class_ inherited__\">Enum\u003C/span>):\n    ERROR = \u003Cspan class=\"hljs-string\">&quot;error&quot;\u003C/span>\n    WARNING = \u003Cspan class=\"hljs-string\">&quot;warning&quot;\u003C/span>\n    INFO = \u003Cspan class=\"hljs-string\">&quot;info&quot;\u003C/span>\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">ValidationCategory\u003C/span>(\u003Cspan class=\"hljs-title class_ inherited__\">Enum\u003C/span>):\n    FRONTMATTER = \u003Cspan class=\"hljs-string\">&quot;frontmatter&quot;\u003C/span>\n    CONTENT = \u003Cspan class=\"hljs-string\">&quot;content&quot;\u003C/span>\n    STRUCTURE = \u003Cspan class=\"hljs-string\">&quot;structure&quot;\u003C/span>\n    LINKS = \u003Cspan class=\"hljs-string\">&quot;links&quot;\u003C/span>\n    IMAGES = \u003Cspan class=\"hljs-string\">&quot;images&quot;\u003C/span>\n    STYLE = \u003Cspan class=\"hljs-string\">&quot;style&quot;\u003C/span>\n\n\u003Cspan class=\"hljs-meta\">@dataclass\u003C/span>\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">ValidationResult\u003C/span>:\n    level: ValidationLevel\n    category: ValidationCategory\n    message: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\n    line_number: \u003Cspan class=\"hljs-type\">Optional\u003C/span>[\u003Cspan class=\"hljs-built_in\">int\u003C/span>] = \u003Cspan class=\"hljs-literal\">None\u003C/span>\n    column_number: \u003Cspan class=\"hljs-type\">Optional\u003C/span>[\u003Cspan class=\"hljs-built_in\">int\u003C/span>] = \u003Cspan class=\"hljs-literal\">None\u003C/span>\n    suggestion: \u003Cspan class=\"hljs-type\">Optional\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>] = \u003Cspan class=\"hljs-literal\">None\u003C/span>\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">MarkdownValidator\u003C/span>:\n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">__init__\u003C/span>(\u003Cspan class=\"hljs-params\">self, schema_path: \u003Cspan class=\"hljs-built_in\">str\u003C/span> = \u003Cspan class=\"hljs-string\">&quot;markdown-schema.yml&quot;\u003C/span>\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Initialize validator with schema configuration&quot;&quot;&quot;\u003C/span>\n        self.schema = self.load_schema(schema_path)\n        self.results: \u003Cspan class=\"hljs-type\">List\u003C/span>[ValidationResult] = []\n        \n        \u003Cspan class=\"hljs-comment\"># Compiled regex patterns for performance\u003C/span>\n        self.patterns = {\n            \u003Cspan class=\"hljs-string\">&#x27;frontmatter&#x27;\u003C/span>: re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^---\\n(.*?)\\n---&#x27;\u003C/span>, re.DOTALL),\n            \u003Cspan class=\"hljs-string\">&#x27;heading&#x27;\u003C/span>: re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^(#{1,6})\\s+(.+)$&#x27;\u003C/span>, re.MULTILINE),\n            \u003Cspan class=\"hljs-string\">&#x27;code_block&#x27;\u003C/span>: re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;```(\\w*)\\n(.*?)\\n```&#x27;\u003C/span>, re.DOTALL),\n            \u003Cspan class=\"hljs-string\">&#x27;inline_code&#x27;\u003C/span>: re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;`([^`]+)`&#x27;\u003C/span>),\n            \u003Cspan class=\"hljs-string\">&#x27;link&#x27;\u003C/span>: re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;\\[([^\\]]+)\\]\\(([^)]+)\\)&#x27;\u003C/span>),\n            \u003Cspan class=\"hljs-string\">&#x27;image&#x27;\u003C/span>: re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;!\\[([^\\]]*)\\]\\(([^)]+)\\)&#x27;\u003C/span>),\n            \u003Cspan class=\"hljs-string\">&#x27;liquid_syntax&#x27;\u003C/span>: re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;\\{\\{.*?\\}\\}|\\{%.*?%\\}&#x27;\u003C/span>),\n            \u003Cspan class=\"hljs-string\">&#x27;html_tags&#x27;\u003C/span>: re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;&lt;[^&gt;]+&gt;&#x27;\u003C/span>),\n            \u003Cspan class=\"hljs-string\">&#x27;word_boundary&#x27;\u003C/span>: re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;\\b\\w+\\b&#x27;\u003C/span>)\n        }\n        \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">load_schema\u003C/span>(\u003Cspan class=\"hljs-params\">self, schema_path: \u003Cspan class=\"hljs-built_in\">str\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;Load validation schema from YAML file&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">try\u003C/span>:\n            \u003Cspan class=\"hljs-keyword\">with\u003C/span> \u003Cspan class=\"hljs-built_in\">open\u003C/span>(schema_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                \u003Cspan class=\"hljs-keyword\">return\u003C/span> yaml.safe_load(f)\n        \u003Cspan class=\"hljs-keyword\">except\u003C/span> FileNotFoundError:\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> self.get_default_schema()\n        \u003Cspan class=\"hljs-keyword\">except\u003C/span> yaml.YAMLError \u003Cspan class=\"hljs-keyword\">as\u003C/span> e:\n            \u003Cspan class=\"hljs-keyword\">raise\u003C/span> ValueError(\u003Cspan class=\"hljs-string\">f&quot;Invalid schema YAML: \u003Cspan class=\"hljs-subst\">{e}\u003C/span>&quot;\u003C/span>)\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">get_default_schema\u003C/span>(\u003Cspan class=\"hljs-params\">self\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;Return default schema when no schema file is found&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> {\n            \u003Cspan class=\"hljs-string\">&#x27;schema_version&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;1.0&#x27;\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&#x27;document_types&#x27;\u003C/span>: {\n                \u003Cspan class=\"hljs-string\">&#x27;default&#x27;\u003C/span>: {\n                    \u003Cspan class=\"hljs-string\">&#x27;required_frontmatter&#x27;\u003C/span>: [\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-string\">&#x27;content_rules&#x27;\u003C/span>: {\n                        \u003Cspan class=\"hljs-string\">&#x27;min_word_count&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">100\u003C/span>,\n                        \u003Cspan class=\"hljs-string\">&#x27;max_word_count&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">10000\u003C/span>\n                    }\n                }\n            }\n        }\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate_file\u003C/span>(\u003Cspan class=\"hljs-params\">self, file_path: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, document_type: \u003Cspan class=\"hljs-built_in\">str\u003C/span> = \u003Cspan class=\"hljs-string\">&#x27;default&#x27;\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">List\u003C/span>[ValidationResult]:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate a single Markdown file&quot;&quot;&quot;\u003C/span>\n        self.results = []\n        \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        \u003Cspan class=\"hljs-keyword\">except\u003C/span> Exception \u003Cspan class=\"hljs-keyword\">as\u003C/span> e:\n            self.results.append(ValidationResult(\n                level=ValidationLevel.ERROR,\n                category=ValidationCategory.STRUCTURE,\n                message=\u003Cspan class=\"hljs-string\">f&quot;Cannot read file: \u003Cspan class=\"hljs-subst\">{e}\u003C/span>&quot;\u003C/span>\n            ))\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> self.results\n        \n        \u003Cspan class=\"hljs-comment\"># Get document type schema\u003C/span>\n        schema = self.schema[\u003Cspan class=\"hljs-string\">&#x27;document_types&#x27;\u003C/span>].get(document_type, \n                                                   self.schema[\u003Cspan class=\"hljs-string\">&#x27;document_types&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;default&#x27;\u003C/span>])\n        \n        \u003Cspan class=\"hljs-comment\"># Parse frontmatter and content\u003C/span>\n        frontmatter, content_body = self.parse_document(content)\n        \n        \u003Cspan class=\"hljs-comment\"># Run validation checks\u003C/span>\n        self.validate_frontmatter(frontmatter, schema)\n        self.validate_content_structure(content_body, schema)\n        self.validate_content_rules(content_body, schema)\n        self.validate_links(content_body, file_path)\n        self.validate_images(content_body, file_path)\n        self.validate_code_blocks(content_body, schema)\n        self.validate_style_guidelines(content_body)\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> self.results\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">parse_document\u003C/span>(\u003Cspan class=\"hljs-params\">self, content: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Tuple\u003C/span>[\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-built_in\">str\u003C/span>]:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Parse frontmatter and content body from markdown&quot;&quot;&quot;\u003C/span>\n        frontmatter_match = self.patterns[\u003Cspan class=\"hljs-string\">&#x27;frontmatter&#x27;\u003C/span>].\u003Cspan class=\"hljs-keyword\">match\u003C/span>(content)\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> frontmatter_match:\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> {}, content\n        \n        \u003Cspan class=\"hljs-keyword\">try\u003C/span>:\n            frontmatter = yaml.safe_load(frontmatter_match.group(\u003Cspan class=\"hljs-number\">1\u003C/span>))\n            content_body = content[frontmatter_match.end():]\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> frontmatter \u003Cspan class=\"hljs-keyword\">or\u003C/span> {}, content_body\n        \u003Cspan class=\"hljs-keyword\">except\u003C/span> yaml.YAMLError \u003Cspan class=\"hljs-keyword\">as\u003C/span> e:\n            self.results.append(ValidationResult(\n                level=ValidationLevel.ERROR,\n                category=ValidationCategory.FRONTMATTER,\n                message=\u003Cspan class=\"hljs-string\">f&quot;Invalid frontmatter YAML: \u003Cspan class=\"hljs-subst\">{e}\u003C/span>&quot;\u003C/span>,\n                line_number=\u003Cspan class=\"hljs-number\">1\u003C/span>\n            ))\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> {}, content\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate_frontmatter\u003C/span>(\u003Cspan class=\"hljs-params\">self, frontmatter: \u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>], schema: \u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>]\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate frontmatter against schema requirements&quot;&quot;&quot;\u003C/span>\n        required_fields = schema.get(\u003Cspan class=\"hljs-string\">&#x27;required_frontmatter&#x27;\u003C/span>, [])\n        optional_fields = schema.get(\u003Cspan class=\"hljs-string\">&#x27;optional_frontmatter&#x27;\u003C/span>, [])\n        frontmatter_rules = schema.get(\u003Cspan class=\"hljs-string\">&#x27;frontmatter_rules&#x27;\u003C/span>, {})\n        \n        \u003Cspan class=\"hljs-comment\"># Check required fields\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> field \u003Cspan class=\"hljs-keyword\">in\u003C/span> required_fields:\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> field \u003Cspan class=\"hljs-keyword\">not\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> frontmatter:\n                self.results.append(ValidationResult(\n                    level=ValidationLevel.ERROR,\n                    category=ValidationCategory.FRONTMATTER,\n                    message=\u003Cspan class=\"hljs-string\">f&quot;Missing required frontmatter field: \u003Cspan class=\"hljs-subst\">{field}\u003C/span>&quot;\u003C/span>,\n                    suggestion=\u003Cspan class=\"hljs-string\">f&quot;Add &#x27;\u003Cspan class=\"hljs-subst\">{field}\u003C/span>: [value]&#x27; to frontmatter&quot;\u003C/span>\n                ))\n            \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n                \u003Cspan class=\"hljs-comment\"># Validate field according to rules\u003C/span>\n                self.validate_frontmatter_field(field, frontmatter[field], frontmatter_rules.get(field, {}))\n        \n        \u003Cspan class=\"hljs-comment\"># Check for unknown fields\u003C/span>\n        all_allowed = \u003Cspan class=\"hljs-built_in\">set\u003C/span>(required_fields + optional_fields)\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> field \u003Cspan class=\"hljs-keyword\">in\u003C/span> frontmatter:\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> field \u003Cspan class=\"hljs-keyword\">not\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> all_allowed:\n                self.results.append(ValidationResult(\n                    level=ValidationLevel.WARNING,\n                    category=ValidationCategory.FRONTMATTER,\n                    message=\u003Cspan class=\"hljs-string\">f&quot;Unknown frontmatter field: \u003Cspan class=\"hljs-subst\">{field}\u003C/span>&quot;\u003C/span>,\n                    suggestion=\u003Cspan class=\"hljs-string\">&quot;Remove unknown field or add to schema&quot;\u003C/span>\n                ))\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate_frontmatter_field\u003C/span>(\u003Cspan class=\"hljs-params\">self, field_name: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, value: \u003Cspan class=\"hljs-type\">Any\u003C/span>, rules: \u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>]\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate individual frontmatter field against rules&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> rules:\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Type validation\u003C/span>\n        expected_type = rules.get(\u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>)\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> expected_type == \u003Cspan class=\"hljs-string\">&#x27;string&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">and\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> \u003Cspan class=\"hljs-built_in\">isinstance\u003C/span>(value, \u003Cspan class=\"hljs-built_in\">str\u003C/span>):\n            self.results.append(ValidationResult(\n                level=ValidationLevel.ERROR,\n                category=ValidationCategory.FRONTMATTER,\n                message=\u003Cspan class=\"hljs-string\">f&quot;Field &#x27;\u003Cspan class=\"hljs-subst\">{field_name}\u003C/span>&#x27; must be a string&quot;\u003C/span>,\n                suggestion=\u003Cspan class=\"hljs-string\">f&quot;Change \u003Cspan class=\"hljs-subst\">{field_name}\u003C/span> value to string format&quot;\u003C/span>\n            ))\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">elif\u003C/span> expected_type == \u003Cspan class=\"hljs-string\">&#x27;date&#x27;\u003C/span>:\n            self.validate_date_field(field_name, value, rules)\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> \u003Cspan class=\"hljs-built_in\">isinstance\u003C/span>(value, \u003Cspan class=\"hljs-built_in\">str\u003C/span>):\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Length validation\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;min_length&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> rules \u003Cspan class=\"hljs-keyword\">and\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(value) &lt; rules[\u003Cspan class=\"hljs-string\">&#x27;min_length&#x27;\u003C/span>]:\n            self.results.append(ValidationResult(\n                level=ValidationLevel.WARNING,\n                category=ValidationCategory.FRONTMATTER,\n                message=\u003Cspan class=\"hljs-string\">f&quot;Field &#x27;\u003Cspan class=\"hljs-subst\">{field_name}\u003C/span>&#x27; is too short (min \u003Cspan class=\"hljs-subst\">{rules[\u003Cspan class=\"hljs-string\">&#x27;min_length&#x27;\u003C/span>]}\u003C/span> chars)&quot;\u003C/span>,\n                suggestion=\u003Cspan class=\"hljs-string\">f&quot;Expand \u003Cspan class=\"hljs-subst\">{field_name}\u003C/span> to meet minimum length requirement&quot;\u003C/span>\n            ))\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;max_length&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> rules \u003Cspan class=\"hljs-keyword\">and\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(value) &gt; rules[\u003Cspan class=\"hljs-string\">&#x27;max_length&#x27;\u003C/span>]:\n            self.results.append(ValidationResult(\n                level=ValidationLevel.WARNING,\n                category=ValidationCategory.FRONTMATTER,\n                message=\u003Cspan class=\"hljs-string\">f&quot;Field &#x27;\u003Cspan class=\"hljs-subst\">{field_name}\u003C/span>&#x27; is too long (max \u003Cspan class=\"hljs-subst\">{rules[\u003Cspan class=\"hljs-string\">&#x27;max_length&#x27;\u003C/span>]}\u003C/span> chars)&quot;\u003C/span>,\n                suggestion=\u003Cspan class=\"hljs-string\">f&quot;Shorten \u003Cspan class=\"hljs-subst\">{field_name}\u003C/span> to meet maximum length requirement&quot;\u003C/span>\n            ))\n        \n        \u003Cspan class=\"hljs-comment\"># Pattern validation\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;pattern&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> rules:\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> re.\u003Cspan class=\"hljs-keyword\">match\u003C/span>(rules[\u003Cspan class=\"hljs-string\">&#x27;pattern&#x27;\u003C/span>], value):\n                self.results.append(ValidationResult(\n                    level=ValidationLevel.ERROR,\n                    category=ValidationCategory.FRONTMATTER,\n                    message=\u003Cspan class=\"hljs-string\">f&quot;Field &#x27;\u003Cspan class=\"hljs-subst\">{field_name}\u003C/span>&#x27; doesn&#x27;t match required pattern&quot;\u003C/span>,\n                    suggestion=\u003Cspan class=\"hljs-string\">f&quot;Update \u003Cspan class=\"hljs-subst\">{field_name}\u003C/span> format to match: \u003Cspan class=\"hljs-subst\">{rules[\u003Cspan class=\"hljs-string\">&#x27;pattern&#x27;\u003C/span>]}\u003C/span>&quot;\u003C/span>\n                ))\n        \n        \u003Cspan class=\"hljs-comment\"># Allowed values validation\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;allowed_values&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> rules:\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> value \u003Cspan class=\"hljs-keyword\">not\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> rules[\u003Cspan class=\"hljs-string\">&#x27;allowed_values&#x27;\u003C/span>]:\n                self.results.append(ValidationResult(\n                    level=ValidationLevel.ERROR,\n                    category=ValidationCategory.FRONTMATTER,\n                    message=\u003Cspan class=\"hljs-string\">f&quot;Field &#x27;\u003Cspan class=\"hljs-subst\">{field_name}\u003C/span>&#x27; has invalid value: \u003Cspan class=\"hljs-subst\">{value}\u003C/span>&quot;\u003C/span>,\n                    suggestion=\u003Cspan class=\"hljs-string\">f&quot;Use one of: \u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-string\">&#x27;, &#x27;\u003C/span>.join(rules[\u003Cspan class=\"hljs-string\">&#x27;allowed_values&#x27;\u003C/span>])}\u003C/span>&quot;\u003C/span>\n                ))\n        \n        \u003Cspan class=\"hljs-comment\"># Custom validations\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> field_name == \u003Cspan class=\"hljs-string\">&#x27;keywords&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">and\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;min_keywords&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> rules:\n            keywords = [k.strip() \u003Cspan class=\"hljs-keyword\">for\u003C/span> k \u003Cspan class=\"hljs-keyword\">in\u003C/span> value.split(rules.get(\u003Cspan class=\"hljs-string\">&#x27;separator&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;,&#x27;\u003C/span>))]\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(keywords) &lt; rules[\u003Cspan class=\"hljs-string\">&#x27;min_keywords&#x27;\u003C/span>]:\n                self.results.append(ValidationResult(\n                    level=ValidationLevel.WARNING,\n                    category=ValidationCategory.FRONTMATTER,\n                    message=\u003Cspan class=\"hljs-string\">f&quot;Too few keywords (\u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-built_in\">len\u003C/span>(keywords)}\u003C/span> &lt; \u003Cspan class=\"hljs-subst\">{rules[\u003Cspan class=\"hljs-string\">&#x27;min_keywords&#x27;\u003C/span>]}\u003C/span>)&quot;\u003C/span>,\n                    suggestion=\u003Cspan class=\"hljs-string\">f&quot;Add more relevant keywords&quot;\u003C/span>\n                ))\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;must_end_with_period&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> rules \u003Cspan class=\"hljs-keyword\">and\u003C/span> rules[\u003Cspan class=\"hljs-string\">&#x27;must_end_with_period&#x27;\u003C/span>]:\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> value.rstrip().endswith(\u003Cspan class=\"hljs-string\">&#x27;.&#x27;\u003C/span>):\n                self.results.append(ValidationResult(\n                    level=ValidationLevel.WARNING,\n                    category=ValidationCategory.FRONTMATTER,\n                    message=\u003Cspan class=\"hljs-string\">f&quot;Field &#x27;\u003Cspan class=\"hljs-subst\">{field_name}\u003C/span>&#x27; should end with a period&quot;\u003C/span>,\n                    suggestion=\u003Cspan class=\"hljs-string\">f&quot;Add period at the end of \u003Cspan class=\"hljs-subst\">{field_name}\u003C/span>&quot;\u003C/span>\n                ))\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate_date_field\u003C/span>(\u003Cspan class=\"hljs-params\">self, field_name: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, value: \u003Cspan class=\"hljs-type\">Any\u003C/span>, rules: \u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>]\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate date field with specific date rules&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">try\u003C/span>:\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">isinstance\u003C/span>(value, \u003Cspan class=\"hljs-built_in\">str\u003C/span>):\n                parsed_date = datetime.strptime(value, rules.get(\u003Cspan class=\"hljs-string\">&#x27;format&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;%Y-%m-%d&#x27;\u003C/span>)).date()\n            \u003Cspan class=\"hljs-keyword\">elif\u003C/span> \u003Cspan class=\"hljs-built_in\">isinstance\u003C/span>(value, date):\n                parsed_date = value\n            \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n                self.results.append(ValidationResult(\n                    level=ValidationLevel.ERROR,\n                    category=ValidationCategory.FRONTMATTER,\n                    message=\u003Cspan class=\"hljs-string\">f&quot;Field &#x27;\u003Cspan class=\"hljs-subst\">{field_name}\u003C/span>&#x27; must be a valid date&quot;\u003C/span>,\n                    suggestion=\u003Cspan class=\"hljs-string\">f&quot;Use format: \u003Cspan class=\"hljs-subst\">{rules.get(\u003Cspan class=\"hljs-string\">&#x27;format&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;YYYY-MM-DD&#x27;\u003C/span>)}\u003C/span>&quot;\u003C/span>\n                ))\n                \u003Cspan class=\"hljs-keyword\">return\u003C/span>\n            \n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> rules.get(\u003Cspan class=\"hljs-string\">&#x27;not_future&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">and\u003C/span> parsed_date &gt; date.today():\n                self.results.append(ValidationResult(\n                    level=ValidationLevel.WARNING,\n                    category=ValidationCategory.FRONTMATTER,\n                    message=\u003Cspan class=\"hljs-string\">f&quot;Field &#x27;\u003Cspan class=\"hljs-subst\">{field_name}\u003C/span>&#x27; is set to future date&quot;\u003C/span>,\n                    suggestion=\u003Cspan class=\"hljs-string\">&quot;Use current or past date&quot;\u003C/span>\n                ))\n                \n        \u003Cspan class=\"hljs-keyword\">except\u003C/span> ValueError:\n            self.results.append(ValidationResult(\n                level=ValidationLevel.ERROR,\n                category=ValidationCategory.FRONTMATTER,\n                message=\u003Cspan class=\"hljs-string\">f&quot;Field &#x27;\u003Cspan class=\"hljs-subst\">{field_name}\u003C/span>&#x27; has invalid date format&quot;\u003C/span>,\n                suggestion=\u003Cspan class=\"hljs-string\">f&quot;Use format: \u003Cspan class=\"hljs-subst\">{rules.get(\u003Cspan class=\"hljs-string\">&#x27;format&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;YYYY-MM-DD&#x27;\u003C/span>)}\u003C/span>&quot;\u003C/span>\n            ))\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate_content_structure\u003C/span>(\u003Cspan class=\"hljs-params\">self, content: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, schema: \u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>]\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate overall content structure&quot;&quot;&quot;\u003C/span>\n        content_rules = schema.get(\u003Cspan class=\"hljs-string\">&#x27;content_rules&#x27;\u003C/span>, {})\n        \n        \u003Cspan class=\"hljs-comment\"># Word count validation\u003C/span>\n        words = self.patterns[\u003Cspan class=\"hljs-string\">&#x27;word_boundary&#x27;\u003C/span>].findall(content)\n        word_count = \u003Cspan class=\"hljs-built_in\">len\u003C/span>(words)\n        \n        min_words = content_rules.get(\u003Cspan class=\"hljs-string\">&#x27;min_word_count&#x27;\u003C/span>, \u003Cspan class=\"hljs-number\">0\u003C/span>)\n        max_words = content_rules.get(\u003Cspan class=\"hljs-string\">&#x27;max_word_count&#x27;\u003C/span>, \u003Cspan class=\"hljs-built_in\">float\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;inf&#x27;\u003C/span>))\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> word_count &lt; min_words:\n            self.results.append(ValidationResult(\n                level=ValidationLevel.WARNING,\n                category=ValidationCategory.CONTENT,\n                message=\u003Cspan class=\"hljs-string\">f&quot;Content too short: \u003Cspan class=\"hljs-subst\">{word_count}\u003C/span> words (min \u003Cspan class=\"hljs-subst\">{min_words}\u003C/span>)&quot;\u003C/span>,\n                suggestion=\u003Cspan class=\"hljs-string\">f&quot;Add \u003Cspan class=\"hljs-subst\">{min_words - word_count}\u003C/span> more words&quot;\u003C/span>\n            ))\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> word_count &gt; max_words:\n            self.results.append(ValidationResult(\n                level=ValidationLevel.WARNING,\n                category=ValidationCategory.CONTENT,\n                message=\u003Cspan class=\"hljs-string\">f&quot;Content too long: \u003Cspan class=\"hljs-subst\">{word_count}\u003C/span> words (max \u003Cspan class=\"hljs-subst\">{max_words}\u003C/span>)&quot;\u003C/span>,\n                suggestion=\u003Cspan class=\"hljs-string\">f&quot;Remove \u003Cspan class=\"hljs-subst\">{word_count - max_words}\u003C/span> words or split content&quot;\u003C/span>\n            ))\n        \n        \u003Cspan class=\"hljs-comment\"># Heading structure validation\u003C/span>\n        self.validate_heading_structure(content, content_rules)\n        \n        \u003Cspan class=\"hljs-comment\"># Required sections validation\u003C/span>\n        self.validate_required_sections(content, content_rules)\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate_heading_structure\u003C/span>(\u003Cspan class=\"hljs-params\">self, content: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, rules: \u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>]\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate heading hierarchy and structure&quot;&quot;&quot;\u003C/span>\n        heading_rules = rules.get(\u003Cspan class=\"hljs-string\">&#x27;heading_structure&#x27;\u003C/span>, {})\n        headings = self.patterns[\u003Cspan class=\"hljs-string\">&#x27;heading&#x27;\u003C/span>].findall(content)\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> headings:\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> heading_rules.get(\u003Cspan class=\"hljs-string\">&#x27;require_h1&#x27;\u003C/span>):\n                self.results.append(ValidationResult(\n                    level=ValidationLevel.ERROR,\n                    category=ValidationCategory.STRUCTURE,\n                    message=\u003Cspan class=\"hljs-string\">&quot;Missing required H1 heading&quot;\u003C/span>,\n                    suggestion=\u003Cspan class=\"hljs-string\">&quot;Add a main heading with # at the beginning&quot;\u003C/span>\n                ))\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Check for H1 requirement\u003C/span>\n        has_h1 = \u003Cspan class=\"hljs-built_in\">any\u003C/span>(\u003Cspan class=\"hljs-built_in\">len\u003C/span>(h[\u003Cspan class=\"hljs-number\">0\u003C/span>]) == \u003Cspan class=\"hljs-number\">1\u003C/span> \u003Cspan class=\"hljs-keyword\">for\u003C/span> h \u003Cspan class=\"hljs-keyword\">in\u003C/span> headings)\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> heading_rules.get(\u003Cspan class=\"hljs-string\">&#x27;require_h1&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">and\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> has_h1:\n            self.results.append(ValidationResult(\n                level=ValidationLevel.ERROR,\n                category=ValidationCategory.STRUCTURE,\n                message=\u003Cspan class=\"hljs-string\">&quot;Missing required H1 heading&quot;\u003C/span>,\n                suggestion=\u003Cspan class=\"hljs-string\">&quot;Add a main heading with #&quot;\u003C/span>\n            ))\n        \n        \u003Cspan class=\"hljs-comment\"># Check maximum heading level\u003C/span>\n        max_level = heading_rules.get(\u003Cspan class=\"hljs-string\">&#x27;max_heading_level&#x27;\u003C/span>, \u003Cspan class=\"hljs-number\">6\u003C/span>)\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> heading_hashes, heading_text \u003Cspan class=\"hljs-keyword\">in\u003C/span> headings:\n            level = \u003Cspan class=\"hljs-built_in\">len\u003C/span>(heading_hashes)\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> level &gt; max_level:\n                self.results.append(ValidationResult(\n                    level=ValidationLevel.WARNING,\n                    category=ValidationCategory.STRUCTURE,\n                    message=\u003Cspan class=\"hljs-string\">f&quot;Heading level \u003Cspan class=\"hljs-subst\">{level}\u003C/span> exceeds maximum \u003Cspan class=\"hljs-subst\">{max_level}\u003C/span>: \u003Cspan class=\"hljs-subst\">{heading_text}\u003C/span>&quot;\u003C/span>,\n                    suggestion=\u003Cspan class=\"hljs-string\">f&quot;Use heading level \u003Cspan class=\"hljs-subst\">{max_level}\u003C/span> or lower&quot;\u003C/span>\n                ))\n        \n        \u003Cspan class=\"hljs-comment\"># Check sequential levels\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> heading_rules.get(\u003Cspan class=\"hljs-string\">&#x27;sequential_levels&#x27;\u003C/span>):\n            levels = [\u003Cspan class=\"hljs-built_in\">len\u003C/span>(h[\u003Cspan class=\"hljs-number\">0\u003C/span>]) \u003Cspan class=\"hljs-keyword\">for\u003C/span> h \u003Cspan class=\"hljs-keyword\">in\u003C/span> headings]\n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> i \u003Cspan class=\"hljs-keyword\">in\u003C/span> \u003Cspan class=\"hljs-built_in\">range\u003C/span>(\u003Cspan class=\"hljs-number\">1\u003C/span>, \u003Cspan class=\"hljs-built_in\">len\u003C/span>(levels)):\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> levels[i] &gt; levels[i-\u003Cspan class=\"hljs-number\">1\u003C/span>] + \u003Cspan class=\"hljs-number\">1\u003C/span>:\n                    self.results.append(ValidationResult(\n                        level=ValidationLevel.WARNING,\n                        category=ValidationCategory.STRUCTURE,\n                        message=\u003Cspan class=\"hljs-string\">f&quot;Heading level jumps from \u003Cspan class=\"hljs-subst\">{levels[i-\u003Cspan class=\"hljs-number\">1\u003C/span>]}\u003C/span> to \u003Cspan class=\"hljs-subst\">{levels[i]}\u003C/span>&quot;\u003C/span>,\n                        suggestion=\u003Cspan class=\"hljs-string\">&quot;Use sequential heading levels&quot;\u003C/span>\n                    ))\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate_required_sections\u003C/span>(\u003Cspan class=\"hljs-params\">self, content: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, rules: \u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>]\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate presence of required content sections&quot;&quot;&quot;\u003C/span>\n        required_sections = rules.get(\u003Cspan class=\"hljs-string\">&#x27;required_sections&#x27;\u003C/span>, [])\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> section \u003Cspan class=\"hljs-keyword\">in\u003C/span> required_sections:\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> section == \u003Cspan class=\"hljs-string\">&#x27;introduction_paragraph&#x27;\u003C/span>:\n                \u003Cspan class=\"hljs-comment\"># Check for substantial first paragraph\u003C/span>\n                paragraphs = content.strip().split(\u003Cspan class=\"hljs-string\">&#x27;\\n\\n&#x27;\u003C/span>)\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> paragraphs \u003Cspan class=\"hljs-keyword\">or\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(paragraphs[\u003Cspan class=\"hljs-number\">0\u003C/span>].split()) &lt; \u003Cspan class=\"hljs-number\">20\u003C/span>:\n                    self.results.append(ValidationResult(\n                        level=ValidationLevel.WARNING,\n                        category=ValidationCategory.CONTENT,\n                        message=\u003Cspan class=\"hljs-string\">&quot;Missing substantial introduction paragraph&quot;\u003C/span>,\n                        suggestion=\u003Cspan class=\"hljs-string\">&quot;Add a comprehensive introduction (20+ words)&quot;\u003C/span>\n                    ))\n            \n            \u003Cspan class=\"hljs-keyword\">elif\u003C/span> section == \u003Cspan class=\"hljs-string\">&#x27;conclusion_section&#x27;\u003C/span>:\n                \u003Cspan class=\"hljs-comment\"># Check for conclusion heading or paragraph at end\u003C/span>\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> re.search(\u003Cspan class=\"hljs-string\">r&#x27;## Conclusion|# Conclusion|In conclusion|To conclude&#x27;\u003C/span>, content, re.IGNORECASE):\n                    self.results.append(ValidationResult(\n                        level=ValidationLevel.WARNING,\n                        category=ValidationCategory.CONTENT,\n                        message=\u003Cspan class=\"hljs-string\">&quot;Missing conclusion section&quot;\u003C/span>,\n                        suggestion=\u003Cspan class=\"hljs-string\">&quot;Add a conclusion section or paragraph&quot;\u003C/span>\n                    ))\n            \n            \u003Cspan class=\"hljs-keyword\">elif\u003C/span> section == \u003Cspan class=\"hljs-string\">&#x27;main_headings&#x27;\u003C/span>:\n                headings = self.patterns[\u003Cspan class=\"hljs-string\">&#x27;heading&#x27;\u003C/span>].findall(content)\n                main_headings = [h \u003Cspan class=\"hljs-keyword\">for\u003C/span> h \u003Cspan class=\"hljs-keyword\">in\u003C/span> headings \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(h[\u003Cspan class=\"hljs-number\">0\u003C/span>]) &lt;= \u003Cspan class=\"hljs-number\">3\u003C/span>]  \u003Cspan class=\"hljs-comment\"># H1, H2, H3\u003C/span>\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(main_headings) &lt; \u003Cspan class=\"hljs-number\">2\u003C/span>:\n                    self.results.append(ValidationResult(\n                        level=ValidationLevel.WARNING,\n                        category=ValidationCategory.STRUCTURE,\n                        message=\u003Cspan class=\"hljs-string\">&quot;Insufficient main headings for content structure&quot;\u003C/span>,\n                        suggestion=\u003Cspan class=\"hljs-string\">&quot;Add more section headings to organize content&quot;\u003C/span>\n                    ))\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate_content_rules\u003C/span>(\u003Cspan class=\"hljs-params\">self, content: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, schema: \u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>]\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate specific content formatting rules&quot;&quot;&quot;\u003C/span>\n        content_rules = schema.get(\u003Cspan class=\"hljs-string\">&#x27;content_rules&#x27;\u003C/span>, {})\n        \n        \u003Cspan class=\"hljs-comment\"># Table of contents requirement\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> content_rules.get(\u003Cspan class=\"hljs-string\">&#x27;require_table_of_contents&#x27;\u003C/span>):\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> re.search(\u003Cspan class=\"hljs-string\">r&#x27;table of contents|toc&#x27;\u003C/span>, content, re.IGNORECASE):\n                self.results.append(ValidationResult(\n                    level=ValidationLevel.WARNING,\n                    category=ValidationCategory.CONTENT,\n                    message=\u003Cspan class=\"hljs-string\">&quot;Missing table of contents&quot;\u003C/span>,\n                    suggestion=\u003Cspan class=\"hljs-string\">&quot;Add a table of contents section&quot;\u003C/span>\n                ))\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate_links\u003C/span>(\u003Cspan class=\"hljs-params\">self, content: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, file_path: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate links in content&quot;&quot;&quot;\u003C/span>\n        links = self.patterns[\u003Cspan class=\"hljs-string\">&#x27;link&#x27;\u003C/span>].findall(content)\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> link_text, link_url \u003Cspan class=\"hljs-keyword\">in\u003C/span> links:\n            \u003Cspan class=\"hljs-comment\"># Check for empty link text\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> link_text.strip():\n                self.results.append(ValidationResult(\n                    level=ValidationLevel.WARNING,\n                    category=ValidationCategory.LINKS,\n                    message=\u003Cspan class=\"hljs-string\">f&quot;Link has empty description: \u003Cspan class=\"hljs-subst\">{link_url}\u003C/span>&quot;\u003C/span>,\n                    suggestion=\u003Cspan class=\"hljs-string\">&quot;Add descriptive link text&quot;\u003C/span>\n                ))\n            \n            \u003Cspan class=\"hljs-comment\"># Validate internal links\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> link_url.startswith(\u003Cspan class=\"hljs-string\">&#x27;/&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">or\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> link_url.startswith((\u003Cspan class=\"hljs-string\">&#x27;http://&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;https://&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;mailto:&#x27;\u003C/span>)):\n                self.validate_internal_link(link_url, file_path)\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate_internal_link\u003C/span>(\u003Cspan class=\"hljs-params\">self, link_url: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, file_path: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate internal link existence&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-comment\"># Convert relative link to absolute path\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> link_url.startswith(\u003Cspan class=\"hljs-string\">&#x27;/&#x27;\u003C/span>):\n            \u003Cspan class=\"hljs-comment\"># Absolute path from site root\u003C/span>\n            base_dir = Path(file_path).parent\n            \u003Cspan class=\"hljs-keyword\">while\u003C/span> base_dir.name != \u003Cspan class=\"hljs-string\">&#x27;_posts&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">and\u003C/span> base_dir.parent != base_dir:\n                base_dir = base_dir.parent\n            site_root = base_dir.parent \u003Cspan class=\"hljs-keyword\">if\u003C/span> base_dir.name == \u003Cspan class=\"hljs-string\">&#x27;_posts&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">else\u003C/span> base_dir\n            target_path = site_root / link_url.lstrip(\u003Cspan class=\"hljs-string\">&#x27;/&#x27;\u003C/span>)\n        \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n            \u003Cspan class=\"hljs-comment\"># Relative path\u003C/span>\n            target_path = Path(file_path).parent / link_url\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> target_path.exists():\n            self.results.append(ValidationResult(\n                level=ValidationLevel.ERROR,\n                category=ValidationCategory.LINKS,\n                message=\u003Cspan class=\"hljs-string\">f&quot;Broken internal link: \u003Cspan class=\"hljs-subst\">{link_url}\u003C/span>&quot;\u003C/span>,\n                suggestion=\u003Cspan class=\"hljs-string\">&quot;Fix link path or create target file&quot;\u003C/span>\n            ))\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate_images\u003C/span>(\u003Cspan class=\"hljs-params\">self, content: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, file_path: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate images in content&quot;&quot;&quot;\u003C/span>\n        images = self.patterns[\u003Cspan class=\"hljs-string\">&#x27;image&#x27;\u003C/span>].findall(content)\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> alt_text, image_url \u003Cspan class=\"hljs-keyword\">in\u003C/span> images:\n            \u003Cspan class=\"hljs-comment\"># Check for alt text\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> alt_text.strip():\n                self.results.append(ValidationResult(\n                    level=ValidationLevel.WARNING,\n                    category=ValidationCategory.IMAGES,\n                    message=\u003Cspan class=\"hljs-string\">f&quot;Image missing alt text: \u003Cspan class=\"hljs-subst\">{image_url}\u003C/span>&quot;\u003C/span>,\n                    suggestion=\u003Cspan class=\"hljs-string\">&quot;Add descriptive alt text for accessibility&quot;\u003C/span>\n                ))\n            \n            \u003Cspan class=\"hljs-comment\"># Validate image file existence for local images\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> image_url.startswith((\u003Cspan class=\"hljs-string\">&#x27;http://&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;https://&#x27;\u003C/span>)):\n                self.validate_image_file(image_url, file_path)\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate_image_file\u003C/span>(\u003Cspan class=\"hljs-params\">self, image_url: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, file_path: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate local image file existence and properties&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> image_url.startswith(\u003Cspan class=\"hljs-string\">&#x27;/&#x27;\u003C/span>):\n            \u003Cspan class=\"hljs-comment\"># Absolute path from site root\u003C/span>\n            base_dir = Path(file_path).parent\n            \u003Cspan class=\"hljs-keyword\">while\u003C/span> base_dir.name != \u003Cspan class=\"hljs-string\">&#x27;_posts&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">and\u003C/span> base_dir.parent != base_dir:\n                base_dir = base_dir.parent\n            site_root = base_dir.parent \u003Cspan class=\"hljs-keyword\">if\u003C/span> base_dir.name == \u003Cspan class=\"hljs-string\">&#x27;_posts&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">else\u003C/span> base_dir\n            image_path = site_root / image_url.lstrip(\u003Cspan class=\"hljs-string\">&#x27;/&#x27;\u003C/span>)\n        \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n            \u003Cspan class=\"hljs-comment\"># Relative path\u003C/span>\n            image_path = Path(file_path).parent / image_url\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> image_path.exists():\n            self.results.append(ValidationResult(\n                level=ValidationLevel.ERROR,\n                category=ValidationCategory.IMAGES,\n                message=\u003Cspan class=\"hljs-string\">f&quot;Missing image file: \u003Cspan class=\"hljs-subst\">{image_url}\u003C/span>&quot;\u003C/span>,\n                suggestion=\u003Cspan class=\"hljs-string\">&quot;Add image file or fix image path&quot;\u003C/span>\n            ))\n        \u003Cspan class=\"hljs-keyword\">elif\u003C/span> image_path.is_file():\n            \u003Cspan class=\"hljs-comment\"># Check file size if it exists\u003C/span>\n            file_size = image_path.stat().st_size\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> file_size &gt; \u003Cspan class=\"hljs-number\">2\u003C/span> * \u003Cspan class=\"hljs-number\">1024\u003C/span> * \u003Cspan class=\"hljs-number\">1024\u003C/span>:  \u003Cspan class=\"hljs-comment\"># 2MB limit\u003C/span>\n                self.results.append(ValidationResult(\n                    level=ValidationLevel.WARNING,\n                    category=ValidationCategory.IMAGES,\n                    message=\u003Cspan class=\"hljs-string\">f&quot;Large image file (\u003Cspan class=\"hljs-subst\">{file_size // \u003Cspan class=\"hljs-number\">1024\u003C/span>}\u003C/span>KB): \u003Cspan class=\"hljs-subst\">{image_url}\u003C/span>&quot;\u003C/span>,\n                    suggestion=\u003Cspan class=\"hljs-string\">&quot;Optimize image size for web performance&quot;\u003C/span>\n                ))\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate_code_blocks\u003C/span>(\u003Cspan class=\"hljs-params\">self, content: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, schema: \u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>]\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate code blocks formatting and content&quot;&quot;&quot;\u003C/span>\n        code_rules = schema.get(\u003Cspan class=\"hljs-string\">&#x27;content_rules&#x27;\u003C/span>, {}).get(\u003Cspan class=\"hljs-string\">&#x27;code_blocks&#x27;\u003C/span>, {})\n        code_blocks = self.patterns[\u003Cspan class=\"hljs-string\">&#x27;code_block&#x27;\u003C/span>].findall(content)\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> language, code_content \u003Cspan class=\"hljs-keyword\">in\u003C/span> code_blocks:\n            \u003Cspan class=\"hljs-comment\"># Check for language specification\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> code_rules.get(\u003Cspan class=\"hljs-string\">&#x27;require_language_tags&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">and\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> language.strip():\n                self.results.append(ValidationResult(\n                    level=ValidationLevel.WARNING,\n                    category=ValidationCategory.CONTENT,\n                    message=\u003Cspan class=\"hljs-string\">&quot;Code block missing language specification&quot;\u003C/span>,\n                    suggestion=\u003Cspan class=\"hljs-string\">&quot;Add language identifier after opening backticks&quot;\u003C/span>\n                ))\n            \n            \u003Cspan class=\"hljs-comment\"># Check line length\u003C/span>\n            max_line_length = code_rules.get(\u003Cspan class=\"hljs-string\">&#x27;max_line_length&#x27;\u003C/span>)\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> max_line_length:\n                lines = code_content.split(\u003Cspan class=\"hljs-string\">&#x27;\\n&#x27;\u003C/span>)\n                \u003Cspan class=\"hljs-keyword\">for\u003C/span> i, 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> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(line) &gt; max_line_length:\n                        self.results.append(ValidationResult(\n                            level=ValidationLevel.WARNING,\n                            category=ValidationCategory.CONTENT,\n                            message=\u003Cspan class=\"hljs-string\">f&quot;Code block line \u003Cspan class=\"hljs-subst\">{i}\u003C/span> exceeds \u003Cspan class=\"hljs-subst\">{max_line_length}\u003C/span> characters&quot;\u003C/span>,\n                            suggestion=\u003Cspan class=\"hljs-string\">&quot;Break long lines or use horizontal scrolling&quot;\u003C/span>\n                        ))\n            \n            \u003Cspan class=\"hljs-comment\"># Check for unescaped Liquid syntax\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> code_rules.get(\u003Cspan class=\"hljs-string\">&#x27;escape_liquid_syntax&#x27;\u003C/span>):\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> self.patterns[\u003Cspan class=\"hljs-string\">&#x27;liquid_syntax&#x27;\u003C/span>].search(code_content):\n                    \u003Cspan class=\"hljs-comment\"># Check if properly wrapped with raw tags\u003C/span>\n                    raw_pattern = re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;\\{\\%\\s*raw\\s*\\%\\}.*?\\{\\%\\s*endraw\\s*\\%\\}&#x27;\u003C/span>, re.DOTALL)\n                    \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> raw_pattern.search(content):\n                        self.results.append(ValidationResult(\n                            level=ValidationLevel.ERROR,\n                            category=ValidationCategory.CONTENT,\n                            message=\u003Cspan class=\"hljs-string\">&quot;Code block contains unescaped Liquid syntax&quot;\u003C/span>,\n                            suggestion=\u003Cspan class=\"hljs-string\">&quot;Wrap code block with {%&quot;\u003C/span> + \u003Cspan class=\"hljs-string\">&quot; raw %} and {%&quot;\u003C/span> + \u003Cspan class=\"hljs-string\">&quot; endraw %} tags&quot;\u003C/span>\n                        ))\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate_style_guidelines\u003C/span>(\u003Cspan class=\"hljs-params\">self, content: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate writing style and formatting guidelines&quot;&quot;&quot;\u003C/span>\n        lines = content.split(\u003Cspan class=\"hljs-string\">&#x27;\\n&#x27;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> i, 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-comment\"># Check for trailing whitespace\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> line.rstrip() != line:\n                self.results.append(ValidationResult(\n                    level=ValidationLevel.INFO,\n                    category=ValidationCategory.STYLE,\n                    message=\u003Cspan class=\"hljs-string\">f&quot;Line \u003Cspan class=\"hljs-subst\">{i}\u003C/span> has trailing whitespace&quot;\u003C/span>,\n                    suggestion=\u003Cspan class=\"hljs-string\">&quot;Remove trailing whitespace&quot;\u003C/span>\n                ))\n            \n            \u003Cspan class=\"hljs-comment\"># Check for very long lines (prose)\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(line) &gt; \u003Cspan class=\"hljs-number\">120\u003C/span> \u003Cspan class=\"hljs-keyword\">and\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> line.strip().startswith((\u003Cspan class=\"hljs-string\">&#x27;```&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;|&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;#&#x27;\u003C/span>)):\n                self.results.append(ValidationResult(\n                    level=ValidationLevel.INFO,\n                    category=ValidationCategory.STYLE,\n                    message=\u003Cspan class=\"hljs-string\">f&quot;Line \u003Cspan class=\"hljs-subst\">{i}\u003C/span> is very long (\u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-built_in\">len\u003C/span>(line)}\u003C/span> chars)&quot;\u003C/span>,\n                    suggestion=\u003Cspan class=\"hljs-string\">&quot;Consider breaking into shorter sentences&quot;\u003C/span>\n                ))\n        \n        \u003Cspan class=\"hljs-comment\"># Check for repeated words\u003C/span>\n        words = self.patterns[\u003Cspan class=\"hljs-string\">&#x27;word_boundary&#x27;\u003C/span>].findall(content.lower())\n        word_pairs = [(words[i], words[i+\u003Cspan class=\"hljs-number\">1\u003C/span>]) \u003Cspan class=\"hljs-keyword\">for\u003C/span> i \u003Cspan class=\"hljs-keyword\">in\u003C/span> \u003Cspan class=\"hljs-built_in\">range\u003C/span>(\u003Cspan class=\"hljs-built_in\">len\u003C/span>(words)-\u003Cspan class=\"hljs-number\">1\u003C/span>)]\n        repeated_pairs = [pair \u003Cspan class=\"hljs-keyword\">for\u003C/span> pair \u003Cspan class=\"hljs-keyword\">in\u003C/span> \u003Cspan class=\"hljs-built_in\">set\u003C/span>(word_pairs) \u003Cspan class=\"hljs-keyword\">if\u003C/span> word_pairs.count(pair) &gt; \u003Cspan class=\"hljs-number\">3\u003C/span> \u003Cspan class=\"hljs-keyword\">and\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(pair[\u003Cspan class=\"hljs-number\">0\u003C/span>]) &gt; \u003Cspan class=\"hljs-number\">3\u003C/span>]\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> pair \u003Cspan class=\"hljs-keyword\">in\u003C/span> repeated_pairs[:\u003Cspan class=\"hljs-number\">3\u003C/span>]:  \u003Cspan class=\"hljs-comment\"># Limit to avoid spam\u003C/span>\n            self.results.append(ValidationResult(\n                level=ValidationLevel.INFO,\n                category=ValidationCategory.STYLE,\n                message=\u003Cspan class=\"hljs-string\">f&quot;Frequently repeated word pair: &#x27;\u003Cspan class=\"hljs-subst\">{pair[\u003Cspan class=\"hljs-number\">0\u003C/span>]}\u003C/span> \u003Cspan class=\"hljs-subst\">{pair[\u003Cspan class=\"hljs-number\">1\u003C/span>]}\u003C/span>&#x27;&quot;\u003C/span>,\n                suggestion=\u003Cspan class=\"hljs-string\">&quot;Consider varying word choice for better readability&quot;\u003C/span>\n            ))\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">generate_report\u003C/span>(\u003Cspan class=\"hljs-params\">self, results: \u003Cspan class=\"hljs-type\">List\u003C/span>[ValidationResult]\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">str\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Generate human-readable validation report&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> results:\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-string\">&quot;✅ All validation checks passed!&quot;\u003C/span>\n        \n        report = [\u003Cspan class=\"hljs-string\">&quot;# Markdown Validation Report&quot;\u003C/span>, \u003Cspan class=\"hljs-string\">&quot;&quot;\u003C/span>]\n        \n        \u003Cspan class=\"hljs-comment\"># Summary\u003C/span>\n        error_count = \u003Cspan class=\"hljs-built_in\">len\u003C/span>([r \u003Cspan class=\"hljs-keyword\">for\u003C/span> r \u003Cspan class=\"hljs-keyword\">in\u003C/span> results \u003Cspan class=\"hljs-keyword\">if\u003C/span> r.level == ValidationLevel.ERROR])\n        warning_count = \u003Cspan class=\"hljs-built_in\">len\u003C/span>([r \u003Cspan class=\"hljs-keyword\">for\u003C/span> r \u003Cspan class=\"hljs-keyword\">in\u003C/span> results \u003Cspan class=\"hljs-keyword\">if\u003C/span> r.level == ValidationLevel.WARNING])\n        info_count = \u003Cspan class=\"hljs-built_in\">len\u003C/span>([r \u003Cspan class=\"hljs-keyword\">for\u003C/span> r \u003Cspan class=\"hljs-keyword\">in\u003C/span> results \u003Cspan class=\"hljs-keyword\">if\u003C/span> r.level == ValidationLevel.INFO])\n        \n        report.append(\u003Cspan class=\"hljs-string\">f&quot;## Summary&quot;\u003C/span>)\n        report.append(\u003Cspan class=\"hljs-string\">f&quot;- ❌ Errors: \u003Cspan class=\"hljs-subst\">{error_count}\u003C/span>&quot;\u003C/span>)\n        report.append(\u003Cspan class=\"hljs-string\">f&quot;- ⚠️  Warnings: \u003Cspan class=\"hljs-subst\">{warning_count}\u003C/span>&quot;\u003C/span>)  \n        report.append(\u003Cspan class=\"hljs-string\">f&quot;- ℹ️  Info: \u003Cspan class=\"hljs-subst\">{info_count}\u003C/span>&quot;\u003C/span>)\n        report.append(\u003Cspan class=\"hljs-string\">&quot;&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-comment\"># Group by category\u003C/span>\n        categories = {}\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> result \u003Cspan class=\"hljs-keyword\">in\u003C/span> results:\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> result.category \u003Cspan class=\"hljs-keyword\">not\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> categories:\n                categories[result.category] = []\n            categories[result.category].append(result)\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> category, category_results \u003Cspan class=\"hljs-keyword\">in\u003C/span> categories.items():\n            report.append(\u003Cspan class=\"hljs-string\">f&quot;## \u003Cspan class=\"hljs-subst\">{category.value.title()}\u003C/span> Issues&quot;\u003C/span>)\n            report.append(\u003Cspan class=\"hljs-string\">&quot;&quot;\u003C/span>)\n            \n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> result \u003Cspan class=\"hljs-keyword\">in\u003C/span> category_results:\n                level_icon = {\u003Cspan class=\"hljs-string\">&quot;error&quot;\u003C/span>: \u003Cspan class=\"hljs-string\">&quot;❌&quot;\u003C/span>, \u003Cspan class=\"hljs-string\">&quot;warning&quot;\u003C/span>: \u003Cspan class=\"hljs-string\">&quot;⚠️&quot;\u003C/span>, \u003Cspan class=\"hljs-string\">&quot;info&quot;\u003C/span>: \u003Cspan class=\"hljs-string\">&quot;ℹ️&quot;\u003C/span>}[result.level.value]\n                location = \u003Cspan class=\"hljs-string\">f&quot; (Line \u003Cspan class=\"hljs-subst\">{result.line_number}\u003C/span>)&quot;\u003C/span> \u003Cspan class=\"hljs-keyword\">if\u003C/span> result.line_number \u003Cspan class=\"hljs-keyword\">else\u003C/span> \u003Cspan class=\"hljs-string\">&quot;&quot;\u003C/span>\n                \n                report.append(\u003Cspan class=\"hljs-string\">f&quot;### \u003Cspan class=\"hljs-subst\">{level_icon}\u003C/span> \u003Cspan class=\"hljs-subst\">{result.message}\u003C/span>\u003Cspan class=\"hljs-subst\">{location}\u003C/span>&quot;\u003C/span>)\n                \n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> result.suggestion:\n                    report.append(\u003Cspan class=\"hljs-string\">f&quot;**Suggestion:** \u003Cspan class=\"hljs-subst\">{result.suggestion}\u003C/span>&quot;\u003C/span>)\n                \n                report.append(\u003Cspan class=\"hljs-string\">&quot;&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-string\">&quot;\\n&quot;\u003C/span>.join(report)\n\n\u003Cspan class=\"hljs-comment\"># Usage examples and CLI interface\u003C/span>\n\u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">validate_directory\u003C/span>(\u003Cspan class=\"hljs-params\">directory_path: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, schema_path: \u003Cspan class=\"hljs-built_in\">str\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\">List\u003C/span>[ValidationResult]]:\n    \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validate all Markdown files in a directory&quot;&quot;&quot;\u003C/span>\n    validator = MarkdownValidator(schema_path) \u003Cspan class=\"hljs-keyword\">if\u003C/span> schema_path \u003Cspan class=\"hljs-keyword\">else\u003C/span> MarkdownValidator()\n    results = {}\n    \n    \u003Cspan class=\"hljs-keyword\">for\u003C/span> file_path \u003Cspan class=\"hljs-keyword\">in\u003C/span> Path(directory_path).rglob(\u003Cspan class=\"hljs-string\">&quot;*.md&quot;\u003C/span>):\n        file_results = validator.validate_file(\u003Cspan class=\"hljs-built_in\">str\u003C/span>(file_path))\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> file_results:\n            results[\u003Cspan class=\"hljs-built_in\">str\u003C/span>(file_path)] = file_results\n    \n    \u003Cspan class=\"hljs-keyword\">return\u003C/span> results\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 validator&quot;&quot;&quot;\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">import\u003C/span> argparse\n    \n    parser = argparse.ArgumentParser(description=\u003Cspan class=\"hljs-string\">&quot;Validate Markdown files&quot;\u003C/span>)\n    parser.add_argument(\u003Cspan class=\"hljs-string\">&quot;path&quot;\u003C/span>, \u003Cspan class=\"hljs-built_in\">help\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;File or directory path to validate&quot;\u003C/span>)\n    parser.add_argument(\u003Cspan class=\"hljs-string\">&quot;--schema&quot;\u003C/span>, \u003Cspan class=\"hljs-built_in\">help\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;Path to validation schema file&quot;\u003C/span>)\n    parser.add_argument(\u003Cspan class=\"hljs-string\">&quot;--type&quot;\u003C/span>, default=\u003Cspan class=\"hljs-string\">&quot;default&quot;\u003C/span>, \u003Cspan class=\"hljs-built_in\">help\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;Document type to validate against&quot;\u003C/span>)\n    parser.add_argument(\u003Cspan class=\"hljs-string\">&quot;--format&quot;\u003C/span>, choices=[\u003Cspan class=\"hljs-string\">&quot;text&quot;\u003C/span>, \u003Cspan class=\"hljs-string\">&quot;json&quot;\u003C/span>], default=\u003Cspan class=\"hljs-string\">&quot;text&quot;\u003C/span>, \u003Cspan class=\"hljs-built_in\">help\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;Output format&quot;\u003C/span>)\n    parser.add_argument(\u003Cspan class=\"hljs-string\">&quot;--errors-only&quot;\u003C/span>, action=\u003Cspan class=\"hljs-string\">&quot;store_true&quot;\u003C/span>, \u003Cspan class=\"hljs-built_in\">help\u003C/span>=\u003Cspan class=\"hljs-string\">&quot;Show only errors&quot;\u003C/span>)\n    \n    args = parser.parse_args()\n    \n    validator = MarkdownValidator(args.schema) \u003Cspan class=\"hljs-keyword\">if\u003C/span> args.schema \u003Cspan class=\"hljs-keyword\">else\u003C/span> MarkdownValidator()\n    \n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> os.path.isfile(args.path):\n        results = validator.validate_file(args.path, args.\u003Cspan class=\"hljs-built_in\">type\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> args.errors_only:\n            results = [r \u003Cspan class=\"hljs-keyword\">for\u003C/span> r \u003Cspan class=\"hljs-keyword\">in\u003C/span> results \u003Cspan class=\"hljs-keyword\">if\u003C/span> r.level == ValidationLevel.ERROR]\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> args.\u003Cspan class=\"hljs-built_in\">format\u003C/span> == \u003Cspan class=\"hljs-string\">&quot;json&quot;\u003C/span>:\n            \u003Cspan class=\"hljs-keyword\">import\u003C/span> json\n            json_results = [\n                {\n                    \u003Cspan class=\"hljs-string\">&quot;level&quot;\u003C/span>: r.level.value,\n                    \u003Cspan class=\"hljs-string\">&quot;category&quot;\u003C/span>: r.category.value,\n                    \u003Cspan class=\"hljs-string\">&quot;message&quot;\u003C/span>: r.message,\n                    \u003Cspan class=\"hljs-string\">&quot;line_number&quot;\u003C/span>: r.line_number,\n                    \u003Cspan class=\"hljs-string\">&quot;suggestion&quot;\u003C/span>: r.suggestion\n                }\n                \u003Cspan class=\"hljs-keyword\">for\u003C/span> r \u003Cspan class=\"hljs-keyword\">in\u003C/span> results\n            ]\n            \u003Cspan class=\"hljs-built_in\">print\u003C/span>(json.dumps(json_results, indent=\u003Cspan class=\"hljs-number\">2\u003C/span>))\n        \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n            \u003Cspan class=\"hljs-built_in\">print\u003C/span>(validator.generate_report(results))\n    \n    \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n        all_results = validate_directory(args.path, args.schema)\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> file_path, results \u003Cspan class=\"hljs-keyword\">in\u003C/span> all_results.items():\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> args.errors_only:\n                results = [r \u003Cspan class=\"hljs-keyword\">for\u003C/span> r \u003Cspan class=\"hljs-keyword\">in\u003C/span> results \u003Cspan class=\"hljs-keyword\">if\u003C/span> r.level == ValidationLevel.ERROR]\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> results:\n                    \u003Cspan class=\"hljs-keyword\">continue\u003C/span>\n            \n            \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;\\n\u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-string\">&#x27;=&#x27;\u003C/span>*\u003Cspan class=\"hljs-number\">60\u003C/span>}\u003C/span>&quot;\u003C/span>)\n            \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;File: \u003Cspan class=\"hljs-subst\">{file_path}\u003C/span>&quot;\u003C/span>)\n            \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">&#x27;=&#x27;\u003C/span>*\u003Cspan class=\"hljs-number\">60\u003C/span>)\n            \u003Cspan class=\"hljs-built_in\">print\u003C/span>(validator.generate_report(results))\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=\"advanced-validation-techniques\">Advanced Validation Techniques\u003C/h2>\n\u003Ch3 id=\"custom-rule-development\">Custom Rule Development\u003C/h3>\n\u003Cp>Creating specialized validation rules for specific content requirements:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-python\">\u003Cspan class=\"hljs-comment\"># custom_validators.py - Specialized validation extensions\u003C/span>\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> abc \u003Cspan class=\"hljs-keyword\">import\u003C/span> ABC, abstractmethod\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> typing \u003Cspan class=\"hljs-keyword\">import\u003C/span> \u003Cspan class=\"hljs-type\">List\u003C/span>, \u003Cspan class=\"hljs-type\">Dict\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> re\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> dataclasses \u003Cspan class=\"hljs-keyword\">import\u003C/span> dataclass\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">CustomValidator\u003C/span>(\u003Cspan class=\"hljs-title class_ inherited__\">ABC\u003C/span>):\n    \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Abstract base class for custom validators&quot;&quot;&quot;\u003C/span>\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>, frontmatter: \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>[ValidationResult]:\n        \u003Cspan class=\"hljs-keyword\">pass\u003C/span>\n    \n\u003Cspan class=\"hljs-meta\">    @abstractmethod\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">get_name\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">str\u003C/span>:\n        \u003Cspan class=\"hljs-keyword\">pass\u003C/span>\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">TechnicalWritingValidator\u003C/span>(\u003Cspan class=\"hljs-title class_ inherited__\">CustomValidator\u003C/span>):\n    \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validator for technical writing standards&quot;&quot;&quot;\u003C/span>\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">__init__\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>):\n        self.prohibited_phrases = [\n            \u003Cspan class=\"hljs-string\">&quot;click here&quot;\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&quot;read more&quot;\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&quot;as you can see&quot;\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&quot;obviously&quot;\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&quot;simply&quot;\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&quot;just&quot;\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&quot;easy&quot;\u003C/span>\n        ]\n        \n        self.required_patterns = {\n            \u003Cspan class=\"hljs-string\">&#x27;api_documentation&#x27;\u003C/span>: [\n                \u003Cspan class=\"hljs-string\">r&#x27;## Parameters?&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">r&#x27;## Response&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">r&#x27;## Example&#x27;\u003C/span>\n            ],\n            \u003Cspan class=\"hljs-string\">&#x27;tutorial&#x27;\u003C/span>: [\n                \u003Cspan class=\"hljs-string\">r&#x27;## Prerequisites?&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">r&#x27;## Step \\d+&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">r&#x27;## Conclusion&#x27;\u003C/span>\n            ]\n        }\n    \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>, frontmatter: \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>[ValidationResult]:\n        results = []\n        content_lower = content.lower()\n        \n        \u003Cspan class=\"hljs-comment\"># Check for prohibited phrases\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> phrase \u003Cspan class=\"hljs-keyword\">in\u003C/span> self.prohibited_phrases:\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> phrase \u003Cspan class=\"hljs-keyword\">in\u003C/span> content_lower:\n                results.append(ValidationResult(\n                    level=ValidationLevel.WARNING,\n                    category=ValidationCategory.STYLE,\n                    message=\u003Cspan class=\"hljs-string\">f&quot;Avoid using &#x27;\u003Cspan class=\"hljs-subst\">{phrase}\u003C/span>&#x27; in technical writing&quot;\u003C/span>,\n                    suggestion=\u003Cspan class=\"hljs-string\">f&quot;Replace &#x27;\u003Cspan class=\"hljs-subst\">{phrase}\u003C/span>&#x27; with more specific language&quot;\u003C/span>\n                ))\n        \n        \u003Cspan class=\"hljs-comment\"># Check passive voice usage\u003C/span>\n        passive_patterns = [\n            \u003Cspan class=\"hljs-string\">r&#x27;\\b\\w+ed\\s+by\\b&#x27;\u003C/span>,\n            \u003Cspan class=\"hljs-string\">r&#x27;\\bis\\s+\\w+ed\\b&#x27;\u003C/span>,\n            \u003Cspan class=\"hljs-string\">r&#x27;\\bare\\s+\\w+ed\\b&#x27;\u003C/span>,\n            \u003Cspan class=\"hljs-string\">r&#x27;\\bwas\\s+\\w+ed\\b&#x27;\u003C/span>,\n            \u003Cspan class=\"hljs-string\">r&#x27;\\bwere\\s+\\w+ed\\b&#x27;\u003C/span>\n        ]\n        \n        passive_count = \u003Cspan class=\"hljs-number\">0\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> pattern \u003Cspan class=\"hljs-keyword\">in\u003C/span> passive_patterns:\n            passive_count += \u003Cspan class=\"hljs-built_in\">len\u003C/span>(re.findall(pattern, content_lower))\n        \n        total_sentences = \u003Cspan class=\"hljs-built_in\">len\u003C/span>(re.findall(\u003Cspan class=\"hljs-string\">r&#x27;[.!?]+&#x27;\u003C/span>, content))\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> total_sentences &gt; \u003Cspan class=\"hljs-number\">0\u003C/span> \u003Cspan class=\"hljs-keyword\">and\u003C/span> (passive_count / total_sentences) &gt; \u003Cspan class=\"hljs-number\">0.3\u003C/span>:\n            results.append(ValidationResult(\n                level=ValidationLevel.INFO,\n                category=ValidationCategory.STYLE,\n                message=\u003Cspan class=\"hljs-string\">f&quot;High passive voice usage (\u003Cspan class=\"hljs-subst\">{passive_count}\u003C/span>/\u003Cspan class=\"hljs-subst\">{total_sentences}\u003C/span> sentences)&quot;\u003C/span>,\n                suggestion=\u003Cspan class=\"hljs-string\">&quot;Consider using more active voice constructions&quot;\u003C/span>\n            ))\n        \n        \u003Cspan class=\"hljs-comment\"># Check document type specific patterns\u003C/span>\n        doc_category = frontmatter.get(\u003Cspan class=\"hljs-string\">&#x27;category&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>).lower()\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> doc_category \u003Cspan class=\"hljs-keyword\">in\u003C/span> self.required_patterns:\n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> pattern \u003Cspan class=\"hljs-keyword\">in\u003C/span> self.required_patterns[doc_category]:\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> re.search(pattern, content, re.IGNORECASE):\n                    results.append(ValidationResult(\n                        level=ValidationLevel.WARNING,\n                        category=ValidationCategory.STRUCTURE,\n                        message=\u003Cspan class=\"hljs-string\">f&quot;Missing expected section for \u003Cspan class=\"hljs-subst\">{doc_category}\u003C/span>: \u003Cspan class=\"hljs-subst\">{pattern}\u003C/span>&quot;\u003C/span>,\n                        suggestion=\u003Cspan class=\"hljs-string\">f&quot;Add section matching pattern: \u003Cspan class=\"hljs-subst\">{pattern}\u003C/span>&quot;\u003C/span>\n                    ))\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> results\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">get_name\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">str\u003C/span>:\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-string\">&quot;Technical Writing Standards&quot;\u003C/span>\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">AccessibilityValidator\u003C/span>(\u003Cspan class=\"hljs-title class_ inherited__\">CustomValidator\u003C/span>):\n    \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validator for accessibility compliance&quot;&quot;&quot;\u003C/span>\n    \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>, frontmatter: \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>[ValidationResult]:\n        results = []\n        \n        \u003Cspan class=\"hljs-comment\"># Check image alt text quality\u003C/span>\n        image_pattern = re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;!\\[([^\\]]*)\\]\\(([^)]+)\\)&#x27;\u003C/span>)\n        images = image_pattern.findall(content)\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> alt_text, image_url \u003Cspan class=\"hljs-keyword\">in\u003C/span> images:\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> alt_text.strip():\n                results.append(ValidationResult(\n                    level=ValidationLevel.ERROR,\n                    category=ValidationCategory.IMAGES,\n                    message=\u003Cspan class=\"hljs-string\">f&quot;Image missing alt text: \u003Cspan class=\"hljs-subst\">{image_url}\u003C/span>&quot;\u003C/span>,\n                    suggestion=\u003Cspan class=\"hljs-string\">&quot;Add descriptive alt text for screen readers&quot;\u003C/span>\n                ))\n            \u003Cspan class=\"hljs-keyword\">elif\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(alt_text.split()) &lt; \u003Cspan class=\"hljs-number\">3\u003C/span>:\n                results.append(ValidationResult(\n                    level=ValidationLevel.WARNING,\n                    category=ValidationCategory.IMAGES,\n                    message=\u003Cspan class=\"hljs-string\">f&quot;Alt text may be too brief: &#x27;\u003Cspan class=\"hljs-subst\">{alt_text}\u003C/span>&#x27;&quot;\u003C/span>,\n                    suggestion=\u003Cspan class=\"hljs-string\">&quot;Provide more descriptive alt text (3+ words)&quot;\u003C/span>\n                ))\n            \u003Cspan class=\"hljs-keyword\">elif\u003C/span> alt_text.lower().startswith((\u003Cspan class=\"hljs-string\">&#x27;image of&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;picture of&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;photo of&#x27;\u003C/span>)):\n                results.append(ValidationResult(\n                    level=ValidationLevel.INFO,\n                    category=ValidationCategory.IMAGES,\n                    message=\u003Cspan class=\"hljs-string\">f&quot;Alt text contains redundant prefix: &#x27;\u003Cspan class=\"hljs-subst\">{alt_text}\u003C/span>&#x27;&quot;\u003C/span>,\n                    suggestion=\u003Cspan class=\"hljs-string\">&quot;Remove &#x27;image of&#x27;, &#x27;picture of&#x27;, etc. from alt text&quot;\u003C/span>\n                ))\n        \n        \u003Cspan class=\"hljs-comment\"># Check heading hierarchy\u003C/span>\n        heading_pattern = re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^(#{1,6})\\s+(.+)$&#x27;\u003C/span>, re.MULTILINE)\n        headings = heading_pattern.findall(content)\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> headings:\n            levels = [\u003Cspan class=\"hljs-built_in\">len\u003C/span>(h[\u003Cspan class=\"hljs-number\">0\u003C/span>]) \u003Cspan class=\"hljs-keyword\">for\u003C/span> h \u003Cspan class=\"hljs-keyword\">in\u003C/span> headings]\n            \n            \u003Cspan class=\"hljs-comment\"># Check if starts with H1\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> levels[\u003Cspan class=\"hljs-number\">0\u003C/span>] != \u003Cspan class=\"hljs-number\">1\u003C/span>:\n                results.append(ValidationResult(\n                    level=ValidationLevel.WARNING,\n                    category=ValidationCategory.STRUCTURE,\n                    message=\u003Cspan class=\"hljs-string\">&quot;Document should start with H1 heading&quot;\u003C/span>,\n                    suggestion=\u003Cspan class=\"hljs-string\">&quot;Use # for the main document title&quot;\u003C/span>\n                ))\n            \n            \u003Cspan class=\"hljs-comment\"># Check for skipped heading levels\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> i \u003Cspan class=\"hljs-keyword\">in\u003C/span> \u003Cspan class=\"hljs-built_in\">range\u003C/span>(\u003Cspan class=\"hljs-number\">1\u003C/span>, \u003Cspan class=\"hljs-built_in\">len\u003C/span>(levels)):\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> levels[i] &gt; levels[i-\u003Cspan class=\"hljs-number\">1\u003C/span>] + \u003Cspan class=\"hljs-number\">1\u003C/span>:\n                    results.append(ValidationResult(\n                        level=ValidationLevel.WARNING,\n                        category=ValidationCategory.STRUCTURE,\n                        message=\u003Cspan class=\"hljs-string\">f&quot;Heading level jumps from H\u003Cspan class=\"hljs-subst\">{levels[i-\u003Cspan class=\"hljs-number\">1\u003C/span>]}\u003C/span> to H\u003Cspan class=\"hljs-subst\">{levels[i]}\u003C/span>&quot;\u003C/span>,\n                        suggestion=\u003Cspan class=\"hljs-string\">&quot;Use sequential heading levels for proper document structure&quot;\u003C/span>\n                    ))\n        \n        \u003Cspan class=\"hljs-comment\"># Check for meaningful link text\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 = link_pattern.findall(content)\n        \n        problematic_link_texts = [\u003Cspan class=\"hljs-string\">&#x27;click here&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;here&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;read more&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;more&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;link&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;this&#x27;\u003C/span>]\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> link_text, link_url \u003Cspan class=\"hljs-keyword\">in\u003C/span> links:\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> link_text.lower().strip() \u003Cspan class=\"hljs-keyword\">in\u003C/span> problematic_link_texts:\n                results.append(ValidationResult(\n                    level=ValidationLevel.WARNING,\n                    category=ValidationCategory.LINKS,\n                    message=\u003Cspan class=\"hljs-string\">f&quot;Non-descriptive link text: &#x27;\u003Cspan class=\"hljs-subst\">{link_text}\u003C/span>&#x27;&quot;\u003C/span>,\n                    suggestion=\u003Cspan class=\"hljs-string\">&quot;Use descriptive text that explains the link destination&quot;\u003C/span>\n                ))\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> results\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">get_name\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">str\u003C/span>:\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-string\">&quot;Accessibility Compliance&quot;\u003C/span>\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">SEOValidator\u003C/span>(\u003Cspan class=\"hljs-title class_ inherited__\">CustomValidator\u003C/span>):\n    \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Validator for SEO best practices&quot;&quot;&quot;\u003C/span>\n    \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>, frontmatter: \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>[ValidationResult]:\n        results = []\n        \n        \u003Cspan class=\"hljs-comment\"># Check title length\u003C/span>\n        title = frontmatter.get(\u003Cspan class=\"hljs-string\">&#x27;title&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>)\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> title:\n            title_length = \u003Cspan class=\"hljs-built_in\">len\u003C/span>(title)\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> title_length &lt; \u003Cspan class=\"hljs-number\">30\u003C/span>:\n                results.append(ValidationResult(\n                    level=ValidationLevel.WARNING,\n                    category=ValidationCategory.FRONTMATTER,\n                    message=\u003Cspan class=\"hljs-string\">f&quot;Title may be too short for SEO (\u003Cspan class=\"hljs-subst\">{title_length}\u003C/span> chars)&quot;\u003C/span>,\n                    suggestion=\u003Cspan class=\"hljs-string\">&quot;Consider expanding title to 30-60 characters&quot;\u003C/span>\n                ))\n            \u003Cspan class=\"hljs-keyword\">elif\u003C/span> title_length &gt; \u003Cspan class=\"hljs-number\">60\u003C/span>:\n                results.append(ValidationResult(\n                    level=ValidationLevel.WARNING,\n                    category=ValidationCategory.FRONTMATTER,\n                    message=\u003Cspan class=\"hljs-string\">f&quot;Title may be too long for SEO (\u003Cspan class=\"hljs-subst\">{title_length}\u003C/span> chars)&quot;\u003C/span>,\n                    suggestion=\u003Cspan class=\"hljs-string\">&quot;Consider shortening title to under 60 characters&quot;\u003C/span>\n                ))\n        \n        \u003Cspan class=\"hljs-comment\"># Check description\u003C/span>\n        description = frontmatter.get(\u003Cspan class=\"hljs-string\">&#x27;description&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>)\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> description:\n            desc_length = \u003Cspan class=\"hljs-built_in\">len\u003C/span>(description)\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> desc_length &lt; \u003Cspan class=\"hljs-number\">120\u003C/span>:\n                results.append(ValidationResult(\n                    level=ValidationLevel.WARNING,\n                    category=ValidationCategory.FRONTMATTER,\n                    message=\u003Cspan class=\"hljs-string\">f&quot;Description may be too short for SEO (\u003Cspan class=\"hljs-subst\">{desc_length}\u003C/span> chars)&quot;\u003C/span>,\n                    suggestion=\u003Cspan class=\"hljs-string\">&quot;Consider expanding description to 120-160 characters&quot;\u003C/span>\n                ))\n            \u003Cspan class=\"hljs-keyword\">elif\u003C/span> desc_length &gt; \u003Cspan class=\"hljs-number\">160\u003C/span>:\n                results.append(ValidationResult(\n                    level=ValidationLevel.WARNING,\n                    category=ValidationCategory.FRONTMATTER,\n                    message=\u003Cspan class=\"hljs-string\">f&quot;Description may be too long for SEO (\u003Cspan class=\"hljs-subst\">{desc_length}\u003C/span> chars)&quot;\u003C/span>,\n                    suggestion=\u003Cspan class=\"hljs-string\">&quot;Consider shortening description to under 160 characters&quot;\u003C/span>\n                ))\n        \n        \u003Cspan class=\"hljs-comment\"># Check keyword usage in content\u003C/span>\n        keywords = frontmatter.get(\u003Cspan class=\"hljs-string\">&#x27;keywords&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;&#x27;\u003C/span>)\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> keywords:\n            keyword_list = [k.strip().lower() \u003Cspan class=\"hljs-keyword\">for\u003C/span> k \u003Cspan class=\"hljs-keyword\">in\u003C/span> keywords.split(\u003Cspan class=\"hljs-string\">&#x27;,&#x27;\u003C/span>)]\n            content_lower = content.lower()\n            \n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> keyword \u003Cspan class=\"hljs-keyword\">in\u003C/span> keyword_list[:\u003Cspan class=\"hljs-number\">3\u003C/span>]:  \u003Cspan class=\"hljs-comment\"># Check first 3 keywords\u003C/span>\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> keyword \u003Cspan class=\"hljs-keyword\">not\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> content_lower:\n                    results.append(ValidationResult(\n                        level=ValidationLevel.INFO,\n                        category=ValidationCategory.CONTENT,\n                        message=\u003Cspan class=\"hljs-string\">f&quot;Keyword &#x27;\u003Cspan class=\"hljs-subst\">{keyword}\u003C/span>&#x27; not found in content&quot;\u003C/span>,\n                        suggestion=\u003Cspan class=\"hljs-string\">&quot;Consider incorporating keywords naturally in content&quot;\u003C/span>\n                    ))\n        \n        \u003Cspan class=\"hljs-comment\"># Check heading structure for SEO\u003C/span>\n        heading_pattern = re.\u003Cspan class=\"hljs-built_in\">compile\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^(#{1,6})\\s+(.+)$&#x27;\u003C/span>, re.MULTILINE)\n        headings = heading_pattern.findall(content)\n        \n        h1_count = \u003Cspan class=\"hljs-built_in\">len\u003C/span>([h \u003Cspan class=\"hljs-keyword\">for\u003C/span> h \u003Cspan class=\"hljs-keyword\">in\u003C/span> headings \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(h[\u003Cspan class=\"hljs-number\">0\u003C/span>]) == \u003Cspan class=\"hljs-number\">1\u003C/span>])\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> h1_count == \u003Cspan class=\"hljs-number\">0\u003C/span>:\n            results.append(ValidationResult(\n                level=ValidationLevel.WARNING,\n                category=ValidationCategory.STRUCTURE,\n                message=\u003Cspan class=\"hljs-string\">&quot;Missing H1 heading for SEO&quot;\u003C/span>,\n                suggestion=\u003Cspan class=\"hljs-string\">&quot;Add a main H1 heading&quot;\u003C/span>\n            ))\n        \u003Cspan class=\"hljs-keyword\">elif\u003C/span> h1_count &gt; \u003Cspan class=\"hljs-number\">1\u003C/span>:\n            results.append(ValidationResult(\n                level=ValidationLevel.WARNING,\n                category=ValidationCategory.STRUCTURE,\n                message=\u003Cspan class=\"hljs-string\">f&quot;Multiple H1 headings found (\u003Cspan class=\"hljs-subst\">{h1_count}\u003C/span>)&quot;\u003C/span>,\n                suggestion=\u003Cspan class=\"hljs-string\">&quot;Use only one H1 heading per document&quot;\u003C/span>\n            ))\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> results\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">get_name\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">str\u003C/span>:\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-string\">&quot;SEO Best Practices&quot;\u003C/span>\n\u003C/code>\u003C/pre>\u003Ch3 id=\"integration-with-development-workflows\">Integration with Development Workflows\u003C/h3>\n\u003Cp>For comprehensive documentation workflows, data validation systems integrate seamlessly with \u003Ca href=\"/blog/markdown-automation-workflows-complete-guide\">automated testing and CI/CD pipelines\u003C/a> to ensure that content quality standards are maintained throughout the development lifecycle, providing immediate feedback to authors and preventing quality issues from reaching production environments.\u003C/p>\n\u003Cp>When building sophisticated content management systems, validation frameworks work effectively with \u003Ca href=\"/blog/markdown-version-control-git-integration-complete-guide\">version control and Git integration\u003C/a> to implement pre-commit hooks, automated quality checks, and comprehensive review processes that maintain editorial standards across distributed teams and complex content repositories.\u003C/p>\n\u003Cp>For advanced documentation architectures, schema validation complements \u003Ca href=\"/blog/markdown-progressive-web-app-documentation-complete-guide\">Progressive Web App documentation systems\u003C/a> by ensuring that content structure meets API requirements, maintains consistent metadata for offline functionality, and provides reliable data structures for interactive documentation features and enhanced user experiences.\u003C/p>\n\u003Ch2 id=\"automated-quality-assurance-workflows\">Automated Quality Assurance Workflows\u003C/h2>\n\u003Ch3 id=\"cicd-integration\">CI/CD Integration\u003C/h3>\n\u003Cp>Implementing comprehensive validation in continuous integration pipelines:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-yaml\">\u003Cspan class=\"hljs-comment\"># .github/workflows/content-validation.yml\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\">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>]\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>]\n\n\u003Cspan class=\"hljs-attr\">jobs:\u003C/span>\n  \u003Cspan class=\"hljs-attr\">validate-content:\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\">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\">&#x27;3.9&#x27;\u003C/span>\n        \u003Cspan class=\"hljs-attr\">cache:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;pip&#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\">validation\u003C/span> \u003Cspan class=\"hljs-string\">dependencies\u003C/span>\n      \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n        pip install PyYAML requests pathlib\n        pip install -r requirements-validation.txt\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\">validation\u003C/span>\n      \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n        python scripts/markdown_validator.py content/ \\\n          --schema config/content-schema.yml \\\n          --format json &gt; validation-results.json\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\">validation\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_validation_report.py \\\n          --input validation-results.json \\\n          --output validation-report.md\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\">validation\u003C/span> \u003Cspan class=\"hljs-string\">results\u003C/span>\n      \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n        error_count=$(jq &#x27;[.[] | select(.level == &quot;error&quot;)] | length&#x27; validation-results.json)\n        if [ &quot;$error_count&quot; -gt 0 ]; then\n          echo &quot;❌ Content validation failed with $error_count errors&quot;\n          exit 1\n        else\n          echo &quot;✅ Content validation passed&quot;\n        fi\n\u003C/span>    \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\">validation\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@v6\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\u003C/span>          \n          \u003Cspan class=\"hljs-string\">try\u003C/span> {\n            \u003Cspan class=\"hljs-string\">const\u003C/span> \u003Cspan class=\"hljs-string\">report\u003C/span> \u003Cspan class=\"hljs-string\">=\u003C/span> \u003Cspan class=\"hljs-string\">fs.readFileSync(&#x27;validation-report.md&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;utf8&#x27;\u003C/span>\u003Cspan class=\"hljs-string\">);\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\">report\u003C/span>\n            }\u003Cspan class=\"hljs-string\">);\u003C/span>\n          } \u003Cspan class=\"hljs-string\">catch\u003C/span> \u003Cspan class=\"hljs-string\">(error)\u003C/span> {\n            \u003Cspan class=\"hljs-string\">console.error(&#x27;Failed\u003C/span> \u003Cspan class=\"hljs-string\">to\u003C/span> \u003Cspan class=\"hljs-string\">post\u003C/span> \u003Cspan class=\"hljs-string\">validation\u003C/span> \u003Cspan class=\"hljs-string\">report:&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">error);\u003C/span>\n          }\n    \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\">artifacts\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@v3\u003C/span>\n      \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n        \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">validation-results\u003C/span>\n        \u003Cspan class=\"hljs-attr\">path:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          validation-results.json\n          validation-report.md\u003C/span>\n\u003C/code>\u003C/pre>\u003Ch3 id=\"pre-commit-hooks\">Pre-commit Hooks\u003C/h3>\n\u003Cp>Setting up local validation with Git hooks:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-bash\">\u003Cspan class=\"hljs-meta\">#!/bin/bash\u003C/span>\n\u003Cspan class=\"hljs-comment\"># .git/hooks/pre-commit - Content validation before commits\u003C/span>\n\n\u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;🔍 Running content validation...&quot;\u003C/span>\n\n\u003Cspan class=\"hljs-comment\"># Find all staged Markdown files\u003C/span>\nstaged_files=$(git diff --cached --name-only --diff-filter=ACM | grep \u003Cspan class=\"hljs-string\">&#x27;\\.md$&#x27;\u003C/span>)\n\n\u003Cspan class=\"hljs-keyword\">if\u003C/span> [ -z \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$staged_files\u003C/span>&quot;\u003C/span> ]; \u003Cspan class=\"hljs-keyword\">then\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;No Markdown files to validate&quot;\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">exit\u003C/span> 0\n\u003Cspan class=\"hljs-keyword\">fi\u003C/span>\n\n\u003Cspan class=\"hljs-comment\"># Create temporary file with staged content\u003C/span>\ntemp_dir=$(\u003Cspan class=\"hljs-built_in\">mktemp\u003C/span> -d)\nvalidation_failed=\u003Cspan class=\"hljs-literal\">false\u003C/span>\n\n\u003Cspan class=\"hljs-keyword\">for\u003C/span> file \u003Cspan class=\"hljs-keyword\">in\u003C/span> \u003Cspan class=\"hljs-variable\">$staged_files\u003C/span>; \u003Cspan class=\"hljs-keyword\">do\u003C/span>\n    \u003Cspan class=\"hljs-comment\"># Get staged version of file\u003C/span>\n    git show \u003Cspan class=\"hljs-string\">&quot;:\u003Cspan class=\"hljs-variable\">$file\u003C/span>&quot;\u003C/span> &gt; \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$temp_dir\u003C/span>/\u003Cspan class=\"hljs-subst\">$(basename $file)\u003C/span>&quot;\u003C/span>\n    \n    \u003Cspan class=\"hljs-comment\"># Validate the staged content\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> ! python scripts/markdown_validator.py \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$temp_dir\u003C/span>/\u003Cspan class=\"hljs-subst\">$(basename $file)\u003C/span>&quot;\u003C/span> --errors-only; \u003Cspan class=\"hljs-keyword\">then\u003C/span>\n        \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;❌ Validation failed for: \u003Cspan class=\"hljs-variable\">$file\u003C/span>&quot;\u003C/span>\n        validation_failed=\u003Cspan class=\"hljs-literal\">true\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">fi\u003C/span>\n\u003Cspan class=\"hljs-keyword\">done\u003C/span>\n\n\u003Cspan class=\"hljs-comment\"># Cleanup\u003C/span>\n\u003Cspan class=\"hljs-built_in\">rm\u003C/span> -rf \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$temp_dir\u003C/span>&quot;\u003C/span>\n\n\u003Cspan class=\"hljs-keyword\">if\u003C/span> [ \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$validation_failed\u003C/span>&quot;\u003C/span> = \u003Cspan class=\"hljs-literal\">true\u003C/span> ]; \u003Cspan class=\"hljs-keyword\">then\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;&quot;\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;❌ Content validation failed. Please fix issues before committing.&quot;\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;   Run &#x27;python scripts/markdown_validator.py &lt;file&gt;&#x27; for detailed results&quot;\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">exit\u003C/span> 1\n\u003Cspan class=\"hljs-keyword\">fi\u003C/span>\n\n\u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;✅ All content validation checks passed&quot;\u003C/span>\n\u003Cspan class=\"hljs-built_in\">exit\u003C/span> 0\n\u003C/code>\u003C/pre>\u003Ch2 id=\"advanced-schema-patterns\">Advanced Schema Patterns\u003C/h2>\n\u003Ch3 id=\"dynamic-schema-generation\">Dynamic Schema Generation\u003C/h3>\n\u003Cp>Creating adaptive validation schemas based on content analysis:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-python\">\u003Cspan class=\"hljs-comment\"># schema_generator.py - Dynamic schema creation\u003C/span>\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> os\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> yaml\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> collections \u003Cspan class=\"hljs-keyword\">import\u003C/span> Counter, defaultdict\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> pathlib \u003Cspan class=\"hljs-keyword\">import\u003C/span> Path\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> re\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">SchemaGenerator\u003C/span>:\n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">__init__\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>):\n        self.content_analysis = {\n            \u003Cspan class=\"hljs-string\">&#x27;frontmatter_fields&#x27;\u003C/span>: Counter(),\n            \u003Cspan class=\"hljs-string\">&#x27;heading_patterns&#x27;\u003C/span>: [],\n            \u003Cspan class=\"hljs-string\">&#x27;content_lengths&#x27;\u003C/span>: [],\n            \u003Cspan class=\"hljs-string\">&#x27;common_sections&#x27;\u003C/span>: Counter(),\n            \u003Cspan class=\"hljs-string\">&#x27;link_patterns&#x27;\u003C/span>: [],\n            \u003Cspan class=\"hljs-string\">&#x27;image_patterns&#x27;\u003C/span>: []\n        }\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">analyze_content_directory\u003C/span>(\u003Cspan class=\"hljs-params\">self, directory_path: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Analyze existing content to generate schema patterns&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> file_path \u003Cspan class=\"hljs-keyword\">in\u003C/span> Path(directory_path).rglob(\u003Cspan class=\"hljs-string\">&quot;*.md&quot;\u003C/span>):\n            self.analyze_file(\u003Cspan class=\"hljs-built_in\">str\u003C/span>(file_path))\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">analyze_file\u003C/span>(\u003Cspan class=\"hljs-params\">self, file_path: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Analyze individual file for schema patterns&quot;&quot;&quot;\u003C/span>\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        \u003Cspan class=\"hljs-keyword\">except\u003C/span>:\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Parse frontmatter\u003C/span>\n        frontmatter_match = re.\u003Cspan class=\"hljs-keyword\">match\u003C/span>(\u003Cspan class=\"hljs-string\">r&#x27;^---\\n(.*?)\\n---&#x27;\u003C/span>, content, re.DOTALL)\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> frontmatter_match:\n            \u003Cspan class=\"hljs-keyword\">try\u003C/span>:\n                frontmatter = yaml.safe_load(frontmatter_match.group(\u003Cspan class=\"hljs-number\">1\u003C/span>))\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">isinstance\u003C/span>(frontmatter, \u003Cspan class=\"hljs-built_in\">dict\u003C/span>):\n                    \u003Cspan class=\"hljs-keyword\">for\u003C/span> field \u003Cspan class=\"hljs-keyword\">in\u003C/span> frontmatter.keys():\n                        self.content_analysis[\u003Cspan class=\"hljs-string\">&#x27;frontmatter_fields&#x27;\u003C/span>][field] += \u003Cspan class=\"hljs-number\">1\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">except\u003C/span>:\n                \u003Cspan class=\"hljs-keyword\">pass\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Analyze content structure\u003C/span>\n        content_body = content[frontmatter_match.end():] \u003Cspan class=\"hljs-keyword\">if\u003C/span> frontmatter_match \u003Cspan class=\"hljs-keyword\">else\u003C/span> content\n        \n        \u003Cspan class=\"hljs-comment\"># Word count\u003C/span>\n        word_count = \u003Cspan class=\"hljs-built_in\">len\u003C/span>(re.findall(\u003Cspan class=\"hljs-string\">r&#x27;\\b\\w+\\b&#x27;\u003C/span>, content_body))\n        self.content_analysis[\u003Cspan class=\"hljs-string\">&#x27;content_lengths&#x27;\u003C/span>].append(word_count)\n        \n        \u003Cspan class=\"hljs-comment\"># Heading analysis\u003C/span>\n        headings = re.findall(\u003Cspan class=\"hljs-string\">r&#x27;^(#{1,6})\\s+(.+)$&#x27;\u003C/span>, content_body, re.MULTILINE)\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> level_hashes, heading_text \u003Cspan class=\"hljs-keyword\">in\u003C/span> headings:\n            level = \u003Cspan class=\"hljs-built_in\">len\u003C/span>(level_hashes)\n            self.content_analysis[\u003Cspan class=\"hljs-string\">&#x27;heading_patterns&#x27;\u003C/span>].append((level, heading_text.lower()))\n            \n            \u003Cspan class=\"hljs-comment\"># Common sections\u003C/span>\n            section_keywords = [\u003Cspan class=\"hljs-string\">&#x27;introduction&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;conclusion&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;overview&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;getting started&#x27;\u003C/span>, \n                             \u003Cspan class=\"hljs-string\">&#x27;installation&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;usage&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;examples&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;troubleshooting&#x27;\u003C/span>]\n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> keyword \u003Cspan class=\"hljs-keyword\">in\u003C/span> section_keywords:\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> keyword \u003Cspan class=\"hljs-keyword\">in\u003C/span> heading_text.lower():\n                    self.content_analysis[\u003Cspan class=\"hljs-string\">&#x27;common_sections&#x27;\u003C/span>][keyword] += \u003Cspan class=\"hljs-number\">1\u003C/span>\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">generate_schema\u003C/span>(\u003Cspan class=\"hljs-params\">self, document_type: \u003Cspan class=\"hljs-built_in\">str\u003C/span> = \u003Cspan class=\"hljs-string\">&quot;auto_generated&quot;\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;Generate validation schema based on analyzed content&quot;&quot;&quot;\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Determine common frontmatter fields\u003C/span>\n        total_files = \u003Cspan class=\"hljs-built_in\">len\u003C/span>(self.content_analysis[\u003Cspan class=\"hljs-string\">&#x27;content_lengths&#x27;\u003C/span>])\n        required_threshold = \u003Cspan class=\"hljs-number\">0.8\u003C/span>  \u003Cspan class=\"hljs-comment\"># Field must appear in 80% of files\u003C/span>\n        optional_threshold = \u003Cspan class=\"hljs-number\">0.3\u003C/span>  \u003Cspan class=\"hljs-comment\"># Field must appear in 30% of files\u003C/span>\n        \n        required_fields = []\n        optional_fields = []\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> field, count \u003Cspan class=\"hljs-keyword\">in\u003C/span> self.content_analysis[\u003Cspan class=\"hljs-string\">&#x27;frontmatter_fields&#x27;\u003C/span>].items():\n            frequency = count / total_files\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> frequency &gt;= required_threshold:\n                required_fields.append(field)\n            \u003Cspan class=\"hljs-keyword\">elif\u003C/span> frequency &gt;= optional_threshold:\n                optional_fields.append(field)\n        \n        \u003Cspan class=\"hljs-comment\"># Content length analysis\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> self.content_analysis[\u003Cspan class=\"hljs-string\">&#x27;content_lengths&#x27;\u003C/span>]:\n            min_length = \u003Cspan class=\"hljs-built_in\">int\u003C/span>(\u003Cspan class=\"hljs-built_in\">min\u003C/span>(self.content_analysis[\u003Cspan class=\"hljs-string\">&#x27;content_lengths&#x27;\u003C/span>]) * \u003Cspan class=\"hljs-number\">0.5\u003C/span>)\n            max_length = \u003Cspan class=\"hljs-built_in\">int\u003C/span>(\u003Cspan class=\"hljs-built_in\">max\u003C/span>(self.content_analysis[\u003Cspan class=\"hljs-string\">&#x27;content_lengths&#x27;\u003C/span>]) * \u003Cspan class=\"hljs-number\">1.5\u003C/span>)\n        \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n            min_length, max_length = \u003Cspan class=\"hljs-number\">100\u003C/span>, \u003Cspan class=\"hljs-number\">5000\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Generate schema\u003C/span>\n        schema = {\n            \u003Cspan class=\"hljs-string\">&#x27;schema_version&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;1.0&#x27;\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&#x27;generated_from_analysis&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&#x27;analysis_stats&#x27;\u003C/span>: {\n                \u003Cspan class=\"hljs-string\">&#x27;files_analyzed&#x27;\u003C/span>: total_files,\n                \u003Cspan class=\"hljs-string\">&#x27;avg_word_count&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">sum\u003C/span>(self.content_analysis[\u003Cspan class=\"hljs-string\">&#x27;content_lengths&#x27;\u003C/span>]) // total_files \u003Cspan class=\"hljs-keyword\">if\u003C/span> total_files &gt; \u003Cspan class=\"hljs-number\">0\u003C/span> \u003Cspan class=\"hljs-keyword\">else\u003C/span> \u003Cspan class=\"hljs-number\">0\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;common_sections&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">dict\u003C/span>(self.content_analysis[\u003Cspan class=\"hljs-string\">&#x27;common_sections&#x27;\u003C/span>].most_common(\u003Cspan class=\"hljs-number\">10\u003C/span>))\n            },\n            \u003Cspan class=\"hljs-string\">&#x27;document_types&#x27;\u003C/span>: {\n                document_type: {\n                    \u003Cspan class=\"hljs-string\">&#x27;required_frontmatter&#x27;\u003C/span>: required_fields,\n                    \u003Cspan class=\"hljs-string\">&#x27;optional_frontmatter&#x27;\u003C/span>: optional_fields,\n                    \u003Cspan class=\"hljs-string\">&#x27;frontmatter_rules&#x27;\u003C/span>: self.generate_frontmatter_rules(),\n                    \u003Cspan class=\"hljs-string\">&#x27;content_rules&#x27;\u003C/span>: {\n                        \u003Cspan class=\"hljs-string\">&#x27;min_word_count&#x27;\u003C/span>: min_length,\n                        \u003Cspan class=\"hljs-string\">&#x27;max_word_count&#x27;\u003C/span>: max_length,\n                        \u003Cspan class=\"hljs-string\">&#x27;heading_structure&#x27;\u003C/span>: {\n                            \u003Cspan class=\"hljs-string\">&#x27;require_h1&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                            \u003Cspan class=\"hljs-string\">&#x27;max_heading_level&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">4\u003C/span>,\n                            \u003Cspan class=\"hljs-string\">&#x27;sequential_levels&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>\n                        }\n                    }\n                }\n            }\n        }\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> schema\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">generate_frontmatter_rules\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\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-string\">&quot;&quot;&quot;Generate specific rules for frontmatter fields&quot;&quot;&quot;\u003C/span>\n        rules = {}\n        \n        \u003Cspan class=\"hljs-comment\"># Standard rules for common fields\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;title&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> self.content_analysis[\u003Cspan class=\"hljs-string\">&#x27;frontmatter_fields&#x27;\u003C/span>]:\n            rules[\u003Cspan class=\"hljs-string\">&#x27;title&#x27;\u003C/span>] = {\n                \u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;string&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;min_length&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">10\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;max_length&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">100\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;pattern&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">r&#x27;^[A-Za-z0-9\\s\\-:,]+$&#x27;\u003C/span>\n            }\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;description&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> self.content_analysis[\u003Cspan class=\"hljs-string\">&#x27;frontmatter_fields&#x27;\u003C/span>]:\n            rules[\u003Cspan class=\"hljs-string\">&#x27;description&#x27;\u003C/span>] = {\n                \u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;string&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;min_length&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">50\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;max_length&#x27;\u003C/span>: \u003Cspan class=\"hljs-number\">200\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;must_end_with_period&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>\n            }\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;date&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> self.content_analysis[\u003Cspan class=\"hljs-string\">&#x27;frontmatter_fields&#x27;\u003C/span>]:\n            rules[\u003Cspan class=\"hljs-string\">&#x27;date&#x27;\u003C/span>] = {\n                \u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;date&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;format&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;YYYY-MM-DD&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;not_future&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>\n            }\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;category&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> self.content_analysis[\u003Cspan class=\"hljs-string\">&#x27;frontmatter_fields&#x27;\u003C/span>]:\n            \u003Cspan class=\"hljs-comment\"># Analyze existing categories\u003C/span>\n            \u003Cspan class=\"hljs-comment\"># This would require additional parsing, simplified for example\u003C/span>\n            rules[\u003Cspan class=\"hljs-string\">&#x27;category&#x27;\u003C/span>] = {\n                \u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;string&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;allowed_values&#x27;\u003C/span>: [\u003Cspan class=\"hljs-string\">&#x27;Tutorial&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;Guide&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;Reference&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;News&#x27;\u003C/span>]\n            }\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> rules\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">save_schema\u003C/span>(\u003Cspan class=\"hljs-params\">self, schema: \u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>], output_path: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Save generated schema to file&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">with\u003C/span> \u003Cspan class=\"hljs-built_in\">open\u003C/span>(output_path, \u003Cspan class=\"hljs-string\">&#x27;w&#x27;\u003C/span>, encoding=\u003Cspan class=\"hljs-string\">&#x27;utf-8&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">as\u003C/span> f:\n            yaml.dump(schema, f, default_flow_style=\u003Cspan class=\"hljs-literal\">False\u003C/span>, indent=\u003Cspan class=\"hljs-number\">2\u003C/span>)\n\n\u003Cspan class=\"hljs-comment\"># Usage example\u003C/span>\n\u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">generate_schema_from_content\u003C/span>():\n    generator = SchemaGenerator()\n    generator.analyze_content_directory(\u003Cspan class=\"hljs-string\">&#x27;content/&#x27;\u003C/span>)\n    schema = generator.generate_schema(\u003Cspan class=\"hljs-string\">&#x27;blog_post&#x27;\u003C/span>)\n    generator.save_schema(schema, \u003Cspan class=\"hljs-string\">&#x27;generated-schema.yml&#x27;\u003C/span>)\n    \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">&quot;Schema generated successfully!&quot;\u003C/span>)\n\n\u003Cspan class=\"hljs-keyword\">if\u003C/span> __name__ == \u003Cspan class=\"hljs-string\">&quot;__main__&quot;\u003C/span>:\n    generate_schema_from_content()\n\u003C/code>\u003C/pre>\u003Ch2 id=\"conclusion\">Conclusion\u003C/h2>\n\u003Cp>Advanced Markdown data validation and schema checking provides the foundation for maintaining high-quality documentation at scale while enabling sophisticated automation workflows that support distributed teams and complex content requirements. By implementing comprehensive validation frameworks, automated quality assurance systems, and intelligent schema management, technical teams can ensure consistent content quality while reducing manual oversight and accelerating content production processes.\u003C/p>\n\u003Cp>The key to successful validation implementation lies in balancing automation with flexibility, ensuring that validation systems support content creators rather than hindering their workflow. Whether you&#39;re building internal documentation systems, managing open-source project documentation, or creating comprehensive knowledge bases, the validation techniques covered in this guide provide the tools necessary for maintaining professional content standards while scaling your documentation efforts effectively.\u003C/p>\n\u003Cp>Remember to iterate on your validation schemas based on real-world usage patterns, implement gradual rollouts of new validation rules to avoid disrupting existing workflows, and maintain clear documentation about validation requirements to help content creators understand and meet quality standards. With properly implemented data validation and schema checking, your Markdown documentation can achieve enterprise-level quality assurance while maintaining the simplicity and accessibility that makes Markdown an ideal choice for technical documentation.\u003C/p>\n",[15,19,22,25,28,31],{"id":16,"text":17,"level":18},"why-master-markdown-data-validation","Why Master Markdown Data Validation?",2,{"id":20,"text":21,"level":18},"foundation-validation-concepts","Foundation Validation Concepts",{"id":23,"text":24,"level":18},"advanced-validation-techniques","Advanced Validation Techniques",{"id":26,"text":27,"level":18},"automated-quality-assurance-workflows","Automated Quality Assurance Workflows",{"id":29,"text":30,"level":18},"advanced-schema-patterns","Advanced Schema Patterns",{"id":32,"text":33,"level":18},"conclusion","Conclusion",[],[36,44,52],{"slug":37,"title":38,"description":39,"excerpt":40,"date":41,"category":9,"author":10,"keywords":42,"readingMinutes":43},"markdown-table-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",22,{"slug":45,"title":46,"description":47,"excerpt":48,"date":49,"category":9,"author":10,"keywords":50,"readingMinutes":51},"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":53,"title":54,"description":55,"excerpt":56,"date":57,"category":9,"author":10,"keywords":58,"readingMinutes":59},"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,1792184943940]