# markdown-doc-linter > Comprehensive documentation quality validation for Markdown files with link checking, structure analysis, heading hierarchy validation, and style enforcement. Use when linting README files, documentation, checking markdown quality, validating doc structure, or ensuring documentation standards. - Author: Claude Assistant - Repository: mfethe1/skills - Version: 20260123221508 - Stars: 0 - Forks: 0 - Last Updated: 2026-02-06 - Source: https://github.com/mfethe1/skills - Web: https://mule.run/skillshub/@@mfethe1/skills~markdown-doc-linter:20260123221508 --- --- name: markdown-doc-linter description: Comprehensive documentation quality validation for Markdown files with link checking, structure analysis, heading hierarchy validation, and style enforcement. Use when linting README files, documentation, checking markdown quality, validating doc structure, or ensuring documentation standards. --- # Markdown Doc Linter Comprehensive documentation quality validation for Markdown files with link checking, structure analysis, and style enforcement. ## Quick Start ```bash # Lint a single markdown file python scripts/lint_markdown.py README.md # Lint all markdown files in a directory python scripts/lint_markdown.py docs/ --recursive # Check with specific rules enabled python scripts/lint_markdown.py README.md --rules headings,links,spelling # Generate detailed report python scripts/lint_markdown.py docs/ --recursive --report lint-report.md # JSON output for CI integration python scripts/lint_markdown.py README.md --json ``` ## Validation Layers ### 1. Structure Validation - **Heading hierarchy**: Ensures proper H1→H2→H3 progression (no skipped levels) - **Single H1 rule**: Documents should have exactly one H1 heading - **Table of contents alignment**: Validates TOC matches actual headings - **Section completeness**: Checks for empty sections ### 2. Link Validation - **Internal link resolution**: Validates `#anchor` links point to existing headings - **File reference checking**: Confirms `./path/to/file.md` exists - **Image reference validation**: Ensures referenced images exist - **Duplicate link detection**: Flags repeated identical links ### 3. Content Quality - **Line length enforcement**: Configurable max line length (default: 120) - **Trailing whitespace detection**: Flags lines with trailing spaces - **Consecutive blank lines**: Limits to configured maximum - **Hard tabs detection**: Flags tabs vs spaces inconsistency - **Code fence language**: Ensures code blocks specify language ### 4. Markdown Syntax - **Emphasis consistency**: Detects mixing * and _ for emphasis - **List marker consistency**: Ensures consistent -, *, or + usage - **Ordered list numbering**: Validates proper 1. 2. 3. or 1. 1. 1. style - **Fenced code blocks**: Prefers fenced over indented code blocks ### 5. Documentation Standards - **Required sections**: Validates presence of configurable required sections - **Frontmatter validation**: Checks YAML frontmatter structure - **Changelog format**: Validates Keep a Changelog format - **API documentation patterns**: Checks for proper parameter/return documentation ## Configuration Create `.markdownlint.json` or pass `--config`: ```json { "line_length": 120, "heading_style": "atx", "emphasis_style": "asterisk", "list_marker": "-", "required_sections": ["Installation", "Usage", "License"], "allow_html": false, "max_blank_lines": 2, "check_links": true, "check_spelling": false } ``` ## Output Format ``` README.md:15:1: E001 [heading-hierarchy] Heading level skipped (H1 to H3) README.md:23:85: W001 [line-length] Line exceeds 120 characters (145 > 120) README.md:42:0: E002 [broken-link] Internal link '#setup' has no matching heading docs/api.md:8:1: W002 [no-language] Fenced code block missing language identifier docs/api.md:56:0: I001 [trailing-whitespace] Line has trailing whitespace Summary: 2 errors, 2 warnings, 1 info | 2 files checked ``` ## Error Codes ### Errors (E###) | Code | Rule | Description | |------|------|-------------| | E001 | heading-hierarchy | Heading level skipped | | E002 | broken-link | Internal link target not found | | E003 | broken-image | Image file not found | | E004 | duplicate-heading | Multiple headings with same text | | E005 | missing-h1 | Document has no H1 heading | | E006 | multiple-h1 | Document has multiple H1 headings | | E007 | empty-section | Heading with no content before next heading | ### Warnings (W###) | Code | Rule | Description | |------|------|-------------| | W001 | line-length | Line exceeds configured maximum | | W002 | no-language | Code fence missing language identifier | | W003 | inconsistent-list | Mixed list markers in same list | | W004 | inconsistent-emphasis | Mixed emphasis styles | | W005 | hard-tabs | Tab character found | | W006 | excess-blank-lines | Too many consecutive blank lines | | W007 | missing-section | Required section not found | ### Info (I###) | Code | Rule | Description | |------|------|-------------| | I001 | trailing-whitespace | Line has trailing whitespace | | I002 | no-newline-eof | File doesn't end with newline | | I003 | html-element | Raw HTML element found | | I004 | long-heading | Heading exceeds recommended length | ## CI Integration ### GitHub Actions ```yaml - name: Lint Documentation run: | python scripts/lint_markdown.py docs/ --recursive --json > lint-results.json if jq -e '.summary.errors > 0' lint-results.json; then exit 1 fi ``` ### Pre-commit Hook ```yaml repos: - repo: local hooks: - id: markdown-lint name: Markdown Lint entry: python scripts/lint_markdown.py language: python files: \.md$ ``` ## Rule Customization Disable specific rules inline: ```markdown This is a very long line that would normally trigger a warning but is disabled for this specific case. ``` Or at file level: ```markdown # This entire file is exempt from linting ```