mirror of
https://github.com/harvard-edge/cs249r_book.git
synced 2026-05-03 00:07:08 -05:00
- Uncomment all chapters in PDF config for complete book builds - Add format_python_in_qmd.py script for code formatting - Remove temporary working files (notes, footnote catalog) - Update changelog (no new content changes since last publish)
98 lines
3.1 KiB
Python
Executable File
98 lines
3.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Format Python code blocks in .qmd files using Black."""
|
|
|
|
import re
|
|
import sys
|
|
from pathlib import Path
|
|
from typing import List
|
|
import subprocess
|
|
import tempfile
|
|
|
|
|
|
def format_python_blocks(content: str, line_length: int = 70) -> str:
|
|
"""Find and format Python code blocks in markdown using Black."""
|
|
lines = content.split('\n')
|
|
result = []
|
|
in_python_block = False
|
|
python_lines = []
|
|
block_indent = ""
|
|
|
|
for line in lines:
|
|
# Detect start of Python block
|
|
if re.match(r'^```(\{\.)?python', line):
|
|
in_python_block = True
|
|
result.append(line)
|
|
python_lines = []
|
|
continue
|
|
|
|
# Detect end of Python block
|
|
if in_python_block and line.strip() == '```':
|
|
# Format accumulated Python code with Black
|
|
if python_lines:
|
|
code = '\n'.join(python_lines)
|
|
try:
|
|
# Write to temp file
|
|
with tempfile.NamedTemporaryFile(
|
|
mode='w', suffix='.py', delete=False
|
|
) as f:
|
|
f.write(code)
|
|
temp_path = f.name
|
|
|
|
# Run Black
|
|
subprocess.run(
|
|
['black', '--line-length', str(line_length),
|
|
'--quiet', temp_path],
|
|
check=True
|
|
)
|
|
|
|
# Read formatted code
|
|
with open(temp_path, 'r') as f:
|
|
formatted = f.read().rstrip()
|
|
|
|
result.extend(formatted.split('\n'))
|
|
|
|
# Cleanup
|
|
Path(temp_path).unlink()
|
|
except (subprocess.CalledProcessError, FileNotFoundError):
|
|
# If Black fails or isn't installed, keep original
|
|
result.extend(python_lines)
|
|
|
|
python_lines = []
|
|
in_python_block = False
|
|
result.append(line)
|
|
continue
|
|
|
|
# Accumulate Python code
|
|
if in_python_block:
|
|
python_lines.append(line)
|
|
else:
|
|
result.append(line)
|
|
|
|
return '\n'.join(result)
|
|
|
|
|
|
def main(files: List[str], line_length: int = 70) -> int:
|
|
"""Format Python blocks in .qmd files."""
|
|
changed = 0
|
|
for filepath in files:
|
|
path = Path(filepath)
|
|
if path.suffix == '.qmd':
|
|
try:
|
|
content = path.read_text(encoding='utf-8')
|
|
formatted = format_python_blocks(content, line_length)
|
|
|
|
if formatted != content:
|
|
path.write_text(formatted, encoding='utf-8')
|
|
print(f"Formatted: {filepath}")
|
|
changed += 1
|
|
except Exception as e:
|
|
print(f"Error processing {filepath}: {e}",
|
|
file=sys.stderr)
|
|
return 1
|
|
|
|
return 0 if changed == 0 else 1 # Return 1 if changes made
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main(sys.argv[1:]))
|