import json
import sys
import re
import os
def detect_language(code):
s = code.strip()
if re.search(r'^\s*[{\[]', s):
try:
json.loads(s)
return 'json'
except:
pass
if re.search(r'^\s*def\s+\w+\s*\(', s, re.M) or \
re.search(r'^\s*(import|from)\s+\w+', s, re.M):
return 'python'
if re.search(r'\b(function\s+\w+\s*\(|const\s+\w+\s*=)', s) or \
re.search(r'=>|console\.(log|error)', s):
return 'javascript'
if re.search(r'\b(type|interface|enum)\s+\w+', s) or \
re.search(r':\s*(string|number|boolean|any|unknown)', s):
return 'typescript'
if re.search(r'^#!.*\b(bash|sh)\b', s, re.M) or \
re.search(r'\b(if|then|fi|for|in|do|done)\b', s):
return 'bash'
if re.search(r'\b(SELECT|INSERT|UPDATE|DELETE|CREATE)\s+', s, re.I):
return 'sql'
if re.search(r'fn\s+\w+\s*\(', s) or \
re.search(r'use\s+std::', s):
return 'rust'
if re.search(r'func\s+\w+\s*\(', s) or \
re.search(r'package\s+\w+', s):
return 'go'
if re.search(r'<(html|head|body|div|span)', s, re.I):
return 'html'
if re.search(r'[a-zA-Z.#][^{]+\{[^}]+\}', s):
return 'css'
return 'text'
def format_markdown(content):
def add_lang_to_fence(match):
indent, info, body, closing = match.groups()
if not info.strip():
lang = detect_language(body)
return f"{indent}```{lang}\n{body}{closing}\n"
return match.group(0)
fence_pattern = r'(?ms)^([ \t]{0,3})```([^\n]*)\n(.*?)(\n\1```)\s*$'
content = re.sub(fence_pattern, add_lang_to_fence, content)
content = re.sub(r'\n{3,}', '\n\n', content)
return content.rstrip() + '\n'
try:
input_data = json.load(sys.stdin)
file_path = input_data.get('tool_input', {}).get('file_path', '')
if not file_path.endswith(('.md', '.mdx')):
sys.exit(0)
if os.path.exists(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
formatted = format_markdown(content)
if formatted != content:
with open(file_path, 'w', encoding='utf-8') as f:
f.write(formatted)
print(f"✓ Fixed markdown formatting in {file_path}")
except Exception as e:
print(f"Error formatting markdown: {e}", file=sys.stderr)
sys.exit(1)