Files
ai-llm-red-team-handbook/fix_md040.py
T
shiva108 ccb930d126 chore: fix markdown linting errors for Gold Master release
- Fixed MD040 errors in Chapter 14 (added language identifiers to 170 code blocks)
- Fixed MD025 error in Chapter 15 (changed H1 to H3/H4 in example section)
- Added RELEASE_REVIEW_REPORT.md documenting final audit
- Created fix_md040.py automation script for future use

All critical and high-priority linting issues resolved.
Handbook is now ready for v1.0 Gold Master release.
2026-01-07 00:16:08 +01:00

116 lines
3.8 KiB
Python

#!/usr/bin/env python3
"""
Fix MD040 linting errors by adding language identifiers to bare code blocks.
Specifically designed for Chapter 14: Prompt Injection
"""
import re
import sys
def detect_code_block_language(content):
"""
Heuristically determine the language of a code block based on its content.
"""
lines = content.strip().split('\n')
# Check for Python indicators
if any(keyword in content for keyword in ['def ', 'import ', 'class ', 'print(', 'return ', ' #', 'if __name__']):
return 'python'
# Check for bash/shell indicators
if any(keyword in content for keyword in ['#!/bin/', 'echo ', 'curl ', 'grep ', 'sed ', 'awk ', '$ ', 'export ']):
return 'bash'
# Check for JSON indicators
if content.strip().startswith('{') and content.strip().endswith('}'):
if '"' in content and ':' in content:
return 'json'
# Check for YAML indicators
if re.search(r'^\w+:\s*$', content, re.MULTILINE) and not any(c in content for c in ['{', '(', 'def ']):
return 'yaml'
# Check for markdown content
if '## ' in content or '### ' in content or '- [ ]' in content:
return 'markdown'
# Check for prompts/examples (conversation format)
if any(indicator in content.lower() for indicator in ['user:', 'assistant:', 'system:', 'prompt:', 'response:']):
return 'text'
# Check for bullet points or list-like content
if content.count('\n- ') > 2 or content.count('\n* ') > 2:
return 'text'
# Check for HTTP/API content
if any(keyword in content for keyword in ['HTTP/', 'GET ', 'POST ', 'Content-Type:', 'Authorization:']):
return 'http'
# Default to text for plain examples
return 'text'
def fix_code_blocks(filepath):
"""
Read a markdown file and add language identifiers to bare code blocks.
"""
with open(filepath, 'r', encoding='utf-8') as f:
content = f.read()
# Pattern to match bare code blocks (``` without language identifier)
# This matches ``` at start of line, optionally followed by newline
pattern = r'^```\s*$'
lines = content.split('\n')
in_code_block = False
code_block_start = -1
code_block_lines = []
fixed_count = 0
i = 0
while i < len(lines):
line = lines[i]
# Check if this is a code fence
if re.match(r'^```+', line):
# Check if it's a bare fence (no language specified)
match = re.match(r'^(```+)(\s*)$', line)
if match and not in_code_block:
# Start of a bare code block
in_code_block = True
code_block_start = i
code_block_lines = []
i += 1
continue
elif match and in_code_block:
# End of code block - analyze and fix
code_content = '\n'.join(code_block_lines)
language = detect_code_block_language(code_content)
# Replace the opening fence with language identifier
lines[code_block_start] = f'```{language}'
fixed_count += 1
in_code_block = False
code_block_start = -1
code_block_lines = []
elif in_code_block:
code_block_lines.append(line)
i += 1
# Write back
with open(filepath, 'w', encoding='utf-8') as f:
f.write('\n'.join(lines))
return fixed_count
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Usage: python fix_md040.py <markdown_file>")
sys.exit(1)
filepath = sys.argv[1]
count = fix_code_blocks(filepath)
print(f"Fixed {count} bare code blocks in {filepath}")