Skip to main content

scripts-fix-md025-frontmatter-config

#!/usr/bin/env python3 """

CODITECT Markdown Quality System Copyright © 2025 AZ1.AI INC - All Rights Reserved

This software is proprietary and confidential. Unauthorized copying, distribution, or use is strictly prohibited.

CODITECT owns all intellectual property rights to this implementation.

MD025 False Positive Fix - Configuration Update

This script fixes MD025 "Multiple top-level headings" false positives caused by YAML frontmatter title: fields being treated as H1 headings.

The fix updates .markdownlint.json to set front_matter_title: "" which tells markdownlint to ignore the YAML title field when checking for multiple H1s.

Usage: python3 fix-md025-frontmatter-config.py [directory] python3 fix-md025-frontmatter-config.py --dry-run [directory]

Note: This is a CONFIGURATION fix, not a content fix. For files with actual duplicate H1 headings, use fix-md025-multiple-top-headings.py instead. """

import json import argparse from pathlib import Path from typing import Optional

def find_markdownlint_config(start_path: Path) -> Optional[Path]: """Find .markdownlint.json in the given directory or parents.""" current = start_path.resolve()

# Search in current directory first
if current.is_file():
current = current.parent

# Check current directory
config_path = current / ".markdownlint.json"
if config_path.exists():
return config_path

# Also check for .markdownlint.jsonc
config_path = current / ".markdownlint.jsonc"
if config_path.exists():
return config_path

return None

def update_config(config_path: Path, dry_run: bool = False) -> bool: """Update .markdownlint.json to fix MD025 false positives.""" try: # Read existing config with open(config_path, 'r', encoding='utf-8') as f: content = f.read()

    # Parse JSON (handle comments if present)
try:
config = json.loads(content)
except json.JSONDecodeError:
# Try removing comments (simple approach)
import re
clean_content = re.sub(r'//.*$', '', content, flags=re.MULTILINE)
config = json.loads(clean_content)

# Check if MD025 already configured correctly
if "MD025" in config:
if isinstance(config["MD025"], dict):
if config["MD025"].get("front_matter_title") == "":
print(f"✓ MD025 front_matter_title already configured in {config_path}")
return False
else:
# Update existing MD025 config
config["MD025"]["front_matter_title"] = ""
elif config["MD025"] is False:
print(f"⚠ MD025 is disabled entirely in {config_path} - no action needed")
return False
else:
# Replace with dict config
config["MD025"] = {"front_matter_title": ""}
else:
# Add MD025 config
config["MD025"] = {"front_matter_title": ""}

if dry_run:
print(f"[DRY RUN] Would update {config_path}")
print(f" Adding: \"MD025\": {{\"front_matter_title\": \"\"}}")
return True

# Write updated config
with open(config_path, 'w', encoding='utf-8') as f:
json.dump(config, f, indent=2)
f.write('\n')

print(f"✓ Updated {config_path}")
print(f" Added: \"MD025\": {{\"front_matter_title\": \"\"}}")
return True

except Exception as e:
print(f"✗ Error updating {config_path}: {e}")
return False

def create_config(target_dir: Path, dry_run: bool = False) -> bool: """Create a new .markdownlint.json with MD025 fix.""" config_path = target_dir / ".markdownlint.json"

config = {
"default": True,
"MD025": {
"front_matter_title": ""
}
}

if dry_run:
print(f"[DRY RUN] Would create {config_path}")
print(f" With MD025 front_matter_title fix")
return True

try:
with open(config_path, 'w', encoding='utf-8') as f:
json.dump(config, f, indent=2)
f.write('\n')

print(f"✓ Created {config_path}")
print(f" With: \"MD025\": {{\"front_matter_title\": \"\"}}")
return True
except Exception as e:
print(f"✗ Error creating {config_path}: {e}")
return False

def main(): parser = argparse.ArgumentParser( description='Fix MD025 false positives from YAML frontmatter titles', formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" This script updates .markdownlint.json to ignore YAML frontmatter titles when checking for multiple top-level headings (MD025).

Problem: Files with YAML frontmatter like:

title: "My Document"

My Document

trigger MD025 because markdownlint treats the YAML title as an H1 heading.

Solution: Configure MD025 with front_matter_title: "" to disable this behavior.

For actual duplicate H1s, use fix-md025-multiple-top-headings.py instead. """ ) parser.add_argument('path', nargs='?', default='.', help='Directory to update config in (default: current)') parser.add_argument('--dry-run', action='store_true', help='Show what would be changed without modifying files') parser.add_argument('--create', action='store_true', help='Create .markdownlint.json if it does not exist')

args = parser.parse_args()

target_path = Path(args.path).resolve()

if not target_path.exists():
print(f"Error: Path does not exist: {target_path}")
return 1

if target_path.is_file():
target_path = target_path.parent

# Find existing config
config_path = find_markdownlint_config(target_path)

if config_path:
success = update_config(config_path, args.dry_run)
elif args.create:
success = create_config(target_path, args.dry_run)
else:
print(f"No .markdownlint.json found in {target_path}")
print("Use --create to create one, or manually create .markdownlint.json")
return 1

if success:
print("\nMD025 false positive fix applied.")
print("Re-run markdownlint to verify YAML frontmatter titles are now ignored.")
return 0
else:
return 1

if name == 'main': exit(main())